@habit.analytics/habit-claims-journey-components 1.0.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.
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1200" fill="none"><rect width="1200" height="1200" fill="#EAEAEA" rx="3"/><g opacity=".5"><g opacity=".5"><path fill="#FAFAFA" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/></g><path stroke="url(#a)" stroke-width="2.418" d="M0-1.209h553.581" transform="scale(1 -1) rotate(45 1163.11 91.165)"/><path stroke="url(#b)" stroke-width="2.418" d="M404.846 598.671h391.726"/><path stroke="url(#c)" stroke-width="2.418" d="M599.5 795.742V404.017"/><path stroke="url(#d)" stroke-width="2.418" d="m795.717 796.597-391.441-391.44"/><path fill="#fff" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/><g clip-path="url(#e)"><path fill="#666" fill-rule="evenodd" d="M616.426 586.58h-31.434v16.176l3.553-3.554.531-.531h9.068l.074-.074 8.463-8.463h2.565l7.18 7.181V586.58Zm-15.715 14.654 3.698 3.699 1.283 1.282-2.565 2.565-1.282-1.283-5.2-5.199h-6.066l-5.514 5.514-.073.073v2.876a2.418 2.418 0 0 0 2.418 2.418h26.598a2.418 2.418 0 0 0 2.418-2.418v-8.317l-8.463-8.463-7.181 7.181-.071.072Zm-19.347 5.442v4.085a6.045 6.045 0 0 0 6.046 6.045h26.598a6.044 6.044 0 0 0 6.045-6.045v-7.108l1.356-1.355-1.282-1.283-.074-.073v-17.989h-38.689v23.43l-.146.146.146.147Z" clip-rule="evenodd"/></g><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/></g><defs><linearGradient id="a" x1="554.061" x2="-.48" y1=".083" y2=".087" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="b" x1="796.912" x2="404.507" y1="599.963" y2="599.965" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="c" x1="600.792" x2="600.794" y1="403.677" y2="796.082" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="d" x1="404.85" x2="796.972" y1="403.903" y2="796.02" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><clipPath id="e"><path fill="#fff" d="M581.364 580.535h38.689v38.689h-38.689z"/></clipPath></defs></svg>
@@ -0,0 +1,14 @@
1
+ User-agent: Googlebot
2
+ Allow: /
3
+
4
+ User-agent: Bingbot
5
+ Allow: /
6
+
7
+ User-agent: Twitterbot
8
+ Allow: /
9
+
10
+ User-agent: facebookexternalhit
11
+ Allow: /
12
+
13
+ User-agent: *
14
+ Allow: /
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ .react-flow{direction:ltr;--xy-edge-stroke-default: #b1b1b7;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #555;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(255, 255, 255, .5);--xy-minimap-background-color-default: #fff;--xy-minimap-mask-background-color-default: rgba(240, 240, 240, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #e2e2e2;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: transparent;--xy-background-pattern-dots-color-default: #91919a;--xy-background-pattern-lines-color-default: #eee;--xy-background-pattern-cross-color-default: #e2e2e2;background-color:var(--xy-background-color, var(--xy-background-color-default));--xy-node-color-default: inherit;--xy-node-border-default: 1px solid #1a192b;--xy-node-background-color-default: #fff;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(0, 0, 0, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #1a192b;--xy-node-border-radius-default: 3px;--xy-handle-background-color-default: #1a192b;--xy-handle-border-color-default: #fff;--xy-selection-background-color-default: rgba(0, 89, 220, .08);--xy-selection-border-default: 1px dotted rgba(0, 89, 220, .8);--xy-controls-button-background-color-default: #fefefe;--xy-controls-button-background-color-hover-default: #f4f4f4;--xy-controls-button-color-default: inherit;--xy-controls-button-color-hover-default: inherit;--xy-controls-button-border-color-default: #eee;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #ffffff;--xy-edge-label-color-default: inherit;--xy-resize-background-color-default: #3367d9}.react-flow.dark{--xy-edge-stroke-default: #3e3e3e;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #727272;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(150, 150, 150, .25);--xy-minimap-background-color-default: #141414;--xy-minimap-mask-background-color-default: rgba(60, 60, 60, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #2b2b2b;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: #141414;--xy-background-pattern-dots-color-default: #777;--xy-background-pattern-lines-color-default: #777;--xy-background-pattern-cross-color-default: #777;--xy-node-color-default: #f8f8f8;--xy-node-border-default: 1px solid #3c3c3c;--xy-node-background-color-default: #1e1e1e;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(255, 255, 255, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #999;--xy-handle-background-color-default: #bebebe;--xy-handle-border-color-default: #1e1e1e;--xy-selection-background-color-default: rgba(200, 200, 220, .08);--xy-selection-border-default: 1px dotted rgba(200, 200, 220, .8);--xy-controls-button-background-color-default: #2b2b2b;--xy-controls-button-background-color-hover-default: #3e3e3e;--xy-controls-button-color-default: #f8f8f8;--xy-controls-button-color-hover-default: #fff;--xy-controls-button-border-color-default: #5b5b5b;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #141414;--xy-edge-label-color-default: #f8f8f8}.react-flow__background{background-color:var(--xy-background-color-props, var(--xy-background-color, var(--xy-background-color-default)));pointer-events:none;z-index:-1}.react-flow__container{position:absolute;width:100%;height:100%;top:0;left:0}.react-flow__pane{z-index:1}.react-flow__pane.draggable{cursor:grab}.react-flow__pane.dragging{cursor:grabbing}.react-flow__pane.selection{cursor:pointer}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow__edge-path{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default));stroke-width:var(--xy-edge-stroke-width, var(--xy-edge-stroke-width-default));fill:none}.react-flow__connection-path{stroke:var(--xy-connectionline-stroke, var(--xy-connectionline-stroke-default));stroke-width:var(--xy-connectionline-stroke-width, var(--xy-connectionline-stroke-width-default));fill:none}.react-flow .react-flow__edges{position:absolute}.react-flow .react-flow__edges svg{overflow:visible;position:absolute;pointer-events:none}.react-flow__edge{pointer-events:visibleStroke}.react-flow__edge.selectable{cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge.selectable:focus .react-flow__edge-path,.react-flow__edge.selectable:focus-visible .react-flow__edge-path{stroke:var(--xy-edge-stroke-selected, var(--xy-edge-stroke-selected-default))}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__arrowhead polyline{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__arrowhead polyline.arrowclosed{fill:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:dashdraw .5s linear infinite}svg.react-flow__connectionline{z-index:1001;overflow:visible;position:absolute}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:default}.react-flow__node.selectable{cursor:pointer}.react-flow__node.draggable{cursor:grab;pointer-events:all}.react-flow__node.draggable.dragging{cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:left top;pointer-events:none}.react-flow__nodesselection-rect{position:absolute;pointer-events:all;cursor:grab}.react-flow__handle{position:absolute;pointer-events:none;min-width:5px;min-height:5px;width:6px;height:6px;background-color:var(--xy-handle-background-color, var(--xy-handle-background-color-default));border:1px solid var(--xy-handle-border-color, var(--xy-handle-border-color-default));border-radius:100%}.react-flow__handle.connectingfrom{pointer-events:all}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;left:50%;bottom:0;transform:translate(-50%,50%)}.react-flow__handle-top{top:0;left:50%;transform:translate(-50%,-50%)}.react-flow__handle-left{top:50%;left:0;transform:translate(-50%,-50%)}.react-flow__handle-right{top:50%;right:0;transform:translate(50%,-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__pane.selection .react-flow__panel{pointer-events:none}.react-flow__panel{position:absolute;z-index:5;margin:15px}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.top.center,.react-flow__panel.bottom.center{left:50%;transform:translate(-15px) translate(-50%)}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.left.center,.react-flow__panel.right.center{top:50%;transform:translateY(-15px) translateY(-50%)}.react-flow__attribution{font-size:10px;background:var(--xy-attribution-background-color, var(--xy-attribution-background-color-default));padding:2px 3px;margin:0}.react-flow__attribution a{text-decoration:none;color:#999}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{position:absolute;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;left:0;top:0}.react-flow__viewport-portal{position:absolute;width:100%;height:100%;left:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__minimap{background:var( --xy-minimap-background-color-props, var(--xy-minimap-background-color, var(--xy-minimap-background-color-default)) )}.react-flow__minimap-svg{display:block}.react-flow__minimap-mask{fill:var( --xy-minimap-mask-background-color-props, var(--xy-minimap-mask-background-color, var(--xy-minimap-mask-background-color-default)) );stroke:var( --xy-minimap-mask-stroke-color-props, var(--xy-minimap-mask-stroke-color, var(--xy-minimap-mask-stroke-color-default)) );stroke-width:var( --xy-minimap-mask-stroke-width-props, var(--xy-minimap-mask-stroke-width, var(--xy-minimap-mask-stroke-width-default)) )}.react-flow__minimap-node{fill:var( --xy-minimap-node-background-color-props, var(--xy-minimap-node-background-color, var(--xy-minimap-node-background-color-default)) );stroke:var( --xy-minimap-node-stroke-color-props, var(--xy-minimap-node-stroke-color, var(--xy-minimap-node-stroke-color-default)) );stroke-width:var( --xy-minimap-node-stroke-width-props, var(--xy-minimap-node-stroke-width, var(--xy-minimap-node-stroke-width-default)) )}.react-flow__background-pattern.dots{fill:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-dots-color-default)) )}.react-flow__background-pattern.lines{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-lines-color-default)) )}.react-flow__background-pattern.cross{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-cross-color-default)) )}.react-flow__controls{display:flex;flex-direction:column;box-shadow:var(--xy-controls-box-shadow, var(--xy-controls-box-shadow-default))}.react-flow__controls.horizontal{flex-direction:row}.react-flow__controls-button{display:flex;justify-content:center;align-items:center;height:26px;width:26px;padding:4px;border:none;background:var(--xy-controls-button-background-color, var(--xy-controls-button-background-color-default));border-bottom:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) );color:var( --xy-controls-button-color-props, var(--xy-controls-button-color, var(--xy-controls-button-color-default)) );cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__controls-button svg{width:100%;max-width:12px;max-height:12px;fill:currentColor}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-input,.react-flow__node-default,.react-flow__node-output,.react-flow__node-group{padding:10px;border-radius:var(--xy-node-border-radius, var(--xy-node-border-radius-default));width:150px;font-size:12px;color:var(--xy-node-color, var(--xy-node-color-default));text-align:center;border:var(--xy-node-border, var(--xy-node-border-default));background-color:var(--xy-node-background-color, var(--xy-node-background-color-default))}.react-flow__node-input.selectable:hover,.react-flow__node-default.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:var(--xy-node-boxshadow-hover, var(--xy-node-boxshadow-hover-default))}.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:var(--xy-node-boxshadow-selected, var(--xy-node-boxshadow-selected-default))}.react-flow__node-group{background-color:var(--xy-node-group-background-color, var(--xy-node-group-background-color-default))}.react-flow__nodesselection-rect,.react-flow__selection{background:var(--xy-selection-background-color, var(--xy-selection-background-color-default));border:var(--xy-selection-border, var(--xy-selection-border-default))}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls-button:hover{background:var( --xy-controls-button-background-color-hover-props, var(--xy-controls-button-background-color-hover, var(--xy-controls-button-background-color-hover-default)) );color:var( --xy-controls-button-color-hover-props, var(--xy-controls-button-color-hover, var(--xy-controls-button-color-hover-default)) )}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__controls-button:last-child{border-bottom:none}.react-flow__controls.horizontal .react-flow__controls-button{border-bottom:none;border-right:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) )}.react-flow__controls.horizontal .react-flow__controls-button:last-child{border-right:none}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{width:5px;height:5px;border:1px solid #fff;border-radius:1px;background-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));translate:-50% -50%}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));border-width:0;border-style:solid}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;transform:translate(-50%);top:0;height:100%}.react-flow__resize-control.line.left{left:0;border-left-width:1px}.react-flow__resize-control.line.right{left:100%;border-right-width:1px}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{height:1px;transform:translateY(-50%);left:0;width:100%}.react-flow__resize-control.line.top{top:0;border-top-width:1px}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.react-flow__edge-textbg{fill:var(--xy-edge-label-background-color, var(--xy-edge-label-background-color-default))}.react-flow__edge-text{fill:var(--xy-edge-label-color, var(--xy-edge-label-color-default))}
package/package.json ADDED
@@ -0,0 +1,130 @@
1
+ {
2
+ "name": "@habit.analytics/habit-claims-journey-components",
3
+ "version": "1.0.0",
4
+ "author": "Habit (https://www.habit.io/)",
5
+ "description": "Visual graph-based journey builder and step-by-step form runner React widgets for claims workflows",
6
+ "keywords": [
7
+ "react",
8
+ "journey-builder",
9
+ "form-runner",
10
+ "graph-editor",
11
+ "claims",
12
+ "react-flow",
13
+ "visual-editor",
14
+ "form-wizard",
15
+ "json-logic",
16
+ "widget"
17
+ ],
18
+ "license": "MIT",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/habitio/habit-claims-journey-components.git"
22
+ },
23
+ "homepage": "https://github.com/habitio/habit-claims-journey-components#readme",
24
+ "type": "module",
25
+ "scripts": {
26
+ "dev": "vite",
27
+ "build": "vite build",
28
+ "build:dev": "vite build --mode development",
29
+ "build:lib": "vite build --config vite.lib.config.ts",
30
+ "lint": "eslint .",
31
+ "preview": "vite preview",
32
+ "test": "vitest run",
33
+ "test:watch": "vitest"
34
+ },
35
+ "main": "dist/index.cjs",
36
+ "module": "dist/index.mjs",
37
+ "types": "src/index.ts",
38
+ "exports": {
39
+ ".": {
40
+ "import": "./dist/index.mjs",
41
+ "require": "./dist/index.cjs",
42
+ "types": "./src/index.ts"
43
+ },
44
+ "./style.css": "./dist/style.css"
45
+ },
46
+ "files": [
47
+ "dist",
48
+ "src/index.ts",
49
+ "src/types"
50
+ ],
51
+ "dependencies": {
52
+ "@hookform/resolvers": "^3.10.0",
53
+ "@radix-ui/react-accordion": "^1.2.11",
54
+ "@radix-ui/react-alert-dialog": "^1.1.14",
55
+ "@radix-ui/react-aspect-ratio": "^1.1.7",
56
+ "@radix-ui/react-avatar": "^1.1.10",
57
+ "@radix-ui/react-checkbox": "^1.3.2",
58
+ "@radix-ui/react-collapsible": "^1.1.11",
59
+ "@radix-ui/react-context-menu": "^2.2.15",
60
+ "@radix-ui/react-dialog": "^1.1.14",
61
+ "@radix-ui/react-dropdown-menu": "^2.1.15",
62
+ "@radix-ui/react-hover-card": "^1.1.14",
63
+ "@radix-ui/react-label": "^2.1.7",
64
+ "@radix-ui/react-menubar": "^1.1.15",
65
+ "@radix-ui/react-navigation-menu": "^1.2.13",
66
+ "@radix-ui/react-popover": "^1.1.14",
67
+ "@radix-ui/react-progress": "^1.1.7",
68
+ "@radix-ui/react-radio-group": "^1.3.7",
69
+ "@radix-ui/react-scroll-area": "^1.2.9",
70
+ "@radix-ui/react-select": "^2.2.5",
71
+ "@radix-ui/react-separator": "^1.1.7",
72
+ "@radix-ui/react-slider": "^1.3.5",
73
+ "@radix-ui/react-slot": "^1.2.3",
74
+ "@radix-ui/react-switch": "^1.2.5",
75
+ "@radix-ui/react-tabs": "^1.1.12",
76
+ "@radix-ui/react-toast": "^1.2.14",
77
+ "@radix-ui/react-toggle": "^1.1.9",
78
+ "@radix-ui/react-toggle-group": "^1.1.10",
79
+ "@radix-ui/react-tooltip": "^1.2.7",
80
+ "@tanstack/react-query": "^5.83.0",
81
+ "class-variance-authority": "^0.7.1",
82
+ "clsx": "^2.1.1",
83
+ "cmdk": "^1.1.1",
84
+ "date-fns": "^3.6.0",
85
+ "embla-carousel-react": "^8.6.0",
86
+ "input-otp": "^1.4.2",
87
+ "json-logic-js": "^2.0.5",
88
+ "lucide-react": "^0.462.0",
89
+ "next-themes": "^0.3.0",
90
+ "react-day-picker": "^8.10.1",
91
+ "react-hook-form": "^7.61.1",
92
+ "react-resizable-panels": "^2.1.9",
93
+ "react-router-dom": "^6.30.1",
94
+ "recharts": "^2.15.4",
95
+ "sonner": "^1.7.4",
96
+ "tailwind-merge": "^2.6.0",
97
+ "tailwindcss-animate": "^1.0.7",
98
+ "vaul": "^0.9.9",
99
+ "zod": "^3.25.76",
100
+ "zustand": "^5.0.11"
101
+ },
102
+ "devDependencies": {
103
+ "@eslint/js": "^9.32.0",
104
+ "@tailwindcss/typography": "^0.5.16",
105
+ "@testing-library/jest-dom": "^6.6.0",
106
+ "@testing-library/react": "^16.0.0",
107
+ "@types/node": "^22.16.5",
108
+ "@types/react": "^18.3.23",
109
+ "@types/react-dom": "^18.3.7",
110
+ "@vitejs/plugin-react-swc": "^3.11.0",
111
+ "autoprefixer": "^10.4.21",
112
+ "eslint": "^9.32.0",
113
+ "eslint-plugin-react-hooks": "^5.2.0",
114
+ "eslint-plugin-react-refresh": "^0.4.20",
115
+ "globals": "^15.15.0",
116
+ "jsdom": "^20.0.3",
117
+ "lovable-tagger": "^1.1.13",
118
+ "postcss": "^8.5.6",
119
+ "tailwindcss": "^3.4.17",
120
+ "typescript": "^5.8.3",
121
+ "typescript-eslint": "^8.38.0",
122
+ "vite": "^5.4.19",
123
+ "vitest": "^3.2.4"
124
+ },
125
+ "peerDependencies": {
126
+ "react": "^18.3.1",
127
+ "react-dom": "^18.3.1",
128
+ "@xyflow/react": "^12.10.0"
129
+ }
130
+ }
package/src/index.ts ADDED
@@ -0,0 +1,21 @@
1
+ // Widgets
2
+ export { JourneyBuilderWidget } from './components/journey-builder/JourneyBuilderWidget';
3
+ export type { JourneyBuilderWidgetProps } from './components/journey-builder/JourneyBuilderWidget';
4
+
5
+ export { FormRunnerWidget } from './components/runner/FormRunnerWidget';
6
+ export type { FormRunnerWidgetProps } from './components/runner/FormRunnerWidget';
7
+
8
+ // Types
9
+ export type {
10
+ ClaimPropertySpec,
11
+ ClaimPropertySpecOption,
12
+ JourneySpec,
13
+ JourneySpecNode,
14
+ JourneySpecEdge,
15
+ JourneyNodeData,
16
+ JourneyEdgeData,
17
+ NodeBinding,
18
+ Actor,
19
+ } from './types/journey';
20
+
21
+ export { SCHEMA_TYPES, getSchemaInfo } from './types/journey';
@@ -0,0 +1,228 @@
1
+ /**
2
+ * A selectable option within a {@link ClaimPropertySpec} that uses a select-type schema.
3
+ */
4
+ export interface ClaimPropertySpecOption {
5
+ /** The stored value submitted when this option is selected. */
6
+ data: string;
7
+ /** Human-readable display text for this option. */
8
+ label: string;
9
+ /** Optional list of follow-up namespace keys that become relevant when this option is chosen. */
10
+ next?: string[];
11
+ }
12
+
13
+ /**
14
+ * A field definition from the claim data model.
15
+ *
16
+ * Each spec describes a single question/field that can be dragged onto the
17
+ * Journey Builder canvas. Specs are provided by the host application and
18
+ * determine the widget type, validation rules, and default labels.
19
+ */
20
+ export interface ClaimPropertySpec {
21
+ /** Unique identifier for this spec. */
22
+ id: string;
23
+ /** Dot-notation namespace used as the answer key (e.g. `"insured.full_name"`). */
24
+ namespace: string;
25
+ /** ID of the parent claim specification this field belongs to. */
26
+ claimspec_id: string;
27
+ /** ID of the parent spec for hierarchical grouping, or `null` for top-level fields. */
28
+ parent_id: string | null;
29
+ /** Display order within the catalog. */
30
+ order_index: number;
31
+ /** Schema type that determines which widget and validation to use (e.g. `"v1_string"`, `"v2_date-1"`). */
32
+ schema: string;
33
+ /** Human-readable label shown in the catalog and on the canvas. */
34
+ label: string;
35
+ /** Default/forced data value, or `null` if user-provided. */
36
+ data: string | null;
37
+ /** When `true`, the `data` value is always used regardless of user input. */
38
+ force_data: boolean;
39
+ /** Selectable options for select-type schemas, or `null` for free-text schemas. */
40
+ options: ClaimPropertySpecOption[] | null;
41
+ /** Optional help text displayed below the input widget. */
42
+ help_text: string | null;
43
+ /** Optional placeholder text for the input widget. */
44
+ placeholder: string | null;
45
+ /** Optional icon identifier. */
46
+ icon: string | null;
47
+ /** Optional image URL. */
48
+ image: string | null;
49
+ /** CSS class names for custom styling. */
50
+ classes: string[];
51
+ }
52
+
53
+ /**
54
+ * The actor responsible for answering a question.
55
+ * - `"customer"` — end-user facing
56
+ * - `"operator"` — internal/back-office facing
57
+ */
58
+ export type Actor = 'customer' | 'operator';
59
+
60
+ /**
61
+ * Maps a node's answer to a target namespace in the final output.
62
+ *
63
+ * A single node can write its answer to multiple namespaces via multiple bindings,
64
+ * enabling data reuse across the claim model.
65
+ */
66
+ export interface NodeBinding {
67
+ /** The namespace key where the answer value will be stored. */
68
+ target_namespace: string;
69
+ }
70
+
71
+ /**
72
+ * Internal data shape for a node on the React Flow canvas.
73
+ *
74
+ * This is the `data` property of a React Flow `Node<JourneyNodeData>`.
75
+ * Not typically used by external consumers — see {@link JourneySpecNode} instead.
76
+ */
77
+ export interface JourneyNodeData extends Record<string, unknown> {
78
+ /** Source spec ID, or `"custom"` for user-created fields. */
79
+ specId: string;
80
+ /** Answer key namespace. */
81
+ namespace: string;
82
+ /** Display label (from spec or override). */
83
+ label: string;
84
+ /** Optional label override set by the builder user. */
85
+ labelOverride?: string;
86
+ /** Schema type determining the widget and validation. */
87
+ schema: string;
88
+ /** Selectable options for select-type schemas. */
89
+ options: ClaimPropertySpecOption[] | null;
90
+ /** Who answers this question. */
91
+ actor: Actor;
92
+ /** Namespace bindings for answer propagation. */
93
+ bindings: NodeBinding[];
94
+ /** Optional widget override (e.g. `"email"`, `"phone"`). */
95
+ widget?: string;
96
+ /** When `true`, the user must provide an answer before proceeding. */
97
+ required: boolean;
98
+ }
99
+
100
+ /**
101
+ * Internal data shape for an edge on the React Flow canvas.
102
+ *
103
+ * This is the `data` property of a React Flow `Edge<JourneyEdgeData>`.
104
+ * Not typically used by external consumers — see {@link JourneySpecEdge} instead.
105
+ */
106
+ export interface JourneyEdgeData extends Record<string, unknown> {
107
+ /** JSON Logic condition that must evaluate to `true` for this edge to be taken. `null` means unconditional. */
108
+ condition: Record<string, unknown> | null;
109
+ /** Higher priority edges are evaluated first. */
110
+ priority: number;
111
+ /** When `true`, this edge is the fallback if no conditional edges match. */
112
+ isDefault: boolean;
113
+ }
114
+
115
+ /**
116
+ * A node in the portable journey specification format.
117
+ *
118
+ * This is the serialized form used in {@link JourneySpec} for export/import
119
+ * and for initializing the {@link FormRunnerWidget}.
120
+ */
121
+ export interface JourneySpecNode {
122
+ /** Unique node identifier. */
123
+ node_id: string;
124
+ /** Namespace used as the answer key in the collected results. */
125
+ question_key: string;
126
+ /** ID of the source {@link ClaimPropertySpec}, or `"custom"`. */
127
+ source_property_spec_id: string;
128
+ /** Schema type (e.g. `"v1_string"`, `"v2_currency-1"`). */
129
+ schema: string;
130
+ /** Options for select-type schemas. */
131
+ options?: ClaimPropertySpecOption[] | null;
132
+ /** Who answers this question. */
133
+ actor: Actor;
134
+ /** Namespace bindings for answer propagation. */
135
+ bindings: NodeBinding[];
136
+ /** UI configuration including widget type. */
137
+ ui: { widget: string };
138
+ /** Canvas position for the builder layout. */
139
+ layout: { x: number; y: number };
140
+ /** Display label from the spec catalog or custom node name. */
141
+ label?: string;
142
+ /** Optional human-readable label override provided by the journey author. */
143
+ label_override?: string;
144
+ /** When `true`, an answer is required before the user can proceed. */
145
+ required?: boolean;
146
+ }
147
+
148
+ /**
149
+ * An edge (connection) in the portable journey specification format.
150
+ *
151
+ * Edges define the navigation path between nodes. Conditional edges use
152
+ * JSON Logic expressions evaluated against `{ answers: { ... } }`.
153
+ */
154
+ export interface JourneySpecEdge {
155
+ /** Unique edge identifier. */
156
+ edge_id: string;
157
+ /** Source node ID. */
158
+ from_node_id: string;
159
+ /** Target node ID. */
160
+ to_node_id: string;
161
+ /** JSON Logic condition, or `null` for unconditional edges. Evaluated against `{ answers }`. */
162
+ condition: Record<string, unknown> | null;
163
+ /** Evaluation priority — higher values are checked first. */
164
+ priority: number;
165
+ /** When `true`, this edge is the fallback taken when no conditional edges match. */
166
+ is_default: boolean;
167
+ }
168
+
169
+ /**
170
+ * The portable journey graph format.
171
+ *
172
+ * This is the primary data contract between the Builder and Runner widgets.
173
+ * - **Output** of `JourneyBuilderWidget` via `onSave` / `onChange` callbacks
174
+ * - **Input** to `FormRunnerWidget` via the `journey` prop
175
+ *
176
+ * @example
177
+ * ```typescript
178
+ * const journey: JourneySpec = {
179
+ * journey_id: "j-001",
180
+ * claimspec_id: "cs-001",
181
+ * version: "1.0",
182
+ * nodes: [...],
183
+ * edges: [...],
184
+ * start_node_id: "node-1",
185
+ * };
186
+ * ```
187
+ */
188
+ export interface JourneySpec {
189
+ /** Unique journey identifier. */
190
+ journey_id: string;
191
+ /** Associated claim specification ID. */
192
+ claimspec_id: string;
193
+ /** Schema version string. */
194
+ version: string;
195
+ /** All question nodes in the journey. */
196
+ nodes: JourneySpecNode[];
197
+ /** All edges (connections) defining navigation paths. */
198
+ edges: JourneySpecEdge[];
199
+ /** ID of the first node, or `null` if auto-detected (node with no incoming edges). */
200
+ start_node_id: string | null;
201
+ }
202
+
203
+ /**
204
+ * Maps schema type strings to their display label and badge color.
205
+ *
206
+ * @see {@link getSchemaInfo} for safe lookup with fallback.
207
+ */
208
+ export const SCHEMA_TYPES = {
209
+ 'v1_string': { label: 'String', color: 'bg-blue-500' },
210
+ 'v2_single_option_select-1': { label: 'Single Select', color: 'bg-purple-500' },
211
+ 'v2_date-1': { label: 'Date', color: 'bg-green-500' },
212
+ 'v2_currency-1': { label: 'Currency', color: 'bg-yellow-500' },
213
+ 'v2_single_asset_upload': { label: 'Upload', color: 'bg-orange-500' },
214
+ 'v2_phone-1': { label: 'Phone', color: 'bg-teal-500' },
215
+ 'v2_email-1': { label: 'Email', color: 'bg-rose-500' },
216
+ } as const;
217
+
218
+ /**
219
+ * Returns the display label and badge color for a schema type.
220
+ *
221
+ * Falls back to `{ label: schema, color: 'bg-muted' }` for unknown types.
222
+ *
223
+ * @param schema - The schema type string (e.g. `"v1_string"`).
224
+ * @returns An object with `label` and `color` properties.
225
+ */
226
+ export function getSchemaInfo(schema: string) {
227
+ return SCHEMA_TYPES[schema as keyof typeof SCHEMA_TYPES] || { label: schema, color: 'bg-muted' };
228
+ }
@@ -0,0 +1,5 @@
1
+ declare module 'json-logic-js' {
2
+ function apply(logic: object, data: object): unknown;
3
+ export default { apply };
4
+ export { apply };
5
+ }