# Navigator 导航器

一个步骤/向导导航组件，引导用户完成多步骤流程。可视化进度并允许用户在带有清晰状态指示器的步骤之间导航。

## 特性

- **步骤可视化**: 向导步骤的可视化表示
- **状态指示器**: 已完成、警告和未开始状态
- **活动跟踪**: 高亮显示当前活动步骤
- **项目高亮**: 高亮显示需要注意的特定项目
- **点击导航**: 点击以在步骤之间导航
- **自定义样式**: 灵活的样式选项
- **动态项目**: 支持动态步骤列表

## 安装

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

```typescript
import Navigator, { NavItemStatus } from '@ticatec/uniface-element/Navigator';
```

## 基本用法

```svelte
<script>
  import Navigator, { NavItemStatus } from '@ticatec/uniface-element/Navigator';

  let activeItem = 0;
  let items = [
    { text: '第1步' },
    { text: '第2步' },
    { text: '第3步' },
    { text: '第4步' }
  ];

  function getStatus(item) {
    const index = items.indexOf(item);
    if (index < activeItem) return NavItemStatus.Completed;
    if (index === activeItem) return NavItemStatus.Completed;
    return NavItemStatus.NotStart;
  }

  function handleClick(item) {
    activeItem = items.indexOf(item);
    console.log('导航到:', item.text);
  }
</script>

<Navigator
  {items}
  activeItem={items[activeItem]}
  retrieveStatus={getStatus}
  itemClickHandler={handleClick}
/>
```

## 属性

| 属性 | 类型 | 默认值 | 说明 |
|------|------|---------|-------------|
| `items` | `Array<any>` | 必填 | 导航项目数组（必须有 `text` 属性） |
| `activeItem` | `any` | `null` | 当前活动项目 |
| `highlights` | `Array<any>` | `[]` | 需要注意的高亮项目 |
| `itemClickHandler` | `(item: any) => void` | 必填 | 项目被点击时的回调 |
| `retrieveStatus` | `(item: any) => NavItemStatus` | 必填 | 获取项目状态的函数 |
| `style` | `string` | `''` | 自定义CSS样式 |

## NavItemStatus 枚举

| 状态 | 值 | 说明 |
|------|------|-------------|
| `NavItemStatus.Completed` | `'nav-completed'` | 步骤已完成 |
| `NavItemStatus.Warning` | `'nav-warning'` | 步骤有警告 |
| `NavItemStatus.NotStart` | `'nav-not-start'` | 步骤未开始 |

## 示例

### 基本向导导航

```svelte
<script>
  import Navigator, { NavItemStatus } from '@ticatec/uniface-element/Navigator';

  let currentStep = 0;

  const steps = [
    { text: '个人信息' },
    { text: '联系方式' },
    { text: '偏好设置' },
    { text: '确认' }
  ];

  function getStepStatus(step) {
    const index = steps.indexOf(step);
    if (index < currentStep) return NavItemStatus.Completed;
    if (index === currentStep) return NavItemStatus.Completed;
    return NavItemStatus.NotStart;
  }

  function handleStepClick(step) {
    const index = steps.indexOf(step);
    if (index <= currentStep) {
      currentStep = index;
    }
  }

  function nextStep() {
    if (currentStep < steps.length - 1) {
      currentStep++;
    }
  }

  function prevStep() {
    if (currentStep > 0) {
      currentStep--;
    }
  }
</script>

<Navigator
  items={steps}
  activeItem={steps[currentStep]}
  retrieveStatus={getStepStatus}
  itemClickHandler={handleStepClick}
/>

<div style="margin-top: 32px; padding: 24px; border: 1px solid #ddd;">
  <h2>{steps[currentStep].text}</h2>
  <p>步骤 {currentStep + 1} 的内容</p>

  <div style="margin-top: 16px; display: flex; gap: 8px;">
    <button disabled={currentStep === 0} on:click={prevStep}>上一步</button>
    <button disabled={currentStep === steps.length - 1} on:click={nextStep}>下一步</button>
  </div>
</div>
```

### 带警告状态

```svelte
<script>
  import Navigator, { NavItemStatus } from '@ticatec/uniface-element/Navigator';

  let currentStep = 2;
  const warningSteps = [1];

  const steps = [
    { text: '账户' },
    { text: '资料' },
    { text: '设置' },
    { text: '确认' }
  ];

  function getStepStatus(step) {
    const index = steps.indexOf(step);
    if (warningSteps.includes(index)) return NavItemStatus.Warning;
    if (index <= currentStep) return NavItemStatus.Completed;
    return NavItemStatus.NotStart;
  }

  function handleStepClick(step) {
    const index = steps.indexOf(step);
    if (index <= currentStep) {
      currentStep = index;
    }
  }
</script>

<Navigator
  items={steps}
  activeItem={steps[currentStep]}
  retrieveStatus={getStepStatus}
  itemClickHandler={handleStepClick}
/>
```

### 带高亮

```svelte
<script>
  import Navigator, { NavItemStatus } from '@ticatec/uniface-element/Navigator';

  let currentStep = 1;
  let highlightedSteps = [2, 3];

  const steps = [
    { text: '上传' },
    { text: '处理' },
    { text: '验证' },
    { text: '完成' }
  ];

  function getStepStatus(step) {
    const index = steps.indexOf(step);
    if (index < currentStep) return NavItemStatus.Completed;
    if (index === currentStep) return NavItemStatus.Completed;
    return NavItemStatus.NotStart;
  }

  function handleStepClick(step) {
    const index = steps.indexOf(step);
    if (index <= currentStep) {
      currentStep = index;
    }
  }
</script>

<Navigator
  items={steps}
  activeItem={steps[currentStep]}
  highlights={highlightedSteps.map(i => steps[i])}
  retrieveStatus={getStepStatus}
  itemClickHandler={handleStepClick}
/>
```

### 自定义样式

```svelte
<script>
  import Navigator, { NavItemStatus } from '@ticatec/uniface-element/Navigator';

  const steps = [
    { text: '①' },
    { text: '②' },
    { text: '③' },
    { text: '④' }
  ];

  function getStepStatus(step) {
    return NavItemStatus.NotStart;
  }

  function handleStepClick(step) {
    console.log('点击:', step.text);
  }
</script>

<Navigator
  items={steps}
  activeItem={steps[0]}
  retrieveStatus={getStepStatus}
  itemClickHandler={handleStepClick}
  style="background: #f5f5f5; padding: 16px; border-radius: 8px;"
/>
```

### 完整表单向导

```svelte
<script>
  import Navigator, { NavItemStatus } from '@ticatec/uniface-element/Navigator';
  import Button from '@ticatec/uniface-element/Button';

  let currentStep = 0;
  let formData = {
    name: '',
    email: '',
    phone: '',
    address: ''
  };

  const wizardSteps = [
    { text: '个人' },
    { text: '联系' },
    { text: '位置' },
    { text: '审查' }
  ];

  function getStepStatus(step) {
    const index = wizardSteps.indexOf(step);
    if (index < currentStep) return NavItemStatus.Completed;
    if (index === currentStep) return NavItemStatus.Completed;
    return NavItemStatus.NotStart;
  }

  function handleStepClick(step) {
    const index = wizardSteps.indexOf(step);
    if (index <= currentStep) {
      currentStep = index;
    }
  }

  function canProceed() {
    switch(currentStep) {
      case 0: return formData.name.length > 0;
      case 1: return formData.email.length > 0;
      case 2: return formData.address.length > 0;
      default: return true;
    }
  }
</script>

<div style="max-width: 800px; margin: 0 auto; padding: 24px;">
  <Navigator
    items={wizardSteps}
    activeItem={wizardSteps[currentStep]}
    retrieveStatus={getStepStatus}
    itemClickHandler={handleStepClick}
  />

  <div style="margin-top: 32px; padding: 24px; border: 1px solid #ddd; border-radius: 8px;">
    {#if currentStep === 0}
      <h2>个人信息</h2>
      <label>
        姓名:
        <input type="text" bind:value={formData.name} placeholder="请输入姓名" />
      </label>
    {:else if currentStep === 1}
      <h2>联系信息</h2>
      <label>
        邮箱:
        <input type="email" bind:value={formData.email} placeholder="your@email.com" />
      </label>
    {:else if currentStep === 2}
      <h2>位置</h2>
      <label>
        地址:
        <input type="text" bind:value={formData.address} placeholder="您的地址" />
      </label>
    {:else}
      <h2>审查您的信息</h2>
      <pre>{JSON.stringify(formData, null, 2)}</pre>
    {/if}

    <div style="margin-top: 24px; display: flex; justify-content: space-between;">
      <Button
        disabled={currentStep === 0}
        onclick={() => currentStep--}
      >
        上一步
      </Button>

      {#if currentStep < wizardSteps.length - 1}
        <Button
          type="primary"
          disabled={!canProceed()}
          onclick={() => currentStep++}
        >
          下一步
        </Button>
      {:else}
        <Button type="primary" onclick={() => console.log('提交:', formData)}>
          提交
        </Button>
      {/if}
    </div>
  </div>
</div>
```

## 最佳实践

1. **清晰的步骤**: 为每个步骤使用简洁、描述性的文本
2. **状态逻辑**: 根据工作流程实现清晰的状态逻辑
3. **导航控制**: 根据进度控制哪些步骤可点击
4. **视觉反馈**: 使用警告指示问题或需要注意的事项
5. **验证**: 如果当前步骤未完成，阻止继续
6. **进度指示**: 清楚地显示哪个步骤是活动的

## 使用场景

- **多步骤表单**: 将复杂的表单分解为可管理的步骤
- **向导**: 引导用户完成复杂流程
- **入门引导**: 分步用户引导流程
- **结账**: 电子商务结账流程
- **配置**: 多阶段配置工作流

## 无障碍访问

- 键盘导航支持
- 当前步骤的清晰视觉指示器
- 语义化HTML结构
- 屏幕阅读器的ARIA属性