@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.
Files changed (44) hide show
  1. package/LICENSE +201 -0
  2. package/dist/esm/assets/src/proteus-chart/ProteusChart.css.ts.vanilla-WpbWN23E.css +9 -0
  3. package/dist/esm/assets/src/proteus-chart/ProteusChartTooltipContent.css.ts.vanilla-sqWemcZm.css +9 -0
  4. package/dist/esm/assets/src/proteus-question/ProteusQuestionItem.css.ts.vanilla-Dns_NfIP.css +26 -0
  5. package/dist/esm/hooks/useEffectEvent.js +14 -0
  6. package/dist/esm/icons/IconAngleLeft.js +21 -0
  7. package/dist/esm/icons/IconCalendar.js +20 -0
  8. package/dist/esm/icons/withIcon.js +31 -0
  9. package/dist/esm/index.js +14 -0
  10. package/dist/esm/proteus-action/ProteusAction.js +41 -0
  11. package/dist/esm/proteus-action/ProteusCancelAction.js +41 -0
  12. package/dist/esm/proteus-chart/ProteusChart-css.js +6 -0
  13. package/dist/esm/proteus-chart/ProteusChart.js +71 -0
  14. package/dist/esm/proteus-chart/ProteusChartTooltipContent-css.js +7 -0
  15. package/dist/esm/proteus-chart/ProteusChartTooltipContent.js +45 -0
  16. package/dist/esm/proteus-data-table/ProteusDataTable.js +34 -0
  17. package/dist/esm/proteus-document/ProteusDocumentContext.js +6 -0
  18. package/dist/esm/proteus-document/ProteusDocumentPathContext.js +8 -0
  19. package/dist/esm/proteus-document/ProteusDocumentRenderer.js +39 -0
  20. package/dist/esm/proteus-document/ProteusDocumentShell.js +128 -0
  21. package/dist/esm/proteus-document/getProteusValue.js +49 -0
  22. package/dist/esm/proteus-document/resolveProteusProp.js +39 -0
  23. package/dist/esm/proteus-document/resolveProteusValue.js +18 -0
  24. package/dist/esm/proteus-document/schemas.js +48 -0
  25. package/dist/esm/proteus-document/useProteusValue.js +15 -0
  26. package/dist/esm/proteus-document/useResolvedProteusProps.js +19 -0
  27. package/dist/esm/proteus-element/ProteusElement.js +153 -0
  28. package/dist/esm/proteus-image/ProteusImage.js +91 -0
  29. package/dist/esm/proteus-image/downloadFile.js +12 -0
  30. package/dist/esm/proteus-input/ProteusInput.js +32 -0
  31. package/dist/esm/proteus-map/ProteusMap.js +35 -0
  32. package/dist/esm/proteus-question/ProteusQuestion.js +96 -0
  33. package/dist/esm/proteus-question/ProteusQuestionItem-css.js +9 -0
  34. package/dist/esm/proteus-question/ProteusQuestionItem.js +57 -0
  35. package/dist/esm/proteus-select/ProteusSelect.js +44 -0
  36. package/dist/esm/proteus-show/ProteusShow.js +70 -0
  37. package/dist/esm/proteus-textarea/ProteusTextarea.js +32 -0
  38. package/dist/esm/proteus-value/ProteusValue.js +9 -0
  39. package/dist/esm/schema/public-schema.json.js +7904 -0
  40. package/dist/esm/schema/runtime-schema.json.js +7851 -0
  41. package/dist/esm/spec.js +1 -0
  42. package/dist/index.d.ts +293 -0
  43. package/dist/spec.d.ts +8626 -0
  44. 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 };