@akonwi/mica 0.6.0 → 0.8.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/README.md +12 -10
- package/combobox.d.ts +9 -0
- package/combobox.js +53 -19
- package/drawer.d.ts +5 -0
- package/drawer.js +1 -1
- package/field.d.ts +10 -0
- package/field.js +1 -1
- package/invoker.d.ts +5 -0
- package/mica.css +68 -14
- package/package.json +36 -8
- package/select.d.ts +5 -0
- package/select.js +1 -1
- package/tabs.d.ts +9 -0
- package/tabs.js +1 -1
- package/toast.d.ts +17 -0
- package/toast.js +2 -2
package/README.md
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
**Custom elements. Native behavior. Nearly no JavaScript.**
|
|
4
4
|
|
|
5
|
-
Mica is a
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
Mica is a **progressive component library** of custom elements —
|
|
6
|
+
progressive as in progressive enhancement: every component starts from
|
|
7
|
+
markup that works, and each layer (CSS, the browser's native behavior, an
|
|
8
|
+
optional JS module) enhances it. No runtime, no build step, no framework.
|
|
9
|
+
View source — there's nothing there but HTML and a stylesheet.
|
|
8
10
|
|
|
9
11
|
```html
|
|
10
12
|
<link rel="stylesheet" href="mica.css">
|
|
@@ -47,18 +49,18 @@ import "@akonwi/mica/mica.css";
|
|
|
47
49
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@akonwi/mica@0.2/mica.css">
|
|
48
50
|
```
|
|
49
51
|
|
|
50
|
-
##
|
|
52
|
+
## Progressive by design
|
|
51
53
|
|
|
52
54
|
Every component states where its behavior comes from
|
|
53
|
-
(see [
|
|
55
|
+
(see [PROGRESSIVE.md](PROGRESSIVE.md)):
|
|
54
56
|
|
|
55
|
-
- **
|
|
57
|
+
- **CSS-only — CSS is the behavior.** Layout primitives: `m-vstack`,
|
|
56
58
|
`m-hstack`, `m-zstack`, `m-center`, `m-box`, `m-grid`, `m-sidecar`,
|
|
57
59
|
`m-switcher`, `m-reel`. Zero JS, work with JS disabled.
|
|
58
|
-
- **
|
|
60
|
+
- **Native behavior — the browser is the behavior.** Styled native elements:
|
|
59
61
|
buttons, forms, `<dialog>`, `<details>` accordions, popover menus,
|
|
60
62
|
tooltips, toasts. Delete the stylesheet and everything still works.
|
|
61
|
-
- **
|
|
63
|
+
- **JS-enhanced — script, honestly.** Where accessibility genuinely requires
|
|
62
64
|
JS: `tabs.js`, `combobox.js`, `field.js` (declarative validation),
|
|
63
65
|
`select.js`, `toast.js`. Each is a tiny standalone module that enhances
|
|
64
66
|
working markup — never renders it. There is no shared runtime.
|
|
@@ -83,8 +85,8 @@ how. Nothing breaks; some things get plainer.
|
|
|
83
85
|
mica itself (view source). The [demo](https://akonwi.io/mica/demo.html) is
|
|
84
86
|
the whole library on one page.
|
|
85
87
|
|
|
86
|
-
Read [VISION.md](VISION.md) for the philosophy and
|
|
87
|
-
for
|
|
88
|
+
Read [VISION.md](VISION.md) for the philosophy and
|
|
89
|
+
[PROGRESSIVE.md](PROGRESSIVE.md) for how components are allowed to work.
|
|
88
90
|
|
|
89
91
|
## License
|
|
90
92
|
|
package/combobox.d.ts
ADDED
package/combobox.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* mica/combobox.js — <m-combobox>: filterable input + listbox.
|
|
1
|
+
/* mica/combobox.js — <m-combobox>: filterable input + listbox. JS-enhanced module.
|
|
2
2
|
*
|
|
3
3
|
* The no-JS state is a native <datalist> — real autocomplete, fully
|
|
4
4
|
* functional, just unstylable. The module upgrades it into the ARIA
|
|
@@ -20,13 +20,16 @@ let uid = 0;
|
|
|
20
20
|
class MCombobox extends HTMLElement {
|
|
21
21
|
#input;
|
|
22
22
|
#list;
|
|
23
|
+
#datalist;
|
|
24
|
+
#listId;
|
|
23
25
|
#options = [];
|
|
24
26
|
#active = -1;
|
|
27
|
+
#observer;
|
|
25
28
|
|
|
26
29
|
connectedCallback() {
|
|
27
30
|
this.#input = this.querySelector("input");
|
|
28
|
-
|
|
29
|
-
if (!this.#input || !datalist) return;
|
|
31
|
+
this.#datalist = this.querySelector("datalist");
|
|
32
|
+
if (!this.#input || !this.#datalist) return;
|
|
30
33
|
|
|
31
34
|
// disable the native popup; the module takes over
|
|
32
35
|
this.#input.removeAttribute("list");
|
|
@@ -35,16 +38,49 @@ class MCombobox extends HTMLElement {
|
|
|
35
38
|
this.#input.setAttribute("aria-autocomplete", "list");
|
|
36
39
|
this.#input.autocomplete = "off";
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
this.#listId = `m-cb-${++uid}`;
|
|
39
42
|
this.#list = document.createElement("div");
|
|
40
|
-
this.#list.id = listId;
|
|
43
|
+
this.#list.id = this.#listId;
|
|
41
44
|
this.#list.setAttribute("role", "listbox");
|
|
42
45
|
this.#list.hidden = true;
|
|
43
46
|
|
|
44
|
-
this.#
|
|
47
|
+
this.#buildOptions();
|
|
48
|
+
this.append(this.#list);
|
|
49
|
+
this.#input.setAttribute("aria-controls", this.#listId);
|
|
50
|
+
|
|
51
|
+
// Options may be rendered asynchronously (a search-backed combobox):
|
|
52
|
+
// rebuild the listbox whenever the author's datalist changes.
|
|
53
|
+
this.#observer = new MutationObserver(() => {
|
|
54
|
+
this.#buildOptions();
|
|
55
|
+
if (document.activeElement === this.#input) this.#openAndFilter();
|
|
56
|
+
});
|
|
57
|
+
this.#observer.observe(this.#datalist, {
|
|
58
|
+
childList: true,
|
|
59
|
+
subtree: true,
|
|
60
|
+
attributes: true,
|
|
61
|
+
attributeFilter: ["value"],
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
this.#input.addEventListener("input", (e) => {
|
|
65
|
+
// ignore our own dispatched events from #choose — they'd reopen
|
|
66
|
+
if (e.isTrusted) this.#openAndFilter();
|
|
67
|
+
});
|
|
68
|
+
this.#input.addEventListener("keydown", (e) => this.#onKey(e));
|
|
69
|
+
this.addEventListener("focusout", (e) => {
|
|
70
|
+
if (!this.contains(e.relatedTarget)) this.#close();
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
disconnectedCallback() {
|
|
75
|
+
this.#observer?.disconnect();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
#buildOptions() {
|
|
79
|
+
this.#list.replaceChildren();
|
|
80
|
+
this.#options = [...this.#datalist.options].map((o, i) => {
|
|
45
81
|
const d = document.createElement("div");
|
|
46
82
|
d.setAttribute("role", "option");
|
|
47
|
-
d.id = `${listId}-${i}`;
|
|
83
|
+
d.id = `${this.#listId}-${i}`;
|
|
48
84
|
d.textContent = o.value || o.textContent;
|
|
49
85
|
// pointerdown so the input never loses focus
|
|
50
86
|
d.addEventListener("pointerdown", (e) => {
|
|
@@ -58,17 +94,7 @@ class MCombobox extends HTMLElement {
|
|
|
58
94
|
this.#list.append(d);
|
|
59
95
|
return d;
|
|
60
96
|
});
|
|
61
|
-
this
|
|
62
|
-
this.#input.setAttribute("aria-controls", listId);
|
|
63
|
-
|
|
64
|
-
this.#input.addEventListener("input", (e) => {
|
|
65
|
-
// ignore our own dispatched events from #choose — they'd reopen
|
|
66
|
-
if (e.isTrusted) this.#openAndFilter();
|
|
67
|
-
});
|
|
68
|
-
this.#input.addEventListener("keydown", (e) => this.#onKey(e));
|
|
69
|
-
this.addEventListener("focusout", (e) => {
|
|
70
|
-
if (!this.contains(e.relatedTarget)) this.#close();
|
|
71
|
-
});
|
|
97
|
+
this.#active = -1;
|
|
72
98
|
}
|
|
73
99
|
|
|
74
100
|
#visible() {
|
|
@@ -127,7 +153,15 @@ class MCombobox extends HTMLElement {
|
|
|
127
153
|
}
|
|
128
154
|
|
|
129
155
|
#choose(option) {
|
|
130
|
-
|
|
156
|
+
// Write through the native prototype setter: frameworks that patch
|
|
157
|
+
// the value property to track controlled inputs (React) only observe
|
|
158
|
+
// the change when it lands on the native setter.
|
|
159
|
+
const setter = Object.getOwnPropertyDescriptor(
|
|
160
|
+
HTMLInputElement.prototype,
|
|
161
|
+
"value",
|
|
162
|
+
)?.set;
|
|
163
|
+
if (setter) setter.call(this.#input, option.textContent);
|
|
164
|
+
else this.#input.value = option.textContent;
|
|
131
165
|
this.#close();
|
|
132
166
|
this.#input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
133
167
|
this.#input.dispatchEvent(new Event("change", { bubbles: true }));
|
package/drawer.d.ts
ADDED
package/drawer.js
CHANGED
package/field.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/* Type declarations for mica/field.js — side-effect module.
|
|
2
|
+
* Registers <m-field>: declarative validation errors via <m-error match>.
|
|
3
|
+
*/
|
|
4
|
+
declare global {
|
|
5
|
+
interface HTMLElementTagNameMap {
|
|
6
|
+
"m-field": HTMLElement;
|
|
7
|
+
"m-error": HTMLElement;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export {};
|
package/field.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* mica/field.js — <m-field>: declarative validation errors.
|
|
1
|
+
/* mica/field.js — <m-field>: declarative validation errors. JS-enhanced module.
|
|
2
2
|
*
|
|
3
3
|
* Enhances working light-DOM markup; never renders it. Without this
|
|
4
4
|
* module, fields inside <m-field> fall back to native bubbles plus the
|
package/invoker.d.ts
ADDED
package/mica.css
CHANGED
|
@@ -40,6 +40,13 @@
|
|
|
40
40
|
--control-height: 2.25rem;
|
|
41
41
|
--control-height-lg: 2.5rem;
|
|
42
42
|
|
|
43
|
+
/* Where toasts pin. App-level config — set once, all toasts obey:
|
|
44
|
+
bottom-right (default) | bottom-left | bottom-center |
|
|
45
|
+
top-right | top-left | top-center.
|
|
46
|
+
Read via container style queries (Baseline newly-available
|
|
47
|
+
2026-05); browsers without them keep the bottom-right default. */
|
|
48
|
+
--toast-position: bottom-right;
|
|
49
|
+
|
|
43
50
|
--focus-ring-width: 2px;
|
|
44
51
|
--focus-ring-offset: 2px;
|
|
45
52
|
--focus-ring-color: var(--color-accent);
|
|
@@ -267,7 +274,7 @@
|
|
|
267
274
|
}
|
|
268
275
|
|
|
269
276
|
/* ------------------------------------------------------------------ *
|
|
270
|
-
* Elements —
|
|
277
|
+
* Elements — native behavior. Native elements styled directly; behavior is the
|
|
271
278
|
* browser's. Presentation APIs are attributes; user CSS still wins
|
|
272
279
|
* because these rules live in a layer.
|
|
273
280
|
* ------------------------------------------------------------------ */
|
|
@@ -1184,7 +1191,7 @@
|
|
|
1184
1191
|
}
|
|
1185
1192
|
|
|
1186
1193
|
/* grab handle — only when drawer.js is loaded (an affordance
|
|
1187
|
-
without its behavior would fake interactivity;
|
|
1194
|
+
without its behavior would fake interactivity; PROGRESSIVE.md).
|
|
1188
1195
|
the handle is the first flex item of the open sheet. */
|
|
1189
1196
|
:where(:root[data-drawer-gestures])
|
|
1190
1197
|
:where(dialog[data-drawer][open])::before {
|
|
@@ -1204,7 +1211,7 @@
|
|
|
1204
1211
|
}
|
|
1205
1212
|
|
|
1206
1213
|
/* scroll lock: the page must not scroll behind any modal dialog.
|
|
1207
|
-
CSS-only best effort (→ no
|
|
1214
|
+
CSS-only best effort (→ no faked-behavior violation); iOS honors
|
|
1208
1215
|
overflow:hidden on the root for modern versions. */
|
|
1209
1216
|
:where(html):has(:where(dialog:modal)) {
|
|
1210
1217
|
overflow: hidden;
|
|
@@ -1384,7 +1391,7 @@
|
|
|
1384
1391
|
}
|
|
1385
1392
|
}
|
|
1386
1393
|
|
|
1387
|
-
/* --- combobox: m-combobox + combobox.js (
|
|
1394
|
+
/* --- combobox: m-combobox + combobox.js (JS-enhanced) ------------------ *
|
|
1388
1395
|
* without the module: a native datalist — functional autocomplete.
|
|
1389
1396
|
* with it: styled listbox, filtering, active-descendant keys.
|
|
1390
1397
|
* positioned within the wrapper (no top layer) so it works everywhere.
|
|
@@ -1421,7 +1428,7 @@
|
|
|
1421
1428
|
}
|
|
1422
1429
|
}
|
|
1423
1430
|
|
|
1424
|
-
/* --- tabs: m-tabs + tabs.js (
|
|
1431
|
+
/* --- tabs: m-tabs + tabs.js (JS-enhanced) ------------------------------ *
|
|
1425
1432
|
* without the module: inert nav, all panels visible in order —
|
|
1426
1433
|
* complete content. with it: tablist semantics + roving focus.
|
|
1427
1434
|
* shadcn segmented look: muted track, surface active tab.
|
|
@@ -1481,7 +1488,7 @@
|
|
|
1481
1488
|
padding-block: var(--space-md);
|
|
1482
1489
|
}
|
|
1483
1490
|
|
|
1484
|
-
/* --- toast: display only (queueing/auto-dismiss are
|
|
1491
|
+
/* --- toast: display only (queueing/auto-dismiss are JS-enhanced) ------- *
|
|
1485
1492
|
* <m-toast popover="manual" role="status"> — manual so it survives
|
|
1486
1493
|
* light dismiss and other popovers; role=status announces.
|
|
1487
1494
|
* ------------------------------------------------------------------ */
|
|
@@ -1514,10 +1521,45 @@
|
|
|
1514
1521
|
border-inline-start: 2px solid var(--color-warn);
|
|
1515
1522
|
}
|
|
1516
1523
|
}
|
|
1517
|
-
/*
|
|
1518
|
-
|
|
1524
|
+
/* --toast-position overrides (base = bottom-right). Style queries read
|
|
1525
|
+
the token from the toast's parent; without support the default
|
|
1526
|
+
corner stands — graceful. Stack offset feeds whichever block inset
|
|
1527
|
+
is active; centers use inset-inline 0 + auto margins. */
|
|
1528
|
+
@container style(--toast-position: bottom-left) {
|
|
1529
|
+
:where(m-toast[popover]) {
|
|
1530
|
+
inset: auto auto calc(var(--space-lg) + var(--m-toast-offset, 0px)) var(--space-lg);
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
@container style(--toast-position: bottom-center) {
|
|
1534
|
+
:where(m-toast[popover]) {
|
|
1535
|
+
inset: auto 0 calc(var(--space-lg) + var(--m-toast-offset, 0px)) 0;
|
|
1536
|
+
margin-inline: auto;
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
@container style(--toast-position: top-right) {
|
|
1540
|
+
:where(m-toast[popover]) {
|
|
1541
|
+
inset: calc(var(--space-lg) + var(--m-toast-offset, 0px)) var(--space-lg) auto auto;
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
@container style(--toast-position: top-left) {
|
|
1545
|
+
:where(m-toast[popover]) {
|
|
1546
|
+
inset: calc(var(--space-lg) + var(--m-toast-offset, 0px)) auto auto var(--space-lg);
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
@container style(--toast-position: top-center) {
|
|
1550
|
+
:where(m-toast[popover]) {
|
|
1551
|
+
inset: calc(var(--space-lg) + var(--m-toast-offset, 0px)) 0 auto 0;
|
|
1552
|
+
margin-inline: auto;
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
/* restacking motion always (both block insets — only the active one
|
|
1557
|
+
ever changes); the entrance slide/fade only where overlay
|
|
1558
|
+
transitions work — see the base popover note. */
|
|
1519
1559
|
:where(m-toast[popover]:popover-open) {
|
|
1520
|
-
transition:
|
|
1560
|
+
transition:
|
|
1561
|
+
inset-block-end 0.15s,
|
|
1562
|
+
inset-block-start 0.15s;
|
|
1521
1563
|
}
|
|
1522
1564
|
@supports (overlay: auto) {
|
|
1523
1565
|
:where(m-toast[popover]:popover-open) {
|
|
@@ -1525,6 +1567,7 @@
|
|
|
1525
1567
|
opacity 0.1s,
|
|
1526
1568
|
translate 0.1s,
|
|
1527
1569
|
inset-block-end 0.15s,
|
|
1570
|
+
inset-block-start 0.15s,
|
|
1528
1571
|
overlay 0.1s allow-discrete,
|
|
1529
1572
|
display 0.1s allow-discrete;
|
|
1530
1573
|
}
|
|
@@ -1533,6 +1576,17 @@
|
|
|
1533
1576
|
translate: 0 0.75rem;
|
|
1534
1577
|
}
|
|
1535
1578
|
}
|
|
1579
|
+
/* top positions enter from above — must follow the base
|
|
1580
|
+
@starting-style in source order to win at equal specificity */
|
|
1581
|
+
@container style(--toast-position: top-right) or
|
|
1582
|
+
style(--toast-position: top-left) or
|
|
1583
|
+
style(--toast-position: top-center) {
|
|
1584
|
+
@starting-style {
|
|
1585
|
+
:where(m-toast[popover]:popover-open) {
|
|
1586
|
+
translate: 0 -0.75rem;
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1536
1590
|
}
|
|
1537
1591
|
|
|
1538
1592
|
/* --- tooltip: css-only, [data-tip] -------------------------------- *
|
|
@@ -1572,9 +1626,9 @@
|
|
|
1572
1626
|
}
|
|
1573
1627
|
|
|
1574
1628
|
/* --- validation errors ------------------------------------------- *
|
|
1575
|
-
*
|
|
1629
|
+
* No JS: a generic <m-error> after a field shows when the
|
|
1576
1630
|
* field is :user-invalid. Submit attempts fall back to native bubbles.
|
|
1577
|
-
*
|
|
1631
|
+
* Enhanced (mica/field.js): <m-field> suppresses bubbles and activates
|
|
1578
1632
|
* per-cause <m-error match="..."> messages. Rules below are all
|
|
1579
1633
|
* zero-specificity; source order resolves them.
|
|
1580
1634
|
* ------------------------------------------------------------------ */
|
|
@@ -1591,13 +1645,13 @@
|
|
|
1591
1645
|
color: var(--color-danger-text);
|
|
1592
1646
|
}
|
|
1593
1647
|
|
|
1594
|
-
/*
|
|
1648
|
+
/* no-JS fallback: generic (matchless) error after user interaction */
|
|
1595
1649
|
:where(input:user-invalid, textarea:user-invalid, select:user-invalid)
|
|
1596
1650
|
~ :where(m-error:not([match])) {
|
|
1597
1651
|
display: block;
|
|
1598
1652
|
}
|
|
1599
1653
|
|
|
1600
|
-
/*
|
|
1654
|
+
/* enhanced: once m-field upgrades, the module owns visibility */
|
|
1601
1655
|
:where(m-field:defined) :where(m-error) {
|
|
1602
1656
|
display: none;
|
|
1603
1657
|
}
|
|
@@ -1642,7 +1696,7 @@
|
|
|
1642
1696
|
}
|
|
1643
1697
|
|
|
1644
1698
|
/* ------------------------------------------------------------------ *
|
|
1645
|
-
* Layout primitives (
|
|
1699
|
+
* Layout primitives (CSS-only)
|
|
1646
1700
|
*
|
|
1647
1701
|
* Mechanism: attributes only set custom properties; rules read custom
|
|
1648
1702
|
* properties. `gap="lg"` and `style="--gap: 2.5rem"` are the same thing.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akonwi/mica",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Custom elements. Native behavior. Nearly no JavaScript.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"css",
|
|
@@ -21,13 +21,34 @@
|
|
|
21
21
|
"exports": {
|
|
22
22
|
".": "./mica.css",
|
|
23
23
|
"./mica.css": "./mica.css",
|
|
24
|
-
"./invoker.js":
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"./
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
"./invoker.js": {
|
|
25
|
+
"types": "./invoker.d.ts",
|
|
26
|
+
"default": "./invoker.js"
|
|
27
|
+
},
|
|
28
|
+
"./drawer.js": {
|
|
29
|
+
"types": "./drawer.d.ts",
|
|
30
|
+
"default": "./drawer.js"
|
|
31
|
+
},
|
|
32
|
+
"./field.js": {
|
|
33
|
+
"types": "./field.d.ts",
|
|
34
|
+
"default": "./field.js"
|
|
35
|
+
},
|
|
36
|
+
"./select.js": {
|
|
37
|
+
"types": "./select.d.ts",
|
|
38
|
+
"default": "./select.js"
|
|
39
|
+
},
|
|
40
|
+
"./tabs.js": {
|
|
41
|
+
"types": "./tabs.d.ts",
|
|
42
|
+
"default": "./tabs.js"
|
|
43
|
+
},
|
|
44
|
+
"./toast.js": {
|
|
45
|
+
"types": "./toast.d.ts",
|
|
46
|
+
"default": "./toast.js"
|
|
47
|
+
},
|
|
48
|
+
"./combobox.js": {
|
|
49
|
+
"types": "./combobox.d.ts",
|
|
50
|
+
"default": "./combobox.js"
|
|
51
|
+
},
|
|
31
52
|
"./types/react": {
|
|
32
53
|
"types": "./types/react.d.ts"
|
|
33
54
|
}
|
|
@@ -35,12 +56,19 @@
|
|
|
35
56
|
"files": [
|
|
36
57
|
"mica.css",
|
|
37
58
|
"invoker.js",
|
|
59
|
+
"invoker.d.ts",
|
|
38
60
|
"drawer.js",
|
|
61
|
+
"drawer.d.ts",
|
|
39
62
|
"field.js",
|
|
63
|
+
"field.d.ts",
|
|
40
64
|
"select.js",
|
|
65
|
+
"select.d.ts",
|
|
41
66
|
"tabs.js",
|
|
67
|
+
"tabs.d.ts",
|
|
42
68
|
"toast.js",
|
|
69
|
+
"toast.d.ts",
|
|
43
70
|
"combobox.js",
|
|
71
|
+
"combobox.d.ts",
|
|
44
72
|
"types/react.d.ts"
|
|
45
73
|
],
|
|
46
74
|
"sideEffects": true,
|
package/select.d.ts
ADDED
package/select.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* mica/select.js — align the open select picker so the selected option
|
|
2
2
|
* overlays the trigger (macOS-native / Base UI `alignItemWithTrigger`
|
|
3
|
-
* behavior).
|
|
3
|
+
* behavior). A JS-enhanced module, and about as small as a module can be:
|
|
4
4
|
*
|
|
5
5
|
* JS supplies exactly one datum — the selected index, as a custom
|
|
6
6
|
* property. All geometry lives in mica.css (anchor positioning).
|
package/tabs.d.ts
ADDED
package/tabs.js
CHANGED
package/toast.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/* Type declarations for mica/toast.js.
|
|
2
|
+
* Importing registers <m-toast> (queueing, auto-dismiss, restacking) and
|
|
3
|
+
* exports the imperative spawner.
|
|
4
|
+
*/
|
|
5
|
+
export interface ToastOptions {
|
|
6
|
+
description?: string;
|
|
7
|
+
variant?: "success" | "warning" | "danger";
|
|
8
|
+
/** Auto-dismiss delay in ms; string accepted as attribute passthrough. */
|
|
9
|
+
duration?: number | string;
|
|
10
|
+
}
|
|
11
|
+
/** Create, show, and return an <m-toast> element. */
|
|
12
|
+
export function toast(title: string, options?: ToastOptions): HTMLElement;
|
|
13
|
+
declare global {
|
|
14
|
+
interface HTMLElementTagNameMap {
|
|
15
|
+
"m-toast": HTMLElement;
|
|
16
|
+
}
|
|
17
|
+
}
|
package/toast.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* mica/toast.js — toast stacking, auto-dismiss, and a spawn helper.
|
|
2
|
-
*
|
|
2
|
+
* JS-enhanced module.
|
|
3
3
|
*
|
|
4
|
-
* Enhances the
|
|
4
|
+
* Enhances the no-JS <m-toast> recipe (corner-pinned manual popovers).
|
|
5
5
|
* Declared toasts keep working without this module — it adds:
|
|
6
6
|
*
|
|
7
7
|
* - stacking: open toasts stack upward; JS ships one number per toast
|