@kitlangton/knobs 0.1.0 → 0.2.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.
Files changed (48) hide show
  1. package/README.md +174 -30
  2. package/dist/dev/{chunk-e13znr7c.js → chunk-4km87zfx.js} +3 -3
  3. package/dist/dev/{chunk-ktsn42p7.js → chunk-5cr85vv6.js} +7448 -5390
  4. package/dist/dev/{chunk-kdewv0mt.js → chunk-693jd1gj.js} +171 -70
  5. package/dist/dev/{chunk-qtt698hp.js → chunk-gezhc24g.js} +21 -7
  6. package/dist/dev/index.js +377 -106
  7. package/dist/index.js +392 -108
  8. package/dist/panel.js +9518 -6749
  9. package/dist/types/core/random.d.ts +61 -1
  10. package/dist/types/core/remote.d.ts +3 -1
  11. package/dist/types/core/schema.d.ts +30 -6
  12. package/dist/types/core/store.d.ts +68 -6
  13. package/dist/types/core/variants.d.ts +10 -2
  14. package/dist/types/index.d.ts +3 -2
  15. package/dist/types/panel/editors.d.ts +11 -0
  16. package/dist/types/panel/flash.d.ts +13 -0
  17. package/dist/types/panel/gpu/renderer.d.ts +78 -6
  18. package/dist/types/panel/haptics.d.ts +6 -2
  19. package/dist/types/panel/has.d.ts +0 -1
  20. package/dist/types/panel/index.d.ts +1 -0
  21. package/dist/types/panel/inspector.d.ts +32 -2
  22. package/dist/types/panel/optkeys.d.ts +7 -0
  23. package/dist/types/panel/presets.d.ts +17 -5
  24. package/dist/types/panel/ramp-morph.d.ts +117 -0
  25. package/dist/types/panel/ramps.d.ts +1 -1
  26. package/dist/types/panel/reel.d.ts +43 -0
  27. package/dist/types/panel/scope.d.ts +19 -0
  28. package/dist/types/panel/slider.d.ts +1 -1
  29. package/dist/types/panel/sound.d.ts +137 -0
  30. package/dist/types/panel/styles.d.ts +1 -1
  31. package/dist/types/panel/toolbar-grid.d.ts +6 -0
  32. package/dist/types/ui/activity-css.d.ts +1 -0
  33. package/dist/types/ui/activity-model.d.ts +122 -0
  34. package/dist/types/ui/activity.d.ts +67 -0
  35. package/dist/types/ui/follow.d.ts +17 -0
  36. package/dist/types/ui/index.d.ts +5 -1
  37. package/dist/types/ui/look.d.ts +9 -0
  38. package/dist/types/ui/picker-css.d.ts +1 -0
  39. package/dist/types/ui/picker-model.d.ts +53 -0
  40. package/dist/types/ui/picker.d.ts +67 -0
  41. package/dist/types/ui/react.d.ts +27 -0
  42. package/dist/types/ui/solid.d.ts +23 -0
  43. package/dist/types/ui/split-model.d.ts +54 -0
  44. package/dist/types/ui/split.d.ts +17 -0
  45. package/dist/ui-react.js +3239 -567
  46. package/dist/ui-solid.js +3123 -472
  47. package/dist/ui.js +2688 -100
  48. package/package.json +1 -1
@@ -0,0 +1,53 @@
1
+ /** The option a digit names: 1–9 pick the first nine, as they read; past the last, none. */
2
+ export declare function digitPick(ids: readonly string[], key: string): string | undefined;
3
+ /** ↑/↓ (and Home/End) from `current`, stopping at the ends. */
4
+ export declare function stepPick(ids: readonly string[], current: string | null, key: "ArrowUp" | "ArrowDown" | "Home" | "End"): string | undefined;
5
+ /**
6
+ * The selection after the options change: the option a host asked for before it was there
7
+ * (`wanted`) once it comes, else the selection while its option stays, else the first.
8
+ */
9
+ export declare function keepPick(ids: readonly string[], selected: string | null, wanted?: string | null): string | null;
10
+ /**
11
+ * A host's `select(id)`: picked now if its option is there; if not, remembered (`wanted`) for
12
+ * the `set()` that brings it, so the order a host's updates land in can't lose it. A later
13
+ * select replaces what was wanted.
14
+ */
15
+ export declare function askPick(ids: readonly string[], id: string): {
16
+ pick: string | undefined;
17
+ wanted: string | null;
18
+ };
19
+ /** What's still wanted after the options change: nothing once its option has come. */
20
+ export declare const stillWanted: (ids: readonly string[], wanted: string | null) => string | null;
21
+ /** The number an option shows: its place, 1, 2, … 12 (only 1–9 are keys that pick). */
22
+ export declare const pickDigit: (index: number) => string;
23
+ /**
24
+ * Whether a key event goes to the picker's digits: a bare 1–9 that nothing focused claimed (a
25
+ * panel row picking its own options, a text field) and that isn't typed into a field.
26
+ */
27
+ export declare function claimsDigit(event: {
28
+ readonly key: string;
29
+ readonly defaultPrevented: boolean;
30
+ readonly metaKey: boolean;
31
+ readonly ctrlKey: boolean;
32
+ readonly altKey: boolean;
33
+ readonly shiftKey: boolean;
34
+ readonly repeat: boolean;
35
+ readonly typing?: boolean;
36
+ }, typing?: boolean): boolean;
37
+ /**
38
+ * Where the card comes to rest on the option at `index`: below the options before it with their
39
+ * bodies shut (once a change settles only the selected option's is open), as tall as its head
40
+ * and its body. The card aims here from the start, rather than chasing the option's top while
41
+ * the last option's body closes above it. With the body not yet measured (a panel mounting for
42
+ * the first time) there's no target yet, and the card holds where it is.
43
+ */
44
+ export declare function cardTarget(heads: readonly number[], index: number, body: number | undefined, gap?: number, top?: number): {
45
+ y: number;
46
+ h: number;
47
+ } | null;
48
+ /**
49
+ * A first-mounted body's height once it has settled: the same reading two frames running, or
50
+ * whatever it reads after `limit` frames (content that never settles doesn't hold the change
51
+ * up). Until then undefined: it's still laying out.
52
+ */
53
+ export declare function settleHeight(previous: number | undefined, now: number, frames: number, limit?: number): number | undefined;
@@ -0,0 +1,67 @@
1
+ import { type UiLook } from "./look.js";
2
+ export interface PickerOption {
3
+ readonly id: string;
4
+ readonly label: string;
5
+ /** Marked "Suggested". */
6
+ readonly suggested?: boolean;
7
+ /**
8
+ * A picture of it (an image URL), small between the number and the name. It loads lazily and
9
+ * fades in once loaded; while loading, or if it fails, nothing is drawn.
10
+ */
11
+ readonly thumb?: string;
12
+ }
13
+ export interface OptionPickerOptions extends UiLook {
14
+ readonly options: readonly PickerOption[];
15
+ /** The option on show, its parameters open under it; the first unless set. */
16
+ readonly selected?: string | null;
17
+ /** The option decided on: it takes a check. */
18
+ readonly chosen?: string | null;
19
+ /** Keys, digits and clicks moved the selection (a host's `select()` doesn't call it). */
20
+ readonly onSelect?: (id: string, source: "key" | "digit" | "pointer") => void;
21
+ /** Enter on an option. */
22
+ readonly onChoose?: (id: string) => void;
23
+ /**
24
+ * Mounts an option's parameters into `element` the first time it opens (a knobs panel, say);
25
+ * return a cleanup for when the option goes or the picker is destroyed. It stays mounted
26
+ * while closed, so a panel keeps its state.
27
+ */
28
+ readonly body?: (option: PickerOption, element: HTMLElement) => (() => void) | void;
29
+ /**
30
+ * Where 1–9 pick from: `"focus"` (the default) while focus is in the picker, its panels
31
+ * included, `"page"` from anywhere, or `false`. A focused row that picks its own options with
32
+ * digits, and text fields, keep them.
33
+ */
34
+ readonly digits?: "focus" | "page" | false;
35
+ /** The accessible name. */
36
+ readonly label?: string;
37
+ /** The suggested mark's words ("Suggested"). */
38
+ readonly suggestedLabel?: string;
39
+ }
40
+ export interface OptionPicker {
41
+ readonly element: HTMLElement;
42
+ /**
43
+ * New options: the selection stays on its option while that's still there, or goes to one
44
+ * `select()` asked for before it was there.
45
+ */
46
+ set(options: readonly PickerOption[]): void;
47
+ /**
48
+ * Opens this option's parameters (closing the last one's). Doesn't call `onSelect`. An id that
49
+ * isn't there yet is remembered, and picked when `set()` brings it.
50
+ */
51
+ select(id: string): void;
52
+ readonly selected: string | null;
53
+ /** Marks the chosen option (`null` for none). */
54
+ choose(id: string | null): void;
55
+ readonly chosen: string | null;
56
+ /** Focuses the selected option. */
57
+ focus(): void;
58
+ destroy(): void;
59
+ dispose(): void;
60
+ }
61
+ /**
62
+ * A column of options (1–n), each with a name, a "Suggested" mark and a check on the chosen one.
63
+ * The selected option sits on a card that glides between options, and its parameters (what
64
+ * `body` mounts, a knobs panel's rows) open under it in place while the last option's close.
65
+ * ↑/↓, Home/End and 1–9 pick; Enter chooses; Tab goes into the parameters.
66
+ */
67
+ export declare function optionPicker(container: HTMLElement, options: OptionPickerOptions): OptionPicker;
@@ -1,5 +1,7 @@
1
1
  import { type CSSProperties, type ReactNode } from "react";
2
+ import { type Activity as ActivityHandle, type ActivityOptions } from "./activity.js";
2
3
  import { type Bento as BentoHandle, type BentoOptions } from "./bento.js";
4
+ import { type OptionPicker as OptionPickerHandle, type OptionPickerOptions, type PickerOption } from "./picker.js";
3
5
  import { type Split as SplitHandle, type SplitOptions } from "./split.js";
4
6
  import { type Timeline as TimelineHandle, type TimelineOptions } from "./timeline.js";
5
7
  import { type Tree as TreeHandle, type TreeOptions } from "./tree.js";
@@ -43,3 +45,28 @@ export type BentoProps = BentoOptions & {
43
45
  * prop; callbacks always call the latest props.
44
46
  */
45
47
  export declare function Bento(props: BentoProps): import("react").JSX.Element;
48
+ export type ActivityProps = ActivityOptions & {
49
+ className?: string;
50
+ style?: CSSProperties;
51
+ onReady?: (activity: ActivityHandle) => void;
52
+ };
53
+ /**
54
+ * `activity()` as a component. New `events` update it in place (rows keep their identity and
55
+ * glide); `selected` follows its prop; callbacks always call the latest props.
56
+ */
57
+ export declare function Activity(props: ActivityProps): import("react").JSX.Element;
58
+ export type OptionPickerProps = Omit<OptionPickerOptions, "body"> & {
59
+ /** An option's parameters, portalled under it the first time it opens (a `<Knobs>` panel, say). */
60
+ children?: (option: PickerOption) => ReactNode;
61
+ className?: string;
62
+ style?: CSSProperties;
63
+ onReady?: (picker: OptionPickerHandle) => void;
64
+ };
65
+ /**
66
+ * `optionPicker()` as a component: `children` renders each opened option's parameters into its
67
+ * place through a portal, so context and state carry through. `options`, `selected` and
68
+ * `chosen` follow their props; callbacks always call the latest props.
69
+ */
70
+ export declare function OptionPicker(props: OptionPickerProps): import("react").JSX.Element;
71
+ export type { ActivityEvent } from "./activity-model.js";
72
+ export type { PickerOption } from "./picker.js";
@@ -1,5 +1,7 @@
1
1
  import { type JSX } from "solid-js";
2
+ import { type Activity as ActivityHandle, type ActivityOptions } from "./activity.js";
2
3
  import { type Bento as BentoHandle, type BentoOptions } from "./bento.js";
4
+ import { type OptionPicker as OptionPickerHandle, type OptionPickerOptions, type PickerOption } from "./picker.js";
3
5
  import { type Split as SplitHandle, type SplitOptions } from "./split.js";
4
6
  import { type Timeline as TimelineHandle, type TimelineOptions } from "./timeline.js";
5
7
  import { type Tree as TreeHandle, type TreeOptions } from "./tree.js";
@@ -38,3 +40,24 @@ export type BentoProps = BentoOptions & {
38
40
  * prop; callbacks always call the latest props.
39
41
  */
40
42
  export declare function Bento(props: BentoProps): JSX.Element;
43
+ export type ActivityProps = ActivityOptions & {
44
+ onReady?: (activity: ActivityHandle) => void;
45
+ };
46
+ /**
47
+ * `activity()` as a component. New `events` update it in place (rows keep their identity and
48
+ * glide); `selected` follows its prop; callbacks always call the latest props.
49
+ */
50
+ export declare function Activity(props: ActivityProps): JSX.Element;
51
+ export type OptionPickerProps = Omit<OptionPickerOptions, "body"> & {
52
+ /** An option's parameters, rendered once, the first time it opens (a `KnobsPanel`, say). */
53
+ children?: (option: PickerOption) => JSX.Element;
54
+ onReady?: (picker: OptionPickerHandle) => void;
55
+ };
56
+ /**
57
+ * `optionPicker()` as a component: `children` renders an option's parameters under it, in this
58
+ * component's context. `options`, `selected` and `chosen` follow their props; callbacks always
59
+ * call the latest props.
60
+ */
61
+ export declare function OptionPicker(props: OptionPickerProps): JSX.Element;
62
+ export type { ActivityEvent } from "./activity-model.js";
63
+ export type { PickerOption } from "./picker.js";
@@ -75,6 +75,60 @@ export declare function collapsibleSide(panes: readonly PaneSpec[], index: numbe
75
75
  * the rest to the end.
76
76
  */
77
77
  export declare function edgeOf(panes: readonly PaneSpec[], id: string): "start" | "end";
78
+ /** How far a folding pane is from its open size (0) to its rail (1), by the size it shows. */
79
+ export declare function foldProgress(size: number, open: number, rail: number): number;
80
+ /** How much of each face a folding pane shows (0…1): its content, open, and its rail, folded. */
81
+ export interface FoldFaces {
82
+ readonly content: number;
83
+ readonly rail: number;
84
+ }
85
+ /** A face that's leaving is gone by this far along the fold. */
86
+ export declare const FACE_OUT = 0.4;
87
+ /** A face that's arriving shows only over this last part of the fold. */
88
+ export declare const FACE_IN = 0.3;
89
+ /**
90
+ * The faces at fold progress `p`, from the last frame's. The content and the rail never show
91
+ * together: the content is gone before 40% and the rail starts past 70% (folding or opening).
92
+ */
93
+ export declare function foldFaces(prev: FoldFaces, p: number): FoldFaces;
94
+ /**
95
+ * The fold's chevron turn (degrees) at progress `p`: half a turn from the open pane's chevron to
96
+ * the rail's, rolling the way the pane's edge travels.
97
+ */
98
+ export declare function chevronTurn(p: number, edge: "start" | "end"): number;
99
+ /**
100
+ * The fold's chevron, flipping: its width (scaleX) against the rail's chevron at flip progress
101
+ * `f` (0 open, 1 folded). The arms close in to a flat line halfway and open out the other way.
102
+ */
103
+ export declare function chevronFlip(f: number): number;
104
+ /** How a pane folds: see `SplitOptions.fold`. */
105
+ export interface FoldStyle {
106
+ readonly chevron: "flip" | "turn";
107
+ readonly title: "travel" | "fade";
108
+ /** Seconds, on a spring with no bounce. */
109
+ readonly duration: number;
110
+ }
111
+ export declare const FOLD_STYLE: FoldStyle;
112
+ export declare function foldStyle(options?: Partial<FoldStyle>): FoldStyle;
113
+ /**
114
+ * Where a header's title and the rail's label sit, each from its own box's start edge and the
115
+ * pane's top (`dy` is the title's height less the label's), as measured with the pane open.
116
+ */
117
+ export interface TitlePlaces {
118
+ readonly title: number;
119
+ readonly label: number;
120
+ readonly dy: number;
121
+ }
122
+ /**
123
+ * The rail's label travelling as the header's title, at fold progress `p`: the offset that puts it
124
+ * on the title (the rail holds on to the pane's moving edge, the header to the inner content that
125
+ * keeps its open size), and its turn from upright (-90°) to the rail's vertical (0°).
126
+ */
127
+ export declare function titleTravel(at: TitlePlaces, open: number, rail: number, edge: "start" | "end", p: number): {
128
+ x: number;
129
+ y: number;
130
+ turn: number;
131
+ };
78
132
  /** A saved layout, kept only where it names known panes with sane values. */
79
133
  export declare function parseLayout(raw: unknown, panes: readonly PaneSpec[]): SplitLayout | undefined;
80
134
  /** A layout as saved: sizes rounded to a tenth of a pixel. */
@@ -39,6 +39,23 @@ export interface SplitOptions extends UiLook {
39
39
  * hint mode (`s`), on by default; a code presses its button.
40
40
  */
41
41
  readonly hints?: boolean;
42
+ /** How collapsible panes fold to their rails and open again. */
43
+ readonly fold?: SplitFold;
44
+ }
45
+ /** How a pane folds (each part has a default). */
46
+ export interface SplitFold {
47
+ /**
48
+ * The collapse chevron: `"flip"` (default) closes it to a flat line and opens it the other way,
49
+ * quickly, on its own snappy spring; `"turn"` spins it half a turn with the fold.
50
+ */
51
+ readonly chevron?: "flip" | "turn";
52
+ /**
53
+ * The header's title: `"travel"` (default) turns it and slides it into the rail's label, one
54
+ * element all the way; `"fade"` fades it out with the header as the rail's label fades in.
55
+ */
56
+ readonly title?: "travel" | "fade";
57
+ /** The fold's spring, in seconds (no bounce): 0.3 unless set. */
58
+ readonly duration?: number;
42
59
  }
43
60
  export interface SplitPane {
44
61
  readonly id: string;