@mieweb/ui 0.7.3-dev.19 → 0.7.3-dev.20
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/dist/brands/index.cjs +7 -7
- package/dist/brands/index.js +2 -2
- package/dist/{chunk-MPMVCAPI.js → chunk-3Z7CLG4U.js} +34 -2
- package/dist/chunk-3Z7CLG4U.js.map +1 -0
- package/dist/{chunk-Z4PECE5S.js → chunk-4PJ24GQ4.js} +2 -2
- package/dist/{chunk-Z4PECE5S.js.map → chunk-4PJ24GQ4.js.map} +1 -1
- package/dist/{chunk-2WLP2ERQ.js → chunk-5D253OQS.js} +3 -3
- package/dist/{chunk-2WLP2ERQ.js.map → chunk-5D253OQS.js.map} +1 -1
- package/dist/chunk-ELYGV32O.cjs +230 -0
- package/dist/chunk-ELYGV32O.cjs.map +1 -0
- package/dist/{chunk-RBEQQ4GG.cjs → chunk-JWTCEWQ4.cjs} +2 -2
- package/dist/{chunk-RBEQQ4GG.cjs.map → chunk-JWTCEWQ4.cjs.map} +1 -1
- package/dist/{chunk-LJBWCUKP.cjs → chunk-LGYGKLJL.cjs} +2 -2
- package/dist/{chunk-LJBWCUKP.cjs.map → chunk-LGYGKLJL.cjs.map} +1 -1
- package/dist/{chunk-DSSMQH74.js → chunk-TXRQQMG5.js} +2 -2
- package/dist/{chunk-DSSMQH74.js.map → chunk-TXRQQMG5.js.map} +1 -1
- package/dist/{chunk-CGVDGVZS.cjs → chunk-VNNFI5DQ.cjs} +34 -2
- package/dist/chunk-VNNFI5DQ.cjs.map +1 -0
- package/dist/{chunk-SETNPK4P.cjs → chunk-X5OS45WZ.cjs} +3 -3
- package/dist/{chunk-SETNPK4P.cjs.map → chunk-X5OS45WZ.cjs.map} +1 -1
- package/dist/chunk-XMECP2MD.js +208 -0
- package/dist/chunk-XMECP2MD.js.map +1 -0
- package/dist/components/Markdown/index.cjs +10 -10
- package/dist/components/Markdown/index.js +2 -2
- package/dist/components/SourceTip/index.cjs +15 -0
- package/dist/components/SourceTip/index.cjs.map +1 -0
- package/dist/components/SourceTip/index.d.cts +58 -0
- package/dist/components/SourceTip/index.d.ts +58 -0
- package/dist/components/SourceTip/index.js +6 -0
- package/dist/components/SourceTip/index.js.map +1 -0
- package/dist/esheet.cjs +5 -5
- package/dist/esheet.js +2 -2
- package/dist/index.cjs +59 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +10 -9
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/tailwind-preset.cjs +4 -4
- package/dist/tailwind-preset.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-CGVDGVZS.cjs.map +0 -1
- package/dist/chunk-MPMVCAPI.js.map +0 -1
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { useEscapeKey } from './chunk-T4ME7QCT.js';
|
|
2
|
+
import { useAnchoredPosition } from './chunk-BOOJDRJO.js';
|
|
3
|
+
import { cn } from './chunk-TQONQSJO.js';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import { createPortal } from 'react-dom';
|
|
6
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
var HIDE_GRACE_MS = 180;
|
|
9
|
+
function SourceTip({
|
|
10
|
+
heading,
|
|
11
|
+
note,
|
|
12
|
+
sources,
|
|
13
|
+
eyebrow = "Source",
|
|
14
|
+
children,
|
|
15
|
+
className,
|
|
16
|
+
underline = false
|
|
17
|
+
}) {
|
|
18
|
+
const [open, setOpen] = React.useState(false);
|
|
19
|
+
const [pinned, setPinned] = React.useState(false);
|
|
20
|
+
const timer = React.useRef(null);
|
|
21
|
+
const suppressFocusShow = React.useRef(false);
|
|
22
|
+
const { anchorRef, floatingRef, style } = useAnchoredPosition({
|
|
23
|
+
open,
|
|
24
|
+
placement: "top",
|
|
25
|
+
offset: 10,
|
|
26
|
+
viewportPadding: 8,
|
|
27
|
+
allowFlip: true
|
|
28
|
+
});
|
|
29
|
+
const clearHideTimer = () => {
|
|
30
|
+
if (timer.current) {
|
|
31
|
+
clearTimeout(timer.current);
|
|
32
|
+
timer.current = null;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const show = React.useCallback(() => {
|
|
36
|
+
clearHideTimer();
|
|
37
|
+
setOpen(true);
|
|
38
|
+
}, []);
|
|
39
|
+
const scheduleHide = React.useCallback(() => {
|
|
40
|
+
if (pinned) return;
|
|
41
|
+
clearHideTimer();
|
|
42
|
+
timer.current = setTimeout(() => setOpen(false), HIDE_GRACE_MS);
|
|
43
|
+
}, [pinned]);
|
|
44
|
+
const close = React.useCallback(() => {
|
|
45
|
+
clearHideTimer();
|
|
46
|
+
setPinned(false);
|
|
47
|
+
setOpen(false);
|
|
48
|
+
if (floatingRef.current?.contains(document.activeElement)) {
|
|
49
|
+
suppressFocusShow.current = true;
|
|
50
|
+
anchorRef.current?.focus();
|
|
51
|
+
}
|
|
52
|
+
}, [anchorRef, floatingRef]);
|
|
53
|
+
React.useEffect(() => () => clearHideTimer(), []);
|
|
54
|
+
React.useEffect(() => {
|
|
55
|
+
if (pinned) floatingRef.current?.focus();
|
|
56
|
+
}, [pinned, floatingRef]);
|
|
57
|
+
useEscapeKey(close, open);
|
|
58
|
+
React.useEffect(() => {
|
|
59
|
+
if (!open || !pinned) return;
|
|
60
|
+
const onPointer = (e) => {
|
|
61
|
+
const t = e.target;
|
|
62
|
+
if (anchorRef.current?.contains(t) || floatingRef.current?.contains(t))
|
|
63
|
+
return;
|
|
64
|
+
close();
|
|
65
|
+
};
|
|
66
|
+
document.addEventListener("mousedown", onPointer);
|
|
67
|
+
document.addEventListener("touchstart", onPointer);
|
|
68
|
+
return () => {
|
|
69
|
+
document.removeEventListener("mousedown", onPointer);
|
|
70
|
+
document.removeEventListener("touchstart", onPointer);
|
|
71
|
+
};
|
|
72
|
+
}, [open, pinned, close, anchorRef, floatingRef]);
|
|
73
|
+
const onTriggerClick = () => {
|
|
74
|
+
const coarse = typeof window !== "undefined" && window.matchMedia("(hover: none)").matches;
|
|
75
|
+
if (!coarse) return;
|
|
76
|
+
togglePin();
|
|
77
|
+
};
|
|
78
|
+
const togglePin = () => {
|
|
79
|
+
if (pinned) close();
|
|
80
|
+
else {
|
|
81
|
+
setPinned(true);
|
|
82
|
+
show();
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const onTriggerKeyDown = (e) => {
|
|
86
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
87
|
+
e.preventDefault();
|
|
88
|
+
togglePin();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const onDialogKeyDown = (e) => {
|
|
92
|
+
if (e.target !== e.currentTarget) return;
|
|
93
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
94
|
+
e.preventDefault();
|
|
95
|
+
close();
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const onTriggerFocus = () => {
|
|
99
|
+
if (suppressFocusShow.current) {
|
|
100
|
+
suppressFocusShow.current = false;
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
show();
|
|
104
|
+
};
|
|
105
|
+
const onBlurCapture = (e) => {
|
|
106
|
+
const next = e.relatedTarget;
|
|
107
|
+
if (next && (anchorRef.current?.contains(next) || floatingRef.current?.contains(next)))
|
|
108
|
+
return;
|
|
109
|
+
scheduleHide();
|
|
110
|
+
};
|
|
111
|
+
const hasSources = Boolean(sources && sources.length > 0);
|
|
112
|
+
return /* @__PURE__ */ jsxs(
|
|
113
|
+
"span",
|
|
114
|
+
{
|
|
115
|
+
ref: anchorRef,
|
|
116
|
+
className: cn(
|
|
117
|
+
"cursor-help",
|
|
118
|
+
underline && "decoration-primary-400/70 underline decoration-dashed underline-offset-4",
|
|
119
|
+
className
|
|
120
|
+
),
|
|
121
|
+
onMouseEnter: show,
|
|
122
|
+
onMouseLeave: scheduleHide,
|
|
123
|
+
onFocus: onTriggerFocus,
|
|
124
|
+
onBlur: onBlurCapture,
|
|
125
|
+
onClick: onTriggerClick,
|
|
126
|
+
onKeyDown: onTriggerKeyDown,
|
|
127
|
+
tabIndex: 0,
|
|
128
|
+
role: "button",
|
|
129
|
+
"aria-haspopup": "dialog",
|
|
130
|
+
"aria-expanded": open,
|
|
131
|
+
"aria-label": `${heading} \u2014 show source`,
|
|
132
|
+
children: [
|
|
133
|
+
children,
|
|
134
|
+
open && createPortal(
|
|
135
|
+
/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- keyboard dismissal on a focused non-modal dialog container is the WAI-ARIA pattern; links inside keep their own semantics */
|
|
136
|
+
/* @__PURE__ */ jsx(
|
|
137
|
+
"span",
|
|
138
|
+
{
|
|
139
|
+
ref: floatingRef,
|
|
140
|
+
role: "dialog",
|
|
141
|
+
"aria-label": heading,
|
|
142
|
+
tabIndex: -1,
|
|
143
|
+
onMouseEnter: show,
|
|
144
|
+
onMouseLeave: scheduleHide,
|
|
145
|
+
onBlurCapture,
|
|
146
|
+
onKeyDown: onDialogKeyDown,
|
|
147
|
+
className: "focus-visible:ring-ring z-50 block w-80 rounded-lg outline-none focus-visible:ring-2",
|
|
148
|
+
style,
|
|
149
|
+
children: /* @__PURE__ */ jsxs("span", { className: "border-border bg-card block overflow-hidden rounded-lg border text-start font-normal tracking-normal normal-case shadow-xl ring-1 ring-black/5 dark:ring-white/10", children: [
|
|
150
|
+
/* @__PURE__ */ jsxs("span", { className: "from-primary-700 to-primary-600 block bg-gradient-to-br px-3.5 py-2.5", children: [
|
|
151
|
+
/* @__PURE__ */ jsx("span", { className: "text-primary-100/90 block text-[10px] font-bold tracking-wide uppercase", children: eyebrow }),
|
|
152
|
+
/* @__PURE__ */ jsx("span", { className: "mt-0.5 block text-sm leading-snug font-semibold text-white", children: heading })
|
|
153
|
+
] }),
|
|
154
|
+
(note || hasSources) && /* @__PURE__ */ jsxs("span", { className: "block px-3.5 py-2.5", children: [
|
|
155
|
+
note && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground block text-[13px] leading-relaxed", children: note }),
|
|
156
|
+
hasSources && /* @__PURE__ */ jsxs(
|
|
157
|
+
"span",
|
|
158
|
+
{
|
|
159
|
+
className: cn(
|
|
160
|
+
"block",
|
|
161
|
+
note && "border-border mt-2.5 border-t border-dashed pt-2.5"
|
|
162
|
+
),
|
|
163
|
+
children: [
|
|
164
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground block text-[10px] font-bold tracking-wide uppercase", children: sources.length === 1 ? "Source" : `${sources.length} sources` }),
|
|
165
|
+
/* @__PURE__ */ jsx("span", { className: "block max-h-52 overflow-y-auto", children: sources.map((s, i) => /* @__PURE__ */ jsxs(
|
|
166
|
+
"span",
|
|
167
|
+
{
|
|
168
|
+
className: "mt-1.5 flex items-center gap-2",
|
|
169
|
+
children: [
|
|
170
|
+
/* @__PURE__ */ jsx(
|
|
171
|
+
"span",
|
|
172
|
+
{
|
|
173
|
+
"aria-hidden": "true",
|
|
174
|
+
className: "bg-primary-400 h-1.5 w-1.5 shrink-0 rounded-full"
|
|
175
|
+
}
|
|
176
|
+
),
|
|
177
|
+
s.url ? /* @__PURE__ */ jsx(
|
|
178
|
+
"a",
|
|
179
|
+
{
|
|
180
|
+
href: s.url,
|
|
181
|
+
target: "_blank",
|
|
182
|
+
rel: "noopener noreferrer",
|
|
183
|
+
className: "text-primary-600 hover:text-primary-500 dark:text-primary-400 dark:hover:text-primary-300 min-w-0 flex-1 truncate text-xs font-semibold",
|
|
184
|
+
children: s.label
|
|
185
|
+
}
|
|
186
|
+
) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground min-w-0 flex-1 truncate text-xs", children: s.label }),
|
|
187
|
+
s.sub && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/70 shrink-0 text-[11px]", children: s.sub })
|
|
188
|
+
]
|
|
189
|
+
},
|
|
190
|
+
`${s.label}-${i}`
|
|
191
|
+
)) })
|
|
192
|
+
]
|
|
193
|
+
}
|
|
194
|
+
)
|
|
195
|
+
] })
|
|
196
|
+
] })
|
|
197
|
+
}
|
|
198
|
+
),
|
|
199
|
+
document.body
|
|
200
|
+
)
|
|
201
|
+
]
|
|
202
|
+
}
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export { SourceTip };
|
|
207
|
+
//# sourceMappingURL=chunk-XMECP2MD.js.map
|
|
208
|
+
//# sourceMappingURL=chunk-XMECP2MD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/SourceTip/SourceTip.tsx"],"names":[],"mappings":"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","file":"chunk-XMECP2MD.js","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { createPortal } from 'react-dom';\nimport { cn } from '../../utils/cn';\nimport { useAnchoredPosition } from '../../hooks/useAnchoredPosition';\nimport { useEscapeKey } from '../../hooks/useEscapeKey';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/** One line of provenance shown in the card. */\nexport interface TipSource {\n /** One-line label — statute name or source title. Truncated on render. */\n label: string;\n /** Source URL. Omit for a provenance line that isn't linkable. */\n url?: string;\n /** Secondary label shown at the end (publisher / host / year). */\n sub?: string;\n}\n\nexport interface SourceTipProps {\n /** The claim this card explains — the card's heading. */\n heading: string;\n /** Free-text provenance, for facts no public URL can verify. */\n note?: string;\n /** Linked (or unlinked) one-line sources. */\n sources?: TipSource[];\n /** Eyebrow above the heading. Defaults to \"Source\". */\n eyebrow?: string;\n /** The visible trigger. */\n children: React.ReactNode;\n className?: string;\n /**\n * Underline the trigger with a dashed rule marking a hoverable claim.\n * Leave off in table cells, which signal hoverability by their own\n * treatment rather than by underlining every cell.\n */\n underline?: boolean;\n}\n\nconst HIDE_GRACE_MS = 180;\n\n// =============================================================================\n// SourceTip\n// =============================================================================\n\n/**\n * A hover card answering \"what backs this claim?\" — an eyebrow + heading,\n * optional free-text provenance, and a list of one-line source links.\n * Suits stat tiles, table cells, and inline facts where a numbered footnote\n * would be overkill.\n *\n * The trigger and card are phrasing content (`span`/`a` only), so it is\n * valid inside `<p>` prose and table cells. The card portals to `body` with\n * fixed positioning, flipping and clamping to stay in the viewport. On\n * touch, a tap pins the card; Escape or an outside tap closes it. A pinned\n * card behaves as a non-modal dialog — focus moves into it so its source\n * links are keyboard-reachable, and returns to the trigger on close.\n *\n * @example\n * ```tsx\n * <SourceTip\n * heading=\"OSHA recordable rate\"\n * sources={[{ label: 'BLS SOII 2023', url: 'https://www.bls.gov/iif/', sub: 'BLS' }]}\n * underline\n * >\n * 2.4 per 100 FTE\n * </SourceTip>\n * ```\n */\nexport function SourceTip({\n heading,\n note,\n sources,\n eyebrow = 'Source',\n children,\n className,\n underline = false,\n}: SourceTipProps) {\n const [open, setOpen] = React.useState(false);\n const [pinned, setPinned] = React.useState(false);\n const timer = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n // True while close() restores focus to the trigger, so the trigger's\n // focus-show doesn't immediately reopen a card the user just dismissed.\n const suppressFocusShow = React.useRef(false);\n\n const { anchorRef, floatingRef, style } = useAnchoredPosition<\n HTMLSpanElement,\n HTMLSpanElement\n >({\n open,\n placement: 'top',\n offset: 10,\n viewportPadding: 8,\n allowFlip: true,\n });\n\n const clearHideTimer = () => {\n if (timer.current) {\n clearTimeout(timer.current);\n timer.current = null;\n }\n };\n\n const show = React.useCallback(() => {\n clearHideTimer();\n setOpen(true);\n }, []);\n\n const scheduleHide = React.useCallback(() => {\n if (pinned) return;\n clearHideTimer();\n timer.current = setTimeout(() => setOpen(false), HIDE_GRACE_MS);\n }, [pinned]);\n\n const close = React.useCallback(() => {\n clearHideTimer();\n setPinned(false);\n setOpen(false);\n // Return focus to the trigger if it was inside the card.\n if (floatingRef.current?.contains(document.activeElement)) {\n suppressFocusShow.current = true;\n anchorRef.current?.focus();\n }\n }, [anchorRef, floatingRef]);\n\n React.useEffect(() => () => clearHideTimer(), []);\n\n // A pinned card is a non-modal dialog: move focus into it so its links\n // are reachable by keyboard.\n React.useEffect(() => {\n if (pinned) floatingRef.current?.focus();\n }, [pinned, floatingRef]);\n\n useEscapeKey(close, open);\n\n // Pinned cards close on an outside tap; hover cards close on their own.\n React.useEffect(() => {\n if (!open || !pinned) return;\n const onPointer = (e: Event) => {\n const t = e.target as Node;\n if (anchorRef.current?.contains(t) || floatingRef.current?.contains(t))\n return;\n close();\n };\n document.addEventListener('mousedown', onPointer);\n document.addEventListener('touchstart', onPointer);\n return () => {\n document.removeEventListener('mousedown', onPointer);\n document.removeEventListener('touchstart', onPointer);\n };\n }, [open, pinned, close, anchorRef, floatingRef]);\n\n // Touch has no hover: tap pins the card instead of falling through.\n const onTriggerClick = () => {\n const coarse =\n typeof window !== 'undefined' &&\n window.matchMedia('(hover: none)').matches;\n if (!coarse) return;\n togglePin();\n };\n\n const togglePin = () => {\n if (pinned) close();\n else {\n setPinned(true);\n show();\n }\n };\n\n const onTriggerKeyDown = (e: React.KeyboardEvent<HTMLSpanElement>) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n togglePin();\n }\n };\n\n // Focus lives on the dialog container once pinned, so Enter/Space there\n // (not on a link inside) must also unpin — the trigger no longer has focus.\n const onDialogKeyDown = (e: React.KeyboardEvent<HTMLSpanElement>) => {\n if (e.target !== e.currentTarget) return;\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n close();\n }\n };\n\n const onTriggerFocus = () => {\n if (suppressFocusShow.current) {\n suppressFocusShow.current = false;\n return;\n }\n show();\n };\n\n const onBlurCapture = (e: React.FocusEvent<HTMLSpanElement>) => {\n const next = e.relatedTarget as Node | null;\n if (\n next &&\n (anchorRef.current?.contains(next) || floatingRef.current?.contains(next))\n )\n return;\n scheduleHide();\n };\n\n const hasSources = Boolean(sources && sources.length > 0);\n\n return (\n <span\n ref={anchorRef}\n className={cn(\n 'cursor-help',\n underline &&\n 'decoration-primary-400/70 underline decoration-dashed underline-offset-4',\n className\n )}\n onMouseEnter={show}\n onMouseLeave={scheduleHide}\n onFocus={onTriggerFocus}\n onBlur={onBlurCapture}\n onClick={onTriggerClick}\n onKeyDown={onTriggerKeyDown}\n tabIndex={0}\n role=\"button\"\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n aria-label={`${heading} — show source`}\n >\n {children}\n {open &&\n createPortal(\n /* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- keyboard dismissal on a focused non-modal dialog container is the WAI-ARIA pattern; links inside keep their own semantics */\n <span\n ref={floatingRef}\n role=\"dialog\"\n aria-label={heading}\n tabIndex={-1}\n onMouseEnter={show}\n onMouseLeave={scheduleHide}\n onBlurCapture={onBlurCapture}\n onKeyDown={onDialogKeyDown}\n className=\"focus-visible:ring-ring z-50 block w-80 rounded-lg outline-none focus-visible:ring-2\"\n style={style}\n >\n <span className=\"border-border bg-card block overflow-hidden rounded-lg border text-start font-normal tracking-normal normal-case shadow-xl ring-1 ring-black/5 dark:ring-white/10\">\n <span className=\"from-primary-700 to-primary-600 block bg-gradient-to-br px-3.5 py-2.5\">\n <span className=\"text-primary-100/90 block text-[10px] font-bold tracking-wide uppercase\">\n {eyebrow}\n </span>\n <span className=\"mt-0.5 block text-sm leading-snug font-semibold text-white\">\n {heading}\n </span>\n </span>\n\n {(note || hasSources) && (\n <span className=\"block px-3.5 py-2.5\">\n {note && (\n <span className=\"text-muted-foreground block text-[13px] leading-relaxed\">\n {note}\n </span>\n )}\n {hasSources && (\n <span\n className={cn(\n 'block',\n note &&\n 'border-border mt-2.5 border-t border-dashed pt-2.5'\n )}\n >\n <span className=\"text-muted-foreground block text-[10px] font-bold tracking-wide uppercase\">\n {sources!.length === 1\n ? 'Source'\n : `${sources!.length} sources`}\n </span>\n <span className=\"block max-h-52 overflow-y-auto\">\n {sources!.map((s, i) => (\n <span\n key={`${s.label}-${i}`}\n className=\"mt-1.5 flex items-center gap-2\"\n >\n <span\n aria-hidden=\"true\"\n className=\"bg-primary-400 h-1.5 w-1.5 shrink-0 rounded-full\"\n />\n {s.url ? (\n <a\n href={s.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary-600 hover:text-primary-500 dark:text-primary-400 dark:hover:text-primary-300 min-w-0 flex-1 truncate text-xs font-semibold\"\n >\n {s.label}\n </a>\n ) : (\n <span className=\"text-muted-foreground min-w-0 flex-1 truncate text-xs\">\n {s.label}\n </span>\n )}\n {s.sub && (\n <span className=\"text-muted-foreground/70 shrink-0 text-[11px]\">\n {s.sub}\n </span>\n )}\n </span>\n ))}\n </span>\n </span>\n )}\n </span>\n )}\n </span>\n </span>,\n document.body\n )}\n </span>\n );\n}\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkLGYGKLJL_cjs = require('../../chunk-LGYGKLJL.cjs');
|
|
4
|
+
var chunk4CUFXCC5_cjs = require('../../chunk-4CUFXCC5.cjs');
|
|
4
5
|
var chunkK4S4FAYX_cjs = require('../../chunk-K4S4FAYX.cjs');
|
|
5
6
|
var chunkFN6VHMLM_cjs = require('../../chunk-FN6VHMLM.cjs');
|
|
6
7
|
var chunkP3JEMF6E_cjs = require('../../chunk-P3JEMF6E.cjs');
|
|
7
|
-
var chunk4CUFXCC5_cjs = require('../../chunk-4CUFXCC5.cjs');
|
|
8
8
|
var chunkYIXTGWT4_cjs = require('../../chunk-YIXTGWT4.cjs');
|
|
9
9
|
require('../../chunk-RDGRKYQ5.cjs');
|
|
10
10
|
require('../../chunk-S5RVSXDV.cjs');
|
|
@@ -13,19 +13,23 @@ require('../../chunk-S5RVSXDV.cjs');
|
|
|
13
13
|
|
|
14
14
|
Object.defineProperty(exports, "CodeBlock", {
|
|
15
15
|
enumerable: true,
|
|
16
|
-
get: function () { return
|
|
16
|
+
get: function () { return chunkLGYGKLJL_cjs.CodeBlock; }
|
|
17
17
|
});
|
|
18
18
|
Object.defineProperty(exports, "MarkdownRenderer", {
|
|
19
19
|
enumerable: true,
|
|
20
|
-
get: function () { return
|
|
20
|
+
get: function () { return chunkLGYGKLJL_cjs.MarkdownRenderer; }
|
|
21
21
|
});
|
|
22
22
|
Object.defineProperty(exports, "highlightCode", {
|
|
23
23
|
enumerable: true,
|
|
24
|
-
get: function () { return
|
|
24
|
+
get: function () { return chunkLGYGKLJL_cjs.highlightCode; }
|
|
25
25
|
});
|
|
26
26
|
Object.defineProperty(exports, "useMarkdown", {
|
|
27
27
|
enumerable: true,
|
|
28
|
-
get: function () { return
|
|
28
|
+
get: function () { return chunkLGYGKLJL_cjs.useMarkdown; }
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(exports, "SurveyBlock", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () { return chunk4CUFXCC5_cjs.SurveyBlock; }
|
|
29
33
|
});
|
|
30
34
|
Object.defineProperty(exports, "CsvBlock", {
|
|
31
35
|
enumerable: true,
|
|
@@ -39,10 +43,6 @@ Object.defineProperty(exports, "MermaidBlock", {
|
|
|
39
43
|
enumerable: true,
|
|
40
44
|
get: function () { return chunkP3JEMF6E_cjs.MermaidBlock; }
|
|
41
45
|
});
|
|
42
|
-
Object.defineProperty(exports, "SurveyBlock", {
|
|
43
|
-
enumerable: true,
|
|
44
|
-
get: function () { return chunk4CUFXCC5_cjs.SurveyBlock; }
|
|
45
|
-
});
|
|
46
46
|
Object.defineProperty(exports, "FenceBlock", {
|
|
47
47
|
enumerable: true,
|
|
48
48
|
get: function () { return chunkYIXTGWT4_cjs.FenceBlock; }
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { CodeBlock, MarkdownRenderer, highlightCode, useMarkdown } from '../../chunk-
|
|
1
|
+
export { CodeBlock, MarkdownRenderer, highlightCode, useMarkdown } from '../../chunk-4PJ24GQ4.js';
|
|
2
|
+
export { SurveyBlock } from '../../chunk-DWCYEPTT.js';
|
|
2
3
|
export { CsvBlock } from '../../chunk-5J5PEUUA.js';
|
|
3
4
|
export { HtmlPreviewBlock } from '../../chunk-UZ5NGGMI.js';
|
|
4
5
|
export { MermaidBlock } from '../../chunk-EHQ77LL5.js';
|
|
5
|
-
export { SurveyBlock } from '../../chunk-DWCYEPTT.js';
|
|
6
6
|
export { FenceBlock } from '../../chunk-NLBT5O2X.js';
|
|
7
7
|
import '../../chunk-D2GID3YK.js';
|
|
8
8
|
import '../../chunk-TQONQSJO.js';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkELYGV32O_cjs = require('../../chunk-ELYGV32O.cjs');
|
|
4
|
+
require('../../chunk-FHY3K6PL.cjs');
|
|
5
|
+
require('../../chunk-MYFZYUPR.cjs');
|
|
6
|
+
require('../../chunk-S5RVSXDV.cjs');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
Object.defineProperty(exports, "SourceTip", {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function () { return chunkELYGV32O_cjs.SourceTip; }
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=index.cjs.map
|
|
15
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
/** One line of provenance shown in the card. */
|
|
5
|
+
interface TipSource {
|
|
6
|
+
/** One-line label — statute name or source title. Truncated on render. */
|
|
7
|
+
label: string;
|
|
8
|
+
/** Source URL. Omit for a provenance line that isn't linkable. */
|
|
9
|
+
url?: string;
|
|
10
|
+
/** Secondary label shown at the end (publisher / host / year). */
|
|
11
|
+
sub?: string;
|
|
12
|
+
}
|
|
13
|
+
interface SourceTipProps {
|
|
14
|
+
/** The claim this card explains — the card's heading. */
|
|
15
|
+
heading: string;
|
|
16
|
+
/** Free-text provenance, for facts no public URL can verify. */
|
|
17
|
+
note?: string;
|
|
18
|
+
/** Linked (or unlinked) one-line sources. */
|
|
19
|
+
sources?: TipSource[];
|
|
20
|
+
/** Eyebrow above the heading. Defaults to "Source". */
|
|
21
|
+
eyebrow?: string;
|
|
22
|
+
/** The visible trigger. */
|
|
23
|
+
children: React.ReactNode;
|
|
24
|
+
className?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Underline the trigger with a dashed rule marking a hoverable claim.
|
|
27
|
+
* Leave off in table cells, which signal hoverability by their own
|
|
28
|
+
* treatment rather than by underlining every cell.
|
|
29
|
+
*/
|
|
30
|
+
underline?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A hover card answering "what backs this claim?" — an eyebrow + heading,
|
|
34
|
+
* optional free-text provenance, and a list of one-line source links.
|
|
35
|
+
* Suits stat tiles, table cells, and inline facts where a numbered footnote
|
|
36
|
+
* would be overkill.
|
|
37
|
+
*
|
|
38
|
+
* The trigger and card are phrasing content (`span`/`a` only), so it is
|
|
39
|
+
* valid inside `<p>` prose and table cells. The card portals to `body` with
|
|
40
|
+
* fixed positioning, flipping and clamping to stay in the viewport. On
|
|
41
|
+
* touch, a tap pins the card; Escape or an outside tap closes it. A pinned
|
|
42
|
+
* card behaves as a non-modal dialog — focus moves into it so its source
|
|
43
|
+
* links are keyboard-reachable, and returns to the trigger on close.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```tsx
|
|
47
|
+
* <SourceTip
|
|
48
|
+
* heading="OSHA recordable rate"
|
|
49
|
+
* sources={[{ label: 'BLS SOII 2023', url: 'https://www.bls.gov/iif/', sub: 'BLS' }]}
|
|
50
|
+
* underline
|
|
51
|
+
* >
|
|
52
|
+
* 2.4 per 100 FTE
|
|
53
|
+
* </SourceTip>
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
declare function SourceTip({ heading, note, sources, eyebrow, children, className, underline, }: SourceTipProps): react_jsx_runtime.JSX.Element;
|
|
57
|
+
|
|
58
|
+
export { SourceTip, type SourceTipProps, type TipSource };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
/** One line of provenance shown in the card. */
|
|
5
|
+
interface TipSource {
|
|
6
|
+
/** One-line label — statute name or source title. Truncated on render. */
|
|
7
|
+
label: string;
|
|
8
|
+
/** Source URL. Omit for a provenance line that isn't linkable. */
|
|
9
|
+
url?: string;
|
|
10
|
+
/** Secondary label shown at the end (publisher / host / year). */
|
|
11
|
+
sub?: string;
|
|
12
|
+
}
|
|
13
|
+
interface SourceTipProps {
|
|
14
|
+
/** The claim this card explains — the card's heading. */
|
|
15
|
+
heading: string;
|
|
16
|
+
/** Free-text provenance, for facts no public URL can verify. */
|
|
17
|
+
note?: string;
|
|
18
|
+
/** Linked (or unlinked) one-line sources. */
|
|
19
|
+
sources?: TipSource[];
|
|
20
|
+
/** Eyebrow above the heading. Defaults to "Source". */
|
|
21
|
+
eyebrow?: string;
|
|
22
|
+
/** The visible trigger. */
|
|
23
|
+
children: React.ReactNode;
|
|
24
|
+
className?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Underline the trigger with a dashed rule marking a hoverable claim.
|
|
27
|
+
* Leave off in table cells, which signal hoverability by their own
|
|
28
|
+
* treatment rather than by underlining every cell.
|
|
29
|
+
*/
|
|
30
|
+
underline?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A hover card answering "what backs this claim?" — an eyebrow + heading,
|
|
34
|
+
* optional free-text provenance, and a list of one-line source links.
|
|
35
|
+
* Suits stat tiles, table cells, and inline facts where a numbered footnote
|
|
36
|
+
* would be overkill.
|
|
37
|
+
*
|
|
38
|
+
* The trigger and card are phrasing content (`span`/`a` only), so it is
|
|
39
|
+
* valid inside `<p>` prose and table cells. The card portals to `body` with
|
|
40
|
+
* fixed positioning, flipping and clamping to stay in the viewport. On
|
|
41
|
+
* touch, a tap pins the card; Escape or an outside tap closes it. A pinned
|
|
42
|
+
* card behaves as a non-modal dialog — focus moves into it so its source
|
|
43
|
+
* links are keyboard-reachable, and returns to the trigger on close.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```tsx
|
|
47
|
+
* <SourceTip
|
|
48
|
+
* heading="OSHA recordable rate"
|
|
49
|
+
* sources={[{ label: 'BLS SOII 2023', url: 'https://www.bls.gov/iif/', sub: 'BLS' }]}
|
|
50
|
+
* underline
|
|
51
|
+
* >
|
|
52
|
+
* 2.4 per 100 FTE
|
|
53
|
+
* </SourceTip>
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
declare function SourceTip({ heading, note, sources, eyebrow, children, className, underline, }: SourceTipProps): react_jsx_runtime.JSX.Element;
|
|
57
|
+
|
|
58
|
+
export { SourceTip, type SourceTipProps, type TipSource };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
package/dist/esheet.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('./chunk-WWJIW2IH.cjs');
|
|
3
|
+
var chunkX5OS45WZ_cjs = require('./chunk-X5OS45WZ.cjs');
|
|
5
4
|
require('./chunk-BSDBI6H7.cjs');
|
|
5
|
+
require('./chunk-WWJIW2IH.cjs');
|
|
6
6
|
require('./chunk-G7EQ3JPX.cjs');
|
|
7
7
|
require('./chunk-U5TTXN45.cjs');
|
|
8
8
|
require('./chunk-AIJAFPGJ.cjs');
|
|
@@ -78,7 +78,7 @@ function MedicationListField({
|
|
|
78
78
|
return definition.medications ?? [];
|
|
79
79
|
}, [response?.answer, definition.medications]);
|
|
80
80
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
81
|
-
|
|
81
|
+
chunkX5OS45WZ_cjs.MedicationReconciliation,
|
|
82
82
|
{
|
|
83
83
|
medications,
|
|
84
84
|
onChange: (next) => onResponse({ answer: JSON.stringify({ medications: next }) }),
|
|
@@ -135,7 +135,7 @@ function AllergyListField({
|
|
|
135
135
|
codeLookup
|
|
136
136
|
}) {
|
|
137
137
|
const definition = field.definition;
|
|
138
|
-
const ambientCodeLookup =
|
|
138
|
+
const ambientCodeLookup = chunkX5OS45WZ_cjs.useCodeLookupConfig();
|
|
139
139
|
const effectiveCodeLookup = codeLookup === false ? void 0 : codeLookup ?? ambientCodeLookup ?? void 0;
|
|
140
140
|
const value = React__namespace.useMemo(() => {
|
|
141
141
|
if (response?.answer) return parseValue2(response.answer);
|
|
@@ -145,7 +145,7 @@ function AllergyListField({
|
|
|
145
145
|
onResponse({ answer: JSON.stringify(next) });
|
|
146
146
|
};
|
|
147
147
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
148
|
-
|
|
148
|
+
chunkX5OS45WZ_cjs.AllergyManager,
|
|
149
149
|
{
|
|
150
150
|
allergies: value.allergies,
|
|
151
151
|
onChange: (allergies) => commit({
|
package/dist/esheet.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { MedicationReconciliation, useCodeLookupConfig, AllergyManager } from './chunk-
|
|
2
|
-
import './chunk-FJ7YPVKV.js';
|
|
1
|
+
import { MedicationReconciliation, useCodeLookupConfig, AllergyManager } from './chunk-5D253OQS.js';
|
|
3
2
|
import './chunk-H3YO5GBM.js';
|
|
3
|
+
import './chunk-FJ7YPVKV.js';
|
|
4
4
|
import './chunk-EPSB4WTL.js';
|
|
5
5
|
import './chunk-IILJGFI5.js';
|
|
6
6
|
import './chunk-I3WGZPI6.js';
|