@agentero/design-system 0.27.1 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/lib/index.d.ts +1 -0
  2. package/lib/index.js +2 -1
  3. package/lib/merge-props.d.ts +42 -0
  4. package/lib/merge-props.js +24 -0
  5. package/mcp/manifests/components.html +1258 -71
  6. package/mcp/manifests/components.json +1033 -9
  7. package/package.json +22 -1
  8. package/src/alert/alert.js +28 -28
  9. package/src/avatar/avatar.js +22 -22
  10. package/src/avatar-group/avatar-group.js +6 -6
  11. package/src/button/button.js +7 -7
  12. package/src/data-table/data-table.js +36 -36
  13. package/src/field/context.d.ts +70 -0
  14. package/src/field/context.js +6 -0
  15. package/src/field/field.d.ts +216 -0
  16. package/src/field/field.js +132 -0
  17. package/src/field/icons.d.ts +9 -0
  18. package/src/field/icons.js +14 -0
  19. package/src/field/index.d.ts +30 -0
  20. package/src/field/index.js +13 -0
  21. package/src/field-text/field-text.d.ts +28 -0
  22. package/src/field-text/field-text.js +26 -0
  23. package/src/field-text/index.d.ts +2 -0
  24. package/src/field-text/index.js +2 -0
  25. package/src/form/form.d.ts +60 -0
  26. package/src/form/form.js +16 -0
  27. package/src/form/index.d.ts +7 -0
  28. package/src/form/index.js +5 -0
  29. package/src/form-text/form-text.d.ts +136 -0
  30. package/src/form-text/form-text.js +40 -0
  31. package/src/form-text/index.d.ts +2 -0
  32. package/src/form-text/index.js +2 -0
  33. package/src/input/context.d.ts +17 -0
  34. package/src/input/context.js +10 -0
  35. package/src/input/index.d.ts +1 -0
  36. package/src/input/index.js +3 -2
  37. package/src/input/input.d.ts +7 -7
  38. package/src/input/input.js +16 -11
  39. package/src/label/context.d.ts +13 -0
  40. package/src/label/context.js +7 -0
  41. package/src/label/index.d.ts +1 -0
  42. package/src/label/index.js +3 -2
  43. package/src/label/label.d.ts +6 -1
  44. package/src/label/label.js +19 -17
  45. package/src/modal/modal.js +23 -23
  46. package/src/progress/progress.js +9 -9
  47. package/src/switch/switch.js +7 -7
  48. package/src/table/table.js +28 -28
  49. package/src/tabs/tabs.js +26 -26
  50. package/src/tag/tag.js +7 -7
@@ -4404,6 +4404,1023 @@
4404
4404
  ],
4405
4405
  "import": "import { Button, DropdownMenu } from \"@agentero/design-system\";"
4406
4406
  },
4407
+ "components-fieldtext": {
4408
+ "id": "components-fieldtext",
4409
+ "name": "FieldText",
4410
+ "path": "./src/field-text/field-text.stories.tsx",
4411
+ "jsDocTags": {
4412
+ "summary": [
4413
+ "Field for a single-line text control, wiring the Input inside it"
4414
+ ],
4415
+ "example": [
4416
+ "<FieldText invalid={!!error} required>\n <Label>Email</Label>\n <Input type=\"email\" />\n <Field.Description>We only use this for policy documents.</Field.Description>\n <Field.Error errors={[error]} />\n</FieldText>"
4417
+ ]
4418
+ },
4419
+ "description": "FieldText is a `Field.Root` for a single-line text control. It provides\n`InputContext`, so the `Input` inside associates itself with the label and\nthe messages and takes `invalid`, `required`, `disabled` and `readOnly` from\nthe field — no `id`, `htmlFor`, `aria-describedby` or `aria-invalid` written\nby hand.\n\nIt knows nothing about form libraries, and its contexts compose: a provider\nnested inside it can extend `InputContext` with `value`, `onChange`, `onBlur`\nand `name`, and `FieldContext` with the errors, as the last story shows.",
4420
+ "summary": "Field for a single-line text control, wiring the Input inside it",
4421
+ "reactComponentMeta": {
4422
+ "displayName": "FieldText",
4423
+ "exportName": "FieldText",
4424
+ "filePath": "/home/runner/work/design-system/design-system/src/field-text/index.ts",
4425
+ "description": "A `Field.Root` for a single-line text control: it provides `InputContext`,\nso the `Input` inside associates itself with the label and the messages and\ntakes `invalid`, `required`, `disabled` and `readOnly` from the field. Every\nother part (`Label`, `Field.Description`, `Field.Error`) works as in any\nfield.\n\nForm-library agnostic, and its contexts compose: a provider nested inside it\ncan extend `InputContext` with `name`, `value`, `onChange`, `onBlur` and\n`ref` to control the `Input`, and `FieldContext` with the errors, on top of\nthe wiring `FieldText` already set.",
4426
+ "jsDocTags": {
4427
+ "summary": [
4428
+ "Field for a single-line text control, wiring the Input inside it"
4429
+ ],
4430
+ "example": [
4431
+ "<FieldText invalid={!!error} required>\n <Label>Email</Label>\n <Input type=\"email\" />\n <Field.Description>We only use this for policy documents.</Field.Description>\n <Field.Error errors={[error]} />\n</FieldText>"
4432
+ ]
4433
+ },
4434
+ "props": {
4435
+ "orientation": {
4436
+ "name": "orientation",
4437
+ "required": false,
4438
+ "type": {
4439
+ "name": "enum",
4440
+ "raw": "\"horizontal\" | \"vertical\" | \"responsive\"",
4441
+ "value": [
4442
+ {
4443
+ "value": "\"horizontal\""
4444
+ },
4445
+ {
4446
+ "value": "\"vertical\""
4447
+ },
4448
+ {
4449
+ "value": "\"responsive\""
4450
+ }
4451
+ ]
4452
+ },
4453
+ "description": "Layout of the field. `vertical` (default) stacks label, control and\nmessages. `horizontal` is one row at every width: the first child fills it\nand the rest keep their natural width, aligned to the right, so the\ncontrols of stacked fields line up. `responsive` stacks below `28rem` and\nbehaves like `horizontal` from there, measured on the field itself, so it\nneeds no particular wrapper. In both, `Field.Content` groups a control with\nits messages, or a label with its description.",
4454
+ "defaultValue": null,
4455
+ "parent": {
4456
+ "name": "FieldRootProps",
4457
+ "fileName": "src/field/field.tsx"
4458
+ },
4459
+ "declarations": [
4460
+ {
4461
+ "name": "TypeLiteral",
4462
+ "fileName": "src/field/field.tsx"
4463
+ }
4464
+ ]
4465
+ },
4466
+ "invalid": {
4467
+ "name": "invalid",
4468
+ "required": false,
4469
+ "type": {
4470
+ "name": "boolean"
4471
+ },
4472
+ "description": "Marks the field as failing validation: sets `data-invalid` on the root and\n`aria-invalid` on the control through its context, which drives the\ncontrol's destructive border. The label keeps its color by design.",
4473
+ "defaultValue": null,
4474
+ "parent": {
4475
+ "name": "FieldRootProps",
4476
+ "fileName": "src/field/field.tsx"
4477
+ },
4478
+ "declarations": [
4479
+ {
4480
+ "name": "TypeLiteral",
4481
+ "fileName": "src/field/field.tsx"
4482
+ }
4483
+ ]
4484
+ },
4485
+ "disabled": {
4486
+ "name": "disabled",
4487
+ "required": false,
4488
+ "type": {
4489
+ "name": "boolean"
4490
+ },
4491
+ "description": "Disables the control through its context and sets `data-disabled` on the root.",
4492
+ "defaultValue": null,
4493
+ "parent": {
4494
+ "name": "FieldRootProps",
4495
+ "fileName": "src/field/field.tsx"
4496
+ },
4497
+ "declarations": [
4498
+ {
4499
+ "name": "TypeLiteral",
4500
+ "fileName": "src/field/field.tsx"
4501
+ }
4502
+ ]
4503
+ },
4504
+ "readOnly": {
4505
+ "name": "readOnly",
4506
+ "required": false,
4507
+ "type": {
4508
+ "name": "boolean"
4509
+ },
4510
+ "description": "Makes the control read-only through its context (focusable and copyable,\nnot editable, still submitted) and sets `data-readonly` on the root.",
4511
+ "defaultValue": null,
4512
+ "parent": {
4513
+ "name": "FieldRootProps",
4514
+ "fileName": "src/field/field.tsx"
4515
+ },
4516
+ "declarations": [
4517
+ {
4518
+ "name": "TypeLiteral",
4519
+ "fileName": "src/field/field.tsx"
4520
+ }
4521
+ ]
4522
+ },
4523
+ "required": {
4524
+ "name": "required",
4525
+ "required": false,
4526
+ "type": {
4527
+ "name": "boolean"
4528
+ },
4529
+ "description": "Single source of truth for a required field: the `Label` shows its\nasterisk and the control receives `required`, both through context.",
4530
+ "defaultValue": null,
4531
+ "parent": {
4532
+ "name": "FieldRootProps",
4533
+ "fileName": "src/field/field.tsx"
4534
+ },
4535
+ "declarations": [
4536
+ {
4537
+ "name": "TypeLiteral",
4538
+ "fileName": "src/field/field.tsx"
4539
+ }
4540
+ ]
4541
+ },
4542
+ "controlId": {
4543
+ "name": "controlId",
4544
+ "required": false,
4545
+ "type": {
4546
+ "name": "string"
4547
+ },
4548
+ "description": "`id` for the control. Generated when omitted. Set it here, not on the\ncontrol, so the label and the messages keep pointing at the right element.",
4549
+ "defaultValue": null,
4550
+ "parent": {
4551
+ "name": "FieldRootProps",
4552
+ "fileName": "src/field/field.tsx"
4553
+ },
4554
+ "declarations": [
4555
+ {
4556
+ "name": "TypeLiteral",
4557
+ "fileName": "src/field/field.tsx"
4558
+ }
4559
+ ]
4560
+ }
4561
+ }
4562
+ },
4563
+ "stories": [
4564
+ {
4565
+ "id": "components-fieldtext--default",
4566
+ "name": "Default",
4567
+ "snippet": "const Default = () => <FieldText\n orientation=\"vertical\"\n invalid={false}\n disabled={false}\n readOnly={false}\n required={false}>\n <Label>Email</Label>\n <Input type=\"email\" placeholder=\"you@example.com\" />\n <Field.Description>We only use this to send policy documents.</Field.Description>\n</FieldText>;",
4568
+ "description": "The composition consumers write: a label, the design system's `Input` and\nhelper text. The label points at the input and the input is described by the\ntext, all through context.",
4569
+ "summary": "Label, Input and description wired with no ids"
4570
+ },
4571
+ {
4572
+ "id": "components-fieldtext--required",
4573
+ "name": "Required",
4574
+ "snippet": "const Required = () => <FieldText\n orientation=\"vertical\"\n invalid={false}\n disabled={false}\n readOnly={false}\n required>\n <Label>Full name</Label>\n <Input placeholder=\"Jane Doe\" />\n</FieldText>;",
4575
+ "description": "`required` on the field reaches both the label's asterisk and the input's\n`required` attribute.",
4576
+ "summary": "Required field driven from the root alone"
4577
+ },
4578
+ {
4579
+ "id": "components-fieldtext--invalid",
4580
+ "name": "Invalid",
4581
+ "snippet": "const Invalid = () => <FieldText\n orientation=\"vertical\"\n invalid\n disabled={false}\n readOnly={false}\n required={false}>\n <Label>Email</Label>\n <Input type=\"email\" defaultValue=\"not-an-email\" />\n <Field.Error errors={[{ message: 'Enter a valid email address.' }]} />\n</FieldText>;",
4582
+ "description": "`invalid` on the field sets `aria-invalid` on the input, which drives its\ndestructive border, and the error is announced with the input.",
4583
+ "summary": "Invalid field with the Input styled by aria-invalid"
4584
+ },
4585
+ {
4586
+ "id": "components-fieldtext--disabled",
4587
+ "name": "Disabled",
4588
+ "snippet": "const Disabled = () => <FieldText\n orientation=\"vertical\"\n invalid={false}\n disabled\n readOnly={false}\n required={false}>\n <Label>Agency</Label>\n <Input defaultValue=\"Acme Insurance\" />\n</FieldText>;",
4589
+ "description": "`disabled` on the field disables the input through context.",
4590
+ "summary": "Disabled field driven from the root"
4591
+ },
4592
+ {
4593
+ "id": "components-fieldtext--read-only",
4594
+ "name": "Read Only",
4595
+ "snippet": "const ReadOnly = () => <FieldText\n orientation=\"vertical\"\n invalid={false}\n disabled={false}\n readOnly\n required={false}>\n <Label>Policy number</Label>\n <Input defaultValue=\"POL-2049-118\" />\n <Field.Description>Assigned by the carrier; contact support to change it.</Field.Description>\n</FieldText>;",
4596
+ "description": "`readOnly` on the field reaches the input through context. The value stays\nfocusable, copyable and submitted, and the input looks like any other.",
4597
+ "summary": "Read-only field driven from the root"
4598
+ },
4599
+ {
4600
+ "id": "components-fieldtext--own-props-win",
4601
+ "name": "Own Props Win",
4602
+ "snippet": "const OwnPropsWin = () => <div className=\"flex flex-col gap-2\">\n <FieldText\n orientation=\"vertical\"\n invalid={false}\n disabled={false}\n readOnly={false}\n required={false}>\n <Label>Website</Label>\n <Input type=\"url\" size=\"lg\" className=\"max-w-xs\" aria-describedby=\"website-hint\" />\n <Field.Description>Include the protocol.</Field.Description>\n </FieldText>\n <p id=\"website-hint\" className=\"text-sm\">Shown on your public profile.\n </p>\n</div>;",
4603
+ "description": "The context is a default, never an override: an extra `aria-describedby` is\nconcatenated with the field's ids, `className` is merged and `size` passes\nthrough untouched.",
4604
+ "summary": "Input's own props merge with, and win over, the field's context"
4605
+ },
4606
+ {
4607
+ "id": "components-fieldtext--controlled-from-context",
4608
+ "name": "Controlled From Context",
4609
+ "snippet": "const ControlledFromContext = () => <ControlledField />;",
4610
+ "description": "The contexts are an extension point: a provider nested in the field adds\n`name`, `value`, `onChange` and `onBlur` to `InputContext`, so a bare\n`<Input />` becomes controlled, and the errors to `FieldContext`, so a bare\n`<Field.Error />` renders them — here with `useState` and no form library.\nThe input's own `onChange` still runs, chained after the provider's.",
4611
+ "summary": "Input controlled and errors supplied from outside the field"
4612
+ }
4613
+ ],
4614
+ "import": "import { Field, FieldContext, FieldText, Input, InputContext, Label } from \"@agentero/design-system\";"
4615
+ },
4616
+ "components-field": {
4617
+ "id": "components-field",
4618
+ "name": "Field.Root",
4619
+ "path": "./src/field/field.stories.tsx",
4620
+ "jsDocTags": {
4621
+ "summary": [
4622
+ "Wraps a label, control, description and error into one field"
4623
+ ],
4624
+ "example": [
4625
+ "<Field.Root invalid={!!error} required>\n <Field.Label>Email</Field.Label>\n <Input type=\"email\" />\n <Field.Description>We only use this for policy documents.</Field.Description>\n <Field.Error errors={[error]} />\n</Field.Root>"
4626
+ ]
4627
+ },
4628
+ "description": "Field lays out a single form field — label, control, helper text and error —\nand wires the accessibility relationships between them. `Field.Root`\ngenerates the ids and shares them through context: `Label` reads\n`LabelContext`, `Field.Description` and `Field.Error` read `FieldContext`,\nand a `Field<X>` such as `FieldText` provides the control's context. Nobody\npasses an `id` by hand.\n\nPresentational and form-library agnostic: pass `invalid` and the error\nmessages from whatever validates the form. Spacing between fields belongs to\n`Field.Group`, never to a margin on the field itself.\n\n`Field.Description` and `Field.Error` register themselves with the root, so\nthe control's `aria-describedby` lists exactly the messages on screen and is\nabsent when there is none.",
4629
+ "summary": "Wraps a label, control, description and error into one field",
4630
+ "reactComponentMeta": {
4631
+ "displayName": "Field.Root",
4632
+ "exportName": "Field",
4633
+ "filePath": "/home/runner/work/design-system/design-system/src/field/index.ts",
4634
+ "description": "Wraps one label, control, description and error into a single field and\nwires the accessibility relationships between them. It generates the ids\nand shares them through context: `Label` reads `LabelContext`,\n`Field.Description` and `Field.Error` read `FieldContext` and register\nthemselves so the control's `aria-describedby` lists exactly the messages on\nscreen, and a `Field<X>` such as `FieldText` provides the control's context so\nthe control associates itself too. Nobody passes an `id` by hand.\n\nPresentational and form-library agnostic: pass `invalid` and the error\nmessages from whatever validates the form. Deliberately not a `role=\"group\"`:\none field is not a set of related controls, and an unnamed group only adds\nscreen-reader verbosity. Real groupings belong to a fieldset with a legend.",
4635
+ "jsDocTags": {
4636
+ "summary": [
4637
+ "Wraps a label, control, description and error into one field"
4638
+ ],
4639
+ "example": [
4640
+ "<Field.Root invalid={!!error} required>\n <Field.Label>Email</Field.Label>\n <Input type=\"email\" />\n <Field.Description>We only use this for policy documents.</Field.Description>\n <Field.Error errors={[error]} />\n</Field.Root>"
4641
+ ]
4642
+ },
4643
+ "props": {
4644
+ "orientation": {
4645
+ "name": "orientation",
4646
+ "required": false,
4647
+ "type": {
4648
+ "name": "enum",
4649
+ "raw": "\"horizontal\" | \"vertical\" | \"responsive\"",
4650
+ "value": [
4651
+ {
4652
+ "value": "\"horizontal\""
4653
+ },
4654
+ {
4655
+ "value": "\"vertical\""
4656
+ },
4657
+ {
4658
+ "value": "\"responsive\""
4659
+ }
4660
+ ]
4661
+ },
4662
+ "description": "Layout of the field. `vertical` (default) stacks label, control and\nmessages. `horizontal` is one row at every width: the first child fills it\nand the rest keep their natural width, aligned to the right, so the\ncontrols of stacked fields line up. `responsive` stacks below `28rem` and\nbehaves like `horizontal` from there, measured on the field itself, so it\nneeds no particular wrapper. In both, `Field.Content` groups a control with\nits messages, or a label with its description.",
4663
+ "defaultValue": {
4664
+ "value": "'vertical'"
4665
+ },
4666
+ "parent": {
4667
+ "name": "FieldRootProps",
4668
+ "fileName": "src/field/field.tsx"
4669
+ },
4670
+ "declarations": [
4671
+ {
4672
+ "name": "TypeLiteral",
4673
+ "fileName": "src/field/field.tsx"
4674
+ }
4675
+ ]
4676
+ },
4677
+ "invalid": {
4678
+ "name": "invalid",
4679
+ "required": false,
4680
+ "type": {
4681
+ "name": "boolean"
4682
+ },
4683
+ "description": "Marks the field as failing validation: sets `data-invalid` on the root and\n`aria-invalid` on the control through its context, which drives the\ncontrol's destructive border. The label keeps its color by design.",
4684
+ "defaultValue": {
4685
+ "value": "false"
4686
+ },
4687
+ "parent": {
4688
+ "name": "FieldRootProps",
4689
+ "fileName": "src/field/field.tsx"
4690
+ },
4691
+ "declarations": [
4692
+ {
4693
+ "name": "TypeLiteral",
4694
+ "fileName": "src/field/field.tsx"
4695
+ }
4696
+ ]
4697
+ },
4698
+ "disabled": {
4699
+ "name": "disabled",
4700
+ "required": false,
4701
+ "type": {
4702
+ "name": "boolean"
4703
+ },
4704
+ "description": "Disables the control through its context and sets `data-disabled` on the root.",
4705
+ "defaultValue": {
4706
+ "value": "false"
4707
+ },
4708
+ "parent": {
4709
+ "name": "FieldRootProps",
4710
+ "fileName": "src/field/field.tsx"
4711
+ },
4712
+ "declarations": [
4713
+ {
4714
+ "name": "TypeLiteral",
4715
+ "fileName": "src/field/field.tsx"
4716
+ }
4717
+ ]
4718
+ },
4719
+ "readOnly": {
4720
+ "name": "readOnly",
4721
+ "required": false,
4722
+ "type": {
4723
+ "name": "boolean"
4724
+ },
4725
+ "description": "Makes the control read-only through its context (focusable and copyable,\nnot editable, still submitted) and sets `data-readonly` on the root.",
4726
+ "defaultValue": {
4727
+ "value": "false"
4728
+ },
4729
+ "parent": {
4730
+ "name": "FieldRootProps",
4731
+ "fileName": "src/field/field.tsx"
4732
+ },
4733
+ "declarations": [
4734
+ {
4735
+ "name": "TypeLiteral",
4736
+ "fileName": "src/field/field.tsx"
4737
+ }
4738
+ ]
4739
+ },
4740
+ "required": {
4741
+ "name": "required",
4742
+ "required": false,
4743
+ "type": {
4744
+ "name": "boolean"
4745
+ },
4746
+ "description": "Single source of truth for a required field: the `Label` shows its\nasterisk and the control receives `required`, both through context.",
4747
+ "defaultValue": {
4748
+ "value": "false"
4749
+ },
4750
+ "parent": {
4751
+ "name": "FieldRootProps",
4752
+ "fileName": "src/field/field.tsx"
4753
+ },
4754
+ "declarations": [
4755
+ {
4756
+ "name": "TypeLiteral",
4757
+ "fileName": "src/field/field.tsx"
4758
+ }
4759
+ ]
4760
+ },
4761
+ "controlId": {
4762
+ "name": "controlId",
4763
+ "required": false,
4764
+ "type": {
4765
+ "name": "string"
4766
+ },
4767
+ "description": "`id` for the control. Generated when omitted. Set it here, not on the\ncontrol, so the label and the messages keep pointing at the right element.",
4768
+ "defaultValue": null,
4769
+ "parent": {
4770
+ "name": "FieldRootProps",
4771
+ "fileName": "src/field/field.tsx"
4772
+ },
4773
+ "declarations": [
4774
+ {
4775
+ "name": "TypeLiteral",
4776
+ "fileName": "src/field/field.tsx"
4777
+ }
4778
+ ]
4779
+ }
4780
+ }
4781
+ },
4782
+ "stories": [
4783
+ {
4784
+ "id": "components-field--default",
4785
+ "name": "Default",
4786
+ "snippet": "const Default = () => <Field.Root\n orientation=\"vertical\"\n invalid={false}\n disabled={false}\n readOnly={false}\n required={false}>\n <Label>Email</Label>\n <DemoInput placeholder=\"you@example.com\" />\n <Field.Description>We only use this to send policy documents.</Field.Description>\n</Field.Root>;",
4787
+ "description": "A vertical field with a label, a control and helper text. The label points\nat the control and the description is referenced by it — neither needed an\nexplicit `id`.",
4788
+ "summary": "Default vertical field with label, control and description"
4789
+ },
4790
+ {
4791
+ "id": "components-field--required",
4792
+ "name": "Required",
4793
+ "snippet": "const Required = () => <Field.Root\n orientation=\"vertical\"\n invalid={false}\n disabled={false}\n readOnly={false}\n required>\n <Label>Full name</Label>\n <DemoInput placeholder=\"Jane Doe\" />\n</Field.Root>;",
4794
+ "description": "`required` on the root is the single source of truth: the label shows its\nasterisk and the control receives `required`, both through context.",
4795
+ "summary": "Required field driven from the root alone"
4796
+ },
4797
+ {
4798
+ "id": "components-field--optional",
4799
+ "name": "Optional",
4800
+ "snippet": "const Optional = () => <Field.Root\n orientation=\"vertical\"\n invalid={false}\n disabled={false}\n readOnly={false}\n required={false}>\n <Label optional>Phone number</Label>\n <DemoInput type=\"tel\" placeholder=\"+1 (555) 000-0000\" />\n</Field.Root>;",
4801
+ "description": "`optional` on the label appends the muted suffix; the control stays\nnon-required.",
4802
+ "summary": "Optional field with the muted label suffix"
4803
+ },
4804
+ {
4805
+ "id": "components-field--with-tooltip",
4806
+ "name": "With Tooltip",
4807
+ "snippet": "const WithTooltip = () => <Field.Root\n orientation=\"vertical\"\n invalid={false}\n disabled={false}\n readOnly={false}\n required>\n <Field.Label tooltip=\"Issued by the IRS to identify your business.\">Tax ID</Field.Label>\n <DemoInput placeholder=\"XX-XXXXXXX\" />\n</Field.Root>;",
4808
+ "description": "`Field.Label` puts an info button beside the caption. It is a sibling of the\n`<label>`, so it keeps its own accessible name, clicking it does not focus\nthe control, and the control's name stays clean. It opens on focus too.",
4809
+ "summary": "Label with a tooltip trigger beside it"
4810
+ },
4811
+ {
4812
+ "id": "components-field--invalid",
4813
+ "name": "Invalid",
4814
+ "snippet": "const Invalid = () => <Field.Root\n orientation=\"vertical\"\n invalid\n disabled={false}\n readOnly={false}\n required={false}>\n <Label>Email</Label>\n <DemoInput type=\"email\" defaultValue=\"not-an-email\" />\n <Field.Error errors={[{ message: 'Enter a valid email address.' }]} />\n</Field.Root>;",
4815
+ "description": "`invalid` on the root sets `data-invalid` for styling and `aria-invalid` on\nthe control, which drives its destructive border; the label keeps its color\nby design. `Field.Error` takes the error objects as they come from a form\nlibrary.",
4816
+ "summary": "Invalid field with a single error message"
4817
+ },
4818
+ {
4819
+ "id": "components-field--multiple-errors",
4820
+ "name": "Multiple Errors",
4821
+ "snippet": "const MultipleErrors = () => <Field.Root\n orientation=\"vertical\"\n invalid\n disabled={false}\n readOnly={false}\n required={false}>\n <Label>Password</Label>\n <DemoInput type=\"password\" defaultValue=\"abc\" />\n <Field.Error\n errors={[\n { message: 'Use at least 8 characters.' },\n { message: 'Include a number.' },\n { message: 'Use at least 8 characters.' }\n ]} />\n</Field.Root>;",
4822
+ "description": "Several errors render as a list, de-duplicated by message.",
4823
+ "summary": "Several errors rendered as a de-duplicated list"
4824
+ },
4825
+ {
4826
+ "id": "components-field--error-with-types",
4827
+ "name": "Error With Types",
4828
+ "snippet": "const ErrorWithTypes = () => <Field.Root\n orientation=\"vertical\"\n invalid\n disabled={false}\n readOnly={false}\n required={false}>\n <Label>Password</Label>\n <DemoInput type=\"password\" defaultValue=\"short\" />\n <Field.Error\n errors={[\n {\n message: 'At least one uppercase letter.',\n types: {\n uppercase: 'At least one uppercase letter.',\n number: 'At least one number.',\n length: ['At least 10 characters.'],\n unnamed: true\n }\n }\n ]} />\n</Field.Root>;",
4829
+ "description": "One error whose `types` lists every rule that failed renders as that same\nlist. A form library fills it when it collects all the failures instead of\nstopping at the first (react-hook-form's `criteriaMode: 'all'`), leaving only\nthe first one in `message`, so the messages take precedence over it. A rule\nthat failed without a message of its own contributes nothing.",
4830
+ "summary": "Every rule a single error collected, rendered as a list"
4831
+ },
4832
+ {
4833
+ "id": "components-field--no-error",
4834
+ "name": "No Error",
4835
+ "snippet": "const NoError = () => <Field.Root\n orientation=\"vertical\"\n invalid={false}\n disabled={false}\n readOnly={false}\n required={false}>\n <Label>Email</Label>\n <DemoInput type=\"email\" />\n <Field.Error errors={[undefined]} />\n</Field.Root>;",
4836
+ "description": "`Field.Error` renders nothing without a message, so it can stay mounted and\nreceive `undefined` entries while the field is valid. With no description\neither, the control carries no `aria-describedby` at all.",
4837
+ "summary": "Error stays mounted and renders nothing while valid"
4838
+ },
4839
+ {
4840
+ "id": "components-field--disabled",
4841
+ "name": "Disabled",
4842
+ "snippet": "const Disabled = () => <Field.Root\n orientation=\"vertical\"\n invalid={false}\n disabled\n readOnly={false}\n required={false}>\n <Label>Agency</Label>\n <DemoInput defaultValue=\"Acme Insurance\" />\n <Field.Description>Managed by your administrator.</Field.Description>\n</Field.Root>;",
4843
+ "description": "`disabled` on the root disables the control through context and sets\n`data-disabled` for styling.",
4844
+ "summary": "Disabled field driven from the root"
4845
+ },
4846
+ {
4847
+ "id": "components-field--read-only",
4848
+ "name": "Read Only",
4849
+ "snippet": "const ReadOnly = () => <Field.Root\n orientation=\"vertical\"\n invalid={false}\n disabled={false}\n readOnly\n required={false}>\n <Label>Policy number</Label>\n <DemoInput defaultValue=\"POL-2049-118\" />\n <Field.Description>Assigned by the carrier; contact support to change it.</Field.Description>\n</Field.Root>;",
4850
+ "description": "`readOnly` on the root makes the control read-only through context and sets\n`data-readonly` for styling. Unlike `disabled`, the value stays focusable,\ncopyable and submitted.",
4851
+ "summary": "Read-only field driven from the root"
4852
+ },
4853
+ {
4854
+ "id": "components-field--horizontal",
4855
+ "name": "Horizontal",
4856
+ "snippet": "const Horizontal = () => (\n <Field.Group className=\"w-[40rem]\">\n <Field.Root orientation=\"horizontal\" data-testid=\"short\">\n <Label>Full name</Label>\n <DemoInput defaultValue=\"Rafa Moro\" className=\"w-72\" />\n </Field.Root>\n\n <Field.Root orientation=\"horizontal\" data-testid=\"long\">\n <Label>Title</Label>\n <Field.Content className=\"w-72\">\n <DemoInput placeholder=\"Software engineer\" />\n <Field.Description>Shown on your public profile.</Field.Description>\n </Field.Content>\n </Field.Root>\n\n <Field.Root orientation=\"horizontal\" data-testid=\"switch\">\n <Field.Content>\n <Label>Auto-renew</Label>\n <Field.Description>Renews the policy automatically before it expires.</Field.Description>\n </Field.Content>\n <DemoInput type=\"checkbox\" className=\"size-5\" />\n </Field.Root>\n\n <div className=\"w-[20rem]\" data-testid=\"narrow\">\n <Field.Root orientation=\"horizontal\">\n <Label>Email</Label>\n <DemoInput type=\"email\" placeholder=\"you@example.com\" className=\"w-40\" />\n </Field.Root>\n </div>\n </Field.Group>\n);",
4857
+ "description": "`horizontal` is one row at every width. The first child fills the row and\neverything after it keeps its natural width, aligned to the right edge, so\nthe controls of stacked fields line up whatever their labels measure. Wrap a\nlabel with its description, or a control with its messages, in\n`Field.Content`. A control sets its own width: `Input` is `w-full`, so it\ngets one here.",
4858
+ "summary": "Horizontal field, one row at every width, controls right-aligned"
4859
+ },
4860
+ {
4861
+ "id": "components-field--responsive",
4862
+ "name": "Responsive",
4863
+ "snippet": "const Responsive = () => (\n <div className=\"flex flex-col gap-8\">\n <div className=\"w-full max-w-[40rem]\" data-testid=\"wide\">\n <Field.Root orientation=\"responsive\">\n <Label>Email</Label>\n <Field.Content className=\"@md/field:w-72\">\n <DemoInput type=\"email\" placeholder=\"you@example.com\" />\n <Field.Description>\n We only use this to send policy documents, and never to contact you about anything\n else.\n </Field.Description>\n </Field.Content>\n </Field.Root>\n </div>\n\n <div className=\"w-full max-w-[20rem]\" data-testid=\"narrow\">\n <Field.Root orientation=\"responsive\">\n <Label>Email</Label>\n <Field.Content>\n <DemoInput type=\"email\" placeholder=\"you@example.com\" />\n <Field.Description>We only use this to send policy documents.</Field.Description>\n </Field.Content>\n </Field.Root>\n </div>\n </div>\n);",
4864
+ "description": "`responsive` stacks the parts below `28rem` and behaves like `horizontal`\nfrom there: first child fills, the rest keep their width on the right. It\nmeasures the field itself, so it needs no particular wrapper. A width that\nshould only apply once horizontal goes behind `@md/field:`.",
4865
+ "summary": "Responsive field that stacks when narrow"
4866
+ },
4867
+ {
4868
+ "id": "components-field--group",
4869
+ "name": "Group",
4870
+ "snippet": "const Group = () => (\n <Field.Group>\n <Field.Root required>\n <Label>Full name</Label>\n <DemoInput placeholder=\"Jane Doe\" />\n </Field.Root>\n\n <Field.Root required invalid>\n <Label>Email</Label>\n <DemoInput type=\"email\" defaultValue=\"not-an-email\" />\n <Field.Error>Enter a valid email address.</Field.Error>\n </Field.Root>\n\n <Field.Root>\n <Label optional>Phone number</Label>\n <DemoInput type=\"tel\" placeholder=\"+1 (555) 000-0000\" />\n </Field.Root>\n </Field.Group>\n);",
4871
+ "description": "`Field.Group` stacks fields and owns the space between them. Each field gets\nits own ids, so several on one page never collide.",
4872
+ "summary": "Several fields stacked in a group"
4873
+ },
4874
+ {
4875
+ "id": "components-field--standalone-outside-field",
4876
+ "name": "Standalone Outside Field",
4877
+ "snippet": "const StandaloneOutsideField = () => (\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"standalone-email\">Email</Label>\n <DemoInput id=\"standalone-email\" type=\"email\" aria-describedby=\"standalone-error\" />\n <Field.Error id=\"standalone-error\">Something went wrong.</Field.Error>\n </div>\n);",
4878
+ "description": "Outside a `Field.Root` every part reads a `null` context and works on its own\nprops alone: `Label` needs its `htmlFor`, `Field.Error` its own `id`.",
4879
+ "summary": "Label and Field.Error used without a Field.Root"
4880
+ },
4881
+ {
4882
+ "id": "components-field--own-props-win",
4883
+ "name": "Own Props Win",
4884
+ "snippet": "const OwnPropsWin = () => (\n <Field.Root>\n <Label htmlFor=\"own-input\">Email</Label>\n <input id=\"own-input\" type=\"email\" className={inputRecipe()} />\n <Field.Description id=\"own-description\">Points wherever you say.</Field.Description>\n </Field.Root>\n);",
4885
+ "description": "A context is a default, never an override: an explicit `htmlFor` or `id` on a\npart wins over what `Field.Root` provides.",
4886
+ "summary": "Explicit props on a part win over the field's context"
4887
+ },
4888
+ {
4889
+ "id": "components-field--errors-from-context",
4890
+ "name": "Errors From Context",
4891
+ "snippet": "const ErrorsFromContext = () => <FieldWithSuppliedErrors />;",
4892
+ "description": "`FieldContext` is an extension point: re-provided under the root with the\nerrors, a bare `<Field.Error />` renders them — here with `useState` and no\nform library. `InputContext` extends the same way with `value`, `onChange`,\n`onBlur` and `name`; see `FieldText`.",
4893
+ "summary": "Errors supplied to a bare Field.Error through context"
4894
+ }
4895
+ ],
4896
+ "import": "import { Field, FieldContext, Label } from \"@agentero/design-system\";"
4897
+ },
4898
+ "components-formtext": {
4899
+ "id": "components-formtext",
4900
+ "name": "FormText",
4901
+ "path": "./src/form-text/form-text.stories.tsx",
4902
+ "jsDocTags": {
4903
+ "summary": [
4904
+ "Label, Input, description and error bound to one react-hook-form field"
4905
+ ],
4906
+ "example": [
4907
+ "<FormText\n name=\"taxId\"\n label=\"Tax ID\"\n tooltip=\"The EIN the IRS issued to the agency.\"\n description=\"Nine digits, with or without the dash.\"\n required\n rules={{ required: 'Enter the tax ID.', pattern: { value: /^\\d{2}-?\\d{7}$/, message: 'Nine digits.' } }}\n inputProps={{ inputMode: 'numeric', autoComplete: 'off' }}\n/>"
4908
+ ]
4909
+ },
4910
+ "description": "FormText is a complete text field bound to one react-hook-form value: label,\n`Input`, helper text and validation error in the standard order, wired\nthrough `useController`. It renders inside a `Form.Root` and needs only a\n`name`; `required`, `invalid` and the error reach the label, the input's\n`aria-*` attributes and the message with no ids written by hand.\n\nIt covers the common case. For another layout — an input with addons, a\ndifferent control, a message rendered elsewhere — compose `useController`\nwith the `FieldText`, `Label`, `Input` and `Field.*` primitives directly.",
4911
+ "summary": "Label, Input, description and error bound to one react-hook-form field",
4912
+ "reactComponentMeta": {
4913
+ "displayName": "FormText",
4914
+ "exportName": "FormText",
4915
+ "filePath": "/home/runner/work/design-system/design-system/src/form-text/index.ts",
4916
+ "description": "A complete text field bound to one react-hook-form value: label, `Input`,\nhelper text and validation error, laid out in the standard order and wired\nthrough `useController`. It renders inside a `Form.Root`, which provides the\nform, and needs only a `name`, which on a typed form must point at a string\n(`FormTextPath`). The `required`, `invalid` and error states\nreach the label, the input's `aria-*` attributes and the message with no\nids written by hand.\n\nUse it for the common case: a labelled single-line input in a form. When\nthe layout is different — an input with addons, another control, a\nmessage rendered elsewhere — compose the primitives yourself:\n`useController` with [FieldText](?path=/docs/components-fieldtext--docs),\n`Label`, `Input`, `Field.Description` and `Field.Error`. `FormText` adds no\nbehaviour of its own over that composition.\n\nErrors come from `useController`'s per-field state, never from\n`formState.errors`, so the message stays fresh under the React Compiler.\nWith `criteriaMode: 'all'` on the form the error carries every rule that\nfailed and `Field.Error` lists them all. An error on an array or object path\n(`error.root`) is not this field's: render a `Field.Error` for it where the\ngroup lives.",
4917
+ "jsDocTags": {
4918
+ "summary": [
4919
+ "Label, Input, description and error bound to one react-hook-form field"
4920
+ ],
4921
+ "example": [
4922
+ "<FormText\n name=\"taxId\"\n label=\"Tax ID\"\n tooltip=\"The EIN the IRS issued to the agency.\"\n description=\"Nine digits, with or without the dash.\"\n required\n rules={{ required: 'Enter the tax ID.', pattern: { value: /^\\d{2}-?\\d{7}$/, message: 'Nine digits.' } }}\n inputProps={{ inputMode: 'numeric', autoComplete: 'off' }}\n/>"
4923
+ ]
4924
+ },
4925
+ "props": {
4926
+ "disabled": {
4927
+ "name": "disabled",
4928
+ "required": false,
4929
+ "type": {
4930
+ "name": "boolean"
4931
+ },
4932
+ "description": "Disables the control through its context and sets `data-disabled` on the root.\nDisables the input and marks the field. Unlike react-hook-form's own\n`disabled` option, the value stays in the submitted data: disabling a\nfield is a presentation decision, not a change to the form's values.",
4933
+ "defaultValue": null,
4934
+ "parent": {
4935
+ "name": "FieldRootProps",
4936
+ "fileName": "src/field/field.tsx"
4937
+ },
4938
+ "declarations": [
4939
+ {
4940
+ "name": "TypeLiteral",
4941
+ "fileName": "src/field/field.tsx"
4942
+ },
4943
+ {
4944
+ "name": "TypeLiteral",
4945
+ "fileName": "src/form-text/form-text.tsx"
4946
+ }
4947
+ ]
4948
+ },
4949
+ "orientation": {
4950
+ "name": "orientation",
4951
+ "required": false,
4952
+ "type": {
4953
+ "name": "enum",
4954
+ "raw": "\"horizontal\" | \"vertical\" | \"responsive\"",
4955
+ "value": [
4956
+ {
4957
+ "value": "\"horizontal\""
4958
+ },
4959
+ {
4960
+ "value": "\"vertical\""
4961
+ },
4962
+ {
4963
+ "value": "\"responsive\""
4964
+ }
4965
+ ]
4966
+ },
4967
+ "description": "Layout of the field. `vertical` (default) stacks label, control and\nmessages. `horizontal` is one row at every width: the first child fills it\nand the rest keep their natural width, aligned to the right, so the\ncontrols of stacked fields line up. `responsive` stacks below `28rem` and\nbehaves like `horizontal` from there, measured on the field itself, so it\nneeds no particular wrapper. In both, `Field.Content` groups a control with\nits messages, or a label with its description.",
4968
+ "defaultValue": null,
4969
+ "parent": {
4970
+ "name": "FieldRootProps",
4971
+ "fileName": "src/field/field.tsx"
4972
+ },
4973
+ "declarations": [
4974
+ {
4975
+ "name": "TypeLiteral",
4976
+ "fileName": "src/field/field.tsx"
4977
+ }
4978
+ ]
4979
+ },
4980
+ "required": {
4981
+ "name": "required",
4982
+ "required": false,
4983
+ "type": {
4984
+ "name": "boolean"
4985
+ },
4986
+ "description": "Single source of truth for a required field: the `Label` shows its\nasterisk and the control receives `required`, both through context.\nMarks the field required: an asterisk on the label and the native\n`required` attribute on the input, which assistive technology announces.\nIt does not validate — pair it with `rules.required` or a resolver — and it\nnever triggers the browser bubble, since `Form.Root` renders `noValidate`.",
4987
+ "defaultValue": null,
4988
+ "parent": {
4989
+ "name": "FieldRootProps",
4990
+ "fileName": "src/field/field.tsx"
4991
+ },
4992
+ "declarations": [
4993
+ {
4994
+ "name": "TypeLiteral",
4995
+ "fileName": "src/field/field.tsx"
4996
+ },
4997
+ {
4998
+ "name": "TypeLiteral",
4999
+ "fileName": "src/form-text/form-text.tsx"
5000
+ }
5001
+ ]
5002
+ },
5003
+ "readOnly": {
5004
+ "name": "readOnly",
5005
+ "required": false,
5006
+ "type": {
5007
+ "name": "boolean"
5008
+ },
5009
+ "description": "Makes the control read-only through its context (focusable and copyable,\nnot editable, still submitted) and sets `data-readonly` on the root.",
5010
+ "defaultValue": null,
5011
+ "parent": {
5012
+ "name": "FieldRootProps",
5013
+ "fileName": "src/field/field.tsx"
5014
+ },
5015
+ "declarations": [
5016
+ {
5017
+ "name": "TypeLiteral",
5018
+ "fileName": "src/field/field.tsx"
5019
+ }
5020
+ ]
5021
+ },
5022
+ "controlId": {
5023
+ "name": "controlId",
5024
+ "required": false,
5025
+ "type": {
5026
+ "name": "string"
5027
+ },
5028
+ "description": "`id` for the control. Generated when omitted. Set it here, not on the\ncontrol, so the label and the messages keep pointing at the right element.",
5029
+ "defaultValue": null,
5030
+ "parent": {
5031
+ "name": "FieldRootProps",
5032
+ "fileName": "src/field/field.tsx"
5033
+ },
5034
+ "declarations": [
5035
+ {
5036
+ "name": "TypeLiteral",
5037
+ "fileName": "src/field/field.tsx"
5038
+ }
5039
+ ]
5040
+ },
5041
+ "name": {
5042
+ "name": "name",
5043
+ "required": true,
5044
+ "type": {
5045
+ "name": "\"agencyName\""
5046
+ },
5047
+ "description": "Path of the value in the form, nested paths included (`'agency.npn'`).\nType it against the form's values with the generic\n(`<FormText<Values> name=\"agency.npn\" />`) or by passing `control`: the\npath must then exist and hold a string (`FormTextPath`).",
5048
+ "defaultValue": null,
5049
+ "parent": {
5050
+ "name": "FormTextProps",
5051
+ "fileName": "src/form-text/form-text.tsx"
5052
+ },
5053
+ "declarations": [
5054
+ {
5055
+ "name": "TypeLiteral",
5056
+ "fileName": "src/form-text/form-text.tsx"
5057
+ }
5058
+ ]
5059
+ },
5060
+ "control": {
5061
+ "name": "control",
5062
+ "required": false,
5063
+ "type": {
5064
+ "name": "Control<FieldValues, any, FieldValues>"
5065
+ },
5066
+ "description": "The form's `control`, from `useForm()`. Defaults to the one the\nsurrounding `Form.Root` provides; pass it explicitly to get `name`\ninference without writing the generic, or when the field renders outside\na `Form.Root`. A `control` whose resolver transforms the values is\naccepted as is.",
5067
+ "defaultValue": null,
5068
+ "parent": {
5069
+ "name": "FormTextProps",
5070
+ "fileName": "src/form-text/form-text.tsx"
5071
+ },
5072
+ "declarations": [
5073
+ {
5074
+ "name": "TypeLiteral",
5075
+ "fileName": "src/form-text/form-text.tsx"
5076
+ }
5077
+ ]
5078
+ },
5079
+ "rules": {
5080
+ "name": "rules",
5081
+ "required": false,
5082
+ "type": {
5083
+ "name": "Omit<RegisterOptions<FieldValues, \"agencyName\">, \"disabled\" | \"valueAsNumber\" | \"valueAsDate\" | \"setValueAs\">"
5084
+ },
5085
+ "description": "react-hook-form validation rules for this field (`required`, `pattern`,\n`validate`…), same as `register`'s. They only validate: `rules.required`\ndoes not mark the field `required` — that is a separate, visible decision.",
5086
+ "defaultValue": null,
5087
+ "parent": {
5088
+ "name": "FormTextProps",
5089
+ "fileName": "src/form-text/form-text.tsx"
5090
+ },
5091
+ "declarations": [
5092
+ {
5093
+ "name": "TypeLiteral",
5094
+ "fileName": "src/form-text/form-text.tsx"
5095
+ }
5096
+ ]
5097
+ },
5098
+ "shouldUnregister": {
5099
+ "name": "shouldUnregister",
5100
+ "required": false,
5101
+ "type": {
5102
+ "name": "boolean"
5103
+ },
5104
+ "description": "Drops the value from the form when the field unmounts, react-hook-form's\n`shouldUnregister`. Defaults to `false`: a field revealed by another one\nkeeps its value while hidden.",
5105
+ "defaultValue": null,
5106
+ "parent": {
5107
+ "name": "FormTextProps",
5108
+ "fileName": "src/form-text/form-text.tsx"
5109
+ },
5110
+ "declarations": [
5111
+ {
5112
+ "name": "TypeLiteral",
5113
+ "fileName": "src/form-text/form-text.tsx"
5114
+ }
5115
+ ]
5116
+ },
5117
+ "label": {
5118
+ "name": "label",
5119
+ "required": true,
5120
+ "type": {
5121
+ "name": "ReactNode"
5122
+ },
5123
+ "description": "The caption, rendered as the field's label. Text in almost every case.",
5124
+ "defaultValue": null,
5125
+ "parent": {
5126
+ "name": "FormTextProps",
5127
+ "fileName": "src/form-text/form-text.tsx"
5128
+ },
5129
+ "declarations": [
5130
+ {
5131
+ "name": "TypeLiteral",
5132
+ "fileName": "src/form-text/form-text.tsx"
5133
+ }
5134
+ ]
5135
+ },
5136
+ "description": {
5137
+ "name": "description",
5138
+ "required": false,
5139
+ "type": {
5140
+ "name": "ReactNode"
5141
+ },
5142
+ "description": "Helper text shown under the control and announced through its\n`aria-describedby`. Use it for guidance the user needs before typing; put\ndetails worth a click in `tooltip` instead.",
5143
+ "defaultValue": null,
5144
+ "parent": {
5145
+ "name": "FormTextProps",
5146
+ "fileName": "src/form-text/form-text.tsx"
5147
+ },
5148
+ "declarations": [
5149
+ {
5150
+ "name": "TypeLiteral",
5151
+ "fileName": "src/form-text/form-text.tsx"
5152
+ }
5153
+ ]
5154
+ },
5155
+ "tooltip": {
5156
+ "name": "tooltip",
5157
+ "required": false,
5158
+ "type": {
5159
+ "name": "ReactNode"
5160
+ },
5161
+ "description": "Content of an info tooltip rendered beside the label, for details that\nwould clutter the description. The trigger is a sibling of the label, so\nthe field's accessible name stays the label text.",
5162
+ "defaultValue": null,
5163
+ "parent": {
5164
+ "name": "FormTextProps",
5165
+ "fileName": "src/form-text/form-text.tsx"
5166
+ },
5167
+ "declarations": [
5168
+ {
5169
+ "name": "TypeLiteral",
5170
+ "fileName": "src/form-text/form-text.tsx"
5171
+ }
5172
+ ]
5173
+ },
5174
+ "tooltipSide": {
5175
+ "name": "tooltipSide",
5176
+ "required": false,
5177
+ "type": {
5178
+ "name": "enum",
5179
+ "raw": "\"right\" | \"top\" | \"bottom\" | \"left\"",
5180
+ "value": [
5181
+ {
5182
+ "value": "\"right\""
5183
+ },
5184
+ {
5185
+ "value": "\"top\""
5186
+ },
5187
+ {
5188
+ "value": "\"bottom\""
5189
+ },
5190
+ {
5191
+ "value": "\"left\""
5192
+ }
5193
+ ]
5194
+ },
5195
+ "description": "Preferred side of the tooltip. Defaults to `'top'`.",
5196
+ "defaultValue": null,
5197
+ "parent": {
5198
+ "name": "FormTextProps",
5199
+ "fileName": "src/form-text/form-text.tsx"
5200
+ },
5201
+ "declarations": [
5202
+ {
5203
+ "name": "TypeLiteral",
5204
+ "fileName": "src/form-text/form-text.tsx"
5205
+ }
5206
+ ]
5207
+ },
5208
+ "optional": {
5209
+ "name": "optional",
5210
+ "required": false,
5211
+ "type": {
5212
+ "name": "boolean"
5213
+ },
5214
+ "description": "Appends a muted \" (optional)\" to the label. The forms mark optional fields\nrather than required ones; ignored when `required` is set.",
5215
+ "defaultValue": null,
5216
+ "parent": {
5217
+ "name": "FormTextProps",
5218
+ "fileName": "src/form-text/form-text.tsx"
5219
+ },
5220
+ "declarations": [
5221
+ {
5222
+ "name": "TypeLiteral",
5223
+ "fileName": "src/form-text/form-text.tsx"
5224
+ }
5225
+ ]
5226
+ },
5227
+ "inputProps": {
5228
+ "name": "inputProps",
5229
+ "required": false,
5230
+ "type": {
5231
+ "name": "FormTextInputProps"
5232
+ },
5233
+ "description": "Everything else the `Input` should receive: `type`, `placeholder`,\n`maxLength`, `autoComplete`, `size`, `className`… Handlers such as\n`onChange` and `onBlur` run after react-hook-form's, which are already\nwired.",
5234
+ "defaultValue": null,
5235
+ "parent": {
5236
+ "name": "FormTextProps",
5237
+ "fileName": "src/form-text/form-text.tsx"
5238
+ },
5239
+ "declarations": [
5240
+ {
5241
+ "name": "TypeLiteral",
5242
+ "fileName": "src/form-text/form-text.tsx"
5243
+ }
5244
+ ]
5245
+ }
5246
+ }
5247
+ },
5248
+ "stories": [
5249
+ {
5250
+ "id": "components-formtext--default",
5251
+ "name": "Default",
5252
+ "snippet": "const Default = () => <AgencyNameForm\n name=\"agencyName\"\n label=\"Agency name\"\n orientation=\"vertical\"\n required\n optional={false}\n disabled={false}\n readOnly={false} />;",
5253
+ "description": "The field consumers write: a `name`, a `label` and the validation rule.\nSubmitting empty renders the error and marks the input invalid; typing\nclears both and the value reaches `onSubmit`.",
5254
+ "summary": "Required text field validating on submit"
5255
+ },
5256
+ {
5257
+ "id": "components-formtext--with-description-and-tooltip",
5258
+ "name": "With Description And Tooltip",
5259
+ "snippet": "const WithDescriptionAndTooltip = () => <TaxIdForm />;",
5260
+ "description": "`description` is helper text under the input, announced through\n`aria-describedby`. `tooltip` is an info button beside the label for details\nworth a click; it is a sibling of the `<label>`, so the field's accessible\nname stays the label text.",
5261
+ "summary": "Helper text under the input and an info tooltip beside the label"
5262
+ },
5263
+ {
5264
+ "id": "components-formtext--optional",
5265
+ "name": "Optional",
5266
+ "snippet": "const Optional = () => <PhoneForm />;",
5267
+ "description": "The forms mark optional fields rather than required ones: `optional`\nappends a muted suffix to the label and leaves the input without the\n`required` attribute.",
5268
+ "summary": "Optional field with the \" (optional)\" label suffix"
5269
+ },
5270
+ {
5271
+ "id": "components-formtext--with-rules",
5272
+ "name": "With Rules",
5273
+ "snippet": "const WithRules = () => <NpnForm />;",
5274
+ "description": "`rules` are react-hook-form's, and `name` accepts nested paths typed against\nthe form's values through the generic. `rules.required` validates but does\nnot mark the field required: that stays an explicit `required` prop.",
5275
+ "summary": "Nested path with validation rules, typed through the generic"
5276
+ },
5277
+ {
5278
+ "id": "components-formtext--all-errors",
5279
+ "name": "All Errors",
5280
+ "snippet": "const AllErrors = () => <PasswordRulesForm />;",
5281
+ "description": "A form set to react-hook-form's `criteriaMode: 'all'` collects every rule\nthat failed instead of stopping at the first, and the field lists them all.\nWith the default `'firstError'` a single message is rendered, as in the other\nstories.",
5282
+ "summary": "Every failed rule listed under criteriaMode 'all'"
5283
+ },
5284
+ {
5285
+ "id": "components-formtext--input-props-chaining",
5286
+ "name": "Input Props Chaining",
5287
+ "snippet": "const InputPropsChaining = () => <MobileForm />;",
5288
+ "description": "`inputProps` carries the input's own attributes — `type`, `placeholder`,\n`maxLength`, `size`… — and its handlers. A consumer `onChange` runs after\nreact-hook-form's: by the time it fires, `getValues` already returns the new\nvalue.",
5289
+ "summary": "Input attributes and a consumer onChange chained after the form's"
5290
+ },
5291
+ {
5292
+ "id": "components-formtext--horizontal",
5293
+ "name": "Horizontal",
5294
+ "snippet": "const Horizontal = () => <ProfileForm />;",
5295
+ "description": "Root props pass through: `orientation=\"horizontal\"` lays the label and the\ncontrol in a row, and `className` on the root or in `inputProps` sizes them.\nThe `Input` is full-width by default, so a settings row gives it a width.\n`responsive` stacks the field below 28rem and rows it from there.",
5296
+ "summary": "Horizontal orientation and class names through the root props"
5297
+ },
5298
+ {
5299
+ "id": "components-formtext--disabled",
5300
+ "name": "Disabled",
5301
+ "snippet": "const Disabled = () => <AccountForm />;",
5302
+ "description": "`disabled` disables the input and marks the field, and the value still\nreaches `onSubmit` — unlike react-hook-form's own `disabled` option, which\ndrops it. Use `readOnly` for a value the user can copy but not edit.",
5303
+ "summary": "Disabled field whose value is still submitted"
5304
+ },
5305
+ {
5306
+ "id": "components-formtext--set-focus",
5307
+ "name": "Set Focus",
5308
+ "snippet": "const SetFocus = () => <SetFocusForm />;",
5309
+ "description": "react-hook-form's `ref` reaches the `<input>`, so `setFocus` and the focus\non the first invalid field after submit both work with no ref written by\nhand.",
5310
+ "summary": "setFocus reaches the input through the merged ref"
5311
+ }
5312
+ ],
5313
+ "import": "import { Button, Field, Form, FormText } from \"@agentero/design-system\";"
5314
+ },
5315
+ "components-form": {
5316
+ "id": "components-form",
5317
+ "name": "Form.Root",
5318
+ "path": "./src/form/form.stories.tsx",
5319
+ "jsDocTags": {
5320
+ "summary": [
5321
+ "Form element bound to a react-hook-form instance, shared with its fields"
5322
+ ],
5323
+ "example": [
5324
+ "const methods = useForm<Values>({ defaultValues: { agencyName: '', email: '' } });\n\n<Form.Root methods={methods} onSubmit={saveAgency} aria-label=\"Agency profile\">\n <FormText name=\"agencyName\" label=\"Agency name\" required rules={{ required: 'Enter the agency name.' }} />\n <FormText name=\"email\" label=\"Email\" inputProps={{ type: 'email' }} />\n <Button type=\"submit\">Save</Button>\n</Form.Root>"
5325
+ ]
5326
+ },
5327
+ "description": "Form is the react-hook-form binding of the design system. `Form.Root` renders\nthe `<form>` and provides the `useForm()` instance to the form fields inside\nit — `FormText` and the other `Form<X>` components — which bind themselves by\n`name`. The submit goes through `handleSubmit`, so `onSubmit` only runs with\nvalid, typed values, and the element is always `noValidate`: validation is\nreact-hook-form's, and the `required` a field sets is announced without the\nbrowser's own bubble.\n\n`react-hook-form` is an optional peer dependency: install it in the app and\nkeep a single copy, since the provider and the fields share one context.",
5328
+ "summary": "Form element bound to a react-hook-form instance, shared with its fields",
5329
+ "reactComponentMeta": {
5330
+ "displayName": "Form.Root",
5331
+ "exportName": "Form",
5332
+ "filePath": "/home/runner/work/design-system/design-system/src/form/index.ts",
5333
+ "description": "The `<form>` element of a react-hook-form form: it provides the `useForm()`\ninstance to the form fields inside it (`FormText` and the other `Form<X>`\ncomponents) and routes the submit through `handleSubmit`. It always renders\n`noValidate`, so the `required` attribute a field sets reaches assistive\ntechnology without the browser's own validation bubble getting in the way:\nvalidation is react-hook-form's, from `rules` or a resolver.\n\nUse it around any form built with the `Form<X>` fields. Without\nreact-hook-form, render a plain `<form>` with the presentational primitives\n([FieldText](?path=/docs/components-fieldtext--docs)) instead — this\ncomponent is only the binding.\n\n`react-hook-form` is an optional peer dependency: the design system never\nbundles its own copy, because `FormProvider` and the fields must share one\nReact context. Two copies in an app (a nested version under a workspace,\nsay) make every field throw from `useController`; `yarn why react-hook-form`\nshould list a single instance.",
5334
+ "jsDocTags": {
5335
+ "summary": [
5336
+ "Form element bound to a react-hook-form instance, shared with its fields"
5337
+ ],
5338
+ "example": [
5339
+ "const methods = useForm<Values>({ defaultValues: { agencyName: '', email: '' } });\n\n<Form.Root methods={methods} onSubmit={saveAgency} aria-label=\"Agency profile\">\n <FormText name=\"agencyName\" label=\"Agency name\" required rules={{ required: 'Enter the agency name.' }} />\n <FormText name=\"email\" label=\"Email\" inputProps={{ type: 'email' }} />\n <Button type=\"submit\">Save</Button>\n</Form.Root>"
5340
+ ]
5341
+ },
5342
+ "props": {
5343
+ "aria-label": {
5344
+ "name": "aria-label",
5345
+ "required": true,
5346
+ "type": {
5347
+ "name": "string"
5348
+ },
5349
+ "description": "Defines a string value that labels the current element.\nAccessible name of the form. A `<form>` only becomes a landmark when it is\nnamed, and screen readers list landmarks by name, so it is required.",
5350
+ "defaultValue": null,
5351
+ "parent": {
5352
+ "name": "AriaAttributes",
5353
+ "fileName": "node_modules/@types/react/index.d.ts"
5354
+ },
5355
+ "declarations": [
5356
+ {
5357
+ "name": "AriaAttributes",
5358
+ "fileName": "node_modules/@types/react/index.d.ts"
5359
+ },
5360
+ {
5361
+ "name": "TypeLiteral",
5362
+ "fileName": "src/form/form.tsx"
5363
+ }
5364
+ ]
5365
+ },
5366
+ "methods": {
5367
+ "name": "methods",
5368
+ "required": true,
5369
+ "type": {
5370
+ "name": "UseFormReturn<AgencyValues, any, AgencyValues>"
5371
+ },
5372
+ "description": "The object `useForm()` returns. `Form.Root` hands it to every form field\ninside through react-hook-form's `FormProvider`, so a `FormText` needs only\nits `name`. Create it in the component that owns the form and pass\n`defaultValues`: a field whose value is `undefined` on the first render\nstarts uncontrolled. A form whose resolver transforms the values\n(`useForm<Input, Context, Output>`) is accepted as is.",
5373
+ "defaultValue": null,
5374
+ "parent": {
5375
+ "name": "FormRootProps",
5376
+ "fileName": "src/form/form.tsx"
5377
+ },
5378
+ "declarations": [
5379
+ {
5380
+ "name": "TypeLiteral",
5381
+ "fileName": "src/form/form.tsx"
5382
+ }
5383
+ ]
5384
+ },
5385
+ "onSubmit": {
5386
+ "name": "onSubmit",
5387
+ "required": false,
5388
+ "type": {
5389
+ "name": "SubmitHandler<AgencyValues>"
5390
+ },
5391
+ "description": "Called with the validated values once validation passes: the resolver's\noutput when it transforms them, the form's values otherwise. Wrapped in\n`methods.handleSubmit`, which prevents the native submit and focuses the\nfirst invalid field; when it is omitted the form validates and does nothing\nelse.",
5392
+ "defaultValue": null,
5393
+ "parent": {
5394
+ "name": "FormRootProps",
5395
+ "fileName": "src/form/form.tsx"
5396
+ },
5397
+ "declarations": [
5398
+ {
5399
+ "name": "TypeLiteral",
5400
+ "fileName": "src/form/form.tsx"
5401
+ }
5402
+ ]
5403
+ }
5404
+ }
5405
+ },
5406
+ "stories": [
5407
+ {
5408
+ "id": "components-form--default",
5409
+ "name": "Default",
5410
+ "snippet": "const Default = () => <AgencyForm />;",
5411
+ "description": "A form with two required fields and a submit button. Submitting empty shows\nboth errors, marks both inputs invalid and focuses the first one — proof that\nreact-hook-form's `ref` reached the inputs. Once filled in, `onSubmit`\nreceives the typed values.",
5412
+ "summary": "Form.Root with FormText fields validating on submit"
5413
+ },
5414
+ {
5415
+ "id": "components-form--no-validate",
5416
+ "name": "No Validate",
5417
+ "snippet": "const NoValidate = () => <NicknameForm />;",
5418
+ "description": "`required` on a field reaches the native attribute, so assistive technology\nannounces it, but the form renders `noValidate`: without `rules`, submitting\nthe field empty is not blocked by the browser and `onSubmit` still runs.\nValidation is react-hook-form's alone.",
5419
+ "summary": "Native required never triggers the browser's validation bubble"
5420
+ }
5421
+ ],
5422
+ "import": "import { Button, Field, Form, FormText } from \"@agentero/design-system\";"
5423
+ },
4407
5424
  "components-hovercard": {
4408
5425
  "id": "components-hovercard",
4409
5426
  "name": "HoverCard.Root",
@@ -4605,23 +5622,23 @@
4605
5622
  "path": "./src/input/input.stories.tsx",
4606
5623
  "jsDocTags": {
4607
5624
  "summary": [
4608
- "Base single-line text control, unaware of fields and form libraries"
5625
+ "Base single-line text control that takes its wiring from InputContext"
4609
5626
  ],
4610
5627
  "example": [
4611
5628
  "<Label htmlFor=\"email\">Email</Label>\n<Input id=\"email\" type=\"email\" placeholder=\"you@example.com\" />",
4612
5629
  "<Input id=\"email\" aria-invalid aria-describedby=\"email-error\" />\n<span id=\"email-error\">Enter a valid email address.</span>"
4613
5630
  ]
4614
5631
  },
4615
- "description": "Input is the base single-line text control. It is intentionally unaware of\nform fields and form libraries: `id`, `aria-invalid` and `aria-describedby`\nare plain props, set by a field wrapper or by hand.\n\nThere is no `status` prop. Mark the control `aria-invalid` and the\ndestructive border follows, so the styling can never disagree with what\nassistive technology announces.",
4616
- "summary": "Base single-line text control, unaware of fields and form libraries",
5632
+ "description": "Input is the base single-line text control. When a container such as\n`FieldText` provides `InputContext`, it picks up `id`, `aria-invalid` and\n`aria-describedby` on its own; standalone, as here, they are plain props set\nby hand.\n\nThere is no `status` prop. Mark the control `aria-invalid` and the\ndestructive border follows, so the styling can never disagree with what\nassistive technology announces.",
5633
+ "summary": "Base single-line text control that takes its wiring from InputContext",
4617
5634
  "reactComponentMeta": {
4618
5635
  "displayName": "Input",
4619
5636
  "exportName": "Input",
4620
5637
  "filePath": "/home/runner/work/design-system/design-system/src/input/input.tsx",
4621
- "description": "Input is the design system's base single-line text control. Reach for it\nwhenever a form collects free text, and pair it with\n[Label](?path=/docs/components-label--docs) so the control has an accessible\nname.\n\nIt is deliberately self-contained: it renders the props it is given and\nknows nothing about form fields, form libraries, or surrounding layout.\nWiring (`id`, `aria-invalid`, `aria-describedby`) arrives as plain props, so\na field wrapper can inject them and standalone usage can set them by hand.\nThere is no `status` prop — mark the control `aria-invalid` and the\ndestructive border follows.\n\nDo not use Input for multi-line text; that is TextArea's job. It also has no\nslots for leading or trailing addons — an input with a currency prefix or a\nunit suffix belongs in an input group, not here.",
5638
+ "description": "Input is the design system's base single-line text control. Reach for it\nwhenever a form collects free text, and pair it with\n[Label](?path=/docs/components-label--docs) so the control has an accessible\nname.\n\nWhen a container provides `InputContext`, the input takes its wiring (`id`,\n`aria-describedby`, `aria-invalid`, `required`, `disabled`, `readOnly`) from\nit with nothing passed by hand; `FieldText` is one such container. Standalone it\nrenders exactly the props it is given, and its own props always win over the\ncontext. There is no `status` prop — mark the control `aria-invalid` and the\ndestructive border follows.\n\nDo not use Input for multi-line text; that is TextArea's job. It also has no\nslots for leading or trailing addons — an input with a currency prefix or a\nunit suffix belongs in an input group, not here.",
4622
5639
  "jsDocTags": {
4623
5640
  "summary": [
4624
- "Base single-line text control, unaware of fields and form libraries"
5641
+ "Base single-line text control that takes its wiring from InputContext"
4625
5642
  ],
4626
5643
  "example": [
4627
5644
  "<Label htmlFor=\"email\">Email</Label>\n<Input id=\"email\" type=\"email\" placeholder=\"you@example.com\" />",
@@ -4885,7 +5902,7 @@
4885
5902
  "displayName": "Label",
4886
5903
  "exportName": "Label",
4887
5904
  "filePath": "/home/runner/work/design-system/design-system/src/label/label.tsx",
4888
- "description": "Accessible caption for a form control, built on Radix's Label primitive so it\nassociates with the control via `htmlFor` and does not select text on\ndouble-click.\n\nKeep it text-only. Nesting an interactive element (a help tooltip trigger, a\nbutton) inside a `<label>` gives that element the label's accessible name and\nmakes a click focus the control — render it as a sibling instead.",
5905
+ "description": "Accessible caption for a form control, built on Radix's Label primitive so it\nassociates with the control via `htmlFor` and does not select text on\ndouble-click.\n\nKeep it text-only. Nesting an interactive element (a help tooltip trigger, a\nbutton) inside a `<label>` gives that element the label's accessible name and\nmakes a click focus the control — render it as a sibling instead.\n\nWhen a container provides `LabelContext`, the label takes `htmlFor` and\n`required` from it and associates itself with the control without an explicit\n`htmlFor`; `Field.Root` is one such container. Standalone it behaves as a\nplain label. Its own props always win over the context.",
4889
5906
  "jsDocTags": {
4890
5907
  "summary": [
4891
5908
  "Accessible caption for a form control"
@@ -4962,7 +5979,7 @@
4962
5979
  {
4963
5980
  "id": "components-label--default",
4964
5981
  "name": "Default",
4965
- "snippet": "const Default = () => <>\n <Label htmlFor=\"email\">Email</Label>\n <input id=\"email\" placeholder=\"you@example.com\" />\n</>;",
5982
+ "snippet": "const Default = () => <>\n <Label htmlFor=\"email\">Email</Label>\n <input id=\"email\" placeholder=\"you@example.com\" className={inputRecipe()} />\n</>;",
4966
5983
  "description": "A plain caption, associated with its control through `htmlFor`.",
4967
5984
  "summary": "Default label associated with a control"
4968
5985
  },
@@ -4986,9 +6003,16 @@
4986
6003
  "snippet": "const RequiredWinsOverOptional = () => <Label optional required>Agency name</Label>;",
4987
6004
  "description": "Contradictory props do not throw — `required` wins and the optional suffix is\ndropped, so a mistake never takes the page down.",
4988
6005
  "summary": "required takes precedence over optional"
6006
+ },
6007
+ {
6008
+ "id": "components-label--inside-field",
6009
+ "name": "Inside Field",
6010
+ "snippet": "const InsideField = () => (\n <div className=\"flex flex-col gap-6\">\n <Field.Root>\n <Label>Email</Label>\n <FieldInput />\n </Field.Root>\n\n <Field.Root>\n <Label htmlFor=\"explicit-control\">Phone</Label>\n <input id=\"explicit-control\" className={inputRecipe()} />\n </Field.Root>\n </div>\n);",
6011
+ "description": "Inside a `Field.Root` the label reads `LabelContext` and points at the\nfield's control with no `htmlFor`. An explicit `htmlFor` still wins.",
6012
+ "summary": "Inside a Field the label associates itself; explicit htmlFor wins"
4989
6013
  }
4990
6014
  ],
4991
- "import": "import { Label } from \"@agentero/design-system\";"
6015
+ "import": "import { Field, Label } from \"@agentero/design-system\";"
4992
6016
  },
4993
6017
  "components-loading": {
4994
6018
  "id": "components-loading",
@@ -7582,6 +8606,6 @@
7582
8606
  },
7583
8607
  "meta": {
7584
8608
  "docgen": "react-component-meta",
7585
- "durationMs": 4717
8609
+ "durationMs": 4273
7586
8610
  }
7587
8611
  }