@kitlangton/knobs 0.4.0-next.1 → 0.4.0-next.11
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 +191 -13
- package/dist/dev/{chunk-ayb292zj.js → chunk-75gbzbyd.js} +3 -3
- package/dist/dev/{chunk-1qzffbpa.js → chunk-bnhzf1tj.js} +240 -87
- package/dist/dev/{chunk-8mabjeyk.js → chunk-j57rhjtm.js} +166 -2
- package/dist/dev/{chunk-3ygqgy1x.js → chunk-mjdgzad5.js} +15 -2
- package/dist/dev/index.js +37 -14
- package/dist/index.js +46 -11
- package/dist/panel.js +408 -73
- package/dist/review-react.js +18580 -0
- package/dist/review-solid.js +18482 -0
- package/dist/review.js +18488 -0
- package/dist/themes.js +281 -23
- package/dist/types/core/remote.d.ts +2 -0
- package/dist/types/core/schema.d.ts +13 -1
- package/dist/types/core/store.d.ts +8 -0
- package/dist/types/panel/gpu/renderer.d.ts +2 -0
- package/dist/types/panel/presets.d.ts +7 -1
- package/dist/types/review/font.d.ts +13 -0
- package/dist/types/review/foundations.d.ts +175 -0
- package/dist/types/review/index.d.ts +13 -0
- package/dist/types/review/react.d.ts +1 -0
- package/dist/types/review/solid.d.ts +1 -0
- package/dist/types/themes/index.d.ts +7 -2
- package/dist/types/themes/review.d.ts +8 -0
- package/dist/types/tokens/schema.d.ts +180 -0
- package/dist/types/ui/compare-css.d.ts +1 -1
- package/dist/types/ui/compare-gpu.d.ts +6 -6
- package/dist/types/ui/compare-model.d.ts +85 -2
- package/dist/types/ui/compare.d.ts +18 -4
- package/dist/types/ui/diff.d.ts +4 -5
- package/dist/types/ui/history-css.d.ts +1 -0
- package/dist/types/ui/history-model.d.ts +249 -0
- package/dist/types/ui/history.d.ts +38 -0
- package/dist/types/ui/icons.d.ts +40 -0
- package/dist/types/ui/index.d.ts +8 -4
- package/dist/types/ui/player-css.d.ts +1 -0
- package/dist/types/ui/player.d.ts +51 -0
- package/dist/types/ui/review-look.d.ts +6 -0
- package/dist/types/ui/review-options.d.ts +28 -0
- package/dist/types/ui/selection-pill-css.d.ts +1 -0
- package/dist/types/ui/selection-pill.d.ts +106 -0
- package/dist/types/ui/timeline-model.d.ts +27 -0
- package/dist/types/ui/timeline.d.ts +16 -1
- package/dist/types/ui/tree.d.ts +3 -2
- package/dist/types/ui/walkthrough-annotations.d.ts +42 -0
- package/dist/types/ui/walkthrough-blocks.d.ts +87 -0
- package/dist/types/ui/walkthrough-media.d.ts +30 -1
- package/dist/types/ui/walkthrough-model.d.ts +469 -5
- package/dist/types/ui/walkthrough.d.ts +27 -5
- package/dist/ui-react.js +5124 -1031
- package/dist/ui-solid.js +5136 -1043
- package/dist/ui.js +6411 -2269
- package/package.json +13 -1
package/dist/themes.js
CHANGED
|
@@ -447,6 +447,22 @@ var TOKENS = [
|
|
|
447
447
|
source: css("var(--k-warn)"),
|
|
448
448
|
doc: "Modified lines."
|
|
449
449
|
},
|
|
450
|
+
{
|
|
451
|
+
name: "before",
|
|
452
|
+
tier: "semantic",
|
|
453
|
+
type: "color",
|
|
454
|
+
group: "Data",
|
|
455
|
+
source: css("var(--k-fg-3)"),
|
|
456
|
+
doc: "Before in a comparison, and only Before: its label and side of the seam. Neutral unless a theme gives it a colour."
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
name: "after",
|
|
460
|
+
tier: "semantic",
|
|
461
|
+
type: "color",
|
|
462
|
+
group: "Data",
|
|
463
|
+
source: css("var(--k-fg)"),
|
|
464
|
+
doc: "After in a comparison, and only After."
|
|
465
|
+
},
|
|
450
466
|
{
|
|
451
467
|
name: "series-1",
|
|
452
468
|
tier: "semantic",
|
|
@@ -537,6 +553,150 @@ var TOKENS = [
|
|
|
537
553
|
source: value("288px"),
|
|
538
554
|
doc: "Panel width."
|
|
539
555
|
},
|
|
556
|
+
{
|
|
557
|
+
name: "space-inside",
|
|
558
|
+
tier: "semantic",
|
|
559
|
+
type: "length",
|
|
560
|
+
group: "Space",
|
|
561
|
+
source: css("var(--k-unit)"),
|
|
562
|
+
doc: "Parts of one thing: an icon and its label, a meta line and its title."
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
name: "space-sibling",
|
|
566
|
+
tier: "semantic",
|
|
567
|
+
type: "length",
|
|
568
|
+
group: "Space",
|
|
569
|
+
source: css("calc(var(--k-unit) * 2)"),
|
|
570
|
+
doc: "Siblings in a group: buttons in a row, a list item's lines."
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
name: "space-title",
|
|
574
|
+
tier: "semantic",
|
|
575
|
+
type: "length",
|
|
576
|
+
group: "Space",
|
|
577
|
+
source: css("calc(var(--k-unit) * 3)"),
|
|
578
|
+
doc: "A heading and what it heads."
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
name: "space-group",
|
|
582
|
+
tier: "semantic",
|
|
583
|
+
type: "length",
|
|
584
|
+
group: "Space",
|
|
585
|
+
source: css("calc(var(--k-unit) * 12)"),
|
|
586
|
+
doc: "Groups inside a section (prose, video, diff), stacked media, feed items (a hairline in the middle)."
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
name: "space-section",
|
|
590
|
+
tier: "semantic",
|
|
591
|
+
type: "length",
|
|
592
|
+
group: "Space",
|
|
593
|
+
source: css("calc(var(--k-unit) * 24)"),
|
|
594
|
+
doc: "Sections of a page (the intro, the updates, each PR), a hairline in the middle."
|
|
595
|
+
},
|
|
596
|
+
{
|
|
597
|
+
name: "space-column",
|
|
598
|
+
tier: "semantic",
|
|
599
|
+
type: "length",
|
|
600
|
+
group: "Space",
|
|
601
|
+
source: css("calc(var(--k-unit) * 6)"),
|
|
602
|
+
doc: "Columns: a contents rail and the page, media side by side."
|
|
603
|
+
},
|
|
604
|
+
{
|
|
605
|
+
name: "pad-page",
|
|
606
|
+
tier: "semantic",
|
|
607
|
+
type: "length",
|
|
608
|
+
group: "Space",
|
|
609
|
+
source: css("calc(var(--k-unit) * 6)"),
|
|
610
|
+
doc: "A page's edge; 16px under 640px wide."
|
|
611
|
+
},
|
|
612
|
+
{
|
|
613
|
+
name: "pad-card",
|
|
614
|
+
tier: "semantic",
|
|
615
|
+
type: "length",
|
|
616
|
+
group: "Space",
|
|
617
|
+
source: css("calc(var(--k-unit) * 3)"),
|
|
618
|
+
doc: "Inside a card or popover."
|
|
619
|
+
},
|
|
620
|
+
{
|
|
621
|
+
name: "type-heading",
|
|
622
|
+
tier: "semantic",
|
|
623
|
+
type: "length",
|
|
624
|
+
group: "Type",
|
|
625
|
+
source: value("20px"),
|
|
626
|
+
doc: "A page's title, weight 500."
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
name: "leading-heading",
|
|
630
|
+
tier: "semantic",
|
|
631
|
+
type: "length",
|
|
632
|
+
group: "Type",
|
|
633
|
+
source: value("28px"),
|
|
634
|
+
doc: "Line height for type-heading."
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
name: "type-title",
|
|
638
|
+
tier: "semantic",
|
|
639
|
+
type: "length",
|
|
640
|
+
group: "Type",
|
|
641
|
+
source: value("16px"),
|
|
642
|
+
doc: "Section titles (under their kicker), weight 500."
|
|
643
|
+
},
|
|
644
|
+
{
|
|
645
|
+
name: "leading-title",
|
|
646
|
+
tier: "semantic",
|
|
647
|
+
type: "length",
|
|
648
|
+
group: "Type",
|
|
649
|
+
source: value("24px"),
|
|
650
|
+
doc: "Line height for type-title."
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
name: "type-body",
|
|
654
|
+
tier: "semantic",
|
|
655
|
+
type: "length",
|
|
656
|
+
group: "Type",
|
|
657
|
+
source: value("13px"),
|
|
658
|
+
doc: "Prose, questions, list rows, step titles; 400, or 500 for emphasis."
|
|
659
|
+
},
|
|
660
|
+
{
|
|
661
|
+
name: "leading-body",
|
|
662
|
+
tier: "semantic",
|
|
663
|
+
type: "length",
|
|
664
|
+
group: "Type",
|
|
665
|
+
source: value("20px"),
|
|
666
|
+
doc: "Line height for type-body."
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
name: "type-label",
|
|
670
|
+
tier: "semantic",
|
|
671
|
+
type: "length",
|
|
672
|
+
group: "Type",
|
|
673
|
+
source: value("12px"),
|
|
674
|
+
doc: "Mono inside body text: code and paths."
|
|
675
|
+
},
|
|
676
|
+
{
|
|
677
|
+
name: "leading-label",
|
|
678
|
+
tier: "semantic",
|
|
679
|
+
type: "length",
|
|
680
|
+
group: "Type",
|
|
681
|
+
source: value("16px"),
|
|
682
|
+
doc: "Line height for type-label."
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
name: "type-small",
|
|
686
|
+
tier: "semantic",
|
|
687
|
+
type: "length",
|
|
688
|
+
group: "Type",
|
|
689
|
+
source: value("11px"),
|
|
690
|
+
doc: "Meta, controls, keys, timestamps; mono inside labels."
|
|
691
|
+
},
|
|
692
|
+
{
|
|
693
|
+
name: "leading-small",
|
|
694
|
+
tier: "semantic",
|
|
695
|
+
type: "length",
|
|
696
|
+
group: "Type",
|
|
697
|
+
source: value("16px"),
|
|
698
|
+
doc: "Line height for type-small."
|
|
699
|
+
},
|
|
540
700
|
{
|
|
541
701
|
name: "font-size",
|
|
542
702
|
tier: "semantic",
|
|
@@ -1443,28 +1603,6 @@ var knobs = defineTheme({
|
|
|
1443
1603
|
material: "glass"
|
|
1444
1604
|
});
|
|
1445
1605
|
|
|
1446
|
-
// src/themes/void.ts
|
|
1447
|
-
var voidTheme = defineTheme({
|
|
1448
|
-
name: "void",
|
|
1449
|
-
extends: knobs,
|
|
1450
|
-
gray: { hue: 0, chroma: 0 },
|
|
1451
|
-
accent: { dark: "#ffffff", light: "#1c1c1c" },
|
|
1452
|
-
material: "flat",
|
|
1453
|
-
tokens: {
|
|
1454
|
-
dark: {
|
|
1455
|
-
"bg-page": "#000000",
|
|
1456
|
-
"bg-inset": "#0a0a0a",
|
|
1457
|
-
bg: "#000000",
|
|
1458
|
-
"bg-raised": "#1c1c1e",
|
|
1459
|
-
"bg-overlay": "#2c2c2e",
|
|
1460
|
-
fg: "#ededed",
|
|
1461
|
-
"fg-2": "#cecece",
|
|
1462
|
-
"fg-3": "#989898",
|
|
1463
|
-
"fg-4": "#7a7a7a",
|
|
1464
|
-
"compare-stage": "#000000"
|
|
1465
|
-
}
|
|
1466
|
-
}
|
|
1467
|
-
});
|
|
1468
1606
|
// src/core/spring.ts
|
|
1469
1607
|
class Spring {
|
|
1470
1608
|
x;
|
|
@@ -1547,6 +1685,125 @@ function springCss(value) {
|
|
|
1547
1685
|
return { easing, duration: ms };
|
|
1548
1686
|
}
|
|
1549
1687
|
|
|
1688
|
+
// src/core/motion.ts
|
|
1689
|
+
var SPRINGS = {
|
|
1690
|
+
instant: { duration: 0.1, bounce: 0 },
|
|
1691
|
+
snappy: { duration: 0.25, bounce: 0 },
|
|
1692
|
+
default: { duration: 0.3, bounce: 0 },
|
|
1693
|
+
calm: { duration: 0.4, bounce: 0 },
|
|
1694
|
+
smooth: { duration: 0.45, bounce: 0 }
|
|
1695
|
+
};
|
|
1696
|
+
var FADE = { duration: 0.16, bounce: 0 };
|
|
1697
|
+
var CLOSE = { duration: 0.18, bounce: 0 };
|
|
1698
|
+
var MOTION = Object.fromEntries(Object.entries(SPRINGS).map(([name, spring]) => [name, springMotion(spring)]));
|
|
1699
|
+
var springLinear = (spring) => {
|
|
1700
|
+
const { omega, zeta } = springMotion(spring);
|
|
1701
|
+
return springEasing(omega, zeta);
|
|
1702
|
+
};
|
|
1703
|
+
var names = Object.keys(SPRINGS);
|
|
1704
|
+
var linear = Object.fromEntries(names.map((n) => [n, springLinear(SPRINGS[n])]));
|
|
1705
|
+
var SPRING_TOKEN = `${SPRINGS.default.duration} ${SPRINGS.default.bounce}`;
|
|
1706
|
+
var DEFAULT_LINEAR = linear.default;
|
|
1707
|
+
var motionCss = `:where(:root,:host){${names.map((n) => `--_k-motion-${n}:${linear[n].easing};--_k-motion-${n}-ms:${linear[n].ms}`).join(";")}}
|
|
1708
|
+
@media(prefers-reduced-motion:reduce){:where(:root,:host){${names.map((n) => `--_k-motion-${n}-ms:0`).join(";")}}}`;
|
|
1709
|
+
|
|
1710
|
+
// src/review/foundations.ts
|
|
1711
|
+
var TRACKING = 0.03;
|
|
1712
|
+
var MEASURE = "66ch";
|
|
1713
|
+
var FONT = {
|
|
1714
|
+
sans: 'system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI Variable Text","Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif',
|
|
1715
|
+
mono: 'ui-monospace,"SF Mono",SFMono-Regular,"Cascadia Mono","JetBrains Mono",Menlo,Consolas,monospace'
|
|
1716
|
+
};
|
|
1717
|
+
var FEATURES = {
|
|
1718
|
+
figures: "tabular-nums",
|
|
1719
|
+
data: '"tnum" 1,"ss01" 1',
|
|
1720
|
+
code: "none"
|
|
1721
|
+
};
|
|
1722
|
+
var MOTION2 = [
|
|
1723
|
+
{
|
|
1724
|
+
name: "hover",
|
|
1725
|
+
spring: null,
|
|
1726
|
+
ms: "0 in, 120 out",
|
|
1727
|
+
use: "A hover's fill: on at once, off softly"
|
|
1728
|
+
},
|
|
1729
|
+
{
|
|
1730
|
+
name: "quick",
|
|
1731
|
+
spring: FADE,
|
|
1732
|
+
use: "Replacing a whole thing in place: fade, scale .98, blur 3 px"
|
|
1733
|
+
},
|
|
1734
|
+
{ name: "close", spring: CLOSE, use: "A popover closing" },
|
|
1735
|
+
{ name: "snappy", spring: SPRINGS.snappy, use: "Controls: a toggle, a pick, a chapter row" },
|
|
1736
|
+
{ name: "state", spring: SPRINGS.default, use: "The selection pill, a disclosure opening" },
|
|
1737
|
+
{
|
|
1738
|
+
name: "calm",
|
|
1739
|
+
spring: SPRINGS.calm,
|
|
1740
|
+
use: "Layout: a compare's height, the page scrolling to a step"
|
|
1741
|
+
},
|
|
1742
|
+
{ name: "smooth", spring: SPRINGS.smooth, use: "A step opening to the full window" }
|
|
1743
|
+
];
|
|
1744
|
+
var foundationCss = `
|
|
1745
|
+
:where(.knobs-walkthrough,.knobs-wt-slot,.knobs-review){
|
|
1746
|
+
--_kr-track:calc((var(--_k-type-body) - 1em) * ${TRACKING});
|
|
1747
|
+
--_kr-measure:var(--k-walkthrough-measure,${MEASURE});
|
|
1748
|
+
--_kr-block:calc(var(--_k-space-title) * 2);
|
|
1749
|
+
--_kr-data:${FEATURES.data};
|
|
1750
|
+
letter-spacing:var(--_kr-track);font-variant-numeric:${FEATURES.figures};font-optical-sizing:auto;font-kerning:normal}
|
|
1751
|
+
:where(.knobs-walkthrough,.knobs-wt-slot,.knobs-review) :where(*){letter-spacing:var(--_kr-track)}
|
|
1752
|
+
:where(.knobs-walkthrough,.knobs-wt-slot,.knobs-review) :where(code,pre,kbd,samp,.knobs-wt-mono){letter-spacing:0;font-variant-ligatures:${FEATURES.code}}
|
|
1753
|
+
`;
|
|
1754
|
+
|
|
1755
|
+
// src/themes/void.ts
|
|
1756
|
+
var voidTheme = defineTheme({
|
|
1757
|
+
name: "void",
|
|
1758
|
+
extends: knobs,
|
|
1759
|
+
gray: { hue: 0, chroma: 0 },
|
|
1760
|
+
accent: { dark: "#ffffff", light: "#1c1c1c" },
|
|
1761
|
+
material: "flat",
|
|
1762
|
+
tokens: {
|
|
1763
|
+
dark: {
|
|
1764
|
+
"bg-page": "#000000",
|
|
1765
|
+
"bg-inset": "#0a0a0a",
|
|
1766
|
+
bg: "#000000",
|
|
1767
|
+
"bg-raised": "#1c1c1e",
|
|
1768
|
+
"bg-overlay": "#2c2c2e",
|
|
1769
|
+
fg: "#ededed",
|
|
1770
|
+
"fg-2": "#cecece",
|
|
1771
|
+
"fg-3": "#989898",
|
|
1772
|
+
"fg-4": "#7a7a7a",
|
|
1773
|
+
"compare-stage": "#000000"
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
});
|
|
1777
|
+
|
|
1778
|
+
// src/themes/review.ts
|
|
1779
|
+
var reviewTheme = defineTheme({
|
|
1780
|
+
name: "review",
|
|
1781
|
+
extends: voidTheme,
|
|
1782
|
+
font: FONT,
|
|
1783
|
+
tokens: {
|
|
1784
|
+
dark: {
|
|
1785
|
+
fill: "#ededed0f",
|
|
1786
|
+
"fill-hover": "#ededed1a",
|
|
1787
|
+
"fill-selected": "#ededed24",
|
|
1788
|
+
"border-subtle": "#ededed47",
|
|
1789
|
+
border: "#ededed4f",
|
|
1790
|
+
"border-strong": "#585858"
|
|
1791
|
+
},
|
|
1792
|
+
light: {
|
|
1793
|
+
"bg-page": "#ffffff",
|
|
1794
|
+
"bg-inset": "#f7f7f7",
|
|
1795
|
+
bg: "#ffffff",
|
|
1796
|
+
"bg-raised": "#ffffff",
|
|
1797
|
+
"bg-overlay": "#ffffff",
|
|
1798
|
+
fill: "#1919190a",
|
|
1799
|
+
"fill-hover": "#19191912",
|
|
1800
|
+
"fill-selected": "#1919191c",
|
|
1801
|
+
"border-subtle": "#19191917",
|
|
1802
|
+
border: "#1919191d",
|
|
1803
|
+
"border-strong": "#dcdcdc"
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
});
|
|
1550
1807
|
// src/core/theme.ts
|
|
1551
1808
|
var property = (k) => k.startsWith("--") ? k : `--k-${k}`;
|
|
1552
1809
|
function presetCss(preset) {
|
|
@@ -1724,7 +1981,7 @@ var problemsPreset = {
|
|
|
1724
1981
|
}
|
|
1725
1982
|
};
|
|
1726
1983
|
// src/themes/index.ts
|
|
1727
|
-
var themes = { knobs, void: voidTheme };
|
|
1984
|
+
var themes = { knobs, void: voidTheme, review: reviewTheme };
|
|
1728
1985
|
export {
|
|
1729
1986
|
APCA_BUDGET,
|
|
1730
1987
|
defineTheme,
|
|
@@ -1732,6 +1989,7 @@ export {
|
|
|
1732
1989
|
labPreset,
|
|
1733
1990
|
presetCss,
|
|
1734
1991
|
problemsPreset,
|
|
1992
|
+
reviewTheme,
|
|
1735
1993
|
themes,
|
|
1736
1994
|
voidTheme
|
|
1737
1995
|
};
|
|
@@ -130,6 +130,8 @@ export interface RemoteControlsOptions {
|
|
|
130
130
|
readonly nullDefaults?: boolean;
|
|
131
131
|
readonly values?: State;
|
|
132
132
|
readonly presets?: Readonly<Record<string, State>>;
|
|
133
|
+
/** Groups pinned above the tab strip, outside the presets (see `ControlsOptions.pinned`). */
|
|
134
|
+
readonly pinned?: readonly string[];
|
|
133
135
|
/** Numbered presets per group, e.g. the phone's preset sets (see `ControlsOptions.groupPresets`). */
|
|
134
136
|
readonly groupPresets?: Readonly<Record<string, readonly GroupPreset[]>>;
|
|
135
137
|
/** Display labels by group id, section id and preset id (see `ControlsOptions.groupLabels`). */
|
|
@@ -50,6 +50,12 @@ export interface FieldMeta {
|
|
|
50
50
|
* Fields without a tab show on every tab.
|
|
51
51
|
*/
|
|
52
52
|
readonly tab?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Pins the field's group to the top of a panel, under the header and above the tab strip, on
|
|
55
|
+
* every tab (the first field of a group that says wins; a field without a group pins itself).
|
|
56
|
+
* Panel presets and saved variants leave pinned fields alone. See `ControlsOptions.pinned`.
|
|
57
|
+
*/
|
|
58
|
+
readonly pinned?: boolean;
|
|
53
59
|
/**
|
|
54
60
|
* A collapsible sub-heading inside the field's group: a flat heading with a hairline, never a
|
|
55
61
|
* card inside the card. Consecutive fields that share it sit under one heading.
|
|
@@ -57,7 +63,7 @@ export interface FieldMeta {
|
|
|
57
63
|
readonly subsection?: string;
|
|
58
64
|
}
|
|
59
65
|
/** Meta keys copied from a field's options or a descriptor onto the field. */
|
|
60
|
-
export declare const META_KEYS: readonly ["label", "group", "groupLabel", "section", "sectionLabel", "groupDescription", "sectionDescription", "shortcut", "random", "disabled", "readOnly", "folded", "sectionFolded", "tab", "subsection"];
|
|
66
|
+
export declare const META_KEYS: readonly ["label", "group", "groupLabel", "section", "sectionLabel", "groupDescription", "sectionDescription", "shortcut", "random", "disabled", "readOnly", "folded", "sectionFolded", "tab", "pinned", "subsection"];
|
|
61
67
|
/** The meta `source` gives, without undefined keys. */
|
|
62
68
|
export declare function pickMeta(source: FieldMeta | undefined, skip?: readonly string[]): FieldMeta;
|
|
63
69
|
/** Marks a knob as half of a flat spring: two number keys drawn as one spring card. */
|
|
@@ -329,6 +335,11 @@ export declare const isReadout: (field: {
|
|
|
329
335
|
/** Whether a field holds a value (actions, toolbars and readouts don't). */
|
|
330
336
|
export declare const hasValue: (field: Field) => field is ValueField;
|
|
331
337
|
export type Schema = Readonly<Record<string, Field>>;
|
|
338
|
+
/**
|
|
339
|
+
* The schema's pinned keys (values, actions and readouts alike): every key of a group in `groups`,
|
|
340
|
+
* or whose first field that gives `pinned` says `true`, and ungrouped fields that say so themselves.
|
|
341
|
+
*/
|
|
342
|
+
export declare function pinnedKeys(schema: Schema, groups?: readonly string[]): ReadonlySet<string>;
|
|
332
343
|
export type FieldValue<F extends Field> = F extends Knob ? number : F extends Choice<infer T> ? T : F extends Toggle ? boolean : F extends SpringField ? SpringValue : F extends ColorField ? string : F extends PointField ? Point : F extends EasingField ? Bezier : F extends VecField<3> ? Vec3 : F extends VecField<2> ? Point : F extends RangeField ? readonly [number, number] : F extends AngleField | SeedField ? number : F extends KeybindField ? string : F extends GradientField ? readonly GradientStop[] : F extends CurveField ? readonly CurvePoint[] : never;
|
|
333
344
|
/** The keys of a schema's readouts (what `controls.watch` takes). */
|
|
334
345
|
export type ReadoutKeys<S extends Schema> = {
|
|
@@ -449,6 +460,7 @@ export declare function range(value: readonly [number, number], options: FieldMe
|
|
|
449
460
|
folded?: boolean;
|
|
450
461
|
sectionFolded?: boolean;
|
|
451
462
|
tab?: string;
|
|
463
|
+
pinned?: boolean;
|
|
452
464
|
subsection?: string;
|
|
453
465
|
};
|
|
454
466
|
/** Degrees on a dial (0–360 and wrapping by default): `angle(45)`, `angle(30, { min: -90, max: 90 })`. */
|
|
@@ -348,6 +348,12 @@ export interface ControlsOptions<S extends Schema> extends LabelOptions {
|
|
|
348
348
|
/** An undo stack the host owns; undo and redo call it (see `HostHistory`). */
|
|
349
349
|
history?: HostHistory;
|
|
350
350
|
presets?: Readonly<Record<string, Partial<Values<S>>>>;
|
|
351
|
+
/**
|
|
352
|
+
* Groups pinned to the top of a panel, under the header and above the tab strip, on every tab
|
|
353
|
+
* (as fields' `pinned: true` pins theirs). Presets and saved variants leave them alone: applying
|
|
354
|
+
* one keeps their values, saving one keeps them out, and they're modified against their defaults.
|
|
355
|
+
*/
|
|
356
|
+
pinned?: readonly string[];
|
|
351
357
|
/**
|
|
352
358
|
* Numbered presets per group, shown as 1, 2, 3… on the group's card in a page. A group's
|
|
353
359
|
* presets cover every key any of them names; keys a preset leaves out are at their defaults,
|
|
@@ -426,6 +432,8 @@ export interface Controls<S extends Schema = Schema> {
|
|
|
426
432
|
readonly sectionFolded: SectionFolded | undefined;
|
|
427
433
|
/** A preset's display label (`presetLabels`, `defaultLabel`), else its id. */
|
|
428
434
|
presetLabel(id: string): string;
|
|
435
|
+
/** Whether `key` is pinned (its group is, see `ControlsOptions.pinned`), outside the presets. */
|
|
436
|
+
isPinned(key: string): boolean;
|
|
429
437
|
readonly error: string | null;
|
|
430
438
|
get(): Values<S>;
|
|
431
439
|
getServerSnapshot(): Values<S>;
|
|
@@ -407,6 +407,8 @@ export interface GpuPanelBinding {
|
|
|
407
407
|
readonly id: string;
|
|
408
408
|
readonly root: HTMLElement;
|
|
409
409
|
readonly body: HTMLElement;
|
|
410
|
+
/** The pinned groups' cards, above the tab strip (empty while none are pinned). */
|
|
411
|
+
readonly pinned?: HTMLElement;
|
|
410
412
|
readonly inline: boolean;
|
|
411
413
|
readonly header: HTMLElement;
|
|
412
414
|
readonly titleEl: HTMLElement;
|
|
@@ -28,6 +28,8 @@ export declare function activeEntryId(controls: Controls<any>): string | null;
|
|
|
28
28
|
* cycling never gets stuck when a saved variant has the exact same values as a built-in preset.
|
|
29
29
|
*/
|
|
30
30
|
export declare function resolveActivePresetEntry<V extends Record<string, any>>(entries: readonly PresetEntry<V>[], currentValues: V, lastAppliedId: string | null, baseId?: string | null): ActivePresetState;
|
|
31
|
+
/** Whether any entry but the defaults gives one of `keys` a value other than its default. */
|
|
32
|
+
export declare function presetsTouch(entries: readonly PresetEntry<any>[], keys: readonly string[], defaults: Readonly<Record<string, unknown>>): boolean;
|
|
31
33
|
export declare function nextPresetIndex(count: number, activeIndex: number, direction: number): number;
|
|
32
34
|
export interface PresetStrip {
|
|
33
35
|
readonly element: HTMLElement;
|
|
@@ -52,9 +54,13 @@ export interface PresetStrip {
|
|
|
52
54
|
readonly nameField: () => HTMLInputElement | null;
|
|
53
55
|
/** Deletes the selected chip when it's a saved variant; returns a status message. */
|
|
54
56
|
deleteActive(): string | undefined;
|
|
57
|
+
/** Whether the strip should show: presets to pick (or saving on) that touch what's shown. */
|
|
58
|
+
shows(): boolean;
|
|
55
59
|
update(): void;
|
|
56
60
|
dispose(): void;
|
|
57
61
|
}
|
|
58
62
|
export declare function createPresetStrip<S extends Schema>(doc: Document, controls: Controls<S>, showVariants: boolean, run: (action: () => unknown) => void, onAfterChange?: () => void,
|
|
59
63
|
/** What a preset's chip says (its id stays its identity); `controls.presetLabel` by default. */
|
|
60
|
-
presetLabel?: (id: string) => string
|
|
64
|
+
presetLabel?: (id: string) => string,
|
|
65
|
+
/** Whether these entries matter where the strip is shown (a tab they don't touch hides it). */
|
|
66
|
+
relevant?: (entries: readonly PresetEntry<any>[]) => boolean): PresetStrip;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Theme } from "../themes/define.js";
|
|
2
|
+
export interface ReviewFontOptions {
|
|
3
|
+
/** A stylesheet that declares the face (Google Fonts, rsms.me/inter, your own). */
|
|
4
|
+
readonly href?: string;
|
|
5
|
+
/** The family, first in the stack: `"Inter"`, `"Geist"`. The platform's face follows it. */
|
|
6
|
+
readonly sans?: string;
|
|
7
|
+
readonly mono?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The review look in a webfont: loads `href` once per document and returns the review theme with
|
|
11
|
+
* `sans` (and `mono`) first in its stacks. Pass it as `theme`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function reviewFont(doc: Document, options: ReviewFontOptions): Theme;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/** The five sizes. Two weights: 400, and 500 for titles and emphasis. */
|
|
2
|
+
export declare const TYPE: readonly [{
|
|
3
|
+
readonly role: "heading";
|
|
4
|
+
readonly size: 20;
|
|
5
|
+
readonly leading: 28;
|
|
6
|
+
readonly weight: 500;
|
|
7
|
+
readonly use: "A page's title";
|
|
8
|
+
}, {
|
|
9
|
+
readonly role: "title";
|
|
10
|
+
readonly size: 16;
|
|
11
|
+
readonly leading: 24;
|
|
12
|
+
readonly weight: 500;
|
|
13
|
+
readonly use: "A section's title, under its kicker";
|
|
14
|
+
}, {
|
|
15
|
+
readonly role: "body";
|
|
16
|
+
readonly size: 13;
|
|
17
|
+
readonly leading: 20;
|
|
18
|
+
readonly weight: 400;
|
|
19
|
+
readonly use: "Prose, step and option titles (500), rows, values";
|
|
20
|
+
}, {
|
|
21
|
+
readonly role: "label";
|
|
22
|
+
readonly size: 12;
|
|
23
|
+
readonly leading: 16;
|
|
24
|
+
readonly weight: 400;
|
|
25
|
+
readonly use: "Mono inside body text: code, paths, evidence chips";
|
|
26
|
+
}, {
|
|
27
|
+
readonly role: "small";
|
|
28
|
+
readonly size: 11;
|
|
29
|
+
readonly leading: 16;
|
|
30
|
+
readonly weight: 400;
|
|
31
|
+
readonly use: "Meta, terms, kickers, controls, keys, times";
|
|
32
|
+
}];
|
|
33
|
+
export type TypeRole = (typeof TYPE)[number]["role"];
|
|
34
|
+
/**
|
|
35
|
+
* Tracking follows size, one rule for every element: (body − size) × 0.03, so 20 px closes up by
|
|
36
|
+
* 0.21 px, 16 px by 0.09, 13 px sits at 0 and 11 px opens by 0.06. Mono never tracks.
|
|
37
|
+
*/
|
|
38
|
+
export declare const TRACKING = 0.03;
|
|
39
|
+
export declare const trackingAt: (size: number, body?: number) => number;
|
|
40
|
+
/** Prose stops here: 45–75 characters, centred on 66. */
|
|
41
|
+
export declare const MEASURE = "66ch";
|
|
42
|
+
/**
|
|
43
|
+
* The type stack: the platform's own UI face (SF Pro with its optical sizes on Apple, Segoe UI
|
|
44
|
+
* Variable on Windows), so nothing downloads, nothing swaps in, and the pages read like the native
|
|
45
|
+
* apps beside them. A webfont goes in through `reviewFont`.
|
|
46
|
+
*/
|
|
47
|
+
export declare const FONT: {
|
|
48
|
+
readonly sans: "system-ui,-apple-system,BlinkMacSystemFont,\"Segoe UI Variable Text\",\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif";
|
|
49
|
+
readonly mono: "ui-monospace,\"SF Mono\",SFMono-Regular,\"Cascadia Mono\",\"JetBrains Mono\",Menlo,Consolas,monospace";
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* OpenType: tabular figures everywhere (times and counts never jitter); in data, `ss01` too
|
|
53
|
+
* (straight-sided 6 and 9 in SF, open digits in Inter: figures that can't be misread); code with
|
|
54
|
+
* no ligatures (`=>` stays two characters).
|
|
55
|
+
*/
|
|
56
|
+
export declare const FEATURES: {
|
|
57
|
+
readonly figures: "tabular-nums";
|
|
58
|
+
readonly data: "\"tnum\" 1,\"ss01\" 1";
|
|
59
|
+
readonly code: "none";
|
|
60
|
+
};
|
|
61
|
+
/** The space roles (px, on the 4 px unit); each from `title` up at least doubles the one below. */
|
|
62
|
+
export declare const SPACE: readonly [{
|
|
63
|
+
readonly role: "inside";
|
|
64
|
+
readonly px: 4;
|
|
65
|
+
readonly use: "Parts of one thing: an icon and its label, a term and its value";
|
|
66
|
+
}, {
|
|
67
|
+
readonly role: "sibling";
|
|
68
|
+
readonly px: 8;
|
|
69
|
+
readonly use: "Siblings in a group: rows, buttons, a list's lines";
|
|
70
|
+
}, {
|
|
71
|
+
readonly role: "title";
|
|
72
|
+
readonly px: 12;
|
|
73
|
+
readonly use: "A heading and what it heads";
|
|
74
|
+
}, {
|
|
75
|
+
readonly role: "block";
|
|
76
|
+
readonly px: 24;
|
|
77
|
+
readonly use: "Blocks inside one piece: fact groups, columns, media and its caption";
|
|
78
|
+
}, {
|
|
79
|
+
readonly role: "group";
|
|
80
|
+
readonly px: 48;
|
|
81
|
+
readonly use: "Steps and options, a hairline in the middle";
|
|
82
|
+
}, {
|
|
83
|
+
readonly role: "section";
|
|
84
|
+
readonly px: 96;
|
|
85
|
+
readonly use: "Sections of a page, a hairline in the middle";
|
|
86
|
+
}];
|
|
87
|
+
/** Hairlines and fills: alpha of the text colour, held to an APCA target on the page. */
|
|
88
|
+
export declare const HAIRLINES: readonly [{
|
|
89
|
+
readonly token: "border-subtle";
|
|
90
|
+
readonly lc: 9;
|
|
91
|
+
readonly use: "Dividers between rows, steps and sections";
|
|
92
|
+
}, {
|
|
93
|
+
readonly token: "border";
|
|
94
|
+
readonly lc: 12;
|
|
95
|
+
readonly use: "Rings round frames and wells";
|
|
96
|
+
}, {
|
|
97
|
+
readonly token: "border-strong";
|
|
98
|
+
readonly lc: 17;
|
|
99
|
+
readonly use: "Interactive edges, a focus that isn't the accent";
|
|
100
|
+
}];
|
|
101
|
+
export declare const FILLS: readonly [{
|
|
102
|
+
readonly token: "fill";
|
|
103
|
+
readonly use: "A well at rest: code, a chip, a frame loading";
|
|
104
|
+
}, {
|
|
105
|
+
readonly token: "fill-hover";
|
|
106
|
+
readonly use: "Under the pointer, at once";
|
|
107
|
+
}, {
|
|
108
|
+
readonly token: "fill-selected";
|
|
109
|
+
readonly use: "The selection pill, a pressed toggle";
|
|
110
|
+
}];
|
|
111
|
+
/** Radii, concentric: what sits inside a frame takes the frame's radius less the gap between. */
|
|
112
|
+
export declare const RADII: readonly [{
|
|
113
|
+
readonly token: "radius";
|
|
114
|
+
readonly px: 8;
|
|
115
|
+
readonly use: "Controls and rows 28–32 px high";
|
|
116
|
+
}, {
|
|
117
|
+
readonly token: "radius-panel";
|
|
118
|
+
readonly px: 12;
|
|
119
|
+
readonly use: "Frames, wells, cards";
|
|
120
|
+
}, {
|
|
121
|
+
readonly token: "radius / 2";
|
|
122
|
+
readonly px: 4;
|
|
123
|
+
readonly use: "Inline code, chips, rows 20 px high";
|
|
124
|
+
}];
|
|
125
|
+
/**
|
|
126
|
+
* The motion set. Springs are a duration and no bounce; nothing moves on load; hovers land at once
|
|
127
|
+
* and ease out; a whole thing replaced in place fades with a 3 px blur.
|
|
128
|
+
*/
|
|
129
|
+
export declare const MOTION: readonly [{
|
|
130
|
+
readonly name: "hover";
|
|
131
|
+
readonly spring: null;
|
|
132
|
+
readonly ms: "0 in, 120 out";
|
|
133
|
+
readonly use: "A hover's fill: on at once, off softly";
|
|
134
|
+
}, {
|
|
135
|
+
readonly name: "quick";
|
|
136
|
+
readonly spring: import("../index.js").SpringValue;
|
|
137
|
+
readonly use: "Replacing a whole thing in place: fade, scale .98, blur 3 px";
|
|
138
|
+
}, {
|
|
139
|
+
readonly name: "close";
|
|
140
|
+
readonly spring: import("../index.js").SpringValue;
|
|
141
|
+
readonly use: "A popover closing";
|
|
142
|
+
}, {
|
|
143
|
+
readonly name: "snappy";
|
|
144
|
+
readonly spring: {
|
|
145
|
+
readonly duration: 0.25;
|
|
146
|
+
readonly bounce: 0;
|
|
147
|
+
};
|
|
148
|
+
readonly use: "Controls: a toggle, a pick, a chapter row";
|
|
149
|
+
}, {
|
|
150
|
+
readonly name: "state";
|
|
151
|
+
readonly spring: {
|
|
152
|
+
readonly duration: 0.3;
|
|
153
|
+
readonly bounce: 0;
|
|
154
|
+
};
|
|
155
|
+
readonly use: "The selection pill, a disclosure opening";
|
|
156
|
+
}, {
|
|
157
|
+
readonly name: "calm";
|
|
158
|
+
readonly spring: {
|
|
159
|
+
readonly duration: 0.4;
|
|
160
|
+
readonly bounce: 0;
|
|
161
|
+
};
|
|
162
|
+
readonly use: "Layout: a compare's height, the page scrolling to a step";
|
|
163
|
+
}, {
|
|
164
|
+
readonly name: "smooth";
|
|
165
|
+
readonly spring: {
|
|
166
|
+
readonly duration: 0.45;
|
|
167
|
+
readonly bounce: 0;
|
|
168
|
+
};
|
|
169
|
+
readonly use: "A step opening to the full window";
|
|
170
|
+
}];
|
|
171
|
+
/**
|
|
172
|
+
* The foundations as private tokens on every review root; the review stylesheet reads them.
|
|
173
|
+
* Tracking is a calc in em, so it resolves on each element at its own size.
|
|
174
|
+
*/
|
|
175
|
+
export declare const foundationCss: string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { FEATURES, FILLS, FONT, HAIRLINES, MEASURE, MOTION, RADII, SPACE, TRACKING, TYPE, trackingAt, type TypeRole, } from "./foundations.js";
|
|
2
|
+
export { reviewFont, type ReviewFontOptions } from "./font.js";
|
|
3
|
+
export { reviewTheme } from "../themes/review.js";
|
|
4
|
+
export { injectUiStyles, restyle, type RestyleLook, type UiLook } from "../ui/look.js";
|
|
5
|
+
export { tasteTest, walkthrough, type TasteTest, type TasteTestOptions, type Walkthrough, type WalkthroughOptions, } from "../ui/walkthrough.js";
|
|
6
|
+
export { decision, facts, mediaSlot, type DecisionOptions, type FactsOptions, type MediaSlot, type MediaSlotOptions, type StepLinks, } from "../ui/walkthrough-media.js";
|
|
7
|
+
export { compare, type Compare, type CompareLoop, type CompareMode, type CompareOptions, type CompareSource, type CompareView, type ZoomRegion, } from "../ui/compare.js";
|
|
8
|
+
export { compareStrip, type CompareStrip, type CompareStripOptions } from "../ui/compare-strip.js";
|
|
9
|
+
export { player, type Player, type PlayerChapter, type PlayerOptions } from "../ui/player.js";
|
|
10
|
+
export { codeDiff, diffReview, type CodeDiff, type CodeDiffOptions, type CodeDiffUpdate, type DiffLayout, type DiffReview, type DiffReviewOptions, } from "../ui/diff.js";
|
|
11
|
+
export type { DiffSource } from "../ui/diff-model.js";
|
|
12
|
+
export { history, type History, type HistoryBand, type HistoryData, type HistoryEvent, type HistoryEvidence, type HistoryGroup, type HistoryLane, type HistoryOptions, type HistoryProvenance, type HistorySpan, type HistoryState, type HistoryTone, } from "../ui/history.js";
|
|
13
|
+
export { collectFeedback, feedbackMarkdown, inlineMarkdown, normalizeWalkthrough, plainMarkdown, readState as readWalkthroughState, walkthroughProgress, type FeedbackItem, type FeedbackNote, type WalkPage, type WalkStep, type WalkthroughAnnotation, type WalkthroughChapter, type WalkthroughDecisionOption, type WalkthroughFact, type WalkthroughFactGroup, type WalkthroughFacts, type WalkthroughDoc, type WalkthroughEvidence, type WalkthroughFeedback, type WalkthroughHistoryEvent, type WalkthroughHistoryGroup, type WalkthroughMedia, type WalkthroughMeta, type WalkthroughOption, type WalkthroughPR, type WalkthroughQA, type WalkthroughSection, type WalkthroughSource, type WalkthroughStackItem, type WalkthroughState, type WalkthroughStatus, type WalkthroughStep, type WalkthroughTableCell, type WalkthroughTableColumn, type WalkthroughTableRow, type WalkthroughTone, type WalkthroughUpdate, } from "../ui/walkthrough-model.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CodeDiff, Compare, CompareStrip, DiffReview, MediaSlot, TasteTest, Walkthrough, type CodeDiffProps, type CompareProps, type CompareStripProps, type DiffReviewProps, type MediaSlotProps, type TasteTestProps, type WalkthroughDoc, type WalkthroughFeedback, type WalkthroughProps, } from "../ui/react.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CodeDiff, Compare, CompareStrip, DiffReview, MediaSlot, TasteTest, Walkthrough, type CodeDiffProps, type CompareProps, type CompareStripProps, type DiffReviewProps, type MediaSlotProps, type TasteTestProps, type WalkthroughDoc, type WalkthroughFeedback, type WalkthroughProps, } from "../ui/solid.js";
|