@birdycom/omniaui 0.11.1 → 0.12.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.
- package/dist/carousel.d.ts +6 -0
- package/dist/carousel.js +46 -0
- package/dist/components-extra.css +39 -0
- package/dist/components.css +166 -29
- package/dist/components.min.css +1 -1
- package/dist/oc-theme.css +1 -1
- package/dist/parts/site-fact-list.css +1 -1
- package/dist/parts/site-link-arrow.css +1 -1
- package/dist/parts/site-next-teaser.css +2 -2
- package/dist/parts/site-product-mark.css +1 -1
- package/dist/parts/site-project-card.css +4 -2
- package/dist/parts/site-stack-list.css +1 -1
- package/dist/parts/site-timeline.css +1 -1
- package/dist/showcase.css +21 -8
- package/manifest.json +8 -0
- package/package.json +3 -2
- package/snippets/carousel-loop.html +20 -0
- package/snippets/lightbox.html +13 -0
package/dist/oc-theme.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* File: oc-theme.css — generated from tokens/semantic.json by @birdycom/omniacss 0.
|
|
1
|
+
/* File: oc-theme.css — generated from tokens/semantic.json by @birdycom/omniacss 0.12.0. Do not edit. */
|
|
2
2
|
/* Semantic theme tokens: every color is light-dark() of an Omnia palette token (oc-colors.css). */
|
|
3
3
|
/* Same source as the desktop export: npx omniacss tokens --format json|dtcg|python */
|
|
4
4
|
:root {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
.oc-fact-list--stacked dd { text-align: start; }
|
|
20
20
|
|
|
21
21
|
/* Values in the accent color. */
|
|
22
|
-
.oc-fact-list--accent dd { color: var(--oc-accent-from); }
|
|
22
|
+
.oc-fact-list--accent dd { color: light-dark(var(--oc-accent-from), oklch(from var(--oc-accent-from) max(l, 0.72) c h)); }
|
|
23
23
|
|
|
24
24
|
/* Very narrow containers: wrap instead of squeezing label and value together. */
|
|
25
25
|
.oc-fact-list > div { flex-wrap: wrap; }
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
.oc-link-arrow--external:is(:hover, :focus-visible)::after { translate: 3px -3px; }
|
|
21
21
|
|
|
22
22
|
/* Colors: accent of the element, or muted text that turns to the foreground color on hover. */
|
|
23
|
-
.oc-link-arrow--accent { color: var(--oc-accent-from); }
|
|
23
|
+
.oc-link-arrow--accent { color: light-dark(var(--oc-accent-from), oklch(from var(--oc-accent-from) max(l, 0.72) c h)); }
|
|
24
24
|
.oc-link-arrow--muted { color: var(--oc-muted-foreground); font-weight: 500; transition: color 0.2s; }
|
|
25
25
|
.oc-link-arrow--muted:hover { color: var(--oc-foreground); }
|
|
26
26
|
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
}
|
|
48
48
|
.oc-next-teaser__tagline::after {
|
|
49
49
|
content: "→";
|
|
50
|
-
color: var(--oc-accent-from);
|
|
50
|
+
color: light-dark(var(--oc-accent-from), oklch(from var(--oc-accent-from) max(l, 0.72) c h));
|
|
51
51
|
transition: translate 0.25s var(--oc-ease-out);
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
.oc-next-teaser--prev .oc-next-teaser__tagline::after { content: none; }
|
|
56
56
|
.oc-next-teaser--prev .oc-next-teaser__tagline::before {
|
|
57
57
|
content: "←";
|
|
58
|
-
color: var(--oc-accent-from);
|
|
58
|
+
color: light-dark(var(--oc-accent-from), oklch(from var(--oc-accent-from) max(l, 0.72) c h));
|
|
59
59
|
transition: translate 0.25s var(--oc-ease-out);
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
.oc-product-mark--soft {
|
|
59
59
|
border: 1px solid color-mix(in oklch, var(--oc-accent-from) 40%, transparent);
|
|
60
60
|
background: color-mix(in oklch, var(--oc-accent-from) 16%, var(--oc-card));
|
|
61
|
-
color: var(--oc-accent-from);
|
|
61
|
+
color: light-dark(var(--oc-accent-from), oklch(from var(--oc-accent-from) max(l, 0.72) c h));
|
|
62
62
|
box-shadow: none;
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -50,6 +50,8 @@
|
|
|
50
50
|
background:
|
|
51
51
|
radial-gradient(circle at 80% 20%, color-mix(in oklch, var(--color-white-50) 30%, transparent), transparent 45%),
|
|
52
52
|
linear-gradient(135deg, var(--oc-accent-from), var(--oc-accent-to));
|
|
53
|
+
/* The hover zoom grows down and sideways (clipped by the frame), never up over the title bar. */
|
|
54
|
+
transform-origin: 50% 0;
|
|
53
55
|
transition: scale 0.5s var(--oc-ease-out);
|
|
54
56
|
}
|
|
55
57
|
|
|
@@ -66,7 +68,7 @@
|
|
|
66
68
|
padding: 0.2rem 0.6rem;
|
|
67
69
|
border-radius: 999px;
|
|
68
70
|
background: color-mix(in oklch, var(--oc-accent-from) 14%, transparent);
|
|
69
|
-
color: var(--oc-accent-from);
|
|
71
|
+
color: light-dark(var(--oc-accent-from), oklch(from var(--oc-accent-from) max(l, 0.72) c h));
|
|
70
72
|
font-size: 0.75rem;
|
|
71
73
|
font-weight: 600;
|
|
72
74
|
}
|
|
@@ -87,7 +89,7 @@
|
|
|
87
89
|
gap: 0.4rem;
|
|
88
90
|
margin-block-start: auto;
|
|
89
91
|
padding-block-start: 0.6rem;
|
|
90
|
-
color: var(--oc-accent-from);
|
|
92
|
+
color: light-dark(var(--oc-accent-from), oklch(from var(--oc-accent-from) max(l, 0.72) c h));
|
|
91
93
|
font-size: 0.9rem;
|
|
92
94
|
font-weight: 600;
|
|
93
95
|
}
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
display: inline-grid;
|
|
33
33
|
place-items: center;
|
|
34
34
|
inline-size: 1.1em;
|
|
35
|
-
color: var(--oc-accent-from);
|
|
35
|
+
color: light-dark(var(--oc-accent-from), oklch(from var(--oc-accent-from) max(l, 0.72) c h));
|
|
36
36
|
}
|
|
37
37
|
.oc-stack-list__icon > :is(img, svg) { inline-size: 100%; block-size: auto; }
|
|
38
38
|
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
/* Date or year label (use a <time> element when it is a real date).
|
|
25
25
|
Scoped under .oc-timeline so it wins over the showcase rules ".oc-timeline span / strong". */
|
|
26
26
|
.oc-timeline .oc-timeline__date {
|
|
27
|
-
color: var(--oc-accent-from);
|
|
27
|
+
color: light-dark(var(--oc-accent-from), oklch(from var(--oc-accent-from) max(l, 0.72) c h));
|
|
28
28
|
font-family: var(--oc-font-mono);
|
|
29
29
|
font-size: 0.85rem;
|
|
30
30
|
}
|
package/dist/showcase.css
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
fact/tag/check lists -> site header -> site footer -> reveal on scroll */
|
|
5
5
|
/* Showcase components — modern site/marketing building blocks, pure CSS (no JavaScript).
|
|
6
6
|
Colors: Omnia palette tokens only (OKLCH), via the theme tokens of components.css.
|
|
7
|
-
Accent per element: --oc-accent-from / --oc-accent-to (or an .oc-accent--* preset).
|
|
7
|
+
Accent per element: --oc-accent-from / --oc-accent-to (or an .oc-accent--* preset).
|
|
8
|
+
Accent as text color: in dark mode lifted to at least OKLCH L 0.72, so a dark custom accent stays readable. */
|
|
8
9
|
|
|
9
10
|
:root {
|
|
10
11
|
--oc-accent-from: var(--oc-brand-1);
|
|
@@ -47,7 +48,9 @@
|
|
|
47
48
|
.oc-btn--pill { border-radius: 999px; }
|
|
48
49
|
.oc-btn--gradient {
|
|
49
50
|
border-radius: 999px;
|
|
50
|
-
|
|
51
|
+
/* border-box: the gradient also runs under the transparent 1px border of .oc-btn; from the padding box it would
|
|
52
|
+
repeat in that border and show a thin stripe of the other end's color on both sides. */
|
|
53
|
+
background: linear-gradient(100deg, var(--oc-accent-from), var(--oc-accent-to)) border-box;
|
|
51
54
|
color: var(--color-white-50);
|
|
52
55
|
box-shadow: 0 10px 30px -10px var(--oc-accent-to);
|
|
53
56
|
transition: transform 0.2s var(--oc-ease-out), box-shadow 0.2s;
|
|
@@ -173,7 +176,7 @@
|
|
|
173
176
|
background:
|
|
174
177
|
linear-gradient(135deg, oklch(from var(--oc-accent-from) l c h / 0.3), oklch(from var(--oc-accent-to) l c h / 0.18)),
|
|
175
178
|
var(--oc-card);
|
|
176
|
-
color: var(--oc-accent-from);
|
|
179
|
+
color: light-dark(var(--oc-accent-from), oklch(from var(--oc-accent-from) max(l, 0.72) c h));
|
|
177
180
|
font-size: calc(var(--oc-tile-size) * 0.45);
|
|
178
181
|
line-height: 1;
|
|
179
182
|
}
|
|
@@ -213,7 +216,7 @@
|
|
|
213
216
|
}
|
|
214
217
|
.oc-product-card__top { display: flex; justify-content: space-between; align-items: flex-start; margin-block-end: 0.75rem; }
|
|
215
218
|
.oc-product-card__name { margin: 0; font-size: 1.45rem; font-weight: 700; letter-spacing: -0.02em; }
|
|
216
|
-
.oc-product-card__tagline { margin: 0; color: var(--oc-accent-from); font-weight: 600; font-size: 0.95rem; }
|
|
219
|
+
.oc-product-card__tagline { margin: 0; color: light-dark(var(--oc-accent-from), oklch(from var(--oc-accent-from) max(l, 0.72) c h)); font-weight: 600; font-size: 0.95rem; }
|
|
217
220
|
.oc-product-card__summary { margin: 0; color: var(--oc-muted-foreground); font-size: 0.95rem; flex-grow: 1; }
|
|
218
221
|
.oc-product-card__more { display: inline-flex; align-items: center; gap: 0.4rem; margin-block-start: 0.75rem; font-weight: 600; font-size: 0.92rem; }
|
|
219
222
|
.oc-product-card__more::after { content: "→"; transition: translate 0.25s var(--oc-ease-out); }
|
|
@@ -235,18 +238,23 @@
|
|
|
235
238
|
.oc-pill--accent {
|
|
236
239
|
border-color: oklch(from var(--oc-accent-from) l c h / 0.45);
|
|
237
240
|
background: oklch(from var(--oc-accent-from) l c h / 0.14);
|
|
238
|
-
color: var(--oc-accent-from);
|
|
241
|
+
color: light-dark(var(--oc-accent-from), oklch(from var(--oc-accent-from) max(l, 0.72) c h));
|
|
239
242
|
}
|
|
243
|
+
/* Pulse: the ring starts at --oc-status-dot-pulse-alpha of the accent and grows to --oc-status-dot-pulse-size.
|
|
244
|
+
--strong starts at the full accent with a wider ring. */
|
|
240
245
|
.oc-status-dot {
|
|
246
|
+
--oc-status-dot-pulse-alpha: 0.6;
|
|
247
|
+
--oc-status-dot-pulse-size: 8px;
|
|
241
248
|
inline-size: 0.5rem;
|
|
242
249
|
aspect-ratio: 1;
|
|
243
250
|
border-radius: 50%;
|
|
244
251
|
background: var(--oc-accent-from);
|
|
245
252
|
animation: oc-pulse 2s infinite;
|
|
246
253
|
}
|
|
254
|
+
.oc-status-dot--strong { --oc-status-dot-pulse-alpha: 1; --oc-status-dot-pulse-size: 10px; }
|
|
247
255
|
@keyframes oc-pulse {
|
|
248
|
-
0% { box-shadow: 0 0 0 0 oklch(from var(--oc-accent-from) l c h /
|
|
249
|
-
70%, 100% { box-shadow: 0 0 0
|
|
256
|
+
0% { box-shadow: 0 0 0 0 oklch(from var(--oc-accent-from) l c h / var(--oc-status-dot-pulse-alpha)); }
|
|
257
|
+
70%, 100% { box-shadow: 0 0 0 var(--oc-status-dot-pulse-size) transparent; }
|
|
250
258
|
}
|
|
251
259
|
|
|
252
260
|
/* Stat strip: big numbers in a bordered row (pairs with .oc-counter for counting up) */
|
|
@@ -277,7 +285,7 @@
|
|
|
277
285
|
var(--oc-card);
|
|
278
286
|
}
|
|
279
287
|
.oc-spotlight__title { display: flex; align-items: center; gap: 1rem; margin: 1.25rem 0 0.5rem; font-size: clamp(2.2rem, 5vw, 3.5rem); line-height: 1.1; }
|
|
280
|
-
.oc-spotlight__tagline { color: var(--oc-accent-from); font-size: 1.2rem; font-weight: 600; }
|
|
288
|
+
.oc-spotlight__tagline { color: light-dark(var(--oc-accent-from), oklch(from var(--oc-accent-from) max(l, 0.72) c h)); font-size: 1.2rem; font-weight: 600; }
|
|
281
289
|
.oc-spotlight__modules { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr)); gap: 0.75rem; margin: 0; padding: 0; list-style: none; }
|
|
282
290
|
.oc-spotlight__modules > li { display: flex; align-items: center; gap: 0.75rem; padding: 0.9rem; border: 1px solid var(--oc-border); border-radius: var(--oc-radius-md); background: var(--oc-surface); font-size: 0.95rem; }
|
|
283
291
|
|
|
@@ -352,9 +360,14 @@
|
|
|
352
360
|
}
|
|
353
361
|
@media (max-width: 860px) {
|
|
354
362
|
.oc-site-header__toggle { display: block; }
|
|
363
|
+
/* The author rule display:flex above beats the UA rule that hides a closed popover. */
|
|
364
|
+
.oc-site-header__nav[popover]:not(:popover-open) { display: none; }
|
|
355
365
|
.oc-site-header__nav[popover]:popover-open {
|
|
356
366
|
position: fixed;
|
|
357
367
|
inset: 4.5rem 0 auto;
|
|
368
|
+
/* The UA popover style sizes to fit-content; let inset span the full width. */
|
|
369
|
+
inline-size: auto;
|
|
370
|
+
block-size: auto;
|
|
358
371
|
display: flex;
|
|
359
372
|
flex-direction: column;
|
|
360
373
|
align-items: stretch;
|
package/manifest.json
CHANGED
|
@@ -1103,6 +1103,14 @@
|
|
|
1103
1103
|
"requires": [
|
|
1104
1104
|
"@birdycom/omniaui"
|
|
1105
1105
|
]
|
|
1106
|
+
},
|
|
1107
|
+
{
|
|
1108
|
+
"name": "carousel-loop",
|
|
1109
|
+
"file": "snippets/carousel-loop.html",
|
|
1110
|
+
"description": "Looping carousel: after the last slide the next button goes back to the first",
|
|
1111
|
+
"requires": [
|
|
1112
|
+
"@birdycom/omniaui"
|
|
1113
|
+
]
|
|
1106
1114
|
}
|
|
1107
1115
|
]
|
|
1108
1116
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@birdycom/omniaui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
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
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"./showcase.css": "./dist/showcase.css",
|
|
30
30
|
"./snippets/*": "./snippets/*",
|
|
31
31
|
"./data-table.js": "./dist/data-table.js",
|
|
32
|
+
"./carousel.js": "./dist/carousel.js",
|
|
32
33
|
"./manifest.json": "./manifest.json",
|
|
33
34
|
"./package.json": "./package.json"
|
|
34
35
|
},
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
"omniaui": "./bin/omniaui.mjs"
|
|
57
58
|
},
|
|
58
59
|
"peerDependencies": {
|
|
59
|
-
"@birdycom/omniacss": "^0.
|
|
60
|
+
"@birdycom/omniacss": "^0.12.0"
|
|
60
61
|
},
|
|
61
62
|
"peerDependenciesMeta": {
|
|
62
63
|
"@birdycom/omniacss": {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<!-- OmniaUI component: carousel-loop - Looping carousel: after the last slide the next button goes back to the first. Needs @birdycom/omniaui CSS and @birdycom/omniaui/carousel.js.
|
|
2
|
+
Class API: .oc-carousel--loop on the carousel, with .oc-carousel-prev / .oc-carousel-next buttons.
|
|
3
|
+
Script: import { initCarousels } from "@birdycom/omniaui/carousel.js"; initCarousels();
|
|
4
|
+
Without the script the buttons stay hidden and the CSS arrows (which stop at the ends) remain. -->
|
|
5
|
+
<div class="oc-carousel oc-carousel--loop">
|
|
6
|
+
<div class="oc-carousel-viewport" id="loop-carousel" tabindex="0" role="region" aria-roledescription="carousel" aria-label="Highlights">
|
|
7
|
+
<div class="oc-carousel-item" id="loop-slide-1" role="group" aria-roledescription="slide" aria-label="1 of 4">Slide 1</div>
|
|
8
|
+
<div class="oc-carousel-item" id="loop-slide-2" role="group" aria-roledescription="slide" aria-label="2 of 4">Slide 2</div>
|
|
9
|
+
<div class="oc-carousel-item" id="loop-slide-3" role="group" aria-roledescription="slide" aria-label="3 of 4">Slide 3</div>
|
|
10
|
+
<div class="oc-carousel-item" id="loop-slide-4" role="group" aria-roledescription="slide" aria-label="4 of 4">Slide 4</div>
|
|
11
|
+
</div>
|
|
12
|
+
<button class="oc-carousel-prev" type="button" aria-controls="loop-carousel" aria-label="Previous slide">←</button>
|
|
13
|
+
<button class="oc-carousel-next" type="button" aria-controls="loop-carousel" aria-label="Next slide">→</button>
|
|
14
|
+
<nav class="oc-carousel-dots" aria-label="Choose a slide">
|
|
15
|
+
<a class="oc-carousel-dot" href="#loop-slide-1" aria-label="Slide 1"></a>
|
|
16
|
+
<a class="oc-carousel-dot" href="#loop-slide-2" aria-label="Slide 2"></a>
|
|
17
|
+
<a class="oc-carousel-dot" href="#loop-slide-3" aria-label="Slide 3"></a>
|
|
18
|
+
<a class="oc-carousel-dot" href="#loop-slide-4" aria-label="Slide 4"></a>
|
|
19
|
+
</nav>
|
|
20
|
+
</div>
|
package/snippets/lightbox.html
CHANGED
|
@@ -47,4 +47,17 @@ document.addEventListener("command", (e) => {
|
|
|
47
47
|
const id = e.source?.dataset.ocLightboxSlide;
|
|
48
48
|
if (id) requestAnimationFrame(() => document.getElementById(id)?.scrollIntoView({ behavior: "instant", block: "nearest", inline: "center" }));
|
|
49
49
|
}, true);
|
|
50
|
+
// Optional: prev / next scroll without putting #slide in the address and the history (without this script they
|
|
51
|
+
// are plain links), and closing removes a slide hash of this viewer from the address.
|
|
52
|
+
document.addEventListener("click", (e) => {
|
|
53
|
+
const nav = e.target.closest?.("dialog.oc-lightbox a.oc-lightbox__nav");
|
|
54
|
+
const slide = nav && document.getElementById(decodeURIComponent(nav.hash.slice(1)));
|
|
55
|
+
if (!slide) return;
|
|
56
|
+
e.preventDefault();
|
|
57
|
+
slide.scrollIntoView({ behavior: matchMedia("(prefers-reduced-motion: reduce)").matches ? "instant" : "smooth", block: "nearest", inline: "center" });
|
|
58
|
+
});
|
|
59
|
+
document.addEventListener("close", (e) => {
|
|
60
|
+
const slide = e.target.matches?.("dialog.oc-lightbox") && location.hash && document.getElementById(decodeURIComponent(location.hash.slice(1)));
|
|
61
|
+
if (slide && e.target.contains(slide)) history.replaceState(history.state, "", location.pathname + location.search);
|
|
62
|
+
}, true);
|
|
50
63
|
</script>
|