@peasant-labs/fairtrade 0.0.1 → 0.0.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/dist/lib/base.css +48 -0
- package/dist/lib/components.css +2 -0
- package/dist/lib/fonts.css +28 -0
- package/dist/lib/icons.js +1 -0
- package/dist/lib/tokens.css +184 -0
- package/dist/lib/tokens.json +768 -0
- package/dist/lib/types/Accordion.d.ts +47 -0
- package/dist/lib/types/Avatar.d.ts +94 -0
- package/dist/lib/types/BrandMark.d.ts +25 -0
- package/dist/lib/types/Breadcrumb.d.ts +66 -0
- package/dist/lib/types/Button.d.ts +86 -0
- package/dist/lib/types/Card.d.ts +145 -0
- package/dist/lib/types/ChartBar.d.ts +51 -0
- package/dist/lib/types/ChartLine.d.ts +54 -0
- package/dist/lib/types/Checkbox.d.ts +132 -0
- package/dist/lib/types/Chip.d.ts +85 -0
- package/dist/lib/types/CliOnboard.d.ts +68 -0
- package/dist/lib/types/CommandPalette.d.ts +6 -0
- package/dist/lib/types/CommitGraph.d.ts +71 -0
- package/dist/lib/types/ConnectionState.d.ts +82 -0
- package/dist/lib/types/ConsentDialog.d.ts +97 -0
- package/dist/lib/types/DataTable.d.ts +116 -0
- package/dist/lib/types/DateRange.d.ts +242 -0
- package/dist/lib/types/Dialog.d.ts +9 -0
- package/dist/lib/types/DiffView.d.ts +39 -0
- package/dist/lib/types/EmptyState.d.ts +28 -0
- package/dist/lib/types/EvidenceCaption.d.ts +39 -0
- package/dist/lib/types/Explainer.d.ts +82 -0
- package/dist/lib/types/FacetRail.d.ts +13 -0
- package/dist/lib/types/Feedback.d.ts +222 -0
- package/dist/lib/types/GroupedMultiSelect.d.ts +67 -0
- package/dist/lib/types/Input.d.ts +158 -0
- package/dist/lib/types/Intensity.d.ts +55 -0
- package/dist/lib/types/MapCanvas.d.ts +89 -0
- package/dist/lib/types/Menu.d.ts +62 -0
- package/dist/lib/types/ModerationQueue.d.ts +135 -0
- package/dist/lib/types/Pager.d.ts +47 -0
- package/dist/lib/types/Pagination.d.ts +50 -0
- package/dist/lib/types/PolicySelect.d.ts +80 -0
- package/dist/lib/types/ProviderIcon.d.ts +84 -0
- package/dist/lib/types/RailShell.d.ts +199 -0
- package/dist/lib/types/Redaction.d.ts +53 -0
- package/dist/lib/types/RoleRoster.d.ts +97 -0
- package/dist/lib/types/SignIn.d.ts +78 -0
- package/dist/lib/types/Sparkline.d.ts +19 -0
- package/dist/lib/types/StatTiles.d.ts +118 -0
- package/dist/lib/types/StepWizard.d.ts +92 -0
- package/dist/lib/types/StepsWaterfall.d.ts +67 -0
- package/dist/lib/types/Switch.d.ts +63 -0
- package/dist/lib/types/Tabs.d.ts +48 -0
- package/dist/lib/types/TimeStrip.d.ts +12 -0
- package/dist/lib/types/Timeline.d.ts +192 -0
- package/dist/lib/types/ToastHost.d.ts +70 -0
- package/dist/lib/types/ToolRenderers.d.ts +24 -0
- package/dist/lib/types/Tooltip.d.ts +80 -0
- package/dist/lib/types/Tour.d.ts +37 -0
- package/dist/lib/types/TranscriptMarkers.d.ts +50 -0
- package/dist/lib/types/Treemap.d.ts +77 -0
- package/dist/lib/types/VisibilityControl.d.ts +54 -0
- package/dist/lib/types/chart-shared.d.ts +63 -0
- package/dist/lib/types/icons.d.ts +1 -0
- package/dist/lib/types/index.d.ts +53 -0
- package/dist/lib/ui.js +8736 -0
- package/package.json +6 -5
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A grouped tri-state multi-select tree. See GroupedMultiSelectProps.
|
|
3
|
+
* @param {GroupedMultiSelectProps} props
|
|
4
|
+
*/
|
|
5
|
+
export default function GroupedMultiSelect({ groups, value, defaultValue, onChange, tokenLabel, defaultOpen, ariaLabel, }: GroupedMultiSelectProps): any;
|
|
6
|
+
export type GMSItem = {
|
|
7
|
+
/**
|
|
8
|
+
* unique selection id (what lands in the value Set).
|
|
9
|
+
*/
|
|
10
|
+
id: string;
|
|
11
|
+
/**
|
|
12
|
+
* the item title — user content, rendered verbatim.
|
|
13
|
+
*/
|
|
14
|
+
label: any;
|
|
15
|
+
/**
|
|
16
|
+
* one-line secondary metadata (e.g. "42 turns · jun 3").
|
|
17
|
+
*/
|
|
18
|
+
meta?: any;
|
|
19
|
+
/**
|
|
20
|
+
* token count for the running tally; defaults to 0.
|
|
21
|
+
*/
|
|
22
|
+
tokens?: number;
|
|
23
|
+
};
|
|
24
|
+
export type GMSGroup = {
|
|
25
|
+
/**
|
|
26
|
+
* unique group id.
|
|
27
|
+
*/
|
|
28
|
+
id: string;
|
|
29
|
+
/**
|
|
30
|
+
* the group title — user content, rendered verbatim.
|
|
31
|
+
*/
|
|
32
|
+
label: any;
|
|
33
|
+
/**
|
|
34
|
+
* the group's selectable items.
|
|
35
|
+
*/
|
|
36
|
+
items: GMSItem[];
|
|
37
|
+
};
|
|
38
|
+
export type GroupedMultiSelectProps = {
|
|
39
|
+
/**
|
|
40
|
+
* the project-grouped tree to render.
|
|
41
|
+
*/
|
|
42
|
+
groups: GMSGroup[];
|
|
43
|
+
/**
|
|
44
|
+
* controlled set of selected item ids; pair with onChange.
|
|
45
|
+
*/
|
|
46
|
+
value?: Set<string>;
|
|
47
|
+
/**
|
|
48
|
+
* initial selection for uncontrolled use.
|
|
49
|
+
*/
|
|
50
|
+
defaultValue?: Set<string>;
|
|
51
|
+
/**
|
|
52
|
+
* called with the next selection Set on any toggle.
|
|
53
|
+
*/
|
|
54
|
+
onChange?: (next: Set<string>) => void;
|
|
55
|
+
/**
|
|
56
|
+
* noun for the tally (chrome, lowercased in display).
|
|
57
|
+
*/
|
|
58
|
+
tokenLabel?: string;
|
|
59
|
+
/**
|
|
60
|
+
* ids of groups expanded on first render (uncontrolled).
|
|
61
|
+
*/
|
|
62
|
+
defaultOpen?: string[];
|
|
63
|
+
/**
|
|
64
|
+
* accessible name for the tree container.
|
|
65
|
+
*/
|
|
66
|
+
ariaLabel?: string;
|
|
67
|
+
};
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field — the label + control + hint/error wrapper (.is-field) the inputs compose into.
|
|
3
|
+
* Renders the label above, the control (children) in the middle, and a hint (.is-hint) or, when
|
|
4
|
+
* `error` is a non-empty string, an error (.is-error with a TriangleAlert icon) below. Wires the
|
|
5
|
+
* label's htmlFor and the hint/error id to the control via the {id, describedBy, invalid}
|
|
6
|
+
* render-prop args so the standalone <Field> can be used with any control. The shipped Input /
|
|
7
|
+
* Textarea / Select use this internally, so most callers never touch Field directly.
|
|
8
|
+
*
|
|
9
|
+
* @param {Object} props
|
|
10
|
+
* @param {React.ReactNode} [props.label] - label text shown above the control. When `lock` is set it
|
|
11
|
+
* is wrapped in `.is-lk` with a leading icon.
|
|
12
|
+
* @param {React.ComponentType<{size?:number}>} [props.lock] - optional lucide icon (e.g. lock={Lock})
|
|
13
|
+
* rendered before the label inside `.is-lk` to flag a read-only/locked field.
|
|
14
|
+
* @param {string} [props.hint] - helper text rendered in `.is-hint` below the control (when no error).
|
|
15
|
+
* @param {string} [props.error] - error message; a non-empty string renders `.is-error` (TriangleAlert
|
|
16
|
+
* + message) instead of the hint and is announced via aria-describedby.
|
|
17
|
+
* @param {string} [props.id] - control id; auto-generated when omitted. Used for label htmlFor.
|
|
18
|
+
* @param {(args:{id:string,describedBy:string|undefined,invalid:boolean})=>React.ReactNode} props.children
|
|
19
|
+
* - render-prop receiving wiring ids; returns the control element.
|
|
20
|
+
* @returns {JSX.Element}
|
|
21
|
+
*/
|
|
22
|
+
export function Field({ label, lock: LockIcon, hint, error, id, children }: {
|
|
23
|
+
label?: React.ReactNode;
|
|
24
|
+
lock?: React.ComponentType<{
|
|
25
|
+
size?: number;
|
|
26
|
+
}>;
|
|
27
|
+
hint?: string;
|
|
28
|
+
error?: string;
|
|
29
|
+
id?: string;
|
|
30
|
+
children: (args: {
|
|
31
|
+
id: string;
|
|
32
|
+
describedBy: string | undefined;
|
|
33
|
+
invalid: boolean;
|
|
34
|
+
}) => React.ReactNode;
|
|
35
|
+
}): JSX.Element;
|
|
36
|
+
/**
|
|
37
|
+
* Input — a single-line text field with the full input-states wiring. When `iconLeft` is supplied the
|
|
38
|
+
* control sits inside an `.input-ico` wrapper (the icon is absolutely positioned, leaving room via the
|
|
39
|
+
* CSS padding). Error sets aria-invalid + the clay border via `.is-input[aria-invalid]` and links the
|
|
40
|
+
* message with aria-describedby. Supports controlled (`value` + `onChange`) and uncontrolled
|
|
41
|
+
* (`defaultValue`) use.
|
|
42
|
+
*
|
|
43
|
+
* Emits `<div class="is-field"><label class="label"/>[<div class="input-ico">]<input class="input is-input"/>[…]<span class="is-hint|is-error"/></div>`
|
|
44
|
+
* matching src/index.css with zero new CSS.
|
|
45
|
+
*
|
|
46
|
+
* @param {Object} props
|
|
47
|
+
* @param {React.ReactNode} [props.label] - label above the field.
|
|
48
|
+
* @param {React.ComponentType<{size?:number}>} [props.lock] - optional lucide icon shown beside the label (.is-lk).
|
|
49
|
+
* @param {string} [props.hint] - helper text under the field.
|
|
50
|
+
* @param {string} [props.error] - error message; non-empty marks the field invalid (aria-invalid, clay border, icon).
|
|
51
|
+
* @param {boolean} [props.invalid=false] - force the invalid border without a message (sets aria-invalid).
|
|
52
|
+
* @param {React.ComponentType<{size?:number}>} [props.iconLeft] - leading lucide icon component (wraps the input in .input-ico).
|
|
53
|
+
* @param {string} [props.type='text'] - native input type.
|
|
54
|
+
* @param {boolean} [props.readOnly=false] - native readonly (surface-2 fill, quiet, still selectable).
|
|
55
|
+
* @param {boolean} [props.disabled=false] - native disabled.
|
|
56
|
+
* @param {string|number} [props.value] - controlled value.
|
|
57
|
+
* @param {string|number} [props.defaultValue] - initial value for uncontrolled use.
|
|
58
|
+
* @param {(e:React.ChangeEvent<HTMLInputElement>)=>void} [props.onChange] - change handler.
|
|
59
|
+
* @param {string} [props.id] - input id; auto-generated + associated with the label when omitted.
|
|
60
|
+
* @returns {JSX.Element}
|
|
61
|
+
*/
|
|
62
|
+
export default function Input({ label, lock, hint, error, invalid, iconLeft: IconLeft, type, readOnly, disabled, value, defaultValue, onChange, id, ...rest }: {
|
|
63
|
+
label?: React.ReactNode;
|
|
64
|
+
lock?: React.ComponentType<{
|
|
65
|
+
size?: number;
|
|
66
|
+
}>;
|
|
67
|
+
hint?: string;
|
|
68
|
+
error?: string;
|
|
69
|
+
invalid?: boolean;
|
|
70
|
+
iconLeft?: React.ComponentType<{
|
|
71
|
+
size?: number;
|
|
72
|
+
}>;
|
|
73
|
+
type?: string;
|
|
74
|
+
readOnly?: boolean;
|
|
75
|
+
disabled?: boolean;
|
|
76
|
+
value?: string | number;
|
|
77
|
+
defaultValue?: string | number;
|
|
78
|
+
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
79
|
+
id?: string;
|
|
80
|
+
}): JSX.Element;
|
|
81
|
+
/**
|
|
82
|
+
* Textarea — the multi-line sibling of Input. Renders `textarea.input.is-input` (the CSS gives it an
|
|
83
|
+
* auto height with a min of one control row and vertical resize). Same label/hint/error and
|
|
84
|
+
* controlled/uncontrolled wiring as Input.
|
|
85
|
+
*
|
|
86
|
+
* @param {Object} props
|
|
87
|
+
* @param {React.ReactNode} [props.label] - label above the field.
|
|
88
|
+
* @param {React.ComponentType<{size?:number}>} [props.lock] - optional lucide icon beside the label (.is-lk).
|
|
89
|
+
* @param {string} [props.hint] - helper text under the field.
|
|
90
|
+
* @param {string} [props.error] - error message; non-empty marks the field invalid.
|
|
91
|
+
* @param {boolean} [props.invalid=false] - force the invalid border (sets aria-invalid).
|
|
92
|
+
* @param {number} [props.rows=3] - visible rows.
|
|
93
|
+
* @param {boolean} [props.readOnly=false] - native readonly.
|
|
94
|
+
* @param {boolean} [props.disabled=false] - native disabled.
|
|
95
|
+
* @param {string} [props.value] - controlled value.
|
|
96
|
+
* @param {string} [props.defaultValue] - initial value for uncontrolled use.
|
|
97
|
+
* @param {(e:React.ChangeEvent<HTMLTextAreaElement>)=>void} [props.onChange] - change handler.
|
|
98
|
+
* @param {string} [props.id] - id; auto-generated + associated with the label when omitted.
|
|
99
|
+
* @returns {JSX.Element}
|
|
100
|
+
*/
|
|
101
|
+
export function Textarea({ label, lock, hint, error, invalid, rows, readOnly, disabled, value, defaultValue, onChange, id, ...rest }: {
|
|
102
|
+
label?: React.ReactNode;
|
|
103
|
+
lock?: React.ComponentType<{
|
|
104
|
+
size?: number;
|
|
105
|
+
}>;
|
|
106
|
+
hint?: string;
|
|
107
|
+
error?: string;
|
|
108
|
+
invalid?: boolean;
|
|
109
|
+
rows?: number;
|
|
110
|
+
readOnly?: boolean;
|
|
111
|
+
disabled?: boolean;
|
|
112
|
+
value?: string;
|
|
113
|
+
defaultValue?: string;
|
|
114
|
+
onChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
115
|
+
id?: string;
|
|
116
|
+
}): JSX.Element;
|
|
117
|
+
/**
|
|
118
|
+
* Select — a styled native `<select>` inside a `.select-wrap` with a trailing ChevronDown (the chevron
|
|
119
|
+
* is decorative and ignores pointer events per the CSS). Pass options either as `children` (raw
|
|
120
|
+
* `<option>` elements) or an `options` array of {value,label}. Same label/hint/error +
|
|
121
|
+
* controlled/uncontrolled wiring as Input.
|
|
122
|
+
*
|
|
123
|
+
* Emits `<div class="is-field"><label/><div class="select-wrap"><select class="select"/>chevron</div>…</div>`.
|
|
124
|
+
*
|
|
125
|
+
* @param {Object} props
|
|
126
|
+
* @param {React.ReactNode} [props.label] - label above the field.
|
|
127
|
+
* @param {React.ComponentType<{size?:number}>} [props.lock] - optional lucide icon beside the label (.is-lk).
|
|
128
|
+
* @param {string} [props.hint] - helper text under the field.
|
|
129
|
+
* @param {string} [props.error] - error message; non-empty marks the field invalid.
|
|
130
|
+
* @param {boolean} [props.invalid=false] - force the invalid border (sets aria-invalid).
|
|
131
|
+
* @param {{value:string,label:string}[]} [props.options] - option list; alternative to passing <option> children.
|
|
132
|
+
* @param {React.ReactNode} [props.children] - raw <option> elements (used when `options` is omitted).
|
|
133
|
+
* @param {boolean} [props.disabled=false] - native disabled.
|
|
134
|
+
* @param {string} [props.value] - controlled value.
|
|
135
|
+
* @param {string} [props.defaultValue] - initial value for uncontrolled use.
|
|
136
|
+
* @param {(e:React.ChangeEvent<HTMLSelectElement>)=>void} [props.onChange] - change handler.
|
|
137
|
+
* @param {string} [props.id] - id; auto-generated + associated with the label when omitted.
|
|
138
|
+
* @returns {JSX.Element}
|
|
139
|
+
*/
|
|
140
|
+
export function Select({ label, lock, hint, error, invalid, options, children, disabled, value, defaultValue, onChange, id, ...rest }: {
|
|
141
|
+
label?: React.ReactNode;
|
|
142
|
+
lock?: React.ComponentType<{
|
|
143
|
+
size?: number;
|
|
144
|
+
}>;
|
|
145
|
+
hint?: string;
|
|
146
|
+
error?: string;
|
|
147
|
+
invalid?: boolean;
|
|
148
|
+
options?: {
|
|
149
|
+
value: string;
|
|
150
|
+
label: string;
|
|
151
|
+
}[];
|
|
152
|
+
children?: React.ReactNode;
|
|
153
|
+
disabled?: boolean;
|
|
154
|
+
value?: string;
|
|
155
|
+
defaultValue?: string;
|
|
156
|
+
onChange?: (e: React.ChangeEvent<HTMLSelectElement>) => void;
|
|
157
|
+
id?: string;
|
|
158
|
+
}): JSX.Element;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** clamp any number into the 0..4 ramp domain (integers only). */
|
|
2
|
+
export function clampLevel(level: any): number;
|
|
3
|
+
/**
|
|
4
|
+
* coverage ratio (recorded / total) → ramp level. 0 / unknown = none; ≥ 0.9
|
|
5
|
+
* reads as fully covered. mirrors peasant's traceabilityLevel quantiles.
|
|
6
|
+
*/
|
|
7
|
+
export function coverageLevel(recorded: any, total: any): 0 | 4 | 1 | 2 | 3;
|
|
8
|
+
/** density (0..1) → ramp level for the bottom-edge effort bar. */
|
|
9
|
+
export function effortLevel(density: any): 0 | 4 | 1 | 2 | 3;
|
|
10
|
+
/** generic value-vs-max quantization (heatmap cells, sparklines). */
|
|
11
|
+
export function quantize(value: any, max: any): 0 | 4 | 1 | 2 | 3;
|
|
12
|
+
/** loc → node size class. small files are compact; large ones get real estate. */
|
|
13
|
+
export function locSize(loc: any): "sm" | "md" | "lg" | "xs" | "xl";
|
|
14
|
+
export function IntensitySwatch({ level, accent, size, label, className, ...rest }: {
|
|
15
|
+
[x: string]: any;
|
|
16
|
+
level?: number;
|
|
17
|
+
accent: any;
|
|
18
|
+
size: any;
|
|
19
|
+
label: any;
|
|
20
|
+
className?: string;
|
|
21
|
+
}): any;
|
|
22
|
+
export function RampLegend({ title, words, className }: {
|
|
23
|
+
title?: string;
|
|
24
|
+
words?: string[];
|
|
25
|
+
className?: string;
|
|
26
|
+
}): any;
|
|
27
|
+
export function Heatmap({ values, levels, max, labels, ariaLabel, className }: {
|
|
28
|
+
values: any;
|
|
29
|
+
levels: any;
|
|
30
|
+
max: any;
|
|
31
|
+
labels: any;
|
|
32
|
+
ariaLabel?: string;
|
|
33
|
+
className?: string;
|
|
34
|
+
}): any;
|
|
35
|
+
export function MapNode({ label, loc, coverage, recorded, total, selected, violation, effortPct, size, as, onClick, className, ...rest }: {
|
|
36
|
+
[x: string]: any;
|
|
37
|
+
label: any;
|
|
38
|
+
loc: any;
|
|
39
|
+
coverage?: number;
|
|
40
|
+
recorded: any;
|
|
41
|
+
total: any;
|
|
42
|
+
selected?: boolean;
|
|
43
|
+
violation?: number;
|
|
44
|
+
effortPct: any;
|
|
45
|
+
size: any;
|
|
46
|
+
as?: string;
|
|
47
|
+
onClick: any;
|
|
48
|
+
className?: string;
|
|
49
|
+
}): any;
|
|
50
|
+
export function IntensityScope({ children, className, ...rest }: {
|
|
51
|
+
[x: string]: any;
|
|
52
|
+
children: any;
|
|
53
|
+
className?: string;
|
|
54
|
+
}): any;
|
|
55
|
+
export default MapNode;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} MapNode
|
|
3
|
+
* @property {string} id stable key (repo-relative path)
|
|
4
|
+
* @property {string} label display label (leaf of a path is shown)
|
|
5
|
+
* @property {'folder'|'file'} kind folder vs file — distinguished by ICON
|
|
6
|
+
* @property {number} [loc=0] lines of code — node WIDTH ∝ loc
|
|
7
|
+
* @property {number} [coverage=0] 0..4 monochrome coverage ramp (the FILL)
|
|
8
|
+
* @property {string} [parent] parent id (forms the tree)
|
|
9
|
+
* @property {number} [violations=0] violation count — a clay badge
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {Object} MapEdge
|
|
13
|
+
* @property {string} from
|
|
14
|
+
* @property {string} to
|
|
15
|
+
* @property {'structure'|'activity'} [kind='structure'] solid vs dashed
|
|
16
|
+
* @property {number} [weight=1] stroke WIDTH ∝ weight (never hue)
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* MapCanvas — an interactive code-structure map. Pan (drag), zoom (square controls /
|
|
20
|
+
* +/- keys, never wheel), semantic zoom (overview / folders / files) with edge
|
|
21
|
+
* ancestor-lifting, a minimap, and a node search combobox. Square metric-encoded
|
|
22
|
+
* nodes (width ∝ LOC, monochrome coverage fill, folder/file icon, amber selection +
|
|
23
|
+
* marker, clay violation badge) and square orthogonal edges (solid structure /
|
|
24
|
+
* dashed activity, width ∝ weight). Full roving-focus keyboard nav with an aria-live
|
|
25
|
+
* region. Pure: no data fetching, deterministic layout.
|
|
26
|
+
*
|
|
27
|
+
* @param {Object} props
|
|
28
|
+
* @param {{nodes: MapNode[], edges?: MapEdge[]}} [props.data] the graph
|
|
29
|
+
* @param {'overview'|'folders'|'files'} [props.grain='folders'] initial semantic zoom
|
|
30
|
+
* @param {string} [props.selectedId] initial selection
|
|
31
|
+
* @param {(id:string|null, node:MapNode|null)=>void} [props.onSelect] selection cb
|
|
32
|
+
* @param {number} [props.height=520] canvas height (px)
|
|
33
|
+
* @param {string} [props.ariaLabel='code map'] application label
|
|
34
|
+
* @param {string} [props.className] extra container class
|
|
35
|
+
*/
|
|
36
|
+
export default function MapCanvas({ data, grain: initialGrain, selectedId: initialSelected, onSelect, height, ariaLabel, className, }: {
|
|
37
|
+
data?: {
|
|
38
|
+
nodes: MapNode[];
|
|
39
|
+
edges?: MapEdge[];
|
|
40
|
+
};
|
|
41
|
+
grain?: "overview" | "folders" | "files";
|
|
42
|
+
selectedId?: string;
|
|
43
|
+
onSelect?: (id: string | null, node: MapNode | null) => void;
|
|
44
|
+
height?: number;
|
|
45
|
+
ariaLabel?: string;
|
|
46
|
+
className?: string;
|
|
47
|
+
}): any;
|
|
48
|
+
export type MapNode = {
|
|
49
|
+
/**
|
|
50
|
+
* stable key (repo-relative path)
|
|
51
|
+
*/
|
|
52
|
+
id: string;
|
|
53
|
+
/**
|
|
54
|
+
* display label (leaf of a path is shown)
|
|
55
|
+
*/
|
|
56
|
+
label: string;
|
|
57
|
+
/**
|
|
58
|
+
* folder vs file — distinguished by ICON
|
|
59
|
+
*/
|
|
60
|
+
kind: "folder" | "file";
|
|
61
|
+
/**
|
|
62
|
+
* lines of code — node WIDTH ∝ loc
|
|
63
|
+
*/
|
|
64
|
+
loc?: number;
|
|
65
|
+
/**
|
|
66
|
+
* 0..4 monochrome coverage ramp (the FILL)
|
|
67
|
+
*/
|
|
68
|
+
coverage?: number;
|
|
69
|
+
/**
|
|
70
|
+
* parent id (forms the tree)
|
|
71
|
+
*/
|
|
72
|
+
parent?: string;
|
|
73
|
+
/**
|
|
74
|
+
* violation count — a clay badge
|
|
75
|
+
*/
|
|
76
|
+
violations?: number;
|
|
77
|
+
};
|
|
78
|
+
export type MapEdge = {
|
|
79
|
+
from: string;
|
|
80
|
+
to: string;
|
|
81
|
+
/**
|
|
82
|
+
* solid vs dashed
|
|
83
|
+
*/
|
|
84
|
+
kind?: "structure" | "activity";
|
|
85
|
+
/**
|
|
86
|
+
* stroke WIDTH ∝ weight (never hue)
|
|
87
|
+
*/
|
|
88
|
+
weight?: number;
|
|
89
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} MenuItem
|
|
3
|
+
* @property {string} label row label (passed-through children case preserved)
|
|
4
|
+
* @property {React.ComponentType<any>} [icon] leading lucide icon component (e.g. icon={Copy})
|
|
5
|
+
* @property {string} [brand] leading provider mark (e.g. brand="claude-code"); takes precedence over icon
|
|
6
|
+
* @property {string} [kbd] right-aligned shortcut hint (e.g. "⌘D")
|
|
7
|
+
* @property {boolean} [danger] destructive (.menu-danger) variant - clay, keeps icon + label
|
|
8
|
+
* @property {boolean} [disabled] aria-disabled row, skipped by arrow keys, not selectable
|
|
9
|
+
* @property {boolean} [separator] a role="separator" .menu-sep hairline row, skipped by keyboard nav
|
|
10
|
+
* @property {() => void} [onSelect] invoked when the row is chosen (click or Enter/Space)
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Menu - a dropdown menu controlled by a single trigger button.
|
|
14
|
+
*
|
|
15
|
+
* @param {Object} props
|
|
16
|
+
* @param {React.ReactNode} props.label trigger label (lowercase chrome by default)
|
|
17
|
+
* @param {MenuItem[]} [props.items=[]] menu rows
|
|
18
|
+
* @param {'start'|'end'} [props.align='start'] which edge of the trigger the popout aligns to
|
|
19
|
+
* @param {React.ReactNode} [props.caption] optional .menu-cap caption rendered inside the popout before the list
|
|
20
|
+
* @param {boolean} [props.defaultOpen=false] render with the popout already open (specimen / screenshot state)
|
|
21
|
+
*/
|
|
22
|
+
export default function Menu({ label, items, align, caption, defaultOpen }: {
|
|
23
|
+
label: React.ReactNode;
|
|
24
|
+
items?: MenuItem[];
|
|
25
|
+
align?: "start" | "end";
|
|
26
|
+
caption?: React.ReactNode;
|
|
27
|
+
defaultOpen?: boolean;
|
|
28
|
+
}): any;
|
|
29
|
+
export type MenuItem = {
|
|
30
|
+
/**
|
|
31
|
+
* row label (passed-through children case preserved)
|
|
32
|
+
*/
|
|
33
|
+
label: string;
|
|
34
|
+
/**
|
|
35
|
+
* leading lucide icon component (e.g. icon={Copy})
|
|
36
|
+
*/
|
|
37
|
+
icon?: React.ComponentType<any>;
|
|
38
|
+
/**
|
|
39
|
+
* leading provider mark (e.g. brand="claude-code"); takes precedence over icon
|
|
40
|
+
*/
|
|
41
|
+
brand?: string;
|
|
42
|
+
/**
|
|
43
|
+
* right-aligned shortcut hint (e.g. "⌘D")
|
|
44
|
+
*/
|
|
45
|
+
kbd?: string;
|
|
46
|
+
/**
|
|
47
|
+
* destructive (.menu-danger) variant - clay, keeps icon + label
|
|
48
|
+
*/
|
|
49
|
+
danger?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* aria-disabled row, skipped by arrow keys, not selectable
|
|
52
|
+
*/
|
|
53
|
+
disabled?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* a role="separator" .menu-sep hairline row, skipped by keyboard nav
|
|
56
|
+
*/
|
|
57
|
+
separator?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* invoked when the row is chosen (click or Enter/Space)
|
|
60
|
+
*/
|
|
61
|
+
onSelect?: () => void;
|
|
62
|
+
};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ApprovalBar — a sticky top bar for reviewing a single pending item. Once acted on it collapses
|
|
3
|
+
* to a one-line resolved acknowledgement (icon + word) rather than disappearing outright.
|
|
4
|
+
* @typedef {Object} ApprovalBarProps
|
|
5
|
+
* @property {React.ReactNode} subject the thing under review, e.g. "pending share to {collective}";
|
|
6
|
+
* the collective/title inside is USER CONTENT (case preserved).
|
|
7
|
+
* @property {() => void} [onApprove] called when approve is clicked (after the optimistic resolve).
|
|
8
|
+
* @property {() => void} [onReject] called when reject is clicked (after the optimistic resolve).
|
|
9
|
+
* @property {string} [approveLabel='approve'] lowercase label for the approve action.
|
|
10
|
+
* @property {string} [rejectLabel='reject'] lowercase label for the reject action.
|
|
11
|
+
* @property {string} [className] extra classes appended to the .mod-bar root.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* @param {ApprovalBarProps} props
|
|
15
|
+
*/
|
|
16
|
+
export function ApprovalBar({ subject, onApprove, onReject, approveLabel, rejectLabel, className, }: ApprovalBarProps): any;
|
|
17
|
+
/**
|
|
18
|
+
* ModerationQueue — a panel listing pending items (member requests OR shares). Each row shows who +
|
|
19
|
+
* detail + relative time, with approve/reject buttons. Acting on a row resolves it OPTIMISTICALLY in
|
|
20
|
+
* place: the buttons swap for an approved/rejected pill (olive/clay + icon) and the row is struck +
|
|
21
|
+
* dimmed, never removed — so the reviewer keeps an audit trail of what they just decided. When no
|
|
22
|
+
* items remain pending an empty state is shown.
|
|
23
|
+
* @typedef {Object} QueueItem
|
|
24
|
+
* @property {string} id stable key.
|
|
25
|
+
* @property {'member'|'share'} [kind] picks the leading icon (user-plus / inbox). defaults to share.
|
|
26
|
+
* @property {React.ReactNode} who the actor — a handle/name. USER CONTENT (case preserved).
|
|
27
|
+
* @property {React.ReactNode} [detail] the secondary line (org, title, …). USER CONTENT.
|
|
28
|
+
* @property {React.ReactNode} [when] relative time, e.g. "2h ago". rendered tabular + lowercased.
|
|
29
|
+
*
|
|
30
|
+
* @typedef {Object} ModerationQueueProps
|
|
31
|
+
* @property {React.ReactNode} [title='pending review'] the panel header label (lowercase chrome).
|
|
32
|
+
* @property {QueueItem[]} [items=[]] the pending items.
|
|
33
|
+
* @property {(item: QueueItem) => void} [onApprove] called with the item when approved.
|
|
34
|
+
* @property {(item: QueueItem) => void} [onReject] called with the item when rejected.
|
|
35
|
+
* @property {React.ReactNode} [emptyLabel='nothing pending'] message for the empty state.
|
|
36
|
+
* @property {string} [className] extra classes appended to the .mod-queue root.
|
|
37
|
+
*/
|
|
38
|
+
/**
|
|
39
|
+
* @param {ModerationQueueProps} props
|
|
40
|
+
*/
|
|
41
|
+
export function ModerationQueue({ title, items, onApprove, onReject, emptyLabel, className, }: ModerationQueueProps): any;
|
|
42
|
+
export default ModerationQueue;
|
|
43
|
+
/**
|
|
44
|
+
* ApprovalBar — a sticky top bar for reviewing a single pending item. Once acted on it collapses
|
|
45
|
+
* to a one-line resolved acknowledgement (icon + word) rather than disappearing outright.
|
|
46
|
+
*/
|
|
47
|
+
export type ApprovalBarProps = {
|
|
48
|
+
/**
|
|
49
|
+
* the thing under review, e.g. "pending share to {collective}";
|
|
50
|
+
* the collective/title inside is USER CONTENT (case preserved).
|
|
51
|
+
*/
|
|
52
|
+
subject: React.ReactNode;
|
|
53
|
+
/**
|
|
54
|
+
* called when approve is clicked (after the optimistic resolve).
|
|
55
|
+
*/
|
|
56
|
+
onApprove?: () => void;
|
|
57
|
+
/**
|
|
58
|
+
* called when reject is clicked (after the optimistic resolve).
|
|
59
|
+
*/
|
|
60
|
+
onReject?: () => void;
|
|
61
|
+
/**
|
|
62
|
+
* lowercase label for the approve action.
|
|
63
|
+
*/
|
|
64
|
+
approveLabel?: string;
|
|
65
|
+
/**
|
|
66
|
+
* lowercase label for the reject action.
|
|
67
|
+
*/
|
|
68
|
+
rejectLabel?: string;
|
|
69
|
+
/**
|
|
70
|
+
* extra classes appended to the .mod-bar root.
|
|
71
|
+
*/
|
|
72
|
+
className?: string;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* ModerationQueue — a panel listing pending items (member requests OR shares). Each row shows who +
|
|
76
|
+
* detail + relative time, with approve/reject buttons. Acting on a row resolves it OPTIMISTICALLY in
|
|
77
|
+
* place: the buttons swap for an approved/rejected pill (olive/clay + icon) and the row is struck +
|
|
78
|
+
* dimmed, never removed — so the reviewer keeps an audit trail of what they just decided. When no
|
|
79
|
+
* items remain pending an empty state is shown.
|
|
80
|
+
*/
|
|
81
|
+
export type QueueItem = {
|
|
82
|
+
/**
|
|
83
|
+
* stable key.
|
|
84
|
+
*/
|
|
85
|
+
id: string;
|
|
86
|
+
/**
|
|
87
|
+
* picks the leading icon (user-plus / inbox). defaults to share.
|
|
88
|
+
*/
|
|
89
|
+
kind?: "member" | "share";
|
|
90
|
+
/**
|
|
91
|
+
* the actor — a handle/name. USER CONTENT (case preserved).
|
|
92
|
+
*/
|
|
93
|
+
who: React.ReactNode;
|
|
94
|
+
/**
|
|
95
|
+
* the secondary line (org, title, …). USER CONTENT.
|
|
96
|
+
*/
|
|
97
|
+
detail?: React.ReactNode;
|
|
98
|
+
/**
|
|
99
|
+
* relative time, e.g. "2h ago". rendered tabular + lowercased.
|
|
100
|
+
*/
|
|
101
|
+
when?: React.ReactNode;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* ModerationQueue — a panel listing pending items (member requests OR shares). Each row shows who +
|
|
105
|
+
* detail + relative time, with approve/reject buttons. Acting on a row resolves it OPTIMISTICALLY in
|
|
106
|
+
* place: the buttons swap for an approved/rejected pill (olive/clay + icon) and the row is struck +
|
|
107
|
+
* dimmed, never removed — so the reviewer keeps an audit trail of what they just decided. When no
|
|
108
|
+
* items remain pending an empty state is shown.
|
|
109
|
+
*/
|
|
110
|
+
export type ModerationQueueProps = {
|
|
111
|
+
/**
|
|
112
|
+
* the panel header label (lowercase chrome).
|
|
113
|
+
*/
|
|
114
|
+
title?: React.ReactNode;
|
|
115
|
+
/**
|
|
116
|
+
* the pending items.
|
|
117
|
+
*/
|
|
118
|
+
items?: QueueItem[];
|
|
119
|
+
/**
|
|
120
|
+
* called with the item when approved.
|
|
121
|
+
*/
|
|
122
|
+
onApprove?: (item: QueueItem) => void;
|
|
123
|
+
/**
|
|
124
|
+
* called with the item when rejected.
|
|
125
|
+
*/
|
|
126
|
+
onReject?: (item: QueueItem) => void;
|
|
127
|
+
/**
|
|
128
|
+
* message for the empty state.
|
|
129
|
+
*/
|
|
130
|
+
emptyLabel?: React.ReactNode;
|
|
131
|
+
/**
|
|
132
|
+
* extra classes appended to the .mod-queue root.
|
|
133
|
+
*/
|
|
134
|
+
className?: string;
|
|
135
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* the simple prev/next pager (the .pager specimen). a label naming the current page,
|
|
3
|
+
* flanked by previous/next icon buttons. reuses .pager + .btn.btn-secondary.btn-sm.btn-icon
|
|
4
|
+
* with no new css. for numbered pagination use a separate component.
|
|
5
|
+
*
|
|
6
|
+
* @typedef {Object} PagerProps
|
|
7
|
+
* @property {number} page - the current (1-based) page number. default 1.
|
|
8
|
+
* @property {number} total - the total number of pages. default 1.
|
|
9
|
+
* @property {() => void} [onPrev] - called when the previous button is clicked.
|
|
10
|
+
* @property {() => void} [onNext] - called when the next button is clicked.
|
|
11
|
+
* @property {(nextPage: number) => void} [onChange] - called with the new page number on either button (fallback when onPrev/onNext are not given).
|
|
12
|
+
* @property {string} [label] - aria-label for the whole pager nav. default 'pagination'.
|
|
13
|
+
*
|
|
14
|
+
* @param {PagerProps} props
|
|
15
|
+
*/
|
|
16
|
+
export default function Pager({ page, total, onPrev, onNext, onChange, label }: PagerProps): any;
|
|
17
|
+
/**
|
|
18
|
+
* the simple prev/next pager (the .pager specimen). a label naming the current page,
|
|
19
|
+
* flanked by previous/next icon buttons. reuses .pager + .btn.btn-secondary.btn-sm.btn-icon
|
|
20
|
+
* with no new css. for numbered pagination use a separate component.
|
|
21
|
+
*/
|
|
22
|
+
export type PagerProps = {
|
|
23
|
+
/**
|
|
24
|
+
* - the current (1-based) page number. default 1.
|
|
25
|
+
*/
|
|
26
|
+
page: number;
|
|
27
|
+
/**
|
|
28
|
+
* - the total number of pages. default 1.
|
|
29
|
+
*/
|
|
30
|
+
total: number;
|
|
31
|
+
/**
|
|
32
|
+
* - called when the previous button is clicked.
|
|
33
|
+
*/
|
|
34
|
+
onPrev?: () => void;
|
|
35
|
+
/**
|
|
36
|
+
* - called when the next button is clicked.
|
|
37
|
+
*/
|
|
38
|
+
onNext?: () => void;
|
|
39
|
+
/**
|
|
40
|
+
* - called with the new page number on either button (fallback when onPrev/onNext are not given).
|
|
41
|
+
*/
|
|
42
|
+
onChange?: (nextPage: number) => void;
|
|
43
|
+
/**
|
|
44
|
+
* - aria-label for the whole pager nav. default 'pagination'.
|
|
45
|
+
*/
|
|
46
|
+
label?: string;
|
|
47
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} PaginationProps
|
|
3
|
+
* @property {number} [page] controlled current page (1-based); pair with onChange.
|
|
4
|
+
* @property {number} [defaultPage=1] initial page when uncontrolled.
|
|
5
|
+
* @property {number} [total] total number of pages. if omitted it is derived from
|
|
6
|
+
* totalItems / pageSize.
|
|
7
|
+
* @property {number} [totalItems] total item count, used with pageSize to derive `total`.
|
|
8
|
+
* @property {number} [pageSize=10] items per page, used with totalItems to derive `total`.
|
|
9
|
+
* @property {(nextPage: number) => void} [onChange] called with the new 1-based page on any change.
|
|
10
|
+
* @property {number} [siblingCount=1] page buttons shown on each side of the current page.
|
|
11
|
+
* @property {string} [label='pagination'] aria-label for the <nav>.
|
|
12
|
+
*
|
|
13
|
+
* @param {PaginationProps} props
|
|
14
|
+
*/
|
|
15
|
+
export default function Pagination({ page, defaultPage, total, totalItems, pageSize, onChange, siblingCount, label, }: PaginationProps): any;
|
|
16
|
+
export type PaginationProps = {
|
|
17
|
+
/**
|
|
18
|
+
* controlled current page (1-based); pair with onChange.
|
|
19
|
+
*/
|
|
20
|
+
page?: number;
|
|
21
|
+
/**
|
|
22
|
+
* initial page when uncontrolled.
|
|
23
|
+
*/
|
|
24
|
+
defaultPage?: number;
|
|
25
|
+
/**
|
|
26
|
+
* total number of pages. if omitted it is derived from
|
|
27
|
+
* totalItems / pageSize.
|
|
28
|
+
*/
|
|
29
|
+
total?: number;
|
|
30
|
+
/**
|
|
31
|
+
* total item count, used with pageSize to derive `total`.
|
|
32
|
+
*/
|
|
33
|
+
totalItems?: number;
|
|
34
|
+
/**
|
|
35
|
+
* items per page, used with totalItems to derive `total`.
|
|
36
|
+
*/
|
|
37
|
+
pageSize?: number;
|
|
38
|
+
/**
|
|
39
|
+
* called with the new 1-based page on any change.
|
|
40
|
+
*/
|
|
41
|
+
onChange?: (nextPage: number) => void;
|
|
42
|
+
/**
|
|
43
|
+
* page buttons shown on each side of the current page.
|
|
44
|
+
*/
|
|
45
|
+
siblingCount?: number;
|
|
46
|
+
/**
|
|
47
|
+
* aria-label for the <nav>.
|
|
48
|
+
*/
|
|
49
|
+
label?: string;
|
|
50
|
+
};
|