# TimeEditor

A specialized time input component with interactive time selection functionality. Features keyboard navigation, automatic validation, and support for both minute and second precision. The component stores time as a numeric value representing total minutes (with fractional seconds).

## Installation

```bash
npm install @ticatec/uniface-element
```

## Import

```typescript
import TimeEditor from "@ticatec/uniface-element/TimeEditor";
```

## Basic Usage

```svelte
<script>
  import TimeEditor from "@ticatec/uniface-element/TimeEditor";
  
  let timeValue = null; // null or number (minutes)
</script>

<TimeEditor bind:value={timeValue} />
```

## Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `number \| null` | `null` | Time value in minutes (e.g., 90.5 = 1:30:30) |
| `precision` | `"M" \| "S"` | `"M"` | Time precision - Minutes or Seconds |
| `mandatory` | `boolean` | `false` | Whether to show zeros instead of underscores for empty fields |
| `disabled` | `boolean` | `false` | Whether the input is disabled |
| `readonly` | `boolean` | `false` | Whether the input is read-only |
| `variant` | `"" \| "plain" \| "outlined" \| "filled"` | `""` | Input visual variant |
| `compact` | `boolean` | `false` | Whether to use compact spacing |
| `style` | `string` | `""` | Additional CSS styles |
| `prefix` | `string` | `""` | Text prefix to display |
| `suffix` | `string` | `""` | Text suffix to display |
| `displayMode` | `DisplayMode` | `DisplayMode.Edit` | Display mode (Edit/View) |
| `class` | `string` | `""` | CSS class name |
| `onchange` | `OnChangeHandler<number>` | `null` | Callback when time value changes |
| `onfocus` | `((event: FocusEvent) => void) \| null` | `null` | Callback when input gains focus |
| `onblur` | `((event: FocusEvent) => void) \| null` | `null` | Callback when input loses focus |

## Features

- **Interactive Selection**: Click or use arrow keys to navigate between time segments
- **Automatic Validation**: Prevents invalid time entries (e.g., 25:70)
- **Flexible Precision**: Support for both minute (HH:MM) and second (HH:MM:SS) precision
- **Clear Functionality**: Built-in clear button to reset the time
- **Visual Feedback**: Highlighted segments show current cursor position
- **Mandatory Mode**: Option to show zeros instead of underscores for required fields

## Value Format

The TimeEditor stores time as a number representing total minutes:
- `90` = 1 hour 30 minutes (01:30)
- `90.5` = 1 hour 30 minutes 30 seconds (01:30:30)
- `null` = empty/unset time

## Examples

### Basic Time Input (Minutes)

```svelte
<script>
  import TimeEditor from "@ticatec/uniface-element/TimeEditor";
  
  let meetingTime = 570; // 9:30 AM (9*60 + 30 = 570 minutes)
</script>

<div class="form-group">
  <label>Meeting Time:</label>
  <TimeEditor bind:value={meetingTime} precision="M" />
</div>

<p>Selected time: {meetingTime ? Math.floor(meetingTime / 60) + ':' + (meetingTime % 60).toString().padStart(2, '0') : 'Not set'}</p>

<style>
  .form-group {
    margin-bottom: 16px;
  }
  
  label {
    display: block;
    margin-bottom: 4px;
    font-weight: 500;
  }
</style>
```

### Time Input with Seconds

```svelte
<script>
  import TimeEditor from "@ticatec/uniface-element/TimeEditor";
  
  let duration = 125.75; // 2:05:45 (125 minutes + 45 seconds)
</script>

<div class="form-group">
  <label>Video Duration:</label>
  <TimeEditor bind:value={duration} precision="S" />
</div>
```

### With Event Handlers

```svelte
<script>
  import TimeEditor from "@ticatec/uniface-element/TimeEditor";
  
  let scheduleTime = null;
  let isFocused = false;
  
  function handleTimeChange(newTime) {
    console.log('Time changed:', newTime);
    if (newTime !== null) {
      const hours = Math.floor(newTime / 60);
      const minutes = Math.floor(newTime % 60);
      const seconds = Math.floor((newTime % 1) * 60);
      console.log(`Time: ${hours}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`);
    }
  }
  
  function handleFocus(event) {
    console.log('Time editor focused');
    isFocused = true;
  }
  
  function handleBlur(event) {
    console.log('Time editor blurred');
    isFocused = false;
  }
</script>

<TimeEditor 
  bind:value={scheduleTime}
  precision="S"
  onchange={handleTimeChange}
  onfocus={handleFocus}
  onblur={handleBlur}
/>

{#if isFocused}
  <p>Time editor is active - use arrow keys to navigate, numbers to input</p>
{/if}
```

### Mandatory Mode

```svelte
<script>
  import TimeEditor from "@ticatec/uniface-element/TimeEditor";
  
  let time1 = null;
  let time2 = null;
</script>

<!-- Optional mode (shows underscores) -->
<div class="form-group">
  <label>Optional Time:</label>
  <TimeEditor bind:value={time1} mandatory={false} />
</div>

<!-- Mandatory mode (shows zeros) -->
<div class="form-group">
  <label>Required Time:</label>
  <TimeEditor bind:value={time2} mandatory={true} />
</div>
```

### Different Variants

```svelte
<script>
  import TimeEditor from "@ticatec/uniface-element/TimeEditor";
  
  let time1 = 480; // 8:00
  let time2 = 540; // 9:00
  let time3 = 600; // 10:00
</script>

<!-- Default variant -->
<TimeEditor bind:value={time1} />

<!-- Outlined variant -->
<TimeEditor bind:value={time2} variant="outlined" />

<!-- Filled variant -->
<TimeEditor bind:value={time3} variant="filled" />
```

### With Prefix and Suffix

```svelte
<script>
  import TimeEditor from "@ticatec/uniface-element/TimeEditor";
  
  let startTime = 480; // 8:00 AM
  let duration = 120;  // 2:00 hours
</script>

<div class="form-group">
  <label>Start Time:</label>
  <TimeEditor bind:value={startTime} suffix=" AM" />
</div>

<div class="form-group">
  <label>Duration:</label>
  <TimeEditor bind:value={duration} prefix="Duration: " suffix=" hrs" />
</div>
```

### Schedule Form Example

```svelte
<script>
  import TimeEditor from "@ticatec/uniface-element/TimeEditor";
  import Button from "@ticatec/uniface-element/Button";
  import TextEditor from "@ticatec/uniface-element/TextEditor";
  
  let schedule = {
    title: '',
    startTime: null,
    endTime: null,
    breakDuration: 15 // 15 minutes
  };
  
  $: totalDuration = schedule.startTime !== null && schedule.endTime !== null 
    ? schedule.endTime - schedule.startTime - schedule.breakDuration
    : 0;
  
  function formatTime(minutes) {
    if (minutes === null) return 'Not set';
    const hours = Math.floor(minutes / 60);
    const mins = Math.floor(minutes % 60);
    return `${hours}:${mins.toString().padStart(2, '0')}`;
  }
  
  function handleSubmit() {
    console.log('Schedule:', schedule);
  }
</script>

<div class="schedule-form">
  <h3>Create Schedule</h3>
  
  <div class="form-field">
    <label>Event Title</label>
    <TextEditor bind:value={schedule.title} placeholder="Enter event title" />
  </div>
  
  <div class="form-row">
    <div class="form-field">
      <label>Start Time</label>
      <TimeEditor bind:value={schedule.startTime} precision="M" />
    </div>
    
    <div class="form-field">
      <label>End Time</label>
      <TimeEditor bind:value={schedule.endTime} precision="M" />
    </div>
  </div>
  
  <div class="form-field">
    <label>Break Duration (minutes)</label>
    <TimeEditor bind:value={schedule.breakDuration} precision="M" />
  </div>
  
  {#if totalDuration > 0}
    <div class="summary">
      <p><strong>Summary:</strong></p>
      <p>Duration: {formatTime(totalDuration)} (excluding breaks)</p>
      <p>Start: {formatTime(schedule.startTime)} - End: {formatTime(schedule.endTime)}</p>
    </div>
  {/if}
  
  <Button 
    type="primary" 
    label="Create Schedule" 
    onClick={handleSubmit}
    disabled={!schedule.title || schedule.startTime === null || schedule.endTime === null}
  />
</div>

<style>
  .schedule-form {
    max-width: 500px;
    padding: 24px;
    border: 1px solid #ddd;
    border-radius: 8px;
  }
  
  h3 {
    margin-bottom: 24px;
  }
  
  .form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
  }
  
  .form-field {
    margin-bottom: 16px;
  }
  
  label {
    display: block;
    margin-bottom: 4px;
    font-weight: 500;
  }
  
  .summary {
    background: #f8f9fa;
    padding: 16px;
    border-radius: 4px;
    margin-bottom: 16px;
  }
  
  .summary p {
    margin: 0 0 4px 0;
  }
</style>
```

### Disabled and Readonly States

```svelte
<script>
  import TimeEditor from "@ticatec/uniface-element/TimeEditor";
  
  let normalTime = 540; // 9:00
  let readonlyTime = 600; // 10:00
  let disabledTime = null;
</script>

<!-- Normal time input -->
<TimeEditor bind:value={normalTime} />

<!-- Readonly time input -->
<TimeEditor bind:value={readonlyTime} readonly />

<!-- Disabled time input -->
<TimeEditor bind:value={disabledTime} disabled />
```

### Timer/Stopwatch Example

```svelte
<script>
  import TimeEditor from "@ticatec/uniface-element/TimeEditor";
  import Button from "@ticatec/uniface-element/Button";
  
  let timerDuration = 5; // 5 minutes
  let currentTime = 0;
  let isRunning = false;
  let interval;
  
  function startTimer() {
    if (timerDuration > 0) {
      currentTime = timerDuration;
      isRunning = true;
      
      interval = setInterval(() => {
        currentTime -= 1/60; // Subtract 1 second (1/60 minute)
        
        if (currentTime <= 0) {
          currentTime = 0;
          stopTimer();
          alert('Timer finished!');
        }
      }, 1000);
    }
  }
  
  function stopTimer() {
    isRunning = false;
    if (interval) {
      clearInterval(interval);
      interval = null;
    }
  }
  
  function resetTimer() {
    stopTimer();
    currentTime = 0;
  }
</script>

<div class="timer-container">
  <h3>Timer</h3>
  
  <div class="form-field">
    <label>Set Duration:</label>
    <TimeEditor bind:value={timerDuration} precision="S" disabled={isRunning} />
  </div>
  
  <div class="form-field">
    <label>Remaining Time:</label>
    <TimeEditor bind:value={currentTime} precision="S" readonly />
  </div>
  
  <div class="timer-controls">
    {#if !isRunning}
      <Button label="Start" onClick={startTimer} disabled={timerDuration <= 0} />
    {:else}
      <Button label="Stop" onClick={stopTimer} />
    {/if}
    <Button label="Reset" onClick={resetTimer} />
  </div>
</div>

<style>
  .timer-container {
    max-width: 300px;
    padding: 20px;
    border: 1px solid #ddd;
    border-radius: 8px;
  }
  
  .form-field {
    margin-bottom: 16px;
  }
  
  label {
    display: block;
    margin-bottom: 4px;
    font-weight: 500;
  }
  
  .timer-controls {
    display: flex;
    gap: 8px;
  }
</style>
```

## Keyboard Navigation

| Key | Action |
|-----|--------|
| `Arrow Left/Up` | Move cursor to previous time segment |
| `Arrow Right/Down` | Move cursor to next time segment |
| `0-9` | Input number at current cursor position |
| `Delete` | Clear current segment |
| `Backspace` | Clear current segment and move cursor back |
| `Tab` | Move focus to next element |

## Time Format

- **Display Format**: HH:MM or HH:MM:SS depending on precision
- **Storage Format**: Numeric value representing total minutes
- **Range**: 00:00 to 23:59 (0 to 1439 minutes)
- **Seconds**: Stored as fractional minutes (30 seconds = 0.5 minutes)

## Behavior

1. **Focus**: Clicking focuses the input and selects the first time segment
2. **Navigation**: Arrow keys move between hour, minute, and second segments
3. **Input**: Number keys replace the current segment value
4. **Validation**: Invalid times are rejected automatically
5. **Clear**: Clear button resets to empty state
6. **Blur**: Validates and commits the final time value

## Accessibility

- Proper keyboard navigation between time segments
- Screen reader compatible with semantic HTML
- Focus indicators for current time segment
- Clear visual feedback for interaction states

## Best Practices

1. **Precision**: Use minute precision for most scheduling applications
2. **Validation**: Implement additional validation in change handlers if needed
3. **Labels**: Provide clear labels describing the time format expected
4. **Default Values**: Consider providing sensible default times
5. **Range Validation**: Validate time ranges in your application logic

## Browser Support

- Modern browsers with full input event support
- Compatible with Svelte 5+
- Keyboard navigation support
- Touch-friendly interface

## Related Components

- `DatePicker` - Date selection component
- `DateTimePicker` - Combined date and time selection
- `NumberEditor` - Numeric input validation
- `TextEditor` - Basic text input component


