@marktiderman/genesis-forms-studio 0.1.1 → 0.2.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/README.md +14 -0
- package/dist/{chunk-ZHH2UHOS.js → chunk-HAEZ7G3G.js} +83 -10
- package/dist/chunk-HAEZ7G3G.js.map +1 -0
- package/dist/index.d.ts +37 -8
- package/dist/index.js +130 -4
- package/dist/index.js.map +1 -1
- package/dist/{rules-BntWGD6S.d.ts → rules-BoOPNHuo.d.ts} +59 -2
- package/dist/rules.d.ts +1 -1
- package/dist/rules.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-ZHH2UHOS.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { SAVE_STATE_LABEL, readinessChip, prefilledUrl, embedSnippet, lowThisWeek, NO_FILTERS, lowScaleAtMost, dayLabel } from './chunk-
|
|
3
|
-
export { NO_FILTERS, SAVE_STATE_LABEL, answerCell, answerColumns, answersByKey, carryAnswers, comparisonFilter, dayLabel, embedSnippet, filterResponses, followUpOf, formAvailability, formCounts, formNavItems, formStatusChip, hasLowRating, hasLowRatingExcept, headlineCards, headlineNumbers, highestRating, isFiltered, isFull, lowRatingAtMost, lowRatingLabel, lowScaleAtMost, lowThisWeek, lowestRating, needsFollowUp, parseInstant, plainLabel, prefilledUrl, presetRange, readinessChip, readinessOf, summarizeResponses, takesResponses, toCsv, toResponseFilter, valuesByKey } from './chunk-
|
|
2
|
+
import { SAVE_STATE_LABEL, readinessChip, prefilledUrl, embedSnippet, STATUS_FILTER_LABEL, lowThisWeek, NO_FILTERS, lowScaleAtMost, dayLabel } from './chunk-HAEZ7G3G.js';
|
|
3
|
+
export { NO_FILTERS, RESPONSE_STATUS_LABEL, SAVE_STATE_LABEL, STATUS_FILTER_LABEL, answerCell, answerColumns, answersByKey, carryAnswers, comparisonFilter, dayLabel, dropOffByQuestion, embedSnippet, filterResponses, followUpOf, formAvailability, formCounts, formNavItems, formStatusChip, hasLowRating, hasLowRatingExcept, headlineCards, headlineNumbers, highestRating, isFiltered, isFull, lowRatingAtMost, lowRatingLabel, lowScaleAtMost, lowThisWeek, lowestRating, matchesStatus, needsFollowUp, parseInstant, plainLabel, prefilledUrl, presetRange, readinessChip, readinessOf, summarizeResponses, takesResponses, toCsv, toResponseFilter, valuesByKey } from './chunk-HAEZ7G3G.js';
|
|
4
4
|
import { StatusBadge, cn, Badge, Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbSeparator, BreadcrumbPage, Button, Separator, ToggleGroup, ToggleGroupItem, Skeleton, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Tabs, TabsList, TabsTrigger, TabsContent, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Label, Textarea, Input, EmptyState, toast } from '@marktiderman/genesis-ui';
|
|
5
|
-
import { Settings, Inbox, GitBranch, ListChecks, Check, Loader2, TriangleAlert, Undo2, Redo2, Eye, Share2, Rocket, CircleAlert, CircleCheck, Star, ExternalLink, Printer, Copy, CalendarDays, X, CircleDot, SquareCheck, Gauge, Type } from 'lucide-react';
|
|
5
|
+
import { Settings, Inbox, GitBranch, ListChecks, Check, Loader2, TriangleAlert, Undo2, Redo2, Eye, Share2, Rocket, CircleAlert, CircleCheck, Star, ExternalLink, Printer, Copy, CalendarDays, CircleDashed, X, CircleDot, SquareCheck, Gauge, Type, ChartNoAxesColumnDecreasing, ImageOff, Image } from 'lucide-react';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
7
|
import { useId, useState, useEffect } from 'react';
|
|
8
8
|
|
|
@@ -604,6 +604,7 @@ function ResponsesFilters({
|
|
|
604
604
|
choices = [],
|
|
605
605
|
ratingMax = null,
|
|
606
606
|
lowLabel = null,
|
|
607
|
+
statuses = false,
|
|
607
608
|
filtered
|
|
608
609
|
}) {
|
|
609
610
|
const ratings = ratingMax ? Array.from({ length: Math.min(ratingMax, 10) - 1 }, (_, i) => i + 1) : [];
|
|
@@ -640,6 +641,20 @@ function ResponsesFilters({
|
|
|
640
641
|
}
|
|
641
642
|
)
|
|
642
643
|
] }) : null,
|
|
644
|
+
statuses ? /* @__PURE__ */ jsxs(
|
|
645
|
+
Select,
|
|
646
|
+
{
|
|
647
|
+
value: value.status ?? "counted",
|
|
648
|
+
onValueChange: (status) => onChange({ ...value, status }),
|
|
649
|
+
children: [
|
|
650
|
+
/* @__PURE__ */ jsxs(SelectTrigger, { className: TRIGGER, "aria-label": "Status", "data-testid": "responses-status", children: [
|
|
651
|
+
/* @__PURE__ */ jsx(CircleDashed, { className: "size-4 text-muted-foreground", "aria-hidden": true }),
|
|
652
|
+
/* @__PURE__ */ jsx(SelectValue, {})
|
|
653
|
+
] }),
|
|
654
|
+
/* @__PURE__ */ jsx(SelectContent, { children: Object.keys(STATUS_FILTER_LABEL).map((s) => /* @__PURE__ */ jsx(SelectItem, { value: s, children: STATUS_FILTER_LABEL[s] }, s)) })
|
|
655
|
+
]
|
|
656
|
+
}
|
|
657
|
+
) : null,
|
|
643
658
|
choices.filter((c) => c.options.length > 0).map((c) => /* @__PURE__ */ jsxs(
|
|
644
659
|
Select,
|
|
645
660
|
{
|
|
@@ -879,7 +894,118 @@ function QuestionSummaryCards({
|
|
|
879
894
|
}
|
|
880
895
|
return /* @__PURE__ */ jsx("div", { className: cn("flex min-w-0 flex-col gap-3", className), children: summaries.map((s) => /* @__PURE__ */ jsx(QuestionSummaryCard, { summary: s, today, answerMeta }, s.key)) });
|
|
881
896
|
}
|
|
897
|
+
var plural2 = (n, one, many = `${one}s`) => `${n} ${n === 1 ? one : many}`;
|
|
898
|
+
function DropOffByQuestion({
|
|
899
|
+
dropOffs,
|
|
900
|
+
isLoading = false,
|
|
901
|
+
title = "Drop-off by question",
|
|
902
|
+
className
|
|
903
|
+
}) {
|
|
904
|
+
if (isLoading) return /* @__PURE__ */ jsx(Skeleton, { className: cn("h-40 w-full rounded-lg", className) });
|
|
905
|
+
const started = dropOffs[0]?.views ?? 0;
|
|
906
|
+
const worst = Math.max(0, ...dropOffs.map((d) => d.stopped));
|
|
907
|
+
return /* @__PURE__ */ jsx(
|
|
908
|
+
SummaryCard,
|
|
909
|
+
{
|
|
910
|
+
icon: /* @__PURE__ */ jsx(ChartNoAxesColumnDecreasing, {}),
|
|
911
|
+
title,
|
|
912
|
+
meta: started ? `${plural2(started, "person", "people")} started` : "Nobody has started yet",
|
|
913
|
+
className,
|
|
914
|
+
testID: "drop-off",
|
|
915
|
+
children: started ? /* @__PURE__ */ jsx("ol", { className: "space-y-3", children: dropOffs.map((d, i) => /* @__PURE__ */ jsxs("li", { className: "space-y-1.5 text-sm", "data-testid": `drop-off-${d.key}`, children: [
|
|
916
|
+
/* @__PURE__ */ jsxs("p", { className: "flex items-baseline justify-between gap-3", children: [
|
|
917
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0 break-words", children: [
|
|
918
|
+
/* @__PURE__ */ jsxs("span", { className: "text-muted-foreground tabular-nums", children: [
|
|
919
|
+
i + 1,
|
|
920
|
+
". "
|
|
921
|
+
] }),
|
|
922
|
+
d.label || "Untitled question"
|
|
923
|
+
] }),
|
|
924
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 whitespace-nowrap tabular-nums text-muted-foreground", children: d.dropOff === null ? "\u2013" : `${d.dropOff}% drop-off` })
|
|
925
|
+
] }),
|
|
926
|
+
/* @__PURE__ */ jsx("span", { className: "block h-2 overflow-hidden rounded-full bg-muted", "aria-hidden": true, children: /* @__PURE__ */ jsx(
|
|
927
|
+
"span",
|
|
928
|
+
{
|
|
929
|
+
className: cn(
|
|
930
|
+
"block h-full rounded-full",
|
|
931
|
+
d.stopped && d.stopped === worst ? "bg-warning" : "bg-primary"
|
|
932
|
+
),
|
|
933
|
+
style: { width: `${d.dropOff ?? 0}%` }
|
|
934
|
+
}
|
|
935
|
+
) }),
|
|
936
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
937
|
+
plural2(d.views, "view"),
|
|
938
|
+
" \xB7 ",
|
|
939
|
+
d.stopped,
|
|
940
|
+
" stopped here"
|
|
941
|
+
] })
|
|
942
|
+
] }, d.key)) }) : null
|
|
943
|
+
}
|
|
944
|
+
);
|
|
945
|
+
}
|
|
946
|
+
var UNDRAWABLE = /* @__PURE__ */ new Set(["image/heic", "image/heif"]);
|
|
947
|
+
function Photo({ photo, resolveUrl }) {
|
|
948
|
+
const [resolved, setResolved] = useState({ state: "loading" });
|
|
949
|
+
const [broken, setBroken] = useState(false);
|
|
950
|
+
useEffect(() => {
|
|
951
|
+
let live = true;
|
|
952
|
+
setResolved({ state: "loading" });
|
|
953
|
+
setBroken(false);
|
|
954
|
+
resolveUrl(photo).then((url) => live && setResolved(url ? { state: "ready", url } : { state: "missing" })).catch(() => live && setResolved({ state: "missing" }));
|
|
955
|
+
return () => {
|
|
956
|
+
live = false;
|
|
957
|
+
};
|
|
958
|
+
}, [photo.id]);
|
|
959
|
+
const tile = "relative size-28 overflow-hidden rounded-md border border-border bg-muted";
|
|
960
|
+
if (resolved.state === "loading") return /* @__PURE__ */ jsx(Skeleton, { className: "size-28 rounded-md", "aria-label": `Loading ${photo.name}` });
|
|
961
|
+
if (resolved.state === "missing") {
|
|
962
|
+
return /* @__PURE__ */ jsxs("div", { className: cn(tile, "flex flex-col items-center justify-center gap-1 p-2 text-center text-xs text-muted-foreground"), children: [
|
|
963
|
+
/* @__PURE__ */ jsx(ImageOff, { className: "size-5", "aria-hidden": "true" }),
|
|
964
|
+
/* @__PURE__ */ jsx("span", { children: "Photo unavailable" })
|
|
965
|
+
] });
|
|
966
|
+
}
|
|
967
|
+
if (broken || UNDRAWABLE.has(photo.type.toLowerCase())) {
|
|
968
|
+
return /* @__PURE__ */ jsxs("div", { className: cn(tile, "flex flex-col items-center justify-center gap-1 p-2 text-center text-xs"), children: [
|
|
969
|
+
/* @__PURE__ */ jsx(Image, { className: "size-5 text-muted-foreground", "aria-hidden": "true" }),
|
|
970
|
+
/* @__PURE__ */ jsx("span", { className: "line-clamp-2 break-all text-muted-foreground", children: photo.name }),
|
|
971
|
+
/* @__PURE__ */ jsxs(
|
|
972
|
+
"a",
|
|
973
|
+
{
|
|
974
|
+
href: resolved.url,
|
|
975
|
+
target: "_blank",
|
|
976
|
+
rel: "noreferrer",
|
|
977
|
+
className: "inline-flex items-center gap-1 font-medium text-primary underline-offset-4 hover:underline",
|
|
978
|
+
children: [
|
|
979
|
+
"Open ",
|
|
980
|
+
/* @__PURE__ */ jsx(ExternalLink, { className: "size-3", "aria-hidden": "true" }),
|
|
981
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: photo.name })
|
|
982
|
+
]
|
|
983
|
+
}
|
|
984
|
+
)
|
|
985
|
+
] });
|
|
986
|
+
}
|
|
987
|
+
return /* @__PURE__ */ jsx(
|
|
988
|
+
"a",
|
|
989
|
+
{
|
|
990
|
+
href: resolved.url,
|
|
991
|
+
target: "_blank",
|
|
992
|
+
rel: "noreferrer",
|
|
993
|
+
className: cn(tile, "block outline-none ring-offset-background focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"),
|
|
994
|
+
title: photo.name,
|
|
995
|
+
children: /* @__PURE__ */ jsx("img", { src: resolved.url, alt: photo.name, loading: "lazy", className: "size-full object-cover", onError: () => setBroken(true) })
|
|
996
|
+
}
|
|
997
|
+
);
|
|
998
|
+
}
|
|
999
|
+
function PhotoAnswer({
|
|
1000
|
+
photos,
|
|
1001
|
+
resolveUrl,
|
|
1002
|
+
className,
|
|
1003
|
+
testID
|
|
1004
|
+
}) {
|
|
1005
|
+
if (!photos.length) return null;
|
|
1006
|
+
return /* @__PURE__ */ jsx("ul", { className: cn("flex flex-wrap gap-3", className), "aria-label": "Photos", "data-testid": testID, children: photos.map((photo) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(Photo, { photo, resolveUrl }) }, photo.id)) });
|
|
1007
|
+
}
|
|
882
1008
|
|
|
883
|
-
export { Chip, FORM_NAV_ICONS, FollowUpList, HeadlineNumbers, QuestionSummaryCard, QuestionSummaryCards, ReadinessChip, ResourceHeader, ResourceSettingsPage, ResponsesFilters, ResponsesToolbar, SettingsSection, ShareDialog, SummaryCard };
|
|
1009
|
+
export { Chip, DropOffByQuestion, FORM_NAV_ICONS, FollowUpList, HeadlineNumbers, PhotoAnswer, QuestionSummaryCard, QuestionSummaryCards, ReadinessChip, ResourceHeader, ResourceSettingsPage, ResponsesFilters, ResponsesToolbar, SettingsSection, ShareDialog, SummaryCard };
|
|
884
1010
|
//# sourceMappingURL=index.js.map
|
|
885
1011
|
//# sourceMappingURL=index.js.map
|