@optiaxiom/proteus 0.0.0 → 0.1.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.
- package/LICENSE +201 -0
- package/dist/esm/assets/src/proteus-chart/ProteusChart.css.ts.vanilla-WpbWN23E.css +9 -0
- package/dist/esm/assets/src/proteus-chart/ProteusChartTooltipContent.css.ts.vanilla-sqWemcZm.css +9 -0
- package/dist/esm/assets/src/proteus-question/ProteusQuestionItem.css.ts.vanilla-Dns_NfIP.css +26 -0
- package/dist/esm/hooks/useEffectEvent.js +14 -0
- package/dist/esm/icons/IconAngleLeft.js +21 -0
- package/dist/esm/icons/IconCalendar.js +20 -0
- package/dist/esm/icons/withIcon.js +31 -0
- package/dist/esm/index.js +14 -0
- package/dist/esm/proteus-action/ProteusAction.js +41 -0
- package/dist/esm/proteus-action/ProteusCancelAction.js +41 -0
- package/dist/esm/proteus-chart/ProteusChart-css.js +6 -0
- package/dist/esm/proteus-chart/ProteusChart.js +71 -0
- package/dist/esm/proteus-chart/ProteusChartTooltipContent-css.js +7 -0
- package/dist/esm/proteus-chart/ProteusChartTooltipContent.js +45 -0
- package/dist/esm/proteus-data-table/ProteusDataTable.js +34 -0
- package/dist/esm/proteus-document/ProteusDocumentContext.js +6 -0
- package/dist/esm/proteus-document/ProteusDocumentPathContext.js +8 -0
- package/dist/esm/proteus-document/ProteusDocumentRenderer.js +39 -0
- package/dist/esm/proteus-document/ProteusDocumentShell.js +128 -0
- package/dist/esm/proteus-document/getProteusValue.js +49 -0
- package/dist/esm/proteus-document/resolveProteusProp.js +39 -0
- package/dist/esm/proteus-document/resolveProteusValue.js +18 -0
- package/dist/esm/proteus-document/schemas.js +48 -0
- package/dist/esm/proteus-document/useProteusValue.js +15 -0
- package/dist/esm/proteus-document/useResolvedProteusProps.js +19 -0
- package/dist/esm/proteus-element/ProteusElement.js +153 -0
- package/dist/esm/proteus-image/ProteusImage.js +91 -0
- package/dist/esm/proteus-image/downloadFile.js +12 -0
- package/dist/esm/proteus-input/ProteusInput.js +32 -0
- package/dist/esm/proteus-map/ProteusMap.js +35 -0
- package/dist/esm/proteus-question/ProteusQuestion.js +96 -0
- package/dist/esm/proteus-question/ProteusQuestionItem-css.js +9 -0
- package/dist/esm/proteus-question/ProteusQuestionItem.js +57 -0
- package/dist/esm/proteus-select/ProteusSelect.js +44 -0
- package/dist/esm/proteus-show/ProteusShow.js +70 -0
- package/dist/esm/proteus-textarea/ProteusTextarea.js +32 -0
- package/dist/esm/proteus-value/ProteusValue.js +9 -0
- package/dist/esm/schema/public-schema.json.js +7904 -0
- package/dist/esm/schema/runtime-schema.json.js +7851 -0
- package/dist/esm/spec.js +1 -0
- package/dist/index.d.ts +293 -0
- package/dist/spec.d.ts +8626 -0
- package/package.json +41 -3
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
import { Disclosure, DisclosureTrigger, Box, Group, Text, DisclosureContent, Heading } from '@optiaxiom/react';
|
|
4
|
+
import { useControllableState } from '@radix-ui/react-use-controllable-state';
|
|
5
|
+
import { set } from 'jsonpointer';
|
|
6
|
+
import { useState, useRef, useEffect } from 'react';
|
|
7
|
+
import { useEffectEvent } from '../hooks/useEffectEvent.js';
|
|
8
|
+
import { downloadFile } from '../proteus-image/downloadFile.js';
|
|
9
|
+
import { ProteusDocumentProvider } from './ProteusDocumentContext.js';
|
|
10
|
+
|
|
11
|
+
function ProteusDocumentShell({
|
|
12
|
+
collapsible: collapsibleProp,
|
|
13
|
+
data = {},
|
|
14
|
+
defaultOpen = true,
|
|
15
|
+
element,
|
|
16
|
+
onDataChange,
|
|
17
|
+
onMessage,
|
|
18
|
+
onOpenChange,
|
|
19
|
+
onToolCall,
|
|
20
|
+
open: openProp,
|
|
21
|
+
readOnly = false,
|
|
22
|
+
strict
|
|
23
|
+
}) {
|
|
24
|
+
const [valid, setValid] = useState(false);
|
|
25
|
+
const formRef = useRef(null);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (formRef.current) {
|
|
28
|
+
setValid(formRef.current.checkValidity());
|
|
29
|
+
}
|
|
30
|
+
}, []);
|
|
31
|
+
const [open, setOpen] = useControllableState({
|
|
32
|
+
defaultProp: defaultOpen,
|
|
33
|
+
onChange: onOpenChange,
|
|
34
|
+
prop: openProp
|
|
35
|
+
});
|
|
36
|
+
const collapsible = collapsibleProp && element.appName;
|
|
37
|
+
const Trigger = collapsible ? DisclosureTrigger : Box;
|
|
38
|
+
return /* @__PURE__ */ jsx(
|
|
39
|
+
ProteusDocumentProvider,
|
|
40
|
+
{
|
|
41
|
+
data,
|
|
42
|
+
onDataChange: useEffectEvent((path, value) => {
|
|
43
|
+
const next = structuredClone(data);
|
|
44
|
+
set(next, path, value);
|
|
45
|
+
onDataChange?.(next);
|
|
46
|
+
}),
|
|
47
|
+
onEvent: useEffectEvent(async (event) => {
|
|
48
|
+
if ("tool" in event) {
|
|
49
|
+
await onToolCall?.(event.tool);
|
|
50
|
+
} else if ("message" in event) {
|
|
51
|
+
await onMessage?.(event.message);
|
|
52
|
+
} else if (event.action === "download") {
|
|
53
|
+
if (typeof event.url === "string") {
|
|
54
|
+
await downloadFile(event.url);
|
|
55
|
+
} else {
|
|
56
|
+
throw new Error("Invalid URL for download action");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}),
|
|
60
|
+
readOnly,
|
|
61
|
+
strict,
|
|
62
|
+
valid,
|
|
63
|
+
children: /* @__PURE__ */ jsxs(
|
|
64
|
+
Disclosure,
|
|
65
|
+
{
|
|
66
|
+
bg: "bg.default",
|
|
67
|
+
border: "1",
|
|
68
|
+
borderColor: "border.tertiary",
|
|
69
|
+
onOpenChange: setOpen,
|
|
70
|
+
open,
|
|
71
|
+
p: "16",
|
|
72
|
+
rounded: "xl",
|
|
73
|
+
children: [
|
|
74
|
+
element.appName && /* @__PURE__ */ jsx(Trigger, { py: "0", ...collapsible ? { chevronPosition: "end" } : {}, children: /* @__PURE__ */ jsxs(Group, { fontSize: "sm", gap: "8", children: [
|
|
75
|
+
/* @__PURE__ */ jsx(
|
|
76
|
+
Box,
|
|
77
|
+
{
|
|
78
|
+
asChild: true,
|
|
79
|
+
bg: element.appIcon ? void 0 : "bg.accent.subtle",
|
|
80
|
+
flex: "none",
|
|
81
|
+
rounded: "xs",
|
|
82
|
+
size: "20",
|
|
83
|
+
children: element.appIcon ? /* @__PURE__ */ jsx("img", { alt: "", src: element.appIcon }) : /* @__PURE__ */ jsx("div", {})
|
|
84
|
+
}
|
|
85
|
+
),
|
|
86
|
+
/* @__PURE__ */ jsx(Text, { fontWeight: "500", children: element.appName }),
|
|
87
|
+
!open && /* @__PURE__ */ jsx(Text, { color: "fg.secondary", lineClamp: "1", children: element.title })
|
|
88
|
+
] }) }),
|
|
89
|
+
/* @__PURE__ */ jsxs(
|
|
90
|
+
DisclosureContent,
|
|
91
|
+
{
|
|
92
|
+
alignItems: "stretch",
|
|
93
|
+
display: "flex",
|
|
94
|
+
flexDirection: "column",
|
|
95
|
+
gap: "16",
|
|
96
|
+
pb: "0",
|
|
97
|
+
pt: element.appName ? "16" : "0",
|
|
98
|
+
children: [
|
|
99
|
+
/* @__PURE__ */ jsxs(Group, { flexDirection: "column", gap: "4", children: [
|
|
100
|
+
/* @__PURE__ */ jsx(Heading, { fontSize: "lg", fontWeight: "600", level: "2", lineClamp: "2", children: element.title }),
|
|
101
|
+
!!element.subtitle && /* @__PURE__ */ jsx(Text, { color: "fg.secondary", fontSize: "sm", children: element.subtitle })
|
|
102
|
+
] }),
|
|
103
|
+
/* @__PURE__ */ jsx(Group, { asChild: true, flexDirection: "column", gap: "16", children: /* @__PURE__ */ jsx(
|
|
104
|
+
"form",
|
|
105
|
+
{
|
|
106
|
+
onChange: (event) => {
|
|
107
|
+
const form = event.currentTarget;
|
|
108
|
+
setTimeout(() => {
|
|
109
|
+
setValid(form.checkValidity());
|
|
110
|
+
});
|
|
111
|
+
},
|
|
112
|
+
ref: formRef,
|
|
113
|
+
children: element.body
|
|
114
|
+
}
|
|
115
|
+
) }),
|
|
116
|
+
element.actions && !readOnly && /* @__PURE__ */ jsx(Group, { gap: "16", justifyContent: "end", w: "full", children: element.actions })
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
)
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
ProteusDocumentShell.displayName = "@optiaxiom/proteus/ProteusDocumentShell";
|
|
127
|
+
|
|
128
|
+
export { ProteusDocumentShell };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { get } from 'jsonpointer';
|
|
2
|
+
|
|
3
|
+
function getProteusValue(data, element, parentPath) {
|
|
4
|
+
try {
|
|
5
|
+
const value = get(
|
|
6
|
+
data,
|
|
7
|
+
element.path.startsWith("/") ? element.path : element.path ? `${parentPath}/${element.path}` : parentPath
|
|
8
|
+
);
|
|
9
|
+
if (element.formatter) {
|
|
10
|
+
return applyFormatter(value, element.formatter);
|
|
11
|
+
}
|
|
12
|
+
return value;
|
|
13
|
+
} catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const formatters = {
|
|
18
|
+
DateTime: (value, options) => {
|
|
19
|
+
if (typeof value === "number" || typeof value === "string") {
|
|
20
|
+
return new Intl.DateTimeFormat(void 0, {
|
|
21
|
+
day: "numeric",
|
|
22
|
+
month: "short",
|
|
23
|
+
...options
|
|
24
|
+
}).format(new Date(value));
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
},
|
|
28
|
+
Number: (value, options) => {
|
|
29
|
+
const num = typeof value === "number" ? value : typeof value === "string" && value !== "" ? Number(value) : NaN;
|
|
30
|
+
if (!Number.isNaN(num)) {
|
|
31
|
+
return new Intl.NumberFormat(void 0, options).format(num);
|
|
32
|
+
}
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
function applyFormatter(value, formatter) {
|
|
37
|
+
const key = typeof formatter === "string" ? formatter : formatter.type;
|
|
38
|
+
const fn = formatters[key];
|
|
39
|
+
if (!fn) {
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
const options = typeof formatter === "string" ? void 0 : formatter.options;
|
|
43
|
+
if (Array.isArray(value)) {
|
|
44
|
+
return value.map((v) => fn(v, options));
|
|
45
|
+
}
|
|
46
|
+
return fn(value, options);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export { applyFormatter, getProteusValue };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { ProteusElement } from '../proteus-element/ProteusElement.js';
|
|
4
|
+
import { getProteusValue } from './getProteusValue.js';
|
|
5
|
+
|
|
6
|
+
function resolveProteusProp(value, data, parentPath) {
|
|
7
|
+
if (typeof value !== "object" || value === null) {
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
if ("$type" in value && value.$type === "Value" && "path" in value && typeof value.path === "string") {
|
|
11
|
+
return getProteusValue(
|
|
12
|
+
data,
|
|
13
|
+
value,
|
|
14
|
+
parentPath
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
if ("$type" in value && value.$type === "Zip" && "sources" in value) {
|
|
18
|
+
const sources = value.sources;
|
|
19
|
+
const resolved = {};
|
|
20
|
+
let length = 0;
|
|
21
|
+
for (const [k, v] of Object.entries(sources)) {
|
|
22
|
+
const arr = resolveProteusProp(v, data, parentPath);
|
|
23
|
+
if (Array.isArray(arr)) {
|
|
24
|
+
resolved[k] = arr;
|
|
25
|
+
length = Math.max(length, arr.length);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return Array.from({ length }, (_, i) => {
|
|
29
|
+
const row = {};
|
|
30
|
+
for (const [k, arr] of Object.entries(resolved)) {
|
|
31
|
+
row[k] = arr[i];
|
|
32
|
+
}
|
|
33
|
+
return row;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return "$type" in value || Array.isArray(value) && value.some((v) => v && typeof v === "object" && "$type" in v) ? /* @__PURE__ */ jsx(ProteusElement, { element: value }) : value;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { resolveProteusProp };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { getProteusValue } from './getProteusValue.js';
|
|
3
|
+
|
|
4
|
+
function resolveProteusValue(value, data, parentPath) {
|
|
5
|
+
if (typeof value !== "object" || value === null) {
|
|
6
|
+
return value;
|
|
7
|
+
}
|
|
8
|
+
if ("$type" in value && value.$type === "Value" && "path" in value && typeof value.path === "string") {
|
|
9
|
+
return getProteusValue(
|
|
10
|
+
data,
|
|
11
|
+
value,
|
|
12
|
+
parentPath
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { resolveProteusValue };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Validator } from '@cfworker/json-schema';
|
|
2
|
+
import proteusDocumentSpec from '../schema/runtime-schema.json.js';
|
|
3
|
+
|
|
4
|
+
const documentValidator = new Validator(
|
|
5
|
+
{
|
|
6
|
+
$ref: "#/definitions/ProteusDocument",
|
|
7
|
+
definitions: proteusDocumentSpec.definitions
|
|
8
|
+
},
|
|
9
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
10
|
+
"7"
|
|
11
|
+
);
|
|
12
|
+
const elementValidator = new Validator(
|
|
13
|
+
{
|
|
14
|
+
$ref: "#/definitions/ProteusNode",
|
|
15
|
+
definitions: proteusDocumentSpec.definitions
|
|
16
|
+
},
|
|
17
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
18
|
+
"7"
|
|
19
|
+
);
|
|
20
|
+
function safeParseDocument({
|
|
21
|
+
actions,
|
|
22
|
+
body,
|
|
23
|
+
...data
|
|
24
|
+
}) {
|
|
25
|
+
const result = documentValidator.validate({ body: [], ...data });
|
|
26
|
+
if (result.valid) {
|
|
27
|
+
return {
|
|
28
|
+
data: { actions, body, ...data },
|
|
29
|
+
success: true
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return { error: result.errors.map(({ error }) => error), success: false };
|
|
33
|
+
}
|
|
34
|
+
function safeParseElement({
|
|
35
|
+
children,
|
|
36
|
+
...data
|
|
37
|
+
}) {
|
|
38
|
+
const result = elementValidator.validate(data);
|
|
39
|
+
if (result.valid) {
|
|
40
|
+
return {
|
|
41
|
+
data: { children, ...data },
|
|
42
|
+
success: true
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return { error: result.errors.map(({ error }) => error), success: false };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { safeParseDocument, safeParseElement };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getProteusValue } from './getProteusValue.js';
|
|
2
|
+
import { useProteusDocumentContext } from './ProteusDocumentContext.js';
|
|
3
|
+
import { useProteusDocumentPathContext } from './ProteusDocumentPathContext.js';
|
|
4
|
+
|
|
5
|
+
function useProteusValue(element) {
|
|
6
|
+
const { data } = useProteusDocumentContext(
|
|
7
|
+
"@optiaxiom/proteus/useProteusValue"
|
|
8
|
+
);
|
|
9
|
+
const { path: parentPath } = useProteusDocumentPathContext(
|
|
10
|
+
"@optiaxiom/proteus/useProteusValue"
|
|
11
|
+
);
|
|
12
|
+
return getProteusValue(data, element, parentPath);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { useProteusValue };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useProteusDocumentContext } from './ProteusDocumentContext.js';
|
|
2
|
+
import { useProteusDocumentPathContext } from './ProteusDocumentPathContext.js';
|
|
3
|
+
import { resolveProteusValue } from './resolveProteusValue.js';
|
|
4
|
+
|
|
5
|
+
function useResolvedProteusProps(props) {
|
|
6
|
+
const { data } = useProteusDocumentContext(
|
|
7
|
+
"@optiaxiom/react/useResolvedProteusProps"
|
|
8
|
+
);
|
|
9
|
+
const { path: parentPath } = useProteusDocumentPathContext(
|
|
10
|
+
"@optiaxiom/react/useResolvedProteusProps"
|
|
11
|
+
);
|
|
12
|
+
const resolved = {};
|
|
13
|
+
for (const [key, value] of Object.entries(props)) {
|
|
14
|
+
resolved[key] = resolveProteusValue(value, data, parentPath);
|
|
15
|
+
}
|
|
16
|
+
return resolved;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { useResolvedProteusProps };
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import { Text, Separator, SelectTrigger, SelectContent, Link, Box, Heading, Group, Field, CardLink, CardHeader, Card, Badge, Avatar } from '@optiaxiom/react';
|
|
4
|
+
import { Time, Range } from '@optiaxiom/react/unstable';
|
|
5
|
+
import { lazy, Suspense } from 'react';
|
|
6
|
+
import { IconCalendar } from '../icons/IconCalendar.js';
|
|
7
|
+
import { ProteusAction } from '../proteus-action/ProteusAction.js';
|
|
8
|
+
import { ProteusCancelAction } from '../proteus-action/ProteusCancelAction.js';
|
|
9
|
+
import { ProteusDataTable } from '../proteus-data-table/ProteusDataTable.js';
|
|
10
|
+
import { useProteusDocumentContext } from '../proteus-document/ProteusDocumentContext.js';
|
|
11
|
+
import { useProteusDocumentPathContext } from '../proteus-document/ProteusDocumentPathContext.js';
|
|
12
|
+
import { resolveProteusProp } from '../proteus-document/resolveProteusProp.js';
|
|
13
|
+
import { safeParseElement } from '../proteus-document/schemas.js';
|
|
14
|
+
import { ProteusImage } from '../proteus-image/ProteusImage.js';
|
|
15
|
+
import { ProteusInput } from '../proteus-input/ProteusInput.js';
|
|
16
|
+
import { ProteusMap } from '../proteus-map/ProteusMap.js';
|
|
17
|
+
import { ProteusQuestion } from '../proteus-question/ProteusQuestion.js';
|
|
18
|
+
import { ProteusSelect } from '../proteus-select/ProteusSelect.js';
|
|
19
|
+
import { ProteusShow } from '../proteus-show/ProteusShow.js';
|
|
20
|
+
import { ProteusTextarea } from '../proteus-textarea/ProteusTextarea.js';
|
|
21
|
+
import { ProteusValue } from '../proteus-value/ProteusValue.js';
|
|
22
|
+
|
|
23
|
+
const ProteusChart = lazy(async () => {
|
|
24
|
+
return {
|
|
25
|
+
default: (await import('../proteus-chart/ProteusChart.js')).ProteusChart
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
const ProteusElement = ({
|
|
29
|
+
element: elementProp
|
|
30
|
+
}) => {
|
|
31
|
+
const { data, strict } = useProteusDocumentContext(
|
|
32
|
+
"@optiaxiom/proteus/ProteusElement"
|
|
33
|
+
);
|
|
34
|
+
const { path: parentPath } = useProteusDocumentPathContext(
|
|
35
|
+
"@optiaxiom/proteus/ProteusElement"
|
|
36
|
+
);
|
|
37
|
+
if (!elementProp) {
|
|
38
|
+
return null;
|
|
39
|
+
} else if (typeof elementProp === "string" || typeof elementProp === "number") {
|
|
40
|
+
return elementProp;
|
|
41
|
+
} else if (Array.isArray(elementProp)) {
|
|
42
|
+
return /* @__PURE__ */ jsx(Fragment, { children: elementProp.map((element2, index) => /* @__PURE__ */ jsx(ProteusElement, { element: element2 }, index)) });
|
|
43
|
+
}
|
|
44
|
+
const result = safeParseElement(elementProp);
|
|
45
|
+
if (!result.success) {
|
|
46
|
+
if (strict) {
|
|
47
|
+
throw new Error(`Invalid element: ${result.error.join("\n")}`);
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const element = result.data;
|
|
52
|
+
const resolve = (obj) => {
|
|
53
|
+
const { $type: _$type, ...rest } = obj;
|
|
54
|
+
const resolved = {};
|
|
55
|
+
for (const [key, value] of Object.entries(rest)) {
|
|
56
|
+
resolved[key] = resolveProteusProp(value, data, parentPath);
|
|
57
|
+
}
|
|
58
|
+
return resolved;
|
|
59
|
+
};
|
|
60
|
+
switch (element.$type) {
|
|
61
|
+
case "Action":
|
|
62
|
+
return /* @__PURE__ */ jsx(ProteusAction, { ...resolve(element) });
|
|
63
|
+
case "Avatar":
|
|
64
|
+
return /* @__PURE__ */ jsx(Avatar, { ...resolve(element) });
|
|
65
|
+
case "Badge":
|
|
66
|
+
return /* @__PURE__ */ jsx(Badge, { ...resolve(element) });
|
|
67
|
+
case "CancelAction":
|
|
68
|
+
return /* @__PURE__ */ jsx(ProteusCancelAction, { ...resolve(element) });
|
|
69
|
+
case "Card":
|
|
70
|
+
return /* @__PURE__ */ jsx(Card, { ...resolve(element) });
|
|
71
|
+
case "CardHeader":
|
|
72
|
+
return /* @__PURE__ */ jsx(CardHeader, { ...resolve(element) });
|
|
73
|
+
case "CardLink":
|
|
74
|
+
return /* @__PURE__ */ jsx(CardLink, { ...resolve(element) });
|
|
75
|
+
case "Chart":
|
|
76
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
|
|
77
|
+
ProteusChart,
|
|
78
|
+
{
|
|
79
|
+
...resolve(element)
|
|
80
|
+
}
|
|
81
|
+
) });
|
|
82
|
+
case "DataTable":
|
|
83
|
+
return /* @__PURE__ */ jsx(
|
|
84
|
+
ProteusDataTable,
|
|
85
|
+
{
|
|
86
|
+
...resolve(element)
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
case "Field":
|
|
90
|
+
return /* @__PURE__ */ jsx(Field, { ...resolve(element) });
|
|
91
|
+
case "Group":
|
|
92
|
+
return /* @__PURE__ */ jsx(Group, { ...resolve(element) });
|
|
93
|
+
case "Heading":
|
|
94
|
+
return /* @__PURE__ */ jsx(Heading, { ...resolve(element) });
|
|
95
|
+
case "IconCalendar":
|
|
96
|
+
return /* @__PURE__ */ jsx(Box, { asChild: true, ...resolve(element), children: /* @__PURE__ */ jsx(IconCalendar, {}) });
|
|
97
|
+
case "Image":
|
|
98
|
+
return /* @__PURE__ */ jsx(ProteusImage, { ...resolve(element) });
|
|
99
|
+
case "Input":
|
|
100
|
+
return /* @__PURE__ */ jsx(ProteusInput, { ...resolve(element) });
|
|
101
|
+
case "Link":
|
|
102
|
+
return /* @__PURE__ */ jsx(Link, { ...resolve(element) });
|
|
103
|
+
case "Map":
|
|
104
|
+
return /* @__PURE__ */ jsx(
|
|
105
|
+
ProteusMap,
|
|
106
|
+
{
|
|
107
|
+
...resolve(element)
|
|
108
|
+
}
|
|
109
|
+
);
|
|
110
|
+
case "Question":
|
|
111
|
+
return /* @__PURE__ */ jsx(ProteusQuestion, { ...resolve(element) });
|
|
112
|
+
case "Range":
|
|
113
|
+
return /* @__PURE__ */ jsx(Range, { ...resolve(element) });
|
|
114
|
+
case "Select":
|
|
115
|
+
return /* @__PURE__ */ jsx(ProteusSelect, { ...resolve(element) });
|
|
116
|
+
case "SelectContent":
|
|
117
|
+
return /* @__PURE__ */ jsx(SelectContent, { ...resolve(element) });
|
|
118
|
+
case "SelectTrigger":
|
|
119
|
+
return /* @__PURE__ */ jsx(SelectTrigger, { ...resolve(element) });
|
|
120
|
+
case "Separator":
|
|
121
|
+
return /* @__PURE__ */ jsx(Separator, { ...resolve(element) });
|
|
122
|
+
case "Show":
|
|
123
|
+
return /* @__PURE__ */ jsx(
|
|
124
|
+
ProteusShow,
|
|
125
|
+
{
|
|
126
|
+
...resolve(element)
|
|
127
|
+
}
|
|
128
|
+
);
|
|
129
|
+
case "Text":
|
|
130
|
+
return /* @__PURE__ */ jsx(Text, { ...resolve(element) });
|
|
131
|
+
case "Textarea":
|
|
132
|
+
return /* @__PURE__ */ jsx(ProteusTextarea, { ...resolve(element) });
|
|
133
|
+
case "Time":
|
|
134
|
+
return /* @__PURE__ */ jsx(
|
|
135
|
+
Time,
|
|
136
|
+
{
|
|
137
|
+
...resolve(element)
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
case "Value":
|
|
141
|
+
return /* @__PURE__ */ jsx(
|
|
142
|
+
ProteusValue,
|
|
143
|
+
{
|
|
144
|
+
...element
|
|
145
|
+
}
|
|
146
|
+
);
|
|
147
|
+
default:
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
ProteusElement.displayName = "@optiaxiom/proteus/ProteusElement";
|
|
152
|
+
|
|
153
|
+
export { ProteusElement };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { Box, Spinner, Dialog, DialogTrigger, DialogContent, DialogHeader, DialogBody, DialogFooter, DialogClose, Button } from '@optiaxiom/react';
|
|
4
|
+
import { useState, useRef } from 'react';
|
|
5
|
+
import { downloadFile } from './downloadFile.js';
|
|
6
|
+
|
|
7
|
+
function ProteusImage(props) {
|
|
8
|
+
const [open, setOpen] = useState(false);
|
|
9
|
+
const [isDownloading, setIsDownloading] = useState(false);
|
|
10
|
+
const [isLoaded, setIsLoaded] = useState(false);
|
|
11
|
+
const imgRef = useRef(null);
|
|
12
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13
|
+
!isLoaded && /* @__PURE__ */ jsx(
|
|
14
|
+
Box,
|
|
15
|
+
{
|
|
16
|
+
alignItems: "center",
|
|
17
|
+
bg: "bg.tertiary",
|
|
18
|
+
display: "flex",
|
|
19
|
+
justifyContent: "center",
|
|
20
|
+
p: "24",
|
|
21
|
+
rounded: "md",
|
|
22
|
+
style: { aspectRatio: "16 / 9" },
|
|
23
|
+
w: "full",
|
|
24
|
+
...props,
|
|
25
|
+
children: /* @__PURE__ */ jsx(Spinner, {})
|
|
26
|
+
}
|
|
27
|
+
),
|
|
28
|
+
/* @__PURE__ */ jsxs(Dialog, { onOpenChange: setOpen, open, children: [
|
|
29
|
+
/* @__PURE__ */ jsx(DialogTrigger, { "aria-label": "Expand", asChild: true, children: /* @__PURE__ */ jsx(Box, { asChild: true, display: isLoaded ? "block" : "none", ...props, children: /* @__PURE__ */ jsx(
|
|
30
|
+
"a",
|
|
31
|
+
{
|
|
32
|
+
href: props.src,
|
|
33
|
+
onClick: (event) => {
|
|
34
|
+
event.preventDefault();
|
|
35
|
+
setOpen(true);
|
|
36
|
+
},
|
|
37
|
+
type: "",
|
|
38
|
+
children: /* @__PURE__ */ jsx(
|
|
39
|
+
Box,
|
|
40
|
+
{
|
|
41
|
+
asChild: true,
|
|
42
|
+
objectFit: "cover",
|
|
43
|
+
overflow: "hidden",
|
|
44
|
+
rounded: "inherit",
|
|
45
|
+
children: /* @__PURE__ */ jsx(
|
|
46
|
+
"img",
|
|
47
|
+
{
|
|
48
|
+
alt: props.alt,
|
|
49
|
+
onLoad: () => setIsLoaded(true),
|
|
50
|
+
ref: imgRef,
|
|
51
|
+
src: props.src
|
|
52
|
+
}
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
) }) }),
|
|
58
|
+
/* @__PURE__ */ jsxs(DialogContent, { size: "lg", children: [
|
|
59
|
+
/* @__PURE__ */ jsx(DialogHeader, { lineClamp: "1", children: props.alt }),
|
|
60
|
+
/* @__PURE__ */ jsx(DialogBody, { children: /* @__PURE__ */ jsx(Box, { asChild: true, display: "block", objectFit: "cover", children: /* @__PURE__ */ jsx("img", { alt: props.alt, src: props.src }) }) }),
|
|
61
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
62
|
+
/* @__PURE__ */ jsx(DialogClose, { children: "Close" }),
|
|
63
|
+
/* @__PURE__ */ jsx(
|
|
64
|
+
Button,
|
|
65
|
+
{
|
|
66
|
+
appearance: "primary",
|
|
67
|
+
asChild: true,
|
|
68
|
+
loading: isDownloading,
|
|
69
|
+
onClick: async (event) => {
|
|
70
|
+
event.preventDefault();
|
|
71
|
+
if (isDownloading) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
setIsDownloading(true);
|
|
75
|
+
try {
|
|
76
|
+
await downloadFile(String(props.src));
|
|
77
|
+
} finally {
|
|
78
|
+
setIsDownloading(false);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
children: /* @__PURE__ */ jsx("a", { download: true, href: props.src, children: "Download" })
|
|
82
|
+
}
|
|
83
|
+
)
|
|
84
|
+
] })
|
|
85
|
+
] })
|
|
86
|
+
] })
|
|
87
|
+
] });
|
|
88
|
+
}
|
|
89
|
+
ProteusImage.displayName = "@optiaxiom/proteus/ProteusImage";
|
|
90
|
+
|
|
91
|
+
export { ProteusImage };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
async function downloadFile(url) {
|
|
2
|
+
const response = await fetch(url, { credentials: "include" });
|
|
3
|
+
const blob = await response.blob();
|
|
4
|
+
const objectUrl = URL.createObjectURL(blob);
|
|
5
|
+
const a = document.createElement("a");
|
|
6
|
+
a.href = objectUrl;
|
|
7
|
+
a.download = url.split("/").pop() || "";
|
|
8
|
+
a.click();
|
|
9
|
+
URL.revokeObjectURL(objectUrl);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { downloadFile };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { Input } 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 ProteusInput(props) {
|
|
9
|
+
const { onDataChange, readOnly } = useProteusDocumentContext(
|
|
10
|
+
"@optiaxiom/proteus/ProteusInput"
|
|
11
|
+
);
|
|
12
|
+
const { path: parentPath } = useProteusDocumentPathContext(
|
|
13
|
+
"@optiaxiom/proteus/ProteusInput"
|
|
14
|
+
);
|
|
15
|
+
const value = useProteusValue({ path: props.name ?? "" });
|
|
16
|
+
return /* @__PURE__ */ jsx(
|
|
17
|
+
Input,
|
|
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 ?? "") : ""
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
ProteusInput.displayName = "@optiaxiom/proteus/ProteusInput";
|
|
31
|
+
|
|
32
|
+
export { ProteusInput };
|
|
@@ -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 };
|