@godxjp/ui 32.1.0 → 32.1.2
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 -2
- package/agent/START-HERE.md +4 -4
- package/agent/components/Calendar.json +1 -1
- package/agent/components/ListRow.json +2 -1
- package/agent/components/Select.json +2 -2
- package/agent/components/Toggle.json +3 -2
- package/agent/components/ToggleGroup.json +1 -1
- package/agent/components.json +9 -7
- package/agent/index.json +4 -4
- package/agent/llms.txt +5 -5
- package/agent/tokens.json +42 -0
- package/dist/components/data-entry/search-select.js +5 -2
- package/dist/components/data-entry/toggle.d.ts +2 -2
- package/dist/components/data-entry/toggle.js +5 -1
- package/dist/contracts/measurement.json +1 -1
- package/dist/styles/control.css +12 -3
- package/dist/styles/data-display-layout.css +7 -0
- package/dist/styles/layers.json +1 -1
- package/dist/styles/toggle.css +14 -0
- package/dist/styles.css +1 -1
- package/dist/tokens/components/control.css +10 -0
- package/package.json +2 -2
- package/scripts/ui-audit.mjs +83 -4
|
@@ -147,6 +147,13 @@
|
|
|
147
147
|
--checkbox-checked-background: initial;
|
|
148
148
|
--switch-checked-background: initial;
|
|
149
149
|
--toggle-on-background: initial;
|
|
150
|
+
|
|
151
|
+
--toggle-on-color: initial;
|
|
152
|
+
|
|
153
|
+
--toggle-quiet-on-background: initial;
|
|
154
|
+
--toggle-quiet-on-color: initial;
|
|
155
|
+
--toggle-quiet-on-count-background: initial;
|
|
156
|
+
--toggle-quiet-on-count-color: initial;
|
|
150
157
|
--slider-track-background: initial;
|
|
151
158
|
--slider-range-background: initial;
|
|
152
159
|
|
|
@@ -366,6 +373,9 @@
|
|
|
366
373
|
|
|
367
374
|
--calendar-bordered-weekday-padding-block: var(--space-1);
|
|
368
375
|
|
|
376
|
+
--calendar-full-day-padding-inline: initial;
|
|
377
|
+
--calendar-full-day-padding-block: initial;
|
|
378
|
+
|
|
369
379
|
--calendar-grid-border-color: initial;
|
|
370
380
|
|
|
371
381
|
--transfer-pane-min-height: 14rem;
|
package/package.json
CHANGED
package/scripts/ui-audit.mjs
CHANGED
|
@@ -1305,8 +1305,11 @@ function lucideLocalNames(source) {
|
|
|
1305
1305
|
*/
|
|
1306
1306
|
function iconSizingRanges(source) {
|
|
1307
1307
|
const ranges = [];
|
|
1308
|
+
// Each of these sizes a glyph it holds directly: Button through its svg utility ladder, the menu
|
|
1309
|
+
// items and TopbarItem through their own rules, Toggle/ToggleGroupItem through `.ui-toggle > svg`
|
|
1310
|
+
// in control.css (a bare star inside a Toggle was a false positive, gh#1257).
|
|
1308
1311
|
for (const m of source.matchAll(
|
|
1309
|
-
/<(Button|DropdownMenuItem|DropdownMenuCheckboxItem|DropdownMenuRadioItem|TopbarItem)\b[\s\S]*?<\/\1>/g,
|
|
1312
|
+
/<(Button|DropdownMenuItem|DropdownMenuCheckboxItem|DropdownMenuRadioItem|TopbarItem|Toggle|ToggleGroupItem)\b[\s\S]*?<\/\1>/g,
|
|
1310
1313
|
)) {
|
|
1311
1314
|
ranges.push([m.index, m.index + m[0].length]);
|
|
1312
1315
|
}
|
|
@@ -1826,6 +1829,8 @@ function staleOwnedRules() {
|
|
|
1826
1829
|
const FORM_TAGS = new Set(["Form", "FormRoot"]);
|
|
1827
1830
|
const formOpenTag = new RegExp(`<(${[...FORM_TAGS].join("|")})(?=[\\s>])([^>]*)>`, "g");
|
|
1828
1831
|
function formTagWalk(scanContent) {
|
|
1832
|
+
const formSpans = [];
|
|
1833
|
+
const formOpens = [];
|
|
1829
1834
|
const stack = [];
|
|
1830
1835
|
const bareByParent = new Map();
|
|
1831
1836
|
const underForm = new Set();
|
|
@@ -1843,11 +1848,18 @@ function formTagWalk(scanContent) {
|
|
|
1843
1848
|
break;
|
|
1844
1849
|
}
|
|
1845
1850
|
}
|
|
1846
|
-
if (FORM_TAGS.has(tag))
|
|
1851
|
+
if (FORM_TAGS.has(tag)) {
|
|
1852
|
+
formDepth = Math.max(0, formDepth - 1);
|
|
1853
|
+
const open = formOpens.pop();
|
|
1854
|
+
if (open !== undefined) formSpans.push([open, m.index]);
|
|
1855
|
+
}
|
|
1847
1856
|
continue;
|
|
1848
1857
|
}
|
|
1849
1858
|
if (tag === "FormField" && formDepth === 0) {
|
|
1850
|
-
|
|
1859
|
+
// A field at the TOP of a return has no parent tag; key it by its component, or two
|
|
1860
|
+
// one-field components in one file (`Field`, `Choice`) read as "Field renders 2 FormFields"
|
|
1861
|
+
// (gh#1260). A lone field is not flagged, so each is now judged on its own.
|
|
1862
|
+
const parent = stack.at(-1)?.index ?? `top:${enclosingComponent(scanContent, m.index)}`;
|
|
1851
1863
|
(bareByParent.get(parent) ?? bareByParent.set(parent, []).get(parent)).push(m.index);
|
|
1852
1864
|
}
|
|
1853
1865
|
if (/^[A-Z]/.test(tag)) {
|
|
@@ -1856,11 +1868,78 @@ function formTagWalk(scanContent) {
|
|
|
1856
1868
|
}
|
|
1857
1869
|
if (selfClose) continue;
|
|
1858
1870
|
stack.push({ tag, index: m.index });
|
|
1859
|
-
if (FORM_TAGS.has(tag))
|
|
1871
|
+
if (FORM_TAGS.has(tag)) {
|
|
1872
|
+
formDepth += 1;
|
|
1873
|
+
formOpens.push(m.index);
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
// gh#1260: JSX inside a RENDER HELPER (`const legFields = (leg) => (…)`) has no Form above it in
|
|
1877
|
+
// the source, but it renders wherever the helper is CALLED. When every call of that helper is
|
|
1878
|
+
// under a Form — directly, or inside another such helper — the JSX is under that Form too.
|
|
1879
|
+
const covered = renderHelperCoverage(scanContent, formSpans);
|
|
1880
|
+
if (covered) {
|
|
1881
|
+
for (const [parent, indexes] of bareByParent) {
|
|
1882
|
+
const kept = indexes.filter((i) => !covered(i));
|
|
1883
|
+
if (kept.length) bareByParent.set(parent, kept);
|
|
1884
|
+
else bareByParent.delete(parent);
|
|
1885
|
+
}
|
|
1886
|
+
for (const [tag, indexes] of outsideForm) {
|
|
1887
|
+
const kept = indexes.filter((i) => !covered(i));
|
|
1888
|
+
if (kept.length < indexes.length) underForm.add(tag);
|
|
1889
|
+
if (kept.length) outsideForm.set(tag, kept);
|
|
1890
|
+
else outsideForm.delete(tag);
|
|
1891
|
+
}
|
|
1860
1892
|
}
|
|
1861
1893
|
return { bareByParent, underForm, outsideForm };
|
|
1862
1894
|
}
|
|
1863
1895
|
|
|
1896
|
+
/**
|
|
1897
|
+
* `index → true` when `index` sits in a same-file render helper whose every call is under a Form
|
|
1898
|
+
* (gh#1260). Helpers are lowercase `function name(` / `const name = (…) =>` declarations; their
|
|
1899
|
+
* body is found by bracket matching, and a helper never called is NOT covered (it might be
|
|
1900
|
+
* exported or passed as a render prop). Returns null when the file declares no helper.
|
|
1901
|
+
*/
|
|
1902
|
+
function renderHelperCoverage(scanContent, formSpans) {
|
|
1903
|
+
const helpers = [];
|
|
1904
|
+
for (const m of scanContent.matchAll(
|
|
1905
|
+
/(?<![\w$.])(?:function\s+([a-z]\w*)\s*(?:<[^>]*>)?\s*\(|(?:const|let)\s+([a-z]\w*)\s*(?::[^=]+)?=\s*(?:async\s*)?(?:\([^()]*(?:\([^()]*\)[^()]*)*\)|[a-z]\w*)\s*(?::[^=]+?)?=>\s*)/g,
|
|
1906
|
+
)) {
|
|
1907
|
+
const name = m[1] ?? m[2];
|
|
1908
|
+
let open;
|
|
1909
|
+
if (m[1]) {
|
|
1910
|
+
const params = matchBracket(scanContent, m.index + m[0].length - 1);
|
|
1911
|
+
if (params < 0) continue;
|
|
1912
|
+
open = scanContent.indexOf("{", params);
|
|
1913
|
+
} else {
|
|
1914
|
+
open = m.index + m[0].length;
|
|
1915
|
+
if (scanContent[open] !== "{" && scanContent[open] !== "(") continue;
|
|
1916
|
+
}
|
|
1917
|
+
const close = open < 0 ? -1 : matchBracket(scanContent, open);
|
|
1918
|
+
if (close < 0) continue;
|
|
1919
|
+
helpers.push({ name, from: open, to: close, decl: m.index });
|
|
1920
|
+
}
|
|
1921
|
+
if (!helpers.length) return null;
|
|
1922
|
+
const inForm = (i) => formSpans.some(([a, b]) => i > a && i < b);
|
|
1923
|
+
/** The innermost helper whose body holds `i`. */
|
|
1924
|
+
const helperAt = (i) =>
|
|
1925
|
+
helpers
|
|
1926
|
+
.filter((h) => i > h.from && i < h.to)
|
|
1927
|
+
.reduce((inner, h) => (!inner || h.from > inner.from ? h : inner), null);
|
|
1928
|
+
const callsOf = (name) =>
|
|
1929
|
+
[...scanContent.matchAll(new RegExp(`(?<![\\w$.])${name}\\s*\\(`, "g"))]
|
|
1930
|
+
.map((c) => c.index)
|
|
1931
|
+
.filter((i) => !helpers.some((h) => h.name === name && i >= h.decl && i < h.from));
|
|
1932
|
+
const covered = (i, depth = 0) => {
|
|
1933
|
+
if (inForm(i)) return true;
|
|
1934
|
+
if (depth > 4) return false;
|
|
1935
|
+
const helper = helperAt(i);
|
|
1936
|
+
if (!helper) return false;
|
|
1937
|
+
const calls = callsOf(helper.name);
|
|
1938
|
+
return calls.length > 0 && calls.every((c) => covered(c, depth + 1));
|
|
1939
|
+
};
|
|
1940
|
+
return (i) => covered(i);
|
|
1941
|
+
}
|
|
1942
|
+
|
|
1864
1943
|
/** The PascalCase component declared last before `index` — the one a FormField group sits in. */
|
|
1865
1944
|
function enclosingComponent(scanContent, index) {
|
|
1866
1945
|
let name = null;
|