asma-ui-core 3.85.0 → 3.86.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/Readme.md +2 -0
- package/dist/asma-ui-core.css +1 -1
- package/dist/components/inputs/button/StyledButton.js +4 -4
- package/dist/components/inputs/slider/StyledSlider.js +158 -107
- package/dist/components/navigation/menu/StyledMenuItem.js +6 -6
- package/dist/components/navigation/tabs/StyledTab.js +7 -7
- package/dist/src/components/inputs/slider/StyledSlider.d.ts +4 -1
- package/package.json +1 -1
- package/src/styles/index.css +103 -0
- package/src/styles/touchReadiness.interaction.test.tsx +161 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import t from "./StyledButton.module.js";
|
|
2
2
|
import f from "clsx";
|
|
3
3
|
import "react";
|
|
4
|
-
import { jsx as
|
|
4
|
+
import { jsx as y, jsxs as g } from "react/jsx-runtime";
|
|
5
5
|
var a = {
|
|
6
6
|
contained: t.contained,
|
|
7
7
|
outlined: t.outlined,
|
|
@@ -15,9 +15,9 @@ var a = {
|
|
|
15
15
|
common: t.common
|
|
16
16
|
}, B = ({ variant: n = "contained", className: i = "", size: e = "medium", children: o, refLink: l, startIcon: d, endIcon: s, dataTest: x, error: p, style: m, ...c }) => {
|
|
17
17
|
const r = e === "large" || e === "medium", u = p ? "error" : "common";
|
|
18
|
-
return /* @__PURE__ */
|
|
18
|
+
return /* @__PURE__ */ g("button", {
|
|
19
19
|
...c,
|
|
20
|
-
className: f(t["asma-ui-core-button"], a[n], a[u], a[e], i),
|
|
20
|
+
className: f("asma-touch-ready", t["asma-ui-core-button"], a[n], a[u], a[e], i),
|
|
21
21
|
style: o ? {
|
|
22
22
|
flexShrink: 0,
|
|
23
23
|
...m
|
|
@@ -26,7 +26,7 @@ var a = {
|
|
|
26
26
|
"data-testid": x,
|
|
27
27
|
children: [
|
|
28
28
|
d,
|
|
29
|
-
o && /* @__PURE__ */
|
|
29
|
+
o && /* @__PURE__ */ y("div", {
|
|
30
30
|
style: {
|
|
31
31
|
overflow: "hidden",
|
|
32
32
|
textOverflow: "ellipsis",
|
|
@@ -1,123 +1,174 @@
|
|
|
1
|
-
import { cn as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import { cn as c } from "../../../helpers/cn.js";
|
|
2
|
+
import { PlusIcon as yt } from "../../icons/plus-icon/PlusIcon.js";
|
|
3
|
+
import { RemoveIcon as xt } from "../../icons/remove-icon/RemoveIcon.js";
|
|
4
|
+
import { StyledButton as tt } from "../button/StyledButton.js";
|
|
5
|
+
import { HelperRow as Nt } from "../../../helpers/HelperRow.js";
|
|
6
|
+
import { useHelperSlot as Mt } from "../../../helpers/useHelperSlot.js";
|
|
7
|
+
import x from "./StyledSlider.module.js";
|
|
8
|
+
import { useId as Pt, useRef as et, useState as rt } from "react";
|
|
9
|
+
import { jsx as i, jsxs as y } from "react/jsx-runtime";
|
|
10
|
+
var j = (m, l, o) => o === l ? 0 : Math.min(100, Math.max(0, (m - l) / (o - l) * 100)), It = (m) => Array.isArray(m) ? [m[0] ?? 0, m[1] ?? 0] : null, Ut = ({ dataTest: m, min: l = 0, max: o = 100, step: h = 1, value: V, defaultValue: lt, disabled: u, size: B = "medium", orientation: F = "horizontal", marks: A, name: at, className: nt, classes: p, slotProps: R, error: N, errorText: ot, helperText: K, reserveHelperText: ct, fromLabel: T, toLabel: D, showButtons: X, ariaLabel: $, ariaLabelledBy: it, onChange: M, onChangeCommitted: k }) => {
|
|
11
|
+
const Y = Pt(), a = F === "vertical", s = B === "small" ? 6 : 8, b = et(null), g = et(null), [st, P] = rt(null), [ut, q] = rt(lt ?? l), v = st ?? V ?? ut, n = It(v), d = n !== null, E = N ? ot ?? K : K, { show: G, role: dt } = Mt("StyledSlider", N, E, ct), H = (A === !0 && Number.isFinite(h) && h > 0 && o > l ? Array.from({ length: Math.floor((o - l) / h) + 1 }, (t, r) => ({ value: l + h * r })) : Array.isArray(A) ? A : []).filter((t) => t.value >= l && t.value <= o), J = d ? Math.min(n[0], n[1]) : l, U = d ? Math.max(n[0], n[1]) : v, O = (t) => d ? t >= J && t <= U : t <= U, ft = d ? Math.min(n[0], n[1]) <= l : v <= l, ht = d ? Math.max(n[0], n[1]) >= o : v >= o, z = d ? j(J, l, o) : 0, Q = j(U, l, o) - z, mt = a ? {
|
|
12
|
+
bottom: `${z}%`,
|
|
13
|
+
height: `${Q}%`
|
|
11
14
|
} : {
|
|
12
|
-
left: `${
|
|
13
|
-
width: `${
|
|
14
|
-
},
|
|
15
|
-
const r =
|
|
16
|
-
return
|
|
17
|
-
},
|
|
18
|
-
const r = t.currentTarget.getBoundingClientRect(), e =
|
|
19
|
-
return Math.min(o, Math.max(l,
|
|
20
|
-
},
|
|
21
|
-
if (
|
|
22
|
-
const r =
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
},
|
|
27
|
-
if (
|
|
28
|
-
const r =
|
|
29
|
-
|
|
30
|
-
},
|
|
31
|
-
if (
|
|
32
|
-
const r =
|
|
33
|
-
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
},
|
|
37
|
-
if (
|
|
38
|
-
const e =
|
|
15
|
+
left: `${z}%`,
|
|
16
|
+
width: `${Q}%`
|
|
17
|
+
}, W = (t) => {
|
|
18
|
+
const r = j(t, l, o);
|
|
19
|
+
return a ? { bottom: `${r}%` } : { left: `${r}%` };
|
|
20
|
+
}, C = (t) => {
|
|
21
|
+
const r = t.currentTarget.getBoundingClientRect(), e = a ? 1 - (t.clientY - (r.top + s)) / (r.height - s * 2) : (t.clientX - (r.left + s)) / (r.width - s * 2), f = l + Math.round(Math.min(1, Math.max(0, e)) * ((o - l) / h)) * h;
|
|
22
|
+
return Math.min(o, Math.max(l, f));
|
|
23
|
+
}, pt = (t) => d && Math.abs((n?.[1] ?? l) - t) < Math.abs((n?.[0] ?? l) - t) ? 1 : 0, bt = (t) => {
|
|
24
|
+
if (u) return;
|
|
25
|
+
const r = C(t), e = pt(r);
|
|
26
|
+
b.current = e, g.current = t.pointerId, t.currentTarget.setPointerCapture(t.pointerId);
|
|
27
|
+
const f = I(r, e);
|
|
28
|
+
P(f), M?.(t, f, e);
|
|
29
|
+
}, gt = (t) => {
|
|
30
|
+
if (u || b.current === null || t.pointerId !== g.current) return;
|
|
31
|
+
const r = b.current, e = I(C(t), r);
|
|
32
|
+
P(e), M?.(t, e, r);
|
|
33
|
+
}, vt = (t) => {
|
|
34
|
+
if (u || b.current === null || t.pointerId !== g.current) return;
|
|
35
|
+
const r = b.current, e = I(C(t), r);
|
|
36
|
+
V === void 0 && q(e), k?.(t, e), t.currentTarget.hasPointerCapture(t.pointerId) && t.currentTarget.releasePointerCapture(t.pointerId), P(null), b.current = null, g.current = null;
|
|
37
|
+
}, wt = (t) => {
|
|
38
|
+
b.current === null || t.pointerId !== g.current || (P(null), b.current = null, g.current = null);
|
|
39
|
+
}, Z = (t) => (r) => {
|
|
40
|
+
if (u) return;
|
|
41
|
+
const e = t === "increment" ? h || 1 : -(h || 1);
|
|
42
|
+
let f = 0, w;
|
|
43
|
+
d ? (f = t === "increment" ? 1 : 0, w = t === "increment" ? Math.max(n[0], n[1]) : Math.min(n[0], n[1])) : w = v;
|
|
44
|
+
const L = Math.min(o, Math.max(l, w + e));
|
|
45
|
+
S(M, r, L, f), S(k, r, L, f);
|
|
46
|
+
}, I = (t, r) => {
|
|
47
|
+
if (!d) return t;
|
|
48
|
+
const e = [n?.[0] ?? 0, n?.[1] ?? 0];
|
|
39
49
|
return e[r] = t, r === 0 && e[0] > e[1] && (e[0] = e[1]), r === 1 && e[1] < e[0] && (e[1] = e[0]), e;
|
|
40
|
-
},
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
},
|
|
50
|
+
}, S = (t, r, e, f) => {
|
|
51
|
+
const w = I(e, f);
|
|
52
|
+
V === void 0 && q(w), t && t(r, w, f);
|
|
53
|
+
}, _ = (t, r) => /* @__PURE__ */ i("input", {
|
|
44
54
|
type: "range",
|
|
45
|
-
"data-testid":
|
|
46
|
-
name:
|
|
55
|
+
"data-testid": d ? `${m}-thumb-${t}` : m,
|
|
56
|
+
name: at,
|
|
47
57
|
min: l,
|
|
48
58
|
max: o,
|
|
49
59
|
step: h,
|
|
50
60
|
value: r,
|
|
51
|
-
disabled:
|
|
52
|
-
"aria-orientation":
|
|
53
|
-
"aria-label": typeof
|
|
54
|
-
"aria-labelledby":
|
|
55
|
-
"aria-invalid":
|
|
56
|
-
"aria-describedby":
|
|
57
|
-
className:
|
|
58
|
-
onChange: (e) =>
|
|
59
|
-
onKeyUp: (e) =>
|
|
61
|
+
disabled: u,
|
|
62
|
+
"aria-orientation": F,
|
|
63
|
+
"aria-label": typeof $ == "function" ? $(t) : $,
|
|
64
|
+
"aria-labelledby": it,
|
|
65
|
+
"aria-invalid": N ? !0 : void 0,
|
|
66
|
+
"aria-describedby": G ? Y : void 0,
|
|
67
|
+
className: c(x.SliderInput, a ? x.Vertical : x.Horizontal, !a && "z-0", B === "small" && x.Small, u && x.Disabled, p?.thumb, R?.thumb?.className),
|
|
68
|
+
onChange: (e) => S(M, e, Number(e.currentTarget.value), t),
|
|
69
|
+
onKeyUp: (e) => S(k, e, Number(e.currentTarget.value), t)
|
|
60
70
|
}, t);
|
|
61
|
-
return /* @__PURE__ */
|
|
62
|
-
className:
|
|
63
|
-
children: [
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
71
|
+
return /* @__PURE__ */ y("div", {
|
|
72
|
+
className: c("flex max-w-[600px] flex-col gap-3", a && "h-full"),
|
|
73
|
+
children: [!a && (T ?? D) && /* @__PURE__ */ y("div", {
|
|
74
|
+
className: "grid w-full grid-cols-2 gap-4",
|
|
75
|
+
children: [!a && T && /* @__PURE__ */ i("span", {
|
|
76
|
+
className: "min-w-0 break-words text-left font-normal text-delta-800",
|
|
77
|
+
children: T
|
|
78
|
+
}), !a && D && /* @__PURE__ */ i("span", {
|
|
79
|
+
className: "min-w-0 break-words text-right font-normal text-delta-800",
|
|
80
|
+
children: D
|
|
81
|
+
})]
|
|
82
|
+
}), /* @__PURE__ */ y("div", {
|
|
83
|
+
className: c("flex", !a && "w-full items-start gap-3", a && "h-full flex-col items-center"),
|
|
84
|
+
children: [
|
|
85
|
+
!a && X && /* @__PURE__ */ i(tt, {
|
|
86
|
+
dataTest: "slider-from-button",
|
|
87
|
+
"aria-label": "Decrease value",
|
|
88
|
+
className: "-mt-0.5 w-8",
|
|
89
|
+
variant: "outlined",
|
|
90
|
+
disabled: u ?? ft,
|
|
91
|
+
startIcon: /* @__PURE__ */ i(xt, {
|
|
92
|
+
width: 24,
|
|
93
|
+
height: 24
|
|
94
|
+
}),
|
|
95
|
+
onClick: Z("decrement")
|
|
96
|
+
}),
|
|
97
|
+
/* @__PURE__ */ y("div", {
|
|
98
|
+
className: c("relative flex", a ? "h-full w-8 flex-col items-center" : "mt-px w-full flex-col", p?.root, nt),
|
|
80
99
|
children: [
|
|
81
|
-
/* @__PURE__ */
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
100
|
+
/* @__PURE__ */ y("div", {
|
|
101
|
+
className: c("relative", a ? "h-full w-8" : "h-4 w-full", u ? "cursor-default" : "cursor-pointer"),
|
|
102
|
+
style: { touchAction: "none" },
|
|
103
|
+
onPointerDown: bt,
|
|
104
|
+
onPointerMove: gt,
|
|
105
|
+
onPointerUp: vt,
|
|
106
|
+
onPointerCancel: wt,
|
|
107
|
+
children: [/* @__PURE__ */ y("div", {
|
|
108
|
+
className: c("absolute", a ? "left-1/2 w-1 -translate-x-1/2" : "top-[calc(50%+6px)] h-1 -translate-y-1/2"),
|
|
109
|
+
style: a ? {
|
|
110
|
+
top: s,
|
|
111
|
+
bottom: s
|
|
112
|
+
} : {
|
|
113
|
+
left: s,
|
|
114
|
+
right: s
|
|
115
|
+
},
|
|
116
|
+
children: [
|
|
117
|
+
/* @__PURE__ */ i("div", { className: c("absolute inset-0 rounded-full bg-delta-100", p?.rail, R?.rail?.className) }),
|
|
118
|
+
/* @__PURE__ */ i("div", {
|
|
119
|
+
className: c("absolute rounded-full", a ? "left-0 w-full" : "top-0 h-full", u ? "bg-delta-200" : "bg-gama-500", p?.track),
|
|
120
|
+
style: mt
|
|
121
|
+
}),
|
|
122
|
+
H.map((t) => {
|
|
123
|
+
const r = O(t.value);
|
|
124
|
+
return /* @__PURE__ */ i("span", {
|
|
125
|
+
className: c("absolute z-10 box-border h-2 w-2 -translate-x-1/2 rounded-full border border-solid", a ? "left-1/2 translate-y-1/2" : "top-1/2 -translate-y-1/2", r ? c(u ? "border-delta-200 bg-delta-200" : "border-gama-500 bg-gama-500", p?.markActive) : c("border-delta-300 bg-white", p?.mark)),
|
|
126
|
+
style: W(t.value)
|
|
127
|
+
}, t.value);
|
|
128
|
+
})
|
|
129
|
+
]
|
|
130
|
+
}), d ? [_(0, n[0]), _(1, n[1])] : _(0, v)]
|
|
85
131
|
}),
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
132
|
+
H.some((t) => t.label != null) && /* @__PURE__ */ i("div", {
|
|
133
|
+
className: c(a ? "pointer-events-none absolute inset-x-0" : "relative mt-[14px] h-6"),
|
|
134
|
+
style: a ? {
|
|
135
|
+
top: s,
|
|
136
|
+
bottom: s
|
|
137
|
+
} : {
|
|
138
|
+
marginLeft: s,
|
|
139
|
+
marginRight: s
|
|
140
|
+
},
|
|
141
|
+
children: H.map((t) => t.label == null ? null : /* @__PURE__ */ i("span", {
|
|
142
|
+
className: c("absolute text-base font-semibold text-delta-700", a ? "left-[37px] translate-y-1/2" : "-translate-x-1/2", O(t.value) && p?.markLabelActive, p?.markLabel, R?.markLabel?.className),
|
|
143
|
+
style: W(t.value),
|
|
144
|
+
children: t.label
|
|
145
|
+
}, t.value))
|
|
146
|
+
}),
|
|
147
|
+
G && /* @__PURE__ */ i(Nt, {
|
|
148
|
+
id: Y,
|
|
149
|
+
role: dt,
|
|
150
|
+
error: N,
|
|
151
|
+
message: E,
|
|
152
|
+
className: "m-0 items-center"
|
|
92
153
|
})
|
|
93
154
|
]
|
|
94
|
-
}),
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}, t.value))
|
|
110
|
-
}),
|
|
111
|
-
K && /* @__PURE__ */ b(ft, {
|
|
112
|
-
id: j,
|
|
113
|
-
role: ot,
|
|
114
|
-
error: v,
|
|
115
|
-
message: B,
|
|
116
|
-
className: "m-0 items-center"
|
|
117
|
-
})
|
|
118
|
-
]
|
|
155
|
+
}),
|
|
156
|
+
!a && X && /* @__PURE__ */ i(tt, {
|
|
157
|
+
dataTest: "slider-to-button",
|
|
158
|
+
"aria-label": "Increase value",
|
|
159
|
+
className: "-mt-0.5 w-8",
|
|
160
|
+
variant: "outlined",
|
|
161
|
+
disabled: u ?? ht,
|
|
162
|
+
startIcon: /* @__PURE__ */ i(yt, {
|
|
163
|
+
width: 24,
|
|
164
|
+
height: 24
|
|
165
|
+
}),
|
|
166
|
+
onClick: Z("increment")
|
|
167
|
+
})
|
|
168
|
+
]
|
|
169
|
+
})]
|
|
119
170
|
});
|
|
120
171
|
};
|
|
121
172
|
export {
|
|
122
|
-
|
|
173
|
+
Ut as StyledSlider
|
|
123
174
|
};
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { cn as
|
|
1
|
+
import { cn as r } from "../../../helpers/cn.js";
|
|
2
2
|
import { resolveSx as y } from "../../../helpers/sx.js";
|
|
3
3
|
import { jsx as f } from "react/jsx-runtime";
|
|
4
|
-
var
|
|
4
|
+
var D = ({ children: n, onClick: o, onMouseDown: i, onMouseUp: l, disabled: e, selected: s, dense: m, className: d, classes: a, sx: u, "data-test": p, "data-testid": x, value: c }) => /* @__PURE__ */ f("li", {
|
|
5
5
|
role: "menuitem",
|
|
6
6
|
"aria-disabled": e ? !0 : void 0,
|
|
7
7
|
tabIndex: -1,
|
|
8
|
-
"data-test":
|
|
9
|
-
"data-testid":
|
|
8
|
+
"data-test": p,
|
|
9
|
+
"data-testid": x,
|
|
10
10
|
onClick: e ? void 0 : o,
|
|
11
11
|
onMouseDown: e ? void 0 : i,
|
|
12
12
|
onMouseUp: e ? void 0 : l,
|
|
13
13
|
onKeyDown: (t) => {
|
|
14
14
|
e || (t.key === "Enter" || t.key === " ") && (t.preventDefault(), o?.(t));
|
|
15
15
|
},
|
|
16
|
-
className:
|
|
16
|
+
className: r("box-border flex items-center px-4 text-base outline-none", m ? "min-h-8 py-1" : "min-h-10 py-2", "asma-pressable asma-touch-target", e ? "cursor-not-allowed text-delta-300 aria-disabled:text-delta-300" : "cursor-pointer text-delta-700 hover:bg-delta-50", s && r("bg-gama-50", a?.selected), a?.root, d),
|
|
17
17
|
style: {
|
|
18
18
|
fontFamily: "Roboto, Helvetica, Arial, sans-serif",
|
|
19
19
|
...y(u)
|
|
@@ -21,5 +21,5 @@ var b = ({ children: n, onClick: o, onMouseDown: i, onMouseUp: l, disabled: e, s
|
|
|
21
21
|
children: n
|
|
22
22
|
});
|
|
23
23
|
export {
|
|
24
|
-
|
|
24
|
+
D as StyledMenuItem
|
|
25
25
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { cn as
|
|
2
|
-
import { resolveSx as
|
|
1
|
+
import { cn as f } from "../../../helpers/cn.js";
|
|
2
|
+
import { resolveSx as x } from "../../../helpers/sx.js";
|
|
3
3
|
import { useTabsContext as u } from "./TabsContext.js";
|
|
4
4
|
import { useCallback as h } from "react";
|
|
5
5
|
import { jsx as d } from "react/jsx-runtime";
|
|
6
|
-
var k = ({ value:
|
|
7
|
-
const t = u(), o =
|
|
6
|
+
var k = ({ value: a, label: i, disabled: e, className: s, sx: l, index: m }) => {
|
|
7
|
+
const t = u(), o = a !== void 0 ? a : m, r = t ? t.value === o : !1, c = /\btext-(?:xs|sm|base|lg|xl|\[)/.test(s ?? ""), p = /\bfont-(?:thin|extralight|light|normal|medium|semibold|bold|extrabold|black)\b/.test(s ?? ""), b = /\b(?:uppercase|lowercase|capitalize|normal-case)\b/.test(s ?? "");
|
|
8
8
|
return /* @__PURE__ */ d("button", {
|
|
9
9
|
ref: h((n) => {
|
|
10
10
|
t?.register(o, n);
|
|
@@ -17,12 +17,12 @@ var k = ({ value: i, label: a, disabled: e, className: s, sx: l, index: m }) =>
|
|
|
17
17
|
tabIndex: r ? 0 : -1,
|
|
18
18
|
"data-tab-value": typeof o == "string" || typeof o == "number" ? String(o) : void 0,
|
|
19
19
|
onClick: (n) => !e && t?.onSelect(n, o),
|
|
20
|
-
className:
|
|
20
|
+
className: f("inline-flex min-h-12 min-w-[90px] shrink-0 items-center justify-center gap-2 whitespace-nowrap rounded-t-lg border-0 bg-transparent px-4 py-3 tracking-normal outline-none transition-colors", !c && (t?.size === "small" ? "text-base" : "text-lg"), !p && (t?.size === "small" || r || e ? "font-semibold" : "font-medium hover:font-semibold focus-visible:font-semibold"), !b && "normal-case", t?.size === "small" && "min-h-10 px-3 py-2", "asma-pressable", e ? "text-delta-300" : r ? "text-gama-500" : "text-delta-600", !e && "cursor-pointer", "focus-visible:shadow-[inset_0_0_0_3px_var(--colors-focus-ring)]", !e && !r && "hover:shadow-[inset_0_-3px_0_0_var(--colors-delta-300)]", s),
|
|
21
21
|
style: {
|
|
22
22
|
fontFamily: "Roboto, Helvetica, Arial, sans-serif",
|
|
23
|
-
...
|
|
23
|
+
...x(l)
|
|
24
24
|
},
|
|
25
|
-
children:
|
|
25
|
+
children: i
|
|
26
26
|
});
|
|
27
27
|
};
|
|
28
28
|
export {
|
|
@@ -50,6 +50,9 @@ export interface StyledSliderProps {
|
|
|
50
50
|
errorText?: string;
|
|
51
51
|
helperText?: string;
|
|
52
52
|
reserveHelperText?: boolean;
|
|
53
|
+
fromLabel?: ReactNode;
|
|
54
|
+
toLabel?: ReactNode;
|
|
55
|
+
showButtons?: boolean;
|
|
53
56
|
/** Accessible name for the thumb input(s) — there is no visible label to derive it from
|
|
54
57
|
* (axe `label`). A function receives the thumb index (0, or 0/1 for a two-thumb range) so each
|
|
55
58
|
* thumb of a range slider can get a distinct name. */
|
|
@@ -67,5 +70,5 @@ export interface StyledSliderProps {
|
|
|
67
70
|
* CI is the visual gate. Upgrade path: tune the 8px thumb inset if a diff shows misalignment.
|
|
68
71
|
* TASK-204.
|
|
69
72
|
*/
|
|
70
|
-
export declare const StyledSlider: ({ dataTest, min, max, step, value, defaultValue, disabled, size, orientation, marks, name, className, classes, slotProps, error, errorText, helperText, reserveHelperText, ariaLabel, ariaLabelledBy, onChange, onChangeCommitted, }: StyledSliderProps) => JSX.Element;
|
|
73
|
+
export declare const StyledSlider: ({ dataTest, min, max, step, value, defaultValue, disabled, size, orientation, marks, name, className, classes, slotProps, error, errorText, helperText, reserveHelperText, fromLabel, toLabel, showButtons, ariaLabel, ariaLabelledBy, onChange, onChangeCommitted, }: StyledSliderProps) => JSX.Element;
|
|
71
74
|
export {};
|
package/package.json
CHANGED
package/src/styles/index.css
CHANGED
|
@@ -47,6 +47,109 @@
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
/*
|
|
51
|
+
* ASMA-8210 (TB-02) — touch-readiness primitives for the Ad Voca mobile TabBar/Menu work.
|
|
52
|
+
*
|
|
53
|
+
* Four opt-in utilities. Every one of them is inert until a finger or a mouse button is on the
|
|
54
|
+
* control, or until the viewport is mobile, so no resting style changes anywhere: the frozen
|
|
55
|
+
* barrel (`api-surface.test.ts`) and the VRT baselines — captured at 1280x720 with a fine
|
|
56
|
+
* pointer — are untouched by design, not by luck. They reach consumers through `dist/style.css`,
|
|
57
|
+
* the same route as `.noselect` and `.absolute-center`, so no new export is needed to use them.
|
|
58
|
+
*
|
|
59
|
+
* Deliberately UNLAYERED (like the reduced-motion block above), not in `@layer utilities`:
|
|
60
|
+
* `tailwind.config.ts` sets `important: true`, and Tailwind v3 importantifies custom utilities
|
|
61
|
+
* inside `@layer utilities` too. That would turn `.asma-hit-area`'s `position: relative` into
|
|
62
|
+
* `!important`, making it unoverridable by Tailwind position utilities and by inline styles.
|
|
63
|
+
* Unlayered, these rules still sit after the `@tailwind utilities` output in source order, so
|
|
64
|
+
* the one `!important` we do want (`.asma-touch-target`, below) keeps beating `min-h-*`.
|
|
65
|
+
*
|
|
66
|
+
* Pick per control:
|
|
67
|
+
* .asma-touch-ready control that already has a designed `:active` (Button, Chip, Switch).
|
|
68
|
+
* .asma-pressable control with no pressed state at all (Tab, MenuItem, Link).
|
|
69
|
+
* .asma-hit-area isolated control that must reach 44px without growing.
|
|
70
|
+
* .asma-touch-target row in a stack, where growing on a phone is the honest fix.
|
|
71
|
+
*
|
|
72
|
+
* Sizes come from `--asma-touch-target-size` (44px, Apple HIG / WCAG 2.5.5 AAA; WCAG 2.5.8 AA
|
|
73
|
+
* asks only 24px, so this is the stricter of the two) and `--asma-pressed-opacity`. Both are
|
|
74
|
+
* plain custom properties: a component or a consumer retunes them without a new class.
|
|
75
|
+
*/
|
|
76
|
+
|
|
77
|
+
/*
|
|
78
|
+
* Kills the grey iOS/Android tap flash and the 300ms double-tap-zoom delay that `touch-action:
|
|
79
|
+
* auto` implies. Both behaviours exist only for touch input, so a mouse or trackpad renders and
|
|
80
|
+
* behaves exactly as it did before.
|
|
81
|
+
*/
|
|
82
|
+
.asma-touch-ready,
|
|
83
|
+
.asma-pressable {
|
|
84
|
+
-webkit-tap-highlight-color: transparent;
|
|
85
|
+
touch-action: manipulation;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/*
|
|
89
|
+
* The replacement for the tap flash removed above — without it, touch would end up with *less*
|
|
90
|
+
* feedback than before. Opacity is background-agnostic (filled, outlined and bare controls all
|
|
91
|
+
* read the same) and layout-neutral, so it never reflows and never reaches a VRT baseline.
|
|
92
|
+
* Disabled controls stay inert, matching their `onClick` being detached.
|
|
93
|
+
*/
|
|
94
|
+
.asma-pressable:active:not(:disabled):not([aria-disabled='true']) {
|
|
95
|
+
opacity: var(--asma-pressed-opacity, 0.7);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/*
|
|
99
|
+
* A 44px pointer target on a control that must keep its drawn size: a transparent, centred
|
|
100
|
+
* overlay that belongs to the control, so a press anywhere inside it activates the control
|
|
101
|
+
* itself. `width/height: 100%` keeps it at least as large as the control it sits on.
|
|
102
|
+
*
|
|
103
|
+
* The supplied `position: relative` carries no `!important` (see the unlayered note above), so
|
|
104
|
+
* an inline `style` always overrides it, and a Tailwind position utility (importantified by
|
|
105
|
+
* `important: true`) does too.
|
|
106
|
+
*
|
|
107
|
+
* Caveats, all of them reasons to reach for `.asma-touch-target` instead:
|
|
108
|
+
* - it is NOT mobile-gated: the enlarged pointer target applies to desktop mouse users too
|
|
109
|
+
* (harmless for isolated controls, surprising next to other clickable things);
|
|
110
|
+
* - it owns the element's `::after`, clobbering any decorative `::after` the control has;
|
|
111
|
+
* - an ancestor `overflow: hidden` clips it, and a scroll container counts it as overflow;
|
|
112
|
+
* - it covers nested interactive children, and neighbours closer together than 44px would
|
|
113
|
+
* overlap and steal each other's presses.
|
|
114
|
+
*/
|
|
115
|
+
.asma-hit-area {
|
|
116
|
+
position: relative;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.asma-hit-area::after {
|
|
120
|
+
content: '';
|
|
121
|
+
position: absolute;
|
|
122
|
+
left: 50%;
|
|
123
|
+
top: 50%;
|
|
124
|
+
width: 100%;
|
|
125
|
+
height: 100%;
|
|
126
|
+
min-width: var(--asma-touch-target-size, 44px);
|
|
127
|
+
min-height: var(--asma-touch-target-size, 44px);
|
|
128
|
+
transform: translate(-50%, -50%);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/*
|
|
132
|
+
* 44px tall rows in a stack, where overlapping hit areas would fight and growing is what the
|
|
133
|
+
* design actually wants. Gated to the mobile breakpoint (`_breakpoints.scss` `$mobile-max`) so
|
|
134
|
+
* tablet and desktop — including every VRT baseline — stay byte-identical. `!important` is
|
|
135
|
+
* required to outrank Tailwind's own `min-h-*`, which `important: true` emits with `!`.
|
|
136
|
+
*
|
|
137
|
+
* This is a LATER-SOURCE OVERRIDE, not a CSS `max()` floor — it replaces whatever `min-height`
|
|
138
|
+
* the component declares, it cannot clamp against it. Two consequences (ASMA-8210 review B1):
|
|
139
|
+
* - Only apply it where the EFFECTIVE min-height is below 44px — effective, not the class you
|
|
140
|
+
* can see: stacked utilities resolve by emitted order, so verify with computed style. On a
|
|
141
|
+
* component resting at `min-h-12` (48px) this rule would SHRINK the target — that is why
|
|
142
|
+
* StyledTab takes only `asma-pressable` (both tab variants effectively rest at 48px; even
|
|
143
|
+
* the small one, whose `min-h-10` loses to the base `min-h-12` by source order).
|
|
144
|
+
* - It deliberately sets no `min-width`: a width override would replace designed minimums
|
|
145
|
+
* like the tab's `min-w-[90px]` with 44px. Width floors stay per-component.
|
|
146
|
+
*/
|
|
147
|
+
@media (max-width: 743px) {
|
|
148
|
+
.asma-touch-target {
|
|
149
|
+
min-height: var(--asma-touch-target-size, 44px) !important;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
50
153
|
@layer utilities {
|
|
51
154
|
.flip-180 {
|
|
52
155
|
transform: rotate(180deg);
|