@medicine-wheel/ui-components 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # @medicine-wheel/ui-components
2
+
3
+ React UI components for the Medicine Wheel Developer Suite — direction cards, beat timelines, node inspectors, OCAP® badges, and Wilson alignment gauges.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @medicine-wheel/ui-components
9
+ ```
10
+
11
+ ## Components
12
+
13
+ ### DirectionCard
14
+ Displays a direction with color coding, Ojibwe name, season, and teachings.
15
+
16
+ ```tsx
17
+ import { DirectionCard } from '@medicine-wheel/ui-components';
18
+
19
+ <DirectionCard direction="east" showOjibwe onClick={handleClick} />
20
+ ```
21
+
22
+ ### BeatTimeline
23
+ Horizontal timeline of narrative beats with direction-coded markers.
24
+
25
+ ```tsx
26
+ import { BeatTimeline } from '@medicine-wheel/ui-components';
27
+
28
+ <BeatTimeline beats={beats} onBeatClick={handleSelect} selectedId="b1" />
29
+ ```
30
+
31
+ ### NodeInspector
32
+ Detail panel for a RelationalNode showing type, direction, metadata, and connections.
33
+
34
+ ```tsx
35
+ import { NodeInspector } from '@medicine-wheel/ui-components';
36
+
37
+ <NodeInspector node={node} edges={edges} allNodes={allNodes} onNavigate={goToNode} />
38
+ ```
39
+
40
+ ### OcapBadge
41
+ Compact OCAP® compliance indicator.
42
+
43
+ ```tsx
44
+ import { OcapBadge } from '@medicine-wheel/ui-components';
45
+
46
+ <OcapBadge ocap={relation.ocap} detailed />
47
+ ```
48
+
49
+ ### WilsonMeter
50
+ SVG gauge for Wilson relational alignment (0–1).
51
+
52
+ ```tsx
53
+ import { WilsonMeter } from '@medicine-wheel/ui-components';
54
+
55
+ <WilsonMeter alignment={0.73} size={48} />
56
+ ```
57
+
58
+ ## Peer dependencies
59
+
60
+ - `react` ^18.0.0 || ^19.0.0
61
+ - `@medicine-wheel/ontology-core` ^0.1.0
62
+
63
+ ## License
64
+
65
+ MIT
66
+
@@ -0,0 +1,14 @@
1
+ import type { NarrativeBeat } from '@medicine-wheel/ontology-core';
2
+ export interface BeatTimelineProps {
3
+ beats: NarrativeBeat[];
4
+ /** Selected beat ID */
5
+ selectedId?: string;
6
+ /** Click handler */
7
+ onBeatClick?: (beat: NarrativeBeat) => void;
8
+ /** Timeline height in px */
9
+ height?: number;
10
+ /** Custom className */
11
+ className?: string;
12
+ }
13
+ export declare function BeatTimeline({ beats, selectedId, onBeatClick, height, className, }: BeatTimelineProps): import("react/jsx-runtime").JSX.Element;
14
+ //# sourceMappingURL=BeatTimeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BeatTimeline.d.ts","sourceRoot":"","sources":["../src/BeatTimeline.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,+BAA+B,CAAC;AAOlF,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,uBAAuB;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oBAAoB;IACpB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;IAC5C,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,UAAU,EACV,WAAW,EACX,MAAY,EACZ,SAAc,GACf,EAAE,iBAAiB,2CAgGnB"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BeatTimeline = BeatTimeline;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const ontology_core_1 = require("@medicine-wheel/ontology-core");
6
+ const DIR_ICONS = {
7
+ east: '🌅', south: '🔥', west: '🌊', north: '❄️',
8
+ };
9
+ function BeatTimeline({ beats, selectedId, onBeatClick, height = 120, className = '', }) {
10
+ const sorted = [...beats].sort((a, b) => a.timestamp.localeCompare(b.timestamp));
11
+ if (sorted.length === 0) {
12
+ return ((0, jsx_runtime_1.jsx)("div", { className: className, style: { height, display: 'flex', alignItems: 'center', justifyContent: 'center', opacity: 0.5, fontSize: '14px' }, children: "No beats yet" }));
13
+ }
14
+ return ((0, jsx_runtime_1.jsxs)("div", { className: className, style: { height, position: 'relative', overflow: 'hidden' }, children: [(0, jsx_runtime_1.jsx)("div", { style: {
15
+ position: 'absolute',
16
+ top: '50%',
17
+ left: '24px',
18
+ right: '24px',
19
+ height: '2px',
20
+ background: 'currentColor',
21
+ opacity: 0.2,
22
+ } }), (0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', alignItems: 'center', height: '100%', padding: '0 16px', gap: '0' }, children: sorted.map((beat, i) => {
23
+ const color = ontology_core_1.DIRECTION_COLORS[beat.direction];
24
+ const icon = DIR_ICONS[beat.direction];
25
+ const isSelected = beat.id === selectedId;
26
+ const leftPercent = sorted.length === 1 ? 50 : (i / (sorted.length - 1)) * 100;
27
+ return ((0, jsx_runtime_1.jsxs)("div", { onClick: () => onBeatClick?.(beat), role: onBeatClick ? 'button' : undefined, tabIndex: onBeatClick ? 0 : undefined, onKeyDown: (e) => { if (e.key === 'Enter' && onBeatClick)
28
+ onBeatClick(beat); }, style: {
29
+ position: 'absolute',
30
+ left: `${leftPercent}%`,
31
+ top: '50%',
32
+ transform: 'translate(-50%, -50%)',
33
+ display: 'flex',
34
+ flexDirection: 'column',
35
+ alignItems: 'center',
36
+ cursor: onBeatClick ? 'pointer' : 'default',
37
+ }, children: [(0, jsx_runtime_1.jsxs)("span", { style: { fontSize: '10px', opacity: 0.5, marginBottom: '4px' }, children: ["Act ", beat.act] }), (0, jsx_runtime_1.jsx)("div", { style: {
38
+ width: isSelected ? '36px' : '28px',
39
+ height: isSelected ? '36px' : '28px',
40
+ borderRadius: '50%',
41
+ background: `${color}30`,
42
+ border: `2px solid ${color}`,
43
+ display: 'flex',
44
+ alignItems: 'center',
45
+ justifyContent: 'center',
46
+ fontSize: isSelected ? '16px' : '14px',
47
+ transition: 'all 0.2s ease',
48
+ boxShadow: isSelected ? `0 0 12px ${color}40` : 'none',
49
+ }, children: icon }), (0, jsx_runtime_1.jsx)("span", { style: {
50
+ fontSize: '11px',
51
+ marginTop: '4px',
52
+ maxWidth: '80px',
53
+ overflow: 'hidden',
54
+ textOverflow: 'ellipsis',
55
+ whiteSpace: 'nowrap',
56
+ textAlign: 'center',
57
+ fontWeight: isSelected ? 600 : 400,
58
+ }, children: beat.title }), beat.ceremonies.length > 0 && ((0, jsx_runtime_1.jsx)("span", { style: { fontSize: '8px', marginTop: '2px' }, children: "\uD83D\uDD25" }))] }, beat.id));
59
+ }) })] }));
60
+ }
61
+ //# sourceMappingURL=BeatTimeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BeatTimeline.js","sourceRoot":"","sources":["../src/BeatTimeline.tsx"],"names":[],"mappings":";;AAwBA,oCAsGC;;AAxHD,iEAAiE;AAEjE,MAAM,SAAS,GAAkC;IAC/C,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI;CACjD,CAAC;AAcF,SAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,UAAU,EACV,WAAW,EACX,MAAM,GAAG,GAAG,EACZ,SAAS,GAAG,EAAE,GACI;IAClB,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAEjF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CACL,gCAAK,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,6BAEvI,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,iCAAK,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAEpF,gCAAK,KAAK,EAAE;oBACV,QAAQ,EAAE,UAAU;oBACpB,GAAG,EAAE,KAAK;oBACV,IAAI,EAAE,MAAM;oBACZ,KAAK,EAAE,MAAM;oBACb,MAAM,EAAE,KAAK;oBACb,UAAU,EAAE,cAAc;oBAC1B,OAAO,EAAE,GAAG;iBACb,GAAI,EAGL,gCAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,YAC/F,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;oBACtB,MAAM,KAAK,GAAG,gCAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBAC/C,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBACvC,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,KAAK,UAAU,CAAC;oBAC1C,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;oBAE/E,OAAO,CACL,iCAEE,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,EAClC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EACxC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EACrC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,WAAW;4BAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAC9E,KAAK,EAAE;4BACL,QAAQ,EAAE,UAAU;4BACpB,IAAI,EAAE,GAAG,WAAW,GAAG;4BACvB,GAAG,EAAE,KAAK;4BACV,SAAS,EAAE,uBAAuB;4BAClC,OAAO,EAAE,MAAM;4BACf,aAAa,EAAE,QAAQ;4BACvB,UAAU,EAAE,QAAQ;4BACpB,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;yBAC5C,aAGD,kCAAM,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,qBAC7D,IAAI,CAAC,GAAG,IACR,EAGP,gCAAK,KAAK,EAAE;oCACV,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;oCACnC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;oCACpC,YAAY,EAAE,KAAK;oCACnB,UAAU,EAAE,GAAG,KAAK,IAAI;oCACxB,MAAM,EAAE,aAAa,KAAK,EAAE;oCAC5B,OAAO,EAAE,MAAM;oCACf,UAAU,EAAE,QAAQ;oCACpB,cAAc,EAAE,QAAQ;oCACxB,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;oCACtC,UAAU,EAAE,eAAe;oCAC3B,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM;iCACvD,YACE,IAAI,GACD,EAGN,iCAAM,KAAK,EAAE;oCACX,QAAQ,EAAE,MAAM;oCAChB,SAAS,EAAE,KAAK;oCAChB,QAAQ,EAAE,MAAM;oCAChB,QAAQ,EAAE,QAAQ;oCAClB,YAAY,EAAE,UAAU;oCACxB,UAAU,EAAE,QAAQ;oCACpB,SAAS,EAAE,QAAQ;oCACnB,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;iCACnC,YACE,IAAI,CAAC,KAAK,GACN,EAGN,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,CAC7B,iCAAM,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,6BAAW,CAC9D,KAvDI,IAAI,CAAC,EAAE,CAwDR,CACP,CAAC;gBACJ,CAAC,CAAC,GACE,IACF,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { Direction, DirectionName } from '@medicine-wheel/ontology-core';
2
+ export interface DirectionCardProps {
3
+ direction: DirectionName;
4
+ /** Optional override data (defaults to DIRECTIONS constant) */
5
+ data?: Direction;
6
+ /** Show the Ojibwe name */
7
+ showOjibwe?: boolean;
8
+ /** Click handler */
9
+ onClick?: (direction: DirectionName) => void;
10
+ /** Whether this card is selected */
11
+ selected?: boolean;
12
+ /** Custom className */
13
+ className?: string;
14
+ }
15
+ export declare function DirectionCard({ direction, data, showOjibwe, onClick, selected, className, }: DirectionCardProps): import("react/jsx-runtime").JSX.Element | null;
16
+ //# sourceMappingURL=DirectionCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DirectionCard.d.ts","sourceRoot":"","sources":["../src/DirectionCard.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAO9E,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,aAAa,CAAC;IACzB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oBAAoB;IACpB,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,oCAAoC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,IAAI,EACJ,UAAiB,EACjB,OAAO,EACP,QAAgB,EAChB,SAAc,GACf,EAAE,kBAAkB,kDAwCpB"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DirectionCard = DirectionCard;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const ontology_core_1 = require("@medicine-wheel/ontology-core");
6
+ const DIR_ICONS = {
7
+ east: '🌅', south: '🔥', west: '🌊', north: '❄️',
8
+ };
9
+ function DirectionCard({ direction, data, showOjibwe = true, onClick, selected = false, className = '', }) {
10
+ const dir = data ?? ontology_core_1.DIRECTIONS.find(d => d.name === direction);
11
+ if (!dir)
12
+ return null;
13
+ const color = ontology_core_1.DIRECTION_COLORS[direction];
14
+ const icon = DIR_ICONS[direction];
15
+ return ((0, jsx_runtime_1.jsxs)("div", { onClick: () => onClick?.(direction), role: onClick ? 'button' : undefined, tabIndex: onClick ? 0 : undefined, onKeyDown: (e) => { if (e.key === 'Enter' && onClick)
16
+ onClick(direction); }, className: className, style: {
17
+ border: `2px solid ${selected ? color : 'transparent'}`,
18
+ borderRadius: '12px',
19
+ padding: '16px',
20
+ background: selected ? `${color}15` : 'transparent',
21
+ cursor: onClick ? 'pointer' : 'default',
22
+ transition: 'all 0.2s ease',
23
+ }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '8px' }, children: [(0, jsx_runtime_1.jsx)("span", { style: { fontSize: '24px' }, children: icon }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h3", { style: { margin: 0, color, textTransform: 'capitalize', fontSize: '16px', fontWeight: 600 }, children: dir.name }), showOjibwe && ((0, jsx_runtime_1.jsx)("span", { style: { fontSize: '12px', opacity: 0.7, fontStyle: 'italic' }, children: dir.ojibwe }))] })] }), (0, jsx_runtime_1.jsx)("p", { style: { margin: '4px 0', fontSize: '13px', opacity: 0.8 }, children: dir.medicine.join(', ') }), (0, jsx_runtime_1.jsxs)("p", { style: { margin: '4px 0', fontSize: '12px', opacity: 0.6 }, children: [dir.season, " \u00B7 ", dir.lifeStage] })] }));
24
+ }
25
+ //# sourceMappingURL=DirectionCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DirectionCard.js","sourceRoot":"","sources":["../src/DirectionCard.tsx"],"names":[],"mappings":";;AA0BA,sCA+CC;;AAnED,iEAA2F;AAE3F,MAAM,SAAS,GAAkC;IAC/C,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI;CACjD,CAAC;AAgBF,SAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,IAAI,EACJ,UAAU,GAAG,IAAI,EACjB,OAAO,EACP,QAAQ,GAAG,KAAK,EAChB,SAAS,GAAG,EAAE,GACK;IACnB,MAAM,GAAG,GAAG,IAAI,IAAI,0BAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;IAC/D,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAEtB,MAAM,KAAK,GAAG,gCAAgB,CAAC,SAAS,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IAElC,OAAO,CACL,iCACE,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,EACnC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EACpC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EACjC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,OAAO;YAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAC3E,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE;YACL,MAAM,EAAE,aAAa,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,EAAE;YACvD,YAAY,EAAE,MAAM;YACpB,OAAO,EAAE,MAAM;YACf,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,aAAa;YACnD,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YACvC,UAAU,EAAE,eAAe;SAC5B,aAED,iCAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,aACpF,iCAAM,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAG,IAAI,GAAQ,EAChD,4CACE,+BAAI,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,YAC5F,GAAG,CAAC,IAAI,GACN,EACJ,UAAU,IAAI,CACb,iCAAM,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,YACjE,GAAG,CAAC,MAAM,GACN,CACR,IACG,IACF,EACN,8BAAG,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,YAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAK,EAC5F,+BAAG,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,aAAG,GAAG,CAAC,MAAM,cAAK,GAAG,CAAC,SAAS,IAAK,IAC7F,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { RelationalNode, RelationalEdge } from '@medicine-wheel/ontology-core';
2
+ export interface NodeInspectorProps {
3
+ node: RelationalNode;
4
+ edges?: RelationalEdge[];
5
+ /** All nodes for resolving edge endpoints */
6
+ allNodes?: RelationalNode[];
7
+ /** Close handler */
8
+ onClose?: () => void;
9
+ /** Navigate to connected node */
10
+ onNavigate?: (nodeId: string) => void;
11
+ /** Custom className */
12
+ className?: string;
13
+ }
14
+ export declare function NodeInspector({ node, edges, allNodes, onClose, onNavigate, className, }: NodeInspectorProps): import("react/jsx-runtime").JSX.Element;
15
+ //# sourceMappingURL=NodeInspector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeInspector.d.ts","sourceRoot":"","sources":["../src/NodeInspector.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAiB,MAAM,+BAA+B,CAAC;AAOnG,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;IAC5B,oBAAoB;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,iCAAiC;IACjC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,KAAU,EACV,QAAa,EACb,OAAO,EACP,UAAU,EACV,SAAc,GACf,EAAE,kBAAkB,2CA4GpB"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NodeInspector = NodeInspector;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const ontology_core_1 = require("@medicine-wheel/ontology-core");
6
+ const DIR_ICONS = {
7
+ east: '🌅', south: '🔥', west: '🌊', north: '❄️',
8
+ };
9
+ function NodeInspector({ node, edges = [], allNodes = [], onClose, onNavigate, className = '', }) {
10
+ const color = node.direction ? ontology_core_1.DIRECTION_COLORS[node.direction] : '#888';
11
+ const icon = node.direction ? DIR_ICONS[node.direction] : '◯';
12
+ const typeColor = ontology_core_1.NODE_TYPE_COLORS[node.type] ?? '#888';
13
+ const nodeMap = new Map(allNodes.map(n => [n.id, n]));
14
+ // Find connected edges
15
+ const connectedEdges = edges.filter(e => e.from_id === node.id || e.to_id === node.id);
16
+ return ((0, jsx_runtime_1.jsxs)("div", { className: className, style: { borderRadius: '12px', border: `1px solid ${color}40`, overflow: 'hidden' }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { padding: '16px', borderBottom: `1px solid ${color}20`, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center', gap: '8px' }, children: [(0, jsx_runtime_1.jsx)("span", { style: { fontSize: '20px' }, children: icon }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h3", { style: { margin: 0, fontSize: '16px', fontWeight: 600 }, children: node.name }), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', gap: '8px', marginTop: '4px' }, children: [(0, jsx_runtime_1.jsx)("span", { style: { fontSize: '11px', padding: '2px 8px', borderRadius: '4px', background: `${typeColor}20`, color: typeColor }, children: node.type }), node.direction && ((0, jsx_runtime_1.jsx)("span", { style: { fontSize: '11px', padding: '2px 8px', borderRadius: '4px', background: `${color}20`, color, textTransform: 'capitalize' }, children: node.direction }))] })] })] }), onClose && ((0, jsx_runtime_1.jsx)("button", { onClick: onClose, style: { background: 'none', border: 'none', cursor: 'pointer', fontSize: '18px', opacity: 0.5, color: 'inherit' }, "aria-label": "Close inspector", children: "\u2715" }))] }), node.metadata && Object.keys(node.metadata).length > 0 && ((0, jsx_runtime_1.jsxs)("div", { style: { padding: '12px 16px', borderBottom: '1px solid rgba(128,128,128,0.1)' }, children: [(0, jsx_runtime_1.jsx)("h4", { style: { margin: '0 0 8px', fontSize: '12px', opacity: 0.5, textTransform: 'uppercase' }, children: "Metadata" }), Object.entries(node.metadata).map(([key, value]) => ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', justifyContent: 'space-between', fontSize: '13px', padding: '2px 0' }, children: [(0, jsx_runtime_1.jsx)("span", { style: { opacity: 0.6 }, children: key }), (0, jsx_runtime_1.jsx)("span", { children: String(value) })] }, key)))] })), connectedEdges.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { style: { padding: '12px 16px' }, children: [(0, jsx_runtime_1.jsxs)("h4", { style: { margin: '0 0 8px', fontSize: '12px', opacity: 0.5, textTransform: 'uppercase' }, children: ["Relations (", connectedEdges.length, ")"] }), connectedEdges.map((edge, i) => {
17
+ const otherId = edge.from_id === node.id ? edge.to_id : edge.from_id;
18
+ const otherNode = nodeMap.get(otherId);
19
+ const otherColor = otherNode?.direction ? ontology_core_1.DIRECTION_COLORS[otherNode.direction] : '#888';
20
+ return ((0, jsx_runtime_1.jsxs)("div", { onClick: () => onNavigate?.(otherId), role: onNavigate ? 'button' : undefined, tabIndex: onNavigate ? 0 : undefined, onKeyDown: (e) => { if (e.key === 'Enter' && onNavigate)
21
+ onNavigate(otherId); }, style: {
22
+ display: 'flex',
23
+ justifyContent: 'space-between',
24
+ alignItems: 'center',
25
+ padding: '6px 8px',
26
+ borderRadius: '6px',
27
+ fontSize: '13px',
28
+ cursor: onNavigate ? 'pointer' : 'default',
29
+ marginBottom: '4px',
30
+ background: 'rgba(128,128,128,0.05)',
31
+ }, children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("span", { style: { opacity: 0.5, fontSize: '11px' }, children: edge.relationship_type }), (0, jsx_runtime_1.jsx)("span", { style: { margin: '0 6px' }, children: "\u2192" }), (0, jsx_runtime_1.jsx)("span", { style: { color: otherColor, fontWeight: 500 }, children: otherNode?.name ?? otherId })] }), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', gap: '6px', alignItems: 'center' }, children: [(0, jsx_runtime_1.jsxs)("span", { style: { fontSize: '11px', opacity: 0.5 }, children: [(edge.strength * 100).toFixed(0), "%"] }), edge.ceremony_honored && (0, jsx_runtime_1.jsx)("span", { style: { fontSize: '10px' }, children: "\uD83D\uDD25" })] })] }, i));
32
+ })] })), (0, jsx_runtime_1.jsxs)("div", { style: { padding: '8px 16px', fontSize: '11px', opacity: 0.4, borderTop: '1px solid rgba(128,128,128,0.1)' }, children: ["ID: ", node.id, " \u00B7 Created: ", new Date(node.created_at).toLocaleDateString()] })] }));
33
+ }
34
+ //# sourceMappingURL=NodeInspector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeInspector.js","sourceRoot":"","sources":["../src/NodeInspector.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { OcapFlags } from '@medicine-wheel/ontology-core';
2
+ export interface OcapBadgeProps {
3
+ ocap?: OcapFlags;
4
+ /** Show detailed breakdown */
5
+ detailed?: boolean;
6
+ /** Custom className */
7
+ className?: string;
8
+ }
9
+ export declare function OcapBadge({ ocap, detailed, className }: OcapBadgeProps): import("react/jsx-runtime").JSX.Element;
10
+ //# sourceMappingURL=OcapBadge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OcapBadge.d.ts","sourceRoot":"","sources":["../src/OcapBadge.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE/D,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,EAAE,IAAI,EAAE,QAAgB,EAAE,SAAc,EAAE,EAAE,cAAc,2CA6DnF"}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OcapBadge = OcapBadge;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ function OcapBadge({ ocap, detailed = false, className = '' }) {
6
+ if (!ocap) {
7
+ return ((0, jsx_runtime_1.jsx)("span", { className: className, style: { fontSize: '12px', padding: '2px 8px', borderRadius: '4px', background: '#ff880020', color: '#ff8800' }, children: "No OCAP" }));
8
+ }
9
+ const flags = [
10
+ { key: 'O', label: 'Ownership', value: ocap.ownership },
11
+ { key: 'C', label: 'Control', value: ocap.control },
12
+ { key: 'A', label: 'Access', value: ocap.access },
13
+ { key: 'P', label: 'Possession', value: ocap.possession },
14
+ ];
15
+ const compliant = ocap.compliant;
16
+ if (!detailed) {
17
+ return ((0, jsx_runtime_1.jsxs)("span", { className: className, title: flags.map(f => `${f.label}: ${f.value ? '✓' : '✗'}`).join(', '), style: {
18
+ fontSize: '12px',
19
+ padding: '2px 8px',
20
+ borderRadius: '4px',
21
+ background: compliant ? '#22c55e20' : '#ef444420',
22
+ color: compliant ? '#22c55e' : '#ef4444',
23
+ fontWeight: 500,
24
+ }, children: ["OCAP\u00AE ", compliant ? '✓' : '✗'] }));
25
+ }
26
+ return ((0, jsx_runtime_1.jsx)("div", { className: className, style: { display: 'flex', gap: '4px', alignItems: 'center' }, children: flags.map(f => ((0, jsx_runtime_1.jsx)("span", { title: f.label, style: {
27
+ width: '22px',
28
+ height: '22px',
29
+ borderRadius: '4px',
30
+ display: 'flex',
31
+ alignItems: 'center',
32
+ justifyContent: 'center',
33
+ fontSize: '11px',
34
+ fontWeight: 600,
35
+ background: f.value ? '#22c55e20' : '#ef444420',
36
+ color: f.value ? '#22c55e' : '#ef4444',
37
+ }, children: f.key }, f.key))) }));
38
+ }
39
+ //# sourceMappingURL=OcapBadge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OcapBadge.js","sourceRoot":"","sources":["../src/OcapBadge.tsx"],"names":[],"mappings":";;AAcA,8BA6DC;;AA7DD,SAAgB,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,GAAG,KAAK,EAAE,SAAS,GAAG,EAAE,EAAkB;IAClF,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CACL,iCAAM,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE,wBAEpI,CACR,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG;QACZ,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE;QACvD,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE;QACnD,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE;QACjD,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE;KAC1D,CAAC;IAEF,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IAEjC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CACL,kCACE,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EACtE,KAAK,EAAE;gBACL,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,SAAS;gBAClB,YAAY,EAAE,KAAK;gBACnB,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW;gBACjD,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;gBACxC,UAAU,EAAE,GAAG;aAChB,4BAEM,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IACvB,CACR,CAAC;IACJ,CAAC;IAED,OAAO,CACL,gCAAK,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,YACpF,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CACd,iCAEE,KAAK,EAAE,CAAC,CAAC,KAAK,EACd,KAAK,EAAE;gBACL,KAAK,EAAE,MAAM;gBACb,MAAM,EAAE,MAAM;gBACd,YAAY,EAAE,KAAK;gBACnB,OAAO,EAAE,MAAM;gBACf,UAAU,EAAE,QAAQ;gBACpB,cAAc,EAAE,QAAQ;gBACxB,QAAQ,EAAE,MAAM;gBAChB,UAAU,EAAE,GAAG;gBACf,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW;gBAC/C,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;aACvC,YAEA,CAAC,CAAC,GAAG,IAfD,CAAC,CAAC,GAAG,CAgBL,CACR,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ export interface WilsonMeterProps {
2
+ /** Alignment value 0–1 */
3
+ alignment: number;
4
+ /** Size in px */
5
+ size?: number;
6
+ /** Show numeric label */
7
+ showLabel?: boolean;
8
+ /** Custom className */
9
+ className?: string;
10
+ }
11
+ export declare function WilsonMeter({ alignment, size, showLabel, className, }: WilsonMeterProps): import("react/jsx-runtime").JSX.Element;
12
+ //# sourceMappingURL=WilsonMeter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WilsonMeter.d.ts","sourceRoot":"","sources":["../src/WilsonMeter.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAQD,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,IAAS,EACT,SAAgB,EAChB,SAAc,GACf,EAAE,gBAAgB,2CAyDlB"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WilsonMeter = WilsonMeter;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ function alignmentColor(value) {
6
+ if (value >= 0.7)
7
+ return '#22c55e';
8
+ if (value >= 0.4)
9
+ return '#f59e0b';
10
+ return '#ef4444';
11
+ }
12
+ function WilsonMeter({ alignment, size = 48, showLabel = true, className = '', }) {
13
+ const clamped = Math.max(0, Math.min(1, alignment));
14
+ const color = alignmentColor(clamped);
15
+ const radius = (size - 8) / 2;
16
+ const circumference = 2 * Math.PI * radius;
17
+ const offset = circumference * (1 - clamped);
18
+ const center = size / 2;
19
+ return ((0, jsx_runtime_1.jsxs)("div", { className: className, style: { display: 'inline-flex', flexDirection: 'column', alignItems: 'center', gap: '4px' }, title: `Wilson Alignment: ${(clamped * 100).toFixed(0)}%`, children: [(0, jsx_runtime_1.jsxs)("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, children: [(0, jsx_runtime_1.jsx)("circle", { cx: center, cy: center, r: radius, fill: "none", stroke: "currentColor", strokeWidth: 3, opacity: 0.1 }), (0, jsx_runtime_1.jsx)("circle", { cx: center, cy: center, r: radius, fill: "none", stroke: color, strokeWidth: 3, strokeDasharray: `${circumference}`, strokeDashoffset: `${offset}`, strokeLinecap: "round", transform: `rotate(-90 ${center} ${center})`, style: { transition: 'stroke-dashoffset 0.5s ease' } }), (0, jsx_runtime_1.jsx)("text", { x: center, y: center, textAnchor: "middle", dominantBaseline: "central", fontSize: size * 0.28, fontWeight: 600, fill: color, children: (clamped * 100).toFixed(0) })] }), showLabel && ((0, jsx_runtime_1.jsx)("span", { style: { fontSize: '10px', opacity: 0.5 }, children: "Wilson" }))] }));
20
+ }
21
+ //# sourceMappingURL=WilsonMeter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WilsonMeter.js","sourceRoot":"","sources":["../src/WilsonMeter.tsx"],"names":[],"mappings":";;AAsBA,kCA8DC;;AApED,SAAS,cAAc,CAAC,KAAa;IACnC,IAAI,KAAK,IAAI,GAAG;QAAE,OAAO,SAAS,CAAC;IACnC,IAAI,KAAK,IAAI,GAAG;QAAE,OAAO,SAAS,CAAC;IACnC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,IAAI,GAAG,EAAE,EACT,SAAS,GAAG,IAAI,EAChB,SAAS,GAAG,EAAE,GACG;IACjB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC;IAC3C,MAAM,MAAM,GAAG,aAAa,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC;IAExB,OAAO,CACL,iCACE,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,EAC5F,KAAK,EAAE,qBAAqB,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,aAEzD,iCAAK,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,IAAI,IAAI,IAAI,EAAE,aAE5D,mCACE,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,CAAC,EAAE,MAAM,EACT,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAE,CAAC,EACd,OAAO,EAAE,GAAG,GACZ,EAEF,mCACE,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,CAAC,EAAE,MAAM,EACT,IAAI,EAAC,MAAM,EACX,MAAM,EAAE,KAAK,EACb,WAAW,EAAE,CAAC,EACd,eAAe,EAAE,GAAG,aAAa,EAAE,EACnC,gBAAgB,EAAE,GAAG,MAAM,EAAE,EAC7B,aAAa,EAAC,OAAO,EACrB,SAAS,EAAE,cAAc,MAAM,IAAI,MAAM,GAAG,EAC5C,KAAK,EAAE,EAAE,UAAU,EAAE,6BAA6B,EAAE,GACpD,EAEF,iCACE,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,UAAU,EAAC,QAAQ,EACnB,gBAAgB,EAAC,SAAS,EAC1B,QAAQ,EAAE,IAAI,GAAG,IAAI,EACrB,UAAU,EAAE,GAAG,EACf,IAAI,EAAE,KAAK,YAEV,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GACtB,IACH,EACL,SAAS,IAAI,CACZ,iCAAM,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,uBAAe,CAC/D,IACG,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @medicine-wheel/ui-components
3
+ *
4
+ * React UI components for the Medicine Wheel Developer Suite.
5
+ */
6
+ export { DirectionCard } from './DirectionCard.js';
7
+ export type { DirectionCardProps } from './DirectionCard.js';
8
+ export { BeatTimeline } from './BeatTimeline.js';
9
+ export type { BeatTimelineProps } from './BeatTimeline.js';
10
+ export { NodeInspector } from './NodeInspector.js';
11
+ export type { NodeInspectorProps } from './NodeInspector.js';
12
+ export { OcapBadge } from './OcapBadge.js';
13
+ export type { OcapBadgeProps } from './OcapBadge.js';
14
+ export { WilsonMeter } from './WilsonMeter.js';
15
+ export type { WilsonMeterProps } from './WilsonMeter.js';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ /**
3
+ * @medicine-wheel/ui-components
4
+ *
5
+ * React UI components for the Medicine Wheel Developer Suite.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.WilsonMeter = exports.OcapBadge = exports.NodeInspector = exports.BeatTimeline = exports.DirectionCard = void 0;
9
+ var DirectionCard_js_1 = require("./DirectionCard.js");
10
+ Object.defineProperty(exports, "DirectionCard", { enumerable: true, get: function () { return DirectionCard_js_1.DirectionCard; } });
11
+ var BeatTimeline_js_1 = require("./BeatTimeline.js");
12
+ Object.defineProperty(exports, "BeatTimeline", { enumerable: true, get: function () { return BeatTimeline_js_1.BeatTimeline; } });
13
+ var NodeInspector_js_1 = require("./NodeInspector.js");
14
+ Object.defineProperty(exports, "NodeInspector", { enumerable: true, get: function () { return NodeInspector_js_1.NodeInspector; } });
15
+ var OcapBadge_js_1 = require("./OcapBadge.js");
16
+ Object.defineProperty(exports, "OcapBadge", { enumerable: true, get: function () { return OcapBadge_js_1.OcapBadge; } });
17
+ var WilsonMeter_js_1 = require("./WilsonMeter.js");
18
+ Object.defineProperty(exports, "WilsonMeter", { enumerable: true, get: function () { return WilsonMeter_js_1.WilsonMeter; } });
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,uDAAmD;AAA1C,iHAAA,aAAa,OAAA;AAGtB,qDAAiD;AAAxC,+GAAA,YAAY,OAAA;AAGrB,uDAAmD;AAA1C,iHAAA,aAAa,OAAA;AAGtB,+CAA2C;AAAlC,yGAAA,SAAS,OAAA;AAGlB,mDAA+C;AAAtC,6GAAA,WAAW,OAAA"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@medicine-wheel/ui-components",
3
+ "version": "0.2.2",
4
+ "description": "React UI components for the Medicine Wheel Developer Suite — direction cards, beat timelines, node inspectors",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js",
11
+ "require": "./dist/index.js",
12
+ "default": "./dist/index.js"
13
+ },
14
+ "./tokens.css": "./src/tokens.css"
15
+ },
16
+ "sideEffects": [
17
+ "./src/tokens.css"
18
+ ],
19
+ "files": [
20
+ "dist",
21
+ "src/tokens.css",
22
+ "README.md"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsc",
26
+ "clean": "rm -rf dist",
27
+ "prepublishOnly": "npm run clean && npm run build"
28
+ },
29
+ "keywords": [
30
+ "medicine-wheel",
31
+ "react",
32
+ "ui",
33
+ "indigenous",
34
+ "four-directions",
35
+ "visualization"
36
+ ],
37
+ "author": "jgwill",
38
+ "license": "MIT",
39
+ "dependencies": {
40
+ "@medicine-wheel/ontology-core": "^0.2.2"
41
+ },
42
+ "peerDependencies": {
43
+ "react": "^18.0.0 || ^19.0.0"
44
+ },
45
+ "devDependencies": {
46
+ "@types/react": "^19.0.0",
47
+ "react": "^19.0.0",
48
+ "typescript": "^5.7.0"
49
+ }
50
+ }
package/src/tokens.css ADDED
@@ -0,0 +1,289 @@
1
+ /**
2
+ * medicine-wheel-ui-components — Design Tokens
3
+ * Source of truth for Medicine Wheel colors, type, spacing, radius, motion.
4
+ * Mirror of Miadi Design System `colors_and_type.css`.
5
+ *
6
+ * Consume from an app with:
7
+ * @import "medicine-wheel-ui-components/tokens.css";
8
+ * Or a bundler path:
9
+ * @import "../../src/ui-components/src/tokens.css";
10
+ *
11
+ * Assumes a webfont file at /fonts/Stereohead.otf (app serves it publicly).
12
+ */
13
+
14
+ @font-face {
15
+ font-family: 'Stereohead';
16
+ src: url('/fonts/Stereohead.otf') format('opentype');
17
+ font-weight: normal;
18
+ font-style: normal;
19
+ font-display: swap;
20
+ }
21
+
22
+ :root {
23
+ /* Base */
24
+ --mw-bg: oklch(0.145 0 0);
25
+ --mw-card: oklch(0.185 0 0);
26
+ --mw-card-2: oklch(0.21 0 0);
27
+ --mw-secondary: oklch(0.269 0 0);
28
+ --mw-border: oklch(0.3 0 0);
29
+ --mw-fg: oklch(0.985 0 0);
30
+ --mw-muted: oklch(0.708 0 0);
31
+ --mw-primary: oklch(0.785 0.115 85);
32
+ --mw-primary-fg: oklch(0.145 0 0);
33
+ --mw-ring: oklch(0.785 0.115 85);
34
+ --mw-destructive: oklch(0.396 0.141 25.723);
35
+
36
+ /* STC panel accent */
37
+ --mw-stc-bg: #111827;
38
+ --mw-stc-card: #1f2937;
39
+ --mw-stc-accent: #0891b2;
40
+ --mw-stc-border: #374151;
41
+
42
+ /* Four Direction colors */
43
+ --mw-east: #FFD700;
44
+ --mw-south: #DC143C;
45
+ --mw-west: #1a1a2e;
46
+ --mw-north: #E8E8E8;
47
+
48
+ --mw-east-tint: #FFD70015;
49
+ --mw-south-tint: #DC143C15;
50
+ --mw-west-tint: #2a2a4a;
51
+ --mw-north-tint: #E8E8E810;
52
+
53
+ --mw-east-border: #FFD70060;
54
+ --mw-south-border: #DC143C60;
55
+ --mw-west-border: #5a5a8060;
56
+ --mw-north-border: #E8E8E860;
57
+
58
+ --mw-west-display: #8888cc; /* legible stand-in for near-black west on dark bg */
59
+
60
+ /* oklch direction tokens (for gradients) */
61
+ --color-east: oklch(0.85 0.15 85);
62
+ --color-south: oklch(0.55 0.22 25);
63
+ --color-west: oklch(0.25 0.05 270);
64
+ --color-north: oklch(0.92 0.01 0);
65
+
66
+ /* Node type colors — ancestor/knowledge retuned for contrast vs human */
67
+ --mw-node-human: #e8913a;
68
+ --mw-node-land: #4a9e5c;
69
+ --mw-node-spirit: #9a5cc6;
70
+ --mw-node-ancestor: #8a5a2a;
71
+ --mw-node-future: #5a9ec6;
72
+ --mw-node-knowledge: #c8d42a;
73
+
74
+ /* Wilson meter */
75
+ --mw-wilson-high: #22c55e;
76
+ --mw-wilson-mid: #f59e0b;
77
+ --mw-wilson-low: #ef4444;
78
+
79
+ /* Typography */
80
+ --font-display: 'Stereohead', 'Nunito', system-ui, sans-serif;
81
+ --font-sans: 'Nunito', system-ui, -apple-system, sans-serif;
82
+ --font-mono: 'JetBrains Mono', ui-monospace, monospace;
83
+
84
+ --text-xs: 0.75rem;
85
+ --text-sm: 0.875rem;
86
+ --text-base: 1rem;
87
+ --text-lg: 1.125rem;
88
+ --text-xl: 1.25rem;
89
+ --text-2xl: 1.5rem;
90
+ --text-3xl: 1.875rem;
91
+ --text-4xl: 2.25rem;
92
+
93
+ --weight-normal: 400;
94
+ --weight-medium: 500;
95
+ --weight-semibold: 600;
96
+ --weight-bold: 700;
97
+ --weight-extrabold: 800;
98
+
99
+ --leading-tight: 1.25;
100
+ --leading-snug: 1.375;
101
+ --leading-normal: 1.5;
102
+ --leading-relaxed:1.625;
103
+
104
+ /* Spacing */
105
+ --space-1: 0.25rem;
106
+ --space-2: 0.5rem;
107
+ --space-3: 0.75rem;
108
+ --space-4: 1rem;
109
+ --space-5: 1.25rem;
110
+ --space-6: 1.5rem;
111
+ --space-8: 2rem;
112
+ --space-10: 2.5rem;
113
+ --space-12: 3rem;
114
+ --space-16: 4rem;
115
+
116
+ /* Radius */
117
+ --radius-sm: 0.25rem;
118
+ --radius: 0.625rem;
119
+ --radius-lg: 0.75rem;
120
+ --radius-full: 9999px;
121
+
122
+ /* Motion */
123
+ --duration-fast: 150ms;
124
+ --duration-default: 200ms;
125
+ --duration-slow: 300ms;
126
+ --duration-pulse: 3s;
127
+ --duration-glow: 2s;
128
+
129
+ /* Layout */
130
+ --max-w-content: 80rem;
131
+ --max-w-focused: 64rem;
132
+ --nav-height: 4rem;
133
+ }
134
+
135
+ /* Type classes */
136
+ .mw-display {
137
+ font-family: var(--font-display);
138
+ font-size: var(--text-4xl);
139
+ font-weight: var(--weight-normal);
140
+ line-height: var(--leading-tight);
141
+ letter-spacing: 0.02em;
142
+ }
143
+ .mw-h1 {
144
+ font-family: var(--font-display);
145
+ font-size: var(--text-3xl);
146
+ font-weight: var(--weight-normal);
147
+ line-height: var(--leading-tight);
148
+ }
149
+ .mw-h2 {
150
+ font-family: var(--font-display);
151
+ font-size: var(--text-2xl);
152
+ font-weight: var(--weight-normal);
153
+ line-height: var(--leading-tight);
154
+ }
155
+ .mw-h3 {
156
+ font-size: var(--text-lg);
157
+ font-weight: var(--weight-semibold);
158
+ line-height: var(--leading-snug);
159
+ }
160
+ .mw-body { font-size: var(--text-base); line-height: var(--leading-relaxed); }
161
+ .mw-body-sm { font-size: var(--text-sm); line-height: var(--leading-normal); }
162
+ .mw-label { font-size: var(--text-sm); font-weight: var(--weight-medium); }
163
+ .mw-meta { font-size: var(--text-xs); color: var(--mw-muted); }
164
+ .mw-ojibwe { font-style: italic; font-size: var(--text-sm); opacity: 0.7; }
165
+ .mw-quote { font-style: italic; color: var(--mw-muted); border-left: 3px solid var(--mw-primary); padding-left: var(--space-4); }
166
+ .mw-mono { font-family: var(--font-mono); font-size: var(--text-sm); background: var(--mw-secondary); padding: 2px 6px; border-radius: var(--radius-sm); }
167
+
168
+ /* Cards */
169
+ .mw-card {
170
+ background: var(--mw-card);
171
+ border: 1px solid var(--mw-border);
172
+ border-radius: var(--radius);
173
+ padding: var(--space-4) var(--space-6);
174
+ }
175
+ .mw-card--east { border-top: 3px solid var(--mw-east); }
176
+ .mw-card--south { border-top: 3px solid var(--mw-south); }
177
+ .mw-card--west { border-top: 3px solid var(--mw-west); }
178
+ .mw-card--north { border-top: 3px solid var(--mw-north); }
179
+ .mw-card--east-left { border-left: 4px solid var(--mw-east); }
180
+ .mw-card--south-left { border-left: 4px solid var(--mw-south); }
181
+ .mw-card--west-left { border-left: 4px solid var(--mw-west); }
182
+ .mw-card--north-left { border-left: 4px solid var(--mw-north); }
183
+
184
+ /* Buttons */
185
+ .mw-btn {
186
+ display: inline-flex;
187
+ align-items: center;
188
+ gap: var(--space-2);
189
+ padding: var(--space-2) var(--space-4);
190
+ border-radius: var(--radius);
191
+ font-size: var(--text-sm);
192
+ font-weight: var(--weight-medium);
193
+ font-family: var(--font-sans);
194
+ cursor: pointer;
195
+ transition: all var(--duration-default) ease;
196
+ border: none;
197
+ outline: none;
198
+ }
199
+ .mw-btn--primary { background: var(--mw-primary); color: var(--mw-primary-fg); }
200
+ .mw-btn--primary:hover { filter: brightness(0.9); }
201
+ .mw-btn--secondary { background: var(--mw-secondary); color: var(--mw-fg); }
202
+ .mw-btn--secondary:hover { background: var(--mw-border); }
203
+ .mw-btn--ghost { background: transparent; color: var(--mw-muted); border: 1px solid var(--mw-border); }
204
+ .mw-btn--ghost:hover { color: var(--mw-fg); background: var(--mw-secondary); }
205
+ .mw-btn--stc { background: var(--mw-stc-accent); color: #fff; }
206
+ .mw-btn--stc:hover { filter: brightness(0.9); }
207
+ .mw-btn--danger { background: transparent; color: var(--mw-destructive); font-weight: var(--weight-bold); }
208
+
209
+ /* Badges */
210
+ .mw-badge {
211
+ display: inline-flex;
212
+ align-items: center;
213
+ padding: 2px var(--space-2);
214
+ border-radius: var(--radius-full);
215
+ font-size: var(--text-xs);
216
+ font-weight: var(--weight-medium);
217
+ background: var(--mw-secondary);
218
+ color: var(--mw-fg);
219
+ }
220
+ .mw-badge--east { background: var(--mw-east-tint); color: var(--mw-east); border: 1px solid var(--mw-east-border); }
221
+ .mw-badge--south { background: #DC143C25; color: #ff6b80; border: 1px solid #DC143C50; }
222
+ .mw-badge--west { background: var(--mw-west-tint); color: var(--mw-west-display); border: 1px solid var(--mw-west-border); }
223
+ .mw-badge--north { background: var(--mw-north-tint); color: var(--mw-north); border: 1px solid var(--mw-north-border); }
224
+ .mw-badge--success { background: #14532d40; color: var(--mw-wilson-high); }
225
+ .mw-badge--warning { background: #78350f40; color: var(--mw-wilson-mid); }
226
+ .mw-badge--error { background: #7f1d1d40; color: var(--mw-wilson-low); }
227
+
228
+ /* Inputs */
229
+ .mw-input {
230
+ width: 100%;
231
+ background: var(--mw-secondary);
232
+ border: 1px solid var(--mw-border);
233
+ border-radius: var(--radius);
234
+ padding: var(--space-2) var(--space-3);
235
+ color: var(--mw-fg);
236
+ font-family: var(--font-sans);
237
+ font-size: var(--text-sm);
238
+ outline: none;
239
+ transition: border-color var(--duration-fast);
240
+ }
241
+ .mw-input:focus { border-color: var(--mw-ring); }
242
+ .mw-input::placeholder { color: var(--mw-muted); }
243
+
244
+ /* Progress */
245
+ .mw-progress-track {
246
+ height: 0.5rem;
247
+ background: var(--mw-secondary);
248
+ border-radius: var(--radius-full);
249
+ overflow: hidden;
250
+ }
251
+ .mw-progress-fill {
252
+ height: 100%;
253
+ background: var(--mw-primary);
254
+ border-radius: var(--radius-full);
255
+ transition: width var(--duration-slow);
256
+ }
257
+ .mw-progress-fill--directions {
258
+ background: linear-gradient(to right, var(--mw-east), var(--mw-south), #6060a0, var(--mw-north));
259
+ }
260
+
261
+ /* Dots */
262
+ .mw-dot {
263
+ width: 0.5rem;
264
+ height: 0.5rem;
265
+ border-radius: var(--radius-full);
266
+ display: inline-block;
267
+ }
268
+ .mw-dot--active { background: var(--mw-wilson-high); }
269
+ .mw-dot--inactive { background: var(--mw-muted); }
270
+ .mw-dot--east { background: var(--mw-east); }
271
+ .mw-dot--south { background: var(--mw-south); }
272
+ .mw-dot--west { background: var(--mw-west-display); }
273
+ .mw-dot--north { background: var(--mw-north); }
274
+
275
+ /* Animations */
276
+ @keyframes mw-pulse-center {
277
+ 0%, 100% { opacity: 0.6; transform: scale(1); }
278
+ 50% { opacity: 1; transform: scale(1.08); }
279
+ }
280
+ @keyframes mw-glow {
281
+ 0%, 100% { filter: brightness(1); }
282
+ 50% { filter: brightness(1.3); }
283
+ }
284
+ @keyframes mw-spin {
285
+ to { transform: rotate(360deg); }
286
+ }
287
+ .mw-pulse { animation: mw-pulse-center var(--duration-pulse) ease-in-out infinite; }
288
+ .mw-glow { animation: mw-glow var(--duration-glow) ease-in-out infinite; }
289
+ .mw-spin { animation: mw-spin 1s linear infinite; }