@mieweb/ui 0.7.0 → 0.7.1
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/CsvBlock-2A5VEDD3.cjs +15 -0
- package/dist/{CsvBlock-7K6XVRYO.cjs.map → CsvBlock-2A5VEDD3.cjs.map} +1 -1
- package/dist/CsvBlock-D6PWAJ5X.js +6 -0
- package/dist/{CsvBlock-AAV4QMSF.js.map → CsvBlock-D6PWAJ5X.js.map} +1 -1
- package/dist/HtmlPreviewBlock-PEHTJ6C3.js +6 -0
- package/dist/{HtmlPreviewBlock-DNINC7RW.js.map → HtmlPreviewBlock-PEHTJ6C3.js.map} +1 -1
- package/dist/HtmlPreviewBlock-SYXCV5RH.cjs +15 -0
- package/dist/{HtmlPreviewBlock-74XQF3KT.cjs.map → HtmlPreviewBlock-SYXCV5RH.cjs.map} +1 -1
- package/dist/MermaidBlock-7NK3AVK2.js +6 -0
- package/dist/{MermaidBlock-PKXGFGU6.js.map → MermaidBlock-7NK3AVK2.js.map} +1 -1
- package/dist/MermaidBlock-AFXNP5NK.cjs +15 -0
- package/dist/{MermaidBlock-R4U7IHSZ.cjs.map → MermaidBlock-AFXNP5NK.cjs.map} +1 -1
- package/dist/SurveyBlock-6KRNKFH5.cjs +15 -0
- package/dist/{SurveyBlock-E52I4PW3.cjs.map → SurveyBlock-6KRNKFH5.cjs.map} +1 -1
- package/dist/SurveyBlock-NNDGXGG4.js +6 -0
- package/dist/{SurveyBlock-IULSBG22.js.map → SurveyBlock-NNDGXGG4.js.map} +1 -1
- package/dist/chunk-6CGM5H4J.js +17 -0
- package/dist/chunk-6CGM5H4J.js.map +1 -0
- package/dist/{chunk-HRS6W74P.js → chunk-6D5F7EDM.js} +3 -3
- package/dist/{chunk-HRS6W74P.js.map → chunk-6D5F7EDM.js.map} +1 -1
- package/dist/{chunk-NAQ3ZALI.cjs → chunk-7VF6WO7H.cjs} +32 -16
- package/dist/chunk-7VF6WO7H.cjs.map +1 -0
- package/dist/{chunk-FGIIXD37.js → chunk-7WMSUXOQ.js} +3 -3
- package/dist/{chunk-FGIIXD37.js.map → chunk-7WMSUXOQ.js.map} +1 -1
- package/dist/{chunk-74NOFB34.cjs → chunk-BB4WQ4LV.cjs} +4 -4
- package/dist/{chunk-74NOFB34.cjs.map → chunk-BB4WQ4LV.cjs.map} +1 -1
- package/dist/{chunk-YD23ZGRU.cjs → chunk-BYUV3IZV.cjs} +16 -4
- package/dist/chunk-BYUV3IZV.cjs.map +1 -0
- package/dist/{chunk-UL3PQ7HL.cjs → chunk-CKD554XR.cjs} +12 -3
- package/dist/chunk-CKD554XR.cjs.map +1 -0
- package/dist/{chunk-FZQAF3WA.cjs → chunk-CVC4NWFA.cjs} +4 -4
- package/dist/{chunk-FZQAF3WA.cjs.map → chunk-CVC4NWFA.cjs.map} +1 -1
- package/dist/{chunk-UO3KEUYK.cjs → chunk-DG7KE4YJ.cjs} +3 -3
- package/dist/chunk-DG7KE4YJ.cjs.map +1 -0
- package/dist/{chunk-Y4ESBDQ5.cjs → chunk-FCBQP2U4.cjs} +36 -38
- package/dist/chunk-FCBQP2U4.cjs.map +1 -0
- package/dist/{chunk-CPJIOOBM.js → chunk-I2W24RHW.js} +3 -3
- package/dist/{chunk-CPJIOOBM.js.map → chunk-I2W24RHW.js.map} +1 -1
- package/dist/{chunk-LIH3IZYK.js → chunk-IHTRKWBG.js} +121 -42
- package/dist/chunk-IHTRKWBG.js.map +1 -0
- package/dist/{chunk-Y65SK5Y2.cjs → chunk-JCNPVK74.cjs} +21 -12
- package/dist/chunk-JCNPVK74.cjs.map +1 -0
- package/dist/{chunk-6RV7HQ4U.cjs → chunk-KBEKQMVY.cjs} +5 -5
- package/dist/{chunk-6RV7HQ4U.cjs.map → chunk-KBEKQMVY.cjs.map} +1 -1
- package/dist/{chunk-FGP64Z24.js → chunk-KOCTIB6U.js} +16 -4
- package/dist/chunk-KOCTIB6U.js.map +1 -0
- package/dist/{chunk-3TERETXH.js → chunk-LJ2ZWIX6.js} +28 -2
- package/dist/chunk-LJ2ZWIX6.js.map +1 -0
- package/dist/{chunk-35VBGVMB.js → chunk-MCCO4A23.js} +24 -8
- package/dist/chunk-MCCO4A23.js.map +1 -0
- package/dist/chunk-NUFUV43P.cjs +20 -0
- package/dist/chunk-NUFUV43P.cjs.map +1 -0
- package/dist/{chunk-NTYGCBCL.js → chunk-OOYEHBYJ.js} +36 -38
- package/dist/chunk-OOYEHBYJ.js.map +1 -0
- package/dist/{chunk-JQEY53SH.cjs → chunk-PFWHWIXS.cjs} +28 -2
- package/dist/chunk-PFWHWIXS.cjs.map +1 -0
- package/dist/{chunk-JTBQNOSL.cjs → chunk-PWHK7SWN.cjs} +6 -6
- package/dist/{chunk-JTBQNOSL.cjs.map → chunk-PWHK7SWN.cjs.map} +1 -1
- package/dist/{chunk-JC6Y3LGF.cjs → chunk-QUUFKGDF.cjs} +120 -41
- package/dist/chunk-QUUFKGDF.cjs.map +1 -0
- package/dist/{chunk-MHJMUKLA.js → chunk-RHYIFIT5.js} +12 -3
- package/dist/chunk-RHYIFIT5.js.map +1 -0
- package/dist/{chunk-FIWKHLWY.js → chunk-SEPYBAML.js} +3 -3
- package/dist/chunk-SEPYBAML.js.map +1 -0
- package/dist/{chunk-WGC3KOP7.js → chunk-T3RWXOCM.js} +3 -3
- package/dist/{chunk-WGC3KOP7.js.map → chunk-T3RWXOCM.js.map} +1 -1
- package/dist/{chunk-NCRYCG5G.js → chunk-UFYXU7KV.js} +3 -3
- package/dist/{chunk-NCRYCG5G.js.map → chunk-UFYXU7KV.js.map} +1 -1
- package/dist/{chunk-VO3NWSCQ.cjs → chunk-V25Z5GR6.cjs} +7 -7
- package/dist/{chunk-VO3NWSCQ.cjs.map → chunk-V25Z5GR6.cjs.map} +1 -1
- package/dist/{chunk-NSLR3B7K.js → chunk-XL7TTKHP.js} +21 -12
- package/dist/chunk-XL7TTKHP.js.map +1 -0
- package/dist/components/DateInput/index.cjs +3 -2
- package/dist/components/DateInput/index.d.cts +4 -0
- package/dist/components/DateInput/index.d.ts +4 -0
- package/dist/components/DateInput/index.js +2 -1
- package/dist/components/Markdown/index.cjs +15 -15
- package/dist/components/Markdown/index.css +1 -1
- package/dist/components/Markdown/index.css.map +1 -1
- package/dist/components/Markdown/index.js +6 -6
- package/dist/components/Markdown/styles.css +4 -1
- package/dist/components/MediaEditor/index.cjs +9 -9
- package/dist/components/MediaEditor/index.d.cts +2 -2
- package/dist/components/MediaEditor/index.d.ts +2 -2
- package/dist/components/MediaEditor/index.js +4 -4
- package/dist/components/MediaPlayer/index.cjs +4 -4
- package/dist/components/MediaPlayer/index.js +1 -1
- package/dist/components/SuperChat/plugins/index.cjs +3 -0
- package/dist/components/SuperChat/plugins/index.cjs.map +1 -1
- package/dist/components/SuperChat/plugins/index.js +3 -0
- package/dist/components/SuperChat/plugins/index.js.map +1 -1
- package/dist/components/TranscriptView/index.cjs +5 -5
- package/dist/components/TranscriptView/index.d.cts +2 -2
- package/dist/components/TranscriptView/index.d.ts +2 -2
- package/dist/components/TranscriptView/index.js +2 -2
- package/dist/esheet.cjs +5 -5
- package/dist/esheet.js +2 -2
- package/dist/hooks/index.cjs +10 -9
- package/dist/hooks/index.d.cts +2 -2
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/index.js +2 -1
- package/dist/index.cjs +82 -82
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +16 -16
- package/dist/styles.css +1 -1
- package/dist/tailwind-preset.cjs +4 -4
- package/dist/tailwind-preset.js +1 -1
- package/dist/{transcript-oaWqY3yr.d.ts → transcript-Cg7uSW-C.d.cts} +4 -1
- package/dist/{transcript-oaWqY3yr.d.cts → transcript-Cg7uSW-C.d.ts} +4 -1
- package/dist/{useTranscriptEdits-CWYnjbGP.d.ts → useTranscriptEdits-C2BbMU37.d.ts} +3 -2
- package/dist/{useTranscriptEdits-BUylQFg0.d.cts → useTranscriptEdits-Hy0Vm-H8.d.cts} +3 -2
- package/package.json +2 -1
- package/dist/CsvBlock-7K6XVRYO.cjs +0 -15
- package/dist/CsvBlock-AAV4QMSF.js +0 -6
- package/dist/HtmlPreviewBlock-74XQF3KT.cjs +0 -15
- package/dist/HtmlPreviewBlock-DNINC7RW.js +0 -6
- package/dist/MermaidBlock-PKXGFGU6.js +0 -6
- package/dist/MermaidBlock-R4U7IHSZ.cjs +0 -15
- package/dist/SurveyBlock-E52I4PW3.cjs +0 -15
- package/dist/SurveyBlock-IULSBG22.js +0 -6
- package/dist/chunk-35VBGVMB.js.map +0 -1
- package/dist/chunk-3TERETXH.js.map +0 -1
- package/dist/chunk-FGP64Z24.js.map +0 -1
- package/dist/chunk-FIWKHLWY.js.map +0 -1
- package/dist/chunk-J7KWQJOB.js +0 -14
- package/dist/chunk-J7KWQJOB.js.map +0 -1
- package/dist/chunk-JC6Y3LGF.cjs.map +0 -1
- package/dist/chunk-JQEY53SH.cjs.map +0 -1
- package/dist/chunk-LIH3IZYK.js.map +0 -1
- package/dist/chunk-MHJMUKLA.js.map +0 -1
- package/dist/chunk-NAQ3ZALI.cjs.map +0 -1
- package/dist/chunk-NSLR3B7K.js.map +0 -1
- package/dist/chunk-NTYGCBCL.js.map +0 -1
- package/dist/chunk-S7JQ3FV5.cjs +0 -16
- package/dist/chunk-S7JQ3FV5.cjs.map +0 -1
- package/dist/chunk-UL3PQ7HL.cjs.map +0 -1
- package/dist/chunk-UO3KEUYK.cjs.map +0 -1
- package/dist/chunk-Y4ESBDQ5.cjs.map +0 -1
- package/dist/chunk-Y65SK5Y2.cjs.map +0 -1
- package/dist/chunk-YD23ZGRU.cjs.map +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkMSRU3XBH_cjs = require('./chunk-MSRU3XBH.cjs');
|
|
4
|
+
var chunkZDEYV373_cjs = require('./chunk-ZDEYV373.cjs');
|
|
4
5
|
var chunkCW75IKA6_cjs = require('./chunk-CW75IKA6.cjs');
|
|
5
6
|
var chunkOR5DRJCW_cjs = require('./chunk-OR5DRJCW.cjs');
|
|
6
7
|
var React = require('react');
|
|
@@ -103,13 +104,24 @@ function formatPickerValue(value, inputType, timeFormat) {
|
|
|
103
104
|
}
|
|
104
105
|
return value;
|
|
105
106
|
}
|
|
106
|
-
function getValidationError(value, mode, minAge, maxAge) {
|
|
107
|
+
function getValidationError(value, mode, minAge, maxAge, minDate, maxDate) {
|
|
107
108
|
if (!value || value.replace(/\D/g, "").length === 0) {
|
|
108
109
|
return void 0;
|
|
109
110
|
}
|
|
110
111
|
if (!chunkCW75IKA6_cjs.isValidDate(value)) {
|
|
111
112
|
return "Please enter a valid date (MM/DD/YYYY)";
|
|
112
113
|
}
|
|
114
|
+
const selectedDate = chunkCW75IKA6_cjs.parseDateValue(value);
|
|
115
|
+
const minimumDate = minDate ? chunkCW75IKA6_cjs.parseDateValue(minDate) : null;
|
|
116
|
+
const maximumDate = maxDate ? chunkCW75IKA6_cjs.parseDateValue(maxDate) : null;
|
|
117
|
+
const minimumDateLabel = minDate ? chunkCW75IKA6_cjs.formatDateValue(minDate) : "";
|
|
118
|
+
const maximumDateLabel = maxDate ? chunkCW75IKA6_cjs.formatDateValue(maxDate) : "";
|
|
119
|
+
if (selectedDate && minimumDate && selectedDate < minimumDate) {
|
|
120
|
+
return `Date must be on or after ${minimumDateLabel}`;
|
|
121
|
+
}
|
|
122
|
+
if (selectedDate && maximumDate && selectedDate > maximumDate) {
|
|
123
|
+
return `Date must be on or before ${maximumDateLabel}`;
|
|
124
|
+
}
|
|
113
125
|
switch (mode) {
|
|
114
126
|
case "dob": {
|
|
115
127
|
if (!chunkCW75IKA6_cjs.isDateInPast(value)) {
|
|
@@ -153,6 +165,8 @@ var DateInput = React__namespace.forwardRef(
|
|
|
153
165
|
mode = "default",
|
|
154
166
|
minAge,
|
|
155
167
|
maxAge,
|
|
168
|
+
minDate,
|
|
169
|
+
maxDate,
|
|
156
170
|
validateOnBlur,
|
|
157
171
|
showCalendar = false,
|
|
158
172
|
width = "full",
|
|
@@ -186,7 +200,9 @@ var DateInput = React__namespace.forwardRef(
|
|
|
186
200
|
displayValue,
|
|
187
201
|
mode,
|
|
188
202
|
minAge,
|
|
189
|
-
maxAge
|
|
203
|
+
maxAge,
|
|
204
|
+
minDate,
|
|
205
|
+
maxDate
|
|
190
206
|
);
|
|
191
207
|
setLocalError(validationError);
|
|
192
208
|
}
|
|
@@ -195,29 +211,14 @@ var DateInput = React__namespace.forwardRef(
|
|
|
195
211
|
const autoComplete = mode === "dob" ? "bday" : mode === "expiration" ? "cc-exp" : void 0;
|
|
196
212
|
const generatedId = React__namespace.useId();
|
|
197
213
|
const [isCalendarOpen, setIsCalendarOpen] = React__namespace.useState(false);
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
top: rect.bottom + 4,
|
|
207
|
-
left: Math.max(8, rect.right - 288),
|
|
208
|
-
zIndex: 9999
|
|
209
|
-
});
|
|
210
|
-
}, []);
|
|
211
|
-
React__namespace.useEffect(() => {
|
|
212
|
-
if (!isCalendarOpen) return;
|
|
213
|
-
updateCalendarPosition();
|
|
214
|
-
window.addEventListener("scroll", updateCalendarPosition, true);
|
|
215
|
-
window.addEventListener("resize", updateCalendarPosition);
|
|
216
|
-
return () => {
|
|
217
|
-
window.removeEventListener("scroll", updateCalendarPosition, true);
|
|
218
|
-
window.removeEventListener("resize", updateCalendarPosition);
|
|
219
|
-
};
|
|
220
|
-
}, [isCalendarOpen, updateCalendarPosition]);
|
|
214
|
+
const {
|
|
215
|
+
anchorRef: buttonRef,
|
|
216
|
+
floatingRef: calendarRef,
|
|
217
|
+
style: calendarStyle
|
|
218
|
+
} = chunkZDEYV373_cjs.useAnchoredPosition({
|
|
219
|
+
open: isCalendarOpen,
|
|
220
|
+
placement: "bottom-end"
|
|
221
|
+
});
|
|
221
222
|
const parsedDate = React__namespace.useMemo(() => {
|
|
222
223
|
const fallback = /* @__PURE__ */ new Date();
|
|
223
224
|
return parsePickerDate(displayValue, inputType) ?? {
|
|
@@ -231,6 +232,51 @@ var DateInput = React__namespace.forwardRef(
|
|
|
231
232
|
const [selectedTime, setSelectedTime] = React__namespace.useState(
|
|
232
233
|
() => inputType === "datetime-local" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/.test(value) ? value.slice(-5) : "00:00"
|
|
233
234
|
);
|
|
235
|
+
const minimumDate = React__namespace.useMemo(
|
|
236
|
+
() => minDate ? chunkCW75IKA6_cjs.parseDateValue(minDate) : null,
|
|
237
|
+
[minDate]
|
|
238
|
+
);
|
|
239
|
+
const maximumDate = React__namespace.useMemo(
|
|
240
|
+
() => maxDate ? chunkCW75IKA6_cjs.parseDateValue(maxDate) : null,
|
|
241
|
+
[maxDate]
|
|
242
|
+
);
|
|
243
|
+
const isDateInRange = React__namespace.useCallback(
|
|
244
|
+
(date) => {
|
|
245
|
+
const candidate = new Date(
|
|
246
|
+
date.getFullYear(),
|
|
247
|
+
date.getMonth(),
|
|
248
|
+
date.getDate()
|
|
249
|
+
);
|
|
250
|
+
return (!minimumDate || candidate >= minimumDate) && (!maximumDate || candidate <= maximumDate);
|
|
251
|
+
},
|
|
252
|
+
[maximumDate, minimumDate]
|
|
253
|
+
);
|
|
254
|
+
const isCalendarDateInRange = React__namespace.useCallback(
|
|
255
|
+
(day) => {
|
|
256
|
+
return isDateInRange(new Date(calendarYear, calendarMonth, day));
|
|
257
|
+
},
|
|
258
|
+
[calendarMonth, calendarYear, isDateInRange]
|
|
259
|
+
);
|
|
260
|
+
const isCalendarMonthInRange = React__namespace.useCallback(
|
|
261
|
+
(month, year) => {
|
|
262
|
+
const firstDay = new Date(year, month, 1);
|
|
263
|
+
const lastDay = new Date(year, month + 1, 0);
|
|
264
|
+
return (!minimumDate || lastDay >= minimumDate) && (!maximumDate || firstDay <= maximumDate);
|
|
265
|
+
},
|
|
266
|
+
[maximumDate, minimumDate]
|
|
267
|
+
);
|
|
268
|
+
const firstCalendarYear = minimumDate ? minimumDate.getFullYear() : (/* @__PURE__ */ new Date()).getFullYear() - 100;
|
|
269
|
+
const lastCalendarYear = maximumDate ? maximumDate.getFullYear() : (/* @__PURE__ */ new Date()).getFullYear() + 49;
|
|
270
|
+
const calendarYears = Array.from(
|
|
271
|
+
{ length: Math.max(0, lastCalendarYear - firstCalendarYear + 1) },
|
|
272
|
+
(_, index) => firstCalendarYear + index
|
|
273
|
+
);
|
|
274
|
+
const previousCalendarMonth = calendarMonth === 0 ? 11 : calendarMonth - 1;
|
|
275
|
+
const previousCalendarYear = calendarMonth === 0 ? calendarYear - 1 : calendarYear;
|
|
276
|
+
const nextCalendarMonth = calendarMonth === 11 ? 0 : calendarMonth + 1;
|
|
277
|
+
const nextCalendarYear = calendarMonth === 11 ? calendarYear + 1 : calendarYear;
|
|
278
|
+
const canGoToPreviousCalendar = inputType === "month" ? !minimumDate || calendarYear > minimumDate.getFullYear() : isCalendarMonthInRange(previousCalendarMonth, previousCalendarYear);
|
|
279
|
+
const canGoToNextCalendar = inputType === "month" ? !maximumDate || calendarYear < maximumDate.getFullYear() : isCalendarMonthInRange(nextCalendarMonth, nextCalendarYear);
|
|
234
280
|
React__namespace.useEffect(() => {
|
|
235
281
|
const date = parsePickerDate(displayValue, inputType);
|
|
236
282
|
if (!date) return;
|
|
@@ -240,6 +286,19 @@ var DateInput = React__namespace.forwardRef(
|
|
|
240
286
|
setSelectedTime(displayValue.slice(-5));
|
|
241
287
|
}
|
|
242
288
|
}, [displayValue, inputType]);
|
|
289
|
+
React__namespace.useEffect(() => {
|
|
290
|
+
if (isCalendarMonthInRange(calendarMonth, calendarYear)) return;
|
|
291
|
+
const closestAllowedDate = minimumDate ?? maximumDate;
|
|
292
|
+
if (!closestAllowedDate) return;
|
|
293
|
+
setCalendarMonth(closestAllowedDate.getMonth());
|
|
294
|
+
setCalendarYear(closestAllowedDate.getFullYear());
|
|
295
|
+
}, [
|
|
296
|
+
calendarMonth,
|
|
297
|
+
calendarYear,
|
|
298
|
+
isCalendarMonthInRange,
|
|
299
|
+
maximumDate,
|
|
300
|
+
minimumDate
|
|
301
|
+
]);
|
|
243
302
|
React__namespace.useEffect(() => {
|
|
244
303
|
const handleClickOutside = (event) => {
|
|
245
304
|
if (calendarRef.current && !calendarRef.current.contains(event.target) && buttonRef.current && !buttonRef.current.contains(event.target)) {
|
|
@@ -250,7 +309,7 @@ var DateInput = React__namespace.forwardRef(
|
|
|
250
309
|
document.addEventListener("mousedown", handleClickOutside);
|
|
251
310
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
252
311
|
}
|
|
253
|
-
}, [isCalendarOpen]);
|
|
312
|
+
}, [isCalendarOpen, buttonRef, calendarRef]);
|
|
254
313
|
React__namespace.useEffect(() => {
|
|
255
314
|
const handleEscape = (event) => {
|
|
256
315
|
if (event.key === "Escape") {
|
|
@@ -262,8 +321,9 @@ var DateInput = React__namespace.forwardRef(
|
|
|
262
321
|
document.addEventListener("keydown", handleEscape);
|
|
263
322
|
return () => document.removeEventListener("keydown", handleEscape);
|
|
264
323
|
}
|
|
265
|
-
}, [isCalendarOpen]);
|
|
324
|
+
}, [isCalendarOpen, buttonRef]);
|
|
266
325
|
const handleDateSelect = (day) => {
|
|
326
|
+
if (!isCalendarDateInRange(day)) return;
|
|
267
327
|
const month = String(calendarMonth + 1).padStart(2, "0");
|
|
268
328
|
const dayStr = String(day).padStart(2, "0");
|
|
269
329
|
const year = String(calendarYear);
|
|
@@ -278,17 +338,30 @@ var DateInput = React__namespace.forwardRef(
|
|
|
278
338
|
formatted,
|
|
279
339
|
mode,
|
|
280
340
|
minAge,
|
|
281
|
-
maxAge
|
|
341
|
+
maxAge,
|
|
342
|
+
minDate,
|
|
343
|
+
maxDate
|
|
282
344
|
);
|
|
283
345
|
setLocalError(validationError);
|
|
284
346
|
}
|
|
285
347
|
};
|
|
286
348
|
const handleMonthSelect = (month) => {
|
|
349
|
+
if (!isCalendarMonthInRange(month, calendarYear)) return;
|
|
287
350
|
const formatted = `${calendarYear}-${String(month + 1).padStart(2, "0")}`;
|
|
288
351
|
setDisplayValue(formatted);
|
|
289
352
|
onChange?.(formatted);
|
|
290
353
|
setIsCalendarOpen(false);
|
|
291
354
|
};
|
|
355
|
+
const handleCalendarYearChange = (year) => {
|
|
356
|
+
setCalendarYear(year);
|
|
357
|
+
if (isCalendarMonthInRange(calendarMonth, year)) return;
|
|
358
|
+
const firstAvailableMonth = MONTH_NAMES.findIndex(
|
|
359
|
+
(_, month) => isCalendarMonthInRange(month, year)
|
|
360
|
+
);
|
|
361
|
+
if (firstAvailableMonth !== -1) {
|
|
362
|
+
setCalendarMonth(firstAvailableMonth);
|
|
363
|
+
}
|
|
364
|
+
};
|
|
292
365
|
const handleTimeChange = (part, nextValue) => {
|
|
293
366
|
const [hour, minute] = selectedTime.split(":");
|
|
294
367
|
const nextTime = part === "hour" ? `${nextValue}:${minute}` : `${hour}:${nextValue}`;
|
|
@@ -334,7 +407,7 @@ var DateInput = React__namespace.forwardRef(
|
|
|
334
407
|
ref: calendarRef,
|
|
335
408
|
className: chunkOR5DRJCW_cjs.cn(
|
|
336
409
|
"bg-background border-border rounded-lg border shadow-lg",
|
|
337
|
-
"w-72 p-3"
|
|
410
|
+
"w-72 overflow-auto p-3"
|
|
338
411
|
),
|
|
339
412
|
style: calendarStyle,
|
|
340
413
|
role: "dialog",
|
|
@@ -355,7 +428,8 @@ var DateInput = React__namespace.forwardRef(
|
|
|
355
428
|
setCalendarMonth(calendarMonth - 1);
|
|
356
429
|
}
|
|
357
430
|
},
|
|
358
|
-
|
|
431
|
+
disabled: !canGoToPreviousCalendar,
|
|
432
|
+
className: "enabled:hover:bg-muted rounded-md p-1 transition-colors disabled:cursor-not-allowed disabled:opacity-50",
|
|
359
433
|
"aria-label": inputType === "month" ? "Previous year" : "Previous month",
|
|
360
434
|
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, {})
|
|
361
435
|
}
|
|
@@ -368,20 +442,19 @@ var DateInput = React__namespace.forwardRef(
|
|
|
368
442
|
onChange: (e) => setCalendarMonth(Number(e.target.value)),
|
|
369
443
|
className: "bg-background border-border rounded border px-2 py-1 text-sm",
|
|
370
444
|
"aria-label": "Select month",
|
|
371
|
-
children: MONTH_NAMES.map(
|
|
445
|
+
children: MONTH_NAMES.map(
|
|
446
|
+
(name, month) => isCalendarMonthInRange(month, calendarYear) ? /* @__PURE__ */ jsxRuntime.jsx("option", { value: month, children: name }, name) : null
|
|
447
|
+
)
|
|
372
448
|
}
|
|
373
449
|
),
|
|
374
450
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
375
451
|
"select",
|
|
376
452
|
{
|
|
377
453
|
value: calendarYear,
|
|
378
|
-
onChange: (e) =>
|
|
454
|
+
onChange: (e) => handleCalendarYearChange(Number(e.target.value)),
|
|
379
455
|
className: "bg-background border-border rounded border px-2 py-1 text-sm",
|
|
380
456
|
"aria-label": "Select year",
|
|
381
|
-
children:
|
|
382
|
-
{ length: 150 },
|
|
383
|
-
(_, i) => (/* @__PURE__ */ new Date()).getFullYear() - 100 + i
|
|
384
|
-
).map((year) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: year, children: year }, year))
|
|
457
|
+
children: calendarYears.map((year) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: year, children: year }, year))
|
|
385
458
|
}
|
|
386
459
|
)
|
|
387
460
|
] }),
|
|
@@ -399,7 +472,8 @@ var DateInput = React__namespace.forwardRef(
|
|
|
399
472
|
setCalendarMonth(calendarMonth + 1);
|
|
400
473
|
}
|
|
401
474
|
},
|
|
402
|
-
|
|
475
|
+
disabled: !canGoToNextCalendar,
|
|
476
|
+
className: "hover:bg-muted rounded-md p-1 transition-colors disabled:cursor-not-allowed disabled:opacity-50",
|
|
403
477
|
"aria-label": inputType === "month" ? "Next year" : "Next month",
|
|
404
478
|
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, {})
|
|
405
479
|
}
|
|
@@ -432,13 +506,14 @@ var DateInput = React__namespace.forwardRef(
|
|
|
432
506
|
"button",
|
|
433
507
|
{
|
|
434
508
|
type: "button",
|
|
435
|
-
disabled: day === null,
|
|
509
|
+
disabled: day === null || !isCalendarDateInRange(day),
|
|
436
510
|
onClick: () => day && handleDateSelect(day),
|
|
437
511
|
className: chunkOR5DRJCW_cjs.cn(
|
|
438
512
|
"h-8 w-8 rounded-md text-sm transition-colors",
|
|
439
513
|
"focus:ring-ring focus:ring-2 focus:outline-none",
|
|
440
514
|
day === null && "invisible",
|
|
441
515
|
day !== null && "hover:bg-muted",
|
|
516
|
+
day !== null && !isCalendarDateInRange(day) && "cursor-not-allowed opacity-50",
|
|
442
517
|
isSelectedDay(day) && "bg-primary-800 hover:bg-primary-900 text-white",
|
|
443
518
|
isToday(day) && !isSelectedDay(day) && "border-primary-800 text-primary-800 border"
|
|
444
519
|
),
|
|
@@ -512,7 +587,11 @@ var DateInput = React__namespace.forwardRef(
|
|
|
512
587
|
handleDateSelect(today.getDate());
|
|
513
588
|
}
|
|
514
589
|
},
|
|
515
|
-
|
|
590
|
+
disabled: inputType === "month" ? !isCalendarMonthInRange(
|
|
591
|
+
(/* @__PURE__ */ new Date()).getMonth(),
|
|
592
|
+
(/* @__PURE__ */ new Date()).getFullYear()
|
|
593
|
+
) : !isDateInRange(/* @__PURE__ */ new Date()),
|
|
594
|
+
className: "text-primary-800 flex-1 text-sm hover:underline disabled:cursor-not-allowed disabled:opacity-50",
|
|
516
595
|
children: "Today"
|
|
517
596
|
}
|
|
518
597
|
),
|
|
@@ -707,5 +786,5 @@ function ChevronRightIcon() {
|
|
|
707
786
|
}
|
|
708
787
|
|
|
709
788
|
exports.DateInput = DateInput;
|
|
710
|
-
//# sourceMappingURL=chunk-
|
|
711
|
-
//# sourceMappingURL=chunk-
|
|
789
|
+
//# sourceMappingURL=chunk-QUUFKGDF.cjs.map
|
|
790
|
+
//# sourceMappingURL=chunk-QUUFKGDF.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/DateInput/DateInput.tsx"],"names":["year","month","day","isValidDate","parseDateValue","formatDateValue","isDateInPast","calculateAge","isDateInFuture","React","useAnchoredPosition","jsxs","cn","jsx","Fragment","Input","Calendar","createPortal"],"mappings":"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","file":"chunk-QUUFKGDF.cjs","sourcesContent":["import * as React from 'react';\nimport { createPortal } from 'react-dom';\nimport { cn } from '../../utils/cn';\nimport {\n formatDateValue,\n isValidDate,\n parseDateValue,\n isDateInPast,\n isDateInFuture,\n calculateAge,\n} from '../../utils/date';\nimport { Input, type InputProps } from '../Input';\nimport { Calendar } from 'lucide-react';\nimport { useAnchoredPosition } from '../../hooks/useAnchoredPosition';\n\nexport type DateInputMode =\n | 'default'\n | 'dob'\n | 'expiration'\n | 'past'\n | 'future';\n\nexport type DateInputType = 'date' | 'datetime-local' | 'month' | 'year';\n\nexport type DateInputWidth = 'full' | 'fit' | 'fixed';\n\nexport type DateInputTimeFormat = '12-hour' | '24-hour';\n\nconst widthClasses: Record<DateInputWidth, string> = {\n full: 'w-full',\n fit: 'w-fit',\n fixed: 'w-44', // ~176px - enough for MM/DD/YYYY + calendar icon\n};\n\nconst sizeClasses = {\n sm: 'h-8 text-sm',\n md: 'h-10 text-base',\n lg: 'h-12 text-lg',\n} as const;\n\nconst MONTH_NAMES = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n];\n\ninterface PickerDate {\n month: number;\n year: number;\n day: number | null;\n}\n\nfunction isValidPickerDate(year: number, month: number, day: number): boolean {\n return (\n Number.isFinite(year) &&\n month >= 1 &&\n month <= 12 &&\n day >= 1 &&\n day <= new Date(year, month, 0).getDate()\n );\n}\n\nfunction parsePickerDate(\n value: string,\n inputType: DateInputType\n): PickerDate | undefined {\n if (inputType === 'datetime-local') {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})T\\d{2}:\\d{2}$/.exec(value);\n if (!match) return undefined;\n const year = Number(match[1]);\n const month = Number(match[2]);\n const day = Number(match[3]);\n const [hour, minute] = value.slice(-5).split(':').map(Number);\n if (!isValidPickerDate(year, month, day) || hour > 23 || minute > 59) {\n return undefined;\n }\n return {\n year,\n month: month - 1,\n day,\n };\n }\n\n if (inputType === 'month') {\n const match = /^(\\d{4})-(\\d{2})$/.exec(value);\n if (!match) return undefined;\n const year = Number(match[1]);\n const month = Number(match[2]);\n if (!Number.isFinite(year) || month < 1 || month > 12) return undefined;\n return { year, month: month - 1, day: null };\n }\n\n if (!isValidDate(value)) return undefined;\n const [month, day, year] = value.split('/').map(Number);\n return { month: month - 1, year, day };\n}\n\nfunction formatPickerValue(\n value: string,\n inputType: DateInputType,\n timeFormat: DateInputTimeFormat\n): string {\n if (inputType === 'datetime-local') {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}:\\d{2})$/.exec(value);\n if (!match) return '';\n if (timeFormat === '12-hour') {\n const [hour, minute] = match[4].split(':').map(Number);\n const displayHour = hour % 12 || 12;\n const meridiem = hour >= 12 ? 'PM' : 'AM';\n return `${match[2]}/${match[3]}/${match[1]} ${displayHour}:${String(minute).padStart(2, '0')} ${meridiem}`;\n }\n return `${match[2]}/${match[3]}/${match[1]} ${match[4]}`;\n }\n\n if (inputType === 'month') {\n const date = parsePickerDate(value, inputType);\n return date ? `${MONTH_NAMES[date.month]} ${date.year}` : '';\n }\n\n return value;\n}\n\nexport interface DateInputProps extends Omit<\n InputProps,\n 'type' | 'onChange' | 'value'\n> {\n /** The value for the selected input type. Dates use MM/DD/YYYY format. */\n value?: string;\n /** Callback fired when the value changes */\n onChange?: (value: string) => void;\n /** Date value format and picker control. */\n inputType?: DateInputType;\n /** Time picker display format for datetime values. */\n timeFormat?: DateInputTimeFormat;\n /** Validation mode for the date input */\n mode?: DateInputMode;\n /** Minimum age for DOB validation (default: 0) */\n minAge?: number;\n /** Maximum age for DOB validation */\n maxAge?: number;\n /** Earliest allowed date in MM/DD/YYYY format. */\n minDate?: string;\n /** Latest allowed date in MM/DD/YYYY format. */\n maxDate?: string;\n /** Whether to validate on blur */\n validateOnBlur?: boolean;\n /** Whether to show a calendar picker button */\n showCalendar?: boolean;\n /** Width behavior of the input */\n width?: DateInputWidth;\n}\n\nfunction getValidationError(\n value: string,\n mode: DateInputMode,\n minAge?: number,\n maxAge?: number,\n minDate?: string,\n maxDate?: string\n): string | undefined {\n if (!value || value.replace(/\\D/g, '').length === 0) {\n return undefined;\n }\n\n if (!isValidDate(value)) {\n return 'Please enter a valid date (MM/DD/YYYY)';\n }\n\n const selectedDate = parseDateValue(value);\n const minimumDate = minDate ? parseDateValue(minDate) : null;\n const maximumDate = maxDate ? parseDateValue(maxDate) : null;\n const minimumDateLabel = minDate ? formatDateValue(minDate) : '';\n const maximumDateLabel = maxDate ? formatDateValue(maxDate) : '';\n\n if (selectedDate && minimumDate && selectedDate < minimumDate) {\n return `Date must be on or after ${minimumDateLabel}`;\n }\n\n if (selectedDate && maximumDate && selectedDate > maximumDate) {\n return `Date must be on or before ${maximumDateLabel}`;\n }\n\n switch (mode) {\n case 'dob': {\n if (!isDateInPast(value)) {\n return 'Date of birth must be in the past';\n }\n const age = calculateAge(value);\n if (age !== null) {\n if (minAge !== undefined && age < minAge) {\n return `Must be at least ${minAge} years old`;\n }\n if (maxAge !== undefined && age > maxAge) {\n return `Must be no more than ${maxAge} years old`;\n }\n }\n break;\n }\n case 'expiration':\n if (!isDateInFuture(value)) {\n return 'Expiration date must be in the future';\n }\n break;\n case 'past':\n if (!isDateInPast(value)) {\n return 'Date must be in the past';\n }\n break;\n case 'future':\n if (!isDateInFuture(value)) {\n return 'Date must be in the future';\n }\n break;\n }\n\n return undefined;\n}\n\n/**\n * A date input that automatically formats to MM/DD/YYYY with validation modes.\n *\n * @example\n * ```tsx\n * // Date of birth with age validation\n * <DateInput\n * label=\"Date of Birth\"\n * mode=\"dob\"\n * minAge={18}\n * validateOnBlur\n * />\n *\n * // With calendar picker\n * <DateInput\n * label=\"Select Date\"\n * showCalendar\n * />\n *\n * // Expiration date\n * <DateInput\n * label=\"License Expiration\"\n * mode=\"expiration\"\n * validateOnBlur\n * />\n * ```\n */\nconst DateInput = React.forwardRef<HTMLInputElement, DateInputProps>(\n (\n {\n value = '',\n onChange,\n inputType = 'date',\n timeFormat = '24-hour',\n mode = 'default',\n minAge,\n maxAge,\n minDate,\n maxDate,\n validateOnBlur,\n showCalendar = false,\n width = 'full',\n className,\n onBlur,\n onClick,\n hasError,\n error,\n ...props\n },\n ref\n ) => {\n const isFormattedDate = inputType === 'date';\n const [displayValue, setDisplayValue] = React.useState(() =>\n isFormattedDate ? formatDateValue(value) : value\n );\n const [localError, setLocalError] = React.useState<string | undefined>();\n\n // Sync external value changes\n React.useEffect(() => {\n setDisplayValue(isFormattedDate ? formatDateValue(value) : value);\n }, [isFormattedDate, value]);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const formatted = formatDateValue(e.target.value);\n setDisplayValue(formatted);\n onChange?.(formatted);\n\n // Clear error when user starts typing again\n if (localError) {\n setLocalError(undefined);\n }\n };\n\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n onBlur?.(e);\n\n if (validateOnBlur) {\n const validationError = getValidationError(\n displayValue,\n mode,\n minAge,\n maxAge,\n minDate,\n maxDate\n );\n setLocalError(validationError);\n }\n };\n\n const placeholder = mode === 'expiration' ? 'MM/DD/YYYY' : 'MM/DD/YYYY';\n const autoComplete =\n mode === 'dob' ? 'bday' : mode === 'expiration' ? 'cc-exp' : undefined;\n\n // Generate stable ID for accessibility\n const generatedId = React.useId();\n\n // Calendar picker state\n const [isCalendarOpen, setIsCalendarOpen] = React.useState(false);\n\n // Portal + fixed positioning so the calendar escapes overflow-hidden\n // ancestors, flips vertically, and clamps to the viewport.\n const {\n anchorRef: buttonRef,\n floatingRef: calendarRef,\n style: calendarStyle,\n } = useAnchoredPosition<HTMLButtonElement, HTMLDivElement>({\n open: isCalendarOpen,\n placement: 'bottom-end',\n });\n\n // Parse current value into date parts for calendar\n const parsedDate = React.useMemo(() => {\n const fallback = new Date();\n return (\n parsePickerDate(displayValue, inputType) ?? {\n month: fallback.getMonth(),\n year: fallback.getFullYear(),\n day: null,\n }\n );\n }, [displayValue, inputType]);\n\n const [calendarMonth, setCalendarMonth] = React.useState(parsedDate.month);\n const [calendarYear, setCalendarYear] = React.useState(parsedDate.year);\n const [selectedTime, setSelectedTime] = React.useState(() =>\n inputType === 'datetime-local' &&\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}$/.test(value)\n ? value.slice(-5)\n : '00:00'\n );\n const minimumDate = React.useMemo(\n () => (minDate ? parseDateValue(minDate) : null),\n [minDate]\n );\n const maximumDate = React.useMemo(\n () => (maxDate ? parseDateValue(maxDate) : null),\n [maxDate]\n );\n\n const isDateInRange = React.useCallback(\n (date: Date) => {\n const candidate = new Date(\n date.getFullYear(),\n date.getMonth(),\n date.getDate()\n );\n return (\n (!minimumDate || candidate >= minimumDate) &&\n (!maximumDate || candidate <= maximumDate)\n );\n },\n [maximumDate, minimumDate]\n );\n\n const isCalendarDateInRange = React.useCallback(\n (day: number) => {\n return isDateInRange(new Date(calendarYear, calendarMonth, day));\n },\n [calendarMonth, calendarYear, isDateInRange]\n );\n\n const isCalendarMonthInRange = React.useCallback(\n (month: number, year: number) => {\n const firstDay = new Date(year, month, 1);\n const lastDay = new Date(year, month + 1, 0);\n return (\n (!minimumDate || lastDay >= minimumDate) &&\n (!maximumDate || firstDay <= maximumDate)\n );\n },\n [maximumDate, minimumDate]\n );\n\n const firstCalendarYear = minimumDate\n ? minimumDate.getFullYear()\n : new Date().getFullYear() - 100;\n const lastCalendarYear = maximumDate\n ? maximumDate.getFullYear()\n : new Date().getFullYear() + 49;\n const calendarYears = Array.from(\n { length: Math.max(0, lastCalendarYear - firstCalendarYear + 1) },\n (_, index) => firstCalendarYear + index\n );\n const previousCalendarMonth = calendarMonth === 0 ? 11 : calendarMonth - 1;\n const previousCalendarYear =\n calendarMonth === 0 ? calendarYear - 1 : calendarYear;\n const nextCalendarMonth = calendarMonth === 11 ? 0 : calendarMonth + 1;\n const nextCalendarYear =\n calendarMonth === 11 ? calendarYear + 1 : calendarYear;\n const canGoToPreviousCalendar =\n inputType === 'month'\n ? !minimumDate || calendarYear > minimumDate.getFullYear()\n : isCalendarMonthInRange(previousCalendarMonth, previousCalendarYear);\n const canGoToNextCalendar =\n inputType === 'month'\n ? !maximumDate || calendarYear < maximumDate.getFullYear()\n : isCalendarMonthInRange(nextCalendarMonth, nextCalendarYear);\n\n // Update calendar view when value changes\n React.useEffect(() => {\n const date = parsePickerDate(displayValue, inputType);\n if (!date) return;\n setCalendarMonth(date.month);\n setCalendarYear(date.year);\n if (inputType === 'datetime-local') {\n setSelectedTime(displayValue.slice(-5));\n }\n }, [displayValue, inputType]);\n\n React.useEffect(() => {\n if (isCalendarMonthInRange(calendarMonth, calendarYear)) return;\n\n const closestAllowedDate = minimumDate ?? maximumDate;\n if (!closestAllowedDate) return;\n\n setCalendarMonth(closestAllowedDate.getMonth());\n setCalendarYear(closestAllowedDate.getFullYear());\n }, [\n calendarMonth,\n calendarYear,\n isCalendarMonthInRange,\n maximumDate,\n minimumDate,\n ]);\n\n // Close calendar on click outside\n React.useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (\n calendarRef.current &&\n !calendarRef.current.contains(event.target as HTMLElement) &&\n buttonRef.current &&\n !buttonRef.current.contains(event.target as HTMLElement)\n ) {\n setIsCalendarOpen(false);\n }\n };\n\n if (isCalendarOpen) {\n document.addEventListener('mousedown', handleClickOutside);\n return () =>\n document.removeEventListener('mousedown', handleClickOutside);\n }\n }, [isCalendarOpen, buttonRef, calendarRef]);\n\n // Close on Escape key\n React.useEffect(() => {\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n setIsCalendarOpen(false);\n buttonRef.current?.focus();\n }\n };\n\n if (isCalendarOpen) {\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }\n }, [isCalendarOpen, buttonRef]);\n\n const handleDateSelect = (day: number) => {\n if (!isCalendarDateInRange(day)) return;\n\n const month = String(calendarMonth + 1).padStart(2, '0');\n const dayStr = String(day).padStart(2, '0');\n const year = String(calendarYear);\n const formatted =\n inputType === 'datetime-local'\n ? `${year}-${month}-${dayStr}T${selectedTime}`\n : `${month}/${dayStr}/${year}`;\n setDisplayValue(formatted);\n onChange?.(formatted);\n if (inputType === 'date') {\n setIsCalendarOpen(false);\n }\n\n // Validate if needed\n if (inputType === 'date' && validateOnBlur) {\n const validationError = getValidationError(\n formatted,\n mode,\n minAge,\n maxAge,\n minDate,\n maxDate\n );\n setLocalError(validationError);\n }\n };\n\n const handleMonthSelect = (month: number) => {\n if (!isCalendarMonthInRange(month, calendarYear)) return;\n\n const formatted = `${calendarYear}-${String(month + 1).padStart(2, '0')}`;\n setDisplayValue(formatted);\n onChange?.(formatted);\n setIsCalendarOpen(false);\n };\n\n const handleCalendarYearChange = (year: number) => {\n setCalendarYear(year);\n if (isCalendarMonthInRange(calendarMonth, year)) return;\n\n const firstAvailableMonth = MONTH_NAMES.findIndex((_, month) =>\n isCalendarMonthInRange(month, year)\n );\n if (firstAvailableMonth !== -1) {\n setCalendarMonth(firstAvailableMonth);\n }\n };\n\n const handleTimeChange = (part: 'hour' | 'minute', nextValue: string) => {\n const [hour, minute] = selectedTime.split(':');\n const nextTime =\n part === 'hour' ? `${nextValue}:${minute}` : `${hour}:${nextValue}`;\n setSelectedTime(nextTime);\n\n if (parsedDate.day === null) return;\n const month = String(parsedDate.month + 1).padStart(2, '0');\n const day = String(parsedDate.day).padStart(2, '0');\n const formatted = `${parsedDate.year}-${month}-${day}T${nextTime}`;\n setDisplayValue(formatted);\n onChange?.(formatted);\n };\n\n const handleMeridiemChange = (meridiem: 'AM' | 'PM') => {\n const [hour] = selectedTime.split(':').map(Number);\n const nextHour = (hour % 12) + (meridiem === 'PM' ? 12 : 0);\n handleTimeChange('hour', String(nextHour).padStart(2, '0'));\n };\n\n const getDaysInMonth = (month: number, year: number) => {\n return new Date(year, month + 1, 0).getDate();\n };\n\n const getFirstDayOfMonth = (month: number, year: number) => {\n return new Date(year, month, 1).getDay();\n };\n\n const renderCalendar = () => {\n const daysInMonth = getDaysInMonth(calendarMonth, calendarYear);\n const firstDay = getFirstDayOfMonth(calendarMonth, calendarYear);\n const days: (number | null)[] = [];\n\n // Add empty cells for days before the first day of the month\n for (let i = 0; i < firstDay; i++) {\n days.push(null);\n }\n\n // Add the days of the month\n for (let i = 1; i <= daysInMonth; i++) {\n days.push(i);\n }\n\n const isSelectedDay = (day: number) => {\n return (\n parsedDate.day === day &&\n parsedDate.month === calendarMonth &&\n parsedDate.year === calendarYear\n );\n };\n\n const isToday = (day: number) => {\n const today = new Date();\n return (\n day === today.getDate() &&\n calendarMonth === today.getMonth() &&\n calendarYear === today.getFullYear()\n );\n };\n\n return (\n <div\n ref={calendarRef}\n className={cn(\n 'bg-background border-border rounded-lg border shadow-lg',\n 'w-72 overflow-auto p-3'\n )}\n style={calendarStyle}\n role=\"dialog\"\n aria-label={\n inputType === 'month'\n ? 'Choose month'\n : inputType === 'datetime-local'\n ? 'Choose date and time'\n : 'Choose date'\n }\n >\n {/* Header with month/year navigation */}\n <div className=\"mb-3 flex items-center justify-between\">\n <button\n type=\"button\"\n onClick={() => {\n if (inputType === 'month') {\n setCalendarYear(calendarYear - 1);\n } else if (calendarMonth === 0) {\n setCalendarMonth(11);\n setCalendarYear(calendarYear - 1);\n } else {\n setCalendarMonth(calendarMonth - 1);\n }\n }}\n disabled={!canGoToPreviousCalendar}\n className=\"enabled:hover:bg-muted rounded-md p-1 transition-colors disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label={\n inputType === 'month' ? 'Previous year' : 'Previous month'\n }\n >\n <ChevronLeftIcon />\n </button>\n <div className=\"flex items-center gap-2\">\n {inputType !== 'month' && (\n <select\n value={calendarMonth}\n onChange={(e) => setCalendarMonth(Number(e.target.value))}\n className=\"bg-background border-border rounded border px-2 py-1 text-sm\"\n aria-label=\"Select month\"\n >\n {MONTH_NAMES.map((name, month) =>\n isCalendarMonthInRange(month, calendarYear) ? (\n <option key={name} value={month}>\n {name}\n </option>\n ) : null\n )}\n </select>\n )}\n <select\n value={calendarYear}\n onChange={(e) =>\n handleCalendarYearChange(Number(e.target.value))\n }\n className=\"bg-background border-border rounded border px-2 py-1 text-sm\"\n aria-label=\"Select year\"\n >\n {calendarYears.map((year) => (\n <option key={year} value={year}>\n {year}\n </option>\n ))}\n </select>\n </div>\n <button\n type=\"button\"\n onClick={() => {\n if (inputType === 'month') {\n setCalendarYear(calendarYear + 1);\n } else if (calendarMonth === 11) {\n setCalendarMonth(0);\n setCalendarYear(calendarYear + 1);\n } else {\n setCalendarMonth(calendarMonth + 1);\n }\n }}\n disabled={!canGoToNextCalendar}\n className=\"hover:bg-muted rounded-md p-1 transition-colors disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label={inputType === 'month' ? 'Next year' : 'Next month'}\n >\n <ChevronRightIcon />\n </button>\n </div>\n\n {inputType === 'month' ? (\n <div className=\"grid grid-cols-3 gap-1\">\n {MONTH_NAMES.map((name, month) => (\n <button\n key={name}\n type=\"button\"\n onClick={() => handleMonthSelect(month)}\n className={cn(\n 'rounded-md px-2 py-2 text-sm transition-colors',\n 'focus:ring-ring focus:ring-2 focus:outline-none',\n 'hover:bg-muted',\n parsedDate.month === month &&\n parsedDate.year === calendarYear &&\n 'bg-primary-800 hover:bg-primary-900 text-white'\n )}\n >\n {name.slice(0, 3)}\n </button>\n ))}\n </div>\n ) : (\n <>\n <div className=\"mb-1 grid grid-cols-7 gap-1\">\n {['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'].map((day) => (\n <div\n key={day}\n className=\"text-muted-foreground py-1 text-center text-xs font-medium\"\n >\n {day}\n </div>\n ))}\n </div>\n <div className=\"grid grid-cols-7 gap-1\">\n {days.map((day, index) => (\n <button\n key={index}\n type=\"button\"\n disabled={day === null || !isCalendarDateInRange(day)}\n onClick={() => day && handleDateSelect(day)}\n className={cn(\n 'h-8 w-8 rounded-md text-sm transition-colors',\n 'focus:ring-ring focus:ring-2 focus:outline-none',\n day === null && 'invisible',\n day !== null && 'hover:bg-muted',\n day !== null &&\n !isCalendarDateInRange(day) &&\n 'cursor-not-allowed opacity-50',\n isSelectedDay(day!) &&\n 'bg-primary-800 hover:bg-primary-900 text-white',\n isToday(day!) &&\n !isSelectedDay(day!) &&\n 'border-primary-800 text-primary-800 border'\n )}\n >\n {day}\n </button>\n ))}\n </div>\n </>\n )}\n\n {inputType === 'datetime-local' && (\n <div className=\"border-border mt-3 flex items-center gap-2 border-t pt-3\">\n <select\n value={\n timeFormat === '12-hour'\n ? String(\n Number(selectedTime.slice(0, 2)) % 12 || 12\n ).padStart(2, '0')\n : selectedTime.slice(0, 2)\n }\n onChange={(event) => {\n const hour = Number(event.target.value);\n const isPm = Number(selectedTime.slice(0, 2)) >= 12;\n handleTimeChange(\n 'hour',\n String(\n timeFormat === '12-hour'\n ? (hour % 12) + (isPm ? 12 : 0)\n : hour\n ).padStart(2, '0')\n );\n }}\n className=\"bg-background border-border rounded border px-2 py-1 text-sm\"\n aria-label=\"Select hour\"\n >\n {Array.from(\n { length: timeFormat === '12-hour' ? 12 : 24 },\n (_, index) => (timeFormat === '12-hour' ? index + 1 : index)\n ).map((hour) => (\n <option key={hour} value={String(hour).padStart(2, '0')}>\n {String(hour).padStart(2, '0')}\n </option>\n ))}\n </select>\n <span aria-hidden=\"true\">:</span>\n <select\n value={selectedTime.slice(3)}\n onChange={(event) =>\n handleTimeChange('minute', event.target.value)\n }\n className=\"bg-background border-border rounded border px-2 py-1 text-sm\"\n aria-label=\"Select minute\"\n >\n {Array.from({ length: 60 }, (_, minute) => (\n <option key={minute} value={String(minute).padStart(2, '0')}>\n {String(minute).padStart(2, '0')}\n </option>\n ))}\n </select>\n {timeFormat === '12-hour' && (\n <select\n value={Number(selectedTime.slice(0, 2)) >= 12 ? 'PM' : 'AM'}\n onChange={(event) =>\n handleMeridiemChange(event.target.value as 'AM' | 'PM')\n }\n className=\"bg-background border-border rounded border px-2 py-1 text-sm\"\n aria-label=\"Select AM or PM\"\n >\n <option value=\"AM\">AM</option>\n <option value=\"PM\">PM</option>\n </select>\n )}\n </div>\n )}\n\n <div className=\"border-border mt-3 flex gap-2 border-t pt-3\">\n <button\n type=\"button\"\n onClick={() => {\n const today = new Date();\n setCalendarMonth(today.getMonth());\n setCalendarYear(today.getFullYear());\n if (inputType === 'month') {\n handleMonthSelect(today.getMonth());\n } else {\n handleDateSelect(today.getDate());\n }\n }}\n disabled={\n inputType === 'month'\n ? !isCalendarMonthInRange(\n new Date().getMonth(),\n new Date().getFullYear()\n )\n : !isDateInRange(new Date())\n }\n className=\"text-primary-800 flex-1 text-sm hover:underline disabled:cursor-not-allowed disabled:opacity-50\"\n >\n Today\n </button>\n {inputType === 'datetime-local' && (\n <button\n type=\"button\"\n onClick={() => setIsCalendarOpen(false)}\n className=\"text-primary-800 flex-1 text-sm hover:underline\"\n >\n Done\n </button>\n )}\n </div>\n </div>\n );\n };\n\n if (inputType === 'year') {\n return (\n <Input\n ref={ref}\n type={inputType === 'year' ? 'text' : inputType}\n inputMode={inputType === 'year' ? 'numeric' : undefined}\n pattern={inputType === 'year' ? '[0-9]{4}' : undefined}\n maxLength={inputType === 'year' ? 4 : undefined}\n placeholder={inputType === 'year' ? 'YYYY' : undefined}\n value={value.replace(/\\D/g, '').slice(0, 4)}\n onChange={(event) =>\n onChange?.(event.target.value.replace(/\\D/g, '').slice(0, 4))\n }\n onBlur={onBlur}\n onClick={onClick}\n hasError={hasError}\n error={error}\n className={cn(widthClasses[width], className)}\n {...props}\n />\n );\n }\n\n if (showCalendar || inputType !== 'date') {\n // Extract label/error/helper and component-specific props to handle positioning correctly\n // Filter out Input component props that aren't valid HTML input attributes\n const { label, helperText, hideLabel, required, size, ...inputProps } =\n props;\n // Ensure size has a valid value (fallback to 'md' if null/undefined)\n const resolvedSize = size ?? 'md';\n const inputId = inputProps.id || generatedId;\n const errorId = `${inputId}-error`;\n const helperId = `${inputId}-helper`;\n const showError = hasError || !!localError;\n const errorMessage = error || localError;\n\n return (\n <div className={cn('flex flex-col gap-1.5', widthClasses[width])}>\n {label && (\n <label\n htmlFor={inputId}\n className={cn(\n 'text-foreground text-sm font-medium',\n hideLabel && 'sr-only'\n )}\n >\n {label}\n {required && (\n <span\n className=\"ml-1\"\n style={{ color: '#ef4444' }}\n aria-hidden=\"true\"\n >\n *\n </span>\n )}\n </label>\n )}\n <div className=\"relative\">\n <input\n ref={ref}\n id={inputId}\n type=\"text\"\n inputMode={inputType === 'date' ? 'numeric' : undefined}\n autoComplete={autoComplete}\n placeholder={\n inputType === 'month'\n ? 'Select month'\n : inputType === 'datetime-local'\n ? 'Select date and time'\n : placeholder\n }\n value={formatPickerValue(displayValue, inputType, timeFormat)}\n onChange={handleChange}\n onBlur={inputType === 'date' ? handleBlur : onBlur}\n onClick={(event) => {\n onClick?.(event);\n setIsCalendarOpen(true);\n }}\n readOnly={!isFormattedDate}\n aria-invalid={showError}\n aria-describedby={\n [errorMessage ? errorId : null, helperText ? helperId : null]\n .filter(Boolean)\n .join(' ') || undefined\n }\n className={cn(\n 'w-full px-3 py-2',\n 'rounded-lg border',\n 'bg-background text-foreground',\n 'placeholder:text-muted-foreground',\n 'transition-colors duration-200',\n 'focus:ring-ring focus:border-transparent focus:ring-2 focus:outline-none',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n sizeClasses[resolvedSize],\n showError\n ? 'border-destructive focus:ring-destructive'\n : 'border-input',\n 'pr-10',\n className\n )}\n {...inputProps}\n />\n <button\n ref={buttonRef}\n type=\"button\"\n onClick={() => setIsCalendarOpen(!isCalendarOpen)}\n className={cn(\n 'absolute top-1/2 right-3 -translate-y-1/2',\n 'text-muted-foreground hover:text-foreground',\n 'focus:text-foreground focus:outline-none',\n 'transition-colors'\n )}\n aria-label=\"Open calendar\"\n aria-expanded={isCalendarOpen}\n aria-haspopup=\"dialog\"\n >\n <Calendar size={18} />\n </button>\n </div>\n {isCalendarOpen && createPortal(renderCalendar(), document.body)}\n {errorMessage && (\n <p\n id={errorId}\n className=\"text-sm\"\n style={{ color: '#ef4444' }}\n role=\"alert\"\n >\n {errorMessage}\n </p>\n )}\n {helperText && !errorMessage && (\n <p id={helperId} className=\"text-muted-foreground text-sm\">\n {helperText}\n </p>\n )}\n </div>\n );\n }\n\n return (\n <Input\n ref={ref}\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete={autoComplete}\n placeholder={placeholder}\n value={displayValue}\n onChange={handleChange}\n onBlur={handleBlur}\n hasError={hasError || !!localError}\n error={error || localError}\n className={cn(widthClasses[width], className)}\n {...props}\n />\n );\n }\n);\n\nDateInput.displayName = 'DateInput';\n\n// Simple icon components\nfunction ChevronLeftIcon() {\n return (\n <svg\n aria-hidden=\"true\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n );\n}\n\nfunction ChevronRightIcon() {\n return (\n <svg\n aria-hidden=\"true\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n );\n}\n\nexport { DateInput };\n"]}
|
|
@@ -80,10 +80,19 @@ var FenceBlock = ({
|
|
|
80
80
|
error ? /* @__PURE__ */ jsxs("div", { className: "p-3", children: [
|
|
81
81
|
/* @__PURE__ */ jsx("div", { className: "rounded-md bg-red-50 p-3 text-sm text-red-800 dark:bg-red-900/20 dark:text-red-300", children: error }),
|
|
82
82
|
/* @__PURE__ */ jsx("pre", { className: "mt-2 overflow-x-auto text-xs whitespace-pre-wrap text-neutral-600 dark:text-neutral-400", children: /* @__PURE__ */ jsx("code", { children: code }) })
|
|
83
|
-
] }) : showRaw ? /* @__PURE__ */ jsx(
|
|
83
|
+
] }) : showRaw ? /* @__PURE__ */ jsx(
|
|
84
|
+
"pre",
|
|
85
|
+
{
|
|
86
|
+
className: "overflow-x-auto p-3 text-sm",
|
|
87
|
+
tabIndex: 0,
|
|
88
|
+
role: "region",
|
|
89
|
+
"aria-label": "Raw code",
|
|
90
|
+
children: /* @__PURE__ */ jsx("code", { children: code })
|
|
91
|
+
}
|
|
92
|
+
) : /* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children })
|
|
84
93
|
] });
|
|
85
94
|
};
|
|
86
95
|
|
|
87
96
|
export { FenceBlock };
|
|
88
|
-
//# sourceMappingURL=chunk-
|
|
89
|
-
//# sourceMappingURL=chunk-
|
|
97
|
+
//# sourceMappingURL=chunk-RHYIFIT5.js.map
|
|
98
|
+
//# sourceMappingURL=chunk-RHYIFIT5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Markdown/FenceBlock.tsx"],"names":[],"mappings":"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","file":"chunk-RHYIFIT5.js","sourcesContent":["/**\n * FenceBlock — Base wrapper for code blocks with copy, raw view toggle, and errors.\n */\nimport { Check, ClipboardCopy, Code, Eye } from 'lucide-react';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { Button } from '../Button';\n\nexport interface FenceBlockProps {\n code: string;\n language?: string;\n supportsRawView?: boolean;\n error?: string;\n children: React.ReactNode;\n /** Extra buttons rendered in the header before the copy button */\n headerActions?: React.ReactNode;\n}\n\ntype CopyState = 'idle' | 'copying' | 'success' | 'error';\n\nexport const FenceBlock: React.FC<FenceBlockProps> = ({\n code,\n language,\n supportsRawView = false,\n error,\n children,\n headerActions,\n}) => {\n const [copyState, setCopyState] = useState<CopyState>('idle');\n const [showRaw, setShowRaw] = useState(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(\n () => () => {\n if (timerRef.current) clearTimeout(timerRef.current);\n },\n []\n );\n\n const scheduleReset = useCallback(() => {\n if (timerRef.current) clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => setCopyState('idle'), 2000);\n }, []);\n\n const handleCopy = useCallback(async () => {\n if (copyState === 'copying') return;\n setCopyState('copying');\n try {\n await navigator.clipboard.writeText(code);\n setCopyState('success');\n scheduleReset();\n } catch {\n try {\n const textarea = document.createElement('textarea');\n textarea.value = code;\n textarea.style.position = 'fixed';\n textarea.style.opacity = '0';\n document.body.appendChild(textarea);\n textarea.select();\n document.execCommand('copy');\n document.body.removeChild(textarea);\n setCopyState('success');\n } catch {\n setCopyState('error');\n }\n scheduleReset();\n }\n }, [code, copyState, scheduleReset]);\n\n return (\n <div className=\"group relative my-3 overflow-hidden rounded-lg border border-neutral-200 bg-neutral-50 dark:border-neutral-700 dark:bg-[#1a1d24]\">\n <div className=\"flex items-center justify-between border-b border-neutral-200 px-3 py-1.5 dark:border-white/[0.08]\">\n <span className=\"text-xs font-medium text-neutral-500 dark:text-neutral-400\">\n {language\n ? language.charAt(0).toUpperCase() + language.slice(1)\n : 'Text'}\n </span>\n <div className=\"flex items-center gap-1\">\n {headerActions}\n {supportsRawView && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setShowRaw((v) => !v)}\n aria-label={showRaw ? 'Show rendered view' : 'Show raw code'}\n className=\"h-7 w-7 p-0\"\n >\n {showRaw ? (\n <Eye className=\"h-3.5 w-3.5\" />\n ) : (\n <Code className=\"h-3.5 w-3.5\" />\n )}\n </Button>\n )}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleCopy}\n aria-label=\"Copy code\"\n className=\"h-7 w-7 p-0\"\n >\n {copyState === 'success' ? (\n <Check className=\"h-3.5 w-3.5 text-green-500\" />\n ) : (\n <ClipboardCopy className=\"h-3.5 w-3.5\" />\n )}\n </Button>\n </div>\n </div>\n\n {error ? (\n <div className=\"p-3\">\n <div className=\"rounded-md bg-red-50 p-3 text-sm text-red-800 dark:bg-red-900/20 dark:text-red-300\">\n {error}\n </div>\n <pre className=\"mt-2 overflow-x-auto text-xs whitespace-pre-wrap text-neutral-600 dark:text-neutral-400\">\n <code>{code}</code>\n </pre>\n </div>\n ) : showRaw ? (\n <pre\n className=\"overflow-x-auto p-3 text-sm\"\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- scrollable code needs keyboard focus (axe: scrollable-region-focusable)\n tabIndex={0}\n role=\"region\"\n aria-label=\"Raw code\"\n >\n <code>{code}</code>\n </pre>\n ) : (\n <div className=\"overflow-x-auto\">{children}</div>\n )}\n </div>\n );\n};\n"]}
|
|
@@ -158,7 +158,7 @@ var TranscriptView = React.forwardRef(
|
|
|
158
158
|
"data-transcript-index": index,
|
|
159
159
|
"aria-current": isActive ? "true" : void 0,
|
|
160
160
|
className: `hover:bg-muted focus-visible:ring-ring flex w-full cursor-pointer gap-3 rounded px-2 py-1 text-left text-sm transition-colors focus-visible:ring-2 focus-visible:outline-none ${isActive ? "bg-primary-500/20" : ""}`,
|
|
161
|
-
|
|
161
|
+
onClick: () => seekTo(row.startMs),
|
|
162
162
|
children: [
|
|
163
163
|
showTimestamps && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground w-12 shrink-0 font-mono", children: formatTimestampMs(row.startMs) }),
|
|
164
164
|
speaker && /* @__PURE__ */ jsxs("span", { className: "text-primary-900 w-24 shrink-0 font-semibold", children: [
|
|
@@ -193,5 +193,5 @@ var TranscriptView = React.forwardRef(
|
|
|
193
193
|
TranscriptView.displayName = "TranscriptView";
|
|
194
194
|
|
|
195
195
|
export { TranscriptView, formatTimestampMs };
|
|
196
|
-
//# sourceMappingURL=chunk-
|
|
197
|
-
//# sourceMappingURL=chunk-
|
|
196
|
+
//# sourceMappingURL=chunk-SEPYBAML.js.map
|
|
197
|
+
//# sourceMappingURL=chunk-SEPYBAML.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/TranscriptView/TranscriptView.tsx"],"names":[],"mappings":"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","file":"chunk-SEPYBAML.js","sourcesContent":["import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type {\n Transcript,\n TranscriptSegment,\n TranscriptWord,\n} from './transcript';\n\n// ============================================================================\n// Types & Interfaces\n// ============================================================================\n\nexport type TranscriptGranularity = 'word' | 'segment';\n\nexport interface TranscriptViewProps extends VariantProps<\n typeof transcriptViewVariants\n> {\n /** The transcript to render */\n transcript: Transcript;\n /**\n * Rendering granularity. Defaults to 'segment' when the transcript has\n * segments, otherwise 'word'.\n */\n granularity?: TranscriptGranularity;\n /** Controlled playback position (ms); the matching word/segment is highlighted */\n currentTimeMs?: number;\n /** Called with the start time (ms) of a clicked word/segment; the host performs the seek/play */\n onSeek?: (timeMs: number) => void;\n /** Auto-scroll the active word/segment into view (default true) */\n followPlayback?: boolean;\n /**\n * Maps Speaker.id to a display label (e.g. Clinician/Patient). Falls back to\n * Speaker.name from transcript.speakers, then the raw id.\n */\n speakerLabels?: Record<string, string>;\n /** Segment mode: merge consecutive same-speaker segments into one row (default false) */\n mergeSameSpeaker?: boolean;\n /** Segment mode: show mm:ss timestamps (default true) */\n showTimestamps?: boolean;\n /** Rendered in a header row (host supplies copy/re-transcribe/remove buttons) */\n actions?: React.ReactNode;\n /** Additional class name */\n className?: string;\n /** Accessible label for the transcript container (default 'Transcript') */\n 'aria-label'?: string;\n}\n\n// ============================================================================\n// Variants\n// ============================================================================\n\nconst transcriptViewVariants = cva('flex flex-col text-foreground', {\n variants: {\n variant: {\n plain: '',\n card: 'rounded-xl border border-border bg-card text-card-foreground p-3',\n },\n },\n defaultVariants: {\n variant: 'plain',\n },\n});\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/** Format milliseconds as m:ss (osheet timestamp style) */\nexport function formatTimestampMs(ms: number): string {\n const totalSeconds = Math.floor(ms / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return `${minutes}:${String(seconds).padStart(2, '0')}`;\n}\n\n/** Resolve a speaker id to its display label */\nfunction resolveSpeakerLabel(\n speakerId: string | undefined,\n speakerLabels: Record<string, string> | undefined,\n transcript: Transcript\n): string | undefined {\n if (!speakerId) return undefined;\n return (\n speakerLabels?.[speakerId] ??\n transcript.speakers?.find((s) => s.id === speakerId)?.name ??\n speakerId\n );\n}\n\n/** A display row in segment mode (possibly the merge of several source segments) */\ninterface SegmentRow {\n text: string;\n startMs: number;\n endMs: number;\n speakerId?: string;\n}\n\n/**\n * Build segment display rows, optionally merging consecutive same-speaker\n * segments (osheet formatTranscriptText behavior). Empty segments are skipped.\n */\nfunction buildSegmentRows(\n segments: TranscriptSegment[],\n merge: boolean\n): SegmentRow[] {\n const rows: SegmentRow[] = [];\n for (const segment of segments) {\n const text = segment.text.trim();\n if (!text) continue;\n const prev = rows[rows.length - 1];\n if (merge && prev && prev.speakerId === segment.speakerId) {\n prev.text += ' ' + text;\n prev.endMs = segment.endMs;\n } else {\n rows.push({\n text,\n startMs: segment.startMs,\n endMs: segment.endMs,\n speakerId: segment.speakerId,\n });\n }\n }\n return rows;\n}\n\n/** Index of the item whose [startMs, endMs) range contains timeMs, or -1 */\nfunction findActiveIndex(\n items: ReadonlyArray<{ startMs: number; endMs: number }>,\n timeMs: number | undefined\n): number {\n if (timeMs === undefined) return -1;\n return items.findIndex(\n (item) => timeMs >= item.startMs && timeMs < item.endMs\n );\n}\n\n/** Run onActivate for click and Enter/Space keyboard activation */\nfunction activationProps(onActivate: () => void) {\n return {\n onClick: onActivate,\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onActivate();\n }\n },\n };\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * Read-only transcript viewer with word-level and segment-level (diarized)\n * rendering modes.\n *\n * Controlled and persistence-agnostic: the host owns playback and passes the\n * position via `currentTimeMs`; clicking a word/segment reports the target\n * time through `onSeek`. Segment mode matches the osheet artifact-viewer row\n * UX (timestamp | speaker | text, click to seek + play). Editing lives in\n * MediaEditor, not here.\n */\nexport const TranscriptView = React.forwardRef<\n HTMLDivElement,\n TranscriptViewProps\n>(\n (\n {\n transcript,\n granularity,\n currentTimeMs,\n onSeek,\n followPlayback = true,\n speakerLabels,\n mergeSameSpeaker = false,\n showTimestamps = true,\n actions,\n variant,\n className,\n 'aria-label': ariaLabel = 'Transcript',\n },\n ref\n ) => {\n const contentRef = React.useRef<HTMLDivElement>(null);\n const isHoveringRef = React.useRef(false);\n\n const resolvedGranularity: TranscriptGranularity =\n granularity ??\n (transcript.segments && transcript.segments.length > 0\n ? 'segment'\n : 'word');\n\n const segmentRows = React.useMemo(\n () =>\n resolvedGranularity === 'segment'\n ? buildSegmentRows(transcript.segments ?? [], mergeSameSpeaker)\n : [],\n [resolvedGranularity, transcript.segments, mergeSameSpeaker]\n );\n\n const activeIndex =\n resolvedGranularity === 'segment'\n ? findActiveIndex(segmentRows, currentTimeMs)\n : findActiveIndex(transcript.words, currentTimeMs);\n\n // Auto-scroll the active item into view, unless the user is hovering\n React.useEffect(() => {\n if (!followPlayback || activeIndex < 0 || isHoveringRef.current) return;\n const el = contentRef.current?.querySelector(\n `[data-transcript-index=\"${activeIndex}\"]`\n );\n el?.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n }, [followPlayback, activeIndex]);\n\n const seekTo = (timeMs: number) => onSeek?.(timeMs);\n\n // ------------------------------------------------------------------\n // Word mode rendering\n // ------------------------------------------------------------------\n const renderWord = (word: TranscriptWord, index: number) => {\n const isActive = index === activeIndex;\n const wordType = word.wordType ?? 'word';\n const durationSec = ((word.endMs - word.startMs) / 1000).toFixed(1);\n\n if (wordType === 'silence-newline') {\n // Longer pause: force a line break (block element inside inline flow)\n return (\n <span\n key={index}\n data-transcript-index={index}\n role=\"button\"\n tabIndex={0}\n aria-current={isActive ? 'true' : undefined}\n aria-label={`Silence, ${durationSec} seconds`}\n className={`hover:bg-muted focus-visible:ring-ring block h-3 cursor-pointer rounded transition-colors focus-visible:ring-2 focus-visible:outline-none ${\n isActive ? 'bg-primary-500/20' : ''\n }`}\n {...activationProps(() => seekTo(word.startMs))}\n />\n );\n }\n\n if (wordType === 'silence') {\n // Short gap: subtle interpunct\n return (\n <span\n key={index}\n data-transcript-index={index}\n role=\"button\"\n tabIndex={0}\n aria-current={isActive ? 'true' : undefined}\n aria-label={`Silence, ${durationSec} seconds`}\n className={`text-muted-foreground/60 hover:bg-muted focus-visible:ring-ring cursor-pointer rounded px-0.5 transition-colors focus-visible:ring-2 focus-visible:outline-none ${\n isActive ? 'bg-primary-500/20' : ''\n }`}\n {...activationProps(() => seekTo(word.startMs))}\n >\n {'\\u00B7 '}\n </span>\n );\n }\n\n return (\n <span\n key={index}\n data-transcript-index={index}\n role=\"button\"\n tabIndex={0}\n aria-current={isActive ? 'true' : undefined}\n className={`hover:bg-muted focus-visible:ring-ring cursor-pointer rounded px-0.5 transition-colors focus-visible:ring-2 focus-visible:outline-none ${\n isActive ? 'bg-primary-500/20 text-foreground' : ''\n }`}\n {...activationProps(() => seekTo(word.startMs))}\n >\n {word.text}{' '}\n </span>\n );\n };\n\n // ------------------------------------------------------------------\n // Segment mode rendering (osheet artifact-viewer row parity)\n // ------------------------------------------------------------------\n const renderSegmentRow = (row: SegmentRow, index: number) => {\n const isActive = index === activeIndex;\n const speaker = resolveSpeakerLabel(\n row.speakerId,\n speakerLabels,\n transcript\n );\n\n return (\n <div key={index} role=\"listitem\">\n <button\n type=\"button\"\n data-transcript-index={index}\n aria-current={isActive ? 'true' : undefined}\n className={`hover:bg-muted focus-visible:ring-ring flex w-full cursor-pointer gap-3 rounded px-2 py-1 text-left text-sm transition-colors focus-visible:ring-2 focus-visible:outline-none ${\n isActive ? 'bg-primary-500/20' : ''\n }`}\n onClick={() => seekTo(row.startMs)}\n >\n {showTimestamps && (\n <span className=\"text-muted-foreground w-12 shrink-0 font-mono\">\n {formatTimestampMs(row.startMs)}\n </span>\n )}\n {speaker && (\n <span className=\"text-primary-900 w-24 shrink-0 font-semibold\">\n {speaker}:\n </span>\n )}\n <span className=\"text-foreground\">{row.text}</span>\n </button>\n </div>\n );\n };\n\n return (\n <div ref={ref} className={transcriptViewVariants({ variant, className })}>\n {actions && (\n <div className=\"border-border mb-2 flex items-center justify-end gap-2 border-b pb-2\">\n {actions}\n </div>\n )}\n <div\n ref={contentRef}\n aria-label={ariaLabel}\n onMouseEnter={() => {\n isHoveringRef.current = true;\n }}\n onMouseLeave={() => {\n isHoveringRef.current = false;\n }}\n {...(resolvedGranularity === 'segment'\n ? { role: 'list', className: 'space-y-2' }\n : { className: 'text-sm leading-relaxed' })}\n >\n {resolvedGranularity === 'segment'\n ? segmentRows.map(renderSegmentRow)\n : transcript.words.map(renderWord)}\n </div>\n </div>\n );\n }\n);\n\nTranscriptView.displayName = 'TranscriptView';\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FenceBlock } from './chunk-
|
|
1
|
+
import { FenceBlock } from './chunk-RHYIFIT5.js';
|
|
2
2
|
import DOMPurify from 'dompurify';
|
|
3
3
|
import { useState, useMemo, useCallback, useEffect } from 'react';
|
|
4
4
|
import { jsx } from 'react/jsx-runtime';
|
|
@@ -144,5 +144,5 @@ var MermaidBlock = ({ code, id }) => {
|
|
|
144
144
|
};
|
|
145
145
|
|
|
146
146
|
export { MermaidBlock };
|
|
147
|
-
//# sourceMappingURL=chunk-
|
|
148
|
-
//# sourceMappingURL=chunk-
|
|
147
|
+
//# sourceMappingURL=chunk-T3RWXOCM.js.map
|
|
148
|
+
//# sourceMappingURL=chunk-T3RWXOCM.js.map
|