@birdycom/omniaui 0.12.5 → 0.13.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 (102) hide show
  1. package/README.md +1 -1
  2. package/bin/lib/copy-js.mjs +12 -1
  3. package/bin/omniaui.mjs +2 -2
  4. package/dist/barcode.d.ts +15 -0
  5. package/dist/barcode.js +164 -0
  6. package/dist/components-extra.css +15 -1
  7. package/dist/components.css +2237 -256
  8. package/dist/components.min.css +1 -1
  9. package/dist/contact-form.d.ts +5 -0
  10. package/dist/contact-form.js +138 -0
  11. package/dist/data-table.js +135 -98
  12. package/dist/fly.d.ts +4 -0
  13. package/dist/fly.js +80 -0
  14. package/dist/form-extras.d.ts +11 -0
  15. package/dist/form-extras.js +214 -0
  16. package/dist/lazy.d.ts +5 -0
  17. package/dist/lazy.js +37 -0
  18. package/dist/oc-theme.css +3 -1
  19. package/dist/parts/app-data-table-footer.css +38 -0
  20. package/dist/parts/app-data-table-rich.css +161 -0
  21. package/dist/parts/app-data-table.css +44 -74
  22. package/dist/parts/app-name-card.css +65 -0
  23. package/dist/parts/app-result.css +39 -0
  24. package/dist/parts/app-titlebar.css +16 -8
  25. package/dist/parts/data-meter-row.css +40 -0
  26. package/dist/parts/data-price.css +20 -0
  27. package/dist/parts/data-ribbon.css +76 -0
  28. package/dist/parts/data-spec-list.css +36 -0
  29. package/dist/parts/data-stock.css +41 -0
  30. package/dist/parts/forms-affix-input.css +1 -1
  31. package/dist/parts/forms-avatar-picker.css +43 -0
  32. package/dist/parts/forms-date-field.css +53 -0
  33. package/dist/parts/forms-density.css +13 -0
  34. package/dist/parts/forms-form-section.css +64 -0
  35. package/dist/parts/forms-form.css +76 -0
  36. package/dist/parts/forms-quantity.css +55 -0
  37. package/dist/parts/forms-rating.css +81 -0
  38. package/dist/parts/media-attachment.css +1 -1
  39. package/dist/parts/media-barcode.css +23 -0
  40. package/dist/parts/media-chat-composer.css +3 -0
  41. package/dist/parts/media-emoji-picker.css +3 -1
  42. package/dist/parts/media-gallery.css +55 -0
  43. package/dist/parts/media-glass-liquid.css +99 -0
  44. package/dist/parts/media-glass-options.css +50 -0
  45. package/dist/parts/media-lazy.css +46 -0
  46. package/dist/parts/media-lightbox.css +4 -0
  47. package/dist/parts/media-message-thread.css +1 -1
  48. package/dist/parts/media-message.css +1 -1
  49. package/dist/parts/nav-topbar-variants.css +96 -0
  50. package/dist/parts/site-base.css +33 -0
  51. package/dist/parts/site-brand-mark.css +56 -0
  52. package/dist/parts/site-cards.css +183 -0
  53. package/dist/parts/site-fly.css +40 -0
  54. package/dist/parts/site-header-variants.css +70 -0
  55. package/dist/parts/site-layout.css +69 -0
  56. package/dist/parts/site-panel.css +29 -0
  57. package/dist/parts/site-prose.css +13 -1
  58. package/dist/parts/utility-hover.css +44 -0
  59. package/dist/showcase.css +114 -22
  60. package/manifest.json +193 -9
  61. package/package.json +7 -2
  62. package/snippets/accordion-accent.html +1 -1
  63. package/snippets/attachment.html +4 -4
  64. package/snippets/avatar-picker.html +40 -0
  65. package/snippets/barcode.html +20 -0
  66. package/snippets/brand-mark.html +41 -0
  67. package/snippets/chat-composer.html +3 -3
  68. package/snippets/data-table.html +51 -76
  69. package/snippets/date-field.html +44 -0
  70. package/snippets/doc-viewer.html +1 -1
  71. package/snippets/emoji-picker.html +1 -1
  72. package/snippets/feature-card.html +52 -0
  73. package/snippets/fly-in.html +30 -0
  74. package/snippets/form-density.html +25 -0
  75. package/snippets/form-section.html +47 -0
  76. package/snippets/gallery.html +25 -0
  77. package/snippets/hover-effects.html +19 -0
  78. package/snippets/icon-list.html +28 -0
  79. package/snippets/lazy.html +39 -0
  80. package/snippets/message-thread.html +12 -12
  81. package/snippets/message.html +10 -10
  82. package/snippets/meter-row.html +29 -0
  83. package/snippets/name-card.html +72 -0
  84. package/snippets/page-header.html +1 -1
  85. package/snippets/page-sections.html +50 -0
  86. package/snippets/panel.html +18 -0
  87. package/snippets/price.html +25 -0
  88. package/snippets/prose.html +3 -3
  89. package/snippets/quantity.html +12 -0
  90. package/snippets/rating.html +26 -0
  91. package/snippets/result.html +31 -0
  92. package/snippets/ribbon.html +48 -0
  93. package/snippets/shot-grid.html +27 -0
  94. package/snippets/sidebar.html +3 -3
  95. package/snippets/spec-list.html +34 -0
  96. package/snippets/stock.html +20 -0
  97. package/snippets/table-actions.html +5 -5
  98. package/snippets/table.html +2 -2
  99. package/snippets/titlebar.html +1 -1
  100. package/snippets/user.html +3 -3
  101. package/dist/parts/app-column-menu.css +0 -85
  102. package/snippets/column-menu.html +0 -38
@@ -0,0 +1,20 @@
1
+ <!-- OmniaUI component: barcode - EAN-13, EAN-8, UPC-A or Code 128 drawn as SVG from a value, no dependency. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/barcode.html | Map: barcode demo markup. Behaviour: barcode.js.
3
+ Class API (modifiers are extra classes / attributes on the same element):
4
+ figure.oc-barcode[data-value]: The barcode. The script replaces its content with the SVG and the digits.
5
+ data-format: auto (default: 12–13 digits EAN-13, 7–8 EAN-8, 11 UPC-A, else Code 128), EAN13, EAN8, UPC or CODE128.
6
+ data-digits="false": Bars only, no digits.
7
+ .oc-barcode--hero / --compact: Large (product page, label) or small (table cell).
8
+ --oc-barcode-height: Height of the bars (4rem).
9
+ [data-error]: Set when the value cannot be encoded (wrong check digit, non-ASCII in Code 128); the reason shows instead of bars.
10
+ encodeBarcode(value, format): Exported: the module string and the text, for your own canvas or PDF.
11
+ barcodeFile(value, { format, digits, moduleWidth, height }): Exported: a print-ready SVG file as text.
12
+ The barcode maker (live preview, download) is the OmniaUI Pro block packages/pro/blocks/barcode-maker.html.
13
+ -->
14
+ <div style="display:flex;flex-wrap:wrap;gap:1.5rem;align-items:center">
15
+ <figure class="oc-barcode oc-barcode--hero" data-value="5400000000010"></figure>
16
+ <figure class="oc-barcode" data-value="SKU-000105"></figure>
17
+ <figure class="oc-barcode" data-value="96385074"></figure>
18
+ <figure class="oc-barcode oc-barcode--compact" data-value="012345678905" data-format="UPC" data-digits="false"></figure>
19
+ <figure class="oc-barcode" data-value="5400000000018"></figure>
20
+ </div>
@@ -0,0 +1,41 @@
1
+ <!-- OmniaUI component: brand-mark - A logo from an icon and text: the mark with a glow in the brand color, a word mark with one part in the brand gradient and a small tagline. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/brand-mark.html | Map: in the header -> sizes.
3
+ Class API (modifiers are extra classes / attributes on the same element):
4
+ .oc-brand-mark: The logo: a link or a span with the icon and the text side by side.
5
+ .oc-brand-mark__icon: The mark (svg or img), 2.25rem, with a drop shadow in brand 1.
6
+ .oc-brand-mark__text: Word mark and tagline stacked.
7
+ .oc-brand-mark__word: The name: --oc-font-display, 800, tight letter spacing.
8
+ .oc-brand-mark__accent: The part of the name in the gradient brand 1 → brand 2.
9
+ .oc-brand-mark__tagline: Mono, uppercase, wide letter spacing, muted.
10
+ .oc-brand-mark--sm / --lg: Smaller (footer) or larger (hero, ecosystem map). The sizes are tokens: --oc-brand-mark-icon, --oc-brand-mark-word, --oc-brand-mark-tagline.
11
+ -->
12
+ <a class="oc-brand-mark" href="#home" aria-label="Company 1, home">
13
+ <svg class="oc-brand-mark__icon" viewBox="0 0 40 40" aria-hidden="true"><defs><linearGradient id="oc-brand-grad" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="var(--oc-brand-1)"/><stop offset="1" stop-color="var(--oc-brand-2)"/></linearGradient></defs><rect width="40" height="40" rx="10" fill="url(#oc-brand-grad)"/><path d="M12 27V13h9a5 5 0 0 1 0 10h-5v4z" fill="var(--oc-background)"/></svg>
14
+ <span class="oc-brand-mark__text">
15
+ <span class="oc-brand-mark__word">Company<span class="oc-brand-mark__accent">1</span></span>
16
+ <span class="oc-brand-mark__tagline">Software &amp; IT</span>
17
+ </span>
18
+ </a>
19
+ <div style="display:flex;flex-wrap:wrap;align-items:center;gap:2.5rem">
20
+ <a class="oc-brand-mark oc-brand-mark--sm" href="#home" aria-label="Company 1, home">
21
+ <svg class="oc-brand-mark__icon" viewBox="0 0 40 40" aria-hidden="true"><defs><linearGradient id="oc-brand-grad-sm" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="var(--oc-brand-1)"/><stop offset="1" stop-color="var(--oc-brand-2)"/></linearGradient></defs><rect width="40" height="40" rx="10" fill="url(#oc-brand-grad-sm)"/><path d="M12 27V13h9a5 5 0 0 1 0 10h-5v4z" fill="var(--oc-background)"/></svg>
22
+ <span class="oc-brand-mark__text">
23
+ <span class="oc-brand-mark__word">Company<span class="oc-brand-mark__accent">1</span></span>
24
+ <span class="oc-brand-mark__tagline">Software &amp; IT</span>
25
+ </span>
26
+ </a>
27
+ <a class="oc-brand-mark" href="#home" aria-label="Company 1, home">
28
+ <svg class="oc-brand-mark__icon" viewBox="0 0 40 40" aria-hidden="true"><defs><linearGradient id="oc-brand-grad-md" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="var(--oc-brand-1)"/><stop offset="1" stop-color="var(--oc-brand-2)"/></linearGradient></defs><rect width="40" height="40" rx="10" fill="url(#oc-brand-grad-md)"/><path d="M12 27V13h9a5 5 0 0 1 0 10h-5v4z" fill="var(--oc-background)"/></svg>
29
+ <span class="oc-brand-mark__text">
30
+ <span class="oc-brand-mark__word">Company<span class="oc-brand-mark__accent">1</span></span>
31
+ <span class="oc-brand-mark__tagline">Software &amp; IT</span>
32
+ </span>
33
+ </a>
34
+ <a class="oc-brand-mark oc-brand-mark--lg" href="#home" aria-label="Company 1, home">
35
+ <svg class="oc-brand-mark__icon" viewBox="0 0 40 40" aria-hidden="true"><defs><linearGradient id="oc-brand-grad-lg" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="var(--oc-brand-1)"/><stop offset="1" stop-color="var(--oc-brand-2)"/></linearGradient></defs><rect width="40" height="40" rx="10" fill="url(#oc-brand-grad-lg)"/><path d="M12 27V13h9a5 5 0 0 1 0 10h-5v4z" fill="var(--oc-background)"/></svg>
36
+ <span class="oc-brand-mark__text">
37
+ <span class="oc-brand-mark__word">Company<span class="oc-brand-mark__accent">1</span></span>
38
+ <span class="oc-brand-mark__tagline">Software &amp; IT</span>
39
+ </span>
40
+ </a>
41
+ </div>
@@ -11,11 +11,11 @@
11
11
  <textarea class="oc-chat-composer__input" id="oc-chat-input" name="message" rows="1" placeholder="Write a message…" required></textarea>
12
12
  <div class="oc-chat-composer__bar">
13
13
  <div class="oc-chat-composer__tools">
14
- <button type="button" class="oc-chat-composer__tool" aria-label="Attach a file">&#128206;</button>
14
+ <button type="button" class="oc-chat-composer__tool" aria-label="Attach a file"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M16.5 6v11.5a4 4 0 0 1-4 4a4 4 0 0 1-4-4V5a2.5 2.5 0 0 1 2.5-2.5A2.5 2.5 0 0 1 13.5 5v10.5a1 1 0 0 1-1 1a1 1 0 0 1-1-1V6H10v9.5a2.5 2.5 0 0 0 2.5 2.5a2.5 2.5 0 0 0 2.5-2.5V5a4 4 0 0 0-4-4a4 4 0 0 0-4 4v12.5a5.5 5.5 0 0 0 5.5 5.5a5.5 5.5 0 0 0 5.5-5.5V6z"/></svg></button>
15
15
  <button type="button" class="oc-chat-composer__tool" aria-label="Mention someone">@</button>
16
- <button type="button" class="oc-chat-composer__tool" aria-label="Insert emoji">&#128578;</button>
16
+ <button type="button" class="oc-chat-composer__tool" aria-label="Insert emoji"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M20 12a8 8 0 0 0-8-8a8 8 0 0 0-8 8a8 8 0 0 0 8 8a8 8 0 0 0 8-8m2 0a10 10 0 0 1-10 10A10 10 0 0 1 2 12A10 10 0 0 1 12 2a10 10 0 0 1 10 10m-12-3.5c0 .8-.7 1.5-1.5 1.5S7 9.3 7 8.5S7.7 7 8.5 7s1.5.7 1.5 1.5m7 0c0 .8-.7 1.5-1.5 1.5S14 9.3 14 8.5S14.7 7 15.5 7s1.5.7 1.5 1.5m-5 9.73c-1.75 0-3.29-.73-4.19-1.81L9.23 14c.45.72 1.52 1.23 2.77 1.23s2.32-.51 2.77-1.23l1.42 1.42c-.9 1.08-2.44 1.81-4.19 1.81"/></svg></button>
17
17
  </div>
18
18
  <span class="oc-chat-composer__hint">Enter for a new line</span>
19
- <button type="submit" class="oc-chat-composer__send" aria-label="Send">&#10148;</button>
19
+ <button type="submit" class="oc-chat-composer__send" aria-label="Send"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M2 21l21-9L2 3v7l15 2l-15 2z"/></svg></button>
20
20
  </div>
21
21
  </form>
@@ -1,21 +1,17 @@
1
- <!-- OmniaUI component: data-table - List table from Korrekt and OmniaDesk: search, sort, pages, columns, resize, drag, trash filter and bulk actions. Needs @birdycom/omniaui CSS.
2
- File: packages/ui/snippets/data-table.html | Map: shell -> toolbar (gear, search, pills, view) -> bulk bar -> table -> footer. Behaviour: src/data-table.js
1
+ <!-- OmniaUI component: data-table - List table for business apps: search, sort, pages, trash filter and bulk actions. Needs @birdycom/omniaui CSS.
2
+ Behaviour: data-table.js (npx omniaui copy-js data-table). Webicons: iconify-icon.
3
+ File: packages/ui/snippets/data-table.html | Map: toolbar (list actions, search, trash pills, view, New) -> bulk bar -> table (sort) -> footer. Behaviour: src/data-table.js
3
4
  -->
4
- <div class="oc-data-table oc-column-menu-scope" id="oc-articles" data-page-size="3" data-oc-live="true" style="--oc-data-table-max: 18rem">
5
+ <div class="oc-data-table" id="oc-articles" data-page-size="3" data-oc-live="true" style="--oc-data-table-max: 18rem">
5
6
  <div class="oc-data-table-toolbar">
6
7
  <div class="oc-data-table-heading">
7
8
  <span class="oc-data-table-title">Articles</span>
8
- <button class="oc-btn oc-btn--outline oc-btn--icon oc-btn--sm" type="button" popovertarget="oc-articles-menu" aria-label="Table actions">
9
- <svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill="currentColor" d="M7.2 1.2h1.6l.3 1.5a4 4 0 0 1 1.1.6l1.4-.6 1.1 1.1-.6 1.4c.3.3.5.7.6 1.1l1.5.3v1.6l-1.5.3a4 4 0 0 1-.6 1.1l.6 1.4-1.1 1.1-1.4-.6a4 4 0 0 1-1.1.6l-.3 1.5H7.2l-.3-1.5a4 4 0 0 1-1.1-.6l-1.4.6-1.1-1.1.6-1.4a4 4 0 0 1-.6-1.1L1.8 8.8V7.2l1.5-.3c.1-.4.3-.8.6-1.1l-.6-1.4 1.1-1.1 1.4.6a4 4 0 0 1 1.1-.6l.3-1.5zM8 6.2a1.8 1.8 0 1 0 0 3.6 1.8 1.8 0 0 0 0-3.6z"/></svg>
10
- </button>
11
- <div class="oc-dropdown-menu" id="oc-articles-menu" popover>
12
- <button class="oc-dropdown-item" type="button" data-oc-export>Export CSV</button>
13
- <button class="oc-dropdown-item" type="button" data-oc-import>Import CSV</button>
14
- <input class="oc-data-table-file" type="file" accept=".csv,text/csv" data-oc-file>
9
+ <button class="oc-btn oc-btn--outline oc-btn--icon oc-btn--sm" type="button" popovertarget="oc-articles-menu" aria-label="List actions" title="List actions"><iconify-icon icon="mdi:tune-variant" aria-hidden="true"></iconify-icon></button>
10
+ <div class="oc-dropdown-menu" id="oc-articles-menu" popover="">
11
+ <button class="oc-dropdown-item" type="button" data-oc-export="">Export CSV</button>
15
12
  <div class="oc-dropdown-separator"></div>
16
13
  <button class="oc-dropdown-item" type="button" data-oc-density="comfortable">Comfortable rows</button>
17
14
  <button class="oc-dropdown-item" type="button" data-oc-density="compact">Compact rows</button>
18
- <button class="oc-dropdown-item" type="button" data-oc-reset-widths>Reset column widths</button>
19
15
  </div>
20
16
  </div>
21
17
  <input class="oc-input oc-data-table-search" type="search" placeholder="Search articles..." aria-label="Search articles">
@@ -26,28 +22,14 @@
26
22
  <button class="oc-filter-pill" type="button" data-oc-filter="archived">Archive only</button>
27
23
  </div>
28
24
  <div class="oc-data-table-view" role="group" aria-label="View">
29
- <button class="oc-btn oc-btn--outline oc-btn--sm" type="button" data-oc-view="table" aria-pressed="true">Table</button>
30
- <button class="oc-btn oc-btn--outline oc-btn--sm" type="button" data-oc-view="grid">Cards</button>
25
+ <button class="oc-btn oc-btn--outline oc-btn--icon oc-btn--sm" type="button" data-oc-view="table" aria-pressed="true" aria-label="Table"><iconify-icon icon="mdi:format-list-bulleted" aria-hidden="true"></iconify-icon></button>
26
+ <button class="oc-btn oc-btn--outline oc-btn--icon oc-btn--sm" type="button" data-oc-view="grid" aria-label="Cards"><iconify-icon icon="mdi:view-grid-outline" aria-hidden="true"></iconify-icon></button>
31
27
  </div>
32
- <div class="oc-data-table-actions"><button class="oc-btn oc-btn--sm" type="button">New article</button></div>
33
- <p class="oc-data-table-sort-summary" data-oc-sort-summary role="status"></p>
34
- </div>
35
- <div class="oc-table-toolbar">
36
- <span class="oc-table-toolbar-spacer"></span>
37
- <button class="oc-btn oc-btn--outline oc-btn--sm" type="button" popovertarget="oc-articles-columns">Columns</button>
38
- </div>
39
- <div class="oc-column-menu" id="oc-articles-columns" popover>
40
- <p class="oc-column-menu-title">Visible columns</p>
41
- <form class="oc-column-menu-list">
42
- <label class="oc-column-menu-item"><input type="checkbox" data-col="3" checked> Article ID</label>
43
- <label class="oc-column-menu-item"><input type="checkbox" data-col="4" checked> Name</label>
44
- <label class="oc-column-menu-item"><input type="checkbox" data-col="5" checked> Price</label>
45
- <label class="oc-column-menu-item"><input type="checkbox" data-col="6"> Supplier</label>
46
- <label class="oc-column-menu-item"><input type="checkbox" data-col="7" checked> Status</label>
47
- </form>
28
+ <div class="oc-data-table-actions"><button class="oc-btn oc-btn--sm" type="button"><iconify-icon icon="mdi:plus" aria-hidden="true"></iconify-icon>New article</button></div>
29
+ <p class="oc-data-table-sort-summary" data-oc-sort-summary="" role="status"></p>
48
30
  </div>
49
31
  <div class="oc-data-table-bulk" hidden>
50
- <span data-oc-selected-count>0 selected</span>
32
+ <span data-oc-selected-count="">0 selected</span>
51
33
  <button class="oc-btn oc-btn--outline oc-btn--sm" type="button" data-oc-bulk="export">Export selection</button>
52
34
  <button class="oc-btn oc-btn--outline oc-btn--sm" type="button" data-oc-bulk="duplicate">Duplicate</button>
53
35
  <button class="oc-btn oc-btn--outline oc-btn--sm" type="button" data-oc-bulk="archive">Move to trash</button>
@@ -60,76 +42,69 @@
60
42
  <table class="oc-table oc-data-table-table">
61
43
  <thead>
62
44
  <tr>
63
- <th data-oc-col="select" class="oc-data-table-select"><input class="oc-checkbox" type="checkbox" data-oc-select-all aria-label="Select all"></th>
64
- <th data-oc-col="order"><span class="oc-visually-hidden">Order</span></th>
65
- <th data-oc-col="sku" data-oc-sort="text"><span class="oc-data-table-th"><button class="oc-table-sort" type="button">Article ID</button><span class="oc-data-table-resize" role="separator" aria-orientation="vertical" aria-label="Resize Article ID"></span></span></th>
66
- <th data-oc-col="name" data-oc-sort="text"><span class="oc-data-table-th"><button class="oc-table-sort" type="button">Name</button><span class="oc-data-table-resize" role="separator" aria-orientation="vertical" aria-label="Resize Name"></span></span></th>
67
- <th data-oc-col="price" data-oc-sort="numeric" data-numeric><span class="oc-data-table-th"><button class="oc-table-sort" type="button">Price</button><span class="oc-data-table-resize" role="separator" aria-orientation="vertical" aria-label="Resize Price"></span></span></th>
68
- <th data-oc-col="supplier" data-oc-sort="text"><span class="oc-data-table-th"><button class="oc-table-sort" type="button">Supplier</button><span class="oc-data-table-resize" role="separator" aria-orientation="vertical" aria-label="Resize Supplier"></span></span></th>
45
+ <th data-oc-col="select" class="oc-data-table-select"><input class="oc-checkbox" type="checkbox" data-oc-select-all="" aria-label="Select all"></th>
46
+ <th data-oc-col="sku" data-oc-sort="text" aria-sort="ascending"><span class="oc-data-table-th"><button class="oc-table-sort" type="button">Article ID</button></span></th>
47
+ <th data-oc-col="name" data-oc-sort="text"><span class="oc-data-table-th"><button class="oc-table-sort" type="button">Name</button></span></th>
48
+ <th data-oc-col="price" data-oc-sort="numeric" data-numeric=""><span class="oc-data-table-th"><button class="oc-table-sort" type="button">Price</button></span></th>
49
+ <th data-oc-col="supplier" data-oc-sort="text"><span class="oc-data-table-th"><button class="oc-table-sort" type="button">Supplier</button></span></th>
69
50
  <th data-oc-col="status" data-oc-sort="text"><span class="oc-data-table-th"><button class="oc-table-sort" type="button">Status</button></span></th>
70
- <th data-oc-col="actions"><span class="oc-visually-hidden">Actions</span></th>
51
+ <th data-oc-col="actions" style="width:7.5rem"><span class="oc-data-table-th">Actions</span></th>
71
52
  </tr>
72
53
  </thead>
73
54
  <tbody>
74
- <tr data-oc-row data-oc-key="schar" data-oc-status="active">
75
- <td data-oc-col="select"><input class="oc-checkbox" type="checkbox" data-oc-select aria-label="Select Scharnier"></td>
76
- <td data-oc-col="order" class="oc-sortable-row-grip-cell"><button class="oc-sortable-row-grip" type="button" aria-label="Move Scharnier"></button></td>
55
+ <tr data-oc-row="" data-oc-key="schar" data-oc-status="active">
56
+ <td data-oc-col="select"><input class="oc-checkbox" type="checkbox" data-oc-select="" aria-label="Select Scharnier"></td>
77
57
  <td data-oc-col="sku">SET-SCHAR-1105C-ONS</td>
78
58
  <td data-oc-col="name">Scharnier 1105</td>
79
- <td data-oc-col="price" data-numeric data-oc-value="5.15">5,15</td>
80
- <td data-oc-col="supplier">Van Hoecke</td>
59
+ <td data-oc-col="price" data-numeric="" data-oc-value="5.15">5,15</td>
60
+ <td data-oc-col="supplier">Supplier 1</td>
81
61
  <td data-oc-col="status"><span class="oc-badge oc-badge--success">Active</span></td>
82
- <td data-oc-col="actions" class="oc-table-actions"><button class="oc-table-row-action" type="button">Edit</button></td>
62
+ <td data-oc-col="actions"><button class="oc-btn oc-btn--soft-primary oc-btn--icon oc-btn--sm" type="button" aria-label="Edit" title="Edit"><iconify-icon icon="mdi:pencil-outline" aria-hidden="true"></iconify-icon></button></td>
83
63
  </tr>
84
- <tr data-oc-row data-oc-key="greep" data-oc-status="active">
85
- <td data-oc-col="select"><input class="oc-checkbox" type="checkbox" data-oc-select aria-label="Select Greep"></td>
86
- <td data-oc-col="order" class="oc-sortable-row-grip-cell"><button class="oc-sortable-row-grip" type="button" aria-label="Move Greep"></button></td>
64
+ <tr data-oc-row="" data-oc-key="greep" data-oc-status="active">
65
+ <td data-oc-col="select"><input class="oc-checkbox" type="checkbox" data-oc-select="" aria-label="Select Greep"></td>
87
66
  <td data-oc-col="sku">SET-GREEP-40</td>
88
67
  <td data-oc-col="name">Greep 40</td>
89
- <td data-oc-col="price" data-numeric data-oc-value="12.4">12,40</td>
90
- <td data-oc-col="supplier">Van Hoecke</td>
68
+ <td data-oc-col="price" data-numeric="" data-oc-value="12.4">12,40</td>
69
+ <td data-oc-col="supplier">Supplier 1</td>
91
70
  <td data-oc-col="status"><span class="oc-badge oc-badge--success">Active</span></td>
92
- <td data-oc-col="actions" class="oc-table-actions"><button class="oc-table-row-action" type="button">Edit</button></td>
71
+ <td data-oc-col="actions"><button class="oc-btn oc-btn--soft-primary oc-btn--icon oc-btn--sm" type="button" aria-label="Edit" title="Edit"><iconify-icon icon="mdi:pencil-outline" aria-hidden="true"></iconify-icon></button></td>
93
72
  </tr>
94
- <tr data-oc-row data-oc-key="plaat" data-oc-status="active">
95
- <td data-oc-col="select"><input class="oc-checkbox" type="checkbox" data-oc-select aria-label="Select Plaat"></td>
96
- <td data-oc-col="order" class="oc-sortable-row-grip-cell"><button class="oc-sortable-row-grip" type="button" aria-label="Move Plaat"></button></td>
73
+ <tr data-oc-row="" data-oc-key="plaat" data-oc-status="active">
74
+ <td data-oc-col="select"><input class="oc-checkbox" type="checkbox" data-oc-select="" aria-label="Select Plaat"></td>
97
75
  <td data-oc-col="sku">PLAAT-18-WIT</td>
98
76
  <td data-oc-col="name">Plaat 18 wit</td>
99
- <td data-oc-col="price" data-numeric data-oc-value="28">28,00</td>
100
- <td data-oc-col="supplier">Egger</td>
77
+ <td data-oc-col="price" data-numeric="" data-oc-value="28">28,00</td>
78
+ <td data-oc-col="supplier">Supplier 2</td>
101
79
  <td data-oc-col="status"><span class="oc-badge oc-badge--success">Active</span></td>
102
- <td data-oc-col="actions" class="oc-table-actions"><button class="oc-table-row-action" type="button">Edit</button></td>
80
+ <td data-oc-col="actions"><button class="oc-btn oc-btn--soft-primary oc-btn--icon oc-btn--sm" type="button" aria-label="Edit" title="Edit"><iconify-icon icon="mdi:pencil-outline" aria-hidden="true"></iconify-icon></button></td>
103
81
  </tr>
104
- <tr data-oc-row data-oc-key="led" data-oc-status="active">
105
- <td data-oc-col="select"><input class="oc-checkbox" type="checkbox" data-oc-select aria-label="Select LED"></td>
106
- <td data-oc-col="order" class="oc-sortable-row-grip-cell"><button class="oc-sortable-row-grip" type="button" aria-label="Move LED"></button></td>
82
+ <tr data-oc-row="" data-oc-key="led" data-oc-status="active">
83
+ <td data-oc-col="select"><input class="oc-checkbox" type="checkbox" data-oc-select="" aria-label="Select LED"></td>
107
84
  <td data-oc-col="sku">LED-STRIP-2M</td>
108
85
  <td data-oc-col="name">LED strip</td>
109
- <td data-oc-col="price" data-numeric data-oc-value="16.9">16,90</td>
110
- <td data-oc-col="supplier">Egger</td>
86
+ <td data-oc-col="price" data-numeric="" data-oc-value="16.9">16,90</td>
87
+ <td data-oc-col="supplier">Supplier 2</td>
111
88
  <td data-oc-col="status"><span class="oc-badge oc-badge--success">Active</span></td>
112
- <td data-oc-col="actions" class="oc-table-actions"><button class="oc-table-row-action" type="button">Edit</button></td>
89
+ <td data-oc-col="actions"><button class="oc-btn oc-btn--soft-primary oc-btn--icon oc-btn--sm" type="button" aria-label="Edit" title="Edit"><iconify-icon icon="mdi:pencil-outline" aria-hidden="true"></iconify-icon></button></td>
113
90
  </tr>
114
- <tr data-oc-row data-oc-key="schroef" data-oc-status="deleted">
115
- <td data-oc-col="select"><input class="oc-checkbox" type="checkbox" data-oc-select aria-label="Select Schroef"></td>
116
- <td data-oc-col="order" class="oc-sortable-row-grip-cell"><button class="oc-sortable-row-grip" type="button" aria-label="Move Schroef"></button></td>
91
+ <tr data-oc-row="" data-oc-key="schroef" data-oc-status="deleted">
92
+ <td data-oc-col="select"><input class="oc-checkbox" type="checkbox" data-oc-select="" aria-label="Select Schroef"></td>
117
93
  <td data-oc-col="sku">SCHROEF-4X40</td>
118
94
  <td data-oc-col="name">Schroef 4x40</td>
119
- <td data-oc-col="price" data-numeric data-oc-value="0.08">0,08</td>
120
- <td data-oc-col="supplier">Van Hoecke</td>
95
+ <td data-oc-col="price" data-numeric="" data-oc-value="0.08">0,08</td>
96
+ <td data-oc-col="supplier">Supplier 1</td>
121
97
  <td data-oc-col="status"><span class="oc-badge oc-badge--secondary">Deleted</span></td>
122
- <td data-oc-col="actions" class="oc-table-actions"><button class="oc-table-row-action" type="button">Edit</button></td>
98
+ <td data-oc-col="actions"><button class="oc-btn oc-btn--soft-primary oc-btn--icon oc-btn--sm" type="button" aria-label="Edit" title="Edit"><iconify-icon icon="mdi:pencil-outline" aria-hidden="true"></iconify-icon></button></td>
123
99
  </tr>
124
- <tr data-oc-row data-oc-key="kast" data-oc-status="archived">
125
- <td data-oc-col="select"><input class="oc-checkbox" type="checkbox" data-oc-select aria-label="Select Kast"></td>
126
- <td data-oc-col="order" class="oc-sortable-row-grip-cell"><button class="oc-sortable-row-grip" type="button" aria-label="Move Kast"></button></td>
100
+ <tr data-oc-row="" data-oc-key="kast" data-oc-status="archived">
101
+ <td data-oc-col="select"><input class="oc-checkbox" type="checkbox" data-oc-select="" aria-label="Select Kast"></td>
127
102
  <td data-oc-col="sku">ARCH-KAST-60</td>
128
103
  <td data-oc-col="name">Kast 60</td>
129
- <td data-oc-col="price" data-numeric data-oc-value="240">240,00</td>
130
- <td data-oc-col="supplier">Egger</td>
104
+ <td data-oc-col="price" data-numeric="" data-oc-value="240">240,00</td>
105
+ <td data-oc-col="supplier">Supplier 2</td>
131
106
  <td data-oc-col="status"><span class="oc-badge oc-badge--secondary">Archived</span></td>
132
- <td data-oc-col="actions" class="oc-table-actions"><button class="oc-table-row-action" type="button">Edit</button></td>
107
+ <td data-oc-col="actions"><button class="oc-btn oc-btn--soft-primary oc-btn--icon oc-btn--sm" type="button" aria-label="Edit" title="Edit"><iconify-icon icon="mdi:pencil-outline" aria-hidden="true"></iconify-icon></button></td>
133
108
  </tr>
134
109
  </tbody>
135
110
  </table>
@@ -137,15 +112,15 @@
137
112
  <p class="oc-data-table-empty" hidden>No results</p>
138
113
  </div>
139
114
  <div class="oc-data-table-footer">
140
- <p class="oc-data-table-summary" data-oc-summary>Showing 1–3 of 4</p>
115
+ <p class="oc-data-table-summary" data-oc-summary="">Showing 1–3 of 4</p>
141
116
  <label class="oc-data-table-per-page">Rows per page
142
- <select class="oc-select" data-oc-page-size aria-label="Rows per page">
117
+ <select class="oc-select" data-oc-page-size="" aria-label="Rows per page">
143
118
  <option value="3" selected>3</option>
144
119
  <option value="5">5</option>
145
120
  <option value="10">10</option>
146
121
  <option value="15">15</option>
147
122
  </select>
148
123
  </label>
149
- <nav class="oc-data-table-pager" data-oc-pager aria-label="Pagination"></nav>
124
+ <nav class="oc-data-table-pager" data-oc-pager="" aria-label="Pagination"></nav>
150
125
  </div>
151
126
  </div>
@@ -0,0 +1,44 @@
1
+ <!-- OmniaUI component: date-field - Native date input with a calendar icon zone and the ISO week (Week 45) next to it. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/date-field.html | Map: date field demo markup. Behaviour: form-extras.js.
3
+ Class API (modifiers are extra classes / attributes on the same element):
4
+ .oc-date-field: The frame around icon, input and week; focus ring on the frame.
5
+ .oc-date-field__icon: The calendar icon zone with a line after it.
6
+ input.oc-date-field__input[type=date]: The native date input (value YYYY-MM-DD).
7
+ output.oc-date-field__week: With form-extras.js: the ISO week of the date, "Week 45". Template: data-oc-week="W{week} · {year}". Hidden without a date.
8
+ .oc-date-field--sm: 2rem high (also inside .oc-density-compact).
9
+ isoWeek(date): Exported from form-extras.js: { week, year } after ISO 8601 (week 1 holds the first Thursday).
10
+ -->
11
+ <div style="display:flex;flex-wrap:wrap;gap:1.5rem;align-items:end">
12
+ <div class="oc-field">
13
+ <label class="oc-field-label" for="oc-date-delivery">Delivery date</label>
14
+ <div class="oc-date-field">
15
+ <span class="oc-date-field__icon"><iconify-icon icon="mdi:calendar-blank-outline" aria-hidden="true"></iconify-icon></span>
16
+ <input class="oc-date-field__input" id="oc-date-delivery" type="date" value="2026-11-12">
17
+ <output class="oc-date-field__week" for="oc-date-delivery"></output>
18
+ </div>
19
+ </div>
20
+ <div class="oc-field">
21
+ <label class="oc-field-label" for="oc-date-start">Start of works</label>
22
+ <div class="oc-date-field">
23
+ <span class="oc-date-field__icon"><iconify-icon icon="mdi:calendar-blank-outline" aria-hidden="true"></iconify-icon></span>
24
+ <input class="oc-date-field__input" id="oc-date-start" type="date" value="2027-01-01">
25
+ <output class="oc-date-field__week" for="oc-date-start" data-oc-week="Week {week} · {year}"></output>
26
+ </div>
27
+ </div>
28
+ <div class="oc-field">
29
+ <label class="oc-field-label" for="oc-date-plain">Without week</label>
30
+ <div class="oc-date-field">
31
+ <span class="oc-date-field__icon"><iconify-icon icon="mdi:calendar-blank-outline" aria-hidden="true"></iconify-icon></span>
32
+ <input class="oc-date-field__input" id="oc-date-plain" type="date" value="2026-12-24">
33
+
34
+ </div>
35
+ </div>
36
+ <div class="oc-field">
37
+ <label class="oc-field-label" for="oc-date-small">Small</label>
38
+ <div class="oc-date-field oc-date-field--sm">
39
+ <span class="oc-date-field__icon"><iconify-icon icon="mdi:calendar-blank-outline" aria-hidden="true"></iconify-icon></span>
40
+ <input class="oc-date-field__input" id="oc-date-small" type="date" value="2026-11-03">
41
+ <output class="oc-date-field__week" for="oc-date-small"></output>
42
+ </div>
43
+ </div>
44
+ </div>
@@ -38,7 +38,7 @@
38
38
  <div class="oc-doc-viewer-dialog__bar">
39
39
  <h2 class="oc-doc-viewer-dialog__title" id="oc-doc-viewer-demo-pdf-title">Brochure 2026</h2>
40
40
  <div class="oc-doc-viewer-dialog__actions">
41
- <a class="oc-btn oc-btn--outline oc-btn--sm" href="#brochure.pdf" download>Download</a>
41
+ <a class="oc-btn oc-btn--outline oc-btn--sm" href="#brochure.pdf">Download</a>
42
42
  <button type="button" class="oc-doc-viewer-dialog__close" command="close" commandfor="oc-doc-viewer-demo-pdf" aria-label="Close">&#10005;</button>
43
43
  </div>
44
44
  </div>
@@ -7,7 +7,7 @@
7
7
  -->
8
8
  <div style="display:flex;gap:0.5rem;align-items:center">
9
9
  <input class="oc-input" id="oc-emoji-field" placeholder="Say something nice" style="inline-size:16rem">
10
- <button type="button" class="oc-emoji-picker__trigger" popovertarget="oc-emoji-demo" aria-label="Insert emoji">&#128578;</button>
10
+ <button type="button" class="oc-emoji-picker__trigger" popovertarget="oc-emoji-demo" aria-label="Insert emoji"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M20 12a8 8 0 0 0-8-8a8 8 0 0 0-8 8a8 8 0 0 0 8 8a8 8 0 0 0 8-8m2 0a10 10 0 0 1-10 10A10 10 0 0 1 2 12A10 10 0 0 1 12 2a10 10 0 0 1 10 10m-12-3.5c0 .8-.7 1.5-1.5 1.5S7 9.3 7 8.5S7.7 7 8.5 7s1.5.7 1.5 1.5m7 0c0 .8-.7 1.5-1.5 1.5S14 9.3 14 8.5S14.7 7 15.5 7s1.5.7 1.5 1.5m-5 9.73c-1.75 0-3.29-.73-4.19-1.81L9.23 14c.45.72 1.52 1.23 2.77 1.23s2.32-.51 2.77-1.23l1.42 1.42c-.9 1.08-2.44 1.81-4.19 1.81"/></svg></button>
11
11
  </div>
12
12
  <div class="oc-emoji-picker" id="oc-emoji-demo" popover data-oc-emoji-target="#oc-emoji-field" aria-label="Emoji">
13
13
  <p class="oc-emoji-picker__label">Smileys</p>
@@ -0,0 +1,52 @@
1
+ <!-- OmniaUI component: feature-card - Cards for services and features (icon tile, title, text) and cards that are links, in a grid whose column width you set. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/feature-card.html | Map: services -> link cards -> brand chips.
3
+ Class API (modifiers are extra classes / attributes on the same element):
4
+ .oc-feature-card: Card: tile, title, text; surface background, the border turns strong on hover.
5
+ .oc-feature-card__title / __text: Title (display font, 1.2rem) and muted text.
6
+ .oc-link-card: A card that is an <a>: __title, __text, __more (arrow moves on hover); the border takes the accent color on hover (.oc-accent--violet …).
7
+ .oc-card-grid: Auto-fill grid; --oc-card-min is the minimum column width (17rem), --oc-card-gap the gap.
8
+ .oc-card-grid--wide: Wide cards (projects): from 32rem, three in a row from 1280px.
9
+ .oc-tag-list--neutral / --lg: Chips without the accent color / larger chips in the display font (a strip of brand names).
10
+ -->
11
+ <div class="oc-card-grid" style="--oc-card-min: 15.5rem; inline-size:100%">
12
+ <article class="oc-feature-card">
13
+ <span class="oc-icon-tile oc-icon-tile--sm" aria-hidden="true"><iconify-icon icon="mdi:application-outline"></iconify-icon></span>
14
+ <h3 class="oc-feature-card__title">Business apps</h3>
15
+ <p class="oc-feature-card__text">Software built around how your company works.</p>
16
+ </article>
17
+ <article class="oc-feature-card">
18
+ <span class="oc-icon-tile oc-icon-tile--sm" aria-hidden="true"><iconify-icon icon="mdi:web"></iconify-icon></span>
19
+ <h3 class="oc-feature-card__title">Websites</h3>
20
+ <p class="oc-feature-card__text">Fast sites you can edit yourself.</p>
21
+ </article>
22
+ <article class="oc-feature-card">
23
+ <span class="oc-icon-tile oc-icon-tile--sm" aria-hidden="true"><iconify-icon icon="mdi:laptop"></iconify-icon></span>
24
+ <h3 class="oc-feature-card__title">Hardware</h3>
25
+ <p class="oc-feature-card__text">Computers, screens and networks, installed on site.</p>
26
+ </article>
27
+ <article class="oc-feature-card">
28
+ <span class="oc-icon-tile oc-icon-tile--sm" aria-hidden="true"><iconify-icon icon="mdi:headset"></iconify-icon></span>
29
+ <h3 class="oc-feature-card__title">Support</h3>
30
+ <p class="oc-feature-card__text">One point of contact for every question.</p>
31
+ </article>
32
+ </div>
33
+ <div class="oc-card-grid" style="--oc-card-min: 16rem; inline-size:100%">
34
+ <a class="oc-link-card oc-accent--violet" href="#agent-1">
35
+ <span class="oc-icon-tile oc-icon-tile--sm oc-accent--violet" aria-hidden="true"><iconify-icon icon="mdi:robot-outline"></iconify-icon></span>
36
+ <span class="oc-link-card__title">Agent 1</span>
37
+ <span class="oc-link-card__text">Answers questions about your own documents.</span>
38
+ <span class="oc-link-card__more">Read more</span>
39
+ </a>
40
+ <a class="oc-link-card oc-accent--violet" href="#agent-2">
41
+ <span class="oc-icon-tile oc-icon-tile--sm oc-accent--violet" aria-hidden="true"><iconify-icon icon="mdi:file-search-outline"></iconify-icon></span>
42
+ <span class="oc-link-card__title">Agent 2</span>
43
+ <span class="oc-link-card__text">Reads incoming invoices and fills in the booking.</span>
44
+ <span class="oc-link-card__more">Read more</span>
45
+ </a>
46
+ </div>
47
+ <div style="display:grid;gap:1rem">
48
+ <ul class="oc-tag-list oc-tag-list--neutral oc-tag-list--lg" aria-label="Brands we work with">
49
+ <li>Brand 1</li><li>Brand 2</li><li>Brand 3</li><li>Brand 4</li><li>Brand 5</li>
50
+ </ul>
51
+ <p class="oc-note" style="margin:0">Other brands on request.</p>
52
+ </div>
@@ -0,0 +1,30 @@
1
+ <!-- OmniaUI component: fly-in - Cards that fly in from the middle of their row when they scroll into view, with a hover lift that keeps working, and a New badge in a product card. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/fly-in.html | Map: product cards.
3
+ Behaviour: fly.js (npx omniaui copy-js fly); works without it.
4
+ Class API (modifiers are extra classes / attributes on the same element):
5
+ .oc-reveal--fly: A card that flies in. Hidden only while html.oc-fly-ready is set (by fly.js) and the card is not yet .is-visible.
6
+ --oc-fly-x: Start offset from the middle of the row; fly.js sets it per card.
7
+ .is-visible: Added by fly.js when the card comes into view; the card flies to its place.
8
+ .oc-product-card__badge: A small New label after the name of a product card (with .oc-pill).
9
+ initFly(scope): Exported from @birdycom/omniaui/fly.js; returns a function that stops watching.
10
+ -->
11
+ <div class="oc-card-grid" style="inline-size:100%">
12
+ <a class="oc-product-card oc-reveal--fly oc-accent--blue" href="#product-1">
13
+ <h3 class="oc-product-card__name">Product 1</h3>
14
+ <p class="oc-product-card__tagline">Plan every shift</p>
15
+ <p class="oc-product-card__summary">Schedules and leave in one view.</p>
16
+ <span class="oc-product-card__more">Read more</span>
17
+ </a>
18
+ <a class="oc-product-card oc-reveal--fly oc-accent--green" href="#product-2">
19
+ <h3 class="oc-product-card__name">Product 2 <span class="oc-product-card__badge oc-pill oc-pill--accent">New</span></h3>
20
+ <p class="oc-product-card__tagline">Quotes in minutes</p>
21
+ <p class="oc-product-card__summary">From quote to invoice without typing twice.</p>
22
+ <span class="oc-product-card__more">Read more</span>
23
+ </a>
24
+ <a class="oc-product-card oc-reveal--fly oc-accent--violet" href="#product-3">
25
+ <h3 class="oc-product-card__name">Product 3</h3>
26
+ <p class="oc-product-card__tagline">Your shop online</p>
27
+ <p class="oc-product-card__summary">Products, stock and orders in one place.</p>
28
+ <span class="oc-product-card__more">Read more</span>
29
+ </a>
30
+ </div>
@@ -0,0 +1,25 @@
1
+ <!-- OmniaUI component: form-density - Compact forms: .oc-density-compact makes every control in it 2rem high instead of 2.5rem. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/form-density.html | Map: form density demo markup.
3
+ Class API (modifiers are extra classes / attributes on the same element):
4
+ .oc-density-compact: On a form or wrapper: controls inside are 2rem high, labels and gaps a step smaller.
5
+ -->
6
+ <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(16rem,1fr));gap:1rem;inline-size:100%">
7
+ <form class="" style="display:grid;gap:0.75rem;padding:1rem;border:1px solid var(--oc-border);border-radius:var(--oc-radius)" onsubmit="event.preventDefault()">
8
+ <p style="margin:0;font-weight:600">Standard (2.5rem)</p>
9
+ <div class="oc-field"><label class="oc-field-label" for="d-desc">Description</label><input class="oc-input" id="d-desc" value="Article 1"></div>
10
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:0.75rem">
11
+ <div class="oc-field"><label class="oc-field-label" for="d-qty">Quantity</label><input class="oc-input" id="d-qty" value="2"></div>
12
+ <div class="oc-field"><label class="oc-field-label" for="d-vat">VAT</label><select class="oc-select" id="d-vat"><option>21%</option><option>6%</option></select></div>
13
+ </div>
14
+ <div style="display:flex;gap:0.5rem"><button class="oc-btn oc-btn--sm" type="submit"><iconify-icon icon="mdi:content-save-outline" aria-hidden="true"></iconify-icon>Save</button><button class="oc-btn oc-btn--outline oc-btn--sm" type="button">Cancel</button></div>
15
+ </form>
16
+ <form class="oc-density-compact" style="display:grid;gap:0.75rem;padding:1rem;border:1px solid var(--oc-border);border-radius:var(--oc-radius)" onsubmit="event.preventDefault()">
17
+ <p style="margin:0;font-weight:600">Compact (2rem)</p>
18
+ <div class="oc-field"><label class="oc-field-label" for="oc-density-compact-desc">Description</label><input class="oc-input" id="oc-density-compact-desc" value="Article 1"></div>
19
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:0.75rem">
20
+ <div class="oc-field"><label class="oc-field-label" for="oc-density-compact-qty">Quantity</label><input class="oc-input" id="oc-density-compact-qty" value="2"></div>
21
+ <div class="oc-field"><label class="oc-field-label" for="oc-density-compact-vat">VAT</label><select class="oc-select" id="oc-density-compact-vat"><option>21%</option><option>6%</option></select></div>
22
+ </div>
23
+ <div style="display:flex;gap:0.5rem"><button class="oc-btn oc-btn--sm" type="submit"><iconify-icon icon="mdi:content-save-outline" aria-hidden="true"></iconify-icon>Save</button><button class="oc-btn oc-btn--outline oc-btn--sm" type="button">Cancel</button></div>
24
+ </form>
25
+ </div>
@@ -0,0 +1,47 @@
1
+ <!-- OmniaUI component: form-section - Collapsible part of a long form with an icon, title, hint and status; red edge while a field inside is invalid. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/form-section.html | Map: form section demo markup.
3
+ Class API (modifiers are extra classes / attributes on the same element):
4
+ .oc-form-section: A <details>; same name on siblings = one open at a time.
5
+ .oc-form-section__summary: Icon, heading (title + hint), status and a chevron.
6
+ .oc-form-section__icon: The webicon of the section in a tinted square.
7
+ .oc-form-section__status: Free slot: a badge (Complete, 1 error), a count …
8
+ .oc-form-section__body: The fields in a responsive grid; .oc-form-section__wide spans the full row.
9
+ :user-invalid / [aria-invalid]: A field that fails validation after the user touched it colors the section red.
10
+ -->
11
+ <form style="inline-size:min(100%,44rem)" onsubmit="event.preventDefault()">
12
+ <details class="oc-form-section" name="contact" open>
13
+ <summary class="oc-form-section__summary">
14
+ <span class="oc-form-section__icon"><iconify-icon icon="mdi:card-account-details-outline" aria-hidden="true"></iconify-icon></span>
15
+ <span class="oc-form-section__heading"><span class="oc-form-section__title">General</span><span class="oc-form-section__hint">Name, VAT number and type</span></span>
16
+ <span class="oc-form-section__status"><span class="oc-badge oc-badge--success">Complete</span></span>
17
+ </summary>
18
+ <div class="oc-form-section__body">
19
+ <div class="oc-field"><label class="oc-field-label" for="fs-name">Name</label><input class="oc-input" id="fs-name" type="text" value="Company 1"></div>
20
+ <div class="oc-field"><label class="oc-field-label" for="fs-vat">VAT number</label><input class="oc-input" id="fs-vat" type="text" value="BE0000.000.001"></div>
21
+ <div class="oc-field"><label class="oc-field-label" for="fs-type">Type</label><input class="oc-input" id="fs-type" type="text" value="Company"></div>
22
+ </div>
23
+ </details>
24
+ <details class="oc-form-section" name="contact">
25
+ <summary class="oc-form-section__summary">
26
+ <span class="oc-form-section__icon"><iconify-icon icon="mdi:map-marker-outline" aria-hidden="true"></iconify-icon></span>
27
+ <span class="oc-form-section__heading"><span class="oc-form-section__title">Address</span><span class="oc-form-section__hint">Invoice and delivery address</span></span>
28
+ <span class="oc-form-section__status"></span>
29
+ </summary>
30
+ <div class="oc-form-section__body">
31
+ <div class="oc-field oc-form-section__wide"><label class="oc-field-label" for="fs-street">Street and number</label><input class="oc-input" id="fs-street" type="text" value="Company address 1"></div>
32
+ <div class="oc-field"><label class="oc-field-label" for="fs-zip">Postal code</label><input class="oc-input" id="fs-zip" type="text" value="1000"></div>
33
+ <div class="oc-field"><label class="oc-field-label" for="fs-city">City</label><input class="oc-input" id="fs-city" type="text" value="City 1"></div>
34
+ </div>
35
+ </details>
36
+ <details class="oc-form-section" name="contact">
37
+ <summary class="oc-form-section__summary">
38
+ <span class="oc-form-section__icon"><iconify-icon icon="mdi:email-outline" aria-hidden="true"></iconify-icon></span>
39
+ <span class="oc-form-section__heading"><span class="oc-form-section__title">Contact</span><span class="oc-form-section__hint">E-mail and phone</span></span>
40
+ <span class="oc-form-section__status"><span class="oc-badge oc-badge--destructive">1 error</span></span>
41
+ </summary>
42
+ <div class="oc-form-section__body">
43
+ <div class="oc-field"><label class="oc-field-label" for="fs-mail">E-mail</label><input class="oc-input" id="fs-mail" type="email" value="info@company1" required></div>
44
+ <div class="oc-field"><label class="oc-field-label" for="fs-phone">Phone</label><input class="oc-input" id="fs-phone" type="tel" value="+32 012 34 56 71"></div>
45
+ </div>
46
+ </details>
47
+ </form>
@@ -0,0 +1,25 @@
1
+ <!-- OmniaUI component: gallery - Product photos with thumbnails: one large photo and a row (or column) of thumbnails. No JavaScript. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/gallery.html | Map: gallery.
3
+ Class API (modifiers are extra classes / attributes on the same element):
4
+ .oc-gallery: The gallery (a container): __stage with one figure.oc-gallery__slide per photo, then __thumbs.
5
+ fieldset.oc-gallery__thumbs: The thumbnails: one label.oc-gallery__thumb per photo with a radio (same name) and an image with alt text. The first photo shows when none is checked.
6
+ .oc-gallery__badge: A badge on the photo ("-20%", "New").
7
+ .oc-gallery--side: Thumbnails in a column on the left once the gallery is 32rem wide or more.
8
+ --oc-gallery-ratio / --oc-gallery-fit / --oc-gallery-thumb: Photo ratio (default 4 / 3), contain or cover, thumbnail size (4rem).
9
+ -->
10
+ <div class="oc-gallery oc-gallery--side" style="inline-size:min(100%,34rem)">
11
+ <div class="oc-gallery__stage">
12
+ <span class="oc-badge oc-badge--destructive oc-gallery__badge">-20%</span>
13
+ <figure class="oc-gallery__slide"><img src="/img/shop/product-1-front.svg" alt="Product 1, front" width="800" height="600"></figure>
14
+ <figure class="oc-gallery__slide"><img src="/img/shop/product-1-angle.svg" alt="Product 1, from the side" width="800" height="600" loading="lazy"></figure>
15
+ <figure class="oc-gallery__slide"><img src="/img/shop/product-1-detail.svg" alt="Product 1, the shade from below" width="800" height="600" loading="lazy"></figure>
16
+ <figure class="oc-gallery__slide"><img src="/img/shop/product-1-box.svg" alt="Product 1, in its box" width="800" height="600" loading="lazy"></figure>
17
+ </div>
18
+ <fieldset class="oc-gallery__thumbs">
19
+ <legend>Photos of Product 1</legend>
20
+ <label class="oc-gallery__thumb"><input type="radio" name="oc-gallery-demo" checked><img src="/img/shop/product-1-front.svg" alt="Front"></label>
21
+ <label class="oc-gallery__thumb"><input type="radio" name="oc-gallery-demo"><img src="/img/shop/product-1-angle.svg" alt="Side"></label>
22
+ <label class="oc-gallery__thumb"><input type="radio" name="oc-gallery-demo"><img src="/img/shop/product-1-detail.svg" alt="Shade from below"></label>
23
+ <label class="oc-gallery__thumb"><input type="radio" name="oc-gallery-demo"><img src="/img/shop/product-1-box.svg" alt="In its box"></label>
24
+ </fieldset>
25
+ </div>
@@ -0,0 +1,19 @@
1
+ <!-- OmniaUI component: hover-effects - Choose how a card reacts to the mouse: lift, grow, glow or stay still, with one smooth curve for all of them. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/hover-effects.html | Map: four effects -> your own distance and speed.
3
+ Class API (modifiers are extra classes / attributes on the same element):
4
+ .oc-hover-lift: Moves up (--oc-hover-lift, 6px) with a soft shadow. The product card does this by default.
5
+ .oc-hover-grow: Grows a little in place (--oc-hover-scale, 1.02).
6
+ .oc-hover-glow: Stays in place, with a ring and glow in the accent color (--oc-accent-from, e.g. with .oc-accent--violet).
7
+ .oc-hover-none: No movement; also turns off the default lift of a product or price card.
8
+ --oc-hover-duration / --oc-hover-ease: Speed (0.45s) and curve (cubic-bezier(0.22, 1, 0.36, 1), a soft ease-out) of every effect.
9
+ -->
10
+ <div class="oc-card-grid" style="inline-size:100%">
11
+ <article class="oc-feature-card oc-hover-lift"><span class="oc-icon-tile oc-icon-tile--sm oc-accent--blue" aria-hidden="true"><iconify-icon icon="mdi:arrow-up-bold-outline"></iconify-icon></span><h3 class="oc-feature-card__title">Lift</h3><p class="oc-feature-card__text">Moves up 6px with a soft shadow. <code>.oc-hover-lift</code></p></article>
12
+ <article class="oc-feature-card oc-hover-grow"><span class="oc-icon-tile oc-icon-tile--sm oc-accent--green" aria-hidden="true"><iconify-icon icon="mdi:arrow-expand"></iconify-icon></span><h3 class="oc-feature-card__title">Grow</h3><p class="oc-feature-card__text">Grows a little in place. <code>.oc-hover-grow</code></p></article>
13
+ <article class="oc-feature-card oc-hover-glow oc-accent--violet"><span class="oc-icon-tile oc-icon-tile--sm oc-accent--violet" aria-hidden="true"><iconify-icon icon="mdi:white-balance-sunny"></iconify-icon></span><h3 class="oc-feature-card__title">Glow</h3><p class="oc-feature-card__text">Stays in place, glows in the accent color. <code>.oc-hover-glow</code></p></article>
14
+ <article class="oc-feature-card oc-hover-none"><span class="oc-icon-tile oc-icon-tile--sm oc-accent--cyan" aria-hidden="true"><iconify-icon icon="mdi:pause-circle-outline"></iconify-icon></span><h3 class="oc-feature-card__title">None</h3><p class="oc-feature-card__text">No movement. <code>.oc-hover-none</code></p></article>
15
+ </div>
16
+ <div class="oc-card-grid" style="inline-size:100%; --oc-hover-lift: 10px; --oc-hover-duration: 0.7s">
17
+ <article class="oc-feature-card oc-hover-lift"><span class="oc-icon-tile oc-icon-tile--sm oc-accent--blue" aria-hidden="true"><iconify-icon icon="mdi:tune-variant"></iconify-icon></span><h3 class="oc-feature-card__title">Slow and high</h3><p class="oc-feature-card__text"><code>--oc-hover-lift: 10px</code> and <code>--oc-hover-duration: 0.7s</code> on the grid.</p></article>
18
+ <article class="oc-feature-card oc-hover-lift"><span class="oc-icon-tile oc-icon-tile--sm oc-accent--green" aria-hidden="true"><iconify-icon icon="mdi:view-grid-outline"></iconify-icon></span><h3 class="oc-feature-card__title">Same grid</h3><p class="oc-feature-card__text">Every card in the grid follows the tokens.</p></article>
19
+ </div>