From 2c8f3a3f3489568a24d5d914729d984cd6d1fae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isaque=20B=C3=B6ck?= Date: Wed, 1 Jul 2026 11:16:42 -0300 Subject: [PATCH 01/11] [NO-ISSUE] feat: add InputGroup composition component with Addon sub-component Implements Figma node 3714-10802. Composition pattern with compound API: InputGroup root + InputGroup.Addon sub-component. States driven by data-invalid / data-required attributes (danger border when invalid alone, warning border when invalid + required). Provides InputGroupContextKey via inject/provide so future input primitives can render borderless inside the group in a follow-up PR. --- .specs/input-group.md | 190 ++++++++++++++++++ .../inputs/input-group/InputGroup.stories.js | 171 ++++++++++++++++ packages/webkit/package.json | 3 + .../components/inputs/input-group/index.ts | 4 + .../inputs/input-group/injection-key.ts | 3 + .../input-group-addon/input-group-addon.vue | 22 ++ .../inputs/input-group/input-group.vue | 43 ++++ 7 files changed, 436 insertions(+) create mode 100644 .specs/input-group.md create mode 100644 apps/storybook/src/stories/components/inputs/input-group/InputGroup.stories.js create mode 100644 packages/webkit/src/components/inputs/input-group/index.ts create mode 100644 packages/webkit/src/components/inputs/input-group/injection-key.ts create mode 100644 packages/webkit/src/components/inputs/input-group/input-group-addon/input-group-addon.vue create mode 100644 packages/webkit/src/components/inputs/input-group/input-group.vue diff --git a/.specs/input-group.md b/.specs/input-group.md new file mode 100644 index 00000000..13e56a36 --- /dev/null +++ b/.specs/input-group.md @@ -0,0 +1,190 @@ +--- +name: input-group +category: inputs +structure: composition +status: implemented +spec_version: 1 +figma: + url: https://www.figma.com/design/t97pXRs7xME3SJDs5iZ5RF/Webkit?node-id=3714-10802 + node_id: 3714:10802 +checksum: e848fa74bfc0ed378b64c4e9d59672d2a9c6d2b800bafe95fb2b7ea0f74308f8 +created: 2026-07-01 +last_updated: 2026-07-01 +--- + +# InputGroup — Component Spec + +## Purpose + +Container that flanks an input primitive with optional addons on either side (icon, static text, button), joined by vertical dividers, and reflects validation state on its border. Composed as `` (root) plus `` sub-components on the left, right, or both — the middle input goes in the root's default slot. Distinct from `field-*` components: `InputGroup` styles the input's *edges*; `field-*` wraps label + helper text. + +The root **provides** an injection key (`InputGroupContextKey`) that future revisions of `input-text` (and other input primitives) will `inject` to render borderless inside the group. Until that lands, the middle slot expects a raw `` element styled with `w-full bg-transparent border-0 outline-none focus:ring-0 h-full px-[var(--spacing-md)] text-[color:var(--text-default)]` — this is the canonical middle-slot markup shown in Usage and stories. + +## Usage + +```vue + + + +``` + +Tree-shaking alternative — standalone root + sub-component, no compound `Object.assign` pulled in: + +```vue + + + +``` + +## Sub-components + +- `input-group-addon/input-group-addon.vue` — Left/right addon slot. Position is determined by source order relative to the middle input, not by a prop. Exposes a `default` slot (scope: none) for the addon content (icon, static text, or a `