@optiaxiom/proteus 0.1.27-next.2 → 0.2.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 (19) hide show
  1. package/dist/esm/assets/src/proteus-chart/{ProteusChart.css.ts.vanilla-BjD9gTQa.css → ProteusChart.css.ts.vanilla-BLxzbWut.css} +2 -2
  2. package/dist/esm/assets/src/proteus-chart/{ProteusChartTooltipContent.css.ts.vanilla-CiBO2VBA.css → ProteusChartTooltipContent.css.ts.vanilla-JTr7n2a8.css} +3 -2
  3. package/dist/esm/assets/src/proteus-document/{ProteusDocumentShell.css.ts.vanilla-CONvLXzv.css → ProteusDocumentShell.css.ts.vanilla-BZNGG_wN.css} +2 -2
  4. package/dist/esm/assets/src/proteus-image-carousel/{ProteusImageCarousel.css.ts.vanilla-BR0bm1gm.css → ProteusImageCarousel.css.ts.vanilla-f4zcbZW_.css} +2 -2
  5. package/dist/esm/assets/src/proteus-question/{ProteusQuestion.css.ts.vanilla-B6KKoYKy.css → ProteusQuestion.css.ts.vanilla-D7Zi6Bwi.css} +2 -2
  6. package/dist/esm/proteus-chart/ProteusChart-css.js +1 -1
  7. package/dist/esm/proteus-chart/ProteusChart.js +16 -5
  8. package/dist/esm/proteus-chart/ProteusChartContext.js +7 -0
  9. package/dist/esm/proteus-chart/ProteusChartTooltipContent-css.js +2 -2
  10. package/dist/esm/proteus-chart/ProteusChartTooltipContent.js +52 -27
  11. package/dist/esm/proteus-document/ProteusDocumentShell-css.js +1 -1
  12. package/dist/esm/proteus-document/ProteusDocumentShell.js +6 -0
  13. package/dist/esm/proteus-image-carousel/ProteusImageCarousel-css.js +1 -1
  14. package/dist/esm/proteus-question/ProteusQuestion-css.js +1 -1
  15. package/dist/esm/proteus-question/ProteusQuestion.js +41 -9
  16. package/dist/esm/schema/public-schema.json.js +96 -111
  17. package/dist/esm/schema/runtime-schema.json.js +96 -111
  18. package/dist/index.d.ts +5 -1
  19. package/package.json +3 -3
@@ -1,5 +1,5 @@
1
- @layer optiaxiom._2m54yp;
2
- @layer optiaxiom._2m54yp {
1
+ @layer optiaxiom._155jno1;
2
+ @layer optiaxiom._155jno1 {
3
3
  .ProteusChart__jmlqij1 {
4
4
  border-radius: 16px;
5
5
  }
@@ -1,7 +1,8 @@
1
- @layer optiaxiom._2m54yp;
2
- @layer optiaxiom._2m54yp {
1
+ @layer optiaxiom._155jno1;
2
+ @layer optiaxiom._155jno1 {
3
3
  .ProteusChartTooltipContent__1gsvq810 {
4
4
  min-width: 128px;
5
+ position: absolute;
5
6
  }
6
7
  .ProteusChartTooltipContent__1gsvq811 {
7
8
  font-variant-numeric: tabular-nums;
@@ -1,5 +1,5 @@
1
- @layer optiaxiom._2m54yp;
2
- @layer optiaxiom._2m54yp {
1
+ @layer optiaxiom._155jno1;
2
+ @layer optiaxiom._155jno1 {
3
3
  .ProteusDocumentShell__vpuvfj1 {
4
4
  margin: -4px;
5
5
  }
@@ -1,5 +1,5 @@
1
- @layer optiaxiom._2m54yp;
2
- @layer optiaxiom._2m54yp {
1
+ @layer optiaxiom._155jno1;
2
+ @layer optiaxiom._155jno1 {
3
3
  .ProteusImageCarousel__1t6qej70 {
4
4
  outline: none;
5
5
  user-select: none;
@@ -1,5 +1,5 @@
1
- @layer optiaxiom._2m54yp;
2
- @layer optiaxiom._2m54yp {
1
+ @layer optiaxiom._155jno1;
2
+ @layer optiaxiom._155jno1 {
3
3
  .ProteusQuestion__8f590p0 {
4
4
  outline: none;
5
5
  }
@@ -1,4 +1,4 @@
1
- import './../assets/src/proteus-chart/ProteusChart.css.ts.vanilla-BjD9gTQa.css';
1
+ import './../assets/src/proteus-chart/ProteusChart.css.ts.vanilla-BLxzbWut.css';
2
2
  import { recipe } from '@optiaxiom/react/css-runtime';
3
3
 
4
4
  var chart = recipe({base:[{border:'1',borderColor:'border.tertiary',fontSize:'sm',p:'16'},'ProteusChart__jmlqij1','ProteusChart__jmlqij0']});
@@ -2,8 +2,10 @@
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
3
  import { Box, theme } from '@optiaxiom/react';
4
4
  import { get } from 'jsonpointer';
5
+ import { useRef } from 'react';
5
6
  import { ResponsiveContainer, BarChart, LineChart, CartesianGrid, YAxis, XAxis, Tooltip, Bar, Line } from 'recharts';
6
7
  import { chart } from './ProteusChart-css.js';
8
+ import { ProteusChartContext } from './ProteusChartContext.js';
7
9
  import { ProteusChartTooltipContent } from './ProteusChartTooltipContent.js';
8
10
 
9
11
  const DEFAULT_COLORS = ["#096DD9", "#E59700", "#38C56C", "#D1D8DE"];
@@ -20,11 +22,12 @@ const ProteusChart = ({
20
22
  const Chart = type === "bar" ? Bar : Line;
21
23
  const CategoryAxis = isVertical ? YAxis : XAxis;
22
24
  const ValueAxis = isVertical ? XAxis : YAxis;
23
- return /* @__PURE__ */ jsx(Box, { asChild: true, ...chart(), children: /* @__PURE__ */ jsx(ResponsiveContainer, { aspect: 16 / 9, width: "100%", children: /* @__PURE__ */ jsxs(ChartComponent, { data, layout, children: [
25
+ const containerRef = useRef(null);
26
+ return /* @__PURE__ */ jsx(ProteusChartContext.Provider, { value: containerRef, children: /* @__PURE__ */ jsx(Box, { asChild: true, ref: containerRef, ...chart(), children: /* @__PURE__ */ jsx(ResponsiveContainer, { aspect: 16 / 9, width: "100%", children: /* @__PURE__ */ jsxs(ChartComponent, { data, layout, children: [
24
27
  /* @__PURE__ */ jsx(
25
28
  CartesianGrid,
26
29
  {
27
- stroke: "#E0E0E0",
30
+ stroke: theme.colors["border.secondary"],
28
31
  strokeDasharray: "4 4",
29
32
  vertical: false
30
33
  }
@@ -36,6 +39,7 @@ const ProteusChart = ({
36
39
  dataKey: (row) => get(row, "/" + xAxisKey),
37
40
  padding: { left: 16, right: 16 },
38
41
  tick: { fill: theme.colors["fg.secondary"] },
42
+ tickFormatter: (value) => value.length > 30 ? value.slice(0, 30) + "\u2026" : value,
39
43
  tickLine: false,
40
44
  tickMargin: 8,
41
45
  type: "category",
@@ -45,7 +49,7 @@ const ProteusChart = ({
45
49
  /* @__PURE__ */ jsx(
46
50
  ValueAxis,
47
51
  {
48
- axisLine: { stroke: "#CBD5E1" },
52
+ axisLine: { stroke: theme.colors["border.default"] },
49
53
  minTickGap: 32,
50
54
  tick: { fill: theme.colors["fg.secondary"] },
51
55
  tickFormatter: (value) => new Intl.NumberFormat(void 0, {
@@ -57,7 +61,14 @@ const ProteusChart = ({
57
61
  width: isVertical ? void 0 : "auto"
58
62
  }
59
63
  ),
60
- /* @__PURE__ */ jsx(Tooltip, { content: ProteusChartTooltipContent, cursor: false }),
64
+ /* @__PURE__ */ jsx(
65
+ Tooltip,
66
+ {
67
+ content: ProteusChartTooltipContent,
68
+ cursor: false,
69
+ portal: document.body
70
+ }
71
+ ),
61
72
  series.map((s, i) => /* @__PURE__ */ jsx(
62
73
  Chart,
63
74
  {
@@ -70,7 +81,7 @@ const ProteusChart = ({
70
81
  },
71
82
  i
72
83
  ))
73
- ] }) }) });
84
+ ] }) }) }) });
74
85
  };
75
86
  ProteusChart.displayName = "@optiaxiom/proteus/ProteusChart";
76
87
 
@@ -0,0 +1,7 @@
1
+ "use client";
2
+ import { createContext, useContext } from 'react';
3
+
4
+ const ProteusChartContext = createContext(void 0);
5
+ const useProteusChartContainer = () => useContext(ProteusChartContext);
6
+
7
+ export { ProteusChartContext, useProteusChartContainer };
@@ -1,7 +1,7 @@
1
- import './../assets/src/proteus-chart/ProteusChartTooltipContent.css.ts.vanilla-CiBO2VBA.css';
1
+ import './../assets/src/proteus-chart/ProteusChartTooltipContent.css.ts.vanilla-JTr7n2a8.css';
2
2
  import { recipe } from '@optiaxiom/react/css-runtime';
3
3
 
4
- var tooltip = recipe({base:[{bg:'bg.default',border:'1',borderColor:'border.secondary',display:'grid',fontSize:'sm',gap:'6',px:'8',py:'10',rounded:'lg',shadow:'lg'},'ProteusChartTooltipContent__1gsvq810']});
4
+ var tooltip = recipe({base:[{bg:'bg.default',border:'1',borderColor:'border.secondary',display:'grid',fontSize:'sm',gap:'6',pointerEvents:'none',px:'8',py:'10',rounded:'lg',shadow:'lg',transition:'all'},'ProteusChartTooltipContent__1gsvq810']});
5
5
  var value = recipe({base:[{color:'fg.default',fontWeight:'500'},'ProteusChartTooltipContent__1gsvq811']});
6
6
 
7
7
  export { tooltip, value };
@@ -1,45 +1,70 @@
1
1
  "use client";
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import { Box, Group } from '@optiaxiom/react';
4
+ import { useRef } from 'react';
4
5
  import { applyFormatter } from '../proteus-document/getProteusValue.js';
6
+ import { useProteusChartContainer } from './ProteusChartContext.js';
5
7
  import { value, tooltip } from './ProteusChartTooltipContent-css.js';
6
8
 
9
+ const OFFSET = 10;
7
10
  function ProteusChartTooltipContent({
8
11
  active,
12
+ coordinate,
9
13
  label,
10
14
  payload
11
15
  }) {
16
+ const containerRef = useProteusChartContainer();
17
+ const ref = useRef(null);
12
18
  if (!active || !payload?.length) {
13
19
  return null;
14
20
  }
15
- return /* @__PURE__ */ jsxs(Box, { ...tooltip(), children: [
16
- label && /* @__PURE__ */ jsx(Box, { fontWeight: "500", children: label }),
17
- /* @__PURE__ */ jsx("div", { children: payload.filter((item) => item.type !== "none").map((item, i) => /* @__PURE__ */ jsxs(
18
- Box,
19
- {
20
- alignItems: "center",
21
- display: "flex",
22
- gap: "8",
23
- justifyContent: "space-between",
24
- children: [
25
- /* @__PURE__ */ jsxs(Group, { gap: "8", children: [
26
- /* @__PURE__ */ jsx(
27
- Box,
28
- {
29
- flex: "none",
30
- rounded: "xs",
31
- size: "10",
32
- style: { backgroundColor: item.color }
33
- }
34
- ),
35
- /* @__PURE__ */ jsx(Box, { color: "fg.tertiary", children: item.name ?? String(item.dataKey) })
36
- ] }),
37
- /* @__PURE__ */ jsx(Box, { ...value(), children: applyFormatter(item.value, "Number") })
38
- ]
21
+ const wrapperRect = containerRef?.current?.querySelector(".recharts-wrapper")?.getBoundingClientRect();
22
+ const tooltipRect = ref.current?.getBoundingClientRect();
23
+ const cx = coordinate?.x ?? 0;
24
+ const cy = coordinate?.y ?? 0;
25
+ const th = tooltipRect?.height ?? 0;
26
+ const translateX = cx + OFFSET;
27
+ const translateY = cy - th / 2;
28
+ return /* @__PURE__ */ jsxs(
29
+ Box,
30
+ {
31
+ ref,
32
+ style: {
33
+ left: 0,
34
+ top: 0,
35
+ transform: `translate(${(wrapperRect?.left ?? 0) + translateX + window.scrollX}px, ${(wrapperRect?.top ?? 0) + translateY + window.scrollY}px)`
39
36
  },
40
- i
41
- )) })
42
- ] });
37
+ ...tooltip(),
38
+ children: [
39
+ label && /* @__PURE__ */ jsx(Box, { fontWeight: "500", children: label }),
40
+ /* @__PURE__ */ jsx("div", { children: payload.filter((item) => item.type !== "none").map((item, i) => /* @__PURE__ */ jsxs(
41
+ Box,
42
+ {
43
+ alignItems: "center",
44
+ display: "flex",
45
+ gap: "8",
46
+ justifyContent: "space-between",
47
+ children: [
48
+ /* @__PURE__ */ jsxs(Group, { gap: "8", children: [
49
+ /* @__PURE__ */ jsx(
50
+ Box,
51
+ {
52
+ flex: "none",
53
+ rounded: "xs",
54
+ size: "10",
55
+ style: { backgroundColor: item.color }
56
+ }
57
+ ),
58
+ /* @__PURE__ */ jsx(Box, { color: "fg.tertiary", children: item.name ?? String(item.dataKey) })
59
+ ] }),
60
+ /* @__PURE__ */ jsx(Box, { ...value(), children: applyFormatter(item.value, "Number") })
61
+ ]
62
+ },
63
+ i
64
+ )) })
65
+ ]
66
+ }
67
+ );
43
68
  }
44
69
 
45
70
  export { ProteusChartTooltipContent };
@@ -1,4 +1,4 @@
1
- import './../assets/src/proteus-document/ProteusDocumentShell.css.ts.vanilla-CONvLXzv.css';
1
+ import './../assets/src/proteus-document/ProteusDocumentShell.css.ts.vanilla-BZNGG_wN.css';
2
2
  import { recipe } from '@optiaxiom/react/css-runtime';
3
3
 
4
4
  var body = recipe({base:[{flexDirection:'column',gap:'16'},'ProteusDocumentShell__vpuvfj0'],variants:{truncate:{false:{},true:[{maxH:'sm',overflow:'auto',p:'4'},'ProteusDocumentShell__vpuvfj1']}}});
@@ -20,6 +20,7 @@ function ProteusDocumentShell({
20
20
  onInteraction,
21
21
  onMessage,
22
22
  onOpenChange,
23
+ onTrack,
23
24
  open: openProp,
24
25
  readOnly = false,
25
26
  strict,
@@ -95,6 +96,11 @@ function ProteusDocumentShell({
95
96
  }
96
97
  return;
97
98
  }),
99
+ onTrack: useEffectEvent(
100
+ (event, properties) => {
101
+ onTrack?.(event, properties);
102
+ }
103
+ ),
98
104
  readOnly,
99
105
  strict,
100
106
  useResource,
@@ -1,4 +1,4 @@
1
- import './../assets/src/proteus-image-carousel/ProteusImageCarousel.css.ts.vanilla-BR0bm1gm.css';
1
+ import './../assets/src/proteus-image-carousel/ProteusImageCarousel.css.ts.vanilla-f4zcbZW_.css';
2
2
  import { recipe } from '@optiaxiom/react/css-runtime';
3
3
 
4
4
  var carousel = recipe({base:[{flexDirection:'column',gap:'12'},'ProteusImageCarousel__1t6qej70']});
@@ -1,4 +1,4 @@
1
- import './../assets/src/proteus-question/ProteusQuestion.css.ts.vanilla-B6KKoYKy.css';
1
+ import './../assets/src/proteus-question/ProteusQuestion.css.ts.vanilla-D7Zi6Bwi.css';
2
2
  import { recipe } from '@optiaxiom/react/css-runtime';
3
3
 
4
4
  var addon = recipe({base:[{display:'grid',fontWeight:'500',placeItems:'center',rounded:'lg',size:'md',transition:'colors'},'ProteusQuestion__8f590p3'],variants:{cursor:{pointer:{cursor:'pointer'}}}});
@@ -12,18 +12,28 @@ import { useProteusDocumentContext } from '../proteus-document/ProteusDocumentCo
12
12
  import { addon, choice, choiceGroup, question } from './ProteusQuestion-css.js';
13
13
 
14
14
  function ProteusQuestion({ questions }) {
15
- const { onEvent } = useProteusDocumentContext(
15
+ const { onEvent, onTrack } = useProteusDocumentContext(
16
16
  "@optiaxiom/proteus/ProteusQuestion"
17
17
  );
18
18
  const [answers, setAnswers] = useState([]);
19
19
  const [currentIndex, setCurrentIndex] = useState(0);
20
20
  const value = answers[currentIndex];
21
21
  const valid = Array.isArray(value) && value.length > 0 && value.every(Boolean);
22
+ const goBack = useCallback(() => {
23
+ onTrack?.("Ask User Question Back", {
24
+ fromIndex: String(currentIndex),
25
+ toIndex: String(currentIndex - 1)
26
+ });
27
+ setCurrentIndex((i) => i - 1);
28
+ }, [currentIndex, onTrack]);
22
29
  const onDismiss = useCallback(() => {
30
+ onTrack?.("Ask User Question Dismissed", {
31
+ questionIndex: String(currentIndex)
32
+ });
23
33
  void onEvent({
24
34
  message: "[User declined to answer the question]"
25
35
  });
26
- }, [onEvent]);
36
+ }, [currentIndex, onEvent, onTrack]);
27
37
  const questionRef = useRef(null);
28
38
  const lastIndexRef = useRef(currentIndex);
29
39
  useEffect(() => {
@@ -57,17 +67,30 @@ function ProteusQuestion({ questions }) {
57
67
  const isLast = currentIndex === questions.length - 1;
58
68
  const otherValue = value?.find((v) => !options.includes(v));
59
69
  const otherChecked = otherValue !== void 0;
60
- const onComplete = () => onEvent({
61
- message: answers.map(
62
- (value2, index) => `Q: ${questions[index].question}
70
+ const onComplete = () => {
71
+ const answeredCount = answers.filter(
72
+ (answer) => Array.isArray(answer) && answer.length > 0
73
+ ).length;
74
+ onTrack?.("Ask User Question Submitted", {
75
+ answeredCount: String(answeredCount),
76
+ skippedCount: String(questions.length - answeredCount),
77
+ totalQuestions: String(questions.length)
78
+ });
79
+ return onEvent({
80
+ message: answers.map(
81
+ (value2, index) => `Q: ${questions[index].question}
63
82
  A: ${value2 || "[Not specified]"}`
64
- ).join("\n\n")
65
- });
83
+ ).join("\n\n")
84
+ });
85
+ };
66
86
  const onValueChange = (value2) => {
67
87
  answers[currentIndex] = value2;
68
88
  setAnswers([...answers]);
69
89
  };
70
90
  const onSkip = () => {
91
+ onTrack?.("Ask User Question Skipped", {
92
+ questionIndex: String(currentIndex)
93
+ });
71
94
  answers[currentIndex] = null;
72
95
  setAnswers([...answers]);
73
96
  if (isLast) {
@@ -77,6 +100,15 @@ A: ${value2 || "[Not specified]"}`
77
100
  }
78
101
  };
79
102
  const onSubmit = () => {
103
+ const currentValue = answers[currentIndex];
104
+ if (currentValue) {
105
+ const firstIndex = options.indexOf(currentValue[0]);
106
+ onTrack?.("Ask User Question Option Selected", {
107
+ isCustomText: String(currentValue.some((v) => !options.includes(v))),
108
+ optionIndex: String(firstIndex),
109
+ questionIndex: String(currentIndex)
110
+ });
111
+ }
80
112
  if (isLast) {
81
113
  void onComplete();
82
114
  } else {
@@ -98,7 +130,7 @@ A: ${value2 || "[Not specified]"}`
98
130
  if ((event.key === "ArrowLeft" || event.key === "ArrowRight") && !(event.target instanceof HTMLInputElement) && !event.target.isContentEditable) {
99
131
  event.preventDefault();
100
132
  if (event.key === "ArrowLeft" && currentIndex > 0) {
101
- setCurrentIndex((i) => i - 1);
133
+ goBack();
102
134
  } else if (event.key === "ArrowRight" && !isLast) {
103
135
  setCurrentIndex((i) => i + 1);
104
136
  }
@@ -121,7 +153,7 @@ A: ${value2 || "[Not specified]"}`
121
153
  icon: /* @__PURE__ */ jsx(IconAngleLeft, {}),
122
154
  onClick: (event) => {
123
155
  event.preventDefault();
124
- setCurrentIndex((i) => i - 1);
156
+ goBack();
125
157
  },
126
158
  size: "sm"
127
159
  }