@optiaxiom/proteus 0.0.0 → 0.1.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 (46) hide show
  1. package/LICENSE +201 -0
  2. package/dist/esm/assets/src/proteus-chart/ProteusChart.css.ts.vanilla-DWDlfc5R.css +9 -0
  3. package/dist/esm/assets/src/proteus-chart/ProteusChartTooltipContent.css.ts.vanilla-WrO00wrg.css +9 -0
  4. package/dist/esm/assets/src/proteus-question/ProteusQuestionItem.css.ts.vanilla-S1I3NGY4.css +32 -0
  5. package/dist/esm/hooks/useEffectEvent.js +14 -0
  6. package/dist/esm/icons/IconAngleLeft.js +21 -0
  7. package/dist/esm/icons/IconAngleRight.js +21 -0
  8. package/dist/esm/icons/IconCalendar.js +20 -0
  9. package/dist/esm/icons/IconPencil.js +20 -0
  10. package/dist/esm/icons/withIcon.js +31 -0
  11. package/dist/esm/index.js +14 -0
  12. package/dist/esm/proteus-action/ProteusAction.js +41 -0
  13. package/dist/esm/proteus-action/ProteusCancelAction.js +41 -0
  14. package/dist/esm/proteus-chart/ProteusChart-css.js +6 -0
  15. package/dist/esm/proteus-chart/ProteusChart.js +71 -0
  16. package/dist/esm/proteus-chart/ProteusChartTooltipContent-css.js +7 -0
  17. package/dist/esm/proteus-chart/ProteusChartTooltipContent.js +45 -0
  18. package/dist/esm/proteus-data-table/ProteusDataTable.js +34 -0
  19. package/dist/esm/proteus-document/ProteusDocumentContext.js +6 -0
  20. package/dist/esm/proteus-document/ProteusDocumentPathContext.js +8 -0
  21. package/dist/esm/proteus-document/ProteusDocumentRenderer.js +39 -0
  22. package/dist/esm/proteus-document/ProteusDocumentShell.js +128 -0
  23. package/dist/esm/proteus-document/getProteusValue.js +49 -0
  24. package/dist/esm/proteus-document/resolveProteusProp.js +39 -0
  25. package/dist/esm/proteus-document/resolveProteusValue.js +18 -0
  26. package/dist/esm/proteus-document/schemas.js +48 -0
  27. package/dist/esm/proteus-document/useProteusValue.js +15 -0
  28. package/dist/esm/proteus-document/useResolvedProteusProps.js +19 -0
  29. package/dist/esm/proteus-element/ProteusElement.js +153 -0
  30. package/dist/esm/proteus-image/ProteusImage.js +91 -0
  31. package/dist/esm/proteus-image/downloadFile.js +12 -0
  32. package/dist/esm/proteus-input/ProteusInput.js +32 -0
  33. package/dist/esm/proteus-map/ProteusMap.js +35 -0
  34. package/dist/esm/proteus-question/ProteusQuestion.js +137 -0
  35. package/dist/esm/proteus-question/ProteusQuestionItem-css.js +9 -0
  36. package/dist/esm/proteus-question/ProteusQuestionItem.js +119 -0
  37. package/dist/esm/proteus-select/ProteusSelect.js +44 -0
  38. package/dist/esm/proteus-show/ProteusShow.js +70 -0
  39. package/dist/esm/proteus-textarea/ProteusTextarea.js +32 -0
  40. package/dist/esm/proteus-value/ProteusValue.js +9 -0
  41. package/dist/esm/schema/public-schema.json.js +7904 -0
  42. package/dist/esm/schema/runtime-schema.json.js +7851 -0
  43. package/dist/esm/spec.js +1 -0
  44. package/dist/index.d.ts +293 -0
  45. package/dist/spec.d.ts +8626 -0
  46. package/package.json +41 -3
@@ -0,0 +1,35 @@
1
+ "use client";
2
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
3
+ import { useProteusDocumentContext } from '../proteus-document/ProteusDocumentContext.js';
4
+ import { useProteusDocumentPathContext, ProteusDocumentPathProvider } from '../proteus-document/ProteusDocumentPathContext.js';
5
+ import { useProteusValue } from '../proteus-document/useProteusValue.js';
6
+
7
+ function ProteusMap({ children, path, separator }) {
8
+ const { strict } = useProteusDocumentContext("@optiaxiom/proteus/ProteusMap");
9
+ const { path: parentPath } = useProteusDocumentPathContext(
10
+ "@optiaxiom/proteus/ProteusMap"
11
+ );
12
+ const array = useProteusValue({ path });
13
+ if (!Array.isArray(array)) {
14
+ if (strict) {
15
+ throw new Error(
16
+ `Expected value at "${path}" to be an array got "${typeof array}" instead`
17
+ );
18
+ }
19
+ return null;
20
+ }
21
+ return /* @__PURE__ */ jsx(Fragment, { children: array.map((_, index) => /* @__PURE__ */ jsxs(
22
+ ProteusDocumentPathProvider,
23
+ {
24
+ path: `${path.startsWith("/") ? path : `${parentPath}/${path}`}/${index}`,
25
+ children: [
26
+ index > 0 && separator,
27
+ children
28
+ ]
29
+ },
30
+ index
31
+ )) });
32
+ }
33
+ ProteusMap.displayName = "@optiaxiom/proteus/ProteusMap";
34
+
35
+ export { ProteusMap };
@@ -0,0 +1,137 @@
1
+ "use client";
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { Group, Button, Text } from '@optiaxiom/react';
4
+ import { useState, useRef, useEffect } from 'react';
5
+ import { IconAngleLeft } from '../icons/IconAngleLeft.js';
6
+ import { IconAngleRight } from '../icons/IconAngleRight.js';
7
+ import { useProteusDocumentContext } from '../proteus-document/ProteusDocumentContext.js';
8
+ import { ProteusQuestionItem } from './ProteusQuestionItem.js';
9
+
10
+ function ProteusQuestion({ questions }) {
11
+ const { onEvent } = useProteusDocumentContext(
12
+ "@optiaxiom/proteus/ProteusQuestion"
13
+ );
14
+ const [answers, setAnswers] = useState([]);
15
+ const [currentIndex, setCurrentIndex] = useState(0);
16
+ const answer = answers[currentIndex];
17
+ const valid = Array.isArray(answer) && answer.length > 0 && answer.every(Boolean);
18
+ const questionRef = useRef(null);
19
+ const lastIndexRef = useRef(currentIndex);
20
+ useEffect(() => {
21
+ if (lastIndexRef.current !== currentIndex) {
22
+ questionRef.current?.animate(
23
+ [
24
+ {
25
+ opacity: 0,
26
+ translate: currentIndex > lastIndexRef.current ? "8px" : "-8px"
27
+ },
28
+ {
29
+ opacity: 1,
30
+ translate: "0px"
31
+ }
32
+ ],
33
+ {
34
+ duration: 150
35
+ }
36
+ );
37
+ lastIndexRef.current = currentIndex;
38
+ }
39
+ }, [currentIndex]);
40
+ if (currentIndex >= questions.length) {
41
+ return null;
42
+ }
43
+ const current = questions[currentIndex];
44
+ const isLast = currentIndex === questions.length - 1;
45
+ const onComplete = () => onEvent({
46
+ message: answers.map(
47
+ (value, index) => `Q: ${questions[index].question}
48
+ A: ${value === null ? "[Not specified]" : value}`
49
+ ).join("\n\n")
50
+ });
51
+ return /* @__PURE__ */ jsxs(Group, { flexDirection: "column", gap: "16", children: [
52
+ /* @__PURE__ */ jsx(
53
+ ProteusQuestionItem,
54
+ {
55
+ addonAfter: questions.length > 1 && /* @__PURE__ */ jsxs(Group, { gap: "6", children: [
56
+ /* @__PURE__ */ jsx(
57
+ Button,
58
+ {
59
+ "aria-label": "Previous",
60
+ disabled: currentIndex === 0,
61
+ icon: /* @__PURE__ */ jsx(IconAngleLeft, {}),
62
+ onClick: (event) => {
63
+ event.preventDefault();
64
+ setCurrentIndex((i) => i - 1);
65
+ },
66
+ size: "sm"
67
+ }
68
+ ),
69
+ /* @__PURE__ */ jsxs(Text, { color: "fg.tertiary", fontSize: "sm", children: [
70
+ currentIndex + 1,
71
+ " of ",
72
+ questions.length
73
+ ] }),
74
+ /* @__PURE__ */ jsx(
75
+ Button,
76
+ {
77
+ "aria-label": "Next",
78
+ disabled: isLast,
79
+ icon: /* @__PURE__ */ jsx(IconAngleRight, {}),
80
+ onClick: (event) => {
81
+ event.preventDefault();
82
+ setCurrentIndex((i) => i + 1);
83
+ },
84
+ size: "sm"
85
+ }
86
+ )
87
+ ] }),
88
+ choiceRef: questionRef,
89
+ onValueChange: (value) => {
90
+ answers[currentIndex] = value;
91
+ setAnswers([...answers]);
92
+ },
93
+ options: current.options,
94
+ question: current.question,
95
+ type: current.type,
96
+ value: answers[currentIndex] ?? null
97
+ }
98
+ ),
99
+ /* @__PURE__ */ jsxs(Group, { gap: "8", justifyContent: "end", children: [
100
+ /* @__PURE__ */ jsx(
101
+ Button,
102
+ {
103
+ onClick: (event) => {
104
+ event.preventDefault();
105
+ answers[currentIndex] = null;
106
+ setAnswers([...answers]);
107
+ if (isLast) {
108
+ void onComplete();
109
+ } else {
110
+ setCurrentIndex((i) => i + 1);
111
+ }
112
+ },
113
+ children: "Skip"
114
+ }
115
+ ),
116
+ /* @__PURE__ */ jsx(
117
+ Button,
118
+ {
119
+ appearance: "primary",
120
+ disabled: !valid,
121
+ onClick: (event) => {
122
+ event.preventDefault();
123
+ if (isLast) {
124
+ void onComplete();
125
+ } else {
126
+ setCurrentIndex((i) => i + 1);
127
+ }
128
+ },
129
+ children: isLast ? "Submit" : "Next"
130
+ }
131
+ )
132
+ ] })
133
+ ] });
134
+ }
135
+ ProteusQuestion.displayName = "@optiaxiom/proteus/ProteusQuestion";
136
+
137
+ export { ProteusQuestion };
@@ -0,0 +1,9 @@
1
+ import './../assets/src/proteus-question/ProteusQuestionItem.css.ts.vanilla-S1I3NGY4.css';
2
+ import { recipe } from '@optiaxiom/react/css-runtime';
3
+
4
+ var addon = recipe({base:[{display:'grid',fontWeight:'500',placeItems:'center',rounded:'lg',size:'md',transition:'colors'},'ProteusQuestionItem__uar8vn3'],variants:{cursor:{pointer:{cursor:'pointer'}}}});
5
+ var choice = recipe({base:[{border:'1',color:'fg.default',flexDirection:'column',fontSize:'md',gap:'8',px:'16',py:'12',rounded:'lg',transition:'colors'},'ProteusQuestionItem__uar8vn2','ProteusQuestionItem__uar8vn0'],variants:{cursor:{text:{cursor:'text'}}}});
6
+ var choiceGroup = recipe({base:{flexDirection:'column',gap:'8'}});
7
+ var input = recipe({base:'ProteusQuestionItem__uar8vn1'});
8
+
9
+ export { addon, choice, choiceGroup, input };
@@ -0,0 +1,119 @@
1
+ "use client";
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { useRef, createElement } from 'react';
4
+ import { Group, Text, Box, Checkbox } from '@optiaxiom/react';
5
+ import { VisuallyHidden, InlineInput } from '@optiaxiom/react/unstable';
6
+ import { IconPencil } from '../icons/IconPencil.js';
7
+ import { choiceGroup, choice, input, addon } from './ProteusQuestionItem-css.js';
8
+
9
+ function ProteusQuestionItem({
10
+ addonAfter,
11
+ choiceRef,
12
+ onValueChange,
13
+ options,
14
+ question,
15
+ type,
16
+ value
17
+ }) {
18
+ const otherInputRef = useRef(null);
19
+ const otherValue = value?.find((v) => !options.includes(v));
20
+ const otherChecked = otherValue !== void 0;
21
+ return /* @__PURE__ */ jsxs(Group, { flexDirection: "column", gap: "16", children: [
22
+ /* @__PURE__ */ jsxs(Group, { children: [
23
+ /* @__PURE__ */ jsx(Text, { flex: "1", fontWeight: "500", children: question }),
24
+ addonAfter
25
+ ] }),
26
+ /* @__PURE__ */ jsxs(Group, { ref: choiceRef, ...choiceGroup(), children: [
27
+ options.map((option, index) => {
28
+ const checked = type === "single_select" ? value?.[0] === option : value?.includes(option);
29
+ const disabled = type === "single_select" && otherChecked && !!otherValue;
30
+ return /* @__PURE__ */ createElement(Box, { asChild: true, ...choice(), key: option }, /* @__PURE__ */ jsxs("label", { children: [
31
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: /* @__PURE__ */ jsx(Box, { asChild: true, ...input(), children: /* @__PURE__ */ jsx(
32
+ "input",
33
+ {
34
+ checked,
35
+ disabled,
36
+ name: type === "single_select" ? "question-item" : void 0,
37
+ onChange: () => {
38
+ if (type === "single_select") {
39
+ onValueChange([option]);
40
+ } else {
41
+ const current = value ?? [];
42
+ onValueChange(
43
+ checked ? current.filter((v) => v !== option) : [...current, option]
44
+ );
45
+ }
46
+ },
47
+ type: type === "single_select" ? "radio" : "checkbox",
48
+ value: option
49
+ }
50
+ ) }) }),
51
+ /* @__PURE__ */ jsxs(Group, { gap: "12", children: [
52
+ /* @__PURE__ */ jsx(Box, { ...addon(), children: type === "single_select" ? index + 1 : /* @__PURE__ */ jsx(
53
+ Checkbox,
54
+ {
55
+ checked,
56
+ hidden: true,
57
+ pointerEvents: "none",
58
+ tabIndex: -1
59
+ }
60
+ ) }),
61
+ /* @__PURE__ */ jsx(Group, { flex: "1", flexDirection: "column", gap: "2", children: /* @__PURE__ */ jsx(Text, { children: option }) })
62
+ ] })
63
+ ] }));
64
+ }),
65
+ /* @__PURE__ */ createElement(Box, { asChild: true, ...choice({ cursor: "text" }), key: "other" }, /* @__PURE__ */ jsxs("label", { children: [
66
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: /* @__PURE__ */ jsx(Box, { asChild: true, ...input(), children: /* @__PURE__ */ jsx(
67
+ "input",
68
+ {
69
+ checked: otherChecked,
70
+ name: type === "single_select" ? "question-item" : void 0,
71
+ onChange: () => {
72
+ if (type === "single_select") {
73
+ if (!otherValue) {
74
+ onValueChange([""]);
75
+ }
76
+ }
77
+ otherInputRef.current?.focus();
78
+ },
79
+ type: "checkbox",
80
+ value: "other"
81
+ }
82
+ ) }) }),
83
+ /* @__PURE__ */ jsxs(Group, { gap: "12", children: [
84
+ /* @__PURE__ */ jsx(Box, { ...addon({ cursor: "pointer" }), children: type === "single_select" ? /* @__PURE__ */ jsx(IconPencil, {}) : /* @__PURE__ */ jsx(
85
+ Checkbox,
86
+ {
87
+ checked: otherChecked,
88
+ hidden: true,
89
+ pointerEvents: "none",
90
+ tabIndex: -1
91
+ }
92
+ ) }),
93
+ /* @__PURE__ */ jsx(Group, { flex: "1", flexDirection: "column", gap: "2", children: /* @__PURE__ */ jsx(
94
+ InlineInput,
95
+ {
96
+ label: "Something else",
97
+ onValueChange: (text) => {
98
+ if (type === "single_select") {
99
+ onValueChange([text]);
100
+ } else {
101
+ const current = value ?? [];
102
+ onValueChange([
103
+ ...current.filter((v) => options.includes(v)),
104
+ ...text ? [text] : []
105
+ ]);
106
+ }
107
+ },
108
+ ref: otherInputRef,
109
+ value: otherValue ?? ""
110
+ }
111
+ ) })
112
+ ] })
113
+ ] }))
114
+ ] })
115
+ ] });
116
+ }
117
+ ProteusQuestionItem.displayName = "@optiaxiom/proteus/ProteusQuestionItem";
118
+
119
+ export { ProteusQuestionItem };
@@ -0,0 +1,44 @@
1
+ "use client";
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { Select } from '@optiaxiom/react';
4
+ import { useRef } from 'react';
5
+ import { useProteusDocumentContext } from '../proteus-document/ProteusDocumentContext.js';
6
+ import { useProteusDocumentPathContext } from '../proteus-document/ProteusDocumentPathContext.js';
7
+ import { useProteusValue } from '../proteus-document/useProteusValue.js';
8
+
9
+ function ProteusSelect({
10
+ children,
11
+ options = [],
12
+ ...props
13
+ }) {
14
+ const { onDataChange, readOnly } = useProteusDocumentContext(
15
+ "@optiaxiom/proteus/ProteusSelect"
16
+ );
17
+ const { path: parentPath } = useProteusDocumentPathContext(
18
+ "@optiaxiom/proteus/ProteusSelect"
19
+ );
20
+ const optionsRef = useRef(options);
21
+ optionsRef.current = options;
22
+ const resolved = useProteusValue({ path: props.name ?? "" });
23
+ const value = props.name ? String(resolved ?? options[0]?.value ?? "") : options[0]?.value ?? "";
24
+ return /* @__PURE__ */ jsx(
25
+ Select,
26
+ {
27
+ ...props,
28
+ onValueChange: (value2) => {
29
+ if (readOnly) {
30
+ return;
31
+ }
32
+ if (props.name) {
33
+ onDataChange?.(`${parentPath}/${props.name}`, value2);
34
+ }
35
+ },
36
+ options,
37
+ value,
38
+ children
39
+ }
40
+ );
41
+ }
42
+ ProteusSelect.displayName = "@optiaxiom/proteus/ProteusSelect";
43
+
44
+ export { ProteusSelect };
@@ -0,0 +1,70 @@
1
+ "use client";
2
+ import { jsx, Fragment } from 'react/jsx-runtime';
3
+ import { useProteusDocumentContext } from '../proteus-document/ProteusDocumentContext.js';
4
+ import { useProteusDocumentPathContext } from '../proteus-document/ProteusDocumentPathContext.js';
5
+ import { resolveProteusValue } from '../proteus-document/resolveProteusValue.js';
6
+
7
+ function ProteusShow({ children, when }) {
8
+ const { data } = useProteusDocumentContext("@optiaxiom/proteus/ProteusShow");
9
+ const { path: parentPath } = useProteusDocumentPathContext(
10
+ "@optiaxiom/proteus/ProteusShow"
11
+ );
12
+ const conditions = Array.isArray(when) ? when : [when];
13
+ const shouldShow = conditions.every(
14
+ (condition) => evaluateCondition(condition, data, parentPath)
15
+ );
16
+ if (!shouldShow) {
17
+ return null;
18
+ }
19
+ return /* @__PURE__ */ jsx(Fragment, { children });
20
+ }
21
+ function evaluateCondition(condition, data, parentPath) {
22
+ if (!condition) {
23
+ return true;
24
+ }
25
+ if ("and" in condition) {
26
+ return condition.and.every(
27
+ (cond) => evaluateCondition(cond, data, parentPath)
28
+ );
29
+ }
30
+ if ("or" in condition) {
31
+ return condition.or.some(
32
+ (cond) => evaluateCondition(cond, data, parentPath)
33
+ );
34
+ }
35
+ if ("!!" in condition) {
36
+ const value = resolveProteusValue(condition["!!"], data, parentPath);
37
+ return !!value;
38
+ }
39
+ if ("==" in condition) {
40
+ const [left, right] = condition["=="];
41
+ return resolveProteusValue(left, data, parentPath) === resolveProteusValue(right, data, parentPath);
42
+ } else if ("!=" in condition) {
43
+ const [left, right] = condition["!="];
44
+ return resolveProteusValue(left, data, parentPath) !== resolveProteusValue(right, data, parentPath);
45
+ } else if ("<" in condition) {
46
+ const [left, right] = condition["<"];
47
+ const leftVal = resolveProteusValue(left, data, parentPath);
48
+ const rightVal = resolveProteusValue(right, data, parentPath);
49
+ return typeof leftVal === "number" && typeof rightVal === "number" && leftVal < rightVal;
50
+ } else if ("<=" in condition) {
51
+ const [left, right] = condition["<="];
52
+ const leftVal = resolveProteusValue(left, data, parentPath);
53
+ const rightVal = resolveProteusValue(right, data, parentPath);
54
+ return typeof leftVal === "number" && typeof rightVal === "number" && leftVal <= rightVal;
55
+ } else if (">" in condition) {
56
+ const [left, right] = condition[">"];
57
+ const leftVal = resolveProteusValue(left, data, parentPath);
58
+ const rightVal = resolveProteusValue(right, data, parentPath);
59
+ return typeof leftVal === "number" && typeof rightVal === "number" && leftVal > rightVal;
60
+ } else if (">=" in condition) {
61
+ const [left, right] = condition[">="];
62
+ const leftVal = resolveProteusValue(left, data, parentPath);
63
+ const rightVal = resolveProteusValue(right, data, parentPath);
64
+ return typeof leftVal === "number" && typeof rightVal === "number" && leftVal >= rightVal;
65
+ }
66
+ return false;
67
+ }
68
+ ProteusShow.displayName = "@optiaxiom/proteus/ProteusShow";
69
+
70
+ export { ProteusShow };
@@ -0,0 +1,32 @@
1
+ "use client";
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { Textarea } from '@optiaxiom/react';
4
+ import { useProteusDocumentContext } from '../proteus-document/ProteusDocumentContext.js';
5
+ import { useProteusDocumentPathContext } from '../proteus-document/ProteusDocumentPathContext.js';
6
+ import { useProteusValue } from '../proteus-document/useProteusValue.js';
7
+
8
+ function ProteusTextarea(props) {
9
+ const { onDataChange, readOnly } = useProteusDocumentContext(
10
+ "@optiaxiom/proteus/ProteusTextarea"
11
+ );
12
+ const { path: parentPath } = useProteusDocumentPathContext(
13
+ "@optiaxiom/proteus/ProteusTextarea"
14
+ );
15
+ const value = useProteusValue({ path: props.name ?? "" });
16
+ return /* @__PURE__ */ jsx(
17
+ Textarea,
18
+ {
19
+ ...props,
20
+ onValueChange: (value2) => {
21
+ if (props.name) {
22
+ onDataChange?.(`${parentPath}/${props.name}`, value2);
23
+ }
24
+ },
25
+ readOnly,
26
+ value: props.name ? String(value ?? "") : void 0
27
+ }
28
+ );
29
+ }
30
+ ProteusTextarea.displayName = "@optiaxiom/proteus/ProteusTextarea";
31
+
32
+ export { ProteusTextarea };
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ import { useProteusValue } from '../proteus-document/useProteusValue.js';
3
+
4
+ function ProteusValue(props) {
5
+ return useProteusValue(props);
6
+ }
7
+ ProteusValue.displayName = "@optiaxiom/proteus/ProteusValue";
8
+
9
+ export { ProteusValue };