@ultrst-armada/floks 0.0.0-stage → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +2 -3
  2. package/index.d.ts +2 -0
  3. package/index.js +2 -0
  4. package/package.json +69 -4
  5. package/packages/canvas-ui/dist/canvas/index.d.ts +54 -0
  6. package/packages/canvas-ui/dist/canvas/index.js +12 -0
  7. package/packages/canvas-ui/dist/chunk-34YRDZPJ.js +189 -0
  8. package/packages/canvas-ui/dist/chunk-6VB74RCH.js +147 -0
  9. package/packages/canvas-ui/dist/chunk-OOTTFWXA.js +508 -0
  10. package/packages/canvas-ui/dist/chunk-QTTWWBNN.js +114 -0
  11. package/packages/canvas-ui/dist/chunk-SA3JADUG.js +160 -0
  12. package/packages/canvas-ui/dist/chunk-U2SC3RMJ.js +391 -0
  13. package/packages/canvas-ui/dist/chunk-XVAHT5WE.js +718 -0
  14. package/packages/canvas-ui/dist/dock/index.d.ts +37 -0
  15. package/packages/canvas-ui/dist/dock/index.js +10 -0
  16. package/packages/canvas-ui/dist/editor/index.d.ts +44 -0
  17. package/packages/canvas-ui/dist/editor/index.js +10 -0
  18. package/packages/canvas-ui/dist/graph-2d/index.d.ts +270 -0
  19. package/packages/canvas-ui/dist/graph-2d/index.js +50 -0
  20. package/packages/canvas-ui/dist/index.d.ts +176 -0
  21. package/packages/canvas-ui/dist/index.js +1171 -0
  22. package/packages/canvas-ui/dist/predictive/index.d.ts +75 -0
  23. package/packages/canvas-ui/dist/predictive/index.js +13 -0
  24. package/packages/canvas-ui/dist/tile-menu/index.d.ts +45 -0
  25. package/packages/canvas-ui/dist/tile-menu/index.js +12 -0
  26. package/packages/canvas-ui/dist/types-D3RRfQUo.d.ts +46 -0
  27. package/packages/canvas-ui/floks.manifest.json +35 -0
  28. package/packages/canvas-ui/package.json +82 -0
  29. package/packages/ui/dist/BottomStrip-DYhAUQR4.d.ts +12 -0
  30. package/packages/ui/dist/chunk-5ZMXFCD4.js +0 -0
  31. package/packages/ui/dist/chunk-62ITRDJX.js +141 -0
  32. package/packages/ui/dist/chunk-A2CDQISJ.js +32 -0
  33. package/packages/ui/dist/chunk-ATQPZLJX.js +238 -0
  34. package/packages/ui/dist/chunk-C32CB5WO.js +1161 -0
  35. package/packages/ui/dist/chunk-C3L53YN4.js +372 -0
  36. package/packages/ui/dist/chunk-DZJ3NSCX.js +665 -0
  37. package/packages/ui/dist/chunk-ELZOBTWX.js +562 -0
  38. package/packages/ui/dist/chunk-GKP6KHTI.js +75 -0
  39. package/packages/ui/dist/chunk-GWW3BGOB.js +238 -0
  40. package/packages/ui/dist/chunk-KIFQA7L6.js +167 -0
  41. package/packages/ui/dist/chunk-KYFSUQVT.js +769 -0
  42. package/packages/ui/dist/chunk-OR5ZNJI4.js +62 -0
  43. package/packages/ui/dist/chunk-RLQ2ALJG.js +182 -0
  44. package/packages/ui/dist/chunk-S227WJ5E.js +152 -0
  45. package/packages/ui/dist/chunk-SLJBDDSN.js +0 -0
  46. package/packages/ui/dist/chunk-TXKLROFC.js +370 -0
  47. package/packages/ui/dist/chunk-UOR4P6PO.js +32 -0
  48. package/packages/ui/dist/chunk-VEWPTZGO.js +351 -0
  49. package/packages/ui/dist/chunk-W42SJGOJ.js +19 -0
  50. package/packages/ui/dist/chunk-XXIH2HWI.js +297 -0
  51. package/packages/ui/dist/chunk-ZQK5I5ZL.js +277 -0
  52. package/packages/ui/dist/components/auth/index.css +183 -0
  53. package/packages/ui/dist/components/auth/index.d.ts +10 -0
  54. package/packages/ui/dist/components/auth/index.js +8 -0
  55. package/packages/ui/dist/components/base/index.css +183 -0
  56. package/packages/ui/dist/components/base/index.d.ts +74 -0
  57. package/packages/ui/dist/components/base/index.js +33 -0
  58. package/packages/ui/dist/components/bottom-strip/index.css +183 -0
  59. package/packages/ui/dist/components/bottom-strip/index.d.ts +67 -0
  60. package/packages/ui/dist/components/bottom-strip/index.js +22 -0
  61. package/packages/ui/dist/components/composite/index.css +273 -0
  62. package/packages/ui/dist/components/composite/index.d.ts +104 -0
  63. package/packages/ui/dist/components/composite/index.js +33 -0
  64. package/packages/ui/dist/components/containers/index.css +404 -0
  65. package/packages/ui/dist/components/containers/index.d.ts +93 -0
  66. package/packages/ui/dist/components/containers/index.js +35 -0
  67. package/packages/ui/dist/components/layout/index.css +246 -0
  68. package/packages/ui/dist/components/layout/index.d.ts +53 -0
  69. package/packages/ui/dist/components/layout/index.js +16 -0
  70. package/packages/ui/dist/components/settings/index.css +183 -0
  71. package/packages/ui/dist/components/settings/index.d.ts +14 -0
  72. package/packages/ui/dist/components/settings/index.js +12 -0
  73. package/packages/ui/dist/components/workspace/index.d.ts +101 -0
  74. package/packages/ui/dist/components/workspace/index.js +16 -0
  75. package/packages/ui/dist/hierarchy/index.css +183 -0
  76. package/packages/ui/dist/hierarchy/index.d.ts +233 -0
  77. package/packages/ui/dist/hierarchy/index.js +74 -0
  78. package/packages/ui/dist/index.css +467 -0
  79. package/packages/ui/dist/index.d.ts +16 -0
  80. package/packages/ui/dist/index.js +320 -0
  81. package/packages/ui/dist/palette/index.d.ts +29 -0
  82. package/packages/ui/dist/palette/index.js +27 -0
  83. package/packages/ui/dist/palettes-De5u5iID.d.ts +394 -0
  84. package/packages/ui/dist/theme/index.d.ts +12063 -0
  85. package/packages/ui/dist/theme/index.js +96 -0
  86. package/packages/ui/floks.manifest.json +119 -0
  87. package/packages/ui/package.json +92 -0
  88. package/packages/ui/src/styles/base.css +130 -0
  89. package/packages/ui/src/styles/composite.css +6 -0
  90. package/packages/ui/src/styles/containers.css +10 -0
  91. package/packages/ui/src/styles/details-panel.css +147 -0
  92. package/packages/ui/src/styles/layout.css +58 -0
  93. package/packages/ui/src/theme/tokens.css +93 -0
@@ -0,0 +1,75 @@
1
+ import * as _kloks_state_graph from '@ultrst-armada/kloks/state-graph';
2
+ import { PredictiveGhostNode, SpaceNode, PredictiveTrace, NodeConnection } from '@ultrst-armada/kloks/state-graph';
3
+ import React__default from 'react';
4
+ import { a as CameraState } from '../types-D3RRfQUo.js';
5
+
6
+ interface PredictiveGhostNodeCardProps {
7
+ ghost: PredictiveGhostNode;
8
+ screenPos: {
9
+ x: number;
10
+ y: number;
11
+ };
12
+ zoom: number;
13
+ onSolidify: (ghost: PredictiveGhostNode) => void;
14
+ isHovered?: boolean;
15
+ onHoverChange?: (hovered: boolean) => void;
16
+ }
17
+
18
+ declare const PredictiveGhostNodeCard: React__default.FC<PredictiveGhostNodeCardProps>;
19
+
20
+ interface PredictiveHudToolbarProps {
21
+ isActive: boolean;
22
+ scenarioIndex: number;
23
+ totalGhosts: number;
24
+ selectedCount: number;
25
+ onToggleActive: () => void;
26
+ onNextScenario: () => void;
27
+ onPrevScenario: () => void;
28
+ onSolidifyAll: () => void;
29
+ onClose: () => void;
30
+ }
31
+ declare const PredictiveHudToolbar: React__default.FC<PredictiveHudToolbarProps>;
32
+
33
+ interface PredictiveLayer2DProps {
34
+ nodes: SpaceNode[];
35
+ ghostNodes: PredictiveGhostNode[];
36
+ traces: PredictiveTrace[];
37
+ selectedNodesWithGhosts: Map<string, PredictiveGhostNode[]>;
38
+ worldToScreen: (x: number, z: number) => {
39
+ x: number;
40
+ y: number;
41
+ };
42
+ camera: CameraState;
43
+ onSolidifyGhost: (ghost: PredictiveGhostNode) => void;
44
+ onSolidifyAllForNode: (parentNodeId: string) => void;
45
+ isActive?: boolean;
46
+ targetNodes?: SpaceNode[];
47
+ onToggleActive?: () => void;
48
+ }
49
+ declare const PredictiveLayer2D: React__default.FC<PredictiveLayer2DProps>;
50
+
51
+ interface UsePredictiveGraph2DProps {
52
+ nodes: SpaceNode[];
53
+ connections: NodeConnection[];
54
+ selectedNodeId: string | null;
55
+ selectedNodeIds?: string[];
56
+ onSolidifyPredictiveNodes?: (ghosts: PredictiveGhostNode[]) => void;
57
+ }
58
+ type UseViewer2DPredictiveProps = UsePredictiveGraph2DProps;
59
+ declare function usePredictiveGraph2D({ nodes, connections, selectedNodeId, selectedNodeIds, onSolidifyPredictiveNodes, }: UsePredictiveGraph2DProps): {
60
+ isActive: boolean;
61
+ scenarioIndex: number;
62
+ targetNodes: SpaceNode[];
63
+ ghostNodes: PredictiveGhostNode[];
64
+ traces: _kloks_state_graph.PredictiveTrace[];
65
+ selectedNodesWithGhosts: Map<string, PredictiveGhostNode[]>;
66
+ toggleActive: () => void;
67
+ nextScenario: () => void;
68
+ prevScenario: () => void;
69
+ solidifyGhost: (ghost: PredictiveGhostNode) => void;
70
+ solidifyAllForNode: (parentNodeId: string) => void;
71
+ solidifyAll: () => void;
72
+ close: () => void;
73
+ };
74
+
75
+ export { PredictiveGhostNodeCard, type PredictiveGhostNodeCardProps, PredictiveHudToolbar, PredictiveLayer2D, type PredictiveLayer2DProps, type UsePredictiveGraph2DProps, type UseViewer2DPredictiveProps, usePredictiveGraph2D };
@@ -0,0 +1,13 @@
1
+ import {
2
+ PredictiveGhostNodeCard,
3
+ PredictiveHudToolbar,
4
+ PredictiveLayer2D,
5
+ usePredictiveGraph2D
6
+ } from "../chunk-OOTTFWXA.js";
7
+ import "../chunk-U2SC3RMJ.js";
8
+ export {
9
+ PredictiveGhostNodeCard,
10
+ PredictiveHudToolbar,
11
+ PredictiveLayer2D,
12
+ usePredictiveGraph2D
13
+ };
@@ -0,0 +1,45 @@
1
+ import * as React from 'react';
2
+ import React__default from 'react';
3
+
4
+ interface TileConfig {
5
+ id: string;
6
+ title: string;
7
+ subtitle?: string;
8
+ icon?: string;
9
+ badges?: string[];
10
+ data?: Record<string, unknown>;
11
+ }
12
+ interface TileAction {
13
+ id: string;
14
+ label: string;
15
+ icon?: string;
16
+ onClick: (tileId: string) => void;
17
+ }
18
+
19
+ interface TileProps {
20
+ tile: TileConfig;
21
+ onClick?: (id: string) => void;
22
+ onContextMenu?: (e: React__default.MouseEvent, id: string) => void;
23
+ dragHandleProps?: Record<string, any>;
24
+ isDragging?: boolean;
25
+ }
26
+ declare function Tile({ tile, onClick, onContextMenu, dragHandleProps, isDragging }: TileProps): React__default.JSX.Element;
27
+
28
+ declare function TileGrid({ tiles, onReorder: _onReorder, onTileClick }: {
29
+ tiles: TileConfig[];
30
+ onReorder?: (tiles: TileConfig[]) => void;
31
+ onTileClick?: (id: string) => void;
32
+ }): React.JSX.Element;
33
+
34
+ declare function TileCreateButton({ onClick }: {
35
+ onClick: () => void;
36
+ }): React.JSX.Element;
37
+
38
+ declare function useTileMenu(initialTiles?: TileConfig[]): {
39
+ tiles: TileConfig[];
40
+ addTile: (tile: TileConfig) => void;
41
+ removeTile: (id: string) => void;
42
+ reorderTiles: (newOrder: TileConfig[]) => void;
43
+ };
44
+
45
+ export { Tile, type TileAction, type TileConfig, TileCreateButton, TileGrid, useTileMenu };
@@ -0,0 +1,12 @@
1
+ import {
2
+ Tile,
3
+ TileCreateButton,
4
+ TileGrid,
5
+ useTileMenu
6
+ } from "../chunk-SA3JADUG.js";
7
+ export {
8
+ Tile,
9
+ TileCreateButton,
10
+ TileGrid,
11
+ useTileMenu
12
+ };
@@ -0,0 +1,46 @@
1
+ import { SpaceNode, NodeConnection } from '@ultrst-armada/kloks/state-graph';
2
+
3
+ interface CameraState {
4
+ x: number;
5
+ y: number;
6
+ zoom: number;
7
+ }
8
+ interface ConnectingWireState {
9
+ sourceNodeId: string;
10
+ direction: 'out' | 'in';
11
+ portId: string;
12
+ socketIndex?: number;
13
+ signalType: string;
14
+ startX: number;
15
+ startY: number;
16
+ currentX: number;
17
+ currentY: number;
18
+ }
19
+ interface Canvas2DViewerProps {
20
+ nodes: SpaceNode[];
21
+ connections: NodeConnection[];
22
+ selectedNodeId: string | null;
23
+ selectedNodeIds?: string[];
24
+ selectedConnectionId?: string | null;
25
+ currentBiome?: string;
26
+ isPlaying?: boolean;
27
+ bpm?: number;
28
+ onSelectNode: (nodeId: string | null, skipFocus?: boolean) => void;
29
+ onSelectConnection?: (connId: string | null) => void;
30
+ onMoveNode: (nodeId: string, position: [number, number, number]) => void;
31
+ onConnectRequest: (fromNodeId: string, toNodeId: string, fromPort?: string, toPort?: string, fromSocketIndex?: number, toSocketIndex?: number) => void;
32
+ onInspectNode?: ((node: SpaceNode) => void) | ((nodeId: string) => void);
33
+ onManualTriggerNode?: ((node: SpaceNode) => void) | ((nodeId: string) => void);
34
+ onMapRightClick?: (screenX: number, screenY: number, worldPosition: [number, number, number], targetNodeId?: string | null, targetSocket?: any) => void;
35
+ onWireReleaseEmptySpace?: (screenX: number, screenY: number, worldPos: [number, number, number], pendingWire: any) => void;
36
+ onSolidifyPredictiveNodes?: (ghosts: any[]) => void;
37
+ [key: string]: any;
38
+ }
39
+ declare const COORD_SCALE = 40;
40
+ declare const BIOME_CONFIGS: Record<string, {
41
+ bg: string;
42
+ gridColor: string;
43
+ aoeColor: string;
44
+ }>;
45
+
46
+ export { BIOME_CONFIGS as B, COORD_SCALE as C, type CameraState as a, type Canvas2DViewerProps as b, type ConnectingWireState as c };
@@ -0,0 +1,35 @@
1
+ {
2
+ "$schema": "https://skipo.dev/schemas/floks-manifest.v1.json",
3
+ "package": "@floks/canvas-ui",
4
+ "version": "1.0.0",
5
+ "components": [
6
+ {
7
+ "id": "InfiniteCanvas",
8
+ "name": "InfiniteCanvas",
9
+ "export": "InfiniteCanvas",
10
+ "subpath": "canvas",
11
+ "targetTypes": ["App.main-content"]
12
+ },
13
+ {
14
+ "id": "DockBar",
15
+ "name": "DockBar",
16
+ "export": "DockBar",
17
+ "subpath": "dock",
18
+ "targetTypes": ["App.footer", "App.main-content"]
19
+ },
20
+ {
21
+ "id": "TileGrid",
22
+ "name": "TileGrid",
23
+ "export": "TileGrid",
24
+ "subpath": "tile-menu",
25
+ "targetTypes": ["App.main-content"]
26
+ },
27
+ {
28
+ "id": "MonacoEditor",
29
+ "name": "MonacoEditor",
30
+ "export": "MonacoEditor",
31
+ "subpath": "editor",
32
+ "targetTypes": ["App.main-content"]
33
+ }
34
+ ]
35
+ }
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "@floks/canvas-ui",
3
+ "version": "1.0.0",
4
+ "description": "Floks Canvas UI — Reusable React Visual Components for Infinite Canvas, Dock, Tile Menus, Code Editor, and Node Cards",
5
+ "type": "module",
6
+ "private": false,
7
+ "publishConfig": {
8
+ "access": "public",
9
+ "registry": "https://registry.npmjs.org/"
10
+ },
11
+ "skipoManifest": "./floks.manifest.json",
12
+ "main": "./dist/index.js",
13
+ "module": "./dist/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "import": "./dist/index.js",
18
+ "types": "./dist/index.d.ts",
19
+ "default": "./dist/index.js"
20
+ },
21
+ "./canvas": {
22
+ "import": "./dist/canvas/index.js",
23
+ "types": "./dist/canvas/index.d.ts",
24
+ "default": "./dist/canvas/index.js"
25
+ },
26
+ "./dock": {
27
+ "import": "./dist/dock/index.js",
28
+ "types": "./dist/dock/index.d.ts",
29
+ "default": "./dist/dock/index.js"
30
+ },
31
+ "./tile-menu": {
32
+ "import": "./dist/tile-menu/index.js",
33
+ "types": "./dist/tile-menu/index.d.ts",
34
+ "default": "./dist/tile-menu/index.js"
35
+ },
36
+ "./editor": {
37
+ "import": "./dist/editor/index.js",
38
+ "types": "./dist/editor/index.d.ts",
39
+ "default": "./dist/editor/index.js"
40
+ },
41
+ "./graph-2d": {
42
+ "import": "./dist/graph-2d/index.js",
43
+ "types": "./dist/graph-2d/index.d.ts",
44
+ "default": "./dist/graph-2d/index.js"
45
+ },
46
+ "./predictive": {
47
+ "import": "./dist/predictive/index.js",
48
+ "types": "./dist/predictive/index.d.ts",
49
+ "default": "./dist/predictive/index.js"
50
+ }
51
+ },
52
+ "scripts": {
53
+ "build": "tsup src/index.ts src/canvas/index.ts src/dock/index.ts src/tile-menu/index.ts src/editor/index.ts src/graph-2d/index.ts src/predictive/index.ts --format esm --dts --clean --external react --external react-dom --external lucide-react --external @floks/ui --external @kloks/state-graph --external @kloks/audio-midi --external monaco-editor --external @dnd-kit/core --external @dnd-kit/sortable --external @dnd-kit/utilities",
54
+ "typecheck": "tsc --noEmit",
55
+ "clean": "rm -rf dist"
56
+ },
57
+ "dependencies": {
58
+ "@floks/ui": "workspace:*"
59
+ },
60
+ "peerDependencies": {
61
+ "@dnd-kit/core": "^6.0.0",
62
+ "@dnd-kit/sortable": "^8.0.0 || ^9.0.0",
63
+ "@dnd-kit/utilities": "^3.0.0",
64
+ "monaco-editor": "^0.50.0",
65
+ "react": "^18.0.0 || ^19.0.0",
66
+ "react-dom": "^18.0.0 || ^19.0.0"
67
+ },
68
+ "peerDependenciesMeta": {
69
+ "@dnd-kit/core": {
70
+ "optional": true
71
+ },
72
+ "@dnd-kit/sortable": {
73
+ "optional": true
74
+ },
75
+ "@dnd-kit/utilities": {
76
+ "optional": true
77
+ },
78
+ "monaco-editor": {
79
+ "optional": true
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,12 @@
1
+ import React__default from 'react';
2
+
3
+ interface BottomStripProps extends React__default.HTMLAttributes<HTMLElement> {
4
+ leftSlot?: React__default.ReactNode;
5
+ centerSlot?: React__default.ReactNode;
6
+ rightSlot?: React__default.ReactNode;
7
+ hideDefaultLeft?: boolean;
8
+ hideDefaultRight?: boolean;
9
+ }
10
+ declare const BottomStrip: React__default.ForwardRefExoticComponent<BottomStripProps & React__default.RefAttributes<HTMLElement>>;
11
+
12
+ export { BottomStrip as B, type BottomStripProps as a };
File without changes
@@ -0,0 +1,141 @@
1
+ // src/components/bottom-strip/BottomStripContext.tsx
2
+ import { createContext, useContext, useState, useCallback, useMemo, useEffect } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ var BottomStripContext = createContext(null);
5
+ function useAutoSaveController(initialEnabled) {
6
+ const [enabled, setEnabled] = useState(initialEnabled);
7
+ const [status, setStatus] = useState("idle");
8
+ const toggle = useCallback(() => setEnabled((prev) => !prev), []);
9
+ return { enabled, status, toggle, setStatus, setEnabled };
10
+ }
11
+ function useApiActivityController() {
12
+ const [activeCount, setActiveCount] = useState(0);
13
+ const [lastEndpoint, setLastEndpoint] = useState(void 0);
14
+ const [lastMethod, setLastMethod] = useState(void 0);
15
+ const recordRequestStart = useCallback((endpoint, method = "GET") => {
16
+ const id = `req_${Date.now()}_${Math.random().toString(36).substring(2, 6)}`;
17
+ setActiveCount((prev) => prev + 1);
18
+ setLastEndpoint(endpoint);
19
+ setLastMethod(method);
20
+ return id;
21
+ }, []);
22
+ const recordRequestEnd = useCallback((_requestId) => {
23
+ setActiveCount((prev) => Math.max(0, prev - 1));
24
+ }, []);
25
+ return { activeCount, lastEndpoint, lastMethod, recordRequestStart, recordRequestEnd };
26
+ }
27
+ function useSystemMessageController() {
28
+ const [systemMessages, setSystemMessages] = useState([]);
29
+ const clearSystemMessage = useCallback((id) => {
30
+ setSystemMessages((prev) => prev.filter((m) => m.id !== id));
31
+ }, []);
32
+ const showSystemMessage = useCallback((message, type = "info", durationMs = 5e3) => {
33
+ const id = `msg_${Date.now()}_${Math.random().toString(36).substring(2, 6)}`;
34
+ const newMsg = { id, type, message, timestamp: Date.now() };
35
+ setSystemMessages((prev) => [...prev.slice(-4), newMsg]);
36
+ if (durationMs > 0) {
37
+ setTimeout(() => clearSystemMessage(id), durationMs);
38
+ }
39
+ }, [clearSystemMessage]);
40
+ return { systemMessages, showSystemMessage, clearSystemMessage };
41
+ }
42
+ function BottomStripProvider({
43
+ children,
44
+ initialAutoSave = true
45
+ }) {
46
+ const [inspectionText, setInspectionTextState] = useState(null);
47
+ const [inspectionDescription, setInspectionDescription] = useState(null);
48
+ const [isDKeyPressed, setIsDKeyPressed] = useState(false);
49
+ useEffect(() => {
50
+ if (typeof window === "undefined") return;
51
+ const isEditable = (el) => {
52
+ const tag = el?.tagName?.toLowerCase();
53
+ return tag === "input" || tag === "textarea" || el?.isContentEditable;
54
+ };
55
+ const handleKeyDown = (e) => {
56
+ if ((e.key === "d" || e.key === "D") && !isEditable(e.target)) {
57
+ setIsDKeyPressed(true);
58
+ }
59
+ };
60
+ const handleKeyUp = (e) => {
61
+ if (e.key === "d" || e.key === "D") {
62
+ setIsDKeyPressed(false);
63
+ }
64
+ };
65
+ const handleBlur = () => setIsDKeyPressed(false);
66
+ window.addEventListener("keydown", handleKeyDown);
67
+ window.addEventListener("keyup", handleKeyUp);
68
+ window.addEventListener("blur", handleBlur);
69
+ return () => {
70
+ window.removeEventListener("keydown", handleKeyDown);
71
+ window.removeEventListener("keyup", handleKeyUp);
72
+ window.removeEventListener("blur", handleBlur);
73
+ };
74
+ }, []);
75
+ const setInspectionText = useCallback(
76
+ (text, description) => {
77
+ if (text && typeof text === "object") {
78
+ setInspectionTextState(text.label || null);
79
+ setInspectionDescription(text.description || null);
80
+ } else {
81
+ setInspectionTextState(typeof text === "string" ? text : null);
82
+ setInspectionDescription(description || null);
83
+ }
84
+ },
85
+ []
86
+ );
87
+ const autoSave = useAutoSaveController(initialAutoSave);
88
+ const apiActivity = useApiActivityController();
89
+ const { systemMessages, showSystemMessage, clearSystemMessage } = useSystemMessageController();
90
+ const value = useMemo(() => ({
91
+ inspectionText,
92
+ inspectionDescription,
93
+ isDKeyPressed,
94
+ setInspectionText,
95
+ autoSave,
96
+ apiActivity,
97
+ systemMessages,
98
+ showSystemMessage,
99
+ clearSystemMessage
100
+ }), [inspectionText, inspectionDescription, isDKeyPressed, setInspectionText, autoSave, apiActivity, systemMessages, showSystemMessage, clearSystemMessage]);
101
+ return /* @__PURE__ */ jsx(BottomStripContext.Provider, { value, children });
102
+ }
103
+ function useBottomStrip() {
104
+ const ctx = useContext(BottomStripContext);
105
+ if (!ctx) {
106
+ return {
107
+ inspectionText: null,
108
+ inspectionDescription: null,
109
+ isDKeyPressed: false,
110
+ setInspectionText: () => {
111
+ },
112
+ autoSave: {
113
+ enabled: true,
114
+ status: "idle",
115
+ toggle: () => {
116
+ },
117
+ setStatus: () => {
118
+ },
119
+ setEnabled: () => {
120
+ }
121
+ },
122
+ apiActivity: {
123
+ activeCount: 0,
124
+ recordRequestStart: () => "noop",
125
+ recordRequestEnd: () => {
126
+ }
127
+ },
128
+ systemMessages: [],
129
+ showSystemMessage: () => {
130
+ },
131
+ clearSystemMessage: () => {
132
+ }
133
+ };
134
+ }
135
+ return ctx;
136
+ }
137
+
138
+ export {
139
+ BottomStripProvider,
140
+ useBottomStrip
141
+ };
@@ -0,0 +1,32 @@
1
+ // src/components/base/BaseButton.tsx
2
+ import { forwardRef } from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ var BaseButton = forwardRef(({
5
+ variant = "secondary",
6
+ size = "md",
7
+ loading,
8
+ icon,
9
+ children,
10
+ className = "",
11
+ disabled,
12
+ ...props
13
+ }, ref) => {
14
+ return /* @__PURE__ */ jsxs(
15
+ "button",
16
+ {
17
+ ref,
18
+ className: `skipo-btn skipo-btn--${variant} skipo-btn--${size} ${className}`,
19
+ disabled: disabled || loading,
20
+ ...props,
21
+ children: [
22
+ loading ? /* @__PURE__ */ jsx("span", { className: "skipo-spinner" }) : icon,
23
+ children
24
+ ]
25
+ }
26
+ );
27
+ });
28
+ BaseButton.displayName = "BaseButton";
29
+
30
+ export {
31
+ BaseButton
32
+ };