@northstar-js/react 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/actions.d.ts +32 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +15 -0
- package/dist/actions.js.map +1 -0
- package/dist/data.d.ts +80 -0
- package/dist/data.d.ts.map +1 -0
- package/dist/data.js +60 -0
- package/dist/data.js.map +1 -0
- package/dist/feedback.d.ts +50 -0
- package/dist/feedback.d.ts.map +1 -0
- package/dist/feedback.js +60 -0
- package/dist/feedback.js.map +1 -0
- package/dist/forms.d.ts +130 -0
- package/dist/forms.d.ts.map +1 -0
- package/dist/forms.js +241 -0
- package/dist/forms.js.map +1 -0
- package/dist/illustrations/data.d.ts +103 -0
- package/dist/illustrations/data.d.ts.map +1 -0
- package/dist/illustrations/data.js +3 -0
- package/dist/illustrations/data.js.map +1 -0
- package/dist/illustrations/index.d.ts +110 -0
- package/dist/illustrations/index.d.ts.map +1 -0
- package/dist/illustrations/index.js +54 -0
- package/dist/illustrations/index.js.map +1 -0
- package/dist/illustrations/types.d.ts +30 -0
- package/dist/illustrations/types.d.ts.map +1 -0
- package/dist/illustrations/types.js +2 -0
- package/dist/illustrations/types.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/icons.d.ts +9 -0
- package/dist/internal/icons.d.ts.map +1 -0
- package/dist/internal/icons.js +12 -0
- package/dist/internal/icons.js.map +1 -0
- package/dist/internal/layers.d.ts +12 -0
- package/dist/internal/layers.d.ts.map +1 -0
- package/dist/internal/layers.js +108 -0
- package/dist/internal/layers.js.map +1 -0
- package/dist/internal/util.d.ts +9 -0
- package/dist/internal/util.d.ts.map +1 -0
- package/dist/internal/util.js +33 -0
- package/dist/internal/util.js.map +1 -0
- package/dist/layout.d.ts +34 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +27 -0
- package/dist/layout.js.map +1 -0
- package/dist/navigation.d.ts +63 -0
- package/dist/navigation.d.ts.map +1 -0
- package/dist/navigation.js +87 -0
- package/dist/navigation.js.map +1 -0
- package/dist/northstar/BriefForm.d.ts +23 -0
- package/dist/northstar/BriefForm.d.ts.map +1 -0
- package/dist/northstar/BriefForm.js +40 -0
- package/dist/northstar/BriefForm.js.map +1 -0
- package/dist/northstar/ExportMenu.d.ts +14 -0
- package/dist/northstar/ExportMenu.d.ts.map +1 -0
- package/dist/northstar/ExportMenu.js +11 -0
- package/dist/northstar/ExportMenu.js.map +1 -0
- package/dist/northstar/PopulationPanel.d.ts +30 -0
- package/dist/northstar/PopulationPanel.d.ts.map +1 -0
- package/dist/northstar/PopulationPanel.js +18 -0
- package/dist/northstar/PopulationPanel.js.map +1 -0
- package/dist/northstar/ResearchBuilder.d.ts +26 -0
- package/dist/northstar/ResearchBuilder.d.ts.map +1 -0
- package/dist/northstar/ResearchBuilder.js +81 -0
- package/dist/northstar/ResearchBuilder.js.map +1 -0
- package/dist/northstar/ResponsesView.d.ts +20 -0
- package/dist/northstar/ResponsesView.d.ts.map +1 -0
- package/dist/northstar/ResponsesView.js +42 -0
- package/dist/northstar/ResponsesView.js.map +1 -0
- package/dist/northstar/Run.d.ts +35 -0
- package/dist/northstar/Run.d.ts.map +1 -0
- package/dist/northstar/Run.js +31 -0
- package/dist/northstar/Run.js.map +1 -0
- package/dist/northstar/StudyShell.d.ts +28 -0
- package/dist/northstar/StudyShell.d.ts.map +1 -0
- package/dist/northstar/StudyShell.js +14 -0
- package/dist/northstar/StudyShell.js.map +1 -0
- package/dist/northstar/StudyStatus.d.ts +15 -0
- package/dist/northstar/StudyStatus.d.ts.map +1 -0
- package/dist/northstar/StudyStatus.js +24 -0
- package/dist/northstar/StudyStatus.js.map +1 -0
- package/dist/northstar/index.d.ts +10 -0
- package/dist/northstar/index.d.ts.map +1 -0
- package/dist/northstar/index.js +10 -0
- package/dist/northstar/index.js.map +1 -0
- package/dist/northstar/messages.d.ts +84 -0
- package/dist/northstar/messages.d.ts.map +1 -0
- package/dist/northstar/messages.js +107 -0
- package/dist/northstar/messages.js.map +1 -0
- package/dist/overlays.d.ts +111 -0
- package/dist/overlays.d.ts.map +1 -0
- package/dist/overlays.js +421 -0
- package/dist/overlays.js.map +1 -0
- package/dist/provider.d.ts +53 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +114 -0
- package/dist/provider.js.map +1 -0
- package/dist/styles.css +971 -0
- package/package.json +71 -3
- package/README.md +0 -3
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useId, useRef } from 'react';
|
|
4
|
+
import { Button } from '../actions.js';
|
|
5
|
+
import { cx, useControllable } from '../internal/util.js';
|
|
6
|
+
import { studyMessages } from './messages.js';
|
|
7
|
+
const EMPTY = { title: '', decision: '', objectives: [] };
|
|
8
|
+
/** The Brief tab: study name, the decision it informs, and its objectives. */
|
|
9
|
+
export function BriefForm({ value, defaultValue, onValueChange, maxObjectives = 5, objectiveMeta, toolbar, readOnly = false, messages, className, ...rest }) {
|
|
10
|
+
const m = studyMessages(messages);
|
|
11
|
+
const [v, setV] = useControllable(value, defaultValue ?? EMPTY, onValueChange);
|
|
12
|
+
const headingId = `ns-brief-${useId().replace(/:/g, '')}`;
|
|
13
|
+
const list = useRef(null);
|
|
14
|
+
const patch = (p) => setV({ ...v, ...p });
|
|
15
|
+
const focusRow = (i) => requestAnimationFrame(() => list.current?.querySelectorAll('input')[i]?.focus());
|
|
16
|
+
const add = () => {
|
|
17
|
+
if (v.objectives.length >= maxObjectives)
|
|
18
|
+
return;
|
|
19
|
+
patch({ objectives: [...v.objectives, ''] });
|
|
20
|
+
focusRow(v.objectives.length);
|
|
21
|
+
};
|
|
22
|
+
const remove = (i) => {
|
|
23
|
+
patch({ objectives: v.objectives.filter((_, j) => j !== i) });
|
|
24
|
+
focusRow(Math.max(0, i - 1));
|
|
25
|
+
};
|
|
26
|
+
const full = v.objectives.length >= maxObjectives;
|
|
27
|
+
return (_jsxs("div", { ...rest, className: cx('ns-brief', className), children: [_jsxs("div", { className: "ns-brief__head", children: [_jsx("input", { className: "ns-brief__title", "aria-label": m.studyName, value: v.title, readOnly: readOnly, onChange: (e) => patch({ title: e.target.value }) }), _jsx("textarea", { className: "ns-brief__decision", rows: 2, "aria-label": m.decision, placeholder: m.decisionPlaceholder, value: v.decision, readOnly: readOnly, onChange: (e) => patch({ decision: e.target.value }) })] }), toolbar && _jsx("div", { className: "ns-brief__toolbar", children: toolbar }), _jsxs("section", { className: "ns-study-panel", "aria-labelledby": headingId, children: [_jsxs("div", { className: "ns-study-panel__head", children: [_jsx("h2", { id: headingId, className: "ns-study-panel__title", children: m.objectives }), _jsx("span", { className: "ns-study-hint", children: m.objectiveCount(v.objectives.length, maxObjectives) }), !readOnly && (_jsx(Button, { variant: "ghost", size: "sm", className: "ns-study-panel__action", onClick: add, disabled: full, children: m.addObjective }))] }), _jsxs("div", { ref: list, role: "list", children: [v.objectives.map((o, i) => (_jsxs("div", { role: "listitem", className: "ns-study-row", children: [_jsxs("span", { className: "ns-study-id", "aria-hidden": "true", children: ["O", i + 1] }), _jsx("input", { className: "ns-study-row__input", "aria-label": m.objectiveLabel(i), value: o, readOnly: readOnly, onChange: (e) => patch({ objectives: v.objectives.map((x, j) => (j === i ? e.target.value : x)) }), onKeyDown: (e) => {
|
|
28
|
+
if (readOnly)
|
|
29
|
+
return;
|
|
30
|
+
if (e.key === 'Enter') {
|
|
31
|
+
e.preventDefault();
|
|
32
|
+
add();
|
|
33
|
+
}
|
|
34
|
+
else if (e.key === 'Backspace' && o === '' && v.objectives.length > 0) {
|
|
35
|
+
e.preventDefault();
|
|
36
|
+
remove(i);
|
|
37
|
+
}
|
|
38
|
+
} }), objectiveMeta && _jsx("span", { className: "ns-tag", children: objectiveMeta(i) }), !readOnly && (_jsx("button", { type: "button", className: "ns-study-icon-button", "aria-label": m.removeObjective(i), onClick: () => remove(i), children: _jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", "aria-hidden": "true", children: _jsx("path", { d: "M3 3l6 6M9 3l-6 6" }) }) }))] }, i))), !readOnly && !full && (_jsxs("div", { role: "listitem", className: "ns-study-row", children: [_jsxs("span", { className: "ns-study-id", "aria-hidden": "true", children: ["O", v.objectives.length + 1] }), _jsx("button", { type: "button", className: "ns-study-row__ghost", onClick: add, children: m.objectivePlaceholder })] }))] })] }), _jsx("span", { className: "ns-study-hint", children: m.objectivesHint })] }));
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=BriefForm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BriefForm.js","sourceRoot":"","sources":["../../src/northstar/BriefForm.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type WithMessages } from './messages.js';
|
|
2
|
+
export type ExportFormat = 'pdf' | 'spec' | 'csv';
|
|
3
|
+
export interface ExportMenuProps extends WithMessages {
|
|
4
|
+
onExport: (format: ExportFormat) => void;
|
|
5
|
+
/** Which formats to offer, in order. Default all three. */
|
|
6
|
+
formats?: ExportFormat[];
|
|
7
|
+
/** Formats shown but not available yet. */
|
|
8
|
+
disabledFormats?: ExportFormat[];
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
/** Export a finished study: PDF report, report spec, or responses as CSV. */
|
|
13
|
+
export declare function ExportMenu({ onExport, formats, disabledFormats, disabled, className, messages }: ExportMenuProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
//# sourceMappingURL=ExportMenu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExportMenu.d.ts","sourceRoot":"","sources":["../../src/northstar/ExportMenu.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAEjE,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;AAElD,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,QAAQ,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IACzC,2DAA2D;IAC3D,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,2CAA2C;IAC3C,eAAe,CAAC,EAAE,YAAY,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,6EAA6E;AAC7E,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,OAAgC,EAAE,eAAoB,EAAE,QAAgB,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,eAAe,2CAiBtJ"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Icon } from '@northstar-js/icons';
|
|
4
|
+
import { Menu } from '../overlays.js';
|
|
5
|
+
import { studyMessages } from './messages.js';
|
|
6
|
+
/** Export a finished study: PDF report, report spec, or responses as CSV. */
|
|
7
|
+
export function ExportMenu({ onExport, formats = ['pdf', 'spec', 'csv'], disabledFormats = [], disabled = false, className, messages }) {
|
|
8
|
+
const m = studyMessages(messages);
|
|
9
|
+
return (_jsxs(Menu.Root, { children: [_jsxs(Menu.Trigger, { className: ['ns-button ns-button--secondary ns-size-md', className].filter(Boolean).join(' '), disabled: disabled, children: [_jsx(Icon, { name: "export", size: 14 }), _jsx("span", { className: "ns-button__label", children: m.export })] }), _jsx(Menu.Content, { align: "end", children: formats.map((f) => (_jsx(Menu.Item, { onSelect: () => onExport(f), disabled: disabledFormats.includes(f), children: m.exportFormats[f] }, f))) })] }));
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=ExportMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExportMenu.js","sourceRoot":"","sources":["../../src/northstar/ExportMenu.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AACb,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,aAAa,EAAqB,MAAM,eAAe,CAAC;AAcjE,6EAA6E;AAC7E,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAE,OAAO,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,eAAe,GAAG,EAAE,EAAE,QAAQ,GAAG,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAmB;IACrJ,MAAM,CAAC,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAClC,OAAO,CACL,MAAC,IAAI,CAAC,IAAI,eACR,MAAC,IAAI,CAAC,OAAO,IAAC,SAAS,EAAE,CAAC,2CAA2C,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,QAAQ,aAC7H,KAAC,IAAI,IAAC,IAAI,EAAC,QAAQ,EAAC,IAAI,EAAE,EAAE,GAAI,EAChC,eAAM,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,MAAM,GAAQ,IACvC,EACf,KAAC,IAAI,CAAC,OAAO,IAAC,KAAK,EAAC,KAAK,YACtB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAClB,KAAC,IAAI,CAAC,IAAI,IAAS,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,YAClF,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IADL,CAAC,CAEL,CACb,CAAC,GACW,IACL,CACb,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { PopulationRef } from '@northstar-js/contracts';
|
|
3
|
+
import { type CompositionRow } from '@northstar-js/charts';
|
|
4
|
+
import { type WithMessages } from './messages.js';
|
|
5
|
+
export interface CompositionGroup {
|
|
6
|
+
/** Dimension name, e.g. "Age". */
|
|
7
|
+
label: string;
|
|
8
|
+
rows: CompositionRow[];
|
|
9
|
+
}
|
|
10
|
+
export interface PopulationPanelProps extends React.HTMLAttributes<HTMLDivElement>, WithMessages {
|
|
11
|
+
/** The study's one population. */
|
|
12
|
+
population: PopulationRef;
|
|
13
|
+
/** Margins (and panel shares once built), one group per dimension. Empty shows the empty state. */
|
|
14
|
+
composition?: CompositionGroup[];
|
|
15
|
+
/** Sub-heading of the composition panel, e.g. which margins it is raked to. */
|
|
16
|
+
compositionNote?: ReactNode;
|
|
17
|
+
/** Sentence under the composition panel. */
|
|
18
|
+
caption?: ReactNode;
|
|
19
|
+
onSizeChange?: (size: number | null) => void;
|
|
20
|
+
onSeedChange?: (seed: number | null) => void;
|
|
21
|
+
onRebuild?: () => void;
|
|
22
|
+
/** Locks size, seed and rebuild (after a run). */
|
|
23
|
+
readOnly?: boolean;
|
|
24
|
+
/** Width of each composition chart. Default 320. */
|
|
25
|
+
chartWidth?: number;
|
|
26
|
+
locale?: string;
|
|
27
|
+
}
|
|
28
|
+
/** The Population tab: market status, size and seed, and the composition against published margins. */
|
|
29
|
+
export declare function PopulationPanel({ population, composition, compositionNote, caption, onSizeChange, onSeedChange, onRebuild, readOnly, chartWidth, locale, messages, className, ...rest }: PopulationPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
//# sourceMappingURL=PopulationPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PopulationPanel.d.ts","sourceRoot":"","sources":["../../src/northstar/PopulationPanel.tsx"],"names":[],"mappings":"AACA,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAMxE,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAEjE,MAAM,WAAW,gBAAgB;IAC/B,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,cAAc,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,oBAAqB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,YAAY;IAC9F,kCAAkC;IAClC,UAAU,EAAE,aAAa,CAAC;IAC1B,mGAAmG;IACnG,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACjC,+EAA+E;IAC/E,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,4CAA4C;IAC5C,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7C,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,uGAAuG;AACvG,wBAAgB,eAAe,CAAC,EAC9B,UAAU,EAAE,WAAgB,EAAE,eAAe,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,QAAgB,EAC/G,UAAgB,EAAE,MAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EAC9D,EAAE,oBAAoB,2CAoEtB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useId } from 'react';
|
|
4
|
+
import { Composition } from '@northstar-js/charts';
|
|
5
|
+
import { MarketStatus } from '@northstar-js/maps';
|
|
6
|
+
import { Button } from '../actions.js';
|
|
7
|
+
import { NumberInput } from '../forms.js';
|
|
8
|
+
import { EmptyPopulation } from '../illustrations/index.js';
|
|
9
|
+
import { cx } from '../internal/util.js';
|
|
10
|
+
import { studyMessages } from './messages.js';
|
|
11
|
+
/** The Population tab: market status, size and seed, and the composition against published margins. */
|
|
12
|
+
export function PopulationPanel({ population, composition = [], compositionNote, caption, onSizeChange, onSeedChange, onRebuild, readOnly = false, chartWidth = 320, locale = 'en', messages, className, ...rest }) {
|
|
13
|
+
const m = studyMessages(messages);
|
|
14
|
+
const id = useId().replace(/:/g, '');
|
|
15
|
+
const sizeId = `ns-pop-size-${id}`, seedId = `ns-pop-seed-${id}`, headId = `ns-pop-comp-${id}`;
|
|
16
|
+
return (_jsxs("div", { ...rest, className: cx('ns-population', className), children: [_jsxs("div", { className: "ns-population__controls", children: [_jsxs("span", { className: "ns-population__market", children: [_jsx("span", { className: "ns-study-label", children: m.market }), _jsx(MarketStatus, { code: population.code, variant: "row" })] }), _jsx("span", { className: "ns-study-divider", "aria-hidden": "true" }), _jsx("label", { className: "ns-study-label", htmlFor: sizeId, children: m.size }), _jsx(NumberInput, { id: sizeId, size: "sm", min: 0, value: population.size, ...(onSizeChange ? { onValueChange: onSizeChange } : {}), disabled: readOnly, className: "ns-population__number" }), _jsx("label", { className: "ns-study-label", htmlFor: seedId, children: m.seed }), _jsx(NumberInput, { id: seedId, size: "sm", min: 0, value: population.seed ?? null, ...(onSeedChange ? { onValueChange: onSeedChange } : {}), disabled: readOnly, className: "ns-population__number" }), _jsx(Button, { size: "sm", onClick: onRebuild, disabled: readOnly || !onRebuild, children: m.rebuild }), _jsx("span", { className: "ns-study-hint", children: m.rebuildHint })] }), _jsxs("section", { className: "ns-study-panel", "aria-labelledby": headId, children: [_jsxs("div", { className: "ns-study-panel__head", children: [_jsx("h2", { id: headId, className: "ns-study-panel__title", children: m.composition }), compositionNote && _jsx("span", { className: "ns-study-hint", children: compositionNote }), population.label && _jsx("span", { className: "ns-study-hint ns-study-panel__end ns-study-mono", children: population.label })] }), composition.length === 0 ? (_jsxs("div", { className: "ns-study-empty", children: [_jsx(EmptyPopulation, {}), _jsx("p", { className: "ns-study-empty__title", children: m.emptyPopulationTitle }), _jsx("p", { className: "ns-study-hint", children: m.emptyPopulationBody })] })) : (_jsx("div", { className: "ns-population__grid", children: composition.map((g) => (_jsxs("div", { className: "ns-population__group", children: [_jsx("h3", { className: "ns-population__group-title", children: g.label }), _jsx(Composition, { margins: g.rows, title: g.label, width: chartWidth, locale: locale })] }, g.label))) }))] }), caption && _jsx("span", { className: "ns-study-hint", children: caption }), _jsxs("div", { className: "ns-study-callout", children: [_jsx("span", { className: "ns-tag ns-tone-signal", children: m.scope }), _jsx("span", { children: m.scopeBody })] })] }));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=PopulationPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PopulationPanel.js","sourceRoot":"","sources":["../../src/northstar/PopulationPanel.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AACb,OAAO,EAAE,KAAK,EAAkB,MAAM,OAAO,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAuB,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAqB,MAAM,eAAe,CAAC;AA2BjE,uGAAuG;AACvG,MAAM,UAAU,eAAe,CAAC,EAC9B,UAAU,EAAE,WAAW,GAAG,EAAE,EAAE,eAAe,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,GAAG,KAAK,EAC/G,UAAU,GAAG,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EACxC;IACrB,MAAM,CAAC,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,eAAe,EAAE,EAAE,EAAE,MAAM,GAAG,eAAe,EAAE,EAAE,EAAE,MAAM,GAAG,eAAe,EAAE,EAAE,CAAC;IAC/F,OAAO,CACL,kBAAS,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,eAAe,EAAE,SAAS,CAAC,aACtD,eAAK,SAAS,EAAC,yBAAyB,aACtC,gBAAM,SAAS,EAAC,uBAAuB,aACrC,eAAM,SAAS,EAAC,gBAAgB,YAAE,CAAC,CAAC,MAAM,GAAQ,EAClD,KAAC,YAAY,IAAC,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,OAAO,EAAC,KAAK,GAAG,IAChD,EACP,eAAM,SAAS,EAAC,kBAAkB,iBAAa,MAAM,GAAG,EACxD,gBAAO,SAAS,EAAC,gBAAgB,EAAC,OAAO,EAAE,MAAM,YAAG,CAAC,CAAC,IAAI,GAAS,EACnE,KAAC,WAAW,IACV,EAAE,EAAE,MAAM,EACV,IAAI,EAAC,IAAI,EACT,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,UAAU,CAAC,IAAI,KAClB,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EACzD,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAC,uBAAuB,GACjC,EACF,gBAAO,SAAS,EAAC,gBAAgB,EAAC,OAAO,EAAE,MAAM,YAAG,CAAC,CAAC,IAAI,GAAS,EACnE,KAAC,WAAW,IACV,EAAE,EAAE,MAAM,EACV,IAAI,EAAC,IAAI,EACT,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,UAAU,CAAC,IAAI,IAAI,IAAI,KAC1B,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EACzD,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAC,uBAAuB,GACjC,EACF,KAAC,MAAM,IAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,IAAI,CAAC,SAAS,YACnE,CAAC,CAAC,OAAO,GACH,EACT,eAAM,SAAS,EAAC,eAAe,YAAE,CAAC,CAAC,WAAW,GAAQ,IAClD,EAEN,mBAAS,SAAS,EAAC,gBAAgB,qBAAkB,MAAM,aACzD,eAAK,SAAS,EAAC,sBAAsB,aACnC,aAAI,EAAE,EAAE,MAAM,EAAE,SAAS,EAAC,uBAAuB,YAAE,CAAC,CAAC,WAAW,GAAM,EACrE,eAAe,IAAI,eAAM,SAAS,EAAC,eAAe,YAAE,eAAe,GAAQ,EAC3E,UAAU,CAAC,KAAK,IAAI,eAAM,SAAS,EAAC,iDAAiD,YAAE,UAAU,CAAC,KAAK,GAAQ,IAC5G,EACL,WAAW,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAC1B,eAAK,SAAS,EAAC,gBAAgB,aAC7B,KAAC,eAAe,KAAG,EACnB,YAAG,SAAS,EAAC,uBAAuB,YAAE,CAAC,CAAC,oBAAoB,GAAK,EACjE,YAAG,SAAS,EAAC,eAAe,YAAE,CAAC,CAAC,mBAAmB,GAAK,IACpD,CACP,CAAC,CAAC,CAAC,CACF,cAAK,SAAS,EAAC,qBAAqB,YACjC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACtB,eAAmB,SAAS,EAAC,sBAAsB,aACjD,aAAI,SAAS,EAAC,4BAA4B,YAAE,CAAC,CAAC,KAAK,GAAM,EACzD,KAAC,WAAW,IAAC,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAI,KAF3E,CAAC,CAAC,KAAK,CAGX,CACP,CAAC,GACE,CACP,IACO,EACT,OAAO,IAAI,eAAM,SAAS,EAAC,eAAe,YAAE,OAAO,GAAQ,EAC5D,eAAK,SAAS,EAAC,kBAAkB,aAC/B,eAAM,SAAS,EAAC,uBAAuB,YAAE,CAAC,CAAC,KAAK,GAAQ,EACxD,yBAAO,CAAC,CAAC,SAAS,GAAQ,IACtB,IACF,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { ResearchItem } from '@northstar-js/contracts';
|
|
3
|
+
import { type WithMessages } from './messages.js';
|
|
4
|
+
export interface AnchorIssue {
|
|
5
|
+
/** Zero-based anchor index. */
|
|
6
|
+
anchor: number;
|
|
7
|
+
message: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
export interface ResearchBuilderProps extends React.HTMLAttributes<HTMLDivElement>, WithMessages {
|
|
10
|
+
items?: ResearchItem[];
|
|
11
|
+
defaultItems?: ResearchItem[];
|
|
12
|
+
onItemsChange?: (items: ResearchItem[]) => void;
|
|
13
|
+
selectedKey?: string | null;
|
|
14
|
+
defaultSelectedKey?: string | null;
|
|
15
|
+
onSelectedKeyChange?: (key: string | null) => void;
|
|
16
|
+
/** Anchor-check results per item key. Items with issues are marked "Fix". */
|
|
17
|
+
anchorIssues?: Record<string, AnchorIssue[]>;
|
|
18
|
+
/** Makes a new item for "Add item". Defaults to an empty five-anchor Likert item. */
|
|
19
|
+
createItem?: (index: number) => ResearchItem;
|
|
20
|
+
/** Extra controls in the editor header (an objective picker, say). */
|
|
21
|
+
editorToolbar?: (item: ResearchItem) => ReactNode;
|
|
22
|
+
readOnly?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/** The Research tab: the item list (add, reorder, remove) beside an editor for wording, type, format and anchors. */
|
|
25
|
+
export declare function ResearchBuilder({ items, defaultItems, onItemsChange, selectedKey, defaultSelectedKey, onSelectedKeyChange, anchorIssues, createItem, editorToolbar, readOnly, messages, className, ...rest }: ResearchBuilderProps): import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
//# sourceMappingURL=ResearchBuilder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResearchBuilder.d.ts","sourceRoot":"","sources":["../../src/northstar/ResearchBuilder.tsx"],"names":[],"mappings":"AACA,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,KAAK,EAAgB,YAAY,EAAkB,MAAM,yBAAyB,CAAC;AAM1F,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAEjE,MAAM,WAAW,WAAW;IAC1B,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,SAAS,CAAC;CACpB;AAKD,MAAM,WAAW,oBAAqB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,YAAY;IAC9F,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,YAAY,EAAE,CAAC;IAC9B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IAChD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACnD,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;IAC7C,qFAAqF;IACrF,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,YAAY,CAAC;IAC7C,sEAAsE;IACtE,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,SAAS,CAAC;IAClD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAMD,qHAAqH;AACrH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,YAAiB,EAC3G,UAAwB,EAAE,aAAa,EAAE,QAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EACxF,EAAE,oBAAoB,2CAsLtB"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useId, useRef } from 'react';
|
|
4
|
+
import { Icon } from '@northstar-js/icons';
|
|
5
|
+
import { Button } from '../actions.js';
|
|
6
|
+
import { Select } from '../forms.js';
|
|
7
|
+
import { EmptyResearch } from '../illustrations/index.js';
|
|
8
|
+
import { cx, useControllable } from '../internal/util.js';
|
|
9
|
+
import { studyMessages } from './messages.js';
|
|
10
|
+
const QUESTION_TYPES = ['mood_direction', 'consensus_trust', 'neutral_factual', 'concrete_habit', 'values_identity', 'intention_virtue'];
|
|
11
|
+
const FORMATS = ['likert', 'single_choice', 'multi_select', 'ranking', 'free_text', 'price_trial'];
|
|
12
|
+
function defaultItem(i) {
|
|
13
|
+
return { key: `item-${Date.now().toString(36)}-${i}`, question: '', type: 'mood_direction', format: 'likert', anchors: ['', '', '', '', ''] };
|
|
14
|
+
}
|
|
15
|
+
/** The Research tab: the item list (add, reorder, remove) beside an editor for wording, type, format and anchors. */
|
|
16
|
+
export function ResearchBuilder({ items, defaultItems, onItemsChange, selectedKey, defaultSelectedKey, onSelectedKeyChange, anchorIssues = {}, createItem = defaultItem, editorToolbar, readOnly = false, messages, className, ...rest }) {
|
|
17
|
+
const m = studyMessages(messages);
|
|
18
|
+
const uid = useId().replace(/:/g, '');
|
|
19
|
+
const [list, setList] = useControllable(items, defaultItems ?? [], onItemsChange);
|
|
20
|
+
const [sel, setSel] = useControllable(selectedKey, defaultSelectedKey ?? list[0]?.key ?? null, onSelectedKeyChange);
|
|
21
|
+
const listRef = useRef(null);
|
|
22
|
+
const index = list.findIndex((x) => x.key === sel);
|
|
23
|
+
const item = index >= 0 ? list[index] : undefined;
|
|
24
|
+
const focusItem = (key) => requestAnimationFrame(() => Array.from(listRef.current?.querySelectorAll('[data-key]') ?? []).find((el) => el.dataset.key === key)?.focus());
|
|
25
|
+
const update = (patch) => {
|
|
26
|
+
if (!item)
|
|
27
|
+
return;
|
|
28
|
+
setList(list.map((x) => (x.key === item.key ? { ...x, ...patch } : x)));
|
|
29
|
+
};
|
|
30
|
+
const move = (i, dir) => {
|
|
31
|
+
const j = i + dir;
|
|
32
|
+
if (j < 0 || j >= list.length)
|
|
33
|
+
return;
|
|
34
|
+
const next = list.slice();
|
|
35
|
+
const a = next[i], b = next[j];
|
|
36
|
+
next[i] = b;
|
|
37
|
+
next[j] = a;
|
|
38
|
+
setList(next);
|
|
39
|
+
focusItem(a.key);
|
|
40
|
+
};
|
|
41
|
+
const remove = (i) => {
|
|
42
|
+
const gone = list[i];
|
|
43
|
+
const next = list.filter((_, j) => j !== i);
|
|
44
|
+
setList(next);
|
|
45
|
+
if (gone.key === sel) {
|
|
46
|
+
const n = next[Math.min(i, next.length - 1)];
|
|
47
|
+
setSel(n?.key ?? null);
|
|
48
|
+
if (n)
|
|
49
|
+
focusItem(n.key);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const add = () => {
|
|
53
|
+
const n = createItem(list.length);
|
|
54
|
+
setList([...list, n]);
|
|
55
|
+
setSel(n.key);
|
|
56
|
+
focusItem(n.key);
|
|
57
|
+
};
|
|
58
|
+
const issues = item ? (anchorIssues[item.key] ?? []) : [];
|
|
59
|
+
const id = (i) => m.itemId(i);
|
|
60
|
+
return (_jsxs("div", { ...rest, className: cx('ns-research', className), children: [_jsxs("div", { className: "ns-research__list", children: [_jsxs("div", { className: "ns-research__list-head", children: [_jsx("span", { children: m.items }), _jsx("span", { className: "ns-study-mono", children: list.length }), !readOnly && (_jsxs(Button, { size: "sm", className: "ns-study-panel__end", onClick: add, children: [_jsx(Icon, { name: "add", size: 14 }), " ", m.addItem] }))] }), list.length === 0 ? (_jsxs("div", { className: "ns-study-empty", children: [_jsx(EmptyResearch, {}), _jsx("p", { className: "ns-study-empty__title", children: m.emptyResearchTitle }), _jsx("p", { className: "ns-study-hint", children: m.emptyResearchBody })] })) : (_jsx("ol", { ref: listRef, className: "ns-research__items", "aria-label": m.items, children: list.map((x, i) => {
|
|
61
|
+
const fix = (anchorIssues[x.key]?.length ?? 0) > 0;
|
|
62
|
+
const on = x.key === sel;
|
|
63
|
+
return (_jsxs("li", { className: cx('ns-research__item', on && 'ns-research__item--on'), children: [_jsxs("button", { type: "button", className: "ns-research__select", "data-key": x.key, "aria-current": on || undefined, onClick: () => setSel(x.key), onKeyDown: (e) => {
|
|
64
|
+
if (readOnly || !e.altKey)
|
|
65
|
+
return;
|
|
66
|
+
if (e.key === 'ArrowUp') {
|
|
67
|
+
e.preventDefault();
|
|
68
|
+
move(i, -1);
|
|
69
|
+
}
|
|
70
|
+
if (e.key === 'ArrowDown') {
|
|
71
|
+
e.preventDefault();
|
|
72
|
+
move(i, 1);
|
|
73
|
+
}
|
|
74
|
+
}, children: [_jsx("span", { className: "ns-study-id", children: id(i) }), _jsx(Icon, { name: fix ? 'off-axis' : 'complete', size: 14, className: fix ? 'ns-study-signal' : 'ns-study-muted' }), _jsx("span", { className: "ns-research__q", children: x.question || '—' }), fix ? _jsx("span", { className: "ns-tag ns-tone-signal", children: m.needsFix }) : x.format && _jsx("span", { className: "ns-tag", children: m.formats[x.format] })] }), !readOnly && (_jsxs("span", { className: "ns-research__tools", children: [_jsx("button", { type: "button", className: "ns-study-icon-button", "aria-label": m.moveUp(id(i)), disabled: i === 0, onClick: () => move(i, -1), children: _jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", "aria-hidden": "true", children: _jsx("path", { d: "M3 7.5 6 4.5 9 7.5" }) }) }), _jsx("button", { type: "button", className: "ns-study-icon-button", "aria-label": m.moveDown(id(i)), disabled: i === list.length - 1, onClick: () => move(i, 1), children: _jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", "aria-hidden": "true", children: _jsx("path", { d: "M3 4.5 6 7.5 9 4.5" }) }) }), _jsx("button", { type: "button", className: "ns-study-icon-button", "aria-label": m.removeItem(id(i)), onClick: () => remove(i), children: _jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", "aria-hidden": "true", children: _jsx("path", { d: "M3 3l6 6M9 3l-6 6" }) }) })] }))] }, x.key));
|
|
75
|
+
}) }))] }), _jsx("div", { className: "ns-research__editor", children: !item ? (_jsx("p", { className: "ns-study-hint", children: m.selectItem })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "ns-research__editor-head", children: [_jsx("span", { className: "ns-study-id", children: id(index) }), _jsx(Select, { size: "sm", "aria-label": m.questionType, value: item.type, disabled: readOnly, options: QUESTION_TYPES.map((t) => ({ value: t, label: m.questionTypes[t] })), onValueChange: (t) => update({ type: t }) }), _jsx(Select, { size: "sm", "aria-label": m.format, value: item.format ?? 'likert', disabled: readOnly, options: FORMATS.map((f) => ({ value: f, label: m.formats[f] })), onValueChange: (f) => update({ format: f }) }), editorToolbar?.(item)] }), _jsx("textarea", { className: "ns-research__wording", rows: 2, "aria-label": m.wording, value: item.question, readOnly: readOnly, onChange: (e) => update({ question: e.target.value }) }), item.anchors && (_jsxs("fieldset", { className: "ns-research__anchors", children: [_jsx("legend", { className: "ns-study-label", children: m.anchors }), item.anchors.map((a, i) => {
|
|
76
|
+
const issue = issues.find((x) => x.anchor === i);
|
|
77
|
+
const descId = `ns-anchor-${uid}-${i}`;
|
|
78
|
+
return (_jsxs("div", { className: "ns-research__anchor", children: [_jsx("span", { className: "ns-study-id", children: i + 1 }), _jsx("input", { className: cx('ns-research__anchor-input', issue && 'ns-invalid'), "aria-label": m.anchorLabel(i), "aria-invalid": issue ? true : undefined, "aria-describedby": issue ? descId : undefined, value: a, readOnly: readOnly, onChange: (e) => update({ anchors: item.anchors.map((y, j) => (j === i ? e.target.value : y)) }) }), _jsx(Icon, { name: issue ? 'off-axis' : 'validate', size: 14, title: issue ? m.anchorNeedsFix : m.anchorPasses, className: issue ? 'ns-study-signal' : 'ns-study-muted' })] }, i));
|
|
79
|
+
})] })), issues.map((x) => (_jsxs("div", { id: `ns-anchor-${uid}-${x.anchor}`, className: "ns-study-callout", children: [_jsx("span", { className: "ns-tag ns-tone-signal", children: m.anchorLabel(x.anchor) }), _jsx("span", { children: x.message })] }, x.anchor))), _jsx("span", { className: "ns-study-hint", children: m.anchorHint })] })) })] }));
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=ResearchBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResearchBuilder.js","sourceRoot":"","sources":["../../src/northstar/ResearchBuilder.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { ResearchItem, Study } from '@northstar-js/contracts';
|
|
3
|
+
import { type WithMessages } from './messages.js';
|
|
4
|
+
export interface ResponsesViewProps extends React.HTMLAttributes<HTMLDivElement>, WithMessages {
|
|
5
|
+
study: Study;
|
|
6
|
+
/** 'objective' groups items under the study's objectives; 'item' lists them in battery order. */
|
|
7
|
+
groupBy?: 'objective' | 'item';
|
|
8
|
+
/** Which objective (index into `study.objectives`) an item belongs to. Default: the first. */
|
|
9
|
+
objectiveOf?: (item: ResearchItem, index: number) => number | undefined;
|
|
10
|
+
/** Extra content under an item's figure (a selected free-text answer, say). */
|
|
11
|
+
renderExtra?: (item: ResearchItem) => ReactNode;
|
|
12
|
+
/** Intro sentence above the figures; pass null to hide. */
|
|
13
|
+
intro?: ReactNode;
|
|
14
|
+
/** Width of each distribution chart. Default 320. */
|
|
15
|
+
chartWidth?: number;
|
|
16
|
+
locale?: string;
|
|
17
|
+
}
|
|
18
|
+
/** The Responses tab: one row per item with its headline figure and distribution, grouped by objective. */
|
|
19
|
+
export declare function ResponsesView({ study, groupBy, objectiveOf, renderExtra, intro, chartWidth, locale, messages, className, ...rest }: ResponsesViewProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=ResponsesView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResponsesView.d.ts","sourceRoot":"","sources":["../../src/northstar/ResponsesView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAInE,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAEjE,MAAM,WAAW,kBAAmB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,YAAY;IAC5F,KAAK,EAAE,KAAK,CAAC;IACb,iGAAiG;IACjG,OAAO,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC/B,8FAA8F;IAC9F,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxE,+EAA+E;IAC/E,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,SAAS,CAAC;IAChD,2DAA2D;IAC3D,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AASD,2GAA2G;AAC3G,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EAAE,OAAqB,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,UAAgB,EAAE,MAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EAC7H,EAAE,kBAAkB,2CA8EpB"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import {} from 'react';
|
|
3
|
+
import { Distribution, Figure } from '@northstar-js/charts';
|
|
4
|
+
import { EmptyResponses } from '../illustrations/index.js';
|
|
5
|
+
import { cx } from '../internal/util.js';
|
|
6
|
+
import { studyMessages } from './messages.js';
|
|
7
|
+
/** The Responses tab: one row per item with its headline figure and distribution, grouped by objective. */
|
|
8
|
+
export function ResponsesView({ study, groupBy = 'objective', objectiveOf, renderExtra, intro, chartWidth = 320, locale = 'en', messages, className, ...rest }) {
|
|
9
|
+
const m = studyMessages(messages);
|
|
10
|
+
const answered = study.items.map((item, index) => ({ item, index })).filter((r) => r.item.result);
|
|
11
|
+
if (answered.length === 0) {
|
|
12
|
+
return (_jsx("div", { ...rest, className: cx('ns-responses', className), children: _jsxs("div", { className: "ns-study-empty", children: [_jsx(EmptyResponses, {}), _jsx("p", { className: "ns-study-empty__title", children: m.emptyResponsesTitle }), _jsx("p", { className: "ns-study-hint", children: m.emptyResponsesBody })] }) }));
|
|
13
|
+
}
|
|
14
|
+
let groups;
|
|
15
|
+
if (groupBy === 'item' || study.objectives.length === 0) {
|
|
16
|
+
groups = [{ key: 'all', title: m.items, rows: answered }];
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
const by = new Map();
|
|
20
|
+
const other = { key: 'other', title: m.otherItems, rows: [] };
|
|
21
|
+
for (const r of answered) {
|
|
22
|
+
const o = objectiveOf ? objectiveOf(r.item, r.index) : 0;
|
|
23
|
+
if (o === undefined || !study.objectives[o]) {
|
|
24
|
+
other.rows.push(r);
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (!by.has(o))
|
|
28
|
+
by.set(o, { key: `o${o}`, code: `O${o + 1}`, title: study.objectives[o], rows: [] });
|
|
29
|
+
by.get(o).rows.push(r);
|
|
30
|
+
}
|
|
31
|
+
groups = [...[...by.entries()].sort((a, b) => a[0] - b[0]).map(([, g]) => g), ...(other.rows.length ? [other] : [])];
|
|
32
|
+
}
|
|
33
|
+
return (_jsxs("div", { ...rest, className: cx('ns-responses', className), children: [intro !== null && _jsx("p", { className: "ns-study-hint ns-responses__intro", children: intro ?? m.responsesIntro }), groups.map((g) => {
|
|
34
|
+
const hid = `ns-resp-${study.id}-${g.key}`;
|
|
35
|
+
return (_jsxs("section", { className: "ns-study-panel", "aria-labelledby": hid, children: [_jsxs("div", { className: "ns-study-panel__head", children: [g.code && _jsx("span", { className: "ns-study-id", children: g.code }), _jsx("h2", { id: hid, className: "ns-study-panel__title", children: g.title }), _jsx("span", { className: "ns-study-hint ns-study-panel__end", children: m.itemCount(g.rows.length) })] }), g.rows.map(({ item, index }) => {
|
|
36
|
+
const h = item.result.headline;
|
|
37
|
+
const d = item.result.distribution;
|
|
38
|
+
return (_jsxs("article", { className: "ns-responses__row", "aria-label": m.itemId(index), children: [_jsx("span", { className: "ns-study-id", children: m.itemId(index) }), _jsx("span", { className: "ns-responses__q", children: item.question }), _jsx("div", { className: "ns-responses__figure", children: h ? (_jsx(Figure, { value: h.value, size: "sm", locale: locale, ...(h.band !== undefined ? { band: h.band } : {}), ...(h.claim ? { claim: h.claim } : {}), ...(h.caption !== undefined ? { caption: h.caption } : {}), ...(h.state ? { state: h.state } : {}) })) : null }), _jsx("div", { className: "ns-responses__dist", children: _jsx(Distribution, { anchors: d.anchors, shares: d.shares, width: chartWidth, locale: locale, title: `${m.distribution} ${m.itemId(index)}` }) }), renderExtra && _jsx("div", { className: "ns-responses__extra", children: renderExtra(item) })] }, item.key));
|
|
39
|
+
})] }, g.key));
|
|
40
|
+
})] }));
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=ResponsesView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResponsesView.js","sourceRoot":"","sources":["../../src/northstar/ResponsesView.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { CostEstimate } from '@northstar-js/contracts';
|
|
3
|
+
import { type WithMessages } from './messages.js';
|
|
4
|
+
/** Format an estimate as currency, or null when there is none. */
|
|
5
|
+
export declare function formatCost(estimate: CostEstimate | undefined, locale?: string): string | null;
|
|
6
|
+
export interface RunCostProps extends React.HTMLAttributes<HTMLDivElement>, WithMessages {
|
|
7
|
+
/** null or undefined shows "Cost unavailable" and disables the run. */
|
|
8
|
+
estimate: CostEstimate | undefined;
|
|
9
|
+
/** Called by the run button. Omit to hide the button. */
|
|
10
|
+
onRun?: () => void;
|
|
11
|
+
/** Disable the run for another reason (an anchor to fix, say). */
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
/** Shown under the button, e.g. why the run is blocked. */
|
|
14
|
+
note?: ReactNode;
|
|
15
|
+
loading?: boolean;
|
|
16
|
+
locale?: string;
|
|
17
|
+
}
|
|
18
|
+
/** Estimated cost and the run button. Without an estimate the cost reads "Cost unavailable" and nothing can run. */
|
|
19
|
+
export declare function RunCost({ estimate, onRun, disabled, note, loading, locale, messages, className, ...rest }: RunCostProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export interface RunConfirmProps extends WithMessages {
|
|
21
|
+
open?: boolean;
|
|
22
|
+
defaultOpen?: boolean;
|
|
23
|
+
onOpenChange?: (open: boolean) => void;
|
|
24
|
+
estimate: CostEstimate | undefined;
|
|
25
|
+
/** Study title, shown in the body. */
|
|
26
|
+
studyTitle?: string;
|
|
27
|
+
onConfirm: () => void;
|
|
28
|
+
/** Optional trigger; usually the RunCost button opens the dialog through `open`. */
|
|
29
|
+
trigger?: ReactNode;
|
|
30
|
+
children?: ReactNode;
|
|
31
|
+
locale?: string;
|
|
32
|
+
}
|
|
33
|
+
/** The paid-run confirmation. Confirm is disabled while no estimate exists. */
|
|
34
|
+
export declare function RunConfirm({ open, defaultOpen, onOpenChange, estimate, studyTitle, onConfirm, trigger, children, locale, messages, }: RunConfirmProps): import("react/jsx-runtime").JSX.Element;
|
|
35
|
+
//# sourceMappingURL=Run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Run.d.ts","sourceRoot":"","sources":["../../src/northstar/Run.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAI5D,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAEjE,kEAAkE;AAClE,wBAAgB,UAAU,CAAC,QAAQ,EAAE,YAAY,GAAG,SAAS,EAAE,MAAM,SAAO,GAAG,MAAM,GAAG,IAAI,CAO3F;AAED,MAAM,WAAW,YAAa,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,YAAY;IACtF,uEAAuE;IACvE,QAAQ,EAAE,YAAY,GAAG,SAAS,CAAC;IACnC,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,oHAAoH;AACpH,wBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAgB,EAAE,IAAI,EAAE,OAAO,EAAE,MAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,YAAY,2CAoBtI;AAED,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,QAAQ,EAAE,YAAY,GAAG,SAAS,CAAC;IACnC,sCAAsC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,oFAAoF;IACpF,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,EACzB,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAa,EAAE,QAAQ,GAC7G,EAAE,eAAe,2CAmCjB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Button } from '../actions.js';
|
|
4
|
+
import { Dialog } from '../overlays.js';
|
|
5
|
+
import { cx } from '../internal/util.js';
|
|
6
|
+
import { studyMessages } from './messages.js';
|
|
7
|
+
/** Format an estimate as currency, or null when there is none. */
|
|
8
|
+
export function formatCost(estimate, locale = 'en') {
|
|
9
|
+
if (!estimate)
|
|
10
|
+
return null;
|
|
11
|
+
try {
|
|
12
|
+
return new Intl.NumberFormat(locale, { style: 'currency', currency: estimate.currency }).format(estimate.amount);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return `${estimate.amount} ${estimate.currency}`;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/** Estimated cost and the run button. Without an estimate the cost reads "Cost unavailable" and nothing can run. */
|
|
19
|
+
export function RunCost({ estimate, onRun, disabled = false, note, loading, locale = 'en', messages, className, ...rest }) {
|
|
20
|
+
const m = studyMessages(messages);
|
|
21
|
+
const cost = formatCost(estimate, locale);
|
|
22
|
+
const unavailable = cost === null;
|
|
23
|
+
return (_jsxs("div", { ...rest, className: cx('ns-run-cost', className), "data-unavailable": unavailable || undefined, children: [_jsxs("div", { className: "ns-run-cost__line", children: [_jsx("span", { className: "ns-study-muted", children: m.estimatedCost }), _jsx("span", { className: cx('ns-study-mono', unavailable && 'ns-study-muted'), children: cost ?? m.costUnavailable })] }), estimate?.basis && _jsx("span", { className: "ns-study-hint", children: estimate.basis }), onRun && (_jsx(Button, { variant: "primary", onClick: onRun, disabled: unavailable || disabled, loading: loading ?? false, className: "ns-run-cost__button", children: m.runStudy })), unavailable && _jsx("span", { className: "ns-study-hint", children: m.costUnavailableHint }), note && _jsx("div", { className: "ns-study-callout", children: note })] }));
|
|
24
|
+
}
|
|
25
|
+
/** The paid-run confirmation. Confirm is disabled while no estimate exists. */
|
|
26
|
+
export function RunConfirm({ open, defaultOpen, onOpenChange, estimate, studyTitle, onConfirm, trigger, children, locale = 'en', messages, }) {
|
|
27
|
+
const m = studyMessages(messages);
|
|
28
|
+
const cost = formatCost(estimate, locale);
|
|
29
|
+
return (_jsxs(Dialog.Root, { ...(open !== undefined ? { open } : {}), ...(defaultOpen !== undefined ? { defaultOpen } : {}), ...(onOpenChange ? { onOpenChange } : {}), children: [trigger && _jsx(Dialog.Trigger, { className: "ns-button ns-button--secondary ns-size-md", children: trigger }), _jsxs(Dialog.Content, { size: "sm", children: [_jsxs(Dialog.Header, { children: [_jsxs("div", { children: [_jsx(Dialog.Title, { children: m.runConfirmTitle }), _jsxs(Dialog.Description, { children: [studyTitle ? `${studyTitle}. ` : '', m.runConfirmBody] })] }), _jsx(Dialog.Close, {})] }), _jsxs("div", { className: "ns-run-cost__line ns-run-confirm__cost", children: [_jsx("span", { className: "ns-study-muted", children: m.estimatedCost }), _jsx("span", { className: "ns-study-mono", children: cost ?? m.costUnavailable })] }), children, _jsxs(Dialog.Footer, { children: [_jsx(Dialog.Close, { className: "ns-button ns-button--secondary ns-size-md", children: m.cancel }), _jsx(Dialog.Close, { className: "ns-button ns-button--primary ns-size-md", disabled: cost === null, onClick: () => onConfirm(), children: m.confirmRun })] })] })] }));
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=Run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Run.js","sourceRoot":"","sources":["../../src/northstar/Run.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { Study, StudyTab } from '@northstar-js/contracts';
|
|
3
|
+
import { type WithMessages } from './messages.js';
|
|
4
|
+
export declare const STUDY_TABS: readonly StudyTab[];
|
|
5
|
+
export interface StudyShellProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'>, WithMessages {
|
|
6
|
+
study: Study;
|
|
7
|
+
/** The open tab (controlled). Falls back to `defaultTab`, then `study.tab`, then 'brief'. */
|
|
8
|
+
tab?: StudyTab;
|
|
9
|
+
defaultTab?: StudyTab;
|
|
10
|
+
onTabChange?: (tab: StudyTab) => void;
|
|
11
|
+
/** Content per tab. `children` renders under the active tab when no panel is given for it. */
|
|
12
|
+
panels?: Partial<Record<StudyTab, ReactNode>>;
|
|
13
|
+
/** Small counter beside each tab label, e.g. "2/3" or "locked". */
|
|
14
|
+
tabMeta?: Partial<Record<StudyTab, ReactNode>>;
|
|
15
|
+
/** Actions at the end of the tab bar (e.g. "Add item" on Research). */
|
|
16
|
+
tabActions?: ReactNode;
|
|
17
|
+
/** Actions at the end of the title bar (export, more). */
|
|
18
|
+
actions?: ReactNode;
|
|
19
|
+
/** Save indicator; omit to hide. */
|
|
20
|
+
saveState?: 'saved' | 'saving';
|
|
21
|
+
/** The breadcrumb root. Defaults to "Studies". */
|
|
22
|
+
crumb?: ReactNode;
|
|
23
|
+
/** Right-hand properties rail. */
|
|
24
|
+
aside?: ReactNode;
|
|
25
|
+
}
|
|
26
|
+
/** The study workspace: title bar, the four tabs Brief → Population → Research → Responses, content and an optional rail. */
|
|
27
|
+
export declare function StudyShell({ study, tab, defaultTab, onTabChange, panels, tabMeta, tabActions, actions, saveState, crumb, aside, messages, className, children, ...rest }: StudyShellProps): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
//# sourceMappingURL=StudyShell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StudyShell.d.ts","sourceRoot":"","sources":["../../src/northstar/StudyShell.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAI/D,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAEjE,eAAO,MAAM,UAAU,EAAE,SAAS,QAAQ,EAAqD,CAAC;AAEhG,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY;IACxG,KAAK,EAAE,KAAK,CAAC;IACb,6FAA6F;IAC7F,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,UAAU,CAAC,EAAE,QAAQ,CAAC;IACtB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC;IACtC,8FAA8F;IAC9F,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;IAC9C,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;IAC/C,uEAAuE;IACvE,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,oCAAoC;IACpC,SAAS,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC/B,kDAAkD;IAClD,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,kCAAkC;IAClC,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,6HAA6H;AAC7H,wBAAgB,UAAU,CAAC,EACzB,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI,EAC3I,EAAE,eAAe,2CA+CjB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Tabs } from '../navigation.js';
|
|
4
|
+
import { cx, useControllable } from '../internal/util.js';
|
|
5
|
+
import { StudyStatus } from './StudyStatus.js';
|
|
6
|
+
import { studyMessages } from './messages.js';
|
|
7
|
+
export const STUDY_TABS = ['brief', 'population', 'research', 'responses'];
|
|
8
|
+
/** The study workspace: title bar, the four tabs Brief → Population → Research → Responses, content and an optional rail. */
|
|
9
|
+
export function StudyShell({ study, tab, defaultTab, onTabChange, panels, tabMeta, tabActions, actions, saveState, crumb, aside, messages, className, children, ...rest }) {
|
|
10
|
+
const m = studyMessages(messages);
|
|
11
|
+
const [current, setCurrent] = useControllable(tab, defaultTab ?? study.tab ?? 'brief', onTabChange);
|
|
12
|
+
return (_jsxs("div", { ...rest, className: cx('ns-study-shell', aside ? 'ns-study-shell--with-aside' : undefined, className), "data-study": study.id, children: [_jsxs("div", { className: "ns-study-shell__main", children: [_jsxs("div", { className: "ns-study-shell__bar", children: [_jsxs("nav", { className: "ns-study-shell__crumb", "aria-label": m.studies, children: [_jsx("span", { children: crumb ?? m.studies }), _jsx("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", stroke: "currentColor", strokeWidth: "1.5", "aria-hidden": "true", children: _jsx("path", { d: "M3.5 2 6.5 5 3.5 8" }) }), _jsx("b", { "aria-current": "page", children: study.title })] }), _jsx(StudyStatus, { state: study.state, messages: messages }), _jsx("span", { className: "ns-study-shell__spacer" }), saveState && (_jsx("span", { className: "ns-study-shell__save", role: "status", children: saveState === 'saving' ? m.saving : m.saved })), actions] }), _jsxs(Tabs.Root, { value: current, onValueChange: (v) => setCurrent(v), className: "ns-study-shell__tabs", children: [_jsxs("div", { className: "ns-study-shell__tabbar", children: [_jsx(Tabs.List, { label: m.studySections, className: "ns-study-shell__tablist", children: STUDY_TABS.map((t) => (_jsxs(Tabs.Trigger, { value: t, className: "ns-study-shell__tab", children: [m.tabs[t], tabMeta?.[t] !== undefined && _jsx("span", { className: "ns-study-shell__tab-meta", children: tabMeta[t] })] }, t))) }), tabActions && _jsx("div", { className: "ns-study-shell__tab-actions", children: tabActions })] }), _jsx(Tabs.Content, { value: current, className: "ns-study-shell__content", children: panels?.[current] ?? children })] })] }), aside && (_jsx("aside", { className: "ns-study-shell__aside", "aria-label": m.studyProperties, children: aside }))] }));
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=StudyShell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StudyShell.js","sourceRoot":"","sources":["../../src/northstar/StudyShell.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { StudyState } from '@northstar-js/contracts';
|
|
2
|
+
import { type IconName } from '@northstar-js/icons';
|
|
3
|
+
import { type WithMessages } from './messages.js';
|
|
4
|
+
/** One dial shape per state: status is told apart by shape and word, never by hue alone. */
|
|
5
|
+
export declare const STATUS_ICON: Record<StudyState, IconName>;
|
|
6
|
+
export interface StudyStatusProps extends React.HTMLAttributes<HTMLSpanElement>, WithMessages {
|
|
7
|
+
state: StudyState;
|
|
8
|
+
/** 'tag' draws a bordered chip; 'inline' only the mark and word. */
|
|
9
|
+
variant?: 'tag' | 'inline';
|
|
10
|
+
/** Icon size in px. */
|
|
11
|
+
size?: number;
|
|
12
|
+
}
|
|
13
|
+
/** Study lifecycle state: a dial shape plus its word. Running sweeps, or stands still under reduced motion. */
|
|
14
|
+
export declare function StudyStatus({ state, variant, size, messages, className, ...rest }: StudyStatusProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
//# sourceMappingURL=StudyStatus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StudyStatus.d.ts","sourceRoot":"","sources":["../../src/northstar/StudyStatus.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAQ,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG1D,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAEjE,4FAA4F;AAC5F,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,UAAU,EAAE,QAAQ,CAQpD,CAAC;AAEF,MAAM,WAAW,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,YAAY;IAC3F,KAAK,EAAE,UAAU,CAAC;IAClB,oEAAoE;IACpE,OAAO,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC3B,uBAAuB;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,+GAA+G;AAC/G,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,OAAe,EAAE,IAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,gBAAgB,2CAehH"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Icon } from '@northstar-js/icons';
|
|
4
|
+
import { usePrefersReducedMotion } from '@northstar-js/motion';
|
|
5
|
+
import { cx } from '../internal/util.js';
|
|
6
|
+
import { studyMessages } from './messages.js';
|
|
7
|
+
/** One dial shape per state: status is told apart by shape and word, never by hue alone. */
|
|
8
|
+
export const STATUS_ICON = {
|
|
9
|
+
draft: 'draft',
|
|
10
|
+
ready: 'study',
|
|
11
|
+
running: 'running',
|
|
12
|
+
complete: 'complete',
|
|
13
|
+
partial: 'drift',
|
|
14
|
+
failed: 'off-axis',
|
|
15
|
+
archived: 'locked',
|
|
16
|
+
};
|
|
17
|
+
/** Study lifecycle state: a dial shape plus its word. Running sweeps, or stands still under reduced motion. */
|
|
18
|
+
export function StudyStatus({ state, variant = 'tag', size = 14, messages, className, ...rest }) {
|
|
19
|
+
const m = studyMessages(messages);
|
|
20
|
+
const reduced = usePrefersReducedMotion();
|
|
21
|
+
const motion = state === 'running' ? (reduced ? 'still' : 'sweep') : undefined;
|
|
22
|
+
return (_jsxs("span", { ...rest, className: cx('ns-study-status', `ns-study-status--${variant}`, `ns-study-status--${state}`, className), "data-state": state, ...(motion ? { 'data-motion': motion } : {}), children: [_jsx(Icon, { name: STATUS_ICON[state], size: size, className: "ns-study-status__mark" }), _jsx("span", { className: "ns-study-status__word", children: m.states[state] })] }));
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=StudyStatus.js.map
|