@openreachtech/furo-vue 1.6.0 → 2.0.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 (119) hide show
  1. package/README.ja.md +2 -0
  2. package/README.md +2 -0
  3. package/docs/design-tokens.md +419 -0
  4. package/docs/furo-accordion.md +109 -0
  5. package/docs/furo-alert-dialog.md +107 -0
  6. package/docs/furo-attachment.md +133 -0
  7. package/docs/furo-autocomplete-field.md +719 -0
  8. package/docs/furo-avatar-group.md +87 -0
  9. package/docs/furo-avatar.md +101 -0
  10. package/docs/furo-badge.md +126 -0
  11. package/docs/furo-breadcrumb.md +89 -0
  12. package/docs/furo-button.md +263 -0
  13. package/docs/furo-checkbox.md +384 -0
  14. package/docs/furo-collapsible.md +104 -0
  15. package/docs/furo-control-block.md +102 -0
  16. package/docs/furo-date-picker.md +270 -0
  17. package/docs/furo-date-time-picker.md +110 -0
  18. package/docs/furo-dialog.md +88 -0
  19. package/docs/furo-drawer.md +122 -0
  20. package/docs/furo-dropdown-menu.md +298 -0
  21. package/docs/furo-editable-field.md +391 -0
  22. package/docs/furo-editor.md +304 -0
  23. package/docs/furo-email-field.md +93 -0
  24. package/docs/furo-empty-state.md +97 -0
  25. package/docs/furo-error-state.md +97 -0
  26. package/docs/furo-file-field.md +163 -0
  27. package/docs/furo-icon.md +288 -0
  28. package/docs/furo-number-field.md +397 -0
  29. package/docs/furo-pagination.md +101 -0
  30. package/docs/furo-password-field.md +75 -0
  31. package/docs/furo-popover.md +114 -0
  32. package/docs/furo-radio.md +125 -0
  33. package/docs/furo-scroll-area.md +112 -0
  34. package/docs/furo-search-field.md +94 -0
  35. package/docs/furo-section-header.md +135 -0
  36. package/docs/furo-select.md +443 -0
  37. package/docs/furo-separator.md +87 -0
  38. package/docs/furo-sidebar.md +178 -0
  39. package/docs/furo-skeleton.md +92 -0
  40. package/docs/furo-splitter.md +103 -0
  41. package/docs/furo-stepper.md +127 -0
  42. package/docs/furo-switch.md +107 -0
  43. package/docs/furo-table.md +233 -0
  44. package/docs/furo-tabs.md +173 -0
  45. package/docs/furo-text-field.md +249 -0
  46. package/docs/furo-textarea.md +214 -0
  47. package/docs/furo-time-field.md +276 -0
  48. package/docs/furo-toast.md +217 -0
  49. package/docs/furo-toggle-group.md +123 -0
  50. package/docs/furo-toggle.md +104 -0
  51. package/docs/furo-tool-bar.md +88 -0
  52. package/docs/furo-tooltip.md +107 -0
  53. package/lib/components/atoms/FuroButton/FuroButtonContext.js +8 -8
  54. package/lib/components/atoms/FuroCheckbox/FuroCheckboxContext.js +1 -1
  55. package/lib/components/atoms/FuroSwitch/FuroSwitchContext.js +1 -1
  56. package/lib/components/atoms/FuroToggle/FuroToggleContext.js +1 -1
  57. package/lib/components/molecules/FuroAccordion/FuroAccordionContext.js +1 -1
  58. package/lib/components/molecules/FuroCollapsible/FuroCollapsibleContext.js +1 -1
  59. package/lib/components/molecules/FuroDropdownMenu/FuroDropdownMenuContext.js +1 -2
  60. package/lib/components/molecules/FuroPopover/FuroPopoverContext.js +1 -1
  61. package/lib/components/molecules/FuroSelect/FuroSelect.vue +8 -6
  62. package/lib/components/molecules/FuroSelect/FuroSelectContext.js +35 -0
  63. package/lib/components/molecules/FuroSelect/FuroSelectOptionText.vue +40 -0
  64. package/lib/components/molecules/FuroSelect/FuroSelectOptionTextContext.js +275 -0
  65. package/lib/components/molecules/FuroSplitter/FuroSplitterContext.js +1 -1
  66. package/lib/components/molecules/FuroToggleGroup/FuroToggleGroupContext.js +1 -1
  67. package/lib/components/molecules/FuroTooltip/FuroTooltipContext.js +1 -1
  68. package/lib/components/organisms/FuroTable/FuroTableContext.js +3 -3
  69. package/lib/components/organisms/FuroToast/FuroToastContext.js +6 -2
  70. package/lib/components/organisms/FuroToast/ToastQueue.js +4 -4
  71. package/nuxt/index.js +9 -9
  72. package/package.json +24 -22
  73. package/public/furo-vue/components.json +1 -1
  74. package/types/generated/components/atoms/FuroAvatar/FuroAvatar.vue.d.ts +6 -15
  75. package/types/generated/components/atoms/FuroBadge/FuroBadge.vue.d.ts +8 -43
  76. package/types/generated/components/atoms/FuroButton/FuroButton.vue.d.ts +10 -45
  77. package/types/generated/components/atoms/FuroButton/FuroButtonContext.d.ts +4 -4
  78. package/types/generated/components/atoms/FuroCheckbox/FuroCheckbox.vue.d.ts +8 -20
  79. package/types/generated/components/atoms/FuroNumberField/FuroNumberField.vue.d.ts +12 -12
  80. package/types/generated/components/atoms/FuroRadio/FuroRadio.vue.d.ts +8 -24
  81. package/types/generated/components/atoms/FuroSwitch/FuroSwitch.vue.d.ts +0 -13
  82. package/types/generated/components/atoms/FuroToggle/FuroToggle.vue.d.ts +8 -19
  83. package/types/generated/components/molecules/FuroAccordion/FuroAccordion.vue.d.ts +14 -30
  84. package/types/generated/components/molecules/FuroAttachment/FuroAttachment.vue.d.ts +8 -44
  85. package/types/generated/components/molecules/FuroAutocompleteField/FuroAutocompleteField.vue.d.ts +74 -105
  86. package/types/generated/components/molecules/FuroAvatarGroup/FuroAvatarGroup.vue.d.ts +9 -18
  87. package/types/generated/components/molecules/FuroBreadcrumb/FuroBreadcrumb.vue.d.ts +22 -48
  88. package/types/generated/components/molecules/FuroCollapsible/FuroCollapsible.vue.d.ts +12 -23
  89. package/types/generated/components/molecules/FuroControlBlock/FuroControlBlock.vue.d.ts +6 -4
  90. package/types/generated/components/molecules/FuroDatePicker/FuroDatePicker.vue.d.ts +14 -16
  91. package/types/generated/components/molecules/FuroDropdownMenu/FuroDropdownMenu.vue.d.ts +13 -13
  92. package/types/generated/components/molecules/FuroDropdownMenu/FuroDropdownMenuOptionRows.vue.d.ts +34 -47
  93. package/types/generated/components/molecules/FuroEditableField/FuroEditableField.vue.d.ts +93 -115
  94. package/types/generated/components/molecules/FuroEmptyState/FuroEmptyState.vue.d.ts +8 -7
  95. package/types/generated/components/molecules/FuroErrorState/FuroErrorState.vue.d.ts +8 -7
  96. package/types/generated/components/molecules/FuroPagination/FuroPagination.vue.d.ts +14 -15
  97. package/types/generated/components/molecules/FuroPopover/FuroPopover.vue.d.ts +8 -7
  98. package/types/generated/components/molecules/FuroScrollArea/FuroScrollArea.vue.d.ts +6 -4
  99. package/types/generated/components/molecules/FuroSearchField/FuroSearchField.vue.d.ts +8 -22
  100. package/types/generated/components/molecules/FuroSectionHeader/FuroSectionHeader.vue.d.ts +10 -25
  101. package/types/generated/components/molecules/FuroSelect/FuroSelect.vue.d.ts +97 -108
  102. package/types/generated/components/molecules/FuroSelect/FuroSelectContext.d.ts +14 -0
  103. package/types/generated/components/molecules/FuroSelect/FuroSelectOptionText.vue.d.ts +52 -0
  104. package/types/generated/components/molecules/FuroSelect/FuroSelectOptionTextContext.d.ts +141 -0
  105. package/types/generated/components/molecules/FuroSplitter/FuroSplitter.vue.d.ts +14 -29
  106. package/types/generated/components/molecules/FuroTimeField/FuroTimeField.vue.d.ts +8 -7
  107. package/types/generated/components/molecules/FuroToggleGroup/FuroToggleGroup.vue.d.ts +9 -24
  108. package/types/generated/components/molecules/FuroToolBar/FuroToolBar.vue.d.ts +6 -9
  109. package/types/generated/components/molecules/FuroTooltip/FuroTooltip.vue.d.ts +8 -7
  110. package/types/generated/components/organisms/FuroAlertDialog/FuroAlertDialog.vue.d.ts +17 -19
  111. package/types/generated/components/organisms/FuroDialog/FuroDialog.vue.d.ts +20 -24
  112. package/types/generated/components/organisms/FuroDrawer/FuroDrawer.vue.d.ts +20 -24
  113. package/types/generated/components/organisms/FuroEditor/FuroEditor.vue.d.ts +9 -42
  114. package/types/generated/components/organisms/FuroSidebar/FuroSidebar.vue.d.ts +23 -62
  115. package/types/generated/components/organisms/FuroStepper/FuroStepper.vue.d.ts +19 -19
  116. package/types/generated/components/organisms/FuroTable/FuroTable.vue.d.ts +54 -71
  117. package/types/generated/components/organisms/FuroTable/FuroTableContext.d.ts +2 -2
  118. package/types/generated/components/organisms/FuroTabs/FuroTabs.vue.d.ts +17 -17
  119. package/types/generated/components/organisms/FuroToast/FuroToast.vue.d.ts +25 -31
@@ -0,0 +1,107 @@
1
+ # FuroAlertDialog
2
+
3
+ Organism — a confirm / destructive overlay built on a headless alert-dialog
4
+ primitive (`Root` + `Portal` + `Overlay` + `Content` + `Title` + `Description` +
5
+ `Action` + `Cancel`). Unlike `FuroDialog`, it forces an explicit decision: there
6
+ is no built-in close button, outside-click never dismisses it, and it ships with
7
+ confirm / cancel action buttons. Domain-agnostic: no GraphQL, router, or Nuxt imports.
8
+
9
+ Location: `lib/components/organisms/FuroAlertDialog/`
10
+
11
+ ## Props
12
+
13
+ | Prop | Type | Default | Notes |
14
+ |------|------|---------|-------|
15
+ | `parcel` | `FuroAlertDialogParcel \| null` | `null` | Reactive behavior object (below) |
16
+
17
+ ### `parcel`
18
+
19
+ | Key | Type | Default | Notes |
20
+ |-----|------|---------|-------|
21
+ | `open` | `boolean` | — | Controlled open state. When set, the parent owns open/close. When omitted, the dialog manages its own state. |
22
+ | `disabled` | `boolean` | `false` | Disables the trigger. |
23
+ | `title` | `string \| null` | `null` | Heading text. Provide a title (or the `title` slot) for accessibility. |
24
+ | `description` | `string \| null` | `null` | Sub-heading text below the title. |
25
+ | `confirmText` | `string` | `'Confirm'` | Label for the built-in confirm button. |
26
+ | `cancelText` | `string` | `'Cancel'` | Label for the built-in cancel button. |
27
+ | `tone` | `'default' \| 'destructive'` | `'default'` | `destructive` renders the confirm button with the destructive variant. |
28
+ | `closeOnEscape` | `boolean` | `true` | `false` ignores the Escape key. |
29
+ | `size` | `'sm' \| 'default' \| 'lg'` | `'default'` | Content width variant. |
30
+ | `busy` | `boolean` | `false` | While `true`, dismissal is blocked and the action buttons are disabled (confirm shows a loading state) — use during async confirm. |
31
+ | `initialFocus` | `string \| null` | `null` | CSS selector (scoped to the content) of the element to focus on open. When unset, the cancel button is focused. |
32
+
33
+ ## Events
34
+
35
+ | Event | Payload | When |
36
+ |-------|---------|------|
37
+ | `confirm` | — | The confirm action was chosen. |
38
+ | `cancel` | — | The cancel action was chosen (button or Escape). |
39
+ | `update:open` | `boolean` | Open state changed — enables `v-model:open`. |
40
+ | `open:change` | `{ open: boolean }` | Open state changed (semantic form). |
41
+
42
+ ## Slots
43
+
44
+ | Slot | Purpose |
45
+ |------|---------|
46
+ | `trigger` | Optional element that opens the dialog. Rendered via `as-child`. Omit when opened via controlled `open`. |
47
+ | `title` | Overrides the heading (falls back to `parcel.title`). |
48
+ | `description` | Overrides the description (falls back to `parcel.description`). |
49
+ | default | Optional body content rendered between the heading and the footer. |
50
+ | `footer` | Overrides the built-in confirm / cancel buttons. Receives `confirm()` and `cancel()` slot props. |
51
+
52
+ ## Usage
53
+
54
+ ### Basic confirm
55
+
56
+ ```vue
57
+ <FuroAlertDialog
58
+ :parcel="{ title: 'Are you sure?', description: 'Confirm to continue.' }"
59
+ @confirm="onConfirm"
60
+ @cancel="onCancel"
61
+ >
62
+ <template #trigger>
63
+ <button type="button">Open confirm</button>
64
+ </template>
65
+ </FuroAlertDialog>
66
+ ```
67
+
68
+ ### Destructive
69
+
70
+ ```vue
71
+ <FuroAlertDialog
72
+ :parcel="{
73
+ title: 'Delete record',
74
+ description: 'This action cannot be undone.',
75
+ tone: 'destructive',
76
+ confirmText: 'Delete',
77
+ }"
78
+ @confirm="deleteRecord"
79
+ >
80
+ <template #trigger>
81
+ <button type="button">Delete…</button>
82
+ </template>
83
+ </FuroAlertDialog>
84
+ ```
85
+
86
+ ### Controlled (`v-model:open`) with async confirm
87
+
88
+ ```vue
89
+ <FuroAlertDialog
90
+ :parcel="{ open: isOpen, title: 'Saving…', busy: isSaving }"
91
+ @confirm="save"
92
+ @open:change="isOpen = $event.open"
93
+ />
94
+ ```
95
+
96
+ While `busy` is `true`, the buttons are disabled and Escape is ignored, so the
97
+ overlay stays open until the parent resolves the async work and clears `open`.
98
+
99
+ ## Notes
100
+
101
+ - The content is portaled to the document body; overlay and content carry
102
+ `unit-alert-dialog-overlay` / `unit-alert-dialog-content` classes inside `@layer furo`.
103
+ - Always provide a title (text or slot) — it is the dialog's accessible name.
104
+ - A description is optional. Without `parcel.description` or a `description` slot the content declares no described-by target, so the headless primitive logs no accessibility warning.
105
+ - Outside-click never dismisses an alert dialog (forced decision). Escape maps to
106
+ `cancel` unless `closeOnEscape` is `false`.
107
+ - Overlay scrim color reuses the `--furo-dialog-overlay-background` component token.
@@ -0,0 +1,133 @@
1
+ # `<FuroAttachment>` Interface Specification
2
+
3
+ ## Overview
4
+
5
+ `<FuroAttachment>` is a **shipped** attachment molecule in the Furo-Vue component system. It renders a file held on a record the same way everywhere: a row carrying the file's name, its size and a type glyph, or the same file as an image preview.
6
+
7
+ It is presentational. It carries no value, takes no primitive from a headless library, and never fetches or deletes anything: its two actions report that they were activated and leave the work to the consumer.
8
+
9
+ **Public SFC prop:** `parcel` only. HTML attributes pass through to the root.
10
+
11
+ ## Summary
12
+
13
+ | Field | Value |
14
+ |---|---|
15
+ | **Layer** | Molecule |
16
+ | **Path** | `lib/components/molecules/FuroAttachment/` |
17
+ | **Base primitive** | None; a `div` holding the glyph or the preview |
18
+ | **Value** | None |
19
+ | **Emits** | `download`, `remove` |
20
+ | **Composes** | `FuroIcon` for the glyph and the spinner, `FuroButton` for the two actions |
21
+
22
+ ## The preview is a variant, not a second component
23
+
24
+ The design draws one Attachment with an image axis. Off, it is a file row with a type glyph. On, it is the same file drawn as a preview. Both are this one component: setting `imageSource` turns the preview on.
25
+
26
+ There is no separate thumbnail component. The reasoning is recorded in [ADR 0034](adr/0034-attachment-absorbs-thumbnail.md): a preview that only ever appears inside an attachment is one state of the attachment rather than a primitive with a contract of its own, and shipping both would leave a consumer choosing between two things the design means as one.
27
+
28
+ The preview always renders at one size and crop, `9rem` square, cropped to fill. Consistency is the point, so it is not a parcel key; an application that has to move it overrides `--furo-attachment-preview-size`.
29
+
30
+ ## A broken preview shows the glyph
31
+
32
+ An image source can rot. When the browser fails to load one, the component falls back to the file row and its type glyph rather than leaving a broken image in the layout, so a dead URL costs the reader the picture and nothing else.
33
+
34
+ The failure is remembered per source. Changing `imageSource` clears it, so a retried upload or a regenerated URL gets a fresh attempt instead of inheriting the previous one's verdict.
35
+
36
+ ## `parcel` keys
37
+
38
+ | Key | Type | Default | Meaning |
39
+ |---|---|---|---|
40
+ | `fileName` | `string` | `''` | Name shown on the row, and the accessible name of the preview when no alternative text is given. |
41
+ | `fileSize` | `string` | `''` | Size shown under the name, already formatted for reading. Hidden while uploading. |
42
+ | `imageSource` | `string` | `null` | Preview source. Setting it turns on the image shape. |
43
+ | `imageAlternativeText` | `string` | the file name | Alternative text for the preview. |
44
+ | `iconName` | `string` | `'ph:file'` | Glyph the row shows in place of a preview. |
45
+ | `uploading` | `boolean` | `false` | Reports the file as still being sent. |
46
+ | `uploadProgress` | `number \| null` | `null` | Share of the upload already sent, nought through one hundred. Values outside the range are clamped. `null` means the size is unknown. |
47
+ | `downloadable` | `boolean` | `true` | Whether the download action renders. |
48
+ | `removable` | `boolean` | `true` | Whether the remove action renders. |
49
+ | `downloadLabel` | `string` | `'Download'` | Accessible name of the download action. |
50
+ | `removeLabel` | `string` | `'Remove'` | Accessible name of the remove action. |
51
+ | `uploadingLabel` | `string` | `'Uploading'` | Accessible name of the upload bar. |
52
+
53
+ The size is taken already formatted rather than as a byte count. Formatting one is a locale decision, and an application that shows sizes anywhere else already owns that decision; taking a number here would give it a second, different answer.
54
+
55
+ ## An upload in flight
56
+
57
+ `uploading` changes what sits under the name and what the actions offer.
58
+
59
+ | Shape | While uploading |
60
+ |---|---|
61
+ | File row | The size caption is replaced by a bar reporting `uploadProgress`. Only the remove action renders, where it cancels. |
62
+ | Preview | The picture is veiled and a spinner replaces both actions. The design reports no share here, because the preview has no room for a bar. |
63
+
64
+ The actions are revealed by hover and by focus once the upload settles, but stay visible throughout an upload: a cancel a reader has to hunt for is not a cancel.
65
+
66
+ ## An upload of unknown size
67
+
68
+ A transport reports how many bytes have left and how many there are in total, but it names the total only once the request announces a computable length. Until then the caller has no denominator and no share to report.
69
+
70
+ Saying so is `uploadProgress: null`, which is also what an absent key means. The bar then drops `aria-valuenow`, which is what makes an ARIA progress bar indeterminate, drops its inline width, and sweeps a partial fill across the track. Assistive technology hears the bar as running with no share, and a reader sees the same.
71
+
72
+ Nought is a share like any other, so `uploadProgress: 0` still draws a measured bar sitting at the start. A caller that means "nothing has left yet" passes `0`; a caller that means "nobody knows" passes `null`.
73
+
74
+ An indeterminate bar carries no number to announce, so the bar takes its accessible name from `uploadingLabel`. The default is `Uploading` and every application overrides it, because the wording is the application's and the language may not be English.
75
+
76
+ Under `prefers-reduced-motion: reduce` the sweep stops. The fill then spans the track at half opacity, which reads as pending rather than as a share, because a partial fill standing still would read as a share it does not have.
77
+
78
+ ## Events
79
+
80
+ | Event | Payload | When |
81
+ |---|---|---|
82
+ | `download` | `{ fileName }` | The download action was activated. |
83
+ | `remove` | `{ fileName }` | The remove action was activated, which cancels an upload in flight. |
84
+
85
+ The payload carries the name so one handler can serve a list of attachments without closing over an index.
86
+
87
+ ## Slots
88
+
89
+ | Slot | Scope | Purpose |
90
+ |---|---|---|
91
+ | `glyph` | — | Replaces the type glyph on the row. Default: the icon named by `iconName`. |
92
+ | `actions` | — | Replaces the whole action cluster. Default: download, remove, and the upload spinner. |
93
+
94
+ ## Styling
95
+
96
+ | Part | Class | Notes |
97
+ |---|---|---|
98
+ | Root | `.unit-attachment` | Gains `.image` while a preview renders and `.uploading` while one is in flight |
99
+ | The glyph | `.glyph` | Only rendered by the default slot content |
100
+ | The text column | `.body` | Holds the name and either the size or the bar |
101
+ | The name | `.name` | |
102
+ | The size | `.caption` | |
103
+ | The bar | `.progress`, `.track`, `.fill` | The track is announced as a progress bar; the fill gains `.indeterminate` while the size is unknown |
104
+ | The preview | `.preview` | Cropped to fill its square |
105
+ | The veil | `.veil` | Hidden from assistive technology |
106
+ | The actions | `.actions`, `.action` | A floating pill on the preview shape, an inline pair on the row |
107
+
108
+ | Custom property | Default | Controls |
109
+ |---|---|---|
110
+ | `--furo-attachment-preview-size` | `9rem` | The side of the preview square |
111
+
112
+ ## Read from the design
113
+
114
+ | Part | Design value | Token |
115
+ |---|---|---|
116
+ | The row's surface | `#f8fafc` | `--color-muted-subtle` |
117
+ | The row's border | `#f1f2f4` | `--color-brand-border-subtle` |
118
+ | The row's corner | `8px` | `--size-border-radius-medium` |
119
+ | The name | `#22252a`, regular 15px/24 | `--color-foreground-title`, `--font-body-large` |
120
+ | The size | `#646c7d`, regular 12px/20 | `--color-foreground-secondary`, `--font-body-small` |
121
+ | The glyph | `#646c7d` | `--color-foreground-secondary` |
122
+ | The bar's track | `#f1f2f4` | `--color-muted` |
123
+ | The bar's fill | `#3b82f6` | `--color-info` |
124
+ | The spinner | `#3b82f6` | `--color-info-text` |
125
+ | The floating pill's surface | `#ffffff` | `--color-background` |
126
+ | The floating pill's border | `#e0e2e6` | `--color-border` |
127
+ | The pill and the action buttons | fully rounded | `--size-border-radius-full` |
128
+ | The gap between glyph, text and actions | `12px` | `--size-space-compact` |
129
+ | The gap between the two actions | `4px` | `--size-space-tiny` |
130
+
131
+ The veil over an uploading preview is drawn in the design as white at eighty percent. It is rendered as `--color-background` at that opacity rather than as a fixed white, so it still veils under a dark theme.
132
+
133
+ The blue the design binds to the bar is its action blue, whose own name in the design is the default surface of that family. The library has no progress role, so the bar takes `--color-info`, the semantic role that already carries that blue. `--color-selected` carries the same value but means "chosen", which a bar reporting an upload is not.