@birdycom/omniaui 0.0.0-stage → 0.11.1
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.
- package/LICENSE +21 -0
- package/README.md +21 -3
- package/bin/lib/add.mjs +126 -0
- package/bin/lib/catalog.mjs +169 -0
- package/bin/lib/project.mjs +90 -0
- package/bin/omniaui.mjs +70 -0
- package/dist/code-block.css +163 -0
- package/dist/components-extra.css +916 -0
- package/dist/components.css +10171 -0
- package/dist/components.min.css +1 -0
- package/dist/data-table.d.ts +9 -0
- package/dist/data-table.js +505 -0
- package/dist/docs-ui.css +267 -0
- package/dist/oc-theme.css +69 -0
- package/dist/parts/.gitkeep +0 -0
- package/dist/parts/app-accordion-accent.css +60 -0
- package/dist/parts/app-alpha-tabs.css +68 -0
- package/dist/parts/app-busy-overlay.css +25 -0
- package/dist/parts/app-column-menu.css +85 -0
- package/dist/parts/app-confirm-dialog.css +70 -0
- package/dist/parts/app-cookie-consent.css +63 -0
- package/dist/parts/app-data-table.css +174 -0
- package/dist/parts/app-greeting.css +47 -0
- package/dist/parts/app-list-toolbar.css +81 -0
- package/dist/parts/app-page-header.css +54 -0
- package/dist/parts/app-severity-card.css +91 -0
- package/dist/parts/app-sidebar-dark.css +15 -0
- package/dist/parts/app-sortable-row.css +52 -0
- package/dist/parts/app-stat-card.css +68 -0
- package/dist/parts/app-table-actions.css +71 -0
- package/dist/parts/app-table-compact.css +54 -0
- package/dist/parts/app-top-progress.css +68 -0
- package/dist/parts/app-tree.css +104 -0
- package/dist/parts/app-upgrade-banner.css +90 -0
- package/dist/parts/app-version-banner.css +80 -0
- package/dist/parts/data-chart-line.css +167 -0
- package/dist/parts/forms-affix-input.css +75 -0
- package/dist/parts/forms-barcode-input.css +75 -0
- package/dist/parts/forms-chip-filter.css +91 -0
- package/dist/parts/forms-color-select.css +97 -0
- package/dist/parts/forms-decimal-input.css +51 -0
- package/dist/parts/forms-filter-counts.css +94 -0
- package/dist/parts/forms-language-select.css +89 -0
- package/dist/parts/forms-number-input.css +98 -0
- package/dist/parts/forms-password-requirements.css +55 -0
- package/dist/parts/forms-phone-input.css +85 -0
- package/dist/parts/forms-time-input.css +74 -0
- package/dist/parts/forms-toggle-field.css +69 -0
- package/dist/parts/media-art.css +21 -0
- package/dist/parts/media-attachment.css +160 -0
- package/dist/parts/media-browser-frame.css +73 -0
- package/dist/parts/media-card.css +83 -0
- package/dist/parts/media-chat-composer.css +90 -0
- package/dist/parts/media-doc-viewer.css +151 -0
- package/dist/parts/media-emoji-picker.css +88 -0
- package/dist/parts/media-entity-card.css +52 -0
- package/dist/parts/media-flip-card.css +78 -0
- package/dist/parts/media-image-zoom.css +68 -0
- package/dist/parts/media-lightbox.css +131 -0
- package/dist/parts/media-message-thread.css +136 -0
- package/dist/parts/media-message.css +160 -0
- package/dist/parts/media-row.css +78 -0
- package/dist/parts/media-stack-card.css +82 -0
- package/dist/parts/media-terminal-log.css +76 -0
- package/dist/parts/media-thumb.css +71 -0
- package/dist/parts/site-fact-list.css +25 -0
- package/dist/parts/site-link-arrow.css +34 -0
- package/dist/parts/site-marquee.css +34 -0
- package/dist/parts/site-next-teaser.css +75 -0
- package/dist/parts/site-price-card.css +91 -0
- package/dist/parts/site-product-mark.css +66 -0
- package/dist/parts/site-project-card.css +111 -0
- package/dist/parts/site-prose.css +124 -0
- package/dist/parts/site-stack-list.css +48 -0
- package/dist/parts/site-timeline.css +54 -0
- package/dist/showcase.css +404 -0
- package/manifest.json +1108 -0
- package/package.json +69 -6
- package/snippets/accordion-accent.html +24 -0
- package/snippets/accordion.html +11 -0
- package/snippets/affix-input.html +30 -0
- package/snippets/alert-dialog.html +22 -0
- package/snippets/alert.html +5 -0
- package/snippets/alpha-tabs.html +37 -0
- package/snippets/aspect-ratio.html +15 -0
- package/snippets/attachment.html +43 -0
- package/snippets/avatar.html +6 -0
- package/snippets/back-link.html +5 -0
- package/snippets/badge.html +5 -0
- package/snippets/barcode-input.html +18 -0
- package/snippets/breadcrumb.html +6 -0
- package/snippets/browser-frame.html +18 -0
- package/snippets/busy-overlay.html +31 -0
- package/snippets/button-group.html +21 -0
- package/snippets/button.html +8 -0
- package/snippets/calendar.html +43 -0
- package/snippets/card.html +17 -0
- package/snippets/carousel.html +21 -0
- package/snippets/chart-line.html +46 -0
- package/snippets/chart.html +27 -0
- package/snippets/chat-composer.html +21 -0
- package/snippets/checkbox.html +5 -0
- package/snippets/checklist.html +23 -0
- package/snippets/chip-filter.html +14 -0
- package/snippets/code-window.html +20 -0
- package/snippets/collapsible.html +19 -0
- package/snippets/color-field.html +13 -0
- package/snippets/color-select.html +18 -0
- package/snippets/column-menu.html +38 -0
- package/snippets/combobox.html +19 -0
- package/snippets/command.html +24 -0
- package/snippets/confirm-dialog.html +32 -0
- package/snippets/context-menu.html +25 -0
- package/snippets/cookie-consent.html +70 -0
- package/snippets/copy-field.html +19 -0
- package/snippets/counter.html +2 -0
- package/snippets/data-table.html +151 -0
- package/snippets/date-picker.html +32 -0
- package/snippets/decimal-input.html +20 -0
- package/snippets/definition-list.html +20 -0
- package/snippets/demo-panel.html +18 -0
- package/snippets/doc-viewer.html +58 -0
- package/snippets/drawer.html +30 -0
- package/snippets/dropdown-menu.html +27 -0
- package/snippets/dropdown.html +9 -0
- package/snippets/dropzone.html +13 -0
- package/snippets/emoji-picker.html +51 -0
- package/snippets/empty-state.html +17 -0
- package/snippets/entity-card.html +26 -0
- package/snippets/expandable-table.html +26 -0
- package/snippets/fact-list.html +14 -0
- package/snippets/filter-counts.html +30 -0
- package/snippets/flip-card.html +22 -0
- package/snippets/form-field.html +6 -0
- package/snippets/greeting.html +22 -0
- package/snippets/heading.html +14 -0
- package/snippets/hover-card.html +18 -0
- package/snippets/image-zoom.html +30 -0
- package/snippets/input-group.html +10 -0
- package/snippets/input.html +5 -0
- package/snippets/item.html +26 -0
- package/snippets/kbd.html +13 -0
- package/snippets/label.html +9 -0
- package/snippets/language-select.html +26 -0
- package/snippets/launcher-card.html +14 -0
- package/snippets/lightbox.html +50 -0
- package/snippets/link-arrow.html +10 -0
- package/snippets/list-toolbar.html +33 -0
- package/snippets/marquee.html +15 -0
- package/snippets/media-card.html +28 -0
- package/snippets/media-row.html +21 -0
- package/snippets/media-thumb.html +12 -0
- package/snippets/menubar.html +30 -0
- package/snippets/message-thread.html +123 -0
- package/snippets/message.html +51 -0
- package/snippets/modal.html +15 -0
- package/snippets/native-select.html +15 -0
- package/snippets/navmenu.html +23 -0
- package/snippets/next-teaser.html +15 -0
- package/snippets/number-input.html +27 -0
- package/snippets/otp-input.html +9 -0
- package/snippets/page-header.html +24 -0
- package/snippets/pagination.html +6 -0
- package/snippets/password-input.html +24 -0
- package/snippets/password-requirements.html +30 -0
- package/snippets/phone-input.html +22 -0
- package/snippets/popover.html +15 -0
- package/snippets/price-card.html +34 -0
- package/snippets/product-mark.html +13 -0
- package/snippets/progress.html +4 -0
- package/snippets/project-card.html +23 -0
- package/snippets/prose.html +54 -0
- package/snippets/radio.html +17 -0
- package/snippets/recovery-codes.html +20 -0
- package/snippets/resizable.html +16 -0
- package/snippets/scroll-area.html +20 -0
- package/snippets/search.html +8 -0
- package/snippets/segmented.html +11 -0
- package/snippets/select.html +7 -0
- package/snippets/separator.html +15 -0
- package/snippets/severity-card.html +35 -0
- package/snippets/sheet.html +32 -0
- package/snippets/sidebar-docs.html +24 -0
- package/snippets/sidebar.html +55 -0
- package/snippets/site-footer.html +6 -0
- package/snippets/site-header.html +26 -0
- package/snippets/skeleton.html +4 -0
- package/snippets/slider.html +17 -0
- package/snippets/sortable-row.html +31 -0
- package/snippets/spinner.html +14 -0
- package/snippets/stack-card.html +17 -0
- package/snippets/stack-list.html +16 -0
- package/snippets/stat-card.html +24 -0
- package/snippets/stepper.html +13 -0
- package/snippets/switch.html +6 -0
- package/snippets/table-actions.html +39 -0
- package/snippets/table-compact.html +24 -0
- package/snippets/table.html +29 -0
- package/snippets/tabs.html +9 -0
- package/snippets/tag-input.html +60 -0
- package/snippets/terminal-log.html +23 -0
- package/snippets/textarea.html +3 -0
- package/snippets/theme-switch.html +6 -0
- package/snippets/time-input.html +26 -0
- package/snippets/timeline.html +28 -0
- package/snippets/toast-stack.html +10 -0
- package/snippets/toast.html +36 -0
- package/snippets/toc.html +13 -0
- package/snippets/toggle-field.html +20 -0
- package/snippets/toggle.html +22 -0
- package/snippets/tooltip.html +4 -0
- package/snippets/top-progress.html +12 -0
- package/snippets/tree.html +38 -0
- package/snippets/upgrade-banner.html +28 -0
- package/snippets/user.html +15 -0
- package/snippets/version-banner.html +15 -0
package/package.json
CHANGED
|
@@ -1,6 +1,69 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@birdycom/omniaui",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@birdycom/omniaui",
|
|
3
|
+
"version": "0.11.1",
|
|
4
|
+
"description": "OmniaUI components: CSS-first UI built on native HTML (dialog, popover, details) with light-dark() theming — no JavaScript required. Includes the omniaui CLI (add/list).",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Serge Cools (Birdycom)",
|
|
8
|
+
"homepage": "https://omniaui.eu",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/Birdycom/OmniaUI.git",
|
|
12
|
+
"directory": "packages/ui"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/Birdycom/OmniaUI/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"css",
|
|
19
|
+
"components",
|
|
20
|
+
"dialog",
|
|
21
|
+
"popover",
|
|
22
|
+
"dark-mode",
|
|
23
|
+
"omniaui",
|
|
24
|
+
"omniacss"
|
|
25
|
+
],
|
|
26
|
+
"exports": {
|
|
27
|
+
".": "./dist/components.css",
|
|
28
|
+
"./min": "./dist/components.min.css",
|
|
29
|
+
"./showcase.css": "./dist/showcase.css",
|
|
30
|
+
"./snippets/*": "./snippets/*",
|
|
31
|
+
"./data-table.js": "./dist/data-table.js",
|
|
32
|
+
"./manifest.json": "./manifest.json",
|
|
33
|
+
"./package.json": "./package.json"
|
|
34
|
+
},
|
|
35
|
+
"style": "./dist/components.css",
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"snippets",
|
|
39
|
+
"bin",
|
|
40
|
+
"manifest.json",
|
|
41
|
+
"README.md",
|
|
42
|
+
"LICENSE"
|
|
43
|
+
],
|
|
44
|
+
"unpkg": "./dist/components.min.css",
|
|
45
|
+
"jsdelivr": "./dist/components.min.css",
|
|
46
|
+
"sideEffects": [
|
|
47
|
+
"*.css"
|
|
48
|
+
],
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=22"
|
|
51
|
+
},
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public"
|
|
54
|
+
},
|
|
55
|
+
"bin": {
|
|
56
|
+
"omniaui": "./bin/omniaui.mjs"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"@birdycom/omniacss": "^0.11.1"
|
|
60
|
+
},
|
|
61
|
+
"peerDependenciesMeta": {
|
|
62
|
+
"@birdycom/omniacss": {
|
|
63
|
+
"optional": true
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"scripts": {
|
|
67
|
+
"test": "node --test test/*.test.mjs"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<!-- OmniaUI component: accordion-accent - Accordion variant: every item is a card with a colored accent edge; presets or semantic colors per item - no JavaScript. Needs @birdycom/omniaui CSS.
|
|
2
|
+
File: packages/ui/snippets/accordion-accent.html | Map: accordion (accent) -> item (default primary) -> item (preset color) -> item (semantic color)
|
|
3
|
+
Class API (modifiers are extra classes / attributes on the same element):
|
|
4
|
+
.oc-accordion.oc-accordion--accent: Separate item cards with a 3px colored start edge. Combine with --flush for edge-only cards.
|
|
5
|
+
Colors: an .oc-accent--blue / cyan / green / orange / red / violet / yellow preset on the accordion or one item,
|
|
6
|
+
or .oc-accordion-item--success / --warning / --danger (or .oc-accordion--success / --warning / --danger for all items).
|
|
7
|
+
Custom property: --oc-accordion-accent (any Omnia color token)
|
|
8
|
+
.oc-accordion-accent-meta: Small accent-colored label at the end of the trigger
|
|
9
|
+
Slots: items (details.oc-accordion-item + summary.oc-accordion-trigger + .oc-accordion-content)
|
|
10
|
+
-->
|
|
11
|
+
<div class="oc-accordion oc-accordion--accent">
|
|
12
|
+
<details class="oc-accordion-item" name="oc-accent-demo" open>
|
|
13
|
+
<summary class="oc-accordion-trigger">Customer details <span class="oc-accordion-accent-meta">Complete</span></summary>
|
|
14
|
+
<div class="oc-accordion-content">Ada Lovelace, Main street 12, Ghent.</div>
|
|
15
|
+
</details>
|
|
16
|
+
<details class="oc-accordion-item oc-accent--violet" name="oc-accent-demo">
|
|
17
|
+
<summary class="oc-accordion-trigger">Materials <span class="oc-accordion-accent-meta">4 items</span></summary>
|
|
18
|
+
<div class="oc-accordion-content">Oak worktop, two cabinets, a sink and the tap.</div>
|
|
19
|
+
</details>
|
|
20
|
+
<details class="oc-accordion-item oc-accordion-item--warning" name="oc-accent-demo">
|
|
21
|
+
<summary class="oc-accordion-trigger">Planning <span class="oc-accordion-accent-meta">Needs a date</span></summary>
|
|
22
|
+
<div class="oc-accordion-content">Pick a start date with the customer.</div>
|
|
23
|
+
</details>
|
|
24
|
+
</div>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<!-- OmniaUI component: accordion — Exclusive accordion on <details name> — no JavaScript. Needs @birdycom/omniaui CSS. -->
|
|
2
|
+
<div class="oc-accordion">
|
|
3
|
+
<details class="oc-accordion-item" name="faq" open>
|
|
4
|
+
<summary class="oc-accordion-trigger">Is it accessible?</summary>
|
|
5
|
+
<div class="oc-accordion-content">Yes. It uses the native details/summary elements.</div>
|
|
6
|
+
</details>
|
|
7
|
+
<details class="oc-accordion-item" name="faq">
|
|
8
|
+
<summary class="oc-accordion-trigger">Does it need JavaScript?</summary>
|
|
9
|
+
<div class="oc-accordion-content">No. Items with the same name open one at a time.</div>
|
|
10
|
+
</details>
|
|
11
|
+
</div>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<!-- OmniaUI component: affix-input - Price, margin and email fields. The symbol sits in its own column. Needs @birdycom/omniaui CSS.
|
|
2
|
+
File: packages/ui/snippets/affix-input.html | Map: euro column -> percent column -> email column
|
|
3
|
+
Class API (modifiers are extra classes / attributes on the same element):
|
|
4
|
+
.oc-input-group--affix: Add to .oc-input-group. The frame is the wrapper; .oc-input-addon is a column with a divider.
|
|
5
|
+
.oc-input-group--end: Optional. Right-aligns the value.
|
|
6
|
+
.oc-input-group--error: Red frame (also via aria-invalid="true" or :user-invalid on the input)
|
|
7
|
+
.oc-input-addon: The symbol column. Before the input = left (euro, percent, @). After the input = right.
|
|
8
|
+
States: :focus-within (ring), :user-invalid (red), disabled input (dimmed)
|
|
9
|
+
-->
|
|
10
|
+
<div class="oc-field">
|
|
11
|
+
<label class="oc-field-label" for="oc-price">Selling price excl. VAT</label>
|
|
12
|
+
<div class="oc-input-group oc-input-group--affix">
|
|
13
|
+
<span class="oc-input-addon" aria-hidden="true">€</span>
|
|
14
|
+
<input class="oc-input" id="oc-price" type="text" inputmode="decimal" name="price" value="5,15">
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="oc-field">
|
|
18
|
+
<label class="oc-field-label" for="oc-margin">Margin %</label>
|
|
19
|
+
<div class="oc-input-group oc-input-group--affix">
|
|
20
|
+
<span class="oc-input-addon" aria-hidden="true">%</span>
|
|
21
|
+
<input class="oc-input" id="oc-margin" type="text" inputmode="decimal" name="margin" value="30">
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="oc-field">
|
|
25
|
+
<label class="oc-field-label" for="oc-mail">Email</label>
|
|
26
|
+
<div class="oc-input-group oc-input-group--affix">
|
|
27
|
+
<span class="oc-input-addon" aria-hidden="true">@</span>
|
|
28
|
+
<input class="oc-input" id="oc-mail" type="email" name="email" autocomplete="email" placeholder="name@company.com">
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<!-- OmniaUI component: alert-dialog - Confirmation modal with a status icon (success, error, warning, info, question). Needs @birdycom/omniaui CSS.
|
|
2
|
+
Class API (modifiers are extra classes / attributes on the same element):
|
|
3
|
+
dialog.oc-modal: Native dialog from the modal component
|
|
4
|
+
.oc-modal-content.oc-modal-content--sm.oc-alert-dialog: Centered content box
|
|
5
|
+
.oc-alert-dialog--success / --error / --warning / --info / --question: Type modifier on the content element (sets the icon color)
|
|
6
|
+
.oc-alert-dialog-icon: Round icon holder with a glyph (!, ✓, ?, i, ×)
|
|
7
|
+
.oc-modal-title / -body / -footer: Title, message and the buttons (secondary left, primary right)
|
|
8
|
+
Slots: icon, title, message (body), footer buttons (secondary + primary)
|
|
9
|
+
-->
|
|
10
|
+
<button class="oc-btn oc-btn--destructive" type="button" command="show-modal" commandfor="oc-alert-dialog-demo">Delete contact</button>
|
|
11
|
+
|
|
12
|
+
<dialog class="oc-modal" id="oc-alert-dialog-demo" closedby="closerequest" aria-labelledby="oc-alert-dialog-title" aria-describedby="oc-alert-dialog-text">
|
|
13
|
+
<div class="oc-modal-content oc-modal-content--sm oc-alert-dialog oc-alert-dialog--warning">
|
|
14
|
+
<span class="oc-alert-dialog-icon" aria-hidden="true">!</span>
|
|
15
|
+
<h2 class="oc-modal-title" id="oc-alert-dialog-title">Delete this contact?</h2>
|
|
16
|
+
<div class="oc-modal-body" id="oc-alert-dialog-text">All related documents stay, but the link to this contact is removed.</div>
|
|
17
|
+
<div class="oc-modal-footer">
|
|
18
|
+
<button class="oc-btn oc-btn--outline" type="button" command="close" commandfor="oc-alert-dialog-demo">Cancel</button>
|
|
19
|
+
<button class="oc-btn oc-btn--destructive" type="button" command="close" commandfor="oc-alert-dialog-demo">Delete</button>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</dialog>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<!-- OmniaUI component: alert — Alerts: info, success, warning, danger. Needs @birdycom/omniaui CSS. -->
|
|
2
|
+
<div class="oc-alert oc-alert--info" role="status">
|
|
3
|
+
<h4 class="oc-alert-title">Heads up!</h4>
|
|
4
|
+
<p class="oc-alert-description">You can add components with the OmniaCSS CLI.</p>
|
|
5
|
+
</div>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<!-- OmniaUI component: alpha-tabs - All + A-Z letter filter bar for long lists; scrolls sideways on small screens. Needs @birdycom/omniaui CSS.
|
|
2
|
+
File: packages/ui/snippets/alpha-tabs.html | Map: nav -> "All" item -> letter items (current, empty)
|
|
3
|
+
Class API (modifiers are extra classes / attributes on the same element):
|
|
4
|
+
nav.oc-alpha-tabs: Letter bar. Modifiers: --wrap (wrap instead of scroll), --sm, --plain (no frame).
|
|
5
|
+
.oc-alpha-tabs-item: One letter (a href="?letter=A" or button). States: aria-current="true" / .is-active, aria-disabled="true" (no entries).
|
|
6
|
+
.oc-alpha-tabs-item--all: The wider "All" item at the start
|
|
7
|
+
Slots: one item per letter (render only the letters you need, or all with empty ones disabled)
|
|
8
|
+
-->
|
|
9
|
+
<nav class="oc-alpha-tabs" aria-label="Filter by letter">
|
|
10
|
+
<a class="oc-alpha-tabs-item oc-alpha-tabs-item--all" href="?letter=all">All</a>
|
|
11
|
+
<a class="oc-alpha-tabs-item" href="?letter=A">A</a>
|
|
12
|
+
<a class="oc-alpha-tabs-item" href="?letter=B" aria-current="true">B</a>
|
|
13
|
+
<a class="oc-alpha-tabs-item" href="?letter=C">C</a>
|
|
14
|
+
<a class="oc-alpha-tabs-item" href="?letter=D">D</a>
|
|
15
|
+
<a class="oc-alpha-tabs-item" aria-disabled="true">E</a>
|
|
16
|
+
<a class="oc-alpha-tabs-item" href="?letter=F">F</a>
|
|
17
|
+
<a class="oc-alpha-tabs-item" href="?letter=G">G</a>
|
|
18
|
+
<a class="oc-alpha-tabs-item" href="?letter=H">H</a>
|
|
19
|
+
<a class="oc-alpha-tabs-item" href="?letter=I">I</a>
|
|
20
|
+
<a class="oc-alpha-tabs-item" href="?letter=J">J</a>
|
|
21
|
+
<a class="oc-alpha-tabs-item" href="?letter=K">K</a>
|
|
22
|
+
<a class="oc-alpha-tabs-item" href="?letter=L">L</a>
|
|
23
|
+
<a class="oc-alpha-tabs-item" href="?letter=M">M</a>
|
|
24
|
+
<a class="oc-alpha-tabs-item" href="?letter=N">N</a>
|
|
25
|
+
<a class="oc-alpha-tabs-item" href="?letter=O">O</a>
|
|
26
|
+
<a class="oc-alpha-tabs-item" href="?letter=P">P</a>
|
|
27
|
+
<a class="oc-alpha-tabs-item" aria-disabled="true">Q</a>
|
|
28
|
+
<a class="oc-alpha-tabs-item" href="?letter=R">R</a>
|
|
29
|
+
<a class="oc-alpha-tabs-item" href="?letter=S">S</a>
|
|
30
|
+
<a class="oc-alpha-tabs-item" href="?letter=T">T</a>
|
|
31
|
+
<a class="oc-alpha-tabs-item" href="?letter=U">U</a>
|
|
32
|
+
<a class="oc-alpha-tabs-item" href="?letter=V">V</a>
|
|
33
|
+
<a class="oc-alpha-tabs-item" href="?letter=W">W</a>
|
|
34
|
+
<a class="oc-alpha-tabs-item" aria-disabled="true">X</a>
|
|
35
|
+
<a class="oc-alpha-tabs-item" href="?letter=Y">Y</a>
|
|
36
|
+
<a class="oc-alpha-tabs-item" href="?letter=Z">Z</a>
|
|
37
|
+
</nav>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!-- OmniaUI component: aspect-ratio - Aspect-ratio box with presets and fill behaviour for img/video/iframe. Needs @birdycom/omniaui CSS.
|
|
2
|
+
Class API (modifiers are extra classes / attributes on the same element):
|
|
3
|
+
.oc-aspect: ratio box (default 16 / 9). Presets: --square, --photo (4/3), --portrait (3/4), --wide (21/9). --center centers text
|
|
4
|
+
--oc-aspect: custom ratio, e.g. style="--oc-aspect: 5 / 2"
|
|
5
|
+
-->
|
|
6
|
+
<div style="max-inline-size:24rem">
|
|
7
|
+
<div class="oc-aspect oc-aspect--center"><span class="oc-item-description">16 / 9</span></div>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div style="display:flex;gap:1rem;flex-wrap:wrap;align-items:flex-start">
|
|
11
|
+
<div class="oc-aspect oc-aspect--square oc-aspect--center" style="inline-size:7rem"><span class="oc-item-description">1 / 1</span></div>
|
|
12
|
+
<div class="oc-aspect oc-aspect--photo oc-aspect--center" style="inline-size:9rem"><span class="oc-item-description">4 / 3</span></div>
|
|
13
|
+
<div class="oc-aspect oc-aspect--portrait oc-aspect--center" style="inline-size:6rem"><span class="oc-item-description">3 / 4</span></div>
|
|
14
|
+
<div class="oc-aspect oc-aspect--center" style="inline-size:12rem;--oc-aspect: 5 / 2"><span class="oc-item-description">5 / 2</span></div>
|
|
15
|
+
</div>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<!-- OmniaUI component: attachment — File chip and image preview for chat messages and composers: icon by type, name, size, remove and upload states. Needs @birdycom/omniaui CSS.
|
|
2
|
+
File: packages/ui/snippets/attachment.html | Map: file chips (types) -> image preview -> composer row (thumb, uploading, error, remove)
|
|
3
|
+
Class API (modifiers are extra classes / attributes on the same element):
|
|
4
|
+
.oc-attachment-list: Wrapping row of chips (ul or div). Modifier: --stack (one per line, full width)
|
|
5
|
+
a.oc-attachment | div.oc-attachment: File chip. Types: --pdf, --doc, --sheet, --zip, --image (tint of the icon tile).
|
|
6
|
+
States: --uploading (progress line from --oc-attachment-progress), --error
|
|
7
|
+
.oc-attachment__icon: Page tile with the extension text, or an img for a small preview
|
|
8
|
+
.oc-attachment__body > .oc-attachment__name + .oc-attachment__size
|
|
9
|
+
button.oc-attachment__remove: Remove button (composer); give it an aria-label with the file name
|
|
10
|
+
a.oc-attachment-image > img + .oc-attachment-image__caption: Image preview inside a message (4 : 3, max 18rem wide)
|
|
11
|
+
.oc-attachment-thumb > img + button.oc-attachment__remove: Square thumbnail of a pasted screenshot
|
|
12
|
+
No JavaScript. Removing a file or tracking upload progress is up to your app; set --oc-attachment-progress inline.
|
|
13
|
+
-->
|
|
14
|
+
<div style="display:grid;gap:1.25rem;inline-size:100%;max-inline-size:40rem">
|
|
15
|
+
<ul class="oc-attachment-list" aria-label="Files in this message">
|
|
16
|
+
<li><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></li>
|
|
17
|
+
<li><a class="oc-attachment oc-attachment--sheet" href="#measurements.xlsx" download><span class="oc-attachment__icon" aria-hidden="true">XLS</span><span class="oc-attachment__body"><span class="oc-attachment__name">Measurements ground floor.xlsx</span><span class="oc-attachment__size">86 KB</span></span></a></li>
|
|
18
|
+
<li><a class="oc-attachment oc-attachment--doc" href="#contract.docx" download><span class="oc-attachment__icon" aria-hidden="true">DOC</span><span class="oc-attachment__body"><span class="oc-attachment__name">Contract addendum.docx</span><span class="oc-attachment__size">240 KB</span></span></a></li>
|
|
19
|
+
<li><a class="oc-attachment oc-attachment--zip" href="#plans.zip" download><span class="oc-attachment__icon" aria-hidden="true">ZIP</span><span class="oc-attachment__body"><span class="oc-attachment__name">Plans architect.zip</span><span class="oc-attachment__size">14.8 MB</span></span></a></li>
|
|
20
|
+
</ul>
|
|
21
|
+
|
|
22
|
+
<a class="oc-attachment-image" href="#worktop-sample.jpg">
|
|
23
|
+
<span class="oc-media-art oc-media-art--6" role="img" aria-label="Photo of the Calacatta worktop sample"></span>
|
|
24
|
+
<span class="oc-attachment-image__caption">worktop-sample.jpg · 2.1 MB</span>
|
|
25
|
+
</a>
|
|
26
|
+
|
|
27
|
+
<div class="oc-attachment-list" aria-label="Files to send">
|
|
28
|
+
<div class="oc-attachment-thumb">
|
|
29
|
+
<span class="oc-media-art oc-media-art--2" role="img" aria-label="Pasted screenshot"></span>
|
|
30
|
+
<button type="button" class="oc-attachment__remove" aria-label="Remove screenshot.png">✕</button>
|
|
31
|
+
</div>
|
|
32
|
+
<div class="oc-attachment oc-attachment--pdf oc-attachment--uploading" style="--oc-attachment-progress:65%">
|
|
33
|
+
<span class="oc-attachment__icon" aria-hidden="true">PDF</span>
|
|
34
|
+
<span class="oc-attachment__body"><span class="oc-attachment__name">Delivery note 4471.pdf</span><span class="oc-attachment__size" role="status">Uploading… 65%</span></span>
|
|
35
|
+
<button type="button" class="oc-attachment__remove" aria-label="Cancel upload of Delivery note 4471.pdf">✕</button>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="oc-attachment oc-attachment--image oc-attachment--error">
|
|
38
|
+
<span class="oc-attachment__icon" aria-hidden="true">HEIC</span>
|
|
39
|
+
<span class="oc-attachment__body"><span class="oc-attachment__name">IMG_2048.heic</span><span class="oc-attachment__size">Larger than 25 MB</span></span>
|
|
40
|
+
<button type="button" class="oc-attachment__remove" aria-label="Remove IMG_2048.heic">✕</button>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<!-- OmniaUI component: back-link - Outline link that names its destination (Back to Products). Needs @birdycom/omniaui CSS.
|
|
2
|
+
Class API (modifiers are extra classes / attributes on the same element):
|
|
3
|
+
.oc-back-link: Anchor styled as an outline button with a leading arrow
|
|
4
|
+
-->
|
|
5
|
+
<a class="oc-back-link" href="#">Back to Products</a>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<!-- OmniaUI component: badge — Badges. Needs @birdycom/omniaui CSS. -->
|
|
2
|
+
<span class="oc-badge">Badge</span>
|
|
3
|
+
<span class="oc-badge oc-badge--secondary">Secondary</span>
|
|
4
|
+
<span class="oc-badge oc-badge--outline">Outline</span>
|
|
5
|
+
<span class="oc-badge oc-badge--destructive">Error</span>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!-- OmniaUI component: barcode-input - Code field with a barcode icon in the left column. Needs @birdycom/omniaui CSS.
|
|
2
|
+
File: packages/ui/snippets/barcode-input.html | Map: labeled field (icon column + value) -> optional preview
|
|
3
|
+
Class API (modifiers are extra classes / attributes on the same element):
|
|
4
|
+
.oc-barcode-input: Wrapper when you also show a preview under the field
|
|
5
|
+
.oc-input-group--affix + .oc-input-addon: The icon column (same chrome as the euro and percent fields)
|
|
6
|
+
.oc-barcode-input-field: Add to .oc-input
|
|
7
|
+
.oc-barcode-preview: Optional preview under the field. Modifier: --empty
|
|
8
|
+
States: aria-invalid="true" on the field turns the frame and the preview red
|
|
9
|
+
Slots: replace .oc-barcode-preview-bars with your own svg, canvas or img
|
|
10
|
+
-->
|
|
11
|
+
<div class="oc-field">
|
|
12
|
+
<label class="oc-field-label" for="oc-barcode-demo">Our barcode</label>
|
|
13
|
+
<div class="oc-input-group oc-input-group--affix">
|
|
14
|
+
<span class="oc-input-addon" aria-hidden="true"><svg viewBox="0 0 16 16"><path fill="currentColor" d="M1 1h1.4v14H1zm2.2 0h.7v14h-.7zm1.6 0h1.5v14H4.8zm2.4 0h.7v14H7.2zm1.6 0h.7v14H8.8zm1.5 0h1.4v14h-1.4zm2.2 0H15v14h-.9z"/></svg></span>
|
|
15
|
+
<input class="oc-input oc-barcode-input-field" id="oc-barcode-demo" name="ean" type="text" maxlength="80" placeholder="EAN-13 or internal code" autocomplete="off" spellcheck="false">
|
|
16
|
+
</div>
|
|
17
|
+
<p class="oc-field-description">13 digits is an EAN-13. Anything else is an internal code.</p>
|
|
18
|
+
</div>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<!-- OmniaUI component: breadcrumb — Breadcrumb. Needs @birdycom/omniaui CSS. -->
|
|
2
|
+
<nav class="oc-breadcrumb" aria-label="Breadcrumb">
|
|
3
|
+
<a class="oc-breadcrumb-item" href="/">Home</a>
|
|
4
|
+
<a class="oc-breadcrumb-item" href="/docs/">Docs</a>
|
|
5
|
+
<span class="oc-breadcrumb-item" aria-current="page">Components</span>
|
|
6
|
+
</nav>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!-- OmniaUI component: browser-frame — Fake browser chrome around a screenshot or live content. Needs @birdycom/omniaui CSS.
|
|
2
|
+
File: packages/ui/snippets/browser-frame.html | Map: figure -> bar (dots, address, actions) -> view (screenshot slot) -> caption
|
|
3
|
+
Class API: figure.oc-browser-frame > .oc-browser-frame__bar (3 × <i>, .oc-browser-frame__address, .oc-browser-frame__actions) ·
|
|
4
|
+
.oc-browser-frame__view > img / video / iframe / any content · figcaption.oc-browser-frame__caption (optional).
|
|
5
|
+
Modifiers: --minimal (dots only), --dark (dark chrome), --tilt (3D angle, straightens on hover), --auto (free height).
|
|
6
|
+
Ratio: --oc-browser-frame-ratio (default 16 / 10). No JavaScript.
|
|
7
|
+
-->
|
|
8
|
+
<figure class="oc-browser-frame" style="max-inline-size:36rem">
|
|
9
|
+
<div class="oc-browser-frame__bar">
|
|
10
|
+
<i></i><i></i><i></i>
|
|
11
|
+
<span class="oc-browser-frame__address">shop.example.com/collections/spring</span>
|
|
12
|
+
<span class="oc-browser-frame__actions" aria-hidden="true">↻ ⋮</span>
|
|
13
|
+
</div>
|
|
14
|
+
<div class="oc-browser-frame__view">
|
|
15
|
+
<div class="oc-media-art oc-media-art--5" role="img" aria-label="Screenshot of the spring collection page"></div>
|
|
16
|
+
</div>
|
|
17
|
+
<figcaption class="oc-browser-frame__caption">Spring collection, 2026 redesign</figcaption>
|
|
18
|
+
</figure>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<!-- OmniaUI component: busy-overlay — Modal "please wait" overlay while a long form submit or upload runs. Needs @birdycom/omniaui CSS.
|
|
2
|
+
File: packages/ui/snippets/busy-overlay.html | Map: form[data-oc-busy] -> dialog (spinner or progress, title, text) -> script
|
|
3
|
+
Class API (modifiers are extra classes / attributes on the same element):
|
|
4
|
+
dialog.oc-busy-overlay[closedby="none"]: The overlay; modal, so the page is inert and Esc does not close it
|
|
5
|
+
.oc-spinner (or .oc-progress > .oc-progress-bar for a known percentage): Activity
|
|
6
|
+
.oc-busy-overlay__title / __text: What is happening and how long it may take
|
|
7
|
+
form[data-oc-busy="<dialog id>"]: Opens the overlay when the form is submitted (after the browser's own validation)
|
|
8
|
+
The overlay appears after 300ms, so quick requests never flash. The page that loads next replaces it;
|
|
9
|
+
after a fetch() call close it yourself with dialog.close().
|
|
10
|
+
-->
|
|
11
|
+
<form class="oc-form-group" data-oc-busy="oc-busy-overlay-demo" action="/photos" method="post" enctype="multipart/form-data">
|
|
12
|
+
<label class="oc-dropzone">
|
|
13
|
+
<input type="file" name="photos[]" accept="image/*" multiple>
|
|
14
|
+
<span><strong>Choose photos</strong> to upload</span>
|
|
15
|
+
<span class="oc-dropzone-hint">They are resized to 600px and 1080px after saving</span>
|
|
16
|
+
</label>
|
|
17
|
+
<button class="oc-btn" type="submit">Save</button>
|
|
18
|
+
</form>
|
|
19
|
+
|
|
20
|
+
<dialog class="oc-busy-overlay" id="oc-busy-overlay-demo" closedby="none" aria-labelledby="oc-busy-overlay-demo-title" aria-describedby="oc-busy-overlay-demo-text">
|
|
21
|
+
<span class="oc-spinner" role="status" aria-label="Busy"></span>
|
|
22
|
+
<h2 class="oc-busy-overlay__title" id="oc-busy-overlay-demo-title">Saving…</h2>
|
|
23
|
+
<p class="oc-busy-overlay__text" id="oc-busy-overlay-demo-text">The photos are being processed. This can take a minute; please keep this page open.</p>
|
|
24
|
+
</dialog>
|
|
25
|
+
<script>
|
|
26
|
+
// Open the busy overlay of a form when it is submitted (the submit event only fires when the form is valid).
|
|
27
|
+
document.addEventListener("submit", (e) => {
|
|
28
|
+
const id = e.target.dataset?.ocBusy;
|
|
29
|
+
if (id) document.getElementById(id)?.showModal();
|
|
30
|
+
});
|
|
31
|
+
</script>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<!-- OmniaUI component: button-group - Joined buttons with shared borders: horizontal, vertical, text addon. Needs @birdycom/omniaui CSS.
|
|
2
|
+
Class API (modifiers are extra classes / attributes on the same element):
|
|
3
|
+
.oc-btn-group: inline-flex wrapper (role="group" + aria-label). Modifier: --vertical.
|
|
4
|
+
.oc-btn: any button variant inside the group
|
|
5
|
+
.oc-btn-group-text: static text cell (a count, a unit) next to a button
|
|
6
|
+
-->
|
|
7
|
+
<div class="oc-btn-group" role="group" aria-label="Text alignment">
|
|
8
|
+
<button class="oc-btn oc-btn--outline" type="button">Left</button>
|
|
9
|
+
<button class="oc-btn oc-btn--outline" type="button">Center</button>
|
|
10
|
+
<button class="oc-btn oc-btn--outline" type="button">Right</button>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<div class="oc-btn-group oc-btn-group--vertical" role="group" aria-label="Zoom">
|
|
14
|
+
<button class="oc-btn oc-btn--outline" type="button">Zoom in</button>
|
|
15
|
+
<button class="oc-btn oc-btn--outline" type="button">Zoom out</button>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="oc-btn-group" role="group" aria-label="Quantity">
|
|
18
|
+
<button class="oc-btn oc-btn--outline" type="button" aria-label="Decrease">−</button>
|
|
19
|
+
<span class="oc-btn-group-text">3 items</span>
|
|
20
|
+
<button class="oc-btn oc-btn--outline" type="button" aria-label="Increase">+</button>
|
|
21
|
+
</div>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<!-- OmniaUI component: button — Buttons: default, secondary, outline, ghost, destructive and sizes. Needs @birdycom/omniaui CSS. -->
|
|
2
|
+
<button class="oc-btn">Default</button>
|
|
3
|
+
<button class="oc-btn oc-btn--secondary">Secondary</button>
|
|
4
|
+
<button class="oc-btn oc-btn--outline">Outline</button>
|
|
5
|
+
<button class="oc-btn oc-btn--ghost">Ghost</button>
|
|
6
|
+
<button class="oc-btn oc-btn--destructive">Delete</button>
|
|
7
|
+
<button class="oc-btn oc-btn--sm">Small</button>
|
|
8
|
+
<button class="oc-btn oc-btn--lg">Large</button>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<!-- OmniaUI component: calendar - Calendar: month grid markup with selected, today, range and outside-day states. Needs @birdycom/omniaui CSS.
|
|
2
|
+
Class API (modifiers are extra classes / attributes on the same element):
|
|
3
|
+
.oc-calendar: container. .oc-calendar-header > .oc-calendar-nav (prev/next) + .oc-calendar-title
|
|
4
|
+
table.oc-calendar-grid[role=grid] > th.oc-calendar-weekday + td > button.oc-calendar-day
|
|
5
|
+
Day states: [aria-selected=true] | --today | --outside | --range-start / --range-middle / --range-end | :disabled
|
|
6
|
+
-->
|
|
7
|
+
<div class="oc-calendar" role="group" aria-label="October 2026">
|
|
8
|
+
<div class="oc-calendar-header">
|
|
9
|
+
<button class="oc-calendar-nav" type="button" aria-label="Previous month"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 6-6 6 6 6"/></svg></button>
|
|
10
|
+
<h3 class="oc-calendar-title" aria-live="polite">October 2026</h3>
|
|
11
|
+
<button class="oc-calendar-nav" type="button" aria-label="Next month"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></button>
|
|
12
|
+
</div>
|
|
13
|
+
<table class="oc-calendar-grid" role="grid" aria-label="October 2026">
|
|
14
|
+
<thead><tr><th class="oc-calendar-weekday" scope="col" abbr="Monday">Mo</th><th class="oc-calendar-weekday" scope="col" abbr="Tuesday">Tu</th><th class="oc-calendar-weekday" scope="col" abbr="Wednesday">We</th><th class="oc-calendar-weekday" scope="col" abbr="Thursday">Th</th><th class="oc-calendar-weekday" scope="col" abbr="Friday">Fr</th><th class="oc-calendar-weekday" scope="col" abbr="Saturday">Sa</th><th class="oc-calendar-weekday" scope="col" abbr="Sunday">Su</th></tr></thead>
|
|
15
|
+
<tbody>
|
|
16
|
+
<tr><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-09-28" tabindex="-1">28</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-09-29" tabindex="-1">29</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-09-30" tabindex="-1">30</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-01">1</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-02">2</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-03">3</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-04">4</button></td></tr>
|
|
17
|
+
<tr><td><button class="oc-calendar-day" type="button" data-date="2026-10-05">5</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-06">6</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-07">7</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-08">8</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-09">9</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-10">10</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-11">11</button></td></tr>
|
|
18
|
+
<tr><td><button class="oc-calendar-day" type="button" data-date="2026-10-12">12</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-13">13</button></td><td><button class="oc-calendar-day oc-calendar-day--today" type="button" data-date="2026-10-14" aria-current="date">14</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-15">15</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-16" aria-selected="true">16</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-17">17</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-18">18</button></td></tr>
|
|
19
|
+
<tr><td><button class="oc-calendar-day" type="button" data-date="2026-10-19">19</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-20">20</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-21">21</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-22">22</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-23">23</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-24">24</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-25">25</button></td></tr>
|
|
20
|
+
<tr><td><button class="oc-calendar-day" type="button" data-date="2026-10-26">26</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-27">27</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-28">28</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-29">29</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-30">30</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-31">31</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-11-01" tabindex="-1">1</button></td></tr>
|
|
21
|
+
<tr><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-11-02" tabindex="-1">2</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-11-03" tabindex="-1">3</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-11-04" tabindex="-1">4</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-11-05" tabindex="-1">5</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-11-06" tabindex="-1">6</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-11-07" tabindex="-1">7</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-11-08" tabindex="-1">8</button></td></tr>
|
|
22
|
+
</tbody>
|
|
23
|
+
</table>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div class="oc-calendar" role="group" aria-label="October 2026">
|
|
27
|
+
<div class="oc-calendar-header">
|
|
28
|
+
<button class="oc-calendar-nav" type="button" aria-label="Previous month"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 6-6 6 6 6"/></svg></button>
|
|
29
|
+
<h3 class="oc-calendar-title" aria-live="polite">October 2026</h3>
|
|
30
|
+
<button class="oc-calendar-nav" type="button" aria-label="Next month"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg></button>
|
|
31
|
+
</div>
|
|
32
|
+
<table class="oc-calendar-grid" role="grid" aria-label="October 2026">
|
|
33
|
+
<thead><tr><th class="oc-calendar-weekday" scope="col" abbr="Monday">Mo</th><th class="oc-calendar-weekday" scope="col" abbr="Tuesday">Tu</th><th class="oc-calendar-weekday" scope="col" abbr="Wednesday">We</th><th class="oc-calendar-weekday" scope="col" abbr="Thursday">Th</th><th class="oc-calendar-weekday" scope="col" abbr="Friday">Fr</th><th class="oc-calendar-weekday" scope="col" abbr="Saturday">Sa</th><th class="oc-calendar-weekday" scope="col" abbr="Sunday">Su</th></tr></thead>
|
|
34
|
+
<tbody>
|
|
35
|
+
<tr><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-09-28" tabindex="-1">28</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-09-29" tabindex="-1">29</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-09-30" tabindex="-1">30</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-01">1</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-02">2</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-03">3</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-04">4</button></td></tr>
|
|
36
|
+
<tr><td><button class="oc-calendar-day" type="button" data-date="2026-10-05">5</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-06">6</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-07">7</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-08">8</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-09">9</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-10">10</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-11">11</button></td></tr>
|
|
37
|
+
<tr><td><button class="oc-calendar-day oc-calendar-day--range-start" type="button" data-date="2026-10-12">12</button></td><td><button class="oc-calendar-day oc-calendar-day--range-middle" type="button" data-date="2026-10-13">13</button></td><td><button class="oc-calendar-day oc-calendar-day--today oc-calendar-day--range-middle" type="button" data-date="2026-10-14" aria-current="date">14</button></td><td><button class="oc-calendar-day oc-calendar-day--range-middle" type="button" data-date="2026-10-15">15</button></td><td><button class="oc-calendar-day oc-calendar-day--range-end" type="button" data-date="2026-10-16">16</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-17">17</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-18">18</button></td></tr>
|
|
38
|
+
<tr><td><button class="oc-calendar-day" type="button" data-date="2026-10-19">19</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-20">20</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-21">21</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-22">22</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-23">23</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-24">24</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-25">25</button></td></tr>
|
|
39
|
+
<tr><td><button class="oc-calendar-day" type="button" data-date="2026-10-26">26</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-27">27</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-28">28</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-29">29</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-30">30</button></td><td><button class="oc-calendar-day" type="button" data-date="2026-10-31">31</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-11-01" tabindex="-1">1</button></td></tr>
|
|
40
|
+
<tr><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-11-02" tabindex="-1">2</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-11-03" tabindex="-1">3</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-11-04" tabindex="-1">4</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-11-05" tabindex="-1">5</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-11-06" tabindex="-1">6</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-11-07" tabindex="-1">7</button></td><td><button class="oc-calendar-day oc-calendar-day--outside" type="button" data-date="2026-11-08" tabindex="-1">8</button></td></tr>
|
|
41
|
+
</tbody>
|
|
42
|
+
</table>
|
|
43
|
+
</div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<!-- OmniaUI component: card — Card with header, content, footer. Needs @birdycom/omniaui CSS. -->
|
|
2
|
+
<div class="oc-card">
|
|
3
|
+
<div class="oc-card-header">
|
|
4
|
+
<h3 class="oc-card-title">Create project</h3>
|
|
5
|
+
<p class="oc-card-description">Deploy your new project in one click.</p>
|
|
6
|
+
</div>
|
|
7
|
+
<div class="oc-card-content">
|
|
8
|
+
<div class="oc-field">
|
|
9
|
+
<label class="oc-field-label" for="project-name">Name</label>
|
|
10
|
+
<input class="oc-input" id="project-name" placeholder="My project">
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
<div class="oc-card-footer">
|
|
14
|
+
<button class="oc-btn oc-btn--outline">Cancel</button>
|
|
15
|
+
<button class="oc-btn">Deploy</button>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<!-- OmniaUI component: carousel - Carousel: CSS scroll-snap with ::scroll-button arrows and ::scroll-marker dots, fallback links. Needs @birdycom/omniaui CSS.
|
|
2
|
+
Class API (modifiers are extra classes / attributes on the same element):
|
|
3
|
+
.oc-carousel: wrapper (anchor scope). Modifiers: --halves, --thirds (slides per view)
|
|
4
|
+
.oc-carousel-viewport: the scroller (tabindex="0", role="region", aria-roledescription="carousel")
|
|
5
|
+
.oc-carousel-item: one slide (role="group" aria-roledescription="slide")
|
|
6
|
+
.oc-carousel-dots > a.oc-carousel-dot: fallback navigation (hidden where ::scroll-marker works)
|
|
7
|
+
-->
|
|
8
|
+
<div class="oc-carousel" style="max-inline-size:34rem">
|
|
9
|
+
<div class="oc-carousel-viewport" tabindex="0" role="region" aria-roledescription="carousel" aria-label="Highlights">
|
|
10
|
+
<div class="oc-carousel-item" id="oc-slide-1" role="group" aria-roledescription="slide" aria-label="1 of 4"><div class="oc-aspect oc-aspect--wide oc-aspect--center"><span class="oc-item-title" style="font-size:1.75rem">Slide 1</span></div></div>
|
|
11
|
+
<div class="oc-carousel-item" id="oc-slide-2" role="group" aria-roledescription="slide" aria-label="2 of 4"><div class="oc-aspect oc-aspect--wide oc-aspect--center"><span class="oc-item-title" style="font-size:1.75rem">Slide 2</span></div></div>
|
|
12
|
+
<div class="oc-carousel-item" id="oc-slide-3" role="group" aria-roledescription="slide" aria-label="3 of 4"><div class="oc-aspect oc-aspect--wide oc-aspect--center"><span class="oc-item-title" style="font-size:1.75rem">Slide 3</span></div></div>
|
|
13
|
+
<div class="oc-carousel-item" id="oc-slide-4" role="group" aria-roledescription="slide" aria-label="4 of 4"><div class="oc-aspect oc-aspect--wide oc-aspect--center"><span class="oc-item-title" style="font-size:1.75rem">Slide 4</span></div></div>
|
|
14
|
+
</div>
|
|
15
|
+
<nav class="oc-carousel-dots" aria-label="Choose a slide">
|
|
16
|
+
<a class="oc-carousel-dot" href="#oc-slide-1" aria-label="Slide 1"></a>
|
|
17
|
+
<a class="oc-carousel-dot" href="#oc-slide-2" aria-label="Slide 2"></a>
|
|
18
|
+
<a class="oc-carousel-dot" href="#oc-slide-3" aria-label="Slide 3"></a>
|
|
19
|
+
<a class="oc-carousel-dot" href="#oc-slide-4" aria-label="Slide 4"></a>
|
|
20
|
+
</nav>
|
|
21
|
+
</div>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<!-- OmniaUI component: chart-line — Line and area chart in inline SVG with axes, legend and tooltips on hover and focus. Needs @birdycom/omniaui CSS.
|
|
2
|
+
File: packages/ui/snippets/chart-line.html | Map: figure -> head (title, sub) -> body (y axis, plot: svg series + hover columns, x axis) -> legend
|
|
3
|
+
Class API (modifiers are extra classes / attributes on the same element):
|
|
4
|
+
figure.oc-chart-line: Chart. Height from --oc-chart-line-height (12rem). Modifiers: --area (filled areas), --dots (dots always
|
|
5
|
+
visible), --spark (no axes or grid; 3rem high)
|
|
6
|
+
.oc-chart-line__head > .oc-chart-line__title, .oc-chart-line__sub, .oc-chart-line__value
|
|
7
|
+
.oc-chart-line__body > ul.oc-chart-line__y (labels top to bottom), .oc-chart-line__plot, ol.oc-chart-line__x
|
|
8
|
+
.oc-chart-line__plot (--oc-chart-line-rows: number of gridline rows, 4) > svg.oc-chart-line__svg (viewBox="0 0 100 100"
|
|
9
|
+
preserveAspectRatio="none") > g.oc-chart-line__series (color by position: --oc-chart-1..5) > path.oc-chart-line__area +
|
|
10
|
+
path.oc-chart-line__path (--dashed). Coordinates: x = index / (count - 1) * 100, y = 100 - value / max * 100
|
|
11
|
+
ul.oc-chart-line__cols (--n: number of points) > li.oc-chart-line__col (--x: index, tabindex="0", aria-label with the values)
|
|
12
|
+
> i.oc-chart-line__dot (--y: value / max in %, one per series) + span.oc-chart-line__tip > strong + span.oc-chart-line__row > b
|
|
13
|
+
.oc-chart-legend (chart component) below the plot: the swatch colors follow the same order
|
|
14
|
+
No JavaScript: tooltips open on :hover and :focus-visible. Generate the paths and percentages on the server or at build time.
|
|
15
|
+
-->
|
|
16
|
+
<figure class="oc-chart-line oc-chart-line--dots" style="max-inline-size:40rem">
|
|
17
|
+
<figcaption class="oc-chart-line__head">
|
|
18
|
+
<span class="oc-chart-line__title">Visitors</span>
|
|
19
|
+
<span class="oc-chart-line__sub">January – June 2026</span>
|
|
20
|
+
</figcaption>
|
|
21
|
+
<div class="oc-chart-line__body">
|
|
22
|
+
<ul class="oc-chart-line__y" aria-hidden="true"><li>320</li><li>240</li><li>160</li><li>80</li><li>0</li></ul>
|
|
23
|
+
<div class="oc-chart-line__plot">
|
|
24
|
+
<svg class="oc-chart-line__svg" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true">
|
|
25
|
+
<g class="oc-chart-line__series">
|
|
26
|
+
<path class="oc-chart-line__area" d="M0 41.87 C3.33 35.68 13.33 7.34 20 4.69 C26.67 4.69 33.33 13.85 40 25.94 C46.67 38.02 53.33 75.73 60 77.19 C66.67 77.19 73.33 42.03 80 34.69 C86.67 33.13 96.67 33.39 100 33.13 L100 100 L0 100 Z"/>
|
|
27
|
+
<path class="oc-chart-line__path" d="M0 41.87 C3.33 35.68 13.33 7.34 20 4.69 C26.67 4.69 33.33 13.85 40 25.94 C46.67 38.02 53.33 75.73 60 77.19 C66.67 77.19 73.33 42.03 80 34.69 C86.67 33.13 96.67 33.39 100 33.13"/>
|
|
28
|
+
</g>
|
|
29
|
+
<g class="oc-chart-line__series">
|
|
30
|
+
<path class="oc-chart-line__area" d="M0 75 C3.33 68.75 13.33 39.58 20 37.5 C26.67 37.5 33.33 61.98 40 62.5 C46.67 62.5 53.33 41.15 60 40.63 C66.67 40.63 73.33 56.77 80 59.38 C86.67 59.38 96.67 56.77 100 56.25 L100 100 L0 100 Z"/>
|
|
31
|
+
<path class="oc-chart-line__path" d="M0 75 C3.33 68.75 13.33 39.58 20 37.5 C26.67 37.5 33.33 61.98 40 62.5 C46.67 62.5 53.33 41.15 60 40.63 C66.67 40.63 73.33 56.77 80 59.38 C86.67 59.38 96.67 56.77 100 56.25"/>
|
|
32
|
+
</g>
|
|
33
|
+
</svg>
|
|
34
|
+
<ul class="oc-chart-line__cols" style="--n:6" aria-label="Visitors per month">
|
|
35
|
+
<li class="oc-chart-line__col" style="--x:0" tabindex="0" aria-label="January: Desktop 186, Mobile 80"><i class="oc-chart-line__dot" style="--y:58.13%"></i><i class="oc-chart-line__dot" style="--y:25%"></i><span class="oc-chart-line__tip" aria-hidden="true"><strong>January</strong><span class="oc-chart-line__row">Desktop<b>186</b></span><span class="oc-chart-line__row">Mobile<b>80</b></span></span></li>
|
|
36
|
+
<li class="oc-chart-line__col" style="--x:1" tabindex="0" aria-label="February: Desktop 305, Mobile 200"><i class="oc-chart-line__dot" style="--y:95.31%"></i><i class="oc-chart-line__dot" style="--y:62.5%"></i><span class="oc-chart-line__tip" aria-hidden="true"><strong>February</strong><span class="oc-chart-line__row">Desktop<b>305</b></span><span class="oc-chart-line__row">Mobile<b>200</b></span></span></li>
|
|
37
|
+
<li class="oc-chart-line__col" style="--x:2" tabindex="0" aria-label="March: Desktop 237, Mobile 120"><i class="oc-chart-line__dot" style="--y:74.06%"></i><i class="oc-chart-line__dot" style="--y:37.5%"></i><span class="oc-chart-line__tip" aria-hidden="true"><strong>March</strong><span class="oc-chart-line__row">Desktop<b>237</b></span><span class="oc-chart-line__row">Mobile<b>120</b></span></span></li>
|
|
38
|
+
<li class="oc-chart-line__col" style="--x:3" tabindex="0" aria-label="April: Desktop 73, Mobile 190"><i class="oc-chart-line__dot" style="--y:22.81%"></i><i class="oc-chart-line__dot" style="--y:59.38%"></i><span class="oc-chart-line__tip" aria-hidden="true"><strong>April</strong><span class="oc-chart-line__row">Desktop<b>73</b></span><span class="oc-chart-line__row">Mobile<b>190</b></span></span></li>
|
|
39
|
+
<li class="oc-chart-line__col" style="--x:4" tabindex="0" aria-label="May: Desktop 209, Mobile 130"><i class="oc-chart-line__dot" style="--y:65.31%"></i><i class="oc-chart-line__dot" style="--y:40.63%"></i><span class="oc-chart-line__tip" aria-hidden="true"><strong>May</strong><span class="oc-chart-line__row">Desktop<b>209</b></span><span class="oc-chart-line__row">Mobile<b>130</b></span></span></li>
|
|
40
|
+
<li class="oc-chart-line__col" style="--x:5" tabindex="0" aria-label="June: Desktop 214, Mobile 140"><i class="oc-chart-line__dot" style="--y:66.88%"></i><i class="oc-chart-line__dot" style="--y:43.75%"></i><span class="oc-chart-line__tip" aria-hidden="true"><strong>June</strong><span class="oc-chart-line__row">Desktop<b>214</b></span><span class="oc-chart-line__row">Mobile<b>140</b></span></span></li>
|
|
41
|
+
</ul>
|
|
42
|
+
</div>
|
|
43
|
+
<ol class="oc-chart-line__x" aria-hidden="true"><li>Jan</li><li>Feb</li><li>Mar</li><li>Apr</li><li>May</li><li>Jun</li></ol>
|
|
44
|
+
</div>
|
|
45
|
+
<ul class="oc-chart-legend"><li><span class="oc-chart-swatch"></span>Desktop</li><li><span class="oc-chart-swatch"></span>Mobile</li></ul>
|
|
46
|
+
</figure>
|