@jirawatpyk/aura-tokens 5.5.0 → 5.6.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/aura-tailwind.css +1 -1
- package/aura-tailwind.prefixed.css +1 -1
- package/aura.css +1 -1
- package/components/aura.bundle.js +180 -38
- package/components/aura.components.css +25 -4
- package/components/index.d.ts +31 -9
- package/package.json +1 -1
- package/tokens.json +1 -1
package/aura-tailwind.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* AURA v5.
|
|
1
|
+
/* AURA v5.6.0 — Tailwind v4 theme. GENERATED by scripts/build-tokens.mts from tokens.json. Do not edit by hand.
|
|
2
2
|
* @import "tailwindcss";
|
|
3
3
|
* @import "@jirawatpyk/aura-tokens/tailwind.css";
|
|
4
4
|
* Gives bg-bg-surface, text-fg-primary, border-border-strong, p-aura-6, rounded-aura-xl, shadow-aura-overlay,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* AURA v5.
|
|
1
|
+
/* AURA v5.6.0 — Tailwind v4 theme with aura- prefixed names. GENERATED by scripts/build-tokens.mts. Do not edit by hand.
|
|
2
2
|
* For apps that already have a Tailwind theme (shadcn): nothing here redefines an existing name.
|
|
3
3
|
* @layer aura-tokens, theme, base, aura, components, utilities;
|
|
4
4
|
* @import "tailwindcss";
|
package/aura.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* AURA v5.
|
|
1
|
+
/* AURA v5.6.0 — GENERATED by scripts/build-tokens.mts from tokens.json. Do not edit by hand. */
|
|
2
2
|
/* Fonts: load aura-fonts.css (or the <link> tags in README) separately, so a blocked Google Fonts never breaks this file. */
|
|
3
3
|
|
|
4
4
|
:root, [data-theme="light"] {
|
|
@@ -3079,10 +3079,35 @@ window.Aura = (() => {
|
|
|
3079
3079
|
promote();
|
|
3080
3080
|
emitToasts();
|
|
3081
3081
|
};
|
|
3082
|
+
var hotkeyOrigin = /* @__PURE__ */ new WeakMap();
|
|
3083
|
+
function outsideToaster(el) {
|
|
3084
|
+
return el && el !== document.body && !el.closest(".aura-toaster") ? el : null;
|
|
3085
|
+
}
|
|
3082
3086
|
function ToastItem(props) {
|
|
3083
3087
|
const str = useStrings();
|
|
3088
|
+
const Link = useLinkComponent();
|
|
3089
|
+
const node = React19.useRef(null);
|
|
3090
|
+
const origin = React19.useRef(null);
|
|
3091
|
+
useIsoLayoutEffect(function() {
|
|
3092
|
+
origin.current = outsideToaster(document.activeElement);
|
|
3093
|
+
const el = node.current;
|
|
3094
|
+
return function() {
|
|
3095
|
+
if (!el || !el.contains(document.activeElement)) return;
|
|
3096
|
+
const back = [hotkeyOrigin.get(el), origin.current].filter(function(b) {
|
|
3097
|
+
return !!b && b.isConnected;
|
|
3098
|
+
})[0];
|
|
3099
|
+
hotkeyOrigin.delete(el);
|
|
3100
|
+
setTimeout(function() {
|
|
3101
|
+
if (back && back.isConnected && (!document.activeElement || document.activeElement === document.body))
|
|
3102
|
+
back.focus();
|
|
3103
|
+
}, 0);
|
|
3104
|
+
};
|
|
3105
|
+
}, []);
|
|
3084
3106
|
const t = props.toast, timer = React19.useRef(null), left = React19.useRef(t.duration || 5e3), since = React19.useRef(0);
|
|
3085
|
-
const hover = React19.useRef(false);
|
|
3107
|
+
const hover = React19.useRef(false), focused = React19.useRef(false);
|
|
3108
|
+
function syncFocus() {
|
|
3109
|
+
if (focused.current && !(node.current && node.current.contains(document.activeElement))) focused.current = false;
|
|
3110
|
+
}
|
|
3086
3111
|
function start() {
|
|
3087
3112
|
if (left.current === Infinity || timer.current) return;
|
|
3088
3113
|
since.current = Date.now();
|
|
@@ -3091,11 +3116,10 @@ window.Aura = (() => {
|
|
|
3091
3116
|
}, left.current);
|
|
3092
3117
|
}
|
|
3093
3118
|
function resume() {
|
|
3094
|
-
|
|
3095
|
-
start();
|
|
3119
|
+
syncFocus();
|
|
3120
|
+
if (!hover.current && !focused.current) start();
|
|
3096
3121
|
}
|
|
3097
3122
|
function pause() {
|
|
3098
|
-
hover.current = true;
|
|
3099
3123
|
if (timer.current) {
|
|
3100
3124
|
clearTimeout(timer.current);
|
|
3101
3125
|
timer.current = null;
|
|
@@ -3107,23 +3131,56 @@ window.Aura = (() => {
|
|
|
3107
3131
|
if (timer.current) clearTimeout(timer.current);
|
|
3108
3132
|
timer.current = null;
|
|
3109
3133
|
left.current = t.duration || 5e3;
|
|
3110
|
-
|
|
3134
|
+
syncFocus();
|
|
3135
|
+
if (!hover.current && !focused.current) start();
|
|
3111
3136
|
return function() {
|
|
3112
3137
|
if (timer.current) clearTimeout(timer.current);
|
|
3113
3138
|
};
|
|
3114
3139
|
},
|
|
3115
3140
|
[t.rev]
|
|
3116
3141
|
);
|
|
3142
|
+
const rich = t.description != null && typeof t.description !== "boolean" && t.description !== "";
|
|
3143
|
+
const actions = (t.actions && t.actions.length ? t.actions : t.action ? [t.action] : []).slice(0, 2);
|
|
3144
|
+
function run(a) {
|
|
3145
|
+
if (a.onClick) a.onClick();
|
|
3146
|
+
if (a.dismiss !== false) toast.dismiss(t.id);
|
|
3147
|
+
}
|
|
3117
3148
|
return /* @__PURE__ */ React19.createElement(
|
|
3118
3149
|
"div",
|
|
3119
3150
|
{
|
|
3120
|
-
|
|
3151
|
+
ref: node,
|
|
3152
|
+
onKeyDown: function(e) {
|
|
3153
|
+
if (e.key === "Escape") {
|
|
3154
|
+
e.stopPropagation();
|
|
3155
|
+
toast.dismiss(t.id);
|
|
3156
|
+
}
|
|
3157
|
+
},
|
|
3158
|
+
className: cx(
|
|
3159
|
+
"aura-toast",
|
|
3160
|
+
"aura-toast--" + t.tone,
|
|
3161
|
+
t.loading && "is-loading",
|
|
3162
|
+
/* Two actions, or one beside a description, go on their own row under the text so it keeps its width. */
|
|
3163
|
+
(actions.length > 1 || actions.length && rich) && "has-action-row"
|
|
3164
|
+
),
|
|
3121
3165
|
role: t.tone === "danger" ? "alert" : "status",
|
|
3122
3166
|
"aria-busy": t.loading || void 0,
|
|
3123
|
-
onMouseEnter:
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3167
|
+
onMouseEnter: function() {
|
|
3168
|
+
hover.current = true;
|
|
3169
|
+
pause();
|
|
3170
|
+
},
|
|
3171
|
+
onMouseLeave: function() {
|
|
3172
|
+
hover.current = false;
|
|
3173
|
+
resume();
|
|
3174
|
+
},
|
|
3175
|
+
onFocus: function() {
|
|
3176
|
+
focused.current = true;
|
|
3177
|
+
pause();
|
|
3178
|
+
},
|
|
3179
|
+
onBlur: function(e) {
|
|
3180
|
+
if (node.current && e.relatedTarget && node.current.contains(e.relatedTarget)) return;
|
|
3181
|
+
focused.current = false;
|
|
3182
|
+
resume();
|
|
3183
|
+
}
|
|
3127
3184
|
},
|
|
3128
3185
|
/* @__PURE__ */ React19.createElement(
|
|
3129
3186
|
Icon,
|
|
@@ -3132,19 +3189,33 @@ window.Aura = (() => {
|
|
|
3132
3189
|
className: cx("aura-toast__icon", t.loading && "aura-spin")
|
|
3133
3190
|
}
|
|
3134
3191
|
),
|
|
3135
|
-
/* @__PURE__ */ React19.createElement("div", { className: "aura-toast__body" }, /* @__PURE__ */ React19.createElement("p", { className: "aura-toast__title" }, t.title),
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3192
|
+
/* @__PURE__ */ React19.createElement("div", { className: "aura-toast__body" }, /* @__PURE__ */ React19.createElement("p", { className: "aura-toast__title" }, t.title), rich ? /* @__PURE__ */ React19.createElement("div", { className: "aura-toast__text" }, t.description) : null),
|
|
3193
|
+
actions.length ? /* @__PURE__ */ React19.createElement("div", { className: "aura-toast__actions" }, actions.map(function(a, i) {
|
|
3194
|
+
return a.href ? /* @__PURE__ */ React19.createElement(
|
|
3195
|
+
Link,
|
|
3196
|
+
{
|
|
3197
|
+
key: i,
|
|
3198
|
+
href: a.href,
|
|
3199
|
+
className: "aura-toast__action",
|
|
3200
|
+
onClick: function(e) {
|
|
3201
|
+
if (plainClick(e)) run(a);
|
|
3202
|
+
else if (a.onClick) a.onClick();
|
|
3203
|
+
}
|
|
3204
|
+
},
|
|
3205
|
+
a.label
|
|
3206
|
+
) : /* @__PURE__ */ React19.createElement(
|
|
3207
|
+
"button",
|
|
3208
|
+
{
|
|
3209
|
+
key: i,
|
|
3210
|
+
type: "button",
|
|
3211
|
+
className: "aura-toast__action",
|
|
3212
|
+
onClick: function() {
|
|
3213
|
+
run(a);
|
|
3214
|
+
}
|
|
3215
|
+
},
|
|
3216
|
+
a.label
|
|
3217
|
+
);
|
|
3218
|
+
})) : null,
|
|
3148
3219
|
/* @__PURE__ */ React19.createElement(
|
|
3149
3220
|
IconButton,
|
|
3150
3221
|
{
|
|
@@ -3158,7 +3229,22 @@ window.Aura = (() => {
|
|
|
3158
3229
|
)
|
|
3159
3230
|
);
|
|
3160
3231
|
}
|
|
3161
|
-
function
|
|
3232
|
+
function hotkeyMatcher(spec) {
|
|
3233
|
+
const parts = spec.split("+").map(function(p) {
|
|
3234
|
+
return p.trim().toLowerCase();
|
|
3235
|
+
});
|
|
3236
|
+
const key = parts[parts.length - 1] || "";
|
|
3237
|
+
const code = /^[a-z]$/.test(key) ? "Key" + key.toUpperCase() : /^[0-9]$/.test(key) ? "Digit" + key : null;
|
|
3238
|
+
const want = function(m) {
|
|
3239
|
+
return parts.indexOf(m) >= 0 && parts.indexOf(m) < parts.length - 1;
|
|
3240
|
+
};
|
|
3241
|
+
return function(e) {
|
|
3242
|
+
if (e.altKey !== want("alt") || e.ctrlKey !== want("ctrl") || e.shiftKey !== want("shift") || e.metaKey !== (want("meta") || want("cmd")))
|
|
3243
|
+
return false;
|
|
3244
|
+
return code ? e.code === code : e.key.toLowerCase() === key;
|
|
3245
|
+
};
|
|
3246
|
+
}
|
|
3247
|
+
function Toaster(props = {}) {
|
|
3162
3248
|
const t = useStrings();
|
|
3163
3249
|
const mounted = useMounted();
|
|
3164
3250
|
const s = React19.useState(toastState.list);
|
|
@@ -3171,15 +3257,49 @@ window.Aura = (() => {
|
|
|
3171
3257
|
});
|
|
3172
3258
|
};
|
|
3173
3259
|
}, []);
|
|
3260
|
+
const region = React19.useRef(null);
|
|
3261
|
+
const hotkey = props.hotkey === void 0 ? "Alt+T" : props.hotkey;
|
|
3262
|
+
React19.useEffect(
|
|
3263
|
+
function() {
|
|
3264
|
+
if (!hotkey) return;
|
|
3265
|
+
const match = hotkeyMatcher(hotkey);
|
|
3266
|
+
function onKey(e) {
|
|
3267
|
+
if (!e.key || e.repeat || e.isComposing || !match(e) || !region.current) return;
|
|
3268
|
+
const el = e.target;
|
|
3269
|
+
const editable = !!el && (el.isContentEditable || /^(INPUT|TEXTAREA)$/.test(el.tagName || ""));
|
|
3270
|
+
const mac = /Mac|iPhone|iPad|iPod/.test(navigator.platform || navigator.userAgent || "");
|
|
3271
|
+
if (editable && mac && e.altKey && !e.ctrlKey && !e.metaKey && e.key.length === 1) return;
|
|
3272
|
+
const items2 = region.current.querySelectorAll(".aura-toast");
|
|
3273
|
+
const last = items2[items2.length - 1];
|
|
3274
|
+
if (!last) return;
|
|
3275
|
+
const target = last.querySelector(".aura-toast__action") || last.querySelector("button");
|
|
3276
|
+
if (!target) return;
|
|
3277
|
+
e.preventDefault();
|
|
3278
|
+
const from = outsideToaster(document.activeElement);
|
|
3279
|
+
if (from) hotkeyOrigin.set(last, from);
|
|
3280
|
+
target.focus();
|
|
3281
|
+
}
|
|
3282
|
+
document.addEventListener("keydown", onKey);
|
|
3283
|
+
return function() {
|
|
3284
|
+
document.removeEventListener("keydown", onKey);
|
|
3285
|
+
};
|
|
3286
|
+
},
|
|
3287
|
+
[hotkey]
|
|
3288
|
+
);
|
|
3174
3289
|
if (!mounted) return null;
|
|
3290
|
+
const pos = props.position || "bottom";
|
|
3291
|
+
const offset = props.offset;
|
|
3175
3292
|
return (0, import_react_dom5.createPortal)(
|
|
3176
3293
|
/* @__PURE__ */ React19.createElement(
|
|
3177
3294
|
"div",
|
|
3178
3295
|
{
|
|
3179
|
-
|
|
3296
|
+
ref: region,
|
|
3297
|
+
className: cx("aura-toaster", pos.indexOf("top") === 0 && "is-top", /center$/.test(pos) && "is-center"),
|
|
3298
|
+
style: offset != null ? { "--aura-toaster-offset": typeof offset === "number" ? offset + "px" : offset } : void 0,
|
|
3180
3299
|
role: "region",
|
|
3181
3300
|
"aria-live": "polite",
|
|
3182
|
-
"aria-label": t.notifications
|
|
3301
|
+
"aria-label": hotkey ? t.notifications + " (" + hotkey + ")" : t.notifications,
|
|
3302
|
+
"aria-keyshortcuts": hotkey || void 0
|
|
3183
3303
|
},
|
|
3184
3304
|
s[0].map(function(t2) {
|
|
3185
3305
|
return /* @__PURE__ */ React19.createElement(ToastItem, { key: t2.id, toast: t2 });
|
|
@@ -4007,7 +4127,27 @@ window.Aura = (() => {
|
|
|
4007
4127
|
);
|
|
4008
4128
|
const sort = sortState[0], setSort = sortState[1];
|
|
4009
4129
|
const selState = useMaybeControlled(props.selected, props.defaultSelected || [], props.onSelectionChange);
|
|
4010
|
-
const
|
|
4130
|
+
const canSelect = function(r) {
|
|
4131
|
+
return !!r && (!props.isRowSelectable || !!props.isRowSelectable(r));
|
|
4132
|
+
};
|
|
4133
|
+
const rejected = {};
|
|
4134
|
+
if (props.isRowSelectable)
|
|
4135
|
+
rows.forEach(function(r) {
|
|
4136
|
+
if (!canSelect(r)) rejected[String(r[rowKey])] = true;
|
|
4137
|
+
});
|
|
4138
|
+
const selected = selState[0].filter(function(k) {
|
|
4139
|
+
return !rejected[String(k)];
|
|
4140
|
+
}), setSelected = selState[1];
|
|
4141
|
+
const droppedSig = selState[0].length === selected.length ? "" : "#" + selState[0].filter(function(k) {
|
|
4142
|
+
return rejected[String(k)];
|
|
4143
|
+
}).join("\0") + "#" + selected.join("\0");
|
|
4144
|
+
React28.useEffect(
|
|
4145
|
+
function() {
|
|
4146
|
+
if (droppedSig !== "") setSelected(selected);
|
|
4147
|
+
},
|
|
4148
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4149
|
+
[droppedSig]
|
|
4150
|
+
);
|
|
4011
4151
|
const pageState = useMaybeControlled(
|
|
4012
4152
|
props.page,
|
|
4013
4153
|
props.defaultPage || 1,
|
|
@@ -4418,7 +4558,7 @@ window.Aura = (() => {
|
|
|
4418
4558
|
el.focus();
|
|
4419
4559
|
}
|
|
4420
4560
|
}
|
|
4421
|
-
const pageKeys = pageRows.map(function(r) {
|
|
4561
|
+
const pageKeys = pageRows.filter(canSelect).map(function(r) {
|
|
4422
4562
|
return r[rowKey];
|
|
4423
4563
|
});
|
|
4424
4564
|
const selSet = {};
|
|
@@ -4682,10 +4822,12 @@ window.Aura = (() => {
|
|
|
4682
4822
|
if (inner) inner.focus();
|
|
4683
4823
|
else handled = false;
|
|
4684
4824
|
} else if (k === " " || k === "Enter") {
|
|
4685
|
-
if (r === 0 && !col && selectable && nRows)
|
|
4686
|
-
|
|
4687
|
-
else if (r
|
|
4688
|
-
else if (r > 0 && k === "
|
|
4825
|
+
if (r === 0 && !col && selectable && nRows) {
|
|
4826
|
+
if (pageKeys.length) toggleAll();
|
|
4827
|
+
} else if (r === 0 && col && col.sortable && canSortAny) sortBy(col.key);
|
|
4828
|
+
else if (r > 0 && k === " " && selectable) {
|
|
4829
|
+
if (canSelect(row)) toggle(row[rowKey], !selSet[row[rowKey]]);
|
|
4830
|
+
} else if (r > 0 && k === "Enter" && rowHref && !target.querySelector("button, a[href]:not(.aura-table__row-link), input, select, textarea"))
|
|
4689
4831
|
followRow(target.closest('[role="row"]'), e);
|
|
4690
4832
|
else if (r > 0 && k === "Enter" && target.querySelector("button, a[href], input, select, textarea"))
|
|
4691
4833
|
target.querySelector("button, a[href], input, select, textarea").focus();
|
|
@@ -4714,7 +4856,7 @@ window.Aura = (() => {
|
|
|
4714
4856
|
activeState[1]({ r: 0, c: 0 });
|
|
4715
4857
|
}
|
|
4716
4858
|
},
|
|
4717
|
-
|
|
4859
|
+
pageKeys.length ? /* @__PURE__ */ React28.createElement(
|
|
4718
4860
|
Checkbox,
|
|
4719
4861
|
{
|
|
4720
4862
|
hideLabel: true,
|
|
@@ -4725,7 +4867,7 @@ window.Aura = (() => {
|
|
|
4725
4867
|
onChange: toggleAll
|
|
4726
4868
|
}
|
|
4727
4869
|
) : null,
|
|
4728
|
-
|
|
4870
|
+
pageKeys.length ? /* @__PURE__ */ React28.createElement("span", { className: "aura-table__sel-text" }, nSel ? t.selectedCount(nSel) : t.selectAll) : /* @__PURE__ */ React28.createElement("span", { className: "aura-sr-only" }, t.selectRows)
|
|
4729
4871
|
)
|
|
4730
4872
|
);
|
|
4731
4873
|
vis.forEach(function(c, i) {
|
|
@@ -4863,12 +5005,12 @@ window.Aura = (() => {
|
|
|
4863
5005
|
className: cx("aura-table__sel", nPinned && "is-pinned"),
|
|
4864
5006
|
tabIndex: tabFor(ri, 0),
|
|
4865
5007
|
"data-rc": ri + ":0",
|
|
4866
|
-
"aria-label": t.selectRow(k),
|
|
5008
|
+
"aria-label": canSelect(r) ? t.selectRow(k) : props.rowSelectDisabledLabel ? props.rowSelectDisabledLabel(r) : void 0,
|
|
4867
5009
|
onFocus: function(e) {
|
|
4868
5010
|
if (e.target === e.currentTarget) activeState[1]({ r: ri, c: 0 });
|
|
4869
5011
|
}
|
|
4870
5012
|
},
|
|
4871
|
-
/* @__PURE__ */ React28.createElement(
|
|
5013
|
+
canSelect(r) ? /* @__PURE__ */ React28.createElement(
|
|
4872
5014
|
Checkbox,
|
|
4873
5015
|
{
|
|
4874
5016
|
hideLabel: true,
|
|
@@ -4879,7 +5021,7 @@ window.Aura = (() => {
|
|
|
4879
5021
|
toggle(k, on);
|
|
4880
5022
|
}
|
|
4881
5023
|
}
|
|
4882
|
-
)
|
|
5024
|
+
) : null
|
|
4883
5025
|
)
|
|
4884
5026
|
);
|
|
4885
5027
|
vis.forEach(function(c, j) {
|
|
@@ -4982,7 +5124,7 @@ window.Aura = (() => {
|
|
|
4982
5124
|
key: k,
|
|
4983
5125
|
role: "row",
|
|
4984
5126
|
"aria-rowindex": first + i + 2,
|
|
4985
|
-
"aria-selected": selectable ? isSel : void 0,
|
|
5127
|
+
"aria-selected": selectable && canSelect(r) ? isSel : void 0,
|
|
4986
5128
|
className: cx(
|
|
4987
5129
|
"aura-table__row",
|
|
4988
5130
|
isSel && "is-selected",
|
|
@@ -496,7 +496,9 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
496
496
|
display: flex; flex-direction: column; gap: var(--aura-space-2); width: min(380px, calc(100vw - 2 * var(--aura-space-4)));
|
|
497
497
|
font-family: var(--font-sans);
|
|
498
498
|
}
|
|
499
|
-
.aura-toaster.is-top { bottom: auto; top: var(--aura-space-6); }
|
|
499
|
+
.aura-toaster.is-top { bottom: auto; top: calc(var(--aura-toaster-offset, var(--aura-space-6)) + env(safe-area-inset-top, 0px)); }
|
|
500
|
+
/* 5.6: top-center / bottom-center; `offset` (or --aura-toaster-offset) clears an app's top bar. */
|
|
501
|
+
.aura-toaster.is-center { right: auto; left: 50%; transform: translateX(-50%); }
|
|
500
502
|
.aura-toast {
|
|
501
503
|
display: flex; align-items: flex-start; gap: var(--aura-space-3); padding: var(--aura-space-3) var(--aura-space-2) var(--aura-space-3) var(--aura-space-4);
|
|
502
504
|
background: var(--aura-bg-surface); color: var(--aura-fg-primary);
|
|
@@ -511,10 +513,27 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
511
513
|
.aura-toast__body { flex: 1; min-width: 0; padding-top: 1px; }
|
|
512
514
|
.aura-toast__title { margin: 0; font-size: 14px; font-weight: 500; line-height: 20px; }
|
|
513
515
|
.aura-toast__text { margin: 2px 0 0; font-size: 13px; line-height: 1.5; color: var(--aura-fg-secondary); }
|
|
516
|
+
.aura-toast__text > * { margin: 0; }
|
|
517
|
+
.aura-toast__text a { color: var(--aura-fg-accent); text-underline-offset: 2px; }
|
|
518
|
+
.aura-toast__text a:focus-visible { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: 1px; border-radius: var(--aura-radius-xs); }
|
|
519
|
+
.aura-toast__actions { flex: none; align-self: center; display: flex; gap: var(--aura-space-1); }
|
|
520
|
+
/* Two actions, or one under a description (5.6): the actions take a row of their own below the text, lined up with it
|
|
521
|
+
* (the action's own padding sits left of the text column), so the text keeps the toast's width. */
|
|
522
|
+
.aura-toast.has-action-row { flex-wrap: wrap; row-gap: var(--aura-space-1); }
|
|
523
|
+
.aura-toast.has-action-row .aura-toast__body { flex-basis: 0; }
|
|
524
|
+
.aura-toast.has-action-row .aura-toast__actions { order: 3; flex-basis: 100%; flex-wrap: wrap; margin-left: calc(16px + var(--aura-space-3) - var(--aura-space-2)); margin-bottom: calc(-1 * var(--aura-space-1)); }
|
|
514
525
|
.aura-toast__action {
|
|
515
526
|
flex: none; align-self: center; height: var(--aura-control-sm); padding: 0 var(--aura-space-2);
|
|
516
527
|
border: 0; border-radius: var(--aura-radius-sm); background: transparent; color: var(--aura-fg-accent);
|
|
517
528
|
font: inherit; font-size: 13px; font-weight: 500; cursor: pointer;
|
|
529
|
+
display: inline-flex; align-items: center; text-decoration: none; white-space: nowrap;
|
|
530
|
+
}
|
|
531
|
+
/* Touch (5.6): the 32px action gets a 44px hit area, as IconButton does. Links in the text only get a little padding —
|
|
532
|
+
* lines sit 20px apart, so a 44px box would overlap the next line's link. */
|
|
533
|
+
@media (pointer: coarse) {
|
|
534
|
+
.aura-toast__action { position: relative; }
|
|
535
|
+
.aura-toast__action::after { content: ''; position: absolute; top: 50%; left: 50%; width: max(100%, var(--aura-touch-target)); height: max(100%, var(--aura-touch-target)); transform: translate(-50%, -50%); }
|
|
536
|
+
.aura-toast__text a { padding-block: 2px; }
|
|
518
537
|
}
|
|
519
538
|
.aura-toast__action:hover { background: var(--aura-bg-surface-hover); }
|
|
520
539
|
.aura-toast__action:focus-visible { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: 0; }
|
|
@@ -1203,6 +1222,8 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
1203
1222
|
.aura-dialog__foot > * { width: 100%; }
|
|
1204
1223
|
.aura-drawer:not(.aura-drawer--nav) { max-width: none; }
|
|
1205
1224
|
.aura-toaster { left: var(--aura-space-4); right: var(--aura-space-4); bottom: var(--aura-space-4); width: auto; }
|
|
1225
|
+
.aura-toaster.is-center { left: var(--aura-space-4); right: var(--aura-space-4); transform: none; }
|
|
1226
|
+
.aura-toaster.is-top { top: calc(var(--aura-toaster-offset, var(--aura-space-4)) + env(safe-area-inset-top, 0px)); }
|
|
1206
1227
|
.aura-card { padding: var(--aura-space-4); }
|
|
1207
1228
|
.aura-stat { padding: var(--aura-space-4); }
|
|
1208
1229
|
.aura-stat__value { font-size: 24px; }
|
|
@@ -1385,9 +1406,9 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
1385
1406
|
@media (max-width: 767.98px) { :root:has(.aura-bottomnav--below-md) { --aura-bottomnav-offset: calc(var(--aura-bottomnav-height) + env(safe-area-inset-bottom, 0px)); } }
|
|
1386
1407
|
@media (max-width: 1023.98px) { :root:has(.aura-bottomnav--below-lg) { --aura-bottomnav-offset: calc(var(--aura-bottomnav-height) + env(safe-area-inset-bottom, 0px)); } }
|
|
1387
1408
|
@media (max-width: 1279.98px) { :root:has(.aura-bottomnav--below-xl) { --aura-bottomnav-offset: calc(var(--aura-bottomnav-height) + env(safe-area-inset-bottom, 0px)); } }
|
|
1388
|
-
/* Toasts clear a BottomNav wherever it shows (phones and tablets). */
|
|
1389
|
-
.aura-toaster:not(.is-top) { bottom: calc(var(--aura-space-6) + var(--aura-bottomnav-offset, 0px)); }
|
|
1390
|
-
@media (max-width: 639.98px) { .aura-toaster:not(.is-top) { bottom: calc(var(--aura-space-4) + var(--aura-bottomnav-offset, 0px)); } }
|
|
1409
|
+
/* Toasts clear a BottomNav wherever it shows (phones and tablets), else the bottom safe-area inset (5.6). */
|
|
1410
|
+
.aura-toaster:not(.is-top) { bottom: calc(var(--aura-toaster-offset, var(--aura-space-6)) + var(--aura-bottomnav-offset, env(safe-area-inset-bottom, 0px))); }
|
|
1411
|
+
@media (max-width: 639.98px) { .aura-toaster:not(.is-top) { bottom: calc(var(--aura-toaster-offset, var(--aura-space-4)) + var(--aura-bottomnav-offset, env(safe-area-inset-bottom, 0px))); } }
|
|
1391
1412
|
|
|
1392
1413
|
/* ---------- 4.19: ActionBar ---------- */
|
|
1393
1414
|
/* Sticky, not fixed: it keeps its place at the end of its parent, so it never covers the last field. */
|
package/components/index.d.ts
CHANGED
|
@@ -124,6 +124,11 @@ export interface DataTableProps<Row extends Record<string, any> = Record<string,
|
|
|
124
124
|
onSortChange?: ((sort: DataTableSort | null) => void) | undefined;
|
|
125
125
|
/** Adds a checkbox column. */
|
|
126
126
|
selectable?: boolean | undefined;
|
|
127
|
+
/** Which rows can be selected (5.6). A row it rejects shows no checkbox (the cell stays, so columns line up), is
|
|
128
|
+
* skipped by select-all, Space and the count, and never appears in `onSelectionChange` — even if passed in. */
|
|
129
|
+
isRowSelectable?: RowCallback<boolean, Row> | undefined;
|
|
130
|
+
/** Accessible name for a rejected row's empty cell, e.g. `(r) => 'Not awaiting review'` (5.6). */
|
|
131
|
+
rowSelectDisabledLabel?: RowCallback<string, Row> | undefined;
|
|
127
132
|
/** Controlled selection (row keys); pair with onSelectionChange. */
|
|
128
133
|
selected?: Array<string | number> | undefined;
|
|
129
134
|
/** Initial selection when uncontrolled. */
|
|
@@ -487,14 +492,23 @@ export interface AlertProps {
|
|
|
487
492
|
onDismiss?: (() => void) | undefined;
|
|
488
493
|
className?: string | undefined;
|
|
489
494
|
}
|
|
495
|
+
/** A button (or, with `href`, a link through AuraProvider's `linkComponent`) on a toast (5.6: `href`, `dismiss`). */
|
|
496
|
+
export interface ToastAction {
|
|
497
|
+
label: string;
|
|
498
|
+
onClick?: (() => void) | undefined;
|
|
499
|
+
/** Makes the action a link (routes through `linkComponent`, so `next/link` navigates client-side). */
|
|
500
|
+
href?: string | undefined;
|
|
501
|
+
/** Default true: the toast closes when the action runs. `false` keeps it (a list of items to work through). */
|
|
502
|
+
dismiss?: boolean | undefined;
|
|
503
|
+
}
|
|
490
504
|
export interface ToastOptions {
|
|
491
505
|
title: string;
|
|
492
|
-
|
|
506
|
+
/** Text, or (5.6) rich content — lines with their own links, read once inside the toast's live region. */
|
|
507
|
+
description?: React$1.ReactNode | undefined;
|
|
493
508
|
tone?: FeedbackTone | undefined;
|
|
494
|
-
action?:
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
} | undefined;
|
|
509
|
+
action?: ToastAction | undefined;
|
|
510
|
+
/** Up to two actions in a row (5.6); used instead of `action` when given. */
|
|
511
|
+
actions?: ToastAction[] | undefined;
|
|
498
512
|
/** ms before it closes itself. Default 5000; Infinity keeps it until dismissed. */
|
|
499
513
|
duration?: number | undefined;
|
|
500
514
|
/** Reuse an id to replace a toast in place (same position, timer restarts) — never a second toast. */
|
|
@@ -1285,10 +1299,18 @@ export declare namespace toast {
|
|
|
1285
1299
|
var dismiss: (id: string) => void;
|
|
1286
1300
|
}
|
|
1287
1301
|
export interface ToasterProps {
|
|
1288
|
-
/** Default `bottom
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1302
|
+
/** Default `bottom` (bottom right). `top` is top right; `top-center` / `bottom-center` centre the stack (5.6).
|
|
1303
|
+
* Below 640px toasts span the width either way. */
|
|
1304
|
+
position?: "bottom" | "bottom-right" | "bottom-center" | "top" | "top-right" | "top-center" | undefined;
|
|
1305
|
+
/** Distance from the top or bottom edge (5.6), e.g. `64` to clear a 56px top bar; px or any CSS length. Sets
|
|
1306
|
+
* `--aura-toaster-offset`; the safe-area inset is added on top. Default 24px (16px below 640px). */
|
|
1307
|
+
offset?: number | string | undefined;
|
|
1308
|
+
/** Keyboard shortcut to the newest toast (5.6): focuses its action, else its close button, and pauses its timer;
|
|
1309
|
+
* Escape closes it and returns focus. Default `"Alt+T"` (matched on the physical key, so macOS Option+T works);
|
|
1310
|
+
* `false` turns it off. */
|
|
1311
|
+
hotkey?: string | false | undefined;
|
|
1312
|
+
}
|
|
1313
|
+
export declare function Toaster(props?: ToasterProps): React$1.ReactElement | null;
|
|
1292
1314
|
export declare const PasswordField: React$1.ForwardRefExoticComponent<PasswordFieldProps & React$1.RefAttributes<HTMLInputElement>>;
|
|
1293
1315
|
export declare const FormErrorSummary: React$1.ForwardRefExoticComponent<FormErrorSummaryProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
1294
1316
|
export declare const FilterBar: React$1.ForwardRefExoticComponent<FilterBarProps & React$1.RefAttributes<HTMLDivElement>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jirawatpyk/aura-tokens",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.6.0",
|
|
4
4
|
"description": "AURA Design System — tokens (CSS variables, Tailwind preset, Figma variables), theme contrast checks and token lint.",
|
|
5
5
|
"main": "tailwind.tokens.cjs",
|
|
6
6
|
"types": "components/index.d.ts",
|
package/tokens.json
CHANGED