@optiaxiom/proteus 0.2.11 → 0.2.13-next.2

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.
@@ -1,5 +1,5 @@
1
- @layer optiaxiom._1om87vs;
2
- @layer optiaxiom._1om87vs {
1
+ @layer optiaxiom.g7voo0;
2
+ @layer optiaxiom.g7voo0 {
3
3
  .ProteusChart__jmlqij1 {
4
4
  border-radius: 16px;
5
5
  }
@@ -1,5 +1,5 @@
1
- @layer optiaxiom._1om87vs;
2
- @layer optiaxiom._1om87vs {
1
+ @layer optiaxiom.g7voo0;
2
+ @layer optiaxiom.g7voo0 {
3
3
  .ProteusChartTooltipContent__1gsvq810 {
4
4
  min-width: 128px;
5
5
  position: absolute;
@@ -1,5 +1,5 @@
1
- @layer optiaxiom._1om87vs;
2
- @layer optiaxiom._1om87vs {
1
+ @layer optiaxiom.g7voo0;
2
+ @layer optiaxiom.g7voo0 {
3
3
  .ProteusDocumentShell__vpuvfj1 {
4
4
  margin: -4px;
5
5
  }
@@ -1,5 +1,5 @@
1
- @layer optiaxiom._1om87vs;
2
- @layer optiaxiom._1om87vs {
1
+ @layer optiaxiom.g7voo0;
2
+ @layer optiaxiom.g7voo0 {
3
3
  .ProteusImageCarousel__1t6qej70 {
4
4
  outline: none;
5
5
  user-select: none;
@@ -1,5 +1,5 @@
1
- @layer optiaxiom._1om87vs;
2
- @layer optiaxiom._1om87vs {
1
+ @layer optiaxiom.g7voo0;
2
+ @layer optiaxiom.g7voo0 {
3
3
  .ProteusQuestion__8f590p0 {
4
4
  outline: none;
5
5
  }
@@ -1,4 +1,4 @@
1
- import './../assets/src/proteus-chart/ProteusChart.css.ts.vanilla-Bhea5BpW.css';
1
+ import './../assets/src/proteus-chart/ProteusChart.css.ts.vanilla-dJjly98l.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']});
@@ -1,4 +1,4 @@
1
- import './../assets/src/proteus-chart/ProteusChartTooltipContent.css.ts.vanilla-7xvqKrcf.css';
1
+ import './../assets/src/proteus-chart/ProteusChartTooltipContent.css.ts.vanilla-Crdo1SWy.css';
2
2
  import { recipe } from '@optiaxiom/react/css-runtime';
3
3
 
4
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',z:'popover'},'ProteusChartTooltipContent__1gsvq810']});
@@ -1,4 +1,4 @@
1
- import './../assets/src/proteus-document/ProteusDocumentShell.css.ts.vanilla-Bil1PxGV.css';
1
+ import './../assets/src/proteus-document/ProteusDocumentShell.css.ts.vanilla-DvoqWndD.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']}}});
@@ -95,6 +95,7 @@ function resolveProteusValue(value, data, parentPath, mapIndices = []) {
95
95
  [...mapIndices, index]
96
96
  )
97
97
  ).filter((v) => v !== void 0);
98
+ const result = "flat" in value && value.flat ? items.flat() : items;
98
99
  if ("separator" in value) {
99
100
  const sep = resolveProteusValue(
100
101
  value.separator,
@@ -102,9 +103,9 @@ function resolveProteusValue(value, data, parentPath, mapIndices = []) {
102
103
  parentPath,
103
104
  mapIndices
104
105
  );
105
- return items.join(typeof sep === "string" ? sep : "");
106
+ return result.join(typeof sep === "string" ? sep : "");
106
107
  }
107
- return items;
108
+ return result;
108
109
  }
109
110
  if (value.$type === "Show" && "when" in value && "children" in value) {
110
111
  const conditions = Array.isArray(value.when) ? value.when : [value.when];
@@ -1,7 +1,8 @@
1
1
  "use client";
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { IconPlus } from '@optiaxiom/icons';
3
4
  import { Flex } from '@optiaxiom/react';
4
- import { FileUpload, VisuallyHidden, FileUploadList, FileUploadDropzone, FileUploadTrigger } from '@optiaxiom/react/unstable';
5
+ import { FileUpload, VisuallyHidden, FileUploadTrigger, FileUploadList, FileUploadDropzone } from '@optiaxiom/react/unstable';
5
6
  import { useRef, useState, useCallback } from 'react';
6
7
  import { useObserveValue } from '../hooks/useObserveValue.js';
7
8
  import { useProteusDocumentContext } from '../proteus-document/ProteusDocumentContext.js';
@@ -9,8 +10,9 @@ import { useProteusDocumentPathContext } from '../proteus-document/ProteusDocume
9
10
 
10
11
  function ProteusFileUpload({
11
12
  accept,
12
- name,
13
- required
13
+ maxFiles,
14
+ minFiles = 0,
15
+ name
14
16
  }) {
15
17
  const { onDataChange, onUpload, readOnly } = useProteusDocumentContext(
16
18
  "@optiaxiom/proteus/ProteusFileUpload"
@@ -19,71 +21,100 @@ function ProteusFileUpload({
19
21
  "@optiaxiom/proteus/ProteusFileUpload"
20
22
  );
21
23
  const inputRef = useRef(null);
22
- const [item, setItem] = useState(null);
24
+ const itemsRef = useRef([]);
25
+ const [items, setItems] = useState([]);
23
26
  const forceValueChange = useObserveValue(inputRef);
24
- const writeUrl = useCallback(
25
- (url) => {
26
- if (!name)
27
- return;
28
- onDataChange?.(`${parentPath}/${name}`, url);
29
- },
30
- [name, onDataChange, parentPath]
31
- );
27
+ const multiple = maxFiles !== 1;
28
+ const atMax = multiple && maxFiles !== void 0 && items.length >= maxFiles;
29
+ const writeValue = useCallback(() => {
30
+ setItems(itemsRef.current);
31
+ if (inputRef.current) {
32
+ forceValueChange(
33
+ itemsRef.current.filter((item) => item.status === "complete").length.toString()
34
+ );
35
+ }
36
+ if (name) {
37
+ const value = itemsRef.current.filter((item) => item.status === "complete").map((item) => item.metadata).filter((metadata) => !!metadata);
38
+ onDataChange?.(`${parentPath}/${name}`, value);
39
+ }
40
+ }, [forceValueChange, name, onDataChange, parentPath]);
32
41
  const handleFilesDrop = useCallback(
33
42
  async (incoming) => {
43
+ if (multiple) {
44
+ incoming = maxFiles !== void 0 ? incoming.slice(0, Math.max(0, maxFiles - itemsRef.current.length)) : incoming;
45
+ } else {
46
+ incoming = incoming.slice(0, 1);
47
+ }
34
48
  if (!onUpload || readOnly || incoming.length === 0) {
35
49
  return;
36
50
  }
37
- const file = incoming[0];
38
- setItem({ file, status: "uploading" });
39
- writeUrl(null);
40
- if (inputRef.current) {
41
- forceValueChange("");
42
- }
43
- try {
44
- const url = await onUpload(file);
45
- setItem(
46
- (curr) => curr?.file === file ? { file, status: "complete" } : curr
47
- );
48
- writeUrl(url);
49
- if (inputRef.current) {
50
- forceValueChange("1");
51
- }
52
- } catch {
53
- setItem(
54
- (curr) => curr?.file === file ? { file, status: "error" } : curr
55
- );
56
- }
51
+ itemsRef.current = [
52
+ ...multiple ? itemsRef.current : [],
53
+ ...incoming.map((file) => ({ file, status: "uploading" }))
54
+ ];
55
+ writeValue();
56
+ const result = new Map(
57
+ await Promise.all(
58
+ incoming.map(
59
+ (file) => onUpload(file).then(
60
+ (metadata) => [
61
+ file,
62
+ {
63
+ file,
64
+ metadata,
65
+ status: "complete"
66
+ }
67
+ ]
68
+ ).catch(
69
+ () => [
70
+ file,
71
+ {
72
+ file,
73
+ status: "error"
74
+ }
75
+ ]
76
+ )
77
+ )
78
+ )
79
+ );
80
+ itemsRef.current = itemsRef.current.map(
81
+ (item) => result.get(item.file) ?? item
82
+ );
83
+ writeValue();
57
84
  },
58
- [forceValueChange, onUpload, readOnly, writeUrl]
85
+ [maxFiles, multiple, onUpload, readOnly, writeValue]
86
+ );
87
+ const handleRemove = useCallback(
88
+ (item) => {
89
+ itemsRef.current = itemsRef.current.filter((i) => i !== item);
90
+ writeValue();
91
+ },
92
+ [writeValue]
59
93
  );
60
- const handleRemove = useCallback(() => {
61
- setItem(null);
62
- writeUrl(null);
63
- if (inputRef.current) {
64
- forceValueChange("");
65
- }
66
- }, [forceValueChange, writeUrl]);
67
94
  return /* @__PURE__ */ jsxs(
68
95
  FileUpload,
69
96
  {
70
97
  accept,
71
- disabled: !onUpload || readOnly,
98
+ disabled: !onUpload || readOnly || atMax,
72
99
  onFilesDrop: handleFilesDrop,
73
100
  children: [
74
101
  /* @__PURE__ */ jsx(VisuallyHidden, { asChild: true, children: /* @__PURE__ */ jsx(
75
102
  "input",
76
103
  {
77
104
  "aria-hidden": true,
105
+ defaultValue: 0,
106
+ max: maxFiles !== void 0 ? String(maxFiles) : void 0,
107
+ min: String(minFiles),
78
108
  name,
79
109
  ref: inputRef,
80
- required,
81
- tabIndex: -1
110
+ tabIndex: -1,
111
+ type: "number"
82
112
  }
83
113
  ) }),
84
- item ? /* @__PURE__ */ jsxs(Flex, { flexDirection: "column", gap: "8", children: [
85
- /* @__PURE__ */ jsx(FileUploadList, { items: [item], onRemove: handleRemove }),
86
- /* @__PURE__ */ jsx(FileUploadDropzone, { overlay: true })
114
+ items.length > 0 ? /* @__PURE__ */ jsxs(Flex, { flexDirection: "column", gap: "8", children: [
115
+ multiple && !atMax && /* @__PURE__ */ jsx(FileUploadTrigger, { alignSelf: "end", icon: /* @__PURE__ */ jsx(IconPlus, {}), children: "Add File" }),
116
+ /* @__PURE__ */ jsx(FileUploadList, { items, onRemove: handleRemove }),
117
+ !atMax && /* @__PURE__ */ jsx(FileUploadDropzone, { overlay: true })
87
118
  ] }) : /* @__PURE__ */ jsx(FileUploadDropzone, { children: /* @__PURE__ */ jsx(FileUploadTrigger, {}) })
88
119
  ]
89
120
  }
@@ -1,4 +1,4 @@
1
- import './../assets/src/proteus-image-carousel/ProteusImageCarousel.css.ts.vanilla-CKWS5NjD.css';
1
+ import './../assets/src/proteus-image-carousel/ProteusImageCarousel.css.ts.vanilla-DWOlO6KM.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-B04UzIcJ.css';
1
+ import './../assets/src/proteus-question/ProteusQuestion.css.ts.vanilla-DLqLEZxX.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'}}}});