@reopt-ai/opt-ui 1.14.0 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/COMPONENT_CATALOG.md +222 -69
  3. package/README.md +26 -0
  4. package/dist/core/index.cjs +4 -4
  5. package/dist/core/index.d.cts +2 -2
  6. package/dist/core/index.d.ts +2 -2
  7. package/dist/core/index.js +2 -2
  8. package/dist/docs/02-components/01-core.md +37 -33
  9. package/dist/docs/02-components/02-visuals.md +1 -1
  10. package/dist/docs/02-components/03-shells.md +191 -36
  11. package/dist/docs/02-components/04-surfaces.md +1 -1
  12. package/dist/docs/02-components/index.md +4 -4
  13. package/dist/id-registry.cjs +24 -0
  14. package/dist/id-registry.js +24 -0
  15. package/dist/id-registry.json +51 -0
  16. package/dist/index.cjs +445 -381
  17. package/dist/index.d.cts +16 -13
  18. package/dist/index.d.ts +16 -13
  19. package/dist/index.js +303 -245
  20. package/dist/{key-pad-menu-CqFI6la9.js → key-pad-menu-BCOeYvsH.js} +50 -61
  21. package/dist/{key-pad-menu-D6pYzaj-.d.cts → key-pad-menu-CaIsTHB2.d.cts} +12 -8
  22. package/dist/{key-pad-menu-BgtSL3xe.cjs → key-pad-menu-Jaqxhx9P.cjs} +48 -71
  23. package/dist/{key-pad-menu-Yh7Fpb8m.d.ts → key-pad-menu-odAEycIX.d.ts} +12 -8
  24. package/dist/meta.cjs +447 -7
  25. package/dist/meta.js +447 -7
  26. package/dist/{field-sidebar-mSVCMAZp.js → replay-player-layout-BVUNsUS1.js} +891 -191
  27. package/dist/{field-sidebar-ePqFX6MN.cjs → replay-player-layout-Cmzptq89.cjs} +931 -189
  28. package/dist/{field-sidebar-CJ4HxP8D.d.cts → replay-player-layout-DpqdfdQ6.d.ts} +246 -3
  29. package/dist/{field-sidebar-DnhpcT2A.d.ts → replay-player-layout-DuZW-gFF.d.cts} +246 -3
  30. package/dist/shells/index.cjs +58 -52
  31. package/dist/shells/index.d.cts +2 -2
  32. package/dist/shells/index.d.ts +2 -2
  33. package/dist/shells/index.js +2 -2
  34. package/dist/{text-truncate-Bd-0WkSP.js → text-truncate-B-8nJgnu.js} +200 -101
  35. package/dist/{text-truncate-Bbul-jMD.d.cts → text-truncate-DOxUijpB.d.cts} +2 -0
  36. package/dist/{text-truncate-Bbul-jMD.d.ts → text-truncate-DOxUijpB.d.ts} +2 -0
  37. package/dist/{text-truncate-BeYW6XZu.cjs → text-truncate-gQhpMy-Z.cjs} +214 -97
  38. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const require_text_truncate = require("./text-truncate-BeYW6XZu.cjs");
4
- const require_key_pad_menu = require("./key-pad-menu-BgtSL3xe.cjs");
5
- const require_field_sidebar = require("./field-sidebar-ePqFX6MN.cjs");
3
+ const require_text_truncate = require("./text-truncate-gQhpMy-Z.cjs");
4
+ const require_key_pad_menu = require("./key-pad-menu-Jaqxhx9P.cjs");
5
+ const require_replay_player_layout = require("./replay-player-layout-Cmzptq89.cjs");
6
6
  let react_jsx_runtime = require("react/jsx-runtime");
7
7
  let react = require("react");
8
8
  react = require_text_truncate.__toESM(react, 1);
@@ -1127,9 +1127,14 @@ function TeamMemberList({ members, title, layout = "list", maxDisplay, onMemberC
1127
1127
  //#region src/shells/auth-form.tsx
1128
1128
  /** Renders the auth form component. */
1129
1129
  function AuthForm({ defaultMode = "login", mode: controlledMode, onModeChange, showRememberMe = true, minPasswordLength = 8, onSubmit, renderExtraFields, labels = {}, ariaLabel }) {
1130
- var _labels$loginTitle, _labels$signupTitle, _labels$emailLabel, _labels$passwordLabel, _labels$confirmPasswo, _labels$rememberMeLab, _labels$loginButton, _labels$signupButton;
1130
+ var _labels$loginTitle, _labels$signupTitle, _labels$emailLabel, _labels$passwordLabel, _labels$confirmPasswo, _labels$rememberMeLab, _labels$loginButton, _labels$signupButton, _labels$submitError;
1131
1131
  const [uncontrolledMode, setUncontrolledMode] = (0, react.useState)(defaultMode);
1132
1132
  const [submitted, setSubmitted] = (0, react.useState)(false);
1133
+ (0, react.useEffect)(() => {
1134
+ if (!submitted) return;
1135
+ const timer = setTimeout(() => setSubmitted(false), 3e3);
1136
+ return () => clearTimeout(timer);
1137
+ }, [submitted]);
1133
1138
  const mode = controlledMode !== null && controlledMode !== void 0 ? controlledMode : uncontrolledMode;
1134
1139
  const handleModeChange = (newMode) => {
1135
1140
  if (controlledMode === void 0) setUncontrolledMode(newMode);
@@ -1168,13 +1173,13 @@ function AuthForm({ defaultMode = "login", mode: controlledMode, onModeChange, s
1168
1173
  }
1169
1174
  return errors;
1170
1175
  },
1171
- onSubmit: (values) => {
1172
- setSubmitted(true);
1173
- setTimeout(() => setSubmitted(false), 3e3);
1174
- if (onSubmit) onSubmit(require_text_truncate._objectSpread2(require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({
1176
+ onSubmit: async (values) => {
1177
+ setSubmitted(false);
1178
+ if (onSubmit) await onSubmit(require_text_truncate._objectSpread2(require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({
1175
1179
  email: values.email,
1176
1180
  password: values.password
1177
1181
  }, mode === "signup" ? { confirmPassword: values.confirmPassword } : {}), mode === "login" ? { rememberMe: values.rememberMe } : {}), {}, { mode }));
1182
+ setSubmitted(true);
1178
1183
  }
1179
1184
  });
1180
1185
  const loginTitle = (_labels$loginTitle = labels.loginTitle) !== null && _labels$loginTitle !== void 0 ? _labels$loginTitle : "로그인";
@@ -1189,11 +1194,13 @@ function AuthForm({ defaultMode = "login", mode: controlledMode, onModeChange, s
1189
1194
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1190
1195
  type: "button",
1191
1196
  className: `flex-1 rounded-l-lg px-4 py-2 text-sm font-medium transition-colors ${mode === "login" ? "bg-accent text-accent-fg" : "text-text-secondary hover:bg-bg-subtle"}`,
1197
+ disabled: form.isSubmitting(),
1192
1198
  onClick: () => handleModeChange("login"),
1193
1199
  children: loginTitle
1194
1200
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1195
1201
  type: "button",
1196
1202
  className: `flex-1 rounded-r-lg px-4 py-2 text-sm font-medium transition-colors ${mode === "signup" ? "bg-accent text-accent-fg" : "text-text-secondary hover:bg-bg-subtle"}`,
1203
+ disabled: form.isSubmitting(),
1197
1204
  onClick: () => handleModeChange("signup"),
1198
1205
  children: signupTitle
1199
1206
  })]
@@ -1202,8 +1209,8 @@ function AuthForm({ defaultMode = "login", mode: controlledMode, onModeChange, s
1202
1209
  store: form,
1203
1210
  "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : mode === "login" ? "로그인 폼" : "회원가입 폼",
1204
1211
  children: [
1205
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1206
- className: "gap-element flex flex-col",
1212
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.FormField, {
1213
+ name: "email",
1207
1214
  children: [
1208
1215
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormLabel, {
1209
1216
  name: "email",
@@ -1218,8 +1225,8 @@ function AuthForm({ defaultMode = "login", mode: controlledMode, onModeChange, s
1218
1225
  ]
1219
1226
  }),
1220
1227
  renderExtraFields === null || renderExtraFields === void 0 ? void 0 : renderExtraFields(mode),
1221
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1222
- className: "gap-element flex flex-col",
1228
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.FormField, {
1229
+ name: "password",
1223
1230
  children: [
1224
1231
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormLabel, {
1225
1232
  name: "password",
@@ -1233,8 +1240,8 @@ function AuthForm({ defaultMode = "login", mode: controlledMode, onModeChange, s
1233
1240
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormError, { name: "password" })
1234
1241
  ]
1235
1242
  }),
1236
- mode === "signup" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1237
- className: "gap-element flex flex-col",
1243
+ mode === "signup" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.FormField, {
1244
+ name: "confirmPassword",
1238
1245
  children: [
1239
1246
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormLabel, {
1240
1247
  name: "confirmPassword",
@@ -1264,7 +1271,13 @@ function AuthForm({ defaultMode = "login", mode: controlledMode, onModeChange, s
1264
1271
  })
1265
1272
  ]
1266
1273
  }),
1274
+ form.getSubmitError() !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1275
+ role: "alert",
1276
+ className: "border-danger bg-danger-subtle text-danger-fg rounded-lg border p-3 text-sm",
1277
+ children: (_labels$submitError = labels.submitError) !== null && _labels$submitError !== void 0 ? _labels$submitError : "처리에 실패했습니다. 다시 시도해주세요."
1278
+ }),
1267
1279
  submitted && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1280
+ role: "status",
1268
1281
  className: "border-success bg-success-subtle text-success-fg rounded-lg border p-3 text-sm",
1269
1282
  children: mode === "login" ? "로그인 성공!" : "회원가입 완료!"
1270
1283
  })
@@ -1275,11 +1288,16 @@ function AuthForm({ defaultMode = "login", mode: controlledMode, onModeChange, s
1275
1288
  //#region src/shells/dynamic-field-form.tsx
1276
1289
  /** Renders the dynamic field form component. */
1277
1290
  function DynamicFieldForm({ initialCount = 1, minFields = 1, maxFields, fieldType = "text", validateField, onSubmit, onFieldsChange, labels = {}, ariaLabel }) {
1278
- var _labels$itemLabel, _labels$itemPlacehold, _labels$removeAriaLab, _labels$addButton, _labels$submitButton;
1291
+ var _labels$itemLabel, _labels$itemPlacehold, _labels$removeAriaLab, _labels$addButton, _labels$submitButton, _labels$submitError;
1279
1292
  const initialFields = Array.from({ length: initialCount }, (_, i) => ({ id: i + 1 }));
1280
1293
  const [fields, setFields] = (0, react.useState)(initialFields);
1281
1294
  const [nextId, setNextId] = (0, react.useState)(initialCount + 1);
1282
1295
  const [submitted, setSubmitted] = (0, react.useState)(false);
1296
+ (0, react.useEffect)(() => {
1297
+ if (!submitted) return;
1298
+ const timer = setTimeout(() => setSubmitted(false), 3e3);
1299
+ return () => clearTimeout(timer);
1300
+ }, [submitted]);
1283
1301
  const [submittedValues, setSubmittedValues] = (0, react.useState)([]);
1284
1302
  const form = (0, _reopt_ai_opt_ui_primitives.useFormStore)({
1285
1303
  defaultValues: { items: Array.from({ length: initialCount }, () => "") },
@@ -1303,12 +1321,12 @@ function DynamicFieldForm({ initialCount = 1, minFields = 1, maxFields, fieldTyp
1303
1321
  }
1304
1322
  return errors;
1305
1323
  },
1306
- onSubmit: (values) => {
1324
+ onSubmit: async (values) => {
1325
+ setSubmitted(false);
1307
1326
  const items = [...values.items];
1327
+ await (onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit(items));
1308
1328
  setSubmittedValues(items);
1309
1329
  setSubmitted(true);
1310
- setTimeout(() => setSubmitted(false), 3e3);
1311
- onSubmit === null || onSubmit === void 0 || onSubmit(items);
1312
1330
  }
1313
1331
  });
1314
1332
  const addField = () => {
@@ -1339,70 +1357,79 @@ function DynamicFieldForm({ initialCount = 1, minFields = 1, maxFields, fieldTyp
1339
1357
  className: "gap-group flex flex-col",
1340
1358
  "data-opt-id": "8RYG7",
1341
1359
  "data-opt-slug": "form-dynamic.DynamicFieldForm",
1342
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.FormRoot, {
1343
- store: form,
1344
- "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : "동적 필드 폼",
1345
- children: [
1346
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1347
- className: "gap-group flex flex-col",
1348
- children: fields.map((field, displayIndex) => {
1349
- const fieldName = `items.${displayIndex}`;
1350
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1351
- className: "gap-element flex flex-col",
1352
- children: [
1353
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormLabel, {
1354
- name: fieldName,
1355
- children: formatTemplate(itemLabel, displayIndex + 1)
1356
- }),
1357
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1358
- className: "gap-element flex",
1359
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1360
- className: "flex-1",
1361
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormInput, {
1362
- name: fieldName,
1363
- type: fieldType,
1364
- placeholder: formatTemplate(itemPlaceholder, displayIndex + 1)
1365
- })
1366
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1367
- type: "button",
1368
- onClick: () => removeField(field.id),
1369
- disabled: fields.length <= minFields,
1370
- className: "border-border text-text-tertiary hover:border-danger hover:bg-danger-subtle hover:text-danger-fg inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-lg border transition-colors disabled:cursor-not-allowed disabled:opacity-30",
1371
- "aria-label": formatTemplate(removeAriaLabel, displayIndex + 1),
1372
- children: "✕"
1373
- })]
1374
- }),
1375
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormError, { name: fieldName })
1376
- ]
1377
- }, field.id);
1360
+ children: [
1361
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.FormRoot, {
1362
+ store: form,
1363
+ "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : "동적 필드 폼",
1364
+ children: [
1365
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1366
+ className: "gap-group flex flex-col",
1367
+ children: fields.map((field, displayIndex) => {
1368
+ const fieldName = `items.${displayIndex}`;
1369
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.FormField, {
1370
+ name: fieldName,
1371
+ children: [
1372
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormLabel, {
1373
+ name: fieldName,
1374
+ children: formatTemplate(itemLabel, displayIndex + 1)
1375
+ }),
1376
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1377
+ className: "gap-element flex",
1378
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1379
+ className: "flex-1",
1380
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormInput, {
1381
+ name: fieldName,
1382
+ type: fieldType,
1383
+ placeholder: formatTemplate(itemPlaceholder, displayIndex + 1)
1384
+ })
1385
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1386
+ type: "button",
1387
+ onClick: () => removeField(field.id),
1388
+ disabled: form.isSubmitting() || fields.length <= minFields,
1389
+ className: "border-border text-text-tertiary hover:border-danger hover:bg-danger-subtle hover:text-danger-fg inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-lg border transition-colors disabled:cursor-not-allowed disabled:opacity-30",
1390
+ "aria-label": formatTemplate(removeAriaLabel, displayIndex + 1),
1391
+ children: "✕"
1392
+ })]
1393
+ }),
1394
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormError, { name: fieldName })
1395
+ ]
1396
+ }, field.id);
1397
+ })
1398
+ }),
1399
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1400
+ type: "button",
1401
+ onClick: addField,
1402
+ disabled: form.isSubmitting() || maxFields !== void 0 && fields.length >= maxFields,
1403
+ className: "border-border text-text-secondary hover:border-accent hover:bg-accent-subtle hover:text-accent w-full rounded-lg border border-dashed px-4 py-2.5 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-30",
1404
+ children: (_labels$addButton = labels.addButton) !== null && _labels$addButton !== void 0 ? _labels$addButton : "+ 항목 추가"
1405
+ }),
1406
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormSubmit, {
1407
+ disabled: form.isSubmitting(),
1408
+ children: (_labels$submitButton = labels.submitButton) !== null && _labels$submitButton !== void 0 ? _labels$submitButton : "제출"
1378
1409
  })
1379
- }),
1380
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1381
- type: "button",
1382
- onClick: addField,
1383
- disabled: maxFields !== void 0 && fields.length >= maxFields,
1384
- className: "border-border text-text-secondary hover:border-accent hover:bg-accent-subtle hover:text-accent w-full rounded-lg border border-dashed px-4 py-2.5 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-30",
1385
- children: (_labels$addButton = labels.addButton) !== null && _labels$addButton !== void 0 ? _labels$addButton : "+ 항목 추가"
1386
- }),
1387
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormSubmit, {
1388
- disabled: form.isSubmitting(),
1389
- children: (_labels$submitButton = labels.submitButton) !== null && _labels$submitButton !== void 0 ? _labels$submitButton : "제출"
1390
- })
1391
- ]
1392
- }), submitted && submittedValues.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1393
- className: "border-success bg-success-subtle rounded-lg border p-3",
1394
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1395
- className: "text-success-fg mb-2 text-sm font-medium",
1396
- children: "제출된 값:"
1397
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
1398
- className: "text-success-fg gap-element flex flex-col text-sm",
1399
- children: submittedValues.map((val, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
1400
- formatTemplate(itemLabel, i + 1),
1401
- ": ",
1402
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: val })
1403
- ] }, i))
1404
- })]
1405
- })]
1410
+ ]
1411
+ }),
1412
+ form.getSubmitError() !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1413
+ role: "alert",
1414
+ className: "border-danger bg-danger-subtle text-danger-fg rounded-lg border p-3 text-sm",
1415
+ children: (_labels$submitError = labels.submitError) !== null && _labels$submitError !== void 0 ? _labels$submitError : "처리에 실패했습니다. 다시 시도해주세요."
1416
+ }),
1417
+ submitted && submittedValues.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1418
+ role: "status",
1419
+ className: "border-success bg-success-subtle rounded-lg border p-3",
1420
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1421
+ className: "text-success-fg mb-2 text-sm font-medium",
1422
+ children: "제출된 값:"
1423
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
1424
+ className: "text-success-fg gap-element flex flex-col text-sm",
1425
+ children: submittedValues.map((val, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
1426
+ formatTemplate(itemLabel, i + 1),
1427
+ ": ",
1428
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: val })
1429
+ ] }, i))
1430
+ })]
1431
+ })
1432
+ ]
1406
1433
  });
1407
1434
  }
1408
1435
  //#endregion
@@ -1414,10 +1441,16 @@ function formatFileSize(bytes) {
1414
1441
  }
1415
1442
  /** Renders the file upload form component. */
1416
1443
  function FileUploadForm({ accept = "image/*,.pdf,.doc,.docx", showPreview = true, showFileInfo = true, showDescription = true, descriptionRows = 3, titleRequired = true, maxFileSize, onSubmit, onFileChange, onPreview, columnMapping, labels = {}, ariaLabel }) {
1417
- var _labels$titleLabel, _labels$titlePlacehol, _labels$descriptionLa, _labels$descriptionPl, _labels$fileLabel, _labels$columnMapping, _labels$submitButton, _labels$successMessag;
1444
+ var _labels$titleLabel, _labels$titlePlacehol, _labels$descriptionLa, _labels$descriptionPl, _labels$fileLabel, _labels$columnMapping, _labels$submitButton, _labels$submitError, _labels$successMessag;
1445
+ const fileId = (0, react.useId)();
1418
1446
  const [selectedFile, setSelectedFile] = (0, react.useState)(null);
1419
1447
  const [preview, setPreview] = (0, react.useState)(null);
1420
1448
  const [submitted, setSubmitted] = (0, react.useState)(false);
1449
+ (0, react.useEffect)(() => {
1450
+ if (!submitted) return;
1451
+ const timer = setTimeout(() => setSubmitted(false), 3e3);
1452
+ return () => clearTimeout(timer);
1453
+ }, [submitted]);
1421
1454
  const [fileSizeError, setFileSizeError] = (0, react.useState)(null);
1422
1455
  const form = (0, _reopt_ai_opt_ui_primitives.useFormStore)({
1423
1456
  defaultValues: {
@@ -1435,14 +1468,14 @@ function FileUploadForm({ accept = "image/*,.pdf,.doc,.docx", showPreview = true
1435
1468
  }
1436
1469
  return errors;
1437
1470
  },
1438
- onSubmit: (values) => {
1439
- setSubmitted(true);
1440
- setTimeout(() => setSubmitted(false), 3e3);
1441
- if (onSubmit) onSubmit({
1471
+ onSubmit: async (values) => {
1472
+ setSubmitted(false);
1473
+ if (onSubmit) await onSubmit({
1442
1474
  title: values.title,
1443
1475
  description: values.description,
1444
1476
  file: selectedFile
1445
1477
  });
1478
+ setSubmitted(true);
1446
1479
  }
1447
1480
  });
1448
1481
  const handleFileChange = (e) => {
@@ -1474,111 +1507,128 @@ function FileUploadForm({ accept = "image/*,.pdf,.doc,.docx", showPreview = true
1474
1507
  className: "gap-group flex flex-col",
1475
1508
  "data-opt-id": "4E3MD",
1476
1509
  "data-opt-slug": "form-upload.FileUploadForm",
1477
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.FormRoot, {
1478
- store: form,
1479
- "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : "파일 업로드 폼",
1480
- children: [
1481
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1482
- className: "gap-element flex flex-col",
1483
- children: [
1484
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormLabel, {
1485
- name: "title",
1486
- children: (_labels$titleLabel = labels.titleLabel) !== null && _labels$titleLabel !== void 0 ? _labels$titleLabel : "제목"
1487
- }),
1488
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormInput, {
1489
- name: "title",
1490
- placeholder: (_labels$titlePlacehol = labels.titlePlaceholder) !== null && _labels$titlePlacehol !== void 0 ? _labels$titlePlacehol : "파일 제목을 입력하세요"
1491
- }),
1492
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormError, { name: "title" })
1493
- ]
1494
- }),
1495
- showDescription && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1496
- className: "gap-element flex flex-col",
1497
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormLabel, {
1498
- name: "description",
1499
- children: (_labels$descriptionLa = labels.descriptionLabel) !== null && _labels$descriptionLa !== void 0 ? _labels$descriptionLa : "설명"
1500
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormTextarea, {
1501
- name: "description",
1502
- placeholder: (_labels$descriptionPl = labels.descriptionPlaceholder) !== null && _labels$descriptionPl !== void 0 ? _labels$descriptionPl : "파일에 대한 설명을 입력하세요",
1503
- rows: descriptionRows,
1504
- resize: "none"
1505
- })]
1506
- }),
1507
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1508
- className: "gap-element flex flex-col",
1509
- children: [
1510
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
1511
- className: "text-text-primary text-sm font-medium",
1512
- children: (_labels$fileLabel = labels.fileLabel) !== null && _labels$fileLabel !== void 0 ? _labels$fileLabel : "파일 선택"
1513
- }),
1514
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1515
- className: "relative",
1516
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1517
- type: "file",
1518
- onChange: handleFileChange,
1519
- accept,
1520
- className: "border-border bg-surface text-text-primary file:bg-accent-subtle file:text-accent hover:file:bg-accent-subtle block w-full cursor-pointer rounded-lg border px-4 py-2.5 text-sm file:mr-4 file:cursor-pointer file:rounded-md file:border-0 file:px-3 file:py-1 file:text-sm file:font-medium"
1521
- })
1522
- }),
1523
- fileSizeError && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1524
- className: "text-danger-fg text-xs",
1525
- children: fileSizeError
1526
- })
1527
- ]
1528
- }),
1529
- selectedFile && showFileInfo && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1530
- className: "border-border-subtle rounded-lg border p-4",
1531
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1532
- className: "gap-element flex flex-col",
1510
+ children: [
1511
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.FormRoot, {
1512
+ store: form,
1513
+ "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : "파일 업로드 폼",
1514
+ children: [
1515
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.FormField, {
1516
+ name: "title",
1533
1517
  children: [
1534
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1535
- className: "flex items-center justify-between text-sm",
1536
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1537
- className: "text-text-primary font-medium",
1538
- children: selectedFile.name
1539
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1540
- className: "text-text-tertiary",
1541
- children: formatFileSize(selectedFile.size)
1542
- })]
1518
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormLabel, {
1519
+ name: "title",
1520
+ children: (_labels$titleLabel = labels.titleLabel) !== null && _labels$titleLabel !== void 0 ? _labels$titleLabel : "제목"
1543
1521
  }),
1544
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1545
- className: "text-text-tertiary text-xs",
1546
- children: ["타입: ", selectedFile.type || " 없음"]
1522
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormInput, {
1523
+ name: "title",
1524
+ placeholder: (_labels$titlePlacehol = labels.titlePlaceholder) !== null && _labels$titlePlacehol !== void 0 ? _labels$titlePlacehol : "파일 제목을 입력하세요"
1525
+ }),
1526
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormError, { name: "title" })
1527
+ ]
1528
+ }),
1529
+ showDescription && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.FormField, {
1530
+ name: "description",
1531
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormLabel, {
1532
+ name: "description",
1533
+ children: (_labels$descriptionLa = labels.descriptionLabel) !== null && _labels$descriptionLa !== void 0 ? _labels$descriptionLa : "설명"
1534
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormTextarea, {
1535
+ name: "description",
1536
+ placeholder: (_labels$descriptionPl = labels.descriptionPlaceholder) !== null && _labels$descriptionPl !== void 0 ? _labels$descriptionPl : "파일에 대한 설명을 입력하세요",
1537
+ rows: descriptionRows,
1538
+ resize: "none"
1539
+ })]
1540
+ }),
1541
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.FormField, {
1542
+ name: "file",
1543
+ children: [
1544
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
1545
+ htmlFor: fileId,
1546
+ className: "text-text-primary text-sm font-medium",
1547
+ children: (_labels$fileLabel = labels.fileLabel) !== null && _labels$fileLabel !== void 0 ? _labels$fileLabel : "파일 선택"
1547
1548
  }),
1548
- showPreview && preview && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1549
- className: "border-border-subtle overflow-hidden rounded-lg border",
1550
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
1551
- src: preview,
1552
- alt: "미리보기",
1553
- className: "max-h-48 w-full object-contain"
1549
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1550
+ className: "relative",
1551
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1552
+ id: fileId,
1553
+ type: "file",
1554
+ disabled: form.isSubmitting(),
1555
+ "aria-invalid": Boolean(fileSizeError),
1556
+ "aria-describedby": fileSizeError ? `${fileId}-error` : void 0,
1557
+ onChange: handleFileChange,
1558
+ accept,
1559
+ className: "border-border bg-surface text-text-primary file:bg-accent-subtle file:text-accent hover:file:bg-accent-subtle block w-full cursor-pointer rounded-lg border px-4 py-2.5 text-sm file:mr-4 file:cursor-pointer file:rounded-md file:border-0 file:px-3 file:py-1 file:text-sm file:font-medium"
1554
1560
  })
1561
+ }),
1562
+ fileSizeError && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1563
+ id: `${fileId}-error`,
1564
+ role: "alert",
1565
+ className: "text-danger-fg text-xs",
1566
+ children: fileSizeError
1555
1567
  })
1556
1568
  ]
1569
+ }),
1570
+ selectedFile && showFileInfo && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1571
+ className: "border-border-subtle rounded-lg border p-4",
1572
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1573
+ className: "gap-element flex flex-col",
1574
+ children: [
1575
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1576
+ className: "flex items-center justify-between text-sm",
1577
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1578
+ className: "text-text-primary font-medium",
1579
+ children: selectedFile.name
1580
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1581
+ className: "text-text-tertiary",
1582
+ children: formatFileSize(selectedFile.size)
1583
+ })]
1584
+ }),
1585
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1586
+ className: "text-text-tertiary text-xs",
1587
+ children: ["타입: ", selectedFile.type || "알 수 없음"]
1588
+ }),
1589
+ showPreview && preview && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1590
+ className: "border-border-subtle overflow-hidden rounded-lg border",
1591
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
1592
+ src: preview,
1593
+ alt: "미리보기",
1594
+ className: "max-h-48 w-full object-contain"
1595
+ })
1596
+ })
1597
+ ]
1598
+ })
1599
+ }),
1600
+ columnMapping && selectedFile && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1601
+ className: "gap-element flex flex-col",
1602
+ "aria-label": (_labels$columnMapping = labels.columnMappingLabel) !== null && _labels$columnMapping !== void 0 ? _labels$columnMapping : "Column mapping",
1603
+ children: columnMapping
1604
+ }),
1605
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormSubmit, {
1606
+ disabled: form.isSubmitting(),
1607
+ children: (_labels$submitButton = labels.submitButton) !== null && _labels$submitButton !== void 0 ? _labels$submitButton : "업로드"
1557
1608
  })
1558
- }),
1559
- columnMapping && selectedFile && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1560
- className: "gap-element flex flex-col",
1561
- "aria-label": (_labels$columnMapping = labels.columnMappingLabel) !== null && _labels$columnMapping !== void 0 ? _labels$columnMapping : "Column mapping",
1562
- children: columnMapping
1563
- }),
1564
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormSubmit, {
1565
- disabled: form.isSubmitting(),
1566
- children: (_labels$submitButton = labels.submitButton) !== null && _labels$submitButton !== void 0 ? _labels$submitButton : "업로드"
1567
- })
1568
- ]
1569
- }), submitted && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1570
- className: "border-success bg-success-subtle text-success-fg rounded-lg border p-3 text-sm",
1571
- children: (_labels$successMessag = labels.successMessage) !== null && _labels$successMessag !== void 0 ? _labels$successMessag : "업로드가 완료되었습니다!"
1572
- })]
1609
+ ]
1610
+ }),
1611
+ form.getSubmitError() !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1612
+ role: "alert",
1613
+ className: "border-danger bg-danger-subtle text-danger-fg rounded-lg border p-3 text-sm",
1614
+ children: (_labels$submitError = labels.submitError) !== null && _labels$submitError !== void 0 ? _labels$submitError : "처리에 실패했습니다. 다시 시도해주세요."
1615
+ }),
1616
+ submitted && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1617
+ role: "status",
1618
+ className: "border-success bg-success-subtle text-success-fg rounded-lg border p-3 text-sm",
1619
+ children: (_labels$successMessag = labels.successMessage) !== null && _labels$successMessag !== void 0 ? _labels$successMessag : "업로드가 완료되었습니다!"
1620
+ })
1621
+ ]
1573
1622
  });
1574
1623
  }
1575
1624
  //#endregion
1576
1625
  //#region src/shells/wizard-form.tsx
1577
1626
  /** Renders the wizard form component. */
1578
1627
  function WizardForm({ fields, steps, showReview = true, onSubmit, onStepChange, resetOnSuccess = false, labels = {}, ariaLabel }) {
1579
- var _labels$reviewTitle, _labels$stepsLabel, _labels$reviewTitle2, _labels$backButton, _labels$submitButton, _labels$nextButton, _labels$successMessag, _labels$resetLink;
1628
+ var _labels$reviewTitle, _labels$stepsLabel, _labels$reviewTitle2, _labels$backButton, _labels$submitButton, _labels$nextButton, _labels$submitError, _labels$successMessag, _labels$resetLink;
1580
1629
  const [currentStep, setCurrentStep] = (0, react.useState)(0);
1581
1630
  const [submitted, setSubmitted] = (0, react.useState)(false);
1631
+ const formId = (0, react.useId)();
1582
1632
  const totalSteps = showReview ? steps.length + 1 : steps.length;
1583
1633
  const isReviewStep = showReview && currentStep === steps.length;
1584
1634
  const isLastStep = currentStep === totalSteps - 1;
@@ -1612,22 +1662,31 @@ function WizardForm({ fields, steps, showReview = true, onSubmit, onStepChange,
1612
1662
  }
1613
1663
  return errors;
1614
1664
  },
1615
- onSubmit: (values) => {
1665
+ onSubmit: async (values) => {
1616
1666
  if (!isLastStep) {
1617
1667
  const next = currentStep + 1;
1618
1668
  setCurrentStep(next);
1619
1669
  onStepChange === null || onStepChange === void 0 || onStepChange(next);
1620
1670
  } else {
1671
+ setSubmitted(false);
1672
+ await (onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit(values));
1621
1673
  setSubmitted(true);
1622
- onSubmit === null || onSubmit === void 0 || onSubmit(values);
1623
- if (resetOnSuccess) setTimeout(() => {
1624
- setCurrentStep(0);
1625
- setSubmitted(false);
1626
- form.reset();
1627
- }, 3e3);
1628
1674
  }
1629
1675
  }
1630
1676
  });
1677
+ (0, react.useEffect)(() => {
1678
+ if (!submitted || !resetOnSuccess) return;
1679
+ const timer = setTimeout(() => {
1680
+ setCurrentStep(0);
1681
+ setSubmitted(false);
1682
+ form.reset();
1683
+ }, 3e3);
1684
+ return () => clearTimeout(timer);
1685
+ }, [
1686
+ submitted,
1687
+ resetOnSuccess,
1688
+ form
1689
+ ]);
1631
1690
  const handleBack = () => {
1632
1691
  if (currentStep > 0) {
1633
1692
  const prev = currentStep - 1;
@@ -1665,8 +1724,8 @@ function WizardForm({ fields, steps, showReview = true, onSubmit, onStepChange,
1665
1724
  ]
1666
1725
  }, field.name);
1667
1726
  }
1668
- if (field.type === "checkbox") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1669
- className: "gap-element flex flex-col",
1727
+ if (field.type === "checkbox") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.FormField, {
1728
+ name: field.name,
1670
1729
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1671
1730
  className: "text-text-primary gap-element flex items-center text-sm",
1672
1731
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormCheckbox, { name: field.name }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: field.label })]
@@ -1674,13 +1733,10 @@ function WizardForm({ fields, steps, showReview = true, onSubmit, onStepChange,
1674
1733
  }, field.name);
1675
1734
  if (field.type === "textarea") {
1676
1735
  var _field$rows, _field$resize;
1677
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1678
- className: "gap-element flex flex-col",
1736
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.FormField, {
1737
+ name: field.name,
1679
1738
  children: [
1680
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormLabel, {
1681
- name: field.name,
1682
- children: field.label
1683
- }),
1739
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormLabel, { children: field.label }),
1684
1740
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormTextarea, {
1685
1741
  name: field.name,
1686
1742
  placeholder: field.placeholder,
@@ -1693,22 +1749,28 @@ function WizardForm({ fields, steps, showReview = true, onSubmit, onStepChange,
1693
1749
  }
1694
1750
  if (field.type === "select") {
1695
1751
  var _field$options2;
1696
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1697
- className: "gap-element flex flex-col",
1752
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.FormField, {
1753
+ name: field.name,
1698
1754
  children: [
1699
1755
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormLabel, {
1700
- name: field.name,
1756
+ htmlFor: `${formId}-${field.name}`,
1701
1757
  children: field.label
1702
1758
  }),
1703
1759
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormSelect, {
1704
1760
  name: field.name,
1761
+ id: `${formId}-${field.name}`,
1762
+ "aria-label": field.label,
1763
+ "aria-describedby": form.getError(field.name) && form.getFieldTouched(field.name) ? `${formId}-${field.name}-error` : void 0,
1705
1764
  placeholder: field.placeholder,
1706
1765
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormSelectPopover, { children: (_field$options2 = field.options) === null || _field$options2 === void 0 ? void 0 : _field$options2.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormSelectItem, {
1707
1766
  value: option.value,
1708
1767
  children: option.label
1709
1768
  }, option.value)) })
1710
1769
  }),
1711
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormError, { name: field.name })
1770
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormError, {
1771
+ name: field.name,
1772
+ id: `${formId}-${field.name}-error`
1773
+ })
1712
1774
  ]
1713
1775
  }, field.name);
1714
1776
  }
@@ -1725,13 +1787,10 @@ function WizardForm({ fields, steps, showReview = true, onSubmit, onStepChange,
1725
1787
  })]
1726
1788
  })]
1727
1789
  }, field.name);
1728
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1729
- className: "gap-element flex flex-col",
1790
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.FormField, {
1791
+ name: field.name,
1730
1792
  children: [
1731
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormLabel, {
1732
- name: field.name,
1733
- children: field.label
1734
- }),
1793
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormLabel, { children: field.label }),
1735
1794
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormInput, {
1736
1795
  name: field.name,
1737
1796
  type: (_field$type = field.type) !== null && _field$type !== void 0 ? _field$type : "text",
@@ -1815,13 +1874,20 @@ function WizardForm({ fields, steps, showReview = true, onSubmit, onStepChange,
1815
1874
  children: [currentStep > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1816
1875
  type: "button",
1817
1876
  onClick: handleBack,
1877
+ disabled: form.isSubmitting(),
1818
1878
  className: "border-border text-text-primary hover:bg-bg-subtle rounded-lg border px-4 py-2 text-sm font-medium",
1819
1879
  children: (_labels$backButton = labels.backButton) !== null && _labels$backButton !== void 0 ? _labels$backButton : "이전"
1820
1880
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FormSubmit, { children: isLastStep ? (_labels$submitButton = labels.submitButton) !== null && _labels$submitButton !== void 0 ? _labels$submitButton : "제출" : (_labels$nextButton = labels.nextButton) !== null && _labels$nextButton !== void 0 ? _labels$nextButton : "다음" })]
1821
1881
  })
1822
1882
  ]
1823
1883
  }),
1884
+ form.getSubmitError() !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1885
+ role: "alert",
1886
+ className: "border-danger bg-danger-subtle text-danger-fg rounded-lg border p-3 text-sm",
1887
+ children: (_labels$submitError = labels.submitError) !== null && _labels$submitError !== void 0 ? _labels$submitError : "처리에 실패했습니다. 다시 시도해주세요."
1888
+ }),
1824
1889
  submitted && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1890
+ role: "status",
1825
1891
  className: "border-success bg-success-subtle rounded-lg border p-4 text-center",
1826
1892
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1827
1893
  className: "text-success-fg text-sm font-medium",
@@ -4217,7 +4283,7 @@ function CriteriaBuilder({ value, onChange, kinds, createCriterion, renderCriter
4217
4283
  className: "sr-only",
4218
4284
  children: labels.rootLogicLegend
4219
4285
  }),
4220
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_field_sidebar.SegmentedControl, {
4286
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_replay_player_layout.SegmentedControl, {
4221
4287
  "aria-label": labels.rootLogicLegend,
4222
4288
  size: "sm",
4223
4289
  options: rootLogicOptions,
@@ -4273,7 +4339,7 @@ function CriteriaBuilder({ value, onChange, kinds, createCriterion, renderCriter
4273
4339
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", {
4274
4340
  className: "sr-only",
4275
4341
  children: labels.groupLogicLegend(letter)
4276
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_field_sidebar.SegmentedControl, {
4342
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_replay_player_layout.SegmentedControl, {
4277
4343
  "aria-label": labels.groupLogicLegend(letter),
4278
4344
  size: "sm",
4279
4345
  options: groupLogicOptions,
@@ -4353,7 +4419,7 @@ function CriteriaBuilder({ value, onChange, kinds, createCriterion, renderCriter
4353
4419
  }),
4354
4420
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4355
4421
  className: "min-w-0 flex-1",
4356
- children: known ? renderCriterion(criterion, api) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_field_sidebar.Callout, {
4422
+ children: known ? renderCriterion(criterion, api) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_replay_player_layout.Callout, {
4357
4423
  tone: "warning",
4358
4424
  size: "sm",
4359
4425
  title: labels.unknownKind(criterion.kind),
@@ -5072,7 +5138,7 @@ const flyoutSize = {
5072
5138
  * ```
5073
5139
  */
5074
5140
  function InspectorLayout({ children, inspector, open, onClose, title, description, actions, footer, breakpoint = "xl", width = "md", labels, className }) {
5075
- const canPush = require_field_sidebar.useMediaQuery(breakpointQuery[breakpoint], true);
5141
+ const canPush = require_replay_player_layout.useMediaQuery(breakpointQuery[breakpoint], true);
5076
5142
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5077
5143
  className: require_text_truncate.cn("flex min-w-0 items-stretch gap-group", className),
5078
5144
  "data-opt-id": "MN44T",
@@ -5083,7 +5149,7 @@ function InspectorLayout({ children, inspector, open, onClose, title, descriptio
5083
5149
  children
5084
5150
  }), canPush ? open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("aside", {
5085
5151
  className: require_text_truncate.cn("shrink-0", pushWidth[width]),
5086
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_field_sidebar.Flyout, {
5152
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_replay_player_layout.Flyout, {
5087
5153
  open,
5088
5154
  onClose,
5089
5155
  type: "inline",
@@ -5095,7 +5161,7 @@ function InspectorLayout({ children, inspector, open, onClose, title, descriptio
5095
5161
  className: "h-full",
5096
5162
  children: inspector
5097
5163
  })
5098
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_field_sidebar.Flyout, {
5164
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_replay_player_layout.Flyout, {
5099
5165
  open,
5100
5166
  onClose,
5101
5167
  type: "overlay",
@@ -5121,11 +5187,11 @@ const defaultLabels$14 = {
5121
5187
  };
5122
5188
  function toggleValue(query, field, value, active, multiSelect) {
5123
5189
  if (active) {
5124
- const remaining = require_field_sidebar.fieldValues(query, field).filter((it) => it !== value);
5125
- const cleared = require_field_sidebar.withoutField(query, field);
5126
- return remaining.reduce((next, keep) => require_field_sidebar.withFieldValue(next, field, keep), cleared);
5190
+ const remaining = require_replay_player_layout.fieldValues(query, field).filter((it) => it !== value);
5191
+ const cleared = require_replay_player_layout.withoutField(query, field);
5192
+ return remaining.reduce((next, keep) => require_replay_player_layout.withFieldValue(next, field, keep), cleared);
5127
5193
  }
5128
- return multiSelect ? require_field_sidebar.withFieldValue(query, field, value) : require_field_sidebar.withFieldValue(require_field_sidebar.withoutField(query, field), field, value);
5194
+ return multiSelect ? require_replay_player_layout.withFieldValue(query, field, value) : require_replay_player_layout.withFieldValue(require_replay_player_layout.withoutField(query, field), field, value);
5129
5195
  }
5130
5196
  /**
5131
5197
  * QueryFilterBar — filter buttons and a query string that are the same thing.
@@ -5157,7 +5223,7 @@ function toggleValue(query, field, value, active, multiSelect) {
5157
5223
  function QueryFilterBar({ value, onChange, filters, fields, actions, showClauses = true, live = false, disabled = false, labels: customLabels, queryBarLabels, className }) {
5158
5224
  const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$14), customLabels);
5159
5225
  const activeCount = (0, react.useMemo)(() => filters.reduce((count, filter) => {
5160
- const values = require_field_sidebar.fieldValues(value, filter.field);
5226
+ const values = require_replay_player_layout.fieldValues(value, filter.field);
5161
5227
  if (filter.kind === "field_value_selection") return count + values.length;
5162
5228
  return count + (filter.value && values.includes(filter.value) ? 1 : 0);
5163
5229
  }, 0), [filters, value]);
@@ -5165,7 +5231,7 @@ function QueryFilterBar({ value, onChange, filters, fields, actions, showClauses
5165
5231
  className: require_text_truncate.cn("flex flex-col gap-element", className),
5166
5232
  "data-opt-id": "SK31N",
5167
5233
  "data-opt-slug": "query-filter-bar.QueryFilterBar",
5168
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_field_sidebar.QueryBar, {
5234
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_replay_player_layout.QueryBar, {
5169
5235
  value,
5170
5236
  onChange,
5171
5237
  fields,
@@ -5183,7 +5249,7 @@ function QueryFilterBar({ value, onChange, filters, fields, actions, showClauses
5183
5249
  children: [
5184
5250
  filters.map((filter) => {
5185
5251
  var _filter$multiSelect, _filter$value;
5186
- const values = require_field_sidebar.fieldValues(value, filter.field);
5252
+ const values = require_replay_player_layout.fieldValues(value, filter.field);
5187
5253
  const multiSelect = (_filter$multiSelect = filter.multiSelect) !== null && _filter$multiSelect !== void 0 ? _filter$multiSelect : true;
5188
5254
  if (filter.kind === "field_value_selection") {
5189
5255
  var _filter$options, _filter$options2;
@@ -5266,7 +5332,7 @@ function QueryFilterBar({ value, onChange, filters, fields, actions, showClauses
5266
5332
  }
5267
5333
  /** Whether the bar is filtering anything — for an empty state's wording. */
5268
5334
  function hasActiveQuery(query) {
5269
- return !require_field_sidebar.isEmptyQuery(query);
5335
+ return !require_replay_player_layout.isEmptyQuery(query);
5270
5336
  }
5271
5337
  //#endregion
5272
5338
  //#region src/shells/catalog-frame.tsx
@@ -5363,7 +5429,7 @@ function CatalogFrame({ children, isEmpty, query, onQueryChange, filters, stats,
5363
5429
  selectedKeys,
5364
5430
  onSelectionChange
5365
5431
  ]);
5366
- const filtering = !require_field_sidebar.isEmptyQuery(query);
5432
+ const filtering = !require_replay_player_layout.isEmptyQuery(query);
5367
5433
  const body = error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.EmptyState, {
5368
5434
  tone: "error",
5369
5435
  hasBorder: true,
@@ -5567,9 +5633,9 @@ const FALLBACK_SWATCHES = [
5567
5633
  "var(--opt-text)"
5568
5634
  ];
5569
5635
  function buildThemeOptions() {
5570
- return require_field_sidebar.THEME_PRESET_IDS.map((id) => {
5636
+ return require_replay_player_layout.THEME_PRESET_IDS.map((id) => {
5571
5637
  var _descriptor$switcherS;
5572
- const descriptor = require_field_sidebar.THEME_REGISTRY[id];
5638
+ const descriptor = require_replay_player_layout.THEME_REGISTRY[id];
5573
5639
  return {
5574
5640
  value: id,
5575
5641
  label: descriptor.label,
@@ -5650,7 +5716,7 @@ function resolveLabels(user) {
5650
5716
  /** Renders the theme switcher component. */
5651
5717
  function ThemeSwitcher({ className, labels: userLabels, variant = "default", customPresetEditor, preset: controlledPreset, onPresetChange, mode: controlledMode, onModeChange }) {
5652
5718
  var _ref;
5653
- const themeContext = require_field_sidebar.useOptionalOptTheme();
5719
+ const themeContext = require_replay_player_layout.useOptionalOptTheme();
5654
5720
  const preset = controlledPreset !== null && controlledPreset !== void 0 ? controlledPreset : themeContext === null || themeContext === void 0 ? void 0 : themeContext.preset;
5655
5721
  const mode = (_ref = controlledMode !== null && controlledMode !== void 0 ? controlledMode : themeContext === null || themeContext === void 0 ? void 0 : themeContext.mode) !== null && _ref !== void 0 ? _ref : "light";
5656
5722
  const setPreset = onPresetChange !== null && onPresetChange !== void 0 ? onPresetChange : themeContext === null || themeContext === void 0 ? void 0 : themeContext.setPreset;
@@ -5659,7 +5725,7 @@ function ThemeSwitcher({ className, labels: userLabels, variant = "default", cus
5659
5725
  const labels = resolveLabels(userLabels);
5660
5726
  const options = buildThemeOptions();
5661
5727
  const activePreset = preset;
5662
- const forcedMode = require_field_sidebar.FORCE_LIGHT_PRESET_IDS.has(activePreset);
5728
+ const forcedMode = require_replay_player_layout.FORCE_LIGHT_PRESET_IDS.has(activePreset);
5663
5729
  const showCustomBadge = controlledPreset === void 0 && ((themeContext === null || themeContext === void 0 ? void 0 : themeContext.isGenerated) === true || (themeContext === null || themeContext === void 0 ? void 0 : themeContext.isPromoted) === true);
5664
5730
  if (options.length === 0) return null;
5665
5731
  if (variant === "compact") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -6174,64 +6240,56 @@ ConfirmDialog.displayName = "ConfirmDialog";
6174
6240
  function AsyncCombobox({ onSearch, debounceMs = 300, loadingText, minChars = 1, placeholder, onSelect, labels: customLabels, className }) {
6175
6241
  const labels = require_text_truncate._objectSpread2({
6176
6242
  input: placeholder !== null && placeholder !== void 0 ? placeholder : "Search",
6243
+ error: "Search failed. Please try again.",
6244
+ retry: "Retry",
6177
6245
  loading: loadingText !== null && loadingText !== void 0 ? loadingText : "Loading…",
6178
6246
  noResults: "No results",
6179
6247
  placeholder: placeholder !== null && placeholder !== void 0 ? placeholder : "Search…"
6180
6248
  }, customLabels);
6181
6249
  const [query, setQuery] = react.useState("");
6182
- const [results, setResults] = react.useState([]);
6183
- const [loading, setLoading] = react.useState(false);
6184
- const timerRef = react.useRef(void 0);
6185
- const searchGenerationRef = react.useRef(0);
6186
- const handleInput = react.useCallback((event) => {
6187
- searchGenerationRef.current += 1;
6250
+ const inputRef = react.useRef(null);
6251
+ const { results, loading, failed, retry, invalidate } = require_replay_player_layout.useAsyncSearch({
6252
+ query,
6253
+ search: onSearch,
6254
+ enabled: query.length >= minChars,
6255
+ debounceMs
6256
+ });
6257
+ const handleInput = (event) => {
6258
+ inputRef.current = event.currentTarget;
6259
+ invalidate();
6188
6260
  setQuery(event.currentTarget.value);
6189
- }, []);
6190
- const handleValueChange = react.useCallback((value) => {
6191
- searchGenerationRef.current += 1;
6192
- if (timerRef.current) clearTimeout(timerRef.current);
6193
- setLoading(false);
6194
- setResults([]);
6261
+ };
6262
+ const handleValueChange = (value) => {
6263
+ invalidate();
6195
6264
  onSelect === null || onSelect === void 0 || onSelect(value);
6196
- }, [onSelect]);
6197
- react.useEffect(() => {
6198
- const generation = ++searchGenerationRef.current;
6199
- if (timerRef.current) clearTimeout(timerRef.current);
6200
- if (query.length < minChars) {
6201
- setResults([]);
6202
- setLoading(false);
6203
- return;
6204
- }
6205
- setLoading(true);
6206
- timerRef.current = setTimeout(async () => {
6207
- try {
6208
- const items = await onSearch(query);
6209
- if (searchGenerationRef.current !== generation) return;
6210
- setResults(items);
6211
- } finally {
6212
- if (searchGenerationRef.current === generation) setLoading(false);
6213
- }
6214
- }, debounceMs);
6215
- return () => {
6216
- if (timerRef.current) clearTimeout(timerRef.current);
6217
- };
6218
- }, [
6219
- query,
6220
- minChars,
6221
- debounceMs,
6222
- onSearch
6223
- ]);
6265
+ };
6224
6266
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.ComboboxRoot, {
6225
6267
  onValueChange: handleValueChange,
6226
6268
  "data-opt-id": "KAKTV",
6227
6269
  "data-opt-slug": "async-combobox.AsyncCombobox",
6228
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.ComboboxInput, {
6270
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.ComboboxInput, require_text_truncate._objectSpread2({
6229
6271
  className: require_text_truncate.cn(className),
6230
6272
  "aria-label": labels.input,
6231
6273
  "aria-busy": loading || void 0,
6232
6274
  placeholder: labels.placeholder,
6233
6275
  onInput: handleInput
6234
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.ComboboxPopover, { children: loading ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6276
+ }, failed ? {
6277
+ "aria-expanded": false,
6278
+ "aria-controls": void 0
6279
+ } : {})), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.ComboboxPopover, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, failed ? { role: "presentation" } : {}), {}, { children: failed ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6280
+ role: "alert",
6281
+ className: "gap-element flex flex-col px-3 py-2 text-sm",
6282
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: labels.error }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.Button, {
6283
+ variant: "secondary",
6284
+ size: "sm",
6285
+ onClick: () => {
6286
+ var _inputRef$current;
6287
+ retry();
6288
+ (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 || _inputRef$current.focus();
6289
+ },
6290
+ children: labels.retry
6291
+ })]
6292
+ }) : loading ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6235
6293
  className: "text-text-secondary gap-element flex items-center px-3 py-2 text-sm",
6236
6294
  role: "status",
6237
6295
  "aria-live": "polite",
@@ -6243,7 +6301,7 @@ function AsyncCombobox({ onSearch, debounceMs = 300, loadingText, minChars = 1,
6243
6301
  }) : results.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.ComboboxEmpty, { children: labels.noResults }) : results.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.ComboboxItem, {
6244
6302
  value: item,
6245
6303
  children: item
6246
- }, item)) })]
6304
+ }, item)) }))]
6247
6305
  });
6248
6306
  }
6249
6307
  //#endregion
@@ -8874,7 +8932,7 @@ const enStarRatingLabels = {
8874
8932
  };
8875
8933
  const enBreadcrumbLabels = { navAriaLabel: "Go to {label}" };
8876
8934
  //#endregion
8877
- exports.ALL_COMPOUND_THEMES = require_field_sidebar.ALL_COMPOUND_THEMES;
8935
+ exports.ALL_COMPOUND_THEMES = require_replay_player_layout.ALL_COMPOUND_THEMES;
8878
8936
  exports.AccordionContent = require_key_pad_menu.AccordionContent;
8879
8937
  exports.AccordionItem = require_key_pad_menu.AccordionItem;
8880
8938
  exports.AccordionRoot = require_key_pad_menu.AccordionRoot;
@@ -8883,7 +8941,7 @@ exports.ActivityFeed = ActivityFeed;
8883
8941
  exports.Alert = require_text_truncate.Alert;
8884
8942
  exports.AlertBuilder = AlertBuilder;
8885
8943
  exports.AlertDialogPanel = require_text_truncate.AlertDialogPanel;
8886
- exports.AppMenubar = require_field_sidebar.AppMenubar;
8944
+ exports.AppMenubar = require_replay_player_layout.AppMenubar;
8887
8945
  exports.AppShell = AppShell;
8888
8946
  exports.AsyncCombobox = AsyncCombobox;
8889
8947
  exports.AuditLog = AuditLog;
@@ -8893,12 +8951,12 @@ exports.Avatar = require_key_pad_menu.Avatar;
8893
8951
  exports.AvatarGroup = require_key_pad_menu.AvatarGroup;
8894
8952
  exports.Badge = require_text_truncate.Badge;
8895
8953
  exports.BlockLayout = require_key_pad_menu.BlockLayout;
8896
- exports.BranchSelect = require_field_sidebar.BranchSelect;
8954
+ exports.BranchSelect = require_replay_player_layout.BranchSelect;
8897
8955
  exports.Breadcrumb = require_key_pad_menu.Breadcrumb;
8898
8956
  exports.BulkActions = BulkActions;
8899
8957
  exports.Button = require_text_truncate.Button;
8900
8958
  exports.COLOR_PRESETS = COLOR_PRESETS;
8901
- exports.Callout = require_field_sidebar.Callout;
8959
+ exports.Callout = require_replay_player_layout.Callout;
8902
8960
  exports.Card = require_key_pad_menu.Card;
8903
8961
  exports.CardContent = require_key_pad_menu.CardContent;
8904
8962
  exports.CardDescription = require_key_pad_menu.CardDescription;
@@ -8927,17 +8985,17 @@ exports.ComboboxInput = require_text_truncate.ComboboxInput;
8927
8985
  exports.ComboboxItem = require_text_truncate.ComboboxItem;
8928
8986
  exports.ComboboxPopover = require_text_truncate.ComboboxPopover;
8929
8987
  exports.ComboboxRoot = require_text_truncate.ComboboxRoot;
8930
- exports.Command = require_field_sidebar.Command;
8931
- exports.CommandDialog = require_field_sidebar.CommandDialog;
8932
- exports.CommandEmpty = require_field_sidebar.CommandEmpty;
8933
- exports.CommandGroup = require_field_sidebar.CommandGroup;
8934
- exports.CommandInput = require_field_sidebar.CommandInput;
8935
- exports.CommandItem = require_field_sidebar.CommandItem;
8936
- exports.CommandList = require_field_sidebar.CommandList;
8937
- exports.CommandPalette = require_field_sidebar.CommandPalette;
8938
- exports.CommandPaletteTrigger = require_field_sidebar.CommandPaletteTrigger;
8939
- exports.CommandSeparator = require_field_sidebar.CommandSeparator;
8940
- exports.CommandShortcut = require_field_sidebar.CommandShortcut;
8988
+ exports.Command = require_replay_player_layout.Command;
8989
+ exports.CommandDialog = require_replay_player_layout.CommandDialog;
8990
+ exports.CommandEmpty = require_replay_player_layout.CommandEmpty;
8991
+ exports.CommandGroup = require_replay_player_layout.CommandGroup;
8992
+ exports.CommandInput = require_replay_player_layout.CommandInput;
8993
+ exports.CommandItem = require_replay_player_layout.CommandItem;
8994
+ exports.CommandList = require_replay_player_layout.CommandList;
8995
+ exports.CommandPalette = require_replay_player_layout.CommandPalette;
8996
+ exports.CommandPaletteTrigger = require_replay_player_layout.CommandPaletteTrigger;
8997
+ exports.CommandSeparator = require_replay_player_layout.CommandSeparator;
8998
+ exports.CommandShortcut = require_replay_player_layout.CommandShortcut;
8941
8999
  exports.ComparisonSelector = ComparisonSelector;
8942
9000
  exports.Composite = _reopt_ai_opt_ui_primitives.Composite;
8943
9001
  exports.CompositeItem = _reopt_ai_opt_ui_primitives.CompositeItem;
@@ -8948,16 +9006,16 @@ exports.ConditionBuilder = require_key_pad_menu.ConditionBuilder;
8948
9006
  exports.ConfirmDialog = ConfirmDialog;
8949
9007
  exports.ConnectionIndicator = ConnectionIndicator;
8950
9008
  exports.Container = require_key_pad_menu.Container;
8951
- exports.ContentTabs = require_field_sidebar.ContentTabs;
9009
+ exports.ContentTabs = require_replay_player_layout.ContentTabs;
8952
9010
  exports.CopyButton = CopyButton;
8953
9011
  exports.CriteriaBuilder = CriteriaBuilder;
8954
9012
  exports.DEFAULT_PRESETS = require_text_truncate.DEFAULT_PRESETS;
8955
- exports.DEFAULT_TIME_PRESETS = require_field_sidebar.DEFAULT_TIME_PRESETS;
8956
- exports.DashboardGrid = require_field_sidebar.DashboardGrid;
9013
+ exports.DEFAULT_TIME_PRESETS = require_replay_player_layout.DEFAULT_TIME_PRESETS;
9014
+ exports.DashboardGrid = require_replay_player_layout.DashboardGrid;
8957
9015
  exports.DataImportWizard = DataImportWizard;
8958
- exports.DataTable = require_field_sidebar.DataTable;
9016
+ exports.DataTable = require_replay_player_layout.DataTable;
8959
9017
  exports.DateRangePicker = require_text_truncate.DateRangePicker;
8960
- exports.DeploymentTimeline = require_field_sidebar.DeploymentTimeline;
9018
+ exports.DeploymentTimeline = require_replay_player_layout.DeploymentTimeline;
8961
9019
  exports.DescriptionList = require_text_truncate.DescriptionList;
8962
9020
  exports.DesignGuidePanel = DesignGuidePanel;
8963
9021
  exports.DialogBody = require_text_truncate.DialogBody;
@@ -8972,7 +9030,7 @@ exports.DialogRoot = require_text_truncate.DialogRoot;
8972
9030
  exports.DisclosureContent = require_text_truncate.DisclosureContent;
8973
9031
  exports.DisclosureRoot = require_text_truncate.DisclosureRoot;
8974
9032
  exports.DisclosureTrigger = require_text_truncate.DisclosureTrigger;
8975
- exports.DomainTable = require_field_sidebar.DomainTable;
9033
+ exports.DomainTable = require_replay_player_layout.DomainTable;
8976
9034
  exports.DrawerClose = require_key_pad_menu.DrawerClose;
8977
9035
  exports.DrawerPanel = require_key_pad_menu.DrawerPanel;
8978
9036
  exports.DrawerRoot = require_key_pad_menu.DrawerRoot;
@@ -8982,11 +9040,11 @@ exports.DropdownMenu = require_text_truncate.DropdownMenu;
8982
9040
  exports.DropdownSeparator = require_text_truncate.DropdownSeparator;
8983
9041
  exports.DropdownTrigger = require_text_truncate.DropdownTrigger;
8984
9042
  exports.DynamicFieldForm = DynamicFieldForm;
8985
- exports.EMPTY_QUERY = require_field_sidebar.EMPTY_QUERY;
8986
- exports.EMPTY_QUERY_FILTERS = require_field_sidebar.EMPTY_QUERY_FILTERS;
8987
- exports.EditorToolbar = require_field_sidebar.EditorToolbar;
9043
+ exports.EMPTY_QUERY = require_replay_player_layout.EMPTY_QUERY;
9044
+ exports.EMPTY_QUERY_FILTERS = require_replay_player_layout.EMPTY_QUERY_FILTERS;
9045
+ exports.EditorToolbar = require_replay_player_layout.EditorToolbar;
8988
9046
  exports.EmptyState = require_text_truncate.EmptyState;
8989
- exports.EnvPanel = require_field_sidebar.EnvPanel;
9047
+ exports.EnvPanel = require_replay_player_layout.EnvPanel;
8990
9048
  exports.ErrorBoundary = ErrorBoundary;
8991
9049
  exports.EventIcon = EventIcon;
8992
9050
  exports.EventMetaEditor = EventMetaEditor;
@@ -8996,25 +9054,25 @@ Object.defineProperty(exports, "EventSparkline", {
8996
9054
  return _reopt_ai_opt_charts.EventSparkline;
8997
9055
  }
8998
9056
  });
8999
- exports.EventTimeline = require_field_sidebar.EventTimeline;
9057
+ exports.EventTimeline = require_replay_player_layout.EventTimeline;
9000
9058
  exports.ExportButton = ExportButton;
9001
9059
  exports.Expression = require_key_pad_menu.Expression;
9002
9060
  exports.ExpressionGroup = require_key_pad_menu.ExpressionGroup;
9003
9061
  exports.FIELD_TYPE_TOKENS = require_text_truncate.FIELD_TYPE_TOKENS;
9004
- exports.FORCE_LIGHT_PRESETS = require_field_sidebar.FORCE_LIGHT_PRESETS;
9005
- exports.FORCE_LIGHT_PRESET_IDS = require_field_sidebar.FORCE_LIGHT_PRESET_IDS;
9062
+ exports.FORCE_LIGHT_PRESETS = require_replay_player_layout.FORCE_LIGHT_PRESETS;
9063
+ exports.FORCE_LIGHT_PRESET_IDS = require_replay_player_layout.FORCE_LIGHT_PRESET_IDS;
9006
9064
  exports.Facet = require_key_pad_menu.Facet;
9007
9065
  exports.FacetGroup = require_key_pad_menu.FacetGroup;
9008
- exports.FailureList = require_field_sidebar.FailureList;
9009
- exports.FaqAccordion = require_field_sidebar.FaqAccordion;
9066
+ exports.FailureList = require_replay_player_layout.FailureList;
9067
+ exports.FaqAccordion = require_replay_player_layout.FaqAccordion;
9010
9068
  exports.FeatureFlagPanel = FeatureFlagPanel;
9011
- exports.FieldSidebar = require_field_sidebar.FieldSidebar;
9069
+ exports.FieldSidebar = require_replay_player_layout.FieldSidebar;
9012
9070
  exports.FieldToken = require_text_truncate.FieldToken;
9013
9071
  exports.FieldTokenLegend = require_text_truncate.FieldTokenLegend;
9014
9072
  exports.FileUploadForm = FileUploadForm;
9015
9073
  exports.FilterBar = FilterBar;
9016
9074
  exports.FloatingActionBar = FloatingActionBar;
9017
- exports.Flyout = require_field_sidebar.Flyout;
9075
+ exports.Flyout = require_replay_player_layout.Flyout;
9018
9076
  exports.FormCheckbox = require_text_truncate.FormCheckbox;
9019
9077
  exports.FormColorPicker = require_text_truncate.FormColorPicker;
9020
9078
  exports.FormControl = require_text_truncate.FormControl;
@@ -9044,8 +9102,8 @@ exports.FormSubmit = require_text_truncate.FormSubmit;
9044
9102
  exports.FormSwitch = require_text_truncate.FormSwitch;
9045
9103
  exports.FormTagInput = require_text_truncate.FormTagInput;
9046
9104
  exports.FormTextarea = require_text_truncate.FormTextarea;
9047
- exports.GENERATED_THEME_ID_DEFAULT = require_field_sidebar.GENERATED_THEME_ID_DEFAULT;
9048
- exports.GLOBAL_THEME_STYLE_ID = require_field_sidebar.GLOBAL_THEME_STYLE_ID;
9105
+ exports.GENERATED_THEME_ID_DEFAULT = require_replay_player_layout.GENERATED_THEME_ID_DEFAULT;
9106
+ exports.GLOBAL_THEME_STYLE_ID = require_replay_player_layout.GLOBAL_THEME_STYLE_ID;
9049
9107
  exports.Heading = require_key_pad_menu.Heading;
9050
9108
  exports.Highlight = require_text_truncate.Highlight;
9051
9109
  exports.IconPicker = require_text_truncate.IconPicker;
@@ -9058,10 +9116,10 @@ exports.InspectorLayout = InspectorLayout;
9058
9116
  exports.KanbanBoard = KanbanBoard;
9059
9117
  exports.Kbd = require_text_truncate.Kbd;
9060
9118
  exports.KeyPadMenu = require_key_pad_menu.KeyPadMenu;
9061
- exports.KeyValueEditor = require_field_sidebar.KeyValueEditor;
9119
+ exports.KeyValueEditor = require_replay_player_layout.KeyValueEditor;
9062
9120
  exports.LiveRegion = require_key_pad_menu.LiveRegion;
9063
9121
  exports.LoadingOverlay = require_key_pad_menu.LoadingOverlay;
9064
- exports.LogTable = require_field_sidebar.LogTable;
9122
+ exports.LogTable = require_replay_player_layout.LogTable;
9065
9123
  exports.Logo = require_key_pad_menu.Logo;
9066
9124
  exports.MegaMenu = MegaMenu;
9067
9125
  exports.MenuButtonArrow = require_text_truncate.MenuButtonArrow;
@@ -9082,12 +9140,12 @@ Object.defineProperty(exports, "MetricsCard", {
9082
9140
  }
9083
9141
  });
9084
9142
  exports.NotificationCenter = NotificationCenter;
9085
- exports.NotificationToast = require_field_sidebar.NotificationToast;
9143
+ exports.NotificationToast = require_replay_player_layout.NotificationToast;
9086
9144
  exports.NumberInput = require_text_truncate.NumberInput;
9087
9145
  exports.OPT_TEXT_PRIMARY = require_text_truncate.OPT_TEXT_PRIMARY;
9088
9146
  exports.OPT_TEXT_SECONDARY = require_text_truncate.OPT_TEXT_SECONDARY;
9089
- exports.OptThemeControllerContext = require_field_sidebar.OptThemeControllerContext;
9090
- exports.OptThemeProvider = require_field_sidebar.OptThemeProvider;
9147
+ exports.OptThemeControllerContext = require_replay_player_layout.OptThemeControllerContext;
9148
+ exports.OptThemeProvider = require_replay_player_layout.OptThemeProvider;
9091
9149
  exports.OtpField = require_key_pad_menu.OtpField;
9092
9150
  exports.POPULAR_ICONS = POPULAR_ICONS;
9093
9151
  exports.PageAside = PageAside;
@@ -9098,22 +9156,25 @@ exports.PopoverContent = require_text_truncate.PopoverContent;
9098
9156
  exports.PopoverRoot = require_text_truncate.PopoverRoot;
9099
9157
  exports.PopoverTrigger = require_text_truncate.PopoverTrigger;
9100
9158
  exports.Progress = require_key_pad_menu.Progress;
9101
- exports.ProjectSwitcher = require_field_sidebar.ProjectSwitcher;
9159
+ exports.ProjectSwitcher = require_replay_player_layout.ProjectSwitcher;
9102
9160
  exports.PromptTemplate = PromptTemplate;
9103
9161
  exports.PropertyExplorer = PropertyExplorer;
9104
- exports.QueryBar = require_field_sidebar.QueryBar;
9162
+ exports.QueryBar = require_replay_player_layout.QueryBar;
9105
9163
  exports.QueryFilterBar = QueryFilterBar;
9106
- exports.QueryFiltersMenu = require_field_sidebar.QueryFiltersMenu;
9107
- exports.QueryHistoryList = require_field_sidebar.QueryHistoryList;
9108
- exports.QueryOutputPane = require_field_sidebar.QueryOutputPane;
9109
- exports.QueryResultChart = require_field_sidebar.QueryResultChart;
9110
- exports.QueryResultsTable = require_field_sidebar.QueryResultsTable;
9111
- exports.QueryToolbar = require_field_sidebar.QueryToolbar;
9112
- exports.QueryVariablesMenu = require_field_sidebar.QueryVariablesMenu;
9113
- exports.QueryWorkspace = require_field_sidebar.QueryWorkspace;
9164
+ exports.QueryFiltersMenu = require_replay_player_layout.QueryFiltersMenu;
9165
+ exports.QueryHistoryList = require_replay_player_layout.QueryHistoryList;
9166
+ exports.QueryOutputPane = require_replay_player_layout.QueryOutputPane;
9167
+ exports.QueryResultChart = require_replay_player_layout.QueryResultChart;
9168
+ exports.QueryResultsTable = require_replay_player_layout.QueryResultsTable;
9169
+ exports.QueryToolbar = require_replay_player_layout.QueryToolbar;
9170
+ exports.QueryVariablesMenu = require_replay_player_layout.QueryVariablesMenu;
9171
+ exports.QueryWorkspace = require_replay_player_layout.QueryWorkspace;
9114
9172
  exports.QuickActions = QuickActions;
9115
9173
  exports.Radio = require_key_pad_menu.Radio;
9116
9174
  exports.RadioGroup = require_key_pad_menu.RadioGroup;
9175
+ exports.ReplayPlayerLayout = require_replay_player_layout.ReplayPlayerLayout;
9176
+ exports.ReplayScrubber = require_replay_player_layout.ReplayScrubber;
9177
+ exports.ReplayTransport = require_replay_player_layout.ReplayTransport;
9117
9178
  exports.ReportBuilder = ReportBuilder;
9118
9179
  Object.defineProperty(exports, "ReportWidget", {
9119
9180
  enumerable: true,
@@ -9131,25 +9192,25 @@ exports.SHADER_PARAM_FALLBACK = require_key_pad_menu.SHADER_PARAM_FALLBACK;
9131
9192
  exports.SHADER_PARAM_KEYS = require_key_pad_menu.SHADER_PARAM_KEYS;
9132
9193
  exports.SHADER_PRESETS = require_key_pad_menu.SHADER_PRESETS;
9133
9194
  exports.SHADER_PRESET_IDS = require_key_pad_menu.SHADER_PRESET_IDS;
9134
- exports.SaveQueryDialog = require_field_sidebar.SaveQueryDialog;
9195
+ exports.SaveQueryDialog = require_replay_player_layout.SaveQueryDialog;
9135
9196
  exports.SavedFilters = SavedFilters;
9136
- exports.SchemaTree = require_field_sidebar.SchemaTree;
9137
- exports.ScoreBreakdown = require_field_sidebar.ScoreBreakdown;
9197
+ exports.SchemaTree = require_replay_player_layout.SchemaTree;
9198
+ exports.ScoreBreakdown = require_replay_player_layout.ScoreBreakdown;
9138
9199
  exports.ScrollArea = require_key_pad_menu.ScrollArea;
9139
- exports.SearchCombobox = require_field_sidebar.SearchCombobox;
9200
+ exports.SearchCombobox = require_replay_player_layout.SearchCombobox;
9140
9201
  exports.Section = require_key_pad_menu.Section;
9141
9202
  exports.SegmentBuilder = SegmentBuilder;
9142
- exports.SegmentedControl = require_field_sidebar.SegmentedControl;
9203
+ exports.SegmentedControl = require_replay_player_layout.SegmentedControl;
9143
9204
  exports.SelectItem = require_text_truncate.SelectItem;
9144
9205
  exports.SelectLabel = require_text_truncate.SelectLabel;
9145
9206
  exports.SelectPopover = require_text_truncate.SelectPopover;
9146
9207
  exports.SelectRoot = require_text_truncate.SelectRoot;
9147
9208
  exports.SelectTrigger = require_text_truncate.SelectTrigger;
9148
9209
  exports.Separator = require_key_pad_menu.Separator;
9149
- exports.SettingsForm = require_field_sidebar.SettingsForm;
9210
+ exports.SettingsForm = require_replay_player_layout.SettingsForm;
9150
9211
  exports.ShaderSurface = require_key_pad_menu.ShaderSurface;
9151
9212
  exports.Sidebar = Sidebar;
9152
- exports.SidebarNav = require_field_sidebar.SidebarNav;
9213
+ exports.SidebarNav = require_replay_player_layout.SidebarNav;
9153
9214
  exports.Skeleton = require_text_truncate.Skeleton;
9154
9215
  exports.SkeletonAvatar = require_text_truncate.SkeletonAvatar;
9155
9216
  exports.SkeletonCard = require_text_truncate.SkeletonCard;
@@ -9158,20 +9219,20 @@ exports.SkeletonText = require_text_truncate.SkeletonText;
9158
9219
  exports.Slider = require_text_truncate.Slider;
9159
9220
  exports.SpatialNavProvider = SpatialNavProvider;
9160
9221
  exports.Spinner = require_text_truncate.Spinner;
9161
- exports.SqlEditor = require_field_sidebar.SqlEditor;
9222
+ exports.SqlEditor = require_replay_player_layout.SqlEditor;
9162
9223
  exports.StarRating = require_text_truncate.StarRating;
9163
9224
  exports.StatCard = require_text_truncate.StatCard;
9164
9225
  exports.StatusDot = StatusDot;
9165
- exports.StatusSelect = require_field_sidebar.StatusSelect;
9226
+ exports.StatusSelect = require_replay_player_layout.StatusSelect;
9166
9227
  exports.StepBuilder = require_key_pad_menu.StepBuilder;
9167
9228
  exports.SummaryRow = SummaryRow;
9168
9229
  exports.SurfaceLayout = require_key_pad_menu.BlockLayout;
9169
9230
  exports.Switch = require_text_truncate.Switch;
9170
9231
  exports.THEME_PALETTES = require_key_pad_menu.THEME_PALETTES;
9171
- exports.THEME_PRESET_IDS = require_field_sidebar.THEME_PRESET_IDS;
9172
- exports.THEME_REGISTRY = require_field_sidebar.THEME_REGISTRY;
9173
- exports.THEME_SPEC_STORAGE_KEY = require_field_sidebar.THEME_SPEC_STORAGE_KEY;
9174
- exports.THEME_TOKENS_STORAGE_KEY = require_field_sidebar.THEME_TOKENS_STORAGE_KEY;
9232
+ exports.THEME_PRESET_IDS = require_replay_player_layout.THEME_PRESET_IDS;
9233
+ exports.THEME_REGISTRY = require_replay_player_layout.THEME_REGISTRY;
9234
+ exports.THEME_SPEC_STORAGE_KEY = require_replay_player_layout.THEME_SPEC_STORAGE_KEY;
9235
+ exports.THEME_TOKENS_STORAGE_KEY = require_replay_player_layout.THEME_TOKENS_STORAGE_KEY;
9175
9236
  exports.Tab = require_text_truncate.Tab;
9176
9237
  exports.TabList = require_text_truncate.TabList;
9177
9238
  exports.TabPanel = require_text_truncate.TabPanel;
@@ -9184,12 +9245,12 @@ exports.Text = require_key_pad_menu.Text;
9184
9245
  exports.TextTruncate = require_text_truncate.TextTruncate;
9185
9246
  exports.Textarea = require_text_truncate.Textarea;
9186
9247
  exports.ThemeSwitcher = ThemeSwitcher;
9187
- exports.TimeRangeControl = require_field_sidebar.TimeRangeControl;
9248
+ exports.TimeRangeControl = require_replay_player_layout.TimeRangeControl;
9188
9249
  exports.TimeRangeSelector = TimeRangeSelector;
9189
- exports.TimeSeriesPanel = require_field_sidebar.TimeSeriesPanel;
9190
- exports.ToastProvider = require_field_sidebar.ToastProvider;
9191
- exports.Toggle = require_key_pad_menu.Toggle;
9192
- exports.ToggleGroup = require_key_pad_menu.ToggleGroup;
9250
+ exports.TimeSeriesPanel = require_replay_player_layout.TimeSeriesPanel;
9251
+ exports.ToastProvider = require_replay_player_layout.ToastProvider;
9252
+ exports.Toggle = require_text_truncate.Toggle;
9253
+ exports.ToggleGroup = require_text_truncate.ToggleGroup;
9193
9254
  exports.ToolbarButton = require_text_truncate.ToolbarButton;
9194
9255
  exports.ToolbarContainer = require_text_truncate.ToolbarContainer;
9195
9256
  exports.ToolbarRoot = require_text_truncate.ToolbarRoot;
@@ -9204,24 +9265,24 @@ Object.defineProperty(exports, "TrendChart", {
9204
9265
  return _reopt_ai_opt_charts.TrendChart;
9205
9266
  }
9206
9267
  });
9207
- exports.VALUELESS_OPERATORS = require_field_sidebar.VALUELESS_OPERATORS;
9268
+ exports.VALUELESS_OPERATORS = require_replay_player_layout.VALUELESS_OPERATORS;
9208
9269
  exports.VerticalTabs = VerticalTabs;
9209
9270
  exports.VirtualList = require_key_pad_menu.VirtualList;
9210
9271
  exports.WebhookConfig = WebhookConfig;
9211
9272
  exports.WidgetGrid = WidgetGrid;
9212
9273
  exports.WizardForm = WizardForm;
9213
- exports.WorkflowCanvas = require_field_sidebar.WorkflowCanvas;
9214
- exports.addClause = require_field_sidebar.addClause;
9215
- exports.applyCellAction = require_field_sidebar.applyCellAction;
9216
- exports.buildTokenCache = require_field_sidebar.buildTokenCache;
9274
+ exports.WorkflowCanvas = require_replay_player_layout.WorkflowCanvas;
9275
+ exports.addClause = require_replay_player_layout.addClause;
9276
+ exports.applyCellAction = require_replay_player_layout.applyCellAction;
9277
+ exports.buildTokenCache = require_replay_player_layout.buildTokenCache;
9217
9278
  exports.cn = require_text_truncate.cn;
9218
- exports.coerceThemeMode = require_field_sidebar.coerceThemeMode;
9219
- exports.computeGeneratedTokens = require_field_sidebar.computeGeneratedTokens;
9279
+ exports.coerceThemeMode = require_replay_player_layout.coerceThemeMode;
9280
+ exports.computeGeneratedTokens = require_replay_player_layout.computeGeneratedTokens;
9220
9281
  exports.computeSpatialTargets = computeSpatialTargets;
9221
- exports.countActiveQueryFilters = require_field_sidebar.countActiveQueryFilters;
9282
+ exports.countActiveQueryFilters = require_replay_player_layout.countActiveQueryFilters;
9222
9283
  exports.createBlock = require_key_pad_menu.createBlock;
9223
9284
  exports.createSurface = require_key_pad_menu.createBlock;
9224
- exports.createThemeBootScript = require_field_sidebar.createThemeBootScript;
9285
+ exports.createThemeBootScript = require_replay_player_layout.createThemeBootScript;
9225
9286
  exports.criteriaBuilderDuplicate = criteriaBuilderDuplicate;
9226
9287
  exports.criteriaBuilderDuplicateGroup = criteriaBuilderDuplicateGroup;
9227
9288
  exports.criteriaBuilderInsert = criteriaBuilderInsert;
@@ -9229,78 +9290,81 @@ exports.criteriaBuilderMove = criteriaBuilderMove;
9229
9290
  exports.criteriaBuilderRemove = criteriaBuilderRemove;
9230
9291
  exports.criteriaBuilderRemoveGroup = criteriaBuilderRemoveGroup;
9231
9292
  exports.criteriaGroupLetter = criteriaGroupLetter;
9232
- exports.defaultQueryChartConfig = require_field_sidebar.defaultQueryChartConfig;
9233
- exports.defineThemeOverrides = require_field_sidebar.defineThemeOverrides;
9234
- exports.describeClause = require_field_sidebar.describeClause;
9293
+ exports.defaultQueryChartConfig = require_replay_player_layout.defaultQueryChartConfig;
9294
+ exports.defineThemeOverrides = require_replay_player_layout.defineThemeOverrides;
9295
+ exports.describeClause = require_replay_player_layout.describeClause;
9235
9296
  exports.enBreadcrumbLabels = enBreadcrumbLabels;
9236
9297
  exports.enComboboxLabels = enComboboxLabels;
9237
9298
  exports.enStarRatingLabels = enStarRatingLabels;
9238
- exports.fieldValues = require_field_sidebar.fieldValues;
9239
- exports.formatClause = require_field_sidebar.formatClause;
9299
+ exports.fieldValues = require_replay_player_layout.fieldValues;
9300
+ exports.formatClause = require_replay_player_layout.formatClause;
9240
9301
  exports.formatOptDateTime = require_text_truncate.formatOptDateTime;
9241
9302
  exports.formatOptNumber = require_text_truncate.formatOptNumber;
9242
9303
  exports.formatOptShortDate = require_text_truncate.formatOptShortDate;
9243
9304
  exports.formatOptTime = require_text_truncate.formatOptTime;
9244
- exports.formatQuery = require_field_sidebar.formatQuery;
9245
- exports.formatQueryCell = require_field_sidebar.formatQueryCell;
9246
- exports.generatedTheme = require_field_sidebar.generatedTheme;
9247
- exports.getCompoundIdForSpec = require_field_sidebar.getCompoundIdForSpec;
9248
- exports.getCompoundTheme = require_field_sidebar.getCompoundTheme;
9305
+ exports.formatQuery = require_replay_player_layout.formatQuery;
9306
+ exports.formatQueryCell = require_replay_player_layout.formatQueryCell;
9307
+ exports.formatReplayElapsed = require_replay_player_layout.formatReplayElapsed;
9308
+ exports.generatedTheme = require_replay_player_layout.generatedTheme;
9309
+ exports.getCompoundIdForSpec = require_replay_player_layout.getCompoundIdForSpec;
9310
+ exports.getCompoundTheme = require_replay_player_layout.getCompoundTheme;
9249
9311
  exports.getShaderFragment = require_key_pad_menu.getShaderFragment;
9250
9312
  exports.getShaderPreset = require_key_pad_menu.getShaderPreset;
9251
- exports.getThemeDescriptor = require_field_sidebar.getThemeDescriptor;
9313
+ exports.getThemeDescriptor = require_replay_player_layout.getThemeDescriptor;
9252
9314
  exports.getTrappedContextRole = getTrappedContextRole;
9315
+ exports.groupReplayMarkers = require_replay_player_layout.groupReplayMarkers;
9253
9316
  exports.hasActiveQuery = hasActiveQuery;
9254
- exports.hasActiveQueryFilters = require_field_sidebar.hasActiveQueryFilters;
9255
- exports.isDescriptorSpec = require_field_sidebar.isDescriptorSpec;
9256
- exports.isEmptyQuery = require_field_sidebar.isEmptyQuery;
9257
- exports.isForceLightSpec = require_field_sidebar.isForceLightSpec;
9258
- exports.isGeneratedSpec = require_field_sidebar.isGeneratedSpec;
9259
- exports.isPresetSpec = require_field_sidebar.isPresetSpec;
9260
- exports.isThemePresetId = require_field_sidebar.isThemePresetId;
9261
- exports.isValidQueryVariableName = require_field_sidebar.isValidQueryVariableName;
9317
+ exports.hasActiveQueryFilters = require_replay_player_layout.hasActiveQueryFilters;
9318
+ exports.isDescriptorSpec = require_replay_player_layout.isDescriptorSpec;
9319
+ exports.isEmptyQuery = require_replay_player_layout.isEmptyQuery;
9320
+ exports.isForceLightSpec = require_replay_player_layout.isForceLightSpec;
9321
+ exports.isGeneratedSpec = require_replay_player_layout.isGeneratedSpec;
9322
+ exports.isPresetSpec = require_replay_player_layout.isPresetSpec;
9323
+ exports.isThemePresetId = require_replay_player_layout.isThemePresetId;
9324
+ exports.isValidQueryVariableName = require_replay_player_layout.isValidQueryVariableName;
9262
9325
  exports.koBreadcrumbLabels = require_text_truncate.koBreadcrumbLabels;
9263
9326
  exports.koComboboxLabels = require_text_truncate.koComboboxLabels;
9264
9327
  exports.koStarRatingLabels = require_text_truncate.koStarRatingLabels;
9265
9328
  exports.matchesQuery = matchesQuery;
9266
9329
  exports.matchesQueryObject = matchesQueryObject;
9267
- exports.numericResultColumns = require_field_sidebar.numericResultColumns;
9268
- exports.parseQuery = require_field_sidebar.parseQuery;
9269
- exports.parseQueryWithDiagnostics = require_field_sidebar.parseQueryWithDiagnostics;
9270
- exports.presetTheme = require_field_sidebar.presetTheme;
9271
- exports.queryFields = require_field_sidebar.queryFields;
9272
- exports.quoteValue = require_field_sidebar.quoteValue;
9273
- exports.readStoredTheme = require_field_sidebar.readStoredTheme;
9274
- exports.removeClause = require_field_sidebar.removeClause;
9330
+ exports.numericResultColumns = require_replay_player_layout.numericResultColumns;
9331
+ exports.parseQuery = require_replay_player_layout.parseQuery;
9332
+ exports.parseQueryWithDiagnostics = require_replay_player_layout.parseQueryWithDiagnostics;
9333
+ exports.presetTheme = require_replay_player_layout.presetTheme;
9334
+ exports.queryFields = require_replay_player_layout.queryFields;
9335
+ exports.quoteValue = require_replay_player_layout.quoteValue;
9336
+ exports.readStoredTheme = require_replay_player_layout.readStoredTheme;
9337
+ exports.removeClause = require_replay_player_layout.removeClause;
9275
9338
  exports.replaceSqlPlaceholder = replaceSqlPlaceholder;
9276
- exports.resolveDescriptor = require_field_sidebar.resolveDescriptor;
9339
+ exports.replayShortcutKey = require_replay_player_layout.replayShortcutKey;
9340
+ exports.resolveDescriptor = require_replay_player_layout.resolveDescriptor;
9277
9341
  exports.resolveFieldType = require_text_truncate.resolveFieldType;
9278
- exports.resolveThemeMode = require_field_sidebar.resolveThemeMode;
9279
- exports.safeParseStoredSpec = require_field_sidebar.safeParseStoredSpec;
9280
- exports.safeParseStoredTokens = require_field_sidebar.safeParseStoredTokens;
9342
+ exports.resolveThemeMode = require_replay_player_layout.resolveThemeMode;
9343
+ exports.safeParseStoredSpec = require_replay_player_layout.safeParseStoredSpec;
9344
+ exports.safeParseStoredTokens = require_replay_player_layout.safeParseStoredTokens;
9281
9345
  exports.schemaValidator = schemaValidator;
9282
- exports.serializeGeneratedTheme = require_field_sidebar.serializeGeneratedTheme;
9283
- exports.serializeThemeRule = require_field_sidebar.serializeThemeRule;
9284
- exports.serializeTokenBody = require_field_sidebar.serializeTokenBody;
9346
+ exports.serializeGeneratedTheme = require_replay_player_layout.serializeGeneratedTheme;
9347
+ exports.serializeThemeRule = require_replay_player_layout.serializeThemeRule;
9348
+ exports.serializeTokenBody = require_replay_player_layout.serializeTokenBody;
9285
9349
  exports.shouldSkipArrow = shouldSkipArrow;
9286
9350
  exports.splitSqlStatements = splitSqlStatements;
9287
9351
  exports.sqlPlaceholderNames = sqlPlaceholderNames;
9288
9352
  exports.sqlStatementAtOffset = sqlStatementAtOffset;
9289
9353
  exports.sqlUsesPlaceholder = sqlUsesPlaceholder;
9290
- exports.toast = require_field_sidebar.toast;
9291
- exports.useAutoRefresh = require_field_sidebar.useAutoRefresh;
9354
+ exports.toast = require_replay_player_layout.toast;
9355
+ exports.useAutoRefresh = require_replay_player_layout.useAutoRefresh;
9292
9356
  exports.useControlledState = require_text_truncate.useControlledState;
9293
9357
  exports.useFieldValue = _reopt_ai_opt_ui_primitives.useFieldValue;
9294
9358
  exports.useFormContext = _reopt_ai_opt_ui_primitives.useFormContext;
9295
9359
  exports.useFormStore = _reopt_ai_opt_ui_primitives.useFormStore;
9296
9360
  exports.useInputId = require_text_truncate.useInputId;
9297
- exports.useOptTheme = require_field_sidebar.useOptTheme;
9298
- exports.useOptThemeController = require_field_sidebar.useOptThemeController;
9299
- exports.useOptionalOptTheme = require_field_sidebar.useOptionalOptTheme;
9361
+ exports.useOptTheme = require_replay_player_layout.useOptTheme;
9362
+ exports.useOptThemeController = require_replay_player_layout.useOptThemeController;
9363
+ exports.useOptionalOptTheme = require_replay_player_layout.useOptionalOptTheme;
9300
9364
  exports.useSidebar = useSidebar;
9301
- exports.useToast = require_field_sidebar.useToast;
9302
- exports.withFieldValue = require_field_sidebar.withFieldValue;
9303
- exports.withoutField = require_field_sidebar.withoutField;
9365
+ exports.useToast = require_replay_player_layout.useToast;
9366
+ exports.withFieldValue = require_replay_player_layout.withFieldValue;
9367
+ exports.withoutField = require_replay_player_layout.withoutField;
9304
9368
  Object.keys(_reopt_ai_opt_charts).forEach(function(k) {
9305
9369
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
9306
9370
  enumerable: true,