@birdycom/omniaui 0.11.0 → 0.11.2

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 (214) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +21 -21
  3. package/bin/lib/add.mjs +126 -126
  4. package/bin/lib/catalog.mjs +169 -169
  5. package/bin/lib/project.mjs +90 -90
  6. package/bin/omniaui.mjs +69 -69
  7. package/dist/code-block.css +25 -25
  8. package/dist/components-extra.css +916 -914
  9. package/dist/components.css +6565 -6469
  10. package/dist/components.min.css +1 -1
  11. package/dist/data-table.d.ts +9 -9
  12. package/dist/data-table.js +505 -505
  13. package/dist/docs-ui.css +267 -265
  14. package/dist/oc-theme.css +69 -69
  15. package/dist/parts/app-accordion-accent.css +60 -60
  16. package/dist/parts/app-alpha-tabs.css +68 -68
  17. package/dist/parts/app-busy-overlay.css +25 -25
  18. package/dist/parts/app-column-menu.css +85 -85
  19. package/dist/parts/app-confirm-dialog.css +70 -70
  20. package/dist/parts/app-cookie-consent.css +63 -63
  21. package/dist/parts/app-data-table.css +174 -174
  22. package/dist/parts/app-greeting.css +47 -47
  23. package/dist/parts/app-list-toolbar.css +81 -81
  24. package/dist/parts/app-page-header.css +54 -54
  25. package/dist/parts/app-severity-card.css +91 -91
  26. package/dist/parts/app-sidebar-dark.css +15 -15
  27. package/dist/parts/app-sortable-row.css +52 -52
  28. package/dist/parts/app-stat-card.css +68 -68
  29. package/dist/parts/app-table-actions.css +71 -71
  30. package/dist/parts/app-table-compact.css +54 -54
  31. package/dist/parts/app-top-progress.css +68 -68
  32. package/dist/parts/app-tree.css +104 -104
  33. package/dist/parts/app-upgrade-banner.css +90 -90
  34. package/dist/parts/app-version-banner.css +80 -80
  35. package/dist/parts/data-chart-line.css +167 -167
  36. package/dist/parts/forms-affix-input.css +75 -75
  37. package/dist/parts/forms-barcode-input.css +75 -75
  38. package/dist/parts/forms-chip-filter.css +91 -91
  39. package/dist/parts/forms-color-select.css +97 -89
  40. package/dist/parts/forms-decimal-input.css +51 -51
  41. package/dist/parts/forms-filter-counts.css +94 -94
  42. package/dist/parts/forms-language-select.css +89 -76
  43. package/dist/parts/forms-number-input.css +98 -95
  44. package/dist/parts/forms-password-requirements.css +55 -55
  45. package/dist/parts/forms-phone-input.css +85 -85
  46. package/dist/parts/forms-time-input.css +74 -74
  47. package/dist/parts/forms-toggle-field.css +69 -69
  48. package/dist/parts/media-art.css +21 -21
  49. package/dist/parts/media-attachment.css +160 -160
  50. package/dist/parts/media-browser-frame.css +73 -73
  51. package/dist/parts/media-card.css +83 -83
  52. package/dist/parts/media-chat-composer.css +90 -90
  53. package/dist/parts/media-doc-viewer.css +151 -151
  54. package/dist/parts/media-emoji-picker.css +88 -88
  55. package/dist/parts/media-entity-card.css +52 -52
  56. package/dist/parts/media-flip-card.css +78 -78
  57. package/dist/parts/media-image-zoom.css +68 -68
  58. package/dist/parts/media-lightbox.css +131 -131
  59. package/dist/parts/media-message-thread.css +136 -136
  60. package/dist/parts/media-message.css +160 -160
  61. package/dist/parts/media-row.css +78 -78
  62. package/dist/parts/media-stack-card.css +82 -82
  63. package/dist/parts/media-terminal-log.css +76 -76
  64. package/dist/parts/media-thumb.css +71 -71
  65. package/dist/parts/site-fact-list.css +25 -25
  66. package/dist/parts/site-link-arrow.css +34 -34
  67. package/dist/parts/site-marquee.css +34 -34
  68. package/dist/parts/site-next-teaser.css +75 -75
  69. package/dist/parts/site-price-card.css +91 -75
  70. package/dist/parts/site-product-mark.css +66 -66
  71. package/dist/parts/site-project-card.css +111 -111
  72. package/dist/parts/site-prose.css +124 -124
  73. package/dist/parts/site-stack-list.css +48 -48
  74. package/dist/parts/site-timeline.css +54 -54
  75. package/dist/showcase.css +410 -404
  76. package/package.json +69 -69
  77. package/snippets/accordion-accent.html +24 -24
  78. package/snippets/accordion.html +11 -11
  79. package/snippets/affix-input.html +30 -30
  80. package/snippets/alert-dialog.html +22 -22
  81. package/snippets/alert.html +5 -5
  82. package/snippets/alpha-tabs.html +37 -37
  83. package/snippets/aspect-ratio.html +15 -15
  84. package/snippets/attachment.html +43 -43
  85. package/snippets/avatar.html +6 -6
  86. package/snippets/back-link.html +5 -5
  87. package/snippets/badge.html +5 -5
  88. package/snippets/barcode-input.html +18 -18
  89. package/snippets/breadcrumb.html +6 -6
  90. package/snippets/browser-frame.html +18 -18
  91. package/snippets/busy-overlay.html +31 -31
  92. package/snippets/button-group.html +21 -21
  93. package/snippets/button.html +8 -8
  94. package/snippets/calendar.html +43 -43
  95. package/snippets/card.html +17 -17
  96. package/snippets/carousel.html +21 -21
  97. package/snippets/chart-line.html +46 -46
  98. package/snippets/chart.html +27 -27
  99. package/snippets/chat-composer.html +21 -21
  100. package/snippets/checkbox.html +5 -5
  101. package/snippets/checklist.html +23 -23
  102. package/snippets/chip-filter.html +14 -14
  103. package/snippets/code-window.html +20 -20
  104. package/snippets/collapsible.html +19 -19
  105. package/snippets/color-field.html +13 -13
  106. package/snippets/color-select.html +18 -18
  107. package/snippets/column-menu.html +38 -38
  108. package/snippets/combobox.html +19 -19
  109. package/snippets/command.html +24 -24
  110. package/snippets/confirm-dialog.html +32 -32
  111. package/snippets/context-menu.html +25 -25
  112. package/snippets/cookie-consent.html +70 -70
  113. package/snippets/copy-field.html +19 -19
  114. package/snippets/counter.html +2 -2
  115. package/snippets/data-table.html +151 -151
  116. package/snippets/date-picker.html +32 -32
  117. package/snippets/decimal-input.html +20 -20
  118. package/snippets/definition-list.html +20 -20
  119. package/snippets/demo-panel.html +18 -18
  120. package/snippets/doc-viewer.html +58 -58
  121. package/snippets/drawer.html +30 -30
  122. package/snippets/dropdown-menu.html +27 -27
  123. package/snippets/dropdown.html +9 -9
  124. package/snippets/dropzone.html +13 -13
  125. package/snippets/emoji-picker.html +51 -51
  126. package/snippets/empty-state.html +17 -17
  127. package/snippets/entity-card.html +26 -26
  128. package/snippets/expandable-table.html +26 -26
  129. package/snippets/fact-list.html +14 -14
  130. package/snippets/filter-counts.html +30 -30
  131. package/snippets/flip-card.html +22 -22
  132. package/snippets/form-field.html +6 -6
  133. package/snippets/greeting.html +22 -22
  134. package/snippets/heading.html +14 -14
  135. package/snippets/hover-card.html +18 -18
  136. package/snippets/image-zoom.html +30 -30
  137. package/snippets/input-group.html +10 -10
  138. package/snippets/input.html +5 -5
  139. package/snippets/item.html +26 -26
  140. package/snippets/kbd.html +13 -13
  141. package/snippets/label.html +9 -9
  142. package/snippets/language-select.html +26 -26
  143. package/snippets/launcher-card.html +14 -14
  144. package/snippets/lightbox.html +50 -50
  145. package/snippets/link-arrow.html +10 -10
  146. package/snippets/list-toolbar.html +33 -33
  147. package/snippets/marquee.html +15 -15
  148. package/snippets/media-card.html +28 -28
  149. package/snippets/media-row.html +21 -21
  150. package/snippets/media-thumb.html +12 -12
  151. package/snippets/menubar.html +30 -30
  152. package/snippets/message-thread.html +123 -123
  153. package/snippets/message.html +51 -51
  154. package/snippets/modal.html +15 -15
  155. package/snippets/native-select.html +15 -15
  156. package/snippets/navmenu.html +23 -23
  157. package/snippets/next-teaser.html +15 -15
  158. package/snippets/number-input.html +27 -27
  159. package/snippets/otp-input.html +9 -9
  160. package/snippets/page-header.html +24 -24
  161. package/snippets/pagination.html +6 -6
  162. package/snippets/password-input.html +24 -24
  163. package/snippets/password-requirements.html +30 -30
  164. package/snippets/phone-input.html +22 -22
  165. package/snippets/popover.html +15 -15
  166. package/snippets/price-card.html +34 -34
  167. package/snippets/product-mark.html +13 -13
  168. package/snippets/progress.html +4 -4
  169. package/snippets/project-card.html +23 -23
  170. package/snippets/prose.html +54 -54
  171. package/snippets/radio.html +17 -17
  172. package/snippets/recovery-codes.html +20 -20
  173. package/snippets/resizable.html +16 -16
  174. package/snippets/scroll-area.html +20 -20
  175. package/snippets/search.html +8 -8
  176. package/snippets/segmented.html +11 -11
  177. package/snippets/select.html +7 -7
  178. package/snippets/separator.html +15 -15
  179. package/snippets/severity-card.html +35 -35
  180. package/snippets/sheet.html +32 -32
  181. package/snippets/sidebar-docs.html +24 -24
  182. package/snippets/sidebar.html +55 -55
  183. package/snippets/site-footer.html +6 -6
  184. package/snippets/site-header.html +26 -26
  185. package/snippets/skeleton.html +4 -4
  186. package/snippets/slider.html +17 -17
  187. package/snippets/sortable-row.html +31 -31
  188. package/snippets/spinner.html +14 -14
  189. package/snippets/stack-card.html +17 -17
  190. package/snippets/stack-list.html +16 -16
  191. package/snippets/stat-card.html +24 -24
  192. package/snippets/stepper.html +13 -13
  193. package/snippets/switch.html +6 -6
  194. package/snippets/table-actions.html +39 -39
  195. package/snippets/table-compact.html +24 -24
  196. package/snippets/table.html +29 -29
  197. package/snippets/tabs.html +9 -9
  198. package/snippets/tag-input.html +60 -17
  199. package/snippets/terminal-log.html +23 -23
  200. package/snippets/textarea.html +3 -3
  201. package/snippets/theme-switch.html +6 -6
  202. package/snippets/time-input.html +26 -26
  203. package/snippets/timeline.html +28 -28
  204. package/snippets/toast-stack.html +10 -10
  205. package/snippets/toast.html +36 -36
  206. package/snippets/toc.html +13 -13
  207. package/snippets/toggle-field.html +20 -20
  208. package/snippets/toggle.html +22 -22
  209. package/snippets/tooltip.html +4 -4
  210. package/snippets/top-progress.html +12 -12
  211. package/snippets/tree.html +38 -38
  212. package/snippets/upgrade-banner.html +28 -28
  213. package/snippets/user.html +15 -15
  214. package/snippets/version-banner.html +15 -15
@@ -1,12 +1,12 @@
1
- <!-- OmniaUI component: media-thumb — 16:9 video thumbnail with duration badge and watch-progress bar. Needs @birdycom/omniaui CSS.
2
- File: packages/ui/snippets/media-thumb.html | Map: thumb link -> picture -> badge -> duration -> progress
3
- Class API: a.oc-media-thumb (or div) > img / video / .oc-media-art · .oc-media-thumb__badge (top left, --live = red) ·
4
- .oc-media-thumb__duration (bottom right) · progress.oc-media-thumb__progress (value / max = watched part).
5
- Modifiers: .oc-media-thumb--square / --portrait. States: .is-watched (dimmed picture). No JavaScript.
6
- -->
7
- <a class="oc-media-thumb" href="#" style="inline-size:20rem" aria-label="Morning light in the dunes, 12 minutes 4 seconds">
8
- <div class="oc-media-art oc-media-art--3"></div>
9
- <span class="oc-media-thumb__badge">New</span>
10
- <span class="oc-media-thumb__duration">12:04</span>
11
- <progress class="oc-media-thumb__progress" value="40" max="100" aria-label="Watched 40%">40%</progress>
12
- </a>
1
+ <!-- OmniaUI component: media-thumb — 16:9 video thumbnail with duration badge and watch-progress bar. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/media-thumb.html | Map: thumb link -> picture -> badge -> duration -> progress
3
+ Class API: a.oc-media-thumb (or div) > img / video / .oc-media-art · .oc-media-thumb__badge (top left, --live = red) ·
4
+ .oc-media-thumb__duration (bottom right) · progress.oc-media-thumb__progress (value / max = watched part).
5
+ Modifiers: .oc-media-thumb--square / --portrait. States: .is-watched (dimmed picture). No JavaScript.
6
+ -->
7
+ <a class="oc-media-thumb" href="#" style="inline-size:20rem" aria-label="Morning light in the dunes, 12 minutes 4 seconds">
8
+ <div class="oc-media-art oc-media-art--3"></div>
9
+ <span class="oc-media-thumb__badge">New</span>
10
+ <span class="oc-media-thumb__duration">12:04</span>
11
+ <progress class="oc-media-thumb__progress" value="40" max="100" aria-label="Watched 40%">40%</progress>
12
+ </a>
@@ -1,30 +1,30 @@
1
- <!-- OmniaUI component: menubar - Menubar: horizontal menu bar built from popover dropdown menus. Needs @birdycom/omniaui CSS.
2
- Class API (modifiers are extra classes / attributes on the same element):
3
- .oc-menubar: the bar (role="menubar")
4
- .oc-menubar-trigger: button with popovertarget
5
- .oc-dropdown-menu[popover]: each menu (+ .oc-dropdown-item, -label, -separator, -shortcut, -sub)
6
- -->
7
- <div class="oc-menubar" role="menubar" aria-label="Application">
8
- <button class="oc-menubar-trigger" type="button" role="menuitem" popovertarget="oc-mb-file" aria-haspopup="menu">File</button>
9
- <button class="oc-menubar-trigger" type="button" role="menuitem" popovertarget="oc-mb-view" aria-haspopup="menu">View</button>
10
- </div>
11
- <div class="oc-dropdown-menu" id="oc-mb-file" popover role="menu">
12
- <button class="oc-dropdown-item" type="button" role="menuitem">New tab <span class="oc-dropdown-shortcut">Ctrl T</span></button>
13
- <button class="oc-dropdown-item" type="button" role="menuitem">New window <span class="oc-dropdown-shortcut">Ctrl N</span></button>
14
- <div class="oc-dropdown-separator" role="separator"></div>
15
- <div class="oc-dropdown-sub">
16
- <button class="oc-dropdown-item" type="button" role="menuitem" aria-haspopup="menu">Share</button>
17
- <div class="oc-dropdown-submenu" role="menu">
18
- <button class="oc-dropdown-item" type="button" role="menuitem">E-mail link</button>
19
- <button class="oc-dropdown-item" type="button" role="menuitem">Messages</button>
20
- </div>
21
- </div>
22
- <div class="oc-dropdown-separator" role="separator"></div>
23
- <button class="oc-dropdown-item" type="button" role="menuitem">Print <span class="oc-dropdown-shortcut">Ctrl P</span></button>
24
- </div>
25
- <div class="oc-dropdown-menu" id="oc-mb-view" popover role="menu">
26
- <button class="oc-dropdown-item" type="button" role="menuitemcheckbox" aria-checked="true">Always show bookmarks</button>
27
- <button class="oc-dropdown-item" type="button" role="menuitemcheckbox" aria-checked="false">Always show full URLs</button>
28
- <div class="oc-dropdown-separator" role="separator"></div>
29
- <button class="oc-dropdown-item" type="button" role="menuitem">Reload <span class="oc-dropdown-shortcut">Ctrl R</span></button>
30
- </div>
1
+ <!-- OmniaUI component: menubar - Menubar: horizontal menu bar built from popover dropdown menus. Needs @birdycom/omniaui CSS.
2
+ Class API (modifiers are extra classes / attributes on the same element):
3
+ .oc-menubar: the bar (role="menubar")
4
+ .oc-menubar-trigger: button with popovertarget
5
+ .oc-dropdown-menu[popover]: each menu (+ .oc-dropdown-item, -label, -separator, -shortcut, -sub)
6
+ -->
7
+ <div class="oc-menubar" role="menubar" aria-label="Application">
8
+ <button class="oc-menubar-trigger" type="button" role="menuitem" popovertarget="oc-mb-file" aria-haspopup="menu">File</button>
9
+ <button class="oc-menubar-trigger" type="button" role="menuitem" popovertarget="oc-mb-view" aria-haspopup="menu">View</button>
10
+ </div>
11
+ <div class="oc-dropdown-menu" id="oc-mb-file" popover role="menu">
12
+ <button class="oc-dropdown-item" type="button" role="menuitem">New tab <span class="oc-dropdown-shortcut">Ctrl T</span></button>
13
+ <button class="oc-dropdown-item" type="button" role="menuitem">New window <span class="oc-dropdown-shortcut">Ctrl N</span></button>
14
+ <div class="oc-dropdown-separator" role="separator"></div>
15
+ <div class="oc-dropdown-sub">
16
+ <button class="oc-dropdown-item" type="button" role="menuitem" aria-haspopup="menu">Share</button>
17
+ <div class="oc-dropdown-submenu" role="menu">
18
+ <button class="oc-dropdown-item" type="button" role="menuitem">E-mail link</button>
19
+ <button class="oc-dropdown-item" type="button" role="menuitem">Messages</button>
20
+ </div>
21
+ </div>
22
+ <div class="oc-dropdown-separator" role="separator"></div>
23
+ <button class="oc-dropdown-item" type="button" role="menuitem">Print <span class="oc-dropdown-shortcut">Ctrl P</span></button>
24
+ </div>
25
+ <div class="oc-dropdown-menu" id="oc-mb-view" popover role="menu">
26
+ <button class="oc-dropdown-item" type="button" role="menuitemcheckbox" aria-checked="true">Always show bookmarks</button>
27
+ <button class="oc-dropdown-item" type="button" role="menuitemcheckbox" aria-checked="false">Always show full URLs</button>
28
+ <div class="oc-dropdown-separator" role="separator"></div>
29
+ <button class="oc-dropdown-item" type="button" role="menuitem">Reload <span class="oc-dropdown-shortcut">Ctrl R</span></button>
30
+ </div>
@@ -1,123 +1,123 @@
1
- <!-- OmniaUI component: message-thread — Scrolling conversation: header with subject, people, status and actions menu, messages that start at the bottom, composer and a sending overlay. Needs @birdycom/omniaui CSS.
2
- File: packages/ui/snippets/message-thread.html | Map: thread -> header (heading, people, badge, menu) -> scroll (message list) -> footer (attachments + chat-composer) -> busy overlay -> optional script
3
- Class API (modifiers are extra classes / attributes on the same element):
4
- section.oc-message-thread: Grid frame, height from --oc-message-thread-height (32rem). Modifier: --plain (no wallpaper).
5
- State: aria-busy="true" shows the sending overlay
6
- .oc-message-thread__header > .oc-message-thread__heading (__title, __meta), .oc-avatar-group.oc-message-thread__people,
7
- .oc-message-thread__actions > .oc-badge, button.oc-message-thread__icon-btn (popovertarget) + .oc-dropdown-menu[popover]
8
- .oc-message-thread__scroll (tabindex="0", role="log"): Scroll area; column-reverse, so it opens at the newest message.
9
- Holds one .oc-message-list (message component)
10
- .oc-message-thread__footer: Bottom bar with an optional .oc-attachment-list and the chat-composer, or a .oc-message-thread__note
11
- .oc-message-thread__busy (role="status"): Overlay with .oc-spinner, strong and span
12
- Optional script (end of this snippet): appends what you type as an outgoing message after a short "Sending" state and
13
- sends with Ctrl/Cmd + Enter. In an app, post the form and render the new message on the server instead.
14
- -->
15
- <section class="oc-message-thread" aria-labelledby="oc-thread-demo-title" style="inline-size:100%;max-inline-size:40rem">
16
- <header class="oc-message-thread__header">
17
- <div class="oc-message-thread__heading">
18
- <h3 class="oc-message-thread__title" id="oc-thread-demo-title">Kitchen worktop: which finish?</h3>
19
- <p class="oc-message-thread__meta"><strong>Villa Dewitte</strong> · Lisa Verbeke → Tom Peeters · 14 Oct 2026</p>
20
- </div>
21
- <div class="oc-avatar-group oc-message-thread__people" aria-label="2 participants"><span class="oc-avatar" title="Lisa Verbeke">LV</span><span class="oc-avatar" title="Tom Peeters">TP</span></div>
22
- <div class="oc-message-thread__actions">
23
- <span class="oc-badge oc-badge--destructive">Urgent</span>
24
- <button type="button" class="oc-message-thread__icon-btn" popovertarget="oc-thread-demo-menu" aria-label="Conversation actions"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><circle cx="12" cy="5" r="1.8"/><circle cx="12" cy="12" r="1.8"/><circle cx="12" cy="19" r="1.8"/></svg></button>
25
- <div class="oc-dropdown-menu" id="oc-thread-demo-menu" popover role="menu">
26
- <button type="button" class="oc-dropdown-item" role="menuitem">Mark as unread</button>
27
- <button type="button" class="oc-dropdown-item" role="menuitem">Move to archive</button>
28
- <div class="oc-dropdown-separator" role="separator"></div>
29
- <button type="button" class="oc-dropdown-item oc-dropdown-item--destructive" role="menuitem">Delete conversation</button>
30
- </div>
31
- </div>
32
- </header>
33
-
34
- <div class="oc-message-thread__scroll" tabindex="0" role="log" aria-label="Messages" aria-live="polite">
35
- <div class="oc-message-list">
36
- <div class="oc-message-divider"><span>Tuesday 14 October</span></div>
37
- <article class="oc-message">
38
- <span class="oc-avatar oc-message__avatar">LV</span>
39
- <div class="oc-message__bubble">
40
- <p class="oc-message__sender">Lisa Verbeke</p>
41
- <div class="oc-message__text"><p>The supplier dropped off two worktop samples at the workshop. Photo attached.</p></div>
42
- <div class="oc-message__attachments"><a class="oc-attachment-image" href="#samples.jpg"><span class="oc-media-art oc-media-art--6" role="img" aria-label="Two worktop samples on the workbench"></span><span class="oc-attachment-image__caption">samples.jpg · 2.1 MB</span></a></div>
43
- <p class="oc-message__meta"><time datetime="2026-10-14T09:12">09:12</time></p>
44
- </div>
45
- </article>
46
- <article class="oc-message oc-message--continued">
47
- <span class="oc-avatar oc-message__avatar">LV</span>
48
- <div class="oc-message__bubble">
49
- <div class="oc-message__text"><p>Which one should we order: <strong>Calacatta matt</strong> or <strong>Nero Marquina polished</strong>? The cutting slot is Friday.</p></div>
50
- <p class="oc-message__meta"><time datetime="2026-10-14T09:13">09:13</time></p>
51
- </div>
52
- </article>
53
- <article class="oc-message oc-message--out">
54
- <span class="oc-avatar oc-message__avatar">TP</span>
55
- <div class="oc-message__bubble">
56
- <div class="oc-message__text"><p>Calacatta matt, 20 mm. I'll send the updated quote to the client today.</p></div>
57
- <div class="oc-message__attachments"><a class="oc-attachment oc-attachment--pdf" href="#quote.pdf" download><span class="oc-attachment__icon" aria-hidden="true">PDF</span><span class="oc-attachment__body"><span class="oc-attachment__name">Quote kitchen Dewitte v2.pdf</span><span class="oc-attachment__size">1.2 MB</span></span></a></div>
58
- <p class="oc-message__meta"><time datetime="2026-10-14T09:20">09:20</time><span class="oc-message__status oc-message__status--read">Read</span></p>
59
- </div>
60
- <div class="oc-message__actions"><button type="button" class="oc-message__action oc-message__action--destructive" aria-label="Delete this message"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6M10 11v6M14 11v6"/></svg></button></div>
61
- </article>
62
- <div class="oc-message-divider"><span>Today</span></div>
63
- <article class="oc-message">
64
- <span class="oc-avatar oc-message__avatar">LV</span>
65
- <div class="oc-message__bubble">
66
- <p class="oc-message__sender">Lisa Verbeke</p>
67
- <div class="oc-message__text"><p>Client signed. Can you confirm the edge profile before 16:00?</p></div>
68
- <p class="oc-message__meta"><time datetime="2026-10-24T10:02">10:02</time></p>
69
- </div>
70
- </article>
71
- </div>
72
- </div>
73
-
74
- <div class="oc-message-thread__footer">
75
- <form class="oc-chat-composer" action="#" aria-label="Reply">
76
- <label class="oc-visually-hidden" for="oc-thread-demo-input">Message</label>
77
- <textarea class="oc-chat-composer__input" id="oc-thread-demo-input" name="message" rows="1" placeholder="Type your reply…" required></textarea>
78
- <div class="oc-chat-composer__bar">
79
- <div class="oc-chat-composer__tools">
80
- <button type="button" class="oc-chat-composer__tool" aria-label="Attach a file">&#128206;</button>
81
- <button type="button" class="oc-chat-composer__tool" aria-label="Insert emoji">&#128578;</button>
82
- </div>
83
- <span class="oc-chat-composer__hint">Ctrl + Enter to send</span>
84
- <button type="submit" class="oc-chat-composer__send" aria-label="Send">&#10148;</button>
85
- </div>
86
- </form>
87
- </div>
88
-
89
- <div class="oc-message-thread__busy" role="status">
90
- <span class="oc-spinner oc-spinner--lg" aria-hidden="true"></span>
91
- <strong>Sending message…</strong>
92
- <span>Please wait, do not close this conversation.</span>
93
- </div>
94
- </section>
95
- <script>
96
- // Optional: append the typed message as an outgoing bubble (demo behaviour; an app posts the form instead).
97
- document.addEventListener("submit", (e) => {
98
- const form = e.target.closest(".oc-message-thread form.oc-chat-composer");
99
- if (!form || e.defaultPrevented) return;
100
- e.preventDefault();
101
- const thread = form.closest(".oc-message-thread"), field = form.querySelector("textarea"), text = field.value.trim();
102
- if (!text) return;
103
- thread.setAttribute("aria-busy", "true");
104
- setTimeout(() => {
105
- const list = thread.querySelector(".oc-message-list"), last = list.lastElementChild;
106
- const msg = document.createElement("article");
107
- msg.className = "oc-message oc-message--out" + (last?.matches(".oc-message--out") ? " oc-message--continued" : "");
108
- msg.innerHTML = '<span class="oc-avatar oc-message__avatar"></span><div class="oc-message__bubble"><div class="oc-message__text"><p></p></div><p class="oc-message__meta"><time></time><span class="oc-message__status">Sent</span></p></div>';
109
- msg.querySelector(".oc-avatar").textContent = list.querySelector(".oc-message--out .oc-avatar")?.textContent || "Me";
110
- msg.querySelector("p").textContent = text;
111
- msg.querySelector("time").textContent = new Date().toTimeString().slice(0, 5);
112
- list.append(msg);
113
- field.value = "";
114
- thread.removeAttribute("aria-busy");
115
- field.focus();
116
- }, 600);
117
- });
118
- document.addEventListener("keydown", (e) => {
119
- if (e.defaultPrevented || e.key !== "Enter" || !(e.ctrlKey || e.metaKey) || !e.target.matches(".oc-message-thread .oc-chat-composer__input")) return;
120
- e.preventDefault();
121
- e.target.form.requestSubmit();
122
- });
123
- </script>
1
+ <!-- OmniaUI component: message-thread — Scrolling conversation: header with subject, people, status and actions menu, messages that start at the bottom, composer and a sending overlay. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/message-thread.html | Map: thread -> header (heading, people, badge, menu) -> scroll (message list) -> footer (attachments + chat-composer) -> busy overlay -> optional script
3
+ Class API (modifiers are extra classes / attributes on the same element):
4
+ section.oc-message-thread: Grid frame, height from --oc-message-thread-height (32rem). Modifier: --plain (no wallpaper).
5
+ State: aria-busy="true" shows the sending overlay
6
+ .oc-message-thread__header > .oc-message-thread__heading (__title, __meta), .oc-avatar-group.oc-message-thread__people,
7
+ .oc-message-thread__actions > .oc-badge, button.oc-message-thread__icon-btn (popovertarget) + .oc-dropdown-menu[popover]
8
+ .oc-message-thread__scroll (tabindex="0", role="log"): Scroll area; column-reverse, so it opens at the newest message.
9
+ Holds one .oc-message-list (message component)
10
+ .oc-message-thread__footer: Bottom bar with an optional .oc-attachment-list and the chat-composer, or a .oc-message-thread__note
11
+ .oc-message-thread__busy (role="status"): Overlay with .oc-spinner, strong and span
12
+ Optional script (end of this snippet): appends what you type as an outgoing message after a short "Sending" state and
13
+ sends with Ctrl/Cmd + Enter. In an app, post the form and render the new message on the server instead.
14
+ -->
15
+ <section class="oc-message-thread" aria-labelledby="oc-thread-demo-title" style="inline-size:100%;max-inline-size:40rem">
16
+ <header class="oc-message-thread__header">
17
+ <div class="oc-message-thread__heading">
18
+ <h3 class="oc-message-thread__title" id="oc-thread-demo-title">Kitchen worktop: which finish?</h3>
19
+ <p class="oc-message-thread__meta"><strong>Villa Dewitte</strong> · Lisa Verbeke → Tom Peeters · 14 Oct 2026</p>
20
+ </div>
21
+ <div class="oc-avatar-group oc-message-thread__people" aria-label="2 participants"><span class="oc-avatar" title="Lisa Verbeke">LV</span><span class="oc-avatar" title="Tom Peeters">TP</span></div>
22
+ <div class="oc-message-thread__actions">
23
+ <span class="oc-badge oc-badge--destructive">Urgent</span>
24
+ <button type="button" class="oc-message-thread__icon-btn" popovertarget="oc-thread-demo-menu" aria-label="Conversation actions"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><circle cx="12" cy="5" r="1.8"/><circle cx="12" cy="12" r="1.8"/><circle cx="12" cy="19" r="1.8"/></svg></button>
25
+ <div class="oc-dropdown-menu" id="oc-thread-demo-menu" popover role="menu">
26
+ <button type="button" class="oc-dropdown-item" role="menuitem">Mark as unread</button>
27
+ <button type="button" class="oc-dropdown-item" role="menuitem">Move to archive</button>
28
+ <div class="oc-dropdown-separator" role="separator"></div>
29
+ <button type="button" class="oc-dropdown-item oc-dropdown-item--destructive" role="menuitem">Delete conversation</button>
30
+ </div>
31
+ </div>
32
+ </header>
33
+
34
+ <div class="oc-message-thread__scroll" tabindex="0" role="log" aria-label="Messages" aria-live="polite">
35
+ <div class="oc-message-list">
36
+ <div class="oc-message-divider"><span>Tuesday 14 October</span></div>
37
+ <article class="oc-message">
38
+ <span class="oc-avatar oc-message__avatar">LV</span>
39
+ <div class="oc-message__bubble">
40
+ <p class="oc-message__sender">Lisa Verbeke</p>
41
+ <div class="oc-message__text"><p>The supplier dropped off two worktop samples at the workshop. Photo attached.</p></div>
42
+ <div class="oc-message__attachments"><a class="oc-attachment-image" href="#samples.jpg"><span class="oc-media-art oc-media-art--6" role="img" aria-label="Two worktop samples on the workbench"></span><span class="oc-attachment-image__caption">samples.jpg · 2.1 MB</span></a></div>
43
+ <p class="oc-message__meta"><time datetime="2026-10-14T09:12">09:12</time></p>
44
+ </div>
45
+ </article>
46
+ <article class="oc-message oc-message--continued">
47
+ <span class="oc-avatar oc-message__avatar">LV</span>
48
+ <div class="oc-message__bubble">
49
+ <div class="oc-message__text"><p>Which one should we order: <strong>Calacatta matt</strong> or <strong>Nero Marquina polished</strong>? The cutting slot is Friday.</p></div>
50
+ <p class="oc-message__meta"><time datetime="2026-10-14T09:13">09:13</time></p>
51
+ </div>
52
+ </article>
53
+ <article class="oc-message oc-message--out">
54
+ <span class="oc-avatar oc-message__avatar">TP</span>
55
+ <div class="oc-message__bubble">
56
+ <div class="oc-message__text"><p>Calacatta matt, 20 mm. I'll send the updated quote to the client today.</p></div>
57
+ <div class="oc-message__attachments"><a class="oc-attachment oc-attachment--pdf" href="#quote.pdf" download><span class="oc-attachment__icon" aria-hidden="true">PDF</span><span class="oc-attachment__body"><span class="oc-attachment__name">Quote kitchen Dewitte v2.pdf</span><span class="oc-attachment__size">1.2 MB</span></span></a></div>
58
+ <p class="oc-message__meta"><time datetime="2026-10-14T09:20">09:20</time><span class="oc-message__status oc-message__status--read">Read</span></p>
59
+ </div>
60
+ <div class="oc-message__actions"><button type="button" class="oc-message__action oc-message__action--destructive" aria-label="Delete this message"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6M10 11v6M14 11v6"/></svg></button></div>
61
+ </article>
62
+ <div class="oc-message-divider"><span>Today</span></div>
63
+ <article class="oc-message">
64
+ <span class="oc-avatar oc-message__avatar">LV</span>
65
+ <div class="oc-message__bubble">
66
+ <p class="oc-message__sender">Lisa Verbeke</p>
67
+ <div class="oc-message__text"><p>Client signed. Can you confirm the edge profile before 16:00?</p></div>
68
+ <p class="oc-message__meta"><time datetime="2026-10-24T10:02">10:02</time></p>
69
+ </div>
70
+ </article>
71
+ </div>
72
+ </div>
73
+
74
+ <div class="oc-message-thread__footer">
75
+ <form class="oc-chat-composer" action="#" aria-label="Reply">
76
+ <label class="oc-visually-hidden" for="oc-thread-demo-input">Message</label>
77
+ <textarea class="oc-chat-composer__input" id="oc-thread-demo-input" name="message" rows="1" placeholder="Type your reply…" required></textarea>
78
+ <div class="oc-chat-composer__bar">
79
+ <div class="oc-chat-composer__tools">
80
+ <button type="button" class="oc-chat-composer__tool" aria-label="Attach a file">&#128206;</button>
81
+ <button type="button" class="oc-chat-composer__tool" aria-label="Insert emoji">&#128578;</button>
82
+ </div>
83
+ <span class="oc-chat-composer__hint">Ctrl + Enter to send</span>
84
+ <button type="submit" class="oc-chat-composer__send" aria-label="Send">&#10148;</button>
85
+ </div>
86
+ </form>
87
+ </div>
88
+
89
+ <div class="oc-message-thread__busy" role="status">
90
+ <span class="oc-spinner oc-spinner--lg" aria-hidden="true"></span>
91
+ <strong>Sending message…</strong>
92
+ <span>Please wait, do not close this conversation.</span>
93
+ </div>
94
+ </section>
95
+ <script>
96
+ // Optional: append the typed message as an outgoing bubble (demo behaviour; an app posts the form instead).
97
+ document.addEventListener("submit", (e) => {
98
+ const form = e.target.closest(".oc-message-thread form.oc-chat-composer");
99
+ if (!form || e.defaultPrevented) return;
100
+ e.preventDefault();
101
+ const thread = form.closest(".oc-message-thread"), field = form.querySelector("textarea"), text = field.value.trim();
102
+ if (!text) return;
103
+ thread.setAttribute("aria-busy", "true");
104
+ setTimeout(() => {
105
+ const list = thread.querySelector(".oc-message-list"), last = list.lastElementChild;
106
+ const msg = document.createElement("article");
107
+ msg.className = "oc-message oc-message--out" + (last?.matches(".oc-message--out") ? " oc-message--continued" : "");
108
+ msg.innerHTML = '<span class="oc-avatar oc-message__avatar"></span><div class="oc-message__bubble"><div class="oc-message__text"><p></p></div><p class="oc-message__meta"><time></time><span class="oc-message__status">Sent</span></p></div>';
109
+ msg.querySelector(".oc-avatar").textContent = list.querySelector(".oc-message--out .oc-avatar")?.textContent || "Me";
110
+ msg.querySelector("p").textContent = text;
111
+ msg.querySelector("time").textContent = new Date().toTimeString().slice(0, 5);
112
+ list.append(msg);
113
+ field.value = "";
114
+ thread.removeAttribute("aria-busy");
115
+ field.focus();
116
+ }, 600);
117
+ });
118
+ document.addEventListener("keydown", (e) => {
119
+ if (e.defaultPrevented || e.key !== "Enter" || !(e.ctrlKey || e.metaKey) || !e.target.matches(".oc-message-thread .oc-chat-composer__input")) return;
120
+ e.preventDefault();
121
+ e.target.form.requestSubmit();
122
+ });
123
+ </script>
@@ -1,51 +1,51 @@
1
- <!-- OmniaUI component: message — Chat bubble: incoming and outgoing, sender, avatar, time, read receipt, hover actions, grouping, reply quote and date divider. Needs @birdycom/omniaui CSS.
2
- File: packages/ui/snippets/message.html | Map: list -> date divider -> incoming group (2) -> outgoing with quote + receipt -> system line
3
- Class API (modifiers are extra classes / attributes on the same element):
4
- .oc-message-list: Column of messages and dividers (role="log" when it updates live). Custom properties: --oc-message-in, --oc-message-out
5
- article.oc-message: One row. Modifiers: --out (right, primary tint), --continued (follows a message of the same sender:
6
- no name, the avatar moves to the last message of the group via :has())
7
- .oc-avatar.oc-message__avatar: Avatar (avatar component); keep it on every message so the grouping can hide it
8
- .oc-message__bubble > .oc-message__sender, a.oc-message__quote (strong + span), .oc-message__text (p, ul, ol, a, strong, code),
9
- .oc-message__attachments (attachment component), .oc-message__meta > time + .oc-message__status (--read, --failed)
10
- .oc-message__actions > button.oc-message__action (--destructive): Shown on hover and keyboard focus, always on touch screens
11
- .oc-message-divider > span: Date divider. Modifier: --system (a centred notice without lines)
12
- No JavaScript. Escape user text on the server; the markup only expects paragraphs, lists and links.
13
- -->
14
- <div class="oc-message-list" role="log" aria-label="Conversation with Lisa Verbeke" style="max-inline-size:36rem">
15
- <div class="oc-message-divider"><span>Tuesday 14 October</span></div>
16
-
17
- <article class="oc-message" aria-label="Lisa Verbeke, 09:12">
18
- <span class="oc-avatar oc-message__avatar">LV</span>
19
- <div class="oc-message__bubble">
20
- <p class="oc-message__sender">Lisa Verbeke</p>
21
- <div class="oc-message__text"><p>Morning Tom! The worktop supplier sent two samples for Villa Dewitte.</p></div>
22
- <p class="oc-message__meta"><time datetime="2026-10-14T09:12">09:12</time></p>
23
- </div>
24
- </article>
25
- <article class="oc-message oc-message--continued" id="oc-message-demo-question" aria-label="Lisa Verbeke, 09:13">
26
- <span class="oc-avatar oc-message__avatar">LV</span>
27
- <div class="oc-message__bubble">
28
- <div class="oc-message__text">
29
- <p>Which finish should we order?</p>
30
- <ul><li><strong>Calacatta</strong> matt, 20 mm</li><li><strong>Nero Marquina</strong> polished, 12 mm</li></ul>
31
- <p>Details are on the <a href="#supplier-sheet">supplier sheet</a>.</p>
32
- </div>
33
- <p class="oc-message__meta"><time datetime="2026-10-14T09:13">09:13</time></p>
34
- </div>
35
- </article>
36
-
37
- <article class="oc-message oc-message--out" aria-label="You, 09:20">
38
- <span class="oc-avatar oc-message__avatar">TP</span>
39
- <div class="oc-message__bubble">
40
- <a class="oc-message__quote" href="#oc-message-demo-question"><strong>Lisa Verbeke</strong><span>Which finish should we order? Calacatta matt, 20 mm or Nero Marquina polished, 12 mm</span></a>
41
- <div class="oc-message__text"><p>Calacatta matt. The client wants the lighter look next to the oak fronts.</p></div>
42
- <p class="oc-message__meta"><time datetime="2026-10-14T09:20">09:20</time><span class="oc-message__status oc-message__status--read"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 12.5 7 17.5 18 6.5M13 16.5l1 1L22.5 9"/></svg>Read</span></p>
43
- </div>
44
- <div class="oc-message__actions">
45
- <button type="button" class="oc-message__action" aria-label="Reply to this message"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 14 4 9l5-5M4 9h10a6 6 0 0 1 6 6v4"/></svg></button>
46
- <button type="button" class="oc-message__action oc-message__action--destructive" aria-label="Delete this message"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6M10 11v6M14 11v6"/></svg></button>
47
- </div>
48
- </article>
49
-
50
- <div class="oc-message-divider oc-message-divider--system" role="note"><span>Lisa Verbeke marked this question as answered</span></div>
51
- </div>
1
+ <!-- OmniaUI component: message — Chat bubble: incoming and outgoing, sender, avatar, time, read receipt, hover actions, grouping, reply quote and date divider. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/message.html | Map: list -> date divider -> incoming group (2) -> outgoing with quote + receipt -> system line
3
+ Class API (modifiers are extra classes / attributes on the same element):
4
+ .oc-message-list: Column of messages and dividers (role="log" when it updates live). Custom properties: --oc-message-in, --oc-message-out
5
+ article.oc-message: One row. Modifiers: --out (right, primary tint), --continued (follows a message of the same sender:
6
+ no name, the avatar moves to the last message of the group via :has())
7
+ .oc-avatar.oc-message__avatar: Avatar (avatar component); keep it on every message so the grouping can hide it
8
+ .oc-message__bubble > .oc-message__sender, a.oc-message__quote (strong + span), .oc-message__text (p, ul, ol, a, strong, code),
9
+ .oc-message__attachments (attachment component), .oc-message__meta > time + .oc-message__status (--read, --failed)
10
+ .oc-message__actions > button.oc-message__action (--destructive): Shown on hover and keyboard focus, always on touch screens
11
+ .oc-message-divider > span: Date divider. Modifier: --system (a centred notice without lines)
12
+ No JavaScript. Escape user text on the server; the markup only expects paragraphs, lists and links.
13
+ -->
14
+ <div class="oc-message-list" role="log" aria-label="Conversation with Lisa Verbeke" style="max-inline-size:36rem">
15
+ <div class="oc-message-divider"><span>Tuesday 14 October</span></div>
16
+
17
+ <article class="oc-message" aria-label="Lisa Verbeke, 09:12">
18
+ <span class="oc-avatar oc-message__avatar">LV</span>
19
+ <div class="oc-message__bubble">
20
+ <p class="oc-message__sender">Lisa Verbeke</p>
21
+ <div class="oc-message__text"><p>Morning Tom! The worktop supplier sent two samples for Villa Dewitte.</p></div>
22
+ <p class="oc-message__meta"><time datetime="2026-10-14T09:12">09:12</time></p>
23
+ </div>
24
+ </article>
25
+ <article class="oc-message oc-message--continued" id="oc-message-demo-question" aria-label="Lisa Verbeke, 09:13">
26
+ <span class="oc-avatar oc-message__avatar">LV</span>
27
+ <div class="oc-message__bubble">
28
+ <div class="oc-message__text">
29
+ <p>Which finish should we order?</p>
30
+ <ul><li><strong>Calacatta</strong> matt, 20 mm</li><li><strong>Nero Marquina</strong> polished, 12 mm</li></ul>
31
+ <p>Details are on the <a href="#supplier-sheet">supplier sheet</a>.</p>
32
+ </div>
33
+ <p class="oc-message__meta"><time datetime="2026-10-14T09:13">09:13</time></p>
34
+ </div>
35
+ </article>
36
+
37
+ <article class="oc-message oc-message--out" aria-label="You, 09:20">
38
+ <span class="oc-avatar oc-message__avatar">TP</span>
39
+ <div class="oc-message__bubble">
40
+ <a class="oc-message__quote" href="#oc-message-demo-question"><strong>Lisa Verbeke</strong><span>Which finish should we order? Calacatta matt, 20 mm or Nero Marquina polished, 12 mm</span></a>
41
+ <div class="oc-message__text"><p>Calacatta matt. The client wants the lighter look next to the oak fronts.</p></div>
42
+ <p class="oc-message__meta"><time datetime="2026-10-14T09:20">09:20</time><span class="oc-message__status oc-message__status--read"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 12.5 7 17.5 18 6.5M13 16.5l1 1L22.5 9"/></svg>Read</span></p>
43
+ </div>
44
+ <div class="oc-message__actions">
45
+ <button type="button" class="oc-message__action" aria-label="Reply to this message"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 14 4 9l5-5M4 9h10a6 6 0 0 1 6 6v4"/></svg></button>
46
+ <button type="button" class="oc-message__action oc-message__action--destructive" aria-label="Delete this message"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6M10 11v6M14 11v6"/></svg></button>
47
+ </div>
48
+ </article>
49
+
50
+ <div class="oc-message-divider oc-message-divider--system" role="note"><span>Lisa Verbeke marked this question as answered</span></div>
51
+ </div>
@@ -1,15 +1,15 @@
1
- <!-- OmniaUI component: modal — Modal on <dialog> — opens with invoker commands, no JavaScript. Needs @birdycom/omniaui CSS. -->
2
- <button class="oc-btn" command="show-modal" commandfor="oc-modal-demo">Open modal</button>
3
-
4
- <dialog class="oc-modal" id="oc-modal-demo" closedby="any" aria-labelledby="oc-modal-demo-title">
5
- <div class="oc-modal-content">
6
- <div class="oc-modal-header">
7
- <h2 class="oc-modal-title" id="oc-modal-demo-title">Are you sure?</h2>
8
- <p class="oc-modal-description">This action cannot be undone.</p>
9
- </div>
10
- <div class="oc-modal-footer">
11
- <button class="oc-btn oc-btn--outline" command="close" commandfor="oc-modal-demo">Cancel</button>
12
- <button class="oc-btn oc-btn--destructive" command="close" commandfor="oc-modal-demo">Delete</button>
13
- </div>
14
- </div>
15
- </dialog>
1
+ <!-- OmniaUI component: modal — Modal on <dialog> — opens with invoker commands, no JavaScript. Needs @birdycom/omniaui CSS. -->
2
+ <button class="oc-btn" command="show-modal" commandfor="oc-modal-demo">Open modal</button>
3
+
4
+ <dialog class="oc-modal" id="oc-modal-demo" closedby="any" aria-labelledby="oc-modal-demo-title">
5
+ <div class="oc-modal-content">
6
+ <div class="oc-modal-header">
7
+ <h2 class="oc-modal-title" id="oc-modal-demo-title">Are you sure?</h2>
8
+ <p class="oc-modal-description">This action cannot be undone.</p>
9
+ </div>
10
+ <div class="oc-modal-footer">
11
+ <button class="oc-btn oc-btn--outline" command="close" commandfor="oc-modal-demo">Cancel</button>
12
+ <button class="oc-btn oc-btn--destructive" command="close" commandfor="oc-modal-demo">Delete</button>
13
+ </div>
14
+ </div>
15
+ </dialog>
@@ -1,15 +1,15 @@
1
- <!-- OmniaUI component: native-select - Native select: themed <select>; optional base-select picker styling. Needs @birdycom/omniaui CSS.
2
- Class API (modifiers are extra classes / attributes on the same element):
3
- select.oc-select: themed select (existing)
4
- select.oc-select.oc-select--custom: also styles ::picker(select), options, checkmark where appearance: base-select is supported; elsewhere it looks like .oc-select
5
- -->
6
- <div class="oc-field" style="max-inline-size:16rem">
7
- <label class="oc-field-label" for="oc-ns-fruit">Fruit</label>
8
- <select class="oc-select oc-select--custom" id="oc-ns-fruit">
9
- <option>Apple</option>
10
- <option selected>Banana</option>
11
- <option>Blueberry</option>
12
- <option>Grapes</option>
13
- <option>Pineapple</option>
14
- </select>
15
- </div>
1
+ <!-- OmniaUI component: native-select - Native select: themed <select>; optional base-select picker styling. Needs @birdycom/omniaui CSS.
2
+ Class API (modifiers are extra classes / attributes on the same element):
3
+ select.oc-select: themed select (existing)
4
+ select.oc-select.oc-select--custom: also styles ::picker(select), options, checkmark where appearance: base-select is supported; elsewhere it looks like .oc-select
5
+ -->
6
+ <div class="oc-field" style="max-inline-size:16rem">
7
+ <label class="oc-field-label" for="oc-ns-fruit">Fruit</label>
8
+ <select class="oc-select oc-select--custom" id="oc-ns-fruit">
9
+ <option>Apple</option>
10
+ <option selected>Banana</option>
11
+ <option>Blueberry</option>
12
+ <option>Grapes</option>
13
+ <option>Pineapple</option>
14
+ </select>
15
+ </div>
@@ -1,23 +1,23 @@
1
- <!-- OmniaUI component: navmenu - Horizontal navigation links with optional dropdown children. Needs @birdycom/omniaui CSS.
2
- Class API (modifiers are extra classes / attributes on the same element):
3
- .oc-navmenu: ul row of items
4
- .oc-navmenu-link: Link or button. State: aria-current="page" or .is-active
5
- .oc-navmenu-link--caret: Adds a chevron (trigger of a dropdown)
6
- .oc-dropdown-menu[popover]: Child menu, from the dropdown component
7
- -->
8
- <nav aria-label="Module navigation">
9
- <ul class="oc-navmenu">
10
- <li><a class="oc-navmenu-link" href="#" aria-current="page">Overview</a></li>
11
- <li><a class="oc-navmenu-link" href="#">Contacts</a></li>
12
- <li>
13
- <button class="oc-navmenu-link oc-navmenu-link--caret" type="button" popovertarget="oc-navmenu-sales">Sales</button>
14
- <div class="oc-dropdown-menu" id="oc-navmenu-sales" popover>
15
- <div class="oc-dropdown-label">Documents</div>
16
- <a class="oc-dropdown-item" href="#">Quotes</a>
17
- <a class="oc-dropdown-item" href="#">Orders</a>
18
- <a class="oc-dropdown-item" href="#">Invoices</a>
19
- </div>
20
- </li>
21
- <li><a class="oc-navmenu-link" href="#">Reports</a></li>
22
- </ul>
23
- </nav>
1
+ <!-- OmniaUI component: navmenu - Horizontal navigation links with optional dropdown children. Needs @birdycom/omniaui CSS.
2
+ Class API (modifiers are extra classes / attributes on the same element):
3
+ .oc-navmenu: ul row of items
4
+ .oc-navmenu-link: Link or button. State: aria-current="page" or .is-active
5
+ .oc-navmenu-link--caret: Adds a chevron (trigger of a dropdown)
6
+ .oc-dropdown-menu[popover]: Child menu, from the dropdown component
7
+ -->
8
+ <nav aria-label="Module navigation">
9
+ <ul class="oc-navmenu">
10
+ <li><a class="oc-navmenu-link" href="#" aria-current="page">Overview</a></li>
11
+ <li><a class="oc-navmenu-link" href="#">Contacts</a></li>
12
+ <li>
13
+ <button class="oc-navmenu-link oc-navmenu-link--caret" type="button" popovertarget="oc-navmenu-sales">Sales</button>
14
+ <div class="oc-dropdown-menu" id="oc-navmenu-sales" popover>
15
+ <div class="oc-dropdown-label">Documents</div>
16
+ <a class="oc-dropdown-item" href="#">Quotes</a>
17
+ <a class="oc-dropdown-item" href="#">Orders</a>
18
+ <a class="oc-dropdown-item" href="#">Invoices</a>
19
+ </div>
20
+ </li>
21
+ <li><a class="oc-navmenu-link" href="#">Reports</a></li>
22
+ </ul>
23
+ </nav>