@optiaxiom/proteus 1.0.0 → 1.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 (64) hide show
  1. package/dist/esm/_virtual/_openai-shim-script.js +3 -2
  2. package/dist/esm/assets/src/proteus-chart/{ProteusChart.css.ts.vanilla-BeRNNwBj.css → ProteusChart.css.ts.vanilla-yGx8JdKz.css} +2 -2
  3. package/dist/esm/assets/src/proteus-chart/{ProteusChartTooltipContent.css.ts.vanilla-Df_IhL_i.css → ProteusChartTooltipContent.css.ts.vanilla-HapBe2oo.css} +2 -2
  4. package/dist/esm/assets/src/proteus-document/{ProteusDocumentShell.css.ts.vanilla-CyMtrn1n.css → ProteusDocumentShell.css.ts.vanilla-BPytQ9pT.css} +2 -2
  5. package/dist/esm/assets/src/proteus-image-carousel/{ProteusImageCarousel.css.ts.vanilla-Dbf7yRF1.css → ProteusImageCarousel.css.ts.vanilla-DnlXoyv1.css} +2 -2
  6. package/dist/esm/assets/src/proteus-question/{ProteusQuestion.css.ts.vanilla-cmHZWqNR.css → ProteusQuestion.css.ts.vanilla-CpDgoW0l.css} +2 -2
  7. package/dist/esm/hooks/useEffectEvent.js +11 -10
  8. package/dist/esm/hooks/useObserveValue.js +24 -30
  9. package/dist/esm/icons/IconAngleLeft.js +13 -19
  10. package/dist/esm/icons/IconAngleRight.js +13 -19
  11. package/dist/esm/icons/IconX.js +10 -18
  12. package/dist/esm/icons/withIcon.js +17 -28
  13. package/dist/esm/index.js +22 -17
  14. package/dist/esm/proteus-action/ProteusAction.js +44 -39
  15. package/dist/esm/proteus-bridge/ProteusBridge.js +71 -85
  16. package/dist/esm/proteus-card-link/ProteusCardLink.js +24 -37
  17. package/dist/esm/proteus-chart/ProteusChart-css.js +14 -5
  18. package/dist/esm/proteus-chart/ProteusChart.js +86 -84
  19. package/dist/esm/proteus-chart/ProteusChartContext.js +3 -3
  20. package/dist/esm/proteus-chart/ProteusChartTooltipContent-css.js +23 -6
  21. package/dist/esm/proteus-chart/ProteusChartTooltipContent.js +52 -66
  22. package/dist/esm/proteus-data-table/ProteusDataTable.js +28 -29
  23. package/dist/esm/proteus-date-input/ProteusDateInput.js +23 -0
  24. package/dist/esm/proteus-document/ProteusDocumentContext.js +4 -3
  25. package/dist/esm/proteus-document/ProteusDocumentPathContext.js +6 -5
  26. package/dist/esm/proteus-document/ProteusDocumentRenderer.js +25 -33
  27. package/dist/esm/proteus-document/ProteusDocumentShell-css.js +32 -6
  28. package/dist/esm/proteus-document/ProteusDocumentShell.js +226 -219
  29. package/dist/esm/proteus-document/getProteusValue.js +28 -42
  30. package/dist/esm/proteus-document/resolveProteusProp.js +31 -49
  31. package/dist/esm/proteus-document/resolveProteusValue.js +73 -136
  32. package/dist/esm/proteus-document/schemas.js +42 -45
  33. package/dist/esm/proteus-document/useResolveProteusValues.js +10 -16
  34. package/dist/esm/proteus-element/ProteusElement.js +114 -180
  35. package/dist/esm/proteus-federated/ProteusFederated.js +51 -52
  36. package/dist/esm/proteus-file-icon/ProteusFileIcon.js +29 -38
  37. package/dist/esm/proteus-file-upload/ProteusFileUpload.js +107 -133
  38. package/dist/esm/proteus-image/ProteusImage.js +99 -106
  39. package/dist/esm/proteus-image/downloadFile.js +3 -2
  40. package/dist/esm/proteus-image-carousel/ProteusImageCarousel-css.js +49 -11
  41. package/dist/esm/proteus-image-carousel/ProteusImageCarousel.js +151 -163
  42. package/dist/esm/proteus-input/ProteusInput.js +19 -27
  43. package/dist/esm/proteus-length/ProteusLength.js +10 -0
  44. package/dist/esm/proteus-map/ProteusMap.js +18 -31
  45. package/dist/esm/proteus-map-index/ProteusMapIndex.js +11 -0
  46. package/dist/esm/proteus-pill-menu/ProteusPillMenu.js +65 -0
  47. package/dist/esm/proteus-pill-menu/useInputValueChangeInteraction.js +36 -0
  48. package/dist/esm/proteus-question/ProteusQuestion-css.js +40 -8
  49. package/dist/esm/proteus-question/ProteusQuestion.js +324 -400
  50. package/dist/esm/proteus-select/ProteusSelect.js +25 -40
  51. package/dist/esm/proteus-show/ProteusShow.js +10 -18
  52. package/dist/esm/proteus-switch/ProteusSwitch.js +33 -36
  53. package/dist/esm/proteus-textarea/ProteusTextarea.js +18 -27
  54. package/dist/esm/proteus-value/ProteusValue.js +4 -4
  55. package/dist/esm/schema/public-schema.js +4537 -0
  56. package/dist/esm/schema/runtime-schema.js +4460 -0
  57. package/dist/esm/spec.js +5 -1
  58. package/dist/esm/use-proteus-value/useProteusValue.js +8 -12
  59. package/dist/index.d.ts +516 -347
  60. package/dist/spec.d.ts +5 -9952
  61. package/package.json +4 -4
  62. package/dist/esm/icons/IconCalendar.js +0 -20
  63. package/dist/esm/schema/public-schema.json.js +0 -9026
  64. package/dist/esm/schema/runtime-schema.json.js +0 -8959
@@ -1,167 +1,155 @@
1
1
  "use client";
2
- import { jsxs, jsx } from 'react/jsx-runtime';
3
- import { Group, Box, Text, Menu, MenuTrigger, MenuContent, Button } from '@optiaxiom/react';
4
- import useEmblaCarousel from 'embla-carousel-react';
5
- import { useState, useCallback, useEffect } from 'react';
6
- import { IconAngleLeft } from '../icons/IconAngleLeft.js';
7
- import { IconAngleRight } from '../icons/IconAngleRight.js';
8
- import { useProteusDocumentContext } from '../proteus-document/ProteusDocumentContext.js';
9
- import { ProteusImage } from '../proteus-image/ProteusImage.js';
10
- import { slide, slideContainer, viewport, navButton, content, thumbnail, carousel } from './ProteusImageCarousel-css.js';
11
-
12
- function ProteusImageCarousel({
13
- images,
14
- title
15
- }) {
16
- const { onEvent } = useProteusDocumentContext(
17
- "@optiaxiom/proteus/ProteusImageCarousel"
18
- );
19
- const [emblaMainRef, emblaMainApi] = useEmblaCarousel({
20
- loop: false,
21
- watchDrag: false
22
- });
23
- const [emblaThumbsRef, emblaThumbsApi] = useEmblaCarousel({
24
- containScroll: "keepSnaps",
25
- dragFree: true
26
- });
27
- const [selectedIndex, setSelectedIndex] = useState(0);
28
- const [canScrollPrev, setCanScrollPrev] = useState(false);
29
- const [canScrollNext, setCanScrollNext] = useState(false);
30
- const onSelect = useCallback(() => {
31
- if (!emblaMainApi || !emblaThumbsApi)
32
- return;
33
- setSelectedIndex(emblaMainApi.selectedScrollSnap());
34
- emblaThumbsApi.scrollTo(emblaMainApi.selectedScrollSnap());
35
- setCanScrollPrev(emblaMainApi.canScrollPrev());
36
- setCanScrollNext(emblaMainApi.canScrollNext());
37
- }, [emblaMainApi, emblaThumbsApi]);
38
- useEffect(() => {
39
- if (!emblaMainApi)
40
- return;
41
- onSelect();
42
- emblaMainApi.on("select", onSelect).on("reInit", onSelect);
43
- }, [emblaMainApi, onSelect]);
44
- if (!images.length) {
45
- return null;
46
- }
47
- return /* @__PURE__ */ jsxs(
48
- Group,
49
- {
50
- "aria-label": title ?? "Image carousel",
51
- "aria-roledescription": "carousel",
52
- onKeyDownCapture: (event) => {
53
- if (event.target instanceof HTMLInputElement)
54
- return;
55
- if (event.key === "ArrowLeft") {
56
- event.preventDefault();
57
- emblaMainApi?.scrollPrev();
58
- } else if (event.key === "ArrowRight") {
59
- event.preventDefault();
60
- emblaMainApi?.scrollNext();
61
- }
62
- },
63
- role: "region",
64
- tabIndex: 0,
65
- ...carousel(),
66
- children: [
67
- /* @__PURE__ */ jsxs(Box, { ...content(), children: [
68
- /* @__PURE__ */ jsx(Box, { ...viewport(), ref: emblaMainRef, children: /* @__PURE__ */ jsx(Group, { ...slideContainer(), children: images.map((image, index) => /* @__PURE__ */ jsx(
69
- ProteusImage,
70
- {
71
- alt: image.alt,
72
- src: image.src,
73
- ...slide()
74
- },
75
- index
76
- )) }) }),
77
- canScrollPrev && /* @__PURE__ */ jsx(
78
- Box,
79
- {
80
- "aria-label": "Previous image",
81
- asChild: true,
82
- onClick: () => emblaMainApi?.scrollPrev(),
83
- ...navButton({ side: "left" }),
84
- children: /* @__PURE__ */ jsx("button", { children: /* @__PURE__ */ jsx(IconAngleLeft, {}) })
85
- }
86
- ),
87
- canScrollNext && /* @__PURE__ */ jsx(
88
- Box,
89
- {
90
- "aria-label": "Next image",
91
- asChild: true,
92
- onClick: () => emblaMainApi?.scrollNext(),
93
- ...navButton({ side: "right" }),
94
- children: /* @__PURE__ */ jsx("button", { children: /* @__PURE__ */ jsx(IconAngleRight, {}) })
95
- }
96
- )
97
- ] }),
98
- images.length > 1 && /* @__PURE__ */ jsx(Box, { overflow: "hidden", ref: emblaThumbsRef, children: /* @__PURE__ */ jsx(Group, { gap: "12", children: images.map((image, index) => /* @__PURE__ */ jsx(
99
- Box,
100
- {
101
- onClick: () => emblaMainApi?.scrollTo(index),
102
- ...thumbnail({
103
- selected: index === selectedIndex
104
- }),
105
- children: /* @__PURE__ */ jsx(Box, { asChild: true, objectFit: "cover", size: "full", children: /* @__PURE__ */ jsx("img", { alt: image.alt, src: image.thumb ?? image.src }) })
106
- },
107
- index
108
- )) }) }),
109
- /* @__PURE__ */ jsxs(Group, { mt: "4", children: [
110
- images.length > 1 && /* @__PURE__ */ jsxs(
111
- Text,
112
- {
113
- bg: "bg.secondary",
114
- color: "fg.default",
115
- fontSize: "sm",
116
- fontWeight: "500",
117
- px: "8",
118
- py: "2",
119
- rounded: "full",
120
- children: [
121
- selectedIndex + 1,
122
- " / ",
123
- images.length
124
- ]
125
- }
126
- ),
127
- images.length > 1 ? /* @__PURE__ */ jsxs(
128
- Menu,
129
- {
130
- options: [
131
- {
132
- execute: () => onEvent({
133
- action: "download",
134
- url: images[selectedIndex].src
135
- }),
136
- label: "Download this image"
137
- },
138
- {
139
- execute: () => onEvent({
140
- action: "download",
141
- url: images.map((image) => image.src)
142
- }),
143
- label: "Download all images"
144
- }
145
- ],
146
- children: [
147
- /* @__PURE__ */ jsx(MenuTrigger, { appearance: "primary", ml: "auto", children: "Download" }),
148
- /* @__PURE__ */ jsx(MenuContent, { align: "end" })
149
- ]
150
- }
151
- ) : /* @__PURE__ */ jsx(
152
- Button,
153
- {
154
- appearance: "primary",
155
- ml: "auto",
156
- onClick: () => onEvent({ action: "download", url: images[0].src }),
157
- children: "Download"
158
- }
159
- )
160
- ] })
161
- ]
162
- }
163
- );
2
+ import { useProteusDocumentContext } from "../proteus-document/ProteusDocumentContext.js";
3
+ import { IconAngleLeft } from "../icons/IconAngleLeft.js";
4
+ import { IconAngleRight } from "../icons/IconAngleRight.js";
5
+ import { ProteusImage } from "../proteus-image/ProteusImage.js";
6
+ import { carousel, content, navButton, slide, slideContainer, thumbnail, viewport } from "./ProteusImageCarousel-css.js";
7
+ import { Box, Button, Group, Menu, MenuContent, MenuTrigger, Text } from "@optiaxiom/react";
8
+ import { useCallback, useEffect, useState } from "react";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ import useEmblaCarousel from "embla-carousel-react";
11
+ //#region src/proteus-image-carousel/ProteusImageCarousel.tsx
12
+ function ProteusImageCarousel({ images, title }) {
13
+ const { onEvent } = useProteusDocumentContext("@optiaxiom/proteus/ProteusImageCarousel");
14
+ const [emblaMainRef, emblaMainApi] = useEmblaCarousel({
15
+ loop: false,
16
+ watchDrag: false
17
+ });
18
+ const [emblaThumbsRef, emblaThumbsApi] = useEmblaCarousel({
19
+ containScroll: "keepSnaps",
20
+ dragFree: true
21
+ });
22
+ const [selectedIndex, setSelectedIndex] = useState(0);
23
+ const [canScrollPrev, setCanScrollPrev] = useState(false);
24
+ const [canScrollNext, setCanScrollNext] = useState(false);
25
+ const onSelect = useCallback(() => {
26
+ if (!emblaMainApi || !emblaThumbsApi) return;
27
+ setSelectedIndex(emblaMainApi.selectedScrollSnap());
28
+ emblaThumbsApi.scrollTo(emblaMainApi.selectedScrollSnap());
29
+ setCanScrollPrev(emblaMainApi.canScrollPrev());
30
+ setCanScrollNext(emblaMainApi.canScrollNext());
31
+ }, [emblaMainApi, emblaThumbsApi]);
32
+ useEffect(() => {
33
+ if (!emblaMainApi) return;
34
+ onSelect();
35
+ emblaMainApi.on("select", onSelect).on("reInit", onSelect);
36
+ }, [emblaMainApi, onSelect]);
37
+ if (!images.length) return null;
38
+ return /* @__PURE__ */ jsxs(Group, {
39
+ "aria-label": title ?? "Image carousel",
40
+ "aria-roledescription": "carousel",
41
+ onKeyDownCapture: (event) => {
42
+ if (event.target instanceof HTMLInputElement) return;
43
+ if (event.key === "ArrowLeft") {
44
+ event.preventDefault();
45
+ emblaMainApi?.scrollPrev();
46
+ } else if (event.key === "ArrowRight") {
47
+ event.preventDefault();
48
+ emblaMainApi?.scrollNext();
49
+ }
50
+ },
51
+ role: "region",
52
+ tabIndex: 0,
53
+ ...carousel(),
54
+ children: [
55
+ /* @__PURE__ */ jsxs(Box, {
56
+ ...content(),
57
+ children: [
58
+ /* @__PURE__ */ jsx(Box, {
59
+ ...viewport(),
60
+ ref: emblaMainRef,
61
+ children: /* @__PURE__ */ jsx(Group, {
62
+ ...slideContainer(),
63
+ children: images.map((image, index) => /* @__PURE__ */ jsx(ProteusImage, {
64
+ alt: image.alt,
65
+ src: image.src,
66
+ ...slide()
67
+ }, index))
68
+ })
69
+ }),
70
+ canScrollPrev && /* @__PURE__ */ jsx(Box, {
71
+ "aria-label": "Previous image",
72
+ asChild: true,
73
+ onClick: () => emblaMainApi?.scrollPrev(),
74
+ ...navButton({ side: "left" }),
75
+ children: /* @__PURE__ */ jsx("button", { children: /* @__PURE__ */ jsx(IconAngleLeft, {}) })
76
+ }),
77
+ canScrollNext && /* @__PURE__ */ jsx(Box, {
78
+ "aria-label": "Next image",
79
+ asChild: true,
80
+ onClick: () => emblaMainApi?.scrollNext(),
81
+ ...navButton({ side: "right" }),
82
+ children: /* @__PURE__ */ jsx("button", { children: /* @__PURE__ */ jsx(IconAngleRight, {}) })
83
+ })
84
+ ]
85
+ }),
86
+ images.length > 1 && /* @__PURE__ */ jsx(Box, {
87
+ overflow: "hidden",
88
+ ref: emblaThumbsRef,
89
+ children: /* @__PURE__ */ jsx(Group, {
90
+ gap: "12",
91
+ children: images.map((image, index) => /* @__PURE__ */ jsx(Box, {
92
+ onClick: () => emblaMainApi?.scrollTo(index),
93
+ ...thumbnail({ selected: index === selectedIndex }),
94
+ children: /* @__PURE__ */ jsx(Box, {
95
+ asChild: true,
96
+ objectFit: "cover",
97
+ size: "full",
98
+ children: /* @__PURE__ */ jsx("img", {
99
+ alt: image.alt,
100
+ src: image.thumb ?? image.src
101
+ })
102
+ })
103
+ }, index))
104
+ })
105
+ }),
106
+ /* @__PURE__ */ jsxs(Group, {
107
+ mt: "4",
108
+ children: [images.length > 1 && /* @__PURE__ */ jsxs(Text, {
109
+ bg: "bg.secondary",
110
+ color: "fg.default",
111
+ fontSize: "sm",
112
+ fontWeight: "500",
113
+ px: "8",
114
+ py: "2",
115
+ rounded: "full",
116
+ children: [
117
+ selectedIndex + 1,
118
+ " / ",
119
+ images.length
120
+ ]
121
+ }), images.length > 1 ? /* @__PURE__ */ jsxs(Menu, {
122
+ options: [{
123
+ execute: () => onEvent({
124
+ action: "download",
125
+ url: images[selectedIndex].src
126
+ }),
127
+ label: "Download this image"
128
+ }, {
129
+ execute: () => onEvent({
130
+ action: "download",
131
+ url: images.map((image) => image.src)
132
+ }),
133
+ label: "Download all images"
134
+ }],
135
+ children: [/* @__PURE__ */ jsx(MenuTrigger, {
136
+ appearance: "primary",
137
+ ml: "auto",
138
+ children: "Download"
139
+ }), /* @__PURE__ */ jsx(MenuContent, { align: "end" })]
140
+ }) : /* @__PURE__ */ jsx(Button, {
141
+ appearance: "primary",
142
+ ml: "auto",
143
+ onClick: () => onEvent({
144
+ action: "download",
145
+ url: images[0].src
146
+ }),
147
+ children: "Download"
148
+ })]
149
+ })
150
+ ]
151
+ });
164
152
  }
165
153
  ProteusImageCarousel.displayName = "@optiaxiom/proteus/ProteusImageCarousel";
166
-
154
+ //#endregion
167
155
  export { ProteusImageCarousel };
@@ -1,32 +1,24 @@
1
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 '../use-proteus-value/useProteusValue.js';
7
-
2
+ import { useProteusDocumentContext } from "../proteus-document/ProteusDocumentContext.js";
3
+ import { useProteusDocumentPathContext } from "../proteus-document/ProteusDocumentPathContext.js";
4
+ import { useProteusValue } from "../use-proteus-value/useProteusValue.js";
5
+ import { Input } from "@optiaxiom/react";
6
+ import { jsx } from "react/jsx-runtime";
7
+ //#region src/proteus-input/ProteusInput.tsx
8
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
- );
9
+ const { onDataChange, readOnly } = useProteusDocumentContext("@optiaxiom/proteus/ProteusInput");
10
+ const { path: parentPath } = useProteusDocumentPathContext("@optiaxiom/proteus/ProteusInput");
11
+ const value = useProteusValue({ path: props.name ?? "" });
12
+ const writePath = props.name ? `${parentPath}/${props.name}` : parentPath;
13
+ return /* @__PURE__ */ jsx(Input, {
14
+ ...props,
15
+ onValueChange: (value) => {
16
+ if (writePath) onDataChange?.(writePath, value);
17
+ },
18
+ readOnly,
19
+ value: String(value ?? "")
20
+ });
29
21
  }
30
22
  ProteusInput.displayName = "@optiaxiom/proteus/ProteusInput";
31
-
23
+ //#endregion
32
24
  export { ProteusInput };
@@ -0,0 +1,10 @@
1
+ "use client";
2
+ import { useProteusValue } from "../use-proteus-value/useProteusValue.js";
3
+ //#region src/proteus-length/ProteusLength.tsx
4
+ function ProteusLength({ path }) {
5
+ const value = useProteusValue({ path });
6
+ return Array.isArray(value) ? value.length : 0;
7
+ }
8
+ ProteusLength.displayName = "@optiaxiom/proteus/ProteusLength";
9
+ //#endregion
10
+ export { ProteusLength };
@@ -1,36 +1,23 @@
1
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 '../use-proteus-value/useProteusValue.js';
6
-
2
+ import { useProteusDocumentContext } from "../proteus-document/ProteusDocumentContext.js";
3
+ import { ProteusDocumentPathProvider, useProteusDocumentPathContext } from "../proteus-document/ProteusDocumentPathContext.js";
4
+ import { useProteusValue } from "../use-proteus-value/useProteusValue.js";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ //#region src/proteus-map/ProteusMap.tsx
7
7
  function ProteusMap({ children, path, separator }) {
8
- const { strict } = useProteusDocumentContext("@optiaxiom/proteus/ProteusMap");
9
- const { mapIndices, 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
- mapIndices: [...mapIndices, index],
25
- path: `${path.startsWith("/") ? path : `${parentPath}/${path}`}/${index}`,
26
- children: [
27
- index > 0 && separator,
28
- children
29
- ]
30
- },
31
- index
32
- )) });
8
+ const { strict } = useProteusDocumentContext("@optiaxiom/proteus/ProteusMap");
9
+ const { mapIndices, path: parentPath } = useProteusDocumentPathContext("@optiaxiom/proteus/ProteusMap");
10
+ const array = useProteusValue({ path });
11
+ if (!Array.isArray(array)) {
12
+ if (strict) throw new Error(`Expected value at "${path}" to be an array got "${typeof array}" instead`);
13
+ return null;
14
+ }
15
+ return /* @__PURE__ */ jsx(Fragment, { children: array.map((_, index) => /* @__PURE__ */ jsxs(ProteusDocumentPathProvider, {
16
+ mapIndices: [...mapIndices, index],
17
+ path: `${path.startsWith("/") ? path : `${parentPath}/${path}`}/${index}`,
18
+ children: [index > 0 && separator, children]
19
+ }, index)) });
33
20
  }
34
21
  ProteusMap.displayName = "@optiaxiom/proteus/ProteusMap";
35
-
22
+ //#endregion
36
23
  export { ProteusMap };
@@ -0,0 +1,11 @@
1
+ "use client";
2
+ import { useProteusDocumentPathContext } from "../proteus-document/ProteusDocumentPathContext.js";
3
+ //#region src/proteus-map-index/ProteusMapIndex.tsx
4
+ function ProteusMapIndex() {
5
+ const { mapIndices } = useProteusDocumentPathContext("@optiaxiom/proteus/ProteusMapIndex");
6
+ const index = mapIndices.at(-1);
7
+ return index === void 0 ? null : index;
8
+ }
9
+ ProteusMapIndex.displayName = "@optiaxiom/proteus/ProteusMapIndex";
10
+ //#endregion
11
+ export { ProteusMapIndex };
@@ -0,0 +1,65 @@
1
+ "use client";
2
+ import { useProteusDocumentContext } from "../proteus-document/ProteusDocumentContext.js";
3
+ import { useProteusDocumentPathContext } from "../proteus-document/ProteusDocumentPathContext.js";
4
+ import { useProteusValue } from "../use-proteus-value/useProteusValue.js";
5
+ import { useInputValueChangeInteraction } from "./useInputValueChangeInteraction.js";
6
+ import "@optiaxiom/react";
7
+ import { useMemo } from "react";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { PillMenu, PillMenuContent, PillMenuTrigger } from "@optiaxiom/react/unstable";
10
+ //#region src/proteus-pill-menu/ProteusPillMenu.tsx
11
+ function ProteusPillMenu({ inputName, name, onInputValueChange, options = [] }) {
12
+ const { onDataChange, readOnly } = useProteusDocumentContext("@optiaxiom/proteus/ProteusPillMenu");
13
+ const { path: parentPath } = useProteusDocumentPathContext("@optiaxiom/proteus/ProteusPillMenu");
14
+ const { inputValue, loading } = useInputValueChangeInteraction({
15
+ inputName,
16
+ onInputValueChange
17
+ });
18
+ const resolved = useProteusValue({ path: name ?? "" });
19
+ const serialized = JSON.stringify(Array.isArray(resolved) ? resolved : []);
20
+ const value = useMemo(() => JSON.parse(serialized), [serialized]);
21
+ const menuOptions = useMemo(() => options.map((option) => ({
22
+ ...option,
23
+ execute: () => {
24
+ if (readOnly || !name) return;
25
+ const next = value.some((v) => v.value === option.value) ? value.filter((v) => v.value !== option.value) : [...value, option];
26
+ onDataChange?.(`${parentPath}/${name}`, next);
27
+ },
28
+ multi: true,
29
+ selected: () => value.some((v) => v.value === option.value)
30
+ })), [
31
+ name,
32
+ onDataChange,
33
+ options,
34
+ parentPath,
35
+ readOnly,
36
+ value
37
+ ]);
38
+ const menuValue = useMemo(() => value.map((item) => ({
39
+ execute: () => {
40
+ if (readOnly || !name) return;
41
+ onDataChange?.(`${parentPath}/${name}`, value.filter((v) => v.value !== item.value));
42
+ },
43
+ label: item.label,
44
+ multi: true
45
+ })), [
46
+ name,
47
+ onDataChange,
48
+ parentPath,
49
+ readOnly,
50
+ value
51
+ ]);
52
+ return /* @__PURE__ */ jsxs(PillMenu, {
53
+ inputValue: inputName ? inputValue : void 0,
54
+ loading,
55
+ onInputValueChange: (inputValue) => {
56
+ if (inputName) onDataChange?.(`${parentPath}/${inputName}`, inputValue);
57
+ },
58
+ options: menuOptions,
59
+ value: menuValue,
60
+ children: [/* @__PURE__ */ jsx(PillMenuTrigger, { readOnly }), /* @__PURE__ */ jsx(PillMenuContent, {})]
61
+ });
62
+ }
63
+ ProteusPillMenu.displayName = "@optiaxiom/proteus/ProteusPillMenu";
64
+ //#endregion
65
+ export { ProteusPillMenu };
@@ -0,0 +1,36 @@
1
+ import { useProteusDocumentContext } from "../proteus-document/ProteusDocumentContext.js";
2
+ import { useResolveProteusValues } from "../proteus-document/useResolveProteusValues.js";
3
+ import { useProteusValue } from "../use-proteus-value/useProteusValue.js";
4
+ import { useEffect, useRef, useState } from "react";
5
+ //#region src/proteus-pill-menu/useInputValueChangeInteraction.ts
6
+ const useInputValueChangeInteraction = ({ inputName, onInputValueChange }) => {
7
+ const { onEvent } = useProteusDocumentContext("@optiaxiom/proteus/useInputValueChangeInteraction");
8
+ const inputValue = useProteusValue({ path: inputName ?? "" });
9
+ const resolvedOnInputValueChange = useResolveProteusValues(onInputValueChange ?? {});
10
+ const resolvedRef = useRef(resolvedOnInputValueChange);
11
+ resolvedRef.current = resolvedOnInputValueChange;
12
+ const onEventRef = useRef(onEvent);
13
+ onEventRef.current = onEvent;
14
+ const [loading, setLoading] = useState();
15
+ const requestIdRef = useRef(0);
16
+ useEffect(() => {
17
+ if (inputName && onInputValueChange) {
18
+ const id = ++requestIdRef.current;
19
+ (async () => {
20
+ setLoading("spinner");
21
+ await onEventRef.current(resolvedRef.current);
22
+ if (requestIdRef.current === id) setLoading(void 0);
23
+ })();
24
+ }
25
+ }, [
26
+ inputName,
27
+ inputValue,
28
+ onInputValueChange
29
+ ]);
30
+ return {
31
+ inputValue,
32
+ loading
33
+ };
34
+ };
35
+ //#endregion
36
+ export { useInputValueChangeInteraction };
@@ -1,9 +1,41 @@
1
- import './../assets/src/proteus-question/ProteusQuestion.css.ts.vanilla-cmHZWqNR.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'},'ProteusQuestion__8f590p3'],variants:{cursor:{pointer:{cursor:'pointer'}}}});
5
- var choice = recipe({base:[{color:'fg.default',flexDirection:'column',fontSize:'md',gap:'8',px:'10',py:'16',rounded:'lg',transition:'colors'},'ProteusQuestion__8f590p2','ProteusQuestion__8f590p1'],variants:{cursor:{pointer:{borderB:'1'},text:{cursor:'text'}}}});
6
- var choiceGroup = recipe({base:{flexDirection:'column'}});
7
- var question = recipe({base:[{flexDirection:'column',gap:'16'},'ProteusQuestion__8f590p0']});
8
-
1
+ import { recipe } from "@optiaxiom/react/css-runtime";
2
+ import "./../assets/src/proteus-question/ProteusQuestion.css.ts.vanilla-CpDgoW0l.css";
3
+ //#region src/proteus-question/ProteusQuestion.css.ts
4
+ var addon = recipe({
5
+ base: [{
6
+ display: "grid",
7
+ fontWeight: "500",
8
+ placeItems: "center",
9
+ rounded: "lg",
10
+ size: "md",
11
+ transition: "colors"
12
+ }, "ProteusQuestion__8f590p3"],
13
+ variants: { cursor: { pointer: { cursor: "pointer" } } }
14
+ });
15
+ var choice = recipe({
16
+ base: [
17
+ {
18
+ color: "fg.default",
19
+ flexDirection: "column",
20
+ fontSize: "md",
21
+ gap: "8",
22
+ px: "10",
23
+ py: "16",
24
+ rounded: "lg",
25
+ transition: "colors"
26
+ },
27
+ "ProteusQuestion__8f590p2",
28
+ "ProteusQuestion__8f590p1"
29
+ ],
30
+ variants: { cursor: {
31
+ pointer: { borderB: "1" },
32
+ text: { cursor: "text" }
33
+ } }
34
+ });
35
+ var choiceGroup = recipe({ base: { flexDirection: "column" } });
36
+ var question = recipe({ base: [{
37
+ flexDirection: "column",
38
+ gap: "16"
39
+ }, "ProteusQuestion__8f590p0"] });
40
+ //#endregion
9
41
  export { addon, choice, choiceGroup, question };