{
  "version": "0.2.0-preview.1",
  "content_digest": "70ac710f4d22dce040e7ac593379ba8aca9dcb59a0b9c0f839819cae0e2bb721",
  "status": "preview",
  "authority": {
    "repository": "cloakedinc/design",
    "path": "packages/design-system",
    "catalog": "packages/design-system/catalog.json",
    "status": "preview"
  },
  "provenance": {
    "repo": "cloakedinc/automation",
    "commit": "f96f416e1c3bfbfaffcd155a88b87b18b8bb25f1",
    "path": "packages/design-system",
    "imported_spec_status": "approved"
  },
  "adaptations": [
    {
      "id": "button-content-gap",
      "status": "preview",
      "description": "Use the specification's 4px content gap instead of the inherited 8px implementation gap."
    },
    {
      "id": "keyboard-focus",
      "status": "preview",
      "description": "Add visible Button and Input keyboard focus and an overridable inset focus default for shared button resets, including FAQ cards and ListItem rows."
    },
    {
      "id": "supporting-text-contrast",
      "status": "preview",
      "description": "Map light secondary text to the existing grey-04-strong primitive for readable helper text on white and cream."
    },
    {
      "id": "danger-text-contrast",
      "status": "preview",
      "description": "Separate readable danger text/borders from destructive fills; preserve the primary danger-button fill and label pair."
    },
    {
      "id": "preview-status",
      "status": "preview",
      "description": "Local components, specs and token adaptations await human sign-off; upstream approved status is provenance only."
    },
    {
      "id": "motion-comparison-accessibility",
      "status": "preview",
      "description": "Preserve the original MotionShowcase comparisons while requiring explicit replay, responding to live reduced-motion changes, and keeping duration tracks usable on small screens."
    },
    {
      "id": "list-item-ownership",
      "status": "preview",
      "description": "List owns listitem wrappers for its content rows, while section labels stay outside the row count and standalone rows retain their existing semantics."
    },
    {
      "id": "card-delta-text-contrast",
      "status": "preview",
      "description": "Mix Card.Delta foregrounds from 60% existing tone solid and 40% primary text for readable contrast in both themes; preserve the four original tone fills."
    },
    {
      "id": "carousel-keyboard-access",
      "status": "preview",
      "description": "Keep all native-scrolling carousel slide controls exposed to assistive technology and keyboard navigation; pause autoplay while focus is inside the carousel."
    }
  ],
  "id": "searchfield",
  "name": "SearchField",
  "category": "Forms",
  "contract_status": "preview",
  "contract_kind": "source-derived",
  "review": {
    "local_status": "not-reviewed",
    "source_approval": null,
    "imported_spec_status": "approved",
    "spec_origin": "imported-adapted",
    "local_spec_source_status": "approved",
    "imported_source_revision": "f96f416e1c3bfbfaffcd155a88b87b18b8bb25f1",
    "note": "Inherited specification status is provenance, not approval of the current local implementation or extracted contract."
  },
  "approval": "required",
  "visual_reference": {
    "stories": [
      {
        "id": "cloaked-design-system-forms-searchfield--playground",
        "name": "Playground",
        "title": "Cloaked Design System/Forms/SearchField",
        "exportName": "Playground",
        "source_path": "packages/design-system/src/components/forms/SearchField/SearchField.stories.tsx",
        "source_digest": "5b8c2dcb590a586aa140e4663e450f2fd74b356f2a01b2ca4f749f9657c19df5",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-forms-searchfield--playground&viewMode=story"
      },
      {
        "id": "cloaked-design-system-forms-searchfield--sizes",
        "name": "Sizes",
        "title": "Cloaked Design System/Forms/SearchField",
        "exportName": "Sizes",
        "source_path": "packages/design-system/src/components/forms/SearchField/SearchField.stories.tsx",
        "source_digest": "5b8c2dcb590a586aa140e4663e450f2fd74b356f2a01b2ca4f749f9657c19df5",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-forms-searchfield--sizes&viewMode=story"
      },
      {
        "id": "cloaked-design-system-forms-searchfield--raised-on-canvas",
        "name": "Raised On Canvas",
        "title": "Cloaked Design System/Forms/SearchField",
        "exportName": "RaisedOnCanvas",
        "source_path": "packages/design-system/src/components/forms/SearchField/SearchField.stories.tsx",
        "source_digest": "5b8c2dcb590a586aa140e4663e450f2fd74b356f2a01b2ca4f749f9657c19df5",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-forms-searchfield--raised-on-canvas&viewMode=story"
      },
      {
        "id": "cloaked-design-system-forms-searchfield--state-matrix",
        "name": "State Matrix",
        "title": "Cloaked Design System/Forms/SearchField",
        "exportName": "StateMatrix",
        "source_path": "packages/design-system/src/components/forms/SearchField/SearchField.stories.tsx",
        "source_digest": "5b8c2dcb590a586aa140e4663e450f2fd74b356f2a01b2ca4f749f9657c19df5",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-forms-searchfield--state-matrix&viewMode=story"
      },
      {
        "id": "cloaked-design-system-forms-searchfield--dark-theme",
        "name": "Dark Theme",
        "title": "Cloaked Design System/Forms/SearchField",
        "exportName": "DarkTheme",
        "source_path": "packages/design-system/src/components/forms/SearchField/SearchField.stories.tsx",
        "source_digest": "5b8c2dcb590a586aa140e4663e450f2fd74b356f2a01b2ca4f749f9657c19df5",
        "status": "preview",
        "local_url": "/storybook/iframe.html?id=cloaked-design-system-forms-searchfield--dark-theme&viewMode=story"
      }
    ],
    "name": "SearchField",
    "id": "searchfield",
    "category": "Forms"
  },
  "stories_source": {
    "path": "packages/design-system/src/components/forms/SearchField/SearchField.stories.tsx",
    "code": "import React, { useState } from 'react';\nimport type { ComponentProps } from 'react';\nimport type { Meta, StoryObj } from '@storybook/react-vite';\nimport { VStack } from '../../layout/VStack/VStack';\nimport { disabledControl, selectArgType } from '../../../storybook/controlOptions';\nimport { SearchField, type SearchFieldSize, type SearchFieldSurface } from './SearchField';\n\nconst SEARCH_FIELD_SIZES = ['sm', 'md'] as const satisfies readonly SearchFieldSize[];\nconst SEARCH_FIELD_SURFACES = ['default', 'raised'] as const satisfies readonly SearchFieldSurface[];\n\nconst meta: Meta<typeof SearchField> = {\n    title: 'Cloaked Design System/Forms/SearchField',\n    component: SearchField,\n    parameters: {\n        a11y: { test: 'error' },\n        stage: 'form-control',\n        docs: {\n            description: {\n                component:\n                    'The search input pattern: a leading search icon, an inline `loading` spinner, and a clear ' +\n                    'action that appears once there is a query. It composes `Input` with `type=\"search\"` and ' +\n                    'defaults autocorrect/autocapitalize/spellcheck off so the field stays quiet. `onSearch` fires ' +\n                    'on the return key (`enterKeyHint` defaults to `search`); `onChange` fires per keystroke. Point ' +\n                    '`ariaControls` at the result list it filters. It is the search primitive inside `Autocomplete`, ' +\n                    'so use `Autocomplete` when you also need a results dropdown.',\n            },\n        },\n    },\n    args: {\n        value: '',\n        size: 'sm',\n        placeholder: 'Search brokers',\n        testId: 'search-field-story',\n    },\n    argTypes: {\n        onChange: { ...disabledControl, description: 'Called with the next query on each edit.' },\n        onSearch: {\n            ...disabledControl,\n            description: 'Called with the current query when the return/search key fires.',\n        },\n        onClear: { ...disabledControl, description: 'Called after the clear action resets the query to empty.' },\n        size: {\n            ...selectArgType(SEARCH_FIELD_SIZES),\n            description: 'Field height tier: `sm` compact vs `md` standard.',\n        },\n        surface: {\n            ...selectArgType(SEARCH_FIELD_SURFACES),\n            description: 'Container background: `default` on a page, `raised` on an already-elevated surface.',\n        },\n        value: { control: 'text', description: 'Current query string.' },\n        placeholder: { control: 'text', description: 'Placeholder shown while the query is empty.' },\n        loading: { control: 'boolean', description: 'Shows the inline trailing spinner while results are fetching.' },\n        disabled: { control: 'boolean', description: 'Blocks typing and clearing.' },\n    },\n};\n\nexport default meta;\n\ntype Story = StoryObj<typeof SearchField>;\n\n/** Controlled wrapper so Storybook accepts typed queries. */\nfunction ControlledSearchField(args: ComponentProps<typeof SearchField>) {\n    const [value, setValue] = useState(args.value);\n    return <SearchField {...args} value={value} onChange={setValue} />;\n}\n\nexport const Playground: Story = {\n    render: args => <ControlledSearchField {...args} />,\n};\n\nexport const Sizes: Story = {\n    parameters: { docs: { description: { story: 'Both `size` tiers: compact `sm` and standard `md`.' } } },\n    render: () => (\n        <VStack gap={16}>\n            <SearchField value='acme' size='sm' placeholder='Small search' testId='search-field-size-sm' />\n            <SearchField value='acme' size='md' placeholder='Medium search' testId='search-field-size-md' />\n        </VStack>\n    ),\n};\n\nexport const RaisedOnCanvas: Story = {\n    parameters: {\n        stage: 'page',\n        docs: {\n            description: {\n                story: 'The `raised` white field on the cream page canvas, where the `default` cream fill would disappear. Every other story shows `default` on the white surface it is built for.',\n            },\n        },\n    },\n    args: {\n        value: 'acme',\n        size: 'md',\n        surface: 'raised',\n        placeholder: 'Raised surface',\n        testId: 'search-field-surface-raised',\n    },\n};\n\nexport const StateMatrix: Story = {\n    parameters: {\n        docs: { description: { story: 'Empty, filled (clear action visible), loading, and disabled states.' } },\n    },\n    render: () => (\n        <VStack gap={16}>\n            <SearchField value='' size='sm' placeholder='Empty search' testId='search-field-matrix-empty' />\n            <SearchField value='acme' size='sm' placeholder='Filled search' testId='search-field-matrix-filled' />\n            <SearchField\n                value='loading'\n                size='sm'\n                loading\n                placeholder='Loading search'\n                testId='search-field-matrix-loading'\n            />\n            <SearchField\n                value='disabled'\n                size='sm'\n                disabled\n                placeholder='Disabled search'\n                testId='search-field-matrix-disabled'\n            />\n        </VStack>\n    ),\n};\n\nexport const DarkTheme: Story = {\n    globals: { theme: 'dark' },\n    parameters: { docs: { description: { story: 'Field, icon, and clear-action tokens on the dark theme.' } } },\n    render: () => (\n        <VStack gap={16}>\n            <SearchField value='acme' size='md' placeholder='Filled search' testId='search-field-dark-filled' />\n            <SearchField\n                value='acme'\n                size='md'\n                surface='raised'\n                placeholder='Raised search'\n                testId='search-field-dark-raised'\n            />\n        </VStack>\n    ),\n};\n"
  },
  "specification": {
    "$schema": "../../../specs/component-spec.schema.json",
    "identity": {
      "name": "SearchField",
      "status": "preview",
      "version": "1.1.0",
      "summary": "A controlled search input with search icon, return-key callback, optional loading indicator, and value-dependent clear action."
    },
    "parts": [
      {
        "id": "control",
        "label": "Control",
        "description": "Input shell that owns size, surface, focus, disabled state, and slots."
      },
      {
        "id": "search-icon",
        "label": "Search icon",
        "description": "Persistent leading icon that communicates search intent."
      },
      {
        "id": "field",
        "label": "Search input",
        "description": "Native search field that owns the controlled query and return-key behavior."
      },
      {
        "id": "loading-indicator",
        "label": "Loading indicator",
        "description": "Optional labelled trailing spinner shown while results update."
      },
      {
        "id": "clear-action",
        "label": "Clear action",
        "description": "Value-dependent trailing button that resets the query."
      }
    ],
    "allowedDesignChoices": {
      "variants": {
        "base": {
          "label": "Base",
          "description": "One search treatment configured through independent size and surface axes."
        }
      },
      "sizes": {
        "sm": {
          "label": "Small"
        },
        "md": {
          "label": "Medium"
        }
      },
      "surfaces": {
        "default": {
          "label": "Default",
          "description": "Uses the semantic input container."
        },
        "raised": {
          "label": "Raised",
          "description": "Uses the raised surface when the field sits directly on the page canvas."
        }
      }
    },
    "variants": [
      {
        "id": "base",
        "label": "Base",
        "description": "Search-specific composition of Input with fixed leading and conditional trailing affordances.",
        "platforms": [
          "ios",
          "android",
          "web"
        ]
      }
    ],
    "sizes": [
      {
        "id": "sm",
        "label": "Small",
        "description": "40-unit compact search field."
      },
      {
        "id": "md",
        "label": "Medium",
        "description": "56-unit standard search field."
      }
    ],
    "measurements": [
      {
        "id": "small-height",
        "label": "Small control height",
        "kind": "exact",
        "token": "--cds-size-40",
        "value": 40,
        "unit": "px",
        "appliesTo": [
          "control",
          "sm"
        ]
      },
      {
        "id": "medium-height",
        "label": "Medium control height",
        "kind": "exact",
        "token": "--cds-size-56",
        "value": 56,
        "unit": "px",
        "appliesTo": [
          "control",
          "md"
        ]
      },
      {
        "id": "web-input-font-size",
        "label": "Web search input font size",
        "kind": "exact",
        "token": "--cds-type-body-size",
        "value": 16,
        "unit": "px",
        "appliesTo": [
          "field",
          "sm",
          "md"
        ],
        "notes": "Web keeps the compact field at the 16px anti-zoom floor."
      }
    ],
    "layout": {
      "alignment": "Search icon, native input, loading indicator, and clear action share the control center line.",
      "flow": "Persistent search icon, flexible input, optional loading indicator, then optional clear action.",
      "notes": [
        "Loading and clear may coexist; each occupies its own trailing slot.",
        "Use Autocomplete when the search field must present selectable results."
      ]
    },
    "typographyAndColor": {
      "typography": [
        {
          "label": "Search query",
          "description": "Use body text on web to prevent focused-input viewport zoom.",
          "token": "--cds-type-body-size"
        }
      ],
      "colors": [
        {
          "label": "Default surface",
          "description": "Use the semantic input container.",
          "token": "--cds-input-container"
        },
        {
          "label": "Raised surface",
          "description": "Use the raised semantic surface.",
          "token": "--cds-bg-surface"
        },
        {
          "label": "Query",
          "description": "Use primary text emphasis.",
          "token": "--cds-text-primary"
        },
        {
          "label": "Placeholder and icons",
          "description": "Use secondary text emphasis.",
          "token": "--cds-text-secondary"
        }
      ]
    },
    "states": [
      {
        "id": "empty",
        "label": "Empty",
        "description": "Shows the placeholder and no clear action."
      },
      {
        "id": "filled",
        "label": "Filled",
        "description": "Shows the controlled query and the clear action."
      },
      {
        "id": "loading",
        "label": "Loading",
        "description": "Shows a labelled trailing spinner while preserving query editing."
      },
      {
        "id": "focused",
        "label": "Focused",
        "description": "Accepts search-key submission; the inherited Input control has no focus ring, since the design system targets a touch surface."
      },
      {
        "id": "disabled",
        "label": "Disabled",
        "description": "Blocks editing and clearing and dims the entire control."
      }
    ],
    "behavior": [
      {
        "label": "Controlled editing",
        "description": "Request query changes on each edit while the parent owns the rendered value."
      },
      {
        "label": "Search return key",
        "description": "Default to callback behavior and a search return-key hint, emitting the current query."
      },
      {
        "label": "Clear",
        "description": "Request an empty query before invoking the optional clear callback."
      },
      {
        "label": "Quiet typing defaults",
        "description": "Default autocorrect, autocapitalization, and spellcheck off for search terms."
      }
    ],
    "accessibility": [
      {
        "label": "Search role and name",
        "description": "Expose native searchbox semantics and require an accessible name."
      },
      {
        "label": "Controlled results",
        "description": "Associate the input with a result container through controls when one exists."
      },
      {
        "label": "Clear action",
        "description": "Name the clear button independently and give it a derived stable test identifier."
      }
    ],
    "contentAdaptation": [
      {
        "label": "Placeholder",
        "description": "Describe what can be searched rather than using generic instructional copy."
      },
      {
        "label": "Long queries",
        "description": "Let the native single-line input scroll horizontally without displacing fixed affordances."
      }
    ],
    "motionHaptics": {
      "motion": [
        {
          "label": "Trailing affordances",
          "description": "Add or remove loading and clear affordances without changing control height."
        }
      ],
      "haptics": [
        {
          "label": "No intrinsic feedback",
          "description": "Typing, search submission, and clearing do not request design-system haptics."
        }
      ]
    },
    "platformDifferences": [
      {
        "platforms": [
          "web"
        ],
        "description": "Small search fields retain a 16px input font instead of the 14px body-small token value.",
        "rationale": "WKWebView zooms focused inputs below 16px; the floor prevents a viewport jump while preserving the compact 40px shell."
      }
    ]
  },
  "specification_source": "packages/design-system/src/components/forms/SearchField/SearchField.spec.json",
  "guidance": {
    "summary": "A controlled search input with search icon, return-key callback, optional loading indicator, and value-dependent clear action.",
    "guidance": [
      {
        "heading": "Overview",
        "body": "A dedicated search input — a leading search icon, an inline `loading` spinner, and a clear\naction that appears once there is a query."
      },
      {
        "heading": "When to use",
        "body": "Reach for `SearchField` when the control's whole job is to filter or query — a broker search,\na website picker, a list filter. It composes `Input` with `type=\"search\"`, defaults\nautocorrect/autocapitalize/spellcheck off so the field stays quiet, fires `onSearch` on the\nreturn key, and gives you the clear affordance for free.\n\n-   Just need a **single-line text value** (email, name, a bare `type=\"search\"` box) with no clear\n    button or search-key semantics? Use `Input` directly.\n-   Need the query to also **drive a results dropdown** the user picks from? Use `Autocomplete` —\n    `SearchField` is the search primitive inside it, so don't rebuild the dropdown around a bare\n    `SearchField`.\n\nIn-app it backs the automations website search (`WebsiteSearchView`) and the add-to-dashboard\npicker (`AddToDashboardBottomSheet`)."
      }
    ],
    "usage": [],
    "examples": [],
    "source": "packages/design-system/src/components/forms/SearchField/SearchField.mdx",
    "status": "local-preview",
    "note": "Guidance is read from local documentation, originally imported from the frozen source. Platform assertions in guidance are not parity verification."
  },
  "links": {
    "human": "/component-searchfield",
    "json": "/data/visual/components/searchfield.json",
    "storybook": "/storybook/?path=/story/cloaked-design-system-forms-searchfield--playground"
  }
}
