344 lines
18 KiB
Markdown
344 lines
18 KiB
Markdown
|
|
# Filament Inventory List — Screen Specification
|
|||
|
|
|
|||
|
|
> **Screen ID:** FIL-001
|
|||
|
|
> **Source of Truth:** [Material Design 3](https://m3.material.io/)
|
|||
|
|
> **Tone:** Modern Industrial/Maker
|
|||
|
|
> **Theme:** Dark Mode, High-Contrast
|
|||
|
|
> **Last Updated:** 2026-04-20
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. Objective
|
|||
|
|
|
|||
|
|
Provide a single, scannable view of all filament spools in inventory. Users (shop operators) must be able to:
|
|||
|
|
|
|||
|
|
- Rapidly assess stock levels at a glance (which spools are low/critical).
|
|||
|
|
- Search by material type, brand, color, or internal tracking ID.
|
|||
|
|
- Filter by status (Available, In Use, Low Stock, Depleted).
|
|||
|
|
- Navigate to spool detail or initiate the Smart Intake workflow.
|
|||
|
|
|
|||
|
|
This is the **primary landing screen** for both the kiosk and the mobile PWA.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. Screen Inventory
|
|||
|
|
|
|||
|
|
| Element | MD3 Component | Notes |
|
|||
|
|
|---------|--------------|-------|
|
|||
|
|
| Top App Bar | `md-top-app-bar` (medium) | Title + search toggle + intake FAB |
|
|||
|
|
| Search Bar | `md-search-bar` | Expandable on tap; collapses to icon on kiosk |
|
|||
|
|
| Filter Chips | `md-chip-set` (filter) | Status filters: All / Available / In Use / Low / Depleted |
|
|||
|
|
| Inventory List | `md-list` (3-line) | Spool cards as list items |
|
|||
|
|
| Low-Stock Badge | `md-badge` | Tonal badge on list items |
|
|||
|
|
| Extended FAB | `md-fab` (extended) | "Smart Intake" CTA |
|
|||
|
|
| Navigation Rail | `md-navigation-rail` | Kiosk only — Inventory / Printers / Jobs / Settings |
|
|||
|
|
| Bottom Navigation | `md-navigation-bar` | Mobile only — same destinations |
|
|||
|
|
| Empty State | Illustration + `md-text-button` | When no spools match filter |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. Layout Specification
|
|||
|
|
|
|||
|
|
### Title
|
|||
|
|
**"Filament Inventory"** — displayed in the Top App Bar headline slot.
|
|||
|
|
|
|||
|
|
### Sections
|
|||
|
|
|
|||
|
|
#### A. Top App Bar (56dp mobile / 64dp kiosk)
|
|||
|
|
- **Leading:** Menu icon (kiosk) / Back arrow (mobile, if deep-linked)
|
|||
|
|
- **Title:** "Filament Inventory"
|
|||
|
|
- **Trailing actions:** Search icon (toggles search bar), Overflow menu (Sort by, Export)
|
|||
|
|
|
|||
|
|
#### B. Search Bar (0dp collapsed → 56dp expanded)
|
|||
|
|
- Triggered by search icon tap or pull-down gesture on mobile
|
|||
|
|
- Placeholder: "Search spools, brands, colors…"
|
|||
|
|
- Auto-focus on expand; dismiss on back/clear
|
|||
|
|
- Real-time filtering as user types
|
|||
|
|
|
|||
|
|
#### C. Filter Chip Row (52dp height, horizontal scroll)
|
|||
|
|
- Chips: `All` | `Available` | `In Use` | `Low Stock` | `Depleted`
|
|||
|
|
- Default selection: `All`
|
|||
|
|
- Multi-select disabled — single filter active at a time
|
|||
|
|
- Chip styling: Tonal variants per status color
|
|||
|
|
- Available: `green` tonal
|
|||
|
|
- In Use: `blue` tonal (primary)
|
|||
|
|
- Low Stock: `yellow` tonal (warning)
|
|||
|
|
- Depleted: `red` tonal (error)
|
|||
|
|
|
|||
|
|
#### D. Inventory List (flex, scrollable)
|
|||
|
|
- Each item is a **3-line list item** with leading/trailing elements:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌──────────────────────────────────────────────────┐
|
|||
|
|
│ [Color Swatch] PLA Basic - Matte Black │
|
|||
|
|
│ Bambu Lab • Slot A3 • 842g left │
|
|||
|
|
│ ▓▓▓▓▓▓▓▓▓▓░░ 67% [Low] badge │
|
|||
|
|
├──────────────────────────────────────────────────┤
|
|||
|
|
│ [Color Swatch] PETG Basic - Transparent │
|
|||
|
|
│ Polymaker • Shelf B2 • 210g left │
|
|||
|
|
│ ▓▓▓░░░░░░░░░ 21% [Critical] ⚠ │
|
|||
|
|
└──────────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- **Leading:** Circular color swatch (40dp) — matches filament color
|
|||
|
|
- **Line 1:** Material name (MaterialBase + Finish + Modifier) — `titleMedium`, `onSurface`
|
|||
|
|
- **Line 2:** Brand • Location • Remaining weight — `bodyMedium`, `onSurfaceVariant`
|
|||
|
|
- **Line 3:** Linear progress indicator + percentage text — `labelSmall`, `onSurfaceVariant`
|
|||
|
|
- **Trailing:** Status badge (tonal chip) + chevron icon
|
|||
|
|
- **Divider:** Full-width between items
|
|||
|
|
|
|||
|
|
**Sort order (default):** Low stock first, then alphabetical by material name.
|
|||
|
|
|
|||
|
|
#### E. Extended FAB (Bottom-end, mobile; Bottom-end, kiosk)
|
|||
|
|
- Label: **"Smart Intake"** + `qr_code_scanner` icon
|
|||
|
|
- Container: `primaryContainer` color
|
|||
|
|
- On tap → navigates to Smart Intake Scan State
|
|||
|
|
|
|||
|
|
#### F. Navigation (Screen-level)
|
|||
|
|
- **Kiosk:** Navigation Rail on leading edge (80dp wide)
|
|||
|
|
- Destinations: Inventory (active), Printers, Jobs, Settings
|
|||
|
|
- **Mobile:** Bottom Navigation Bar (80dp height)
|
|||
|
|
- Same destinations
|
|||
|
|
|
|||
|
|
### Primary CTA
|
|||
|
|
**Smart Intake** (Extended FAB) — always visible, anchored bottom-end.
|
|||
|
|
|
|||
|
|
### Secondary Actions
|
|||
|
|
- Tap list item → Spool Detail View
|
|||
|
|
- Overflow → Sort options (Name A-Z, Name Z-A, Weight Low→High, Weight High→Low, Recently Used)
|
|||
|
|
- Overflow → Export inventory (CSV)
|
|||
|
|
|
|||
|
|
### Key Components
|
|||
|
|
- Search bar with real-time filtering
|
|||
|
|
- Filter chip set (single-select)
|
|||
|
|
- 3-line list items with progress indicators
|
|||
|
|
- Color swatch leading element
|
|||
|
|
- Status tonal badges
|
|||
|
|
- Extended FAB
|
|||
|
|
|
|||
|
|
### States
|
|||
|
|
| State | Visual |
|
|||
|
|
|-------|--------|
|
|||
|
|
| **Loading** | `md-circular-progress` centered, list skeleton (shimmer) |
|
|||
|
|
| **Empty (no spools)** | Spool icon illustration + "No spools in inventory" + "Add your first spool" text button |
|
|||
|
|
| **Empty (no filter matches)** | "No spools match your filter" + Clear filter chip button |
|
|||
|
|
| **Error** | Error illustration + "Couldn't load inventory" + Retry button |
|
|||
|
|
| **Low Stock item** | Yellow tonal badge "Low" + progress bar < 25% yellow |
|
|||
|
|
| **Critical item** | Red tonal badge "Critical" + progress bar < 10% red + pulsing dot |
|
|||
|
|
| **Depleted item** | Red tonal badge "Depleted" + progress bar 0% + strikethrough title |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. UX Rationale
|
|||
|
|
|
|||
|
|
1. **Progress bars beat numbers alone.** A visual progress indicator communicates remaining spool life faster than parsing "210g / 1000g" — critical in a busy workshop where decisions are made in seconds.
|
|||
|
|
|
|||
|
|
2. **Low stock first (default sort).** Operators need to see what's running out before what's plentiful. This prevents the "surprise empty spool" problem mid-print.
|
|||
|
|
|
|||
|
|
3. **Color swatches as leading elements.** Filament identification is primarily visual — operators scan for color before reading text. The swatch leverages pre-attentive processing.
|
|||
|
|
|
|||
|
|
4. **Single-select filters over multi-select.** Workshop operators don't construct complex queries. They want one quick filter tap. Multi-select adds cognitive load for minimal practical benefit.
|
|||
|
|
|
|||
|
|
5. **Smart Intake FAB, not a menu item.** Intake is the most frequent action (new spools arrive regularly). It deserves the highest-affordance control on screen — a FAB is unmissable.
|
|||
|
|
|
|||
|
|
6. **Search collapses by default.** On kiosk, screen space is precious. The search icon expands the bar only when needed, preserving vertical list space.
|
|||
|
|
|
|||
|
|
7. **Empty states with action.** An empty inventory list should immediately offer the path forward — "Add your first spool" links directly to Smart Intake.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. Visual Direction
|
|||
|
|
|
|||
|
|
### Typography (MD3 Type Scale)
|
|||
|
|
|
|||
|
|
| Role | Token | Size | Weight | Line Height |
|
|||
|
|
|------|-------|------|--------|-------------|
|
|||
|
|
| App Bar Title | `titleLarge` | 22sp | 400 | 28sp |
|
|||
|
|
| List Item Line 1 | `titleMedium` | 16sp | 500 | 24sp |
|
|||
|
|
| List Item Line 2 | `bodyMedium` | 14sp | 400 | 20sp |
|
|||
|
|
| List Item Line 3 | `labelSmall` | 11sp | 500 | 16sp |
|
|||
|
|
| Filter Chip Text | `labelLarge` | 14sp | 500 | 20sp |
|
|||
|
|
| FAB Label | `labelLarge` | 14sp | 500 | 20sp |
|
|||
|
|
| Empty State Title | `headlineSmall` | 24sp | 400 | 32sp |
|
|||
|
|
| Empty State Body | `bodyMedium` | 14sp | 400 | 20sp |
|
|||
|
|
|
|||
|
|
### Spacing (MD3 8dp grid)
|
|||
|
|
|
|||
|
|
| Element | Spacing |
|
|||
|
|
|---------|---------|
|
|||
|
|
| App Bar internal padding | 16dp horizontal, 12dp vertical |
|
|||
|
|
| Filter chip row padding | 16dp horizontal, 8dp vertical |
|
|||
|
|
| Chip gap | 8dp |
|
|||
|
|
| List item padding | 16dp horizontal, 12dp vertical (top/bottom of 3-line) |
|
|||
|
|
| List item internal gap | 16dp (leading to content), 16dp (content to trailing) |
|
|||
|
|
| FAB margin | 16dp from edges |
|
|||
|
|
| Content area padding | 0dp (list is edge-to-edge with dividers) |
|
|||
|
|
|
|||
|
|
### Color (MD3 Dark Theme — "Industrial Maker")
|
|||
|
|
|
|||
|
|
Based on a **blue-grey** primary seed for the industrial feel, with **teal** as secondary (maker accent).
|
|||
|
|
|
|||
|
|
| Role | Token | Value (Dark) | Usage |
|
|||
|
|
|------|-------|-------------|-------|
|
|||
|
|
| Background | `surface` | `#1C1B1F` | Screen background |
|
|||
|
|
| On Background | `onSurface` | `#E6E1E5` | Primary text |
|
|||
|
|
| Surface Variant | `surfaceContainer` | `#211F26` | App bar, list items |
|
|||
|
|
| On Surface Variant | `onSurfaceVariant` | `#CAC4D0` | Secondary text, chip outlines |
|
|||
|
|
| Primary | `primary` | `#A8CEDA` | FAB container, active states |
|
|||
|
|
| On Primary | `onPrimary` | `#00303E` | FAB label text |
|
|||
|
|
| Primary Container | `primaryContainer` | `#004D63` | FAB container (tonal), active chip fill |
|
|||
|
|
| On Primary Container | `onPrimaryContainer` | `#A8CEDA` | Active chip text |
|
|||
|
|
| Secondary | `secondary` | `#B1CCC7` | Navigation rail active icon |
|
|||
|
|
| Tertiary | `tertiary` | `#EFB8C8` | Accent (not used here) |
|
|||
|
|
| Error | `error` | `#F2B8B5` | Depleted badge, critical states |
|
|||
|
|
| Error Container | `errorContainer` | `#8C1D18` | Critical badge background |
|
|||
|
|
| On Error Container | `onErrorContainer` | `#F2B8B5` | Critical badge text |
|
|||
|
|
| **Custom: Warning** | — | `#FFD580` | Low stock indicator |
|
|||
|
|
| **Custom: Warning Container** | — | `#5D4200` | Low stock badge background |
|
|||
|
|
| **Custom: Success** | — | `#8BD0A0` | Available badge text |
|
|||
|
|
| **Custom: Success Container** | — | `#00522E` | Available badge background |
|
|||
|
|
| Outline | `outline` | `#938F99` | Dividers, chip outlines |
|
|||
|
|
| Outline Variant | `outlineVariant` | `#49454F` | Subtle borders |
|
|||
|
|
|
|||
|
|
### Color Swatches
|
|||
|
|
Spool color swatches use the actual filament color as a circular filled element (40dp diameter) with a 2dp `outlineVariant` border for visibility on dark backgrounds. For transparent/clear filaments, use a diagonal hatch pattern fill.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 6. Responsiveness
|
|||
|
|
|
|||
|
|
### Kiosk (800×480, Raspberry Pi 5 Touchscreen)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌──────┬──────────────────────────────────────────────┐
|
|||
|
|
│ NAV │ Filament Inventory [🔍] [⋮] │
|
|||
|
|
│ RAIL │──────────────────────────────────────────────│
|
|||
|
|
│ │ [All] [Available] [In Use] [Low] [Depleted] │
|
|||
|
|
│ 📦 │──────────────────────────────────────────────│
|
|||
|
|
│ 🖨️ │ ● PLA Basic - Matte Black │
|
|||
|
|
│ 📋 │ Bambu Lab • Slot A3 • 842g │
|
|||
|
|
│ ⚙️ │ ▓▓▓▓▓▓▓▓▓▓░░ 67% [Low] │
|
|||
|
|
│ │──────────────────────────────────────────────│
|
|||
|
|
│ │ ● PETG Basic - Transparent │
|
|||
|
|
│ │ Polymaker • Shelf B2 • 210g │
|
|||
|
|
│ │ ▓▓▓░░░░░░░░░ 21% [Critical] │
|
|||
|
|
│ │──────────────────────────────────────────────│
|
|||
|
|
│ │ ● ABS Basic - White │
|
|||
|
|
│ │ eSUN • Slot B1 • 950g │
|
|||
|
|
│ │ ▓▓▓▓▓▓▓▓▓▓▓▓ 95% [Available] │
|
|||
|
|
│ │ [+ Smart │
|
|||
|
|
│ │ Intake] ↗ │
|
|||
|
|
└──────┴──────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- **Navigation Rail:** 80dp wide, pinned left
|
|||
|
|
- **List area:** 720dp × 420dp usable
|
|||
|
|
- **Visible items:** ~4-5 spools without scrolling
|
|||
|
|
- **Touch targets:** All interactive elements ≥ 48dp (exceeds 44dp minimum for workshop glove use)
|
|||
|
|
- **FAB:** Bottom-right, 16dp margin from rail and screen edge
|
|||
|
|
|
|||
|
|
### Mobile PWA (375×812, e.g., iPhone 14)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌──────────────────────────────────┐
|
|||
|
|
│ Filament Inventory [🔍] [⋮] │
|
|||
|
|
│──────────────────────────────────│
|
|||
|
|
│ [All] [Avail] [In Use] [Low] [×]│
|
|||
|
|
│──────────────────────────────────│
|
|||
|
|
│ ● PLA Basic - Matte Black │
|
|||
|
|
│ Bambu Lab • Slot A3 • 842g │
|
|||
|
|
│ ▓▓▓▓▓▓▓▓▓▓░░ 67% [Low] │
|
|||
|
|
│──────────────────────────────────│
|
|||
|
|
│ ● PETG Basic - Transparent │
|
|||
|
|
│ Polymaker • Shelf B2 • 210g │
|
|||
|
|
│ ▓▓▓░░░░░░░░░ 21% [Critical] │
|
|||
|
|
│──────────────────────────────────│
|
|||
|
|
│ ● ABS Basic - White │
|
|||
|
|
│ eSUN • Slot B1 • 950g │
|
|||
|
|
│ ▓▓▓▓▓▓▓▓▓▓▓▓ 95% [Avail] │
|
|||
|
|
│──────────────────────────────────│
|
|||
|
|
│ │
|
|||
|
|
│ [+ Smart Intake] ↗ │
|
|||
|
|
│──────────────────────────────────│
|
|||
|
|
│ 📦 🖨️ 📋 ⚙️ │
|
|||
|
|
│ Inventory Printers Jobs Settings │
|
|||
|
|
└──────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- **Bottom Navigation:** 80dp, pinned bottom
|
|||
|
|
- **List area:** 375dp × ~600dp usable
|
|||
|
|
- **Visible items:** ~5-6 spools without scrolling
|
|||
|
|
- **FAB:** Floating above bottom nav, right-aligned
|
|||
|
|
- **Filter chips:** Horizontally scrollable when more than screen width
|
|||
|
|
|
|||
|
|
### Key Adaptations
|
|||
|
|
| Property | Kiosk (800×480) | Mobile (375×812) |
|
|||
|
|
|----------|-----------------|-------------------|
|
|||
|
|
| Navigation | Rail (left) | Bottom bar |
|
|||
|
|
| Search | Collapsed icon by default | Same, but swipe-down gesture also expands |
|
|||
|
|
| List item density | Comfortable (3-line, 72dp) | Same density |
|
|||
|
|
| FAB position | Bottom-right, above list | Bottom-right, above nav bar |
|
|||
|
|
| Filter chips | All visible at once | Horizontally scrollable |
|
|||
|
|
| Sort access | Overflow menu | Overflow menu |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 7. Developer Handoff Notes
|
|||
|
|
|
|||
|
|
### Angular Material Components
|
|||
|
|
|
|||
|
|
| UI Element | Angular Material Component | Notes |
|
|||
|
|
|-----------|--------------------------|-------|
|
|||
|
|
| Top App Bar | `<mat-toolbar>` | Use `@angular/material/toolbar`. Medium emphasis variant. |
|
|||
|
|
| Search | Custom wrapper + `<input matInput>` | No native mat-search-bar in Angular Material; implement custom expandable search with `@ViewChild` animation. |
|
|||
|
|
| Filter Chips | `<mat-chip-listbox>` | Use `mat-chip-option` with `selected` binding. Single-select: deselect others on select. |
|
|||
|
|
| List Items | `<mat-list>` + `<mat-list-item>` | 3-line variant with `matListItemTitle`, `matListItemLine`, `matListItemMeta`. |
|
|||
|
|
| Progress Bar | `<mat-progress-bar>` | Use `mode="determinate"` with `[value]` binding. Custom color classes for warning/error thresholds. |
|
|||
|
|
| Badge | `<mat-badge>` | Overlay on list items. Use `matBadgeColor` for status colors. |
|
|||
|
|
| Extended FAB | `<button mat-fab extended>` | Use `@angular/material/button`. `extended` attribute for label. |
|
|||
|
|
| Nav Rail | `<mat-sidenav>` styled as rail | No native nav-rail in Angular Material yet; implement as styled sidenav with icon buttons. |
|
|||
|
|
| Bottom Nav | `<mat-bottom-nav>` or custom | Use `<nav mat-tab-nav-bar>` positioned at bottom as a workaround. |
|
|||
|
|
| Empty State | Custom component | Illustration (SVG) + `<button mat-button>`. |
|
|||
|
|
| Loading | `<mat-spinner>` | Use `mode="indeterminate"` centered in list area. |
|
|||
|
|
|
|||
|
|
### Interaction Notes
|
|||
|
|
|
|||
|
|
1. **Search expansion:** Animate height from 0→56dp with `@angular/animations` (`expandCollapse` trigger, 200ms ease-out).
|
|||
|
|
2. **Filter chip selection:** Single-select logic in component — on chip click, set `selectedChip = chip.value`, deselect all others.
|
|||
|
|
3. **List item tap → navigation:** Use `routerLink="/spools/:id"` on each `mat-list-item`.
|
|||
|
|
4. **FAB → Smart Intake:** Navigates to `/intake/scan`.
|
|||
|
|
5. **Progress bar color:** Dynamically set based on percentage:
|
|||
|
|
- ≥ 25%: `primary` (teal-blue)
|
|||
|
|
- 10-24%: Custom `warn-yellow` class
|
|||
|
|
- < 10%: `warn` (red)
|
|||
|
|
6. **Skeleton loading:** Use `@angular/material` skeleton pattern or custom shimmer CSS animation on list items during initial load.
|
|||
|
|
7. **Pull-to-refresh (mobile):** Implement with Angular CDK `@cdk/drag-drop` or a custom gesture handler to refresh inventory data.
|
|||
|
|
8. **Infinite scroll / pagination:** Load 20 spools initially, load more on scroll-to-bottom.
|
|||
|
|
|
|||
|
|
### Accessibility
|
|||
|
|
|
|||
|
|
| Requirement | Implementation |
|
|||
|
|
|-------------|---------------|
|
|||
|
|
| Screen reader | Each list item: `aria-label="PLA Basic Matte Black, Bambu Lab, Slot A3, 842 grams remaining, 67 percent, Low stock"` |
|
|||
|
|
| Color swatch | `aria-label="Color: Matte Black"` + `role="img"` |
|
|||
|
|
| Progress bar | `aria-valuenow`, `aria-valuemin="0"`, `aria-valuemax="100"`, `aria-label="Remaining filament: 67 percent"` |
|
|||
|
|
| Filter chips | `role="listbox"`, each chip `role="option"` + `aria-selected` |
|
|||
|
|
| Search | `role="search"`, `aria-label="Search filament inventory"` |
|
|||
|
|
| FAB | `aria-label="Smart Intake: scan new spool"` |
|
|||
|
|
| Keyboard nav | Tab through list items, Enter to select. Escape to dismiss search. |
|
|||
|
|
| Focus management | On search expand, auto-focus input. On search collapse, return focus to search icon. |
|
|||
|
|
| Motion reduction | Respect `prefers-reduced-motion` — disable shimmer, use opacity fade for loading. |
|
|||
|
|
| Contrast | All text meets WCAG AA (4.5:1) against dark surface. Verified: `onSurface` (#E6E1E5) on `surface` (#1C1B1F) = 11.2:1 ✓ |
|
|||
|
|
|
|||
|
|
### SignalR Integration
|
|||
|
|
|
|||
|
|
- Subscribe to `SpoolUpdated` hub event on screen init.
|
|||
|
|
- On event: update the corresponding list item in-place (no full refresh).
|
|||
|
|
- On `SpoolAdded`: insert at sorted position with highlight animation (300ms `primaryContainer` background flash).
|
|||
|
|
- On `SpoolDepleted`: move to Depleted filter group, show toast notification.
|
|||
|
|
|
|||
|
|
### Performance Notes
|
|||
|
|
|
|||
|
|
- Use `TrackByFunction` on `*ngFor` to prevent full list re-render on updates.
|
|||
|
|
- Virtual scrolling via `<cdk-virtual-scroll-viewport>` if inventory exceeds 100 spools.
|
|||
|
|
- Debounce search input at 300ms.
|