@ggui-ai/ui-visual-tester 0.20.0 → 0.21.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/prime-inputs.d.ts.map +1 -1
- package/dist/prime-inputs.js +44 -21
- package/fixture/fixture-runtime.js +77 -39
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prime-inputs.d.ts","sourceRoot":"","sources":["../src/prime-inputs.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"prime-inputs.d.ts","sourceRoot":"","sources":["../src/prime-inputs.ts"],"names":[],"mappings":"AA2EA,wBAAgB,cAAc,CAAC,EAAE,EAAE,gBAAgB,GAAG,mBAAmB,GAAG,MAAM,CAmCjF;AAED,iHAAiH;AACjH,wBAAgB,cAAc,CAAC,EAAE,EAAE,gBAAgB,GAAG,mBAAmB,GAAG,iBAAiB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAYlH;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CA0CrD"}
|
package/dist/prime-inputs.js
CHANGED
|
@@ -7,6 +7,23 @@
|
|
|
7
7
|
// SAME way — one typed-values table, no divergence. Pure DOM + Date only (no
|
|
8
8
|
// Playwright), so it is safe to import into the lightweight happy-dom check
|
|
9
9
|
// worker via the `@ggui-ai/ui-visual-tester/prime-inputs` subpath.
|
|
10
|
+
//
|
|
11
|
+
// Realm rule (ggui#1187 follow-up): every constructor this module needs —
|
|
12
|
+
// `HTMLInputElement`, `HTMLTextAreaElement`, `HTMLSelectElement`, `Event` —
|
|
13
|
+
// is read from the ROOT'S OWN window (`ownerDocument.defaultView`), never
|
|
14
|
+
// from ambient globals. The check worker installs happy-dom's `window` and
|
|
15
|
+
// `document` on `globalThis` without the element constructors, so an
|
|
16
|
+
// `instanceof HTMLInputElement` there is a `ReferenceError`, not a `false`;
|
|
17
|
+
// a browser page or vitest's happy-dom environment happens to have them.
|
|
18
|
+
// One code path, every realm.
|
|
19
|
+
/** The realm an element lives in. A detached document has none — that is a caller error, reported as one. */
|
|
20
|
+
function realmOf(el) {
|
|
21
|
+
const view = el.ownerDocument.defaultView;
|
|
22
|
+
if (view === null) {
|
|
23
|
+
throw new Error('primeInputs: the element is not attached to a window (ownerDocument.defaultView is null) — a detached document has no constructors to prime with');
|
|
24
|
+
}
|
|
25
|
+
return view;
|
|
26
|
+
}
|
|
10
27
|
// #1040: date-like types too — a wizard's first step is routinely gated on one ("preferred follow-up
|
|
11
28
|
// date"), and a Next that never enables hides every step behind it from the probe.
|
|
12
29
|
const TEXT_LIKE_INPUT_TYPES = new Set([
|
|
@@ -52,7 +69,7 @@ function isoWeekOf(y, m, d) {
|
|
|
52
69
|
return `${date.getUTCFullYear()}-W${pad2(week)}`;
|
|
53
70
|
}
|
|
54
71
|
export function sampleValueFor(el) {
|
|
55
|
-
if (!(el instanceof HTMLInputElement))
|
|
72
|
+
if (!(el instanceof realmOf(el).HTMLInputElement))
|
|
56
73
|
return 'probe'; // a textarea has no type to switch on
|
|
57
74
|
switch (el.type) {
|
|
58
75
|
case 'number':
|
|
@@ -90,18 +107,19 @@ export function sampleValueFor(el) {
|
|
|
90
107
|
}
|
|
91
108
|
/** Set a value the way React notices it: through the prototype's native setter, then an input + change event. */
|
|
92
109
|
export function setNativeValue(el, value) {
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
110
|
+
const view = realmOf(el);
|
|
111
|
+
const proto = el instanceof view.HTMLTextAreaElement
|
|
112
|
+
? view.HTMLTextAreaElement.prototype
|
|
113
|
+
: el instanceof view.HTMLSelectElement
|
|
114
|
+
? view.HTMLSelectElement.prototype
|
|
115
|
+
: view.HTMLInputElement.prototype;
|
|
98
116
|
const setter = Object.getOwnPropertyDescriptor(proto, 'value')?.set;
|
|
99
117
|
if (setter)
|
|
100
118
|
setter.call(el, value);
|
|
101
119
|
else
|
|
102
120
|
el.value = value;
|
|
103
|
-
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
104
|
-
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
121
|
+
el.dispatchEvent(new view.Event('input', { bubbles: true }));
|
|
122
|
+
el.dispatchEvent(new view.Event('change', { bubbles: true }));
|
|
105
123
|
}
|
|
106
124
|
/**
|
|
107
125
|
* The generic minimum a user does before pressing Send / Submit / Complete
|
|
@@ -111,12 +129,13 @@ export function setNativeValue(el, value) {
|
|
|
111
129
|
* Returns how many controls were primed.
|
|
112
130
|
*/
|
|
113
131
|
export function primeInputs(root) {
|
|
132
|
+
const view = realmOf(root);
|
|
114
133
|
let primed = 0;
|
|
115
|
-
const editable = (el) => !el.disabled && !
|
|
134
|
+
const editable = (el) => !el.disabled && !el.readOnly;
|
|
116
135
|
for (const el of Array.from(root.querySelectorAll('input, textarea'))) {
|
|
117
|
-
if (!(el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) || !editable(el))
|
|
136
|
+
if (!(el instanceof view.HTMLInputElement || el instanceof view.HTMLTextAreaElement) || !editable(el))
|
|
118
137
|
continue;
|
|
119
|
-
if (el instanceof HTMLInputElement && !TEXT_LIKE_INPUT_TYPES.has(el.type))
|
|
138
|
+
if (el instanceof view.HTMLInputElement && !TEXT_LIKE_INPUT_TYPES.has(el.type))
|
|
120
139
|
continue;
|
|
121
140
|
if (el.value.trim().length > 0)
|
|
122
141
|
continue;
|
|
@@ -125,7 +144,7 @@ export function primeInputs(root) {
|
|
|
125
144
|
primed += 1;
|
|
126
145
|
}
|
|
127
146
|
for (const el of Array.from(root.querySelectorAll('select'))) {
|
|
128
|
-
if (!(el instanceof HTMLSelectElement) || el.disabled)
|
|
147
|
+
if (!(el instanceof view.HTMLSelectElement) || el.disabled)
|
|
129
148
|
continue;
|
|
130
149
|
const current = el.options[el.selectedIndex];
|
|
131
150
|
if (current !== undefined && current.value.trim().length > 0)
|
|
@@ -136,17 +155,21 @@ export function primeInputs(root) {
|
|
|
136
155
|
setNativeValue(el, first.value);
|
|
137
156
|
primed += 1;
|
|
138
157
|
}
|
|
158
|
+
// Radios: one pick per named group; an unnamed radio is its own group.
|
|
159
|
+
// Grouping is done in JS (by `name` equality), not by re-querying with the
|
|
160
|
+
// name interpolated into a selector — no `CSS.escape`, no realm dependency.
|
|
161
|
+
const radios = Array.from(root.querySelectorAll('input[type="radio"]')).filter((m) => m instanceof view.HTMLInputElement);
|
|
139
162
|
const seenGroups = new Set();
|
|
140
|
-
for (const el of
|
|
141
|
-
if (
|
|
163
|
+
for (const el of radios) {
|
|
164
|
+
if (el.disabled)
|
|
142
165
|
continue;
|
|
143
|
-
const group = el.name
|
|
144
|
-
if (
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
166
|
+
const group = el.name;
|
|
167
|
+
if (group !== '') {
|
|
168
|
+
if (seenGroups.has(group))
|
|
169
|
+
continue;
|
|
170
|
+
seenGroups.add(group);
|
|
171
|
+
}
|
|
172
|
+
const members = group !== '' ? radios.filter((m) => m.name === group) : [el];
|
|
150
173
|
if (members.some((m) => m.checked))
|
|
151
174
|
continue;
|
|
152
175
|
const first = members.find((m) => !m.disabled);
|
|
@@ -20580,14 +20580,29 @@
|
|
|
20580
20580
|
easeInOut: "cubic-bezier(0.4, 0, 0.2, 1)",
|
|
20581
20581
|
spring: "cubic-bezier(0.175, 0.885, 0.32, 1.275)"
|
|
20582
20582
|
};
|
|
20583
|
+
var motionVar = {
|
|
20584
|
+
duration: {
|
|
20585
|
+
fast: "var(--ggui-motion-duration-fast)",
|
|
20586
|
+
base: "var(--ggui-motion-duration-base)",
|
|
20587
|
+
slow: "var(--ggui-motion-duration-slow)"
|
|
20588
|
+
},
|
|
20589
|
+
easing: {
|
|
20590
|
+
/** The system's ease-in-out — the default for colour, border and size changes. */
|
|
20591
|
+
standard: "var(--ggui-motion-easing-standard)",
|
|
20592
|
+
/** The decelerating arrival — transforms and entrances. */
|
|
20593
|
+
emphasized: "var(--ggui-motion-easing-emphasized)",
|
|
20594
|
+
/** The accelerating departure. */
|
|
20595
|
+
exit: "var(--ggui-motion-easing-exit)"
|
|
20596
|
+
}
|
|
20597
|
+
};
|
|
20583
20598
|
var transition = {
|
|
20584
20599
|
none: "none",
|
|
20585
|
-
fast: `${duration.fast} ${easing.
|
|
20586
|
-
normal: `${duration.
|
|
20587
|
-
slow: `${duration.slow} ${easing.
|
|
20588
|
-
colors: `color ${duration.
|
|
20589
|
-
opacity: `opacity ${duration.
|
|
20590
|
-
transform: `transform ${duration.
|
|
20600
|
+
fast: `${motionVar.duration.fast} ${motionVar.easing.standard}`,
|
|
20601
|
+
normal: `${motionVar.duration.base} ${motionVar.easing.standard}`,
|
|
20602
|
+
slow: `${motionVar.duration.slow} ${motionVar.easing.standard}`,
|
|
20603
|
+
colors: `color ${motionVar.duration.base} ${motionVar.easing.standard}, background-color ${motionVar.duration.base} ${motionVar.easing.standard}, border-color ${motionVar.duration.base} ${motionVar.easing.standard}`,
|
|
20604
|
+
opacity: `opacity ${motionVar.duration.base} ${motionVar.easing.standard}`,
|
|
20605
|
+
transform: `transform ${motionVar.duration.base} ${motionVar.easing.emphasized}`
|
|
20591
20606
|
};
|
|
20592
20607
|
|
|
20593
20608
|
// ../design/dist/primitives/Button.js
|
|
@@ -20663,7 +20678,7 @@
|
|
|
20663
20678
|
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
20664
20679
|
opacity: isDisabled ? 0.5 : 1,
|
|
20665
20680
|
width: fullWidth ? "100%" : void 0,
|
|
20666
|
-
transition: `background-color ${duration.
|
|
20681
|
+
transition: `background-color ${motionVar.duration.base} ${motionVar.easing.standard}, box-shadow ${motionVar.duration.base} ${motionVar.easing.standard}, opacity ${motionVar.duration.base} ${motionVar.easing.standard}`,
|
|
20667
20682
|
boxShadow: "var(--ggui-shape-shadow-sm, 0 1px 2px rgba(0,0,0,0.05))",
|
|
20668
20683
|
...style
|
|
20669
20684
|
}, ...rest, children: loading ? (0, import_jsx_runtime8.jsx)(Spinner, { size: 16, tone: "inherit" }) : (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [leftIcon, children, rightIcon] }) });
|
|
@@ -20708,7 +20723,7 @@
|
|
|
20708
20723
|
border: `1px solid ${hasError ? "var(--ggui-color-error-500, #ef4444)" : "var(--ggui-color-outline, #d4d4d8)"}`,
|
|
20709
20724
|
backgroundColor: disabled ? "var(--ggui-color-sunken, #fafafa)" : "var(--ggui-color-sunken, #ffffff)",
|
|
20710
20725
|
color: "var(--ggui-color-onContainer, #18181b)",
|
|
20711
|
-
transition: `border-color ${duration.
|
|
20726
|
+
transition: `border-color ${motionVar.duration.base} ${motionVar.easing.standard}, box-shadow ${motionVar.duration.base} ${motionVar.easing.standard}`,
|
|
20712
20727
|
boxSizing: "border-box"
|
|
20713
20728
|
}, ...rest }), hasMessage && (0, import_jsx_runtime9.jsx)("span", { id: messageId, role: hasError ? "alert" : void 0, style: {
|
|
20714
20729
|
fontSize: "var(--ggui-font-size-xs, 12px)",
|
|
@@ -20744,7 +20759,7 @@
|
|
|
20744
20759
|
color: "var(--ggui-color-onContainer, #18181b)",
|
|
20745
20760
|
fontSize: "var(--ggui-font-size-sm, 14px)",
|
|
20746
20761
|
fontFamily: "inherit",
|
|
20747
|
-
transition: `border-color ${duration.
|
|
20762
|
+
transition: `border-color ${motionVar.duration.base} ${motionVar.easing.standard}, box-shadow ${motionVar.duration.base} ${motionVar.easing.standard}`,
|
|
20748
20763
|
boxSizing: "border-box",
|
|
20749
20764
|
resize: autoResize ? "none" : "vertical"
|
|
20750
20765
|
}, ...rest }), (0, import_jsx_runtime10.jsxs)("div", { style: { display: "flex", justifyContent: "space-between" }, children: [hasMessage && (0, import_jsx_runtime10.jsx)("span", { id: messageId, role: hasError ? "alert" : void 0, style: {
|
|
@@ -20789,7 +20804,7 @@
|
|
|
20789
20804
|
backgroundPosition: "right 12px center",
|
|
20790
20805
|
paddingRight: "36px",
|
|
20791
20806
|
boxSizing: "border-box",
|
|
20792
|
-
transition: `border-color ${duration.
|
|
20807
|
+
transition: `border-color ${motionVar.duration.base} ${motionVar.easing.standard}, box-shadow ${motionVar.duration.base} ${motionVar.easing.standard}`
|
|
20793
20808
|
}, ...rest, children: [placeholder && (0, import_jsx_runtime11.jsx)("option", { value: "", disabled: true, children: placeholder }), options.map((opt) => (0, import_jsx_runtime11.jsx)("option", { value: opt.value, disabled: opt.disabled, children: opt.label }, opt.value))] }), hasMessage && (0, import_jsx_runtime11.jsx)("span", { id: messageId, role: hasError ? "alert" : void 0, style: {
|
|
20794
20809
|
fontSize: "var(--ggui-font-size-xs, 12px)",
|
|
20795
20810
|
color: hasError ? "var(--ggui-color-error-500, #ef4444)" : "var(--ggui-color-onSunken, #52525b)"
|
|
@@ -20831,7 +20846,7 @@
|
|
|
20831
20846
|
display: "flex",
|
|
20832
20847
|
alignItems: "center",
|
|
20833
20848
|
justifyContent: "center",
|
|
20834
|
-
transition:
|
|
20849
|
+
transition: `all ${motionVar.duration.base} ${motionVar.easing.standard}`
|
|
20835
20850
|
}, children: (checked || indeterminate) && (0, import_jsx_runtime12.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", style: { color: "var(--ggui-color-onPrimary, #ffffff)" }, children: indeterminate ? (0, import_jsx_runtime12.jsx)("path", { d: "M2.5 6H9.5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) : (0, import_jsx_runtime12.jsx)("path", { d: "M2.5 6L5 8.5L9.5 3.5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] }), (label || description) && (0, import_jsx_runtime12.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "2px" }, children: [label && (0, import_jsx_runtime12.jsx)("span", { style: {
|
|
20836
20851
|
fontSize: "var(--ggui-font-size-sm, 14px)",
|
|
20837
20852
|
fontWeight: "var(--ggui-font-weight-medium, 500)",
|
|
@@ -20873,7 +20888,7 @@
|
|
|
20873
20888
|
borderRadius: "9999px",
|
|
20874
20889
|
backgroundColor: checked ? "var(--ggui-color-primary-600, #0284c7)" : "var(--ggui-color-outline, #d4d4d8)",
|
|
20875
20890
|
position: "relative",
|
|
20876
|
-
transition: `background-color ${duration.
|
|
20891
|
+
transition: `background-color ${motionVar.duration.base} ${motionVar.easing.standard}, box-shadow ${motionVar.duration.base} ${motionVar.easing.standard}`,
|
|
20877
20892
|
flexShrink: 0,
|
|
20878
20893
|
outline: "none",
|
|
20879
20894
|
boxShadow: focused ? "0 0 0 3px var(--ggui-color-primary-200, #bae6fd)" : void 0
|
|
@@ -20885,7 +20900,7 @@
|
|
|
20885
20900
|
position: "absolute",
|
|
20886
20901
|
top: (config.height - config.knob) / 2,
|
|
20887
20902
|
left: checked ? config.width - config.knob - (config.height - config.knob) / 2 : (config.height - config.knob) / 2,
|
|
20888
|
-
transition: `left ${duration.
|
|
20903
|
+
transition: `left ${motionVar.duration.base} ${motionVar.easing.standard}`,
|
|
20889
20904
|
boxShadow: "var(--ggui-shape-shadow-sm, 0 1px 2px rgba(0,0,0,0.05))"
|
|
20890
20905
|
} }) }), label && (0, import_jsx_runtime13.jsx)("span", { style: {
|
|
20891
20906
|
fontSize: "var(--ggui-font-size-sm, 14px)",
|
|
@@ -20943,7 +20958,7 @@
|
|
|
20943
20958
|
display: "flex",
|
|
20944
20959
|
alignItems: "center",
|
|
20945
20960
|
justifyContent: "center",
|
|
20946
|
-
transition:
|
|
20961
|
+
transition: `all ${motionVar.duration.base} ${motionVar.easing.standard}`
|
|
20947
20962
|
}, children: isSelected && (0, import_jsx_runtime14.jsx)("div", { style: {
|
|
20948
20963
|
width: "8px",
|
|
20949
20964
|
height: "8px",
|
|
@@ -20991,7 +21006,7 @@
|
|
|
20991
21006
|
height: "6px",
|
|
20992
21007
|
borderRadius: "3px",
|
|
20993
21008
|
backgroundColor: disabled ? "var(--ggui-color-outline, #d4d4d8)" : "var(--ggui-color-primary-600, #0284c7)",
|
|
20994
|
-
transition:
|
|
21009
|
+
transition: `width ${motionVar.duration.fast} ${motionVar.easing.standard}`
|
|
20995
21010
|
} }), (0, import_jsx_runtime15.jsx)("input", { id: sliderId, type: "range", min, max, step, value, onChange: (e) => onChange?.(Number(e.target.value)), disabled, "aria-labelledby": label ? labelId : void 0, "aria-label": label ? void 0 : "Slider", "aria-valuenow": value, "aria-valuemin": min, "aria-valuemax": max, style: {
|
|
20996
21011
|
position: "absolute",
|
|
20997
21012
|
width: "100%",
|
|
@@ -21009,7 +21024,7 @@
|
|
|
21009
21024
|
backgroundColor: "#ffffff",
|
|
21010
21025
|
border: `2px solid ${disabled ? "var(--ggui-color-outline, #d4d4d8)" : "var(--ggui-color-primary-600, #0284c7)"}`,
|
|
21011
21026
|
boxShadow: "var(--ggui-shape-shadow-sm, 0 1px 2px rgba(0,0,0,0.05))",
|
|
21012
|
-
transition:
|
|
21027
|
+
transition: `left ${motionVar.duration.fast} ${motionVar.easing.standard}`,
|
|
21013
21028
|
pointerEvents: "none"
|
|
21014
21029
|
} })] })] });
|
|
21015
21030
|
}
|
|
@@ -21237,7 +21252,7 @@
|
|
|
21237
21252
|
height: "100%",
|
|
21238
21253
|
borderRadius: height / 2,
|
|
21239
21254
|
backgroundColor: barColor,
|
|
21240
|
-
transition: indeterminate ? "none" :
|
|
21255
|
+
transition: indeterminate ? "none" : `width ${motionVar.duration.slow} ${motionVar.easing.standard}`,
|
|
21241
21256
|
...indeterminate ? {
|
|
21242
21257
|
width: "30%",
|
|
21243
21258
|
animation: "ggui-progress-indeterminate 1.5s ease-in-out infinite"
|
|
@@ -25869,7 +25884,7 @@
|
|
|
25869
25884
|
color: linkColor,
|
|
25870
25885
|
textDecoration: underlineStyle,
|
|
25871
25886
|
cursor: "pointer",
|
|
25872
|
-
transition:
|
|
25887
|
+
transition: `color ${motionVar.duration.base} ${motionVar.easing.standard}`,
|
|
25873
25888
|
...style
|
|
25874
25889
|
}, onMouseEnter: (e) => {
|
|
25875
25890
|
if (underline === "hover") {
|
|
@@ -26029,7 +26044,7 @@
|
|
|
26029
26044
|
cursor: col.sortable ? "pointer" : "default"
|
|
26030
26045
|
}, children: (0, import_jsx_runtime25.jsxs)("span", { style: { display: "inline-flex", alignItems: "center" }, children: [col.header, col.sortable && sortIndicator(sortKey === col.key, sortDirection)] }) }, col.key)) }) }), (0, import_jsx_runtime25.jsx)("tbody", { children: data.map((row, rowIndex) => (0, import_jsx_runtime25.jsx)("tr", { onMouseEnter: hoverable ? () => setHoveredRow(rowIndex) : void 0, onMouseLeave: hoverable ? () => setHoveredRow(null) : void 0, style: {
|
|
26031
26046
|
backgroundColor: hoverable && hoveredRow === rowIndex ? "var(--ggui-color-sunken, #fafafa)" : striped && rowIndex % 2 === 1 ? "var(--ggui-color-sunken, #fafafa)" : "transparent",
|
|
26032
|
-
transition:
|
|
26047
|
+
transition: `background-color ${motionVar.duration.fast} ${motionVar.easing.standard}`
|
|
26033
26048
|
}, children: columns.map((col) => (0, import_jsx_runtime25.jsx)("td", { style: {
|
|
26034
26049
|
padding: cellPadding,
|
|
26035
26050
|
textAlign: col.align || "left",
|
|
@@ -26103,7 +26118,7 @@
|
|
|
26103
26118
|
background: "none",
|
|
26104
26119
|
border: "none",
|
|
26105
26120
|
fontWeight: isActive ? "var(--ggui-font-weight-semibold, 600)" : "var(--ggui-font-weight-medium, 500)",
|
|
26106
|
-
transition: `color ${duration.
|
|
26121
|
+
transition: `color ${motionVar.duration.base} ${motionVar.easing.standard}, background-color ${motionVar.duration.base} ${motionVar.easing.standard}, border-color ${motionVar.duration.base} ${motionVar.easing.standard}`,
|
|
26107
26122
|
whiteSpace: "nowrap",
|
|
26108
26123
|
flex: fullWidth ? 1 : void 0,
|
|
26109
26124
|
justifyContent: fullWidth ? "center" : void 0
|
|
@@ -26397,7 +26412,7 @@
|
|
|
26397
26412
|
var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
|
|
26398
26413
|
var import_react18 = __toESM(require_react(), 1);
|
|
26399
26414
|
var chevron = (expanded) => (0, import_jsx_runtime28.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true", style: {
|
|
26400
|
-
transition: `transform ${duration.
|
|
26415
|
+
transition: `transform ${motionVar.duration.base} ${motionVar.easing.standard}`,
|
|
26401
26416
|
transform: expanded ? "rotate(180deg)" : "rotate(0deg)",
|
|
26402
26417
|
flexShrink: 0
|
|
26403
26418
|
}, children: (0, import_jsx_runtime28.jsx)("path", { fillRule: "evenodd", d: "M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z", clipRule: "evenodd" }) });
|
|
@@ -26470,7 +26485,7 @@
|
|
|
26470
26485
|
fontWeight: "var(--ggui-font-weight-medium, 500)",
|
|
26471
26486
|
color: "var(--ggui-color-onContainer, #18181b)",
|
|
26472
26487
|
textAlign: "left",
|
|
26473
|
-
transition: `background-color ${duration.fast} ${easing.
|
|
26488
|
+
transition: `background-color ${motionVar.duration.fast} ${motionVar.easing.standard}`
|
|
26474
26489
|
}, children: [(0, import_jsx_runtime28.jsx)("span", { children: item.title }), chevron(isExpanded)] }) }), (0, import_jsx_runtime28.jsx)("div", { id: `${uniqueId}-panel-${item.key}`, role: "region", "aria-labelledby": `${uniqueId}-header-${item.key}`, hidden: !isExpanded, style: {
|
|
26475
26490
|
overflow: "hidden"
|
|
26476
26491
|
}, children: isExpanded && (0, import_jsx_runtime28.jsx)("div", { style: {
|
|
@@ -26644,7 +26659,7 @@
|
|
|
26644
26659
|
fontWeight: active ? fontWeight.medium : fontWeight.normal,
|
|
26645
26660
|
textAlign: "left",
|
|
26646
26661
|
cursor: disabled ? "not-allowed" : "pointer",
|
|
26647
|
-
transition:
|
|
26662
|
+
transition: `background-color ${motionVar.duration.fast} ${motionVar.easing.standard}`,
|
|
26648
26663
|
...style
|
|
26649
26664
|
}, onMouseEnter: (e) => {
|
|
26650
26665
|
if (!disabled && !active) {
|
|
@@ -26962,7 +26977,7 @@
|
|
|
26962
26977
|
fontWeight: active ? fontWeight.medium : fontWeight.normal,
|
|
26963
26978
|
cursor: disabled ? "not-allowed" : "pointer",
|
|
26964
26979
|
opacity: disabled ? 0.5 : 1,
|
|
26965
|
-
transition:
|
|
26980
|
+
transition: `all ${motionVar.duration.fast} ${motionVar.easing.standard}`
|
|
26966
26981
|
}, children: page });
|
|
26967
26982
|
return (0, import_jsx_runtime36.jsxs)("nav", { "aria-label": "Pagination", className, style: {
|
|
26968
26983
|
display: "flex",
|
|
@@ -27030,7 +27045,7 @@
|
|
|
27030
27045
|
justifyContent: "center",
|
|
27031
27046
|
flexShrink: 0,
|
|
27032
27047
|
boxSizing: "border-box",
|
|
27033
|
-
transition:
|
|
27048
|
+
transition: `background-color ${motionVar.duration.base} ${motionVar.easing.standard}, border-color ${motionVar.duration.base} ${motionVar.easing.standard}, color ${motionVar.duration.base} ${motionVar.easing.standard}`,
|
|
27034
27049
|
...markerStyles[state]
|
|
27035
27050
|
}, children: state === "completed" ? (0, import_jsx_runtime39.jsx)(Icon, { name: "check", size: 16, tone: "inherit" }) : (0, import_jsx_runtime39.jsx)(Text, { is: "span", size: "sm", weight: "semibold", tone: "inherit", children: index + 1 }) });
|
|
27036
27051
|
}
|
|
@@ -29561,6 +29576,14 @@
|
|
|
29561
29576
|
"--ggui-font-weight-normal",
|
|
29562
29577
|
"--ggui-font-weight-semibold",
|
|
29563
29578
|
"--ggui-letter-spacing-heading",
|
|
29579
|
+
"--ggui-motion-duration-base",
|
|
29580
|
+
"--ggui-motion-duration-fast",
|
|
29581
|
+
"--ggui-motion-duration-slow",
|
|
29582
|
+
"--ggui-motion-easing-emphasized",
|
|
29583
|
+
"--ggui-motion-easing-exit",
|
|
29584
|
+
"--ggui-motion-easing-standard",
|
|
29585
|
+
"--ggui-scrim-opacity",
|
|
29586
|
+
"--ggui-scrim-tint",
|
|
29564
29587
|
"--ggui-shape-radius-control",
|
|
29565
29588
|
"--ggui-shape-radius-full",
|
|
29566
29589
|
"--ggui-shape-radius-lg",
|
|
@@ -32534,6 +32557,7 @@
|
|
|
32534
32557
|
"duration",
|
|
32535
32558
|
"easing",
|
|
32536
32559
|
"transition",
|
|
32560
|
+
"motionVar",
|
|
32537
32561
|
"keyframes",
|
|
32538
32562
|
"thinkingAnimation",
|
|
32539
32563
|
"thinkingKeyframes",
|
|
@@ -32795,6 +32819,13 @@
|
|
|
32795
32819
|
}
|
|
32796
32820
|
|
|
32797
32821
|
// src/prime-inputs.ts
|
|
32822
|
+
function realmOf(el) {
|
|
32823
|
+
const view = el.ownerDocument.defaultView;
|
|
32824
|
+
if (view === null) {
|
|
32825
|
+
throw new Error("primeInputs: the element is not attached to a window (ownerDocument.defaultView is null) \u2014 a detached document has no constructors to prime with");
|
|
32826
|
+
}
|
|
32827
|
+
return view;
|
|
32828
|
+
}
|
|
32798
32829
|
var TEXT_LIKE_INPUT_TYPES = /* @__PURE__ */ new Set([
|
|
32799
32830
|
"text",
|
|
32800
32831
|
"email",
|
|
@@ -32833,7 +32864,7 @@
|
|
|
32833
32864
|
return `${date.getUTCFullYear()}-W${pad2(week)}`;
|
|
32834
32865
|
}
|
|
32835
32866
|
function sampleValueFor(el) {
|
|
32836
|
-
if (!(el instanceof HTMLInputElement)) return "probe";
|
|
32867
|
+
if (!(el instanceof realmOf(el).HTMLInputElement)) return "probe";
|
|
32837
32868
|
switch (el.type) {
|
|
32838
32869
|
case "number":
|
|
32839
32870
|
return "1";
|
|
@@ -32869,25 +32900,27 @@
|
|
|
32869
32900
|
}
|
|
32870
32901
|
}
|
|
32871
32902
|
function setNativeValue(el, value) {
|
|
32872
|
-
const
|
|
32903
|
+
const view = realmOf(el);
|
|
32904
|
+
const proto = el instanceof view.HTMLTextAreaElement ? view.HTMLTextAreaElement.prototype : el instanceof view.HTMLSelectElement ? view.HTMLSelectElement.prototype : view.HTMLInputElement.prototype;
|
|
32873
32905
|
const setter = Object.getOwnPropertyDescriptor(proto, "value")?.set;
|
|
32874
32906
|
if (setter) setter.call(el, value);
|
|
32875
32907
|
else el.value = value;
|
|
32876
|
-
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
32877
|
-
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
32908
|
+
el.dispatchEvent(new view.Event("input", { bubbles: true }));
|
|
32909
|
+
el.dispatchEvent(new view.Event("change", { bubbles: true }));
|
|
32878
32910
|
}
|
|
32879
32911
|
function primeInputs(root) {
|
|
32912
|
+
const view = realmOf(root);
|
|
32880
32913
|
let primed = 0;
|
|
32881
|
-
const editable = (el) => !el.disabled && !
|
|
32914
|
+
const editable = (el) => !el.disabled && !el.readOnly;
|
|
32882
32915
|
for (const el of Array.from(root.querySelectorAll("input, textarea"))) {
|
|
32883
|
-
if (!(el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) || !editable(el)) continue;
|
|
32884
|
-
if (el instanceof HTMLInputElement && !TEXT_LIKE_INPUT_TYPES.has(el.type)) continue;
|
|
32916
|
+
if (!(el instanceof view.HTMLInputElement || el instanceof view.HTMLTextAreaElement) || !editable(el)) continue;
|
|
32917
|
+
if (el instanceof view.HTMLInputElement && !TEXT_LIKE_INPUT_TYPES.has(el.type)) continue;
|
|
32885
32918
|
if (el.value.trim().length > 0) continue;
|
|
32886
32919
|
setNativeValue(el, sampleValueFor(el));
|
|
32887
32920
|
if (el.value.trim().length > 0) primed += 1;
|
|
32888
32921
|
}
|
|
32889
32922
|
for (const el of Array.from(root.querySelectorAll("select"))) {
|
|
32890
|
-
if (!(el instanceof HTMLSelectElement) || el.disabled) continue;
|
|
32923
|
+
if (!(el instanceof view.HTMLSelectElement) || el.disabled) continue;
|
|
32891
32924
|
const current = el.options[el.selectedIndex];
|
|
32892
32925
|
if (current !== void 0 && current.value.trim().length > 0) continue;
|
|
32893
32926
|
const first = Array.from(el.options).find((o) => o.value.trim().length > 0 && !o.disabled);
|
|
@@ -32895,13 +32928,18 @@
|
|
|
32895
32928
|
setNativeValue(el, first.value);
|
|
32896
32929
|
primed += 1;
|
|
32897
32930
|
}
|
|
32931
|
+
const radios = Array.from(root.querySelectorAll('input[type="radio"]')).filter(
|
|
32932
|
+
(m) => m instanceof view.HTMLInputElement
|
|
32933
|
+
);
|
|
32898
32934
|
const seenGroups = /* @__PURE__ */ new Set();
|
|
32899
|
-
for (const el of
|
|
32900
|
-
if (
|
|
32901
|
-
const group = el.name
|
|
32902
|
-
if (
|
|
32903
|
-
|
|
32904
|
-
|
|
32935
|
+
for (const el of radios) {
|
|
32936
|
+
if (el.disabled) continue;
|
|
32937
|
+
const group = el.name;
|
|
32938
|
+
if (group !== "") {
|
|
32939
|
+
if (seenGroups.has(group)) continue;
|
|
32940
|
+
seenGroups.add(group);
|
|
32941
|
+
}
|
|
32942
|
+
const members = group !== "" ? radios.filter((m) => m.name === group) : [el];
|
|
32905
32943
|
if (members.some((m) => m.checked)) continue;
|
|
32906
32944
|
const first = members.find((m) => !m.disabled);
|
|
32907
32945
|
if (first === void 0) continue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ggui-ai/ui-visual-tester",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Behavioral validator for ggui-generated component code. Renders a component in real Chromium via Playwright, clicks each action declared in its contract, and verifies the action actually does something — mutating bound state or dispatching to the agent. Catches buttons wired to no-op handlers that structural validators miss. Playwright is an optional peer dependency, injected by the caller.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ggui",
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"react": "^19.0.0",
|
|
55
55
|
"react-dom": "^19.0.0",
|
|
56
|
-
"@ggui-ai/
|
|
57
|
-
"@ggui-ai/
|
|
58
|
-
"@ggui-ai/wire": "0.
|
|
56
|
+
"@ggui-ai/protocol": "0.21.0",
|
|
57
|
+
"@ggui-ai/design": "0.21.0",
|
|
58
|
+
"@ggui-ai/wire": "0.21.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@playwright/test": "^1.60.0",
|