hazo_ui 6.12.4 → 6.13.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/index.cjs CHANGED
@@ -182,8 +182,8 @@ var require_extends = __commonJS({
182
182
  function _extends11() {
183
183
  return module.exports = _extends11 = Object.assign ? Object.assign.bind() : function(n) {
184
184
  for (var e = 1; e < arguments.length; e++) {
185
- var t22 = arguments[e];
186
- for (var r in t22) ({}).hasOwnProperty.call(t22, r) && (n[r] = t22[r]);
185
+ var t = arguments[e];
186
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
187
187
  }
188
188
  return n;
189
189
  }, module.exports.__esModule = true, module.exports["default"] = module.exports, _extends11.apply(null, arguments);
@@ -197,12 +197,12 @@ var require_objectWithoutPropertiesLoose = __commonJS({
197
197
  "../node_modules/@babel/runtime/helpers/objectWithoutPropertiesLoose.js"(exports, module) {
198
198
  function _objectWithoutPropertiesLoose10(r, e) {
199
199
  if (null == r) return {};
200
- var t22 = {};
200
+ var t = {};
201
201
  for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
202
202
  if (-1 !== e.indexOf(n)) continue;
203
- t22[n] = r[n];
203
+ t[n] = r[n];
204
204
  }
205
- return t22;
205
+ return t;
206
206
  }
207
207
  module.exports = _objectWithoutPropertiesLoose10, module.exports.__esModule = true, module.exports["default"] = module.exports;
208
208
  }
@@ -753,6 +753,11 @@ var en_default = {
753
753
  "rte.horizontal_rule": "Horizontal rule",
754
754
  "rte.insert_image": "Insert image",
755
755
  "rte.table": "Table",
756
+ "rte.tab_html": "HTML",
757
+ "rte.tab_plain_text": "Plain Text",
758
+ "rte.tab_raw_html": "Raw HTML",
759
+ "rte.empty_content": "(empty)",
760
+ "rte.link_placeholder": "https://example.com",
756
761
  "rte.insert_variable": "Insert variable",
757
762
  "rte.attach_file": "Attach file",
758
763
  "rte.block_type.paragraph": "Paragraph",
@@ -801,6 +806,9 @@ var en_default = {
801
806
  "canvas_toolbar.align_right": "Align right",
802
807
  "canvas_toolbar.text_color": "Text color",
803
808
  "canvas_toolbar.font_family": "Font family",
809
+ "canvas_toolbar.font_sans": "Sans",
810
+ "canvas_toolbar.font_serif": "Serif",
811
+ "canvas_toolbar.font_mono": "Mono",
804
812
  "canvas_toolbar.align_top": "Align top",
805
813
  "canvas_toolbar.align_middle": "Align middle",
806
814
  "canvas_toolbar.align_bottom": "Align bottom",
@@ -813,6 +821,8 @@ var en_default = {
813
821
  "notification.loading": "Loading notifications",
814
822
  "notification.mark_all_read": "Mark all as read",
815
823
  "notification.unread": "Unread",
824
+ "notification.unread_count": "{{count}} unread",
825
+ "browser_tab.close_aria": "Close {{label}}",
816
826
  "confirm.cancel": "Cancel",
817
827
  "icon_picker.search_placeholder": "Search icons...",
818
828
  "common.loading": "Loading...",
@@ -832,10 +842,12 @@ var en_default = {
832
842
  "kanban.select_placeholder": "Select {{label}}\u2026",
833
843
  "kanban.select_priority": "Select priority\u2026",
834
844
  "kanban.select_status": "Select status\u2026",
845
+ "kanban.clear": "Clear",
835
846
  "markdown.placeholder": "Write in Markdown\u2026",
836
847
  "markdown.upload_failed": "Upload failed.",
837
848
  "markdown.loading_editor": "Loading editor\u2026",
838
849
  "markdown.uploading_image": "Uploading image\u2026",
850
+ "markdown.upload_placeholder": "uploading\u2026",
839
851
  "cropper.title": "Crop photo",
840
852
  "cropper.save": "Save",
841
853
  "cropper.cancel": "Cancel",
@@ -848,9 +860,102 @@ var en_default = {
848
860
  "celebration.share": "Share",
849
861
  "celebration.copy_image": "Copy image",
850
862
  "celebration.dismiss": "Dismiss",
851
- "charts.date_range": "Date range"
863
+ "charts.date_range": "Date range",
864
+ "flex_input.must_be_valid_number": "Must be a valid number",
865
+ "flex_input.max_decimals": "Maximum {{count}} decimal places allowed",
866
+ "flex_input.min_value": "Must be at least {{min}}",
867
+ "flex_input.max_value": "Must be at most {{max}}",
868
+ "flex_input.alpha_only": "Only letters, numbers, and spaces are allowed",
869
+ "flex_input.must_be_valid_email": "Must be a valid email address",
870
+ "flex_input.min_characters": "Must be at least {{min}} characters",
871
+ "flex_input.max_characters": "Must be at most {{max}} characters",
872
+ "flex_input.invalid_format": "Invalid format",
873
+ "flex_input.invalid_input": "Invalid input",
874
+ "textbox.placeholder": "Type here...",
875
+ "textarea.placeholder": "Type here...",
876
+ "common.remove": "Remove",
877
+ "locale_picker.change_language": "Change language",
878
+ "app_logo.alt_fallback": "Logo",
879
+ "app_header.aria_label": "Application header",
880
+ "skeleton.loading_content": "Loading content",
881
+ "spinner.loading": "Loading",
882
+ "spinner.loading_text": "Loading...",
883
+ "rte.update_link": "Update Link",
884
+ "rte.add_link": "Add Link",
885
+ "rte.remove_link": "Remove",
886
+ "rte.select_size": "Select size",
887
+ "rte.custom_size": "Custom size",
888
+ "rte.insert_table": "Insert",
889
+ "rte.search_variables": "Search variables...",
890
+ "rte.no_variables": "No variables found.",
891
+ "rte.table_operations": "Table Operations",
892
+ "rte.add_row_above": "Add row above",
893
+ "rte.add_row_below": "Add row below",
894
+ "rte.add_col_left": "Add col left",
895
+ "rte.add_col_right": "Add col right",
896
+ "rte.delete_row": "Delete row",
897
+ "rte.delete_col": "Delete col",
898
+ "rte.delete_table": "Delete table",
899
+ "rte.insert_table_heading": "Insert Table",
900
+ "rte.placeholder": "Start typing...",
901
+ "sort.asc": "Asc",
902
+ "sort.desc": "Desc",
903
+ "sort.reorder_aria": "Reorder {{field}}",
904
+ "sort.priority_aria": "Sort priority {{n}}",
905
+ "sort.direction_aria": "Sort direction for {{field}}",
906
+ "sort.remove_aria": "Remove {{field}} from sort",
907
+ "sort.active_sorts": "Active sorts",
908
+ "sort.no_active_sorts": "No active sorts",
909
+ "sort.button_label": "Sort",
910
+ "sort.empty_message": "No sort fields yet. Add one below to start ordering rows.",
911
+ "sort.all_fields_added": "All fields added",
912
+ "sort.add_sort_field": "Add sort field",
913
+ "sort.no_fields_available": "No fields available.",
914
+ "kanban.dnd_pickup": "Picked up {{item}}. Currently in {{column}}. Use arrow keys to choose a different column. Press space to drop, escape to cancel.",
915
+ "kanban.dnd_over": "{{item}} over {{column}}.",
916
+ "kanban.dnd_drop": "{{item}} dropped in {{column}}, position {{pos}}.",
917
+ "kanban.dnd_reorder": "{{item}} reordered to position {{pos}} in {{column}}.",
918
+ "kanban.dnd_cancel": "Movement cancelled. {{item}} returned to {{column}}.",
919
+ "kanban.draggable_card": "draggable card",
920
+ "loading.still_loading": "We're still trying to load the {{label}}. The connection may be slow.",
921
+ "loading.try_again": "Try again",
922
+ "loading.gentle_message": "Loading {{label}}\u2026",
923
+ "loading.default_label": "content",
924
+ "loading.firm_message": "Still working on it \u2014 almost there.",
925
+ "icon_picker.emoji_tab": "Emoji",
926
+ "icon_picker.tools_group": "Tools",
927
+ "icon_picker.home_group": "Home",
928
+ "icon_picker.weather_group": "Weather",
929
+ "icon_picker.nature_group": "Nature",
930
+ "icon_picker.symbols_group": "Symbols",
931
+ "icon_picker.no_results": "No icons found",
932
+ "error.correlation_id": "Correlation ID",
933
+ "charts.total": "Total: {{value}}",
934
+ "charts.pct_of_first": "% of first: {{pct}}%",
935
+ "charts.pct_of_prev": "% of prev: {{pct}}%",
936
+ "charts.dropoff": "Drop-off: \u2212{{value}}",
937
+ "toast.missing_prefix": "Missing: {{items}}"
852
938
  };
853
- var t = i18n.createPackageT("hazo_ui", en_default);
939
+ var default_t = i18n.createPackageT("hazo_ui", en_default);
940
+ var defaultHazoUiT = default_t;
941
+ var HazoUiI18nContext = React27.createContext(default_t);
942
+ function HazoUiI18nProvider({ t, children }) {
943
+ const safe_t = React27.useMemo(
944
+ () => (key, values) => {
945
+ try {
946
+ return t(key, values);
947
+ } catch {
948
+ get_logger().warn("i18n_missing_key_fallback", { key });
949
+ return default_t(key, values);
950
+ }
951
+ },
952
+ [t]
953
+ );
954
+ return /* @__PURE__ */ jsxRuntime.jsx(HazoUiI18nContext.Provider, { value: safe_t, children });
955
+ }
956
+ function useHazoUiT() {
957
+ return React27.useContext(HazoUiI18nContext);
958
+ }
854
959
  function FilterFieldItem({
855
960
  filterConfig,
856
961
  fieldConfig,
@@ -858,6 +963,7 @@ function FilterFieldItem({
858
963
  onOperatorChange,
859
964
  onDelete
860
965
  }) {
966
+ const t = useHazoUiT();
861
967
  const [isCalendarOpen, setIsCalendarOpen] = React27.useState(false);
862
968
  const renderInput = () => {
863
969
  switch (fieldConfig.type) {
@@ -1043,8 +1149,8 @@ function HazoUiMultiFilterDialog({
1043
1149
  availableFields,
1044
1150
  onFilterChange,
1045
1151
  initialFilters = [],
1046
- title = t("filter.title"),
1047
- description = t("filter.description"),
1152
+ title: titleProp,
1153
+ description: descriptionProp,
1048
1154
  headerBackgroundColor,
1049
1155
  headerTextColor,
1050
1156
  submitButtonBackgroundColor,
@@ -1056,6 +1162,9 @@ function HazoUiMultiFilterDialog({
1056
1162
  clearButtonTextColor,
1057
1163
  clearButtonBorderColor
1058
1164
  }) {
1165
+ const t = useHazoUiT();
1166
+ const description = descriptionProp ?? t("filter.description");
1167
+ const title = titleProp ?? t("filter.title");
1059
1168
  const config = get_hazo_ui_config();
1060
1169
  const finalSubmitBgColor = submitButtonBackgroundColor ?? config.submit_button_background_color;
1061
1170
  const finalSubmitTextColor = submitButtonTextColor ?? config.submit_button_text_color;
@@ -1297,7 +1406,6 @@ function HazoUiMultiFilterDialog({
1297
1406
  ] })
1298
1407
  ] });
1299
1408
  }
1300
- var t2 = i18n.createPackageT("hazo_ui", en_default);
1301
1409
  function SortableSortFieldItem({
1302
1410
  sortConfig,
1303
1411
  fieldLabel,
@@ -1305,6 +1413,7 @@ function SortableSortFieldItem({
1305
1413
  onDirectionChange,
1306
1414
  onDelete
1307
1415
  }) {
1416
+ const t = useHazoUiT();
1308
1417
  const {
1309
1418
  attributes,
1310
1419
  listeners,
@@ -1336,7 +1445,7 @@ function SortableSortFieldItem({
1336
1445
  ...attributes,
1337
1446
  ...listeners,
1338
1447
  className: "cls_drag_handle flex h-7 w-5 shrink-0 cursor-grab items-center justify-center rounded text-muted-foreground/60 hover:text-foreground active:cursor-grabbing",
1339
- "aria-label": `Reorder ${fieldLabel}`,
1448
+ "aria-label": t("sort.reorder_aria", { field: fieldLabel }),
1340
1449
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GripVertical, { className: "cls_drag_icon h-4 w-4" })
1341
1450
  }
1342
1451
  ),
@@ -1344,7 +1453,7 @@ function SortableSortFieldItem({
1344
1453
  "span",
1345
1454
  {
1346
1455
  className: "cls_priority_badge inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-muted text-[10px] font-semibold tabular-nums text-muted-foreground",
1347
- "aria-label": `Sort priority ${priority}`,
1456
+ "aria-label": t("sort.priority_aria", { n: priority }),
1348
1457
  children: priority
1349
1458
  }
1350
1459
  ),
@@ -1353,7 +1462,7 @@ function SortableSortFieldItem({
1353
1462
  "div",
1354
1463
  {
1355
1464
  role: "radiogroup",
1356
- "aria-label": `Sort direction for ${fieldLabel}`,
1465
+ "aria-label": t("sort.direction_aria", { field: fieldLabel }),
1357
1466
  className: "cls_direction_control inline-flex shrink-0 items-center rounded-md border border-border/70 bg-muted/40 p-0.5",
1358
1467
  children: [
1359
1468
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -1367,7 +1476,7 @@ function SortableSortFieldItem({
1367
1476
  className: "cls_dir_asc inline-flex items-center gap-1 rounded px-2 py-1 text-xs font-medium text-muted-foreground transition-colors data-[active=true]:bg-background data-[active=true]:text-foreground data-[active=true]:shadow-sm hover:text-foreground",
1368
1477
  children: [
1369
1478
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "h-3 w-3" }),
1370
- "Asc"
1479
+ t("sort.asc")
1371
1480
  ]
1372
1481
  }
1373
1482
  ),
@@ -1382,7 +1491,7 @@ function SortableSortFieldItem({
1382
1491
  className: "cls_dir_desc inline-flex items-center gap-1 rounded px-2 py-1 text-xs font-medium text-muted-foreground transition-colors data-[active=true]:bg-background data-[active=true]:text-foreground data-[active=true]:shadow-sm hover:text-foreground",
1383
1492
  children: [
1384
1493
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, { className: "h-3 w-3" }),
1385
- "Desc"
1494
+ t("sort.desc")
1386
1495
  ]
1387
1496
  }
1388
1497
  )
@@ -1396,7 +1505,7 @@ function SortableSortFieldItem({
1396
1505
  size: "sm",
1397
1506
  onClick: onDelete,
1398
1507
  className: "cls_delete_btn h-7 w-7 shrink-0 p-0 text-muted-foreground/60 hover:bg-destructive/10 hover:text-destructive",
1399
- "aria-label": `Remove ${fieldLabel} from sort`,
1508
+ "aria-label": t("sort.remove_aria", { field: fieldLabel }),
1400
1509
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "cls_delete_icon h-3.5 w-3.5" })
1401
1510
  }
1402
1511
  )
@@ -1408,8 +1517,8 @@ function HazoUiMultiSortDialog({
1408
1517
  availableFields,
1409
1518
  onSortChange,
1410
1519
  initialSortFields = [],
1411
- title = t2("sort.title"),
1412
- description = t2("sort.description"),
1520
+ title: titleProp,
1521
+ description: descriptionProp,
1413
1522
  headerBackgroundColor,
1414
1523
  headerTextColor,
1415
1524
  submitButtonBackgroundColor,
@@ -1421,6 +1530,9 @@ function HazoUiMultiSortDialog({
1421
1530
  clearButtonTextColor,
1422
1531
  clearButtonBorderColor
1423
1532
  }) {
1533
+ const t = useHazoUiT();
1534
+ const description = descriptionProp ?? t("sort.description");
1535
+ const title = titleProp ?? t("sort.title");
1424
1536
  const config = get_hazo_ui_config();
1425
1537
  const finalSubmitBgColor = submitButtonBackgroundColor ?? config.submit_button_background_color;
1426
1538
  const finalSubmitTextColor = submitButtonTextColor ?? config.submit_button_text_color;
@@ -1509,16 +1621,16 @@ function HazoUiMultiSortDialog({
1509
1621
  };
1510
1622
  const hasActiveSorts = initialSortFields.length > 0;
1511
1623
  const tooltipContent = hasActiveSorts ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_sort_tooltip_content space-y-1", children: [
1512
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_tooltip_title text-xs font-semibold mb-1", children: "Active sorts" }),
1624
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_tooltip_title text-xs font-semibold mb-1", children: t("sort.active_sorts") }),
1513
1625
  initialSortFields.map((sortConfig, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_tooltip_item text-xs", children: [
1514
1626
  index + 1,
1515
1627
  ". ",
1516
1628
  getFieldLabel(sortConfig.field),
1517
1629
  " (",
1518
- sortConfig.direction === "asc" ? "Asc" : "Desc",
1630
+ sortConfig.direction === "asc" ? t("sort.asc") : t("sort.desc"),
1519
1631
  ")"
1520
1632
  ] }, sortConfig.field))
1521
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_sort_tooltip_content text-xs", children: "No active sorts" });
1633
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_sort_tooltip_content text-xs", children: t("sort.no_active_sorts") });
1522
1634
  return /* @__PURE__ */ jsxRuntime.jsxs(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: [
1523
1635
  /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
1524
1636
  /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
@@ -1527,7 +1639,7 @@ function HazoUiMultiSortDialog({
1527
1639
  variant: "outline",
1528
1640
  size: "sm",
1529
1641
  className: "cls_sort_button",
1530
- "aria-label": t2("sort.open_dialog_aria"),
1642
+ "aria-label": t("sort.open_dialog_aria"),
1531
1643
  children: [
1532
1644
  /* @__PURE__ */ jsxRuntime.jsx(
1533
1645
  lucideReact.ArrowUpDown,
@@ -1538,7 +1650,7 @@ function HazoUiMultiSortDialog({
1538
1650
  )
1539
1651
  }
1540
1652
  ),
1541
- "Sort",
1653
+ t("sort.button_label"),
1542
1654
  hasActiveSorts && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cls_sort_count ml-2 inline-flex h-4 min-w-4 items-center justify-center rounded-full bg-blue-600 px-1 text-[10px] font-semibold text-white", children: initialSortFields.length })
1543
1655
  ]
1544
1656
  }
@@ -1583,7 +1695,7 @@ function HazoUiMultiSortDialog({
1583
1695
  }
1584
1696
  )
1585
1697
  }
1586
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_empty_sort_fields rounded-lg border border-dashed border-border/70 bg-muted/20 px-4 py-6 text-center text-xs text-muted-foreground", children: "No sort fields yet. Add one below to start ordering rows." }),
1698
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_empty_sort_fields rounded-lg border border-dashed border-border/70 bg-muted/20 px-4 py-6 text-center text-xs text-muted-foreground", children: t("sort.empty_message") }),
1587
1699
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_add_field_section", children: /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: isComboboxOpen, onOpenChange: setIsComboboxOpen, children: [
1588
1700
  /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
1589
1701
  Button,
@@ -1595,13 +1707,13 @@ function HazoUiMultiSortDialog({
1595
1707
  className: "cls_add_field_combobox w-full justify-start gap-2 border border-dashed border-border/70 text-sm font-medium text-muted-foreground hover:border-border hover:bg-muted/40 hover:text-foreground",
1596
1708
  children: [
1597
1709
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "cls_plus_icon h-4 w-4" }),
1598
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: availableFieldsToAdd.length === 0 ? "All fields added" : "Add sort field" })
1710
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: availableFieldsToAdd.length === 0 ? t("sort.all_fields_added") : t("sort.add_sort_field") })
1599
1711
  ]
1600
1712
  }
1601
1713
  ) }),
1602
1714
  /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "cls_combobox_popover w-[var(--radix-popover-trigger-width)] p-0", align: "start", children: /* @__PURE__ */ jsxRuntime.jsxs(Command, { children: [
1603
- /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: t2("sort.search_fields"), className: "cls_command_input" }),
1604
- /* @__PURE__ */ jsxRuntime.jsx(CommandList, { children: availableFieldsToAdd.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: "No fields available." }) : /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { children: availableFieldsToAdd.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
1715
+ /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: t("sort.search_fields"), className: "cls_command_input" }),
1716
+ /* @__PURE__ */ jsxRuntime.jsx(CommandList, { children: availableFieldsToAdd.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: t("sort.no_fields_available") }) : /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { children: availableFieldsToAdd.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
1605
1717
  CommandItem,
1606
1718
  {
1607
1719
  value: field.label,
@@ -1623,7 +1735,7 @@ function HazoUiMultiSortDialog({
1623
1735
  onClick: handleClearAll,
1624
1736
  className: "cls_clear_all_btn text-muted-foreground hover:text-foreground",
1625
1737
  style: clearButtonStyles,
1626
- children: t2("sort.clear_all")
1738
+ children: t("sort.clear_all")
1627
1739
  }
1628
1740
  ) }),
1629
1741
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_footer_right flex items-center gap-2", children: [
@@ -1635,7 +1747,7 @@ function HazoUiMultiSortDialog({
1635
1747
  onClick: handleCancel,
1636
1748
  className: "cls_cancel_btn",
1637
1749
  style: cancelButtonStyles,
1638
- children: t2("sort.cancel")
1750
+ children: t("sort.cancel")
1639
1751
  }
1640
1752
  ),
1641
1753
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1645,7 +1757,7 @@ function HazoUiMultiSortDialog({
1645
1757
  onClick: handleApply,
1646
1758
  className: "cls_apply_btn",
1647
1759
  style: submitButtonStyles,
1648
- children: t2("sort.apply")
1760
+ children: t("sort.apply")
1649
1761
  }
1650
1762
  )
1651
1763
  ] })
@@ -2064,7 +2176,6 @@ var TabsContent = React27__namespace.forwardRef(({ className, ...props }, ref) =
2064
2176
  }
2065
2177
  ));
2066
2178
  TabsContent.displayName = TabsPrimitive__namespace.Content.displayName;
2067
- var t3 = i18n.createPackageT("hazo_ui", en_default);
2068
2179
  function isLucideValue(value) {
2069
2180
  return value.startsWith("lucide:");
2070
2181
  }
@@ -2137,11 +2248,11 @@ var SYMBOLS_ICONS = [
2137
2248
  "Wrench"
2138
2249
  ];
2139
2250
  var LUCIDE_GROUPS = [
2140
- { key: "tools", label: "Tools", icons: TOOLS_ICONS },
2141
- { key: "home", label: "Home", icons: HOME_ICONS },
2142
- { key: "weather", label: "Weather", icons: WEATHER_ICONS },
2143
- { key: "nature", label: "Nature", icons: NATURE_ICONS },
2144
- { key: "symbols", label: "Symbols", icons: SYMBOLS_ICONS }
2251
+ { key: "tools", label_key: "icon_picker.tools_group", icons: TOOLS_ICONS },
2252
+ { key: "home", label_key: "icon_picker.home_group", icons: HOME_ICONS },
2253
+ { key: "weather", label_key: "icon_picker.weather_group", icons: WEATHER_ICONS },
2254
+ { key: "nature", label_key: "icon_picker.nature_group", icons: NATURE_ICONS },
2255
+ { key: "symbols", label_key: "icon_picker.symbols_group", icons: SYMBOLS_ICONS }
2145
2256
  ];
2146
2257
  var EMOJI_ITEMS = [
2147
2258
  // Faces
@@ -2283,6 +2394,7 @@ function HazoUiIconPicker({
2283
2394
  triggerClassName,
2284
2395
  align = "start"
2285
2396
  }) {
2397
+ const t = useHazoUiT();
2286
2398
  const [open, set_open] = React27__namespace.useState(false);
2287
2399
  const [search, set_search] = React27__namespace.useState("");
2288
2400
  const handle_select = React27__namespace.useCallback(
@@ -2330,7 +2442,7 @@ function HazoUiIconPicker({
2330
2442
  type: "text",
2331
2443
  value: search,
2332
2444
  onChange: (e) => set_search(e.target.value),
2333
- placeholder: t3("icon_picker.search_placeholder"),
2445
+ placeholder: t("icon_picker.search_placeholder"),
2334
2446
  className: cn(
2335
2447
  "cls_hazo_ui_icon_picker_search",
2336
2448
  "mb-2 flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm",
@@ -2354,11 +2466,11 @@ function HazoUiIconPicker({
2354
2466
  name
2355
2467
  );
2356
2468
  }),
2357
- filtered_search_results.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "col-span-8 py-4 text-center text-sm text-muted-foreground", children: "No icons found" })
2469
+ filtered_search_results.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "col-span-8 py-4 text-center text-sm text-muted-foreground", children: t("icon_picker.no_results") })
2358
2470
  ] }) : /* @__PURE__ */ jsxRuntime.jsxs(Tabs, { defaultValue: "emoji", children: [
2359
2471
  /* @__PURE__ */ jsxRuntime.jsxs(TabsList, { className: "grid w-full grid-cols-6", children: [
2360
- /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: "emoji", children: "Emoji" }),
2361
- LUCIDE_GROUPS.map((group) => /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: group.key, children: group.label }, group.key))
2472
+ /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: "emoji", children: t("icon_picker.emoji_tab") }),
2473
+ LUCIDE_GROUPS.map((group) => /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: group.key, children: t(group.label_key) }, group.key))
2362
2474
  ] }),
2363
2475
  /* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value: "emoji", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid max-h-56 grid-cols-8 gap-1 overflow-y-auto", children: EMOJI_ITEMS.map((emoji, index) => /* @__PURE__ */ jsxRuntime.jsx(
2364
2476
  "button",
@@ -2390,7 +2502,7 @@ function HazoUiIconPicker({
2390
2502
  }
2391
2503
  ) });
2392
2504
  }
2393
- function validateInput(value, input_type, text_len_min, text_len_max, num_min, num_max, regex, num_decimals) {
2505
+ function validateInput(value, input_type, text_len_min, text_len_max, num_min, num_max, regex, num_decimals, t) {
2394
2506
  if (value === "") {
2395
2507
  return { isValid: true };
2396
2508
  }
@@ -2398,36 +2510,36 @@ function validateInput(value, input_type, text_len_min, text_len_max, num_min, n
2398
2510
  case "numeric": {
2399
2511
  const numValue = parseFloat(value);
2400
2512
  if (isNaN(numValue)) {
2401
- return { isValid: false, errorMessage: "Must be a valid number" };
2513
+ return { isValid: false, errorMessage: t("flex_input.must_be_valid_number") };
2402
2514
  }
2403
2515
  if (num_decimals !== void 0) {
2404
2516
  const decimalPlaces = value.split(".")[1]?.length || 0;
2405
2517
  if (decimalPlaces > num_decimals) {
2406
2518
  return {
2407
2519
  isValid: false,
2408
- errorMessage: `Maximum ${num_decimals} decimal place${num_decimals !== 1 ? "s" : ""} allowed`
2520
+ errorMessage: t("flex_input.max_decimals", { count: num_decimals })
2409
2521
  };
2410
2522
  }
2411
2523
  }
2412
2524
  if (num_min !== void 0 && numValue < num_min) {
2413
- return { isValid: false, errorMessage: `Must be at least ${num_min}` };
2525
+ return { isValid: false, errorMessage: t("flex_input.min_value", { min: num_min }) };
2414
2526
  }
2415
2527
  if (num_max !== void 0 && numValue > num_max) {
2416
- return { isValid: false, errorMessage: `Must be at most ${num_max}` };
2528
+ return { isValid: false, errorMessage: t("flex_input.max_value", { max: num_max }) };
2417
2529
  }
2418
2530
  break;
2419
2531
  }
2420
2532
  case "alpha": {
2421
2533
  const alphaRegex = /^[A-Za-z0-9\s]*$/;
2422
2534
  if (!alphaRegex.test(value)) {
2423
- return { isValid: false, errorMessage: "Only letters, numbers, and spaces are allowed" };
2535
+ return { isValid: false, errorMessage: t("flex_input.alpha_only") };
2424
2536
  }
2425
2537
  break;
2426
2538
  }
2427
2539
  case "email": {
2428
2540
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
2429
2541
  if (!emailRegex.test(value)) {
2430
- return { isValid: false, errorMessage: "Must be a valid email address" };
2542
+ return { isValid: false, errorMessage: t("flex_input.must_be_valid_email") };
2431
2543
  }
2432
2544
  break;
2433
2545
  }
@@ -2435,13 +2547,13 @@ function validateInput(value, input_type, text_len_min, text_len_max, num_min, n
2435
2547
  if (text_len_min !== void 0 && value.length < text_len_min) {
2436
2548
  return {
2437
2549
  isValid: false,
2438
- errorMessage: `Must be at least ${text_len_min} character${text_len_min !== 1 ? "s" : ""}`
2550
+ errorMessage: t("flex_input.min_characters", { min: text_len_min })
2439
2551
  };
2440
2552
  }
2441
2553
  if (text_len_max !== void 0 && value.length > text_len_max) {
2442
2554
  return {
2443
2555
  isValid: false,
2444
- errorMessage: `Must be at most ${text_len_max} character${text_len_max !== 1 ? "s" : ""}`
2556
+ errorMessage: t("flex_input.max_characters", { max: text_len_max })
2445
2557
  };
2446
2558
  }
2447
2559
  break;
@@ -2450,7 +2562,7 @@ function validateInput(value, input_type, text_len_min, text_len_max, num_min, n
2450
2562
  if (regex) {
2451
2563
  const regexPattern = typeof regex === "string" ? new RegExp(regex) : regex;
2452
2564
  if (!regexPattern.test(value)) {
2453
- return { isValid: false, errorMessage: "Invalid format" };
2565
+ return { isValid: false, errorMessage: t("flex_input.invalid_format") };
2454
2566
  }
2455
2567
  }
2456
2568
  return { isValid: true };
@@ -2501,6 +2613,7 @@ var HazoUiFlexInput = React27__namespace.forwardRef(
2501
2613
  onBlur,
2502
2614
  ...props
2503
2615
  }, ref) => {
2616
+ const t = useHazoUiT();
2504
2617
  const [internalValue, setInternalValue] = React27__namespace.useState(
2505
2618
  typeof controlledValue === "string" ? controlledValue : typeof controlledValue === "number" ? String(controlledValue) : ""
2506
2619
  );
@@ -2543,10 +2656,11 @@ var HazoUiFlexInput = React27__namespace.forwardRef(
2543
2656
  num_min,
2544
2657
  num_max,
2545
2658
  regex,
2546
- num_decimals
2659
+ num_decimals,
2660
+ t
2547
2661
  );
2548
2662
  if (!validation.isValid) {
2549
- setErrorMessage(validation.errorMessage || format_guide || "Invalid input");
2663
+ setErrorMessage(validation.errorMessage || format_guide || t("flex_input.invalid_input"));
2550
2664
  } else {
2551
2665
  setErrorMessage(void 0);
2552
2666
  }
@@ -3776,10 +3890,10 @@ var BLOCK_TYPE_LABEL_KEYS = {
3776
3890
  "code-block": "rte.block_type.code_block",
3777
3891
  blockquote: "rte.block_type.blockquote"
3778
3892
  };
3779
- function get_translated_block_types(t22) {
3893
+ function get_translated_block_types(t) {
3780
3894
  return BLOCK_TYPES.map((type) => ({
3781
3895
  ...type,
3782
- label: t22(BLOCK_TYPE_LABEL_KEYS[type.value])
3896
+ label: t(BLOCK_TYPE_LABEL_KEYS[type.value])
3783
3897
  }));
3784
3898
  }
3785
3899
 
@@ -3826,7 +3940,6 @@ function get_file_extension(filename) {
3826
3940
  function is_image_file(mime_type) {
3827
3941
  return mime_type.startsWith("image/");
3828
3942
  }
3829
- var t4 = i18n.createPackageT("hazo_ui", en_default);
3830
3943
  var ALL_ON = {
3831
3944
  undo_redo: true,
3832
3945
  block_type: true,
@@ -3863,6 +3976,7 @@ var Toolbar = ({
3863
3976
  toolbar,
3864
3977
  font_families
3865
3978
  }) => {
3979
+ const t = useHazoUiT();
3866
3980
  const [link_url, set_link_url] = React27__namespace.useState("https://");
3867
3981
  const [link_popover_open, set_link_popover_open] = React27__namespace.useState(false);
3868
3982
  const [text_color_open, set_text_color_open] = React27__namespace.useState(false);
@@ -3881,7 +3995,7 @@ var Toolbar = ({
3881
3995
  }
3882
3996
  const tb = { ...ALL_ON, ...toolbar };
3883
3997
  const font_family_options = font_families && font_families.length > 0 ? font_families : FONT_FAMILIES;
3884
- const block_type_options = get_translated_block_types(t4);
3998
+ const block_type_options = get_translated_block_types(t);
3885
3999
  const get_current_font_size = () => {
3886
4000
  const attrs = editor.getAttributes("textStyle");
3887
4001
  return attrs.fontSize || FONT_SIZE_CONFIG.default;
@@ -4025,7 +4139,7 @@ var Toolbar = ({
4025
4139
  {
4026
4140
  onClick: () => editor.chain().focus().undo().run(),
4027
4141
  disabled: !editor.can().undo(),
4028
- tooltip: t4("rte.undo"),
4142
+ tooltip: t("rte.undo"),
4029
4143
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuUndo2, { className: "h-4 w-4" })
4030
4144
  },
4031
4145
  "undo"
@@ -4035,7 +4149,7 @@ var Toolbar = ({
4035
4149
  {
4036
4150
  onClick: () => editor.chain().focus().redo().run(),
4037
4151
  disabled: !editor.can().redo(),
4038
- tooltip: t4("rte.redo"),
4152
+ tooltip: t("rte.redo"),
4039
4153
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuRedo2, { className: "h-4 w-4" })
4040
4154
  },
4041
4155
  "redo"
@@ -4076,7 +4190,7 @@ var Toolbar = ({
4076
4190
  ToolbarButton,
4077
4191
  {
4078
4192
  onClick: () => handle_font_size_change(-2),
4079
- tooltip: t4("rte.decrease_font_size"),
4193
+ tooltip: t("rte.decrease_font_size"),
4080
4194
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuMinus, { className: "h-3 w-3" })
4081
4195
  }
4082
4196
  ),
@@ -4085,7 +4199,7 @@ var Toolbar = ({
4085
4199
  ToolbarButton,
4086
4200
  {
4087
4201
  onClick: () => handle_font_size_change(FONT_SIZE_CONFIG.step),
4088
- tooltip: t4("rte.increase_font_size"),
4202
+ tooltip: t("rte.increase_font_size"),
4089
4203
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuPlus, { className: "h-3 w-3" })
4090
4204
  }
4091
4205
  )
@@ -4103,7 +4217,7 @@ var Toolbar = ({
4103
4217
  {
4104
4218
  onClick: () => editor.chain().focus().toggleBold().run(),
4105
4219
  is_active: editor.isActive("bold"),
4106
- tooltip: t4("rte.bold"),
4220
+ tooltip: t("rte.bold"),
4107
4221
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuBold, { className: "h-4 w-4" })
4108
4222
  },
4109
4223
  "bold"
@@ -4117,7 +4231,7 @@ var Toolbar = ({
4117
4231
  {
4118
4232
  onClick: () => editor.chain().focus().toggleItalic().run(),
4119
4233
  is_active: editor.isActive("italic"),
4120
- tooltip: t4("rte.italic"),
4234
+ tooltip: t("rte.italic"),
4121
4235
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuItalic, { className: "h-4 w-4" })
4122
4236
  },
4123
4237
  "italic"
@@ -4131,7 +4245,7 @@ var Toolbar = ({
4131
4245
  {
4132
4246
  onClick: () => editor.chain().focus().toggleUnderline().run(),
4133
4247
  is_active: editor.isActive("underline"),
4134
- tooltip: t4("rte.underline"),
4248
+ tooltip: t("rte.underline"),
4135
4249
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuUnderline, { className: "h-4 w-4" })
4136
4250
  },
4137
4251
  "underline"
@@ -4145,7 +4259,7 @@ var Toolbar = ({
4145
4259
  {
4146
4260
  onClick: () => editor.chain().focus().toggleStrike().run(),
4147
4261
  is_active: editor.isActive("strike"),
4148
- tooltip: t4("rte.strikethrough"),
4262
+ tooltip: t("rte.strikethrough"),
4149
4263
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuStrikethrough, { className: "h-4 w-4" })
4150
4264
  },
4151
4265
  "strike"
@@ -4159,7 +4273,7 @@ var Toolbar = ({
4159
4273
  {
4160
4274
  onClick: () => editor.chain().focus().toggleSubscript().run(),
4161
4275
  is_active: editor.isActive("subscript"),
4162
- tooltip: t4("rte.subscript"),
4276
+ tooltip: t("rte.subscript"),
4163
4277
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuSubscript, { className: "h-4 w-4" })
4164
4278
  },
4165
4279
  "sub"
@@ -4173,7 +4287,7 @@ var Toolbar = ({
4173
4287
  {
4174
4288
  onClick: () => editor.chain().focus().toggleSuperscript().run(),
4175
4289
  is_active: editor.isActive("superscript"),
4176
- tooltip: t4("rte.superscript"),
4290
+ tooltip: t("rte.superscript"),
4177
4291
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuSuperscript, { className: "h-4 w-4" })
4178
4292
  },
4179
4293
  "super"
@@ -4187,29 +4301,26 @@ var Toolbar = ({
4187
4301
  if (tb.link) {
4188
4302
  items.push(
4189
4303
  /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: link_popover_open, onOpenChange: set_link_popover_open, children: [
4190
- /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { is_active: editor.isActive("link"), tooltip: t4("rte.link"), children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuLink, { className: "h-4 w-4" }) }) }),
4304
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { is_active: editor.isActive("link"), tooltip: t("rte.link"), children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuLink, { className: "h-4 w-4" }) }) }),
4191
4305
  /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "w-80 p-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
4192
4306
  /* @__PURE__ */ jsxRuntime.jsx(
4193
4307
  Input,
4194
4308
  {
4195
4309
  value: link_url,
4196
4310
  onChange: (e) => set_link_url(e.target.value),
4197
- placeholder: "https://example.com",
4311
+ placeholder: t("rte.link_placeholder"),
4198
4312
  className: "h-8 text-sm"
4199
4313
  }
4200
4314
  ),
4201
4315
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
4202
- /* @__PURE__ */ jsxRuntime.jsxs(Button, { size: "sm", onClick: handle_set_link, className: "flex-1", children: [
4203
- editor.isActive("link") ? "Update" : "Add",
4204
- " Link"
4205
- ] }),
4316
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", onClick: handle_set_link, className: "flex-1", children: editor.isActive("link") ? t("rte.update_link") : t("rte.add_link") }),
4206
4317
  editor.isActive("link") && /* @__PURE__ */ jsxRuntime.jsx(
4207
4318
  Button,
4208
4319
  {
4209
4320
  size: "sm",
4210
4321
  variant: "destructive",
4211
4322
  onClick: handle_remove_link,
4212
- children: "Remove"
4323
+ children: t("rte.remove_link")
4213
4324
  }
4214
4325
  )
4215
4326
  ] })
@@ -4223,7 +4334,7 @@ var Toolbar = ({
4223
4334
  ToolbarButton,
4224
4335
  {
4225
4336
  onClick: () => editor.chain().focus().unsetAllMarks().clearNodes().run(),
4226
- tooltip: t4("rte.clear_formatting"),
4337
+ tooltip: t("rte.clear_formatting"),
4227
4338
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuRemoveFormatting, { className: "h-4 w-4" })
4228
4339
  },
4229
4340
  "clear"
@@ -4237,7 +4348,7 @@ var Toolbar = ({
4237
4348
  if (tb.text_color) {
4238
4349
  items.push(
4239
4350
  /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: text_color_open, onOpenChange: set_text_color_open, children: [
4240
- /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { tooltip: t4("rte.text_color"), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
4351
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { tooltip: t("rte.text_color"), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
4241
4352
  /* @__PURE__ */ jsxRuntime.jsx(lu.LuPalette, { className: "h-4 w-4" }),
4242
4353
  /* @__PURE__ */ jsxRuntime.jsx(
4243
4354
  "div",
@@ -4280,7 +4391,7 @@ var Toolbar = ({
4280
4391
  if (tb.highlight_color) {
4281
4392
  items.push(
4282
4393
  /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: highlight_color_open, onOpenChange: set_highlight_color_open, children: [
4283
- /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { tooltip: t4("rte.highlight_color"), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
4394
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { tooltip: t("rte.highlight_color"), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
4284
4395
  /* @__PURE__ */ jsxRuntime.jsx(lu.LuHighlighter, { className: "h-4 w-4" }),
4285
4396
  /* @__PURE__ */ jsxRuntime.jsx(
4286
4397
  "div",
@@ -4323,7 +4434,7 @@ var Toolbar = ({
4323
4434
  {
4324
4435
  onClick: () => editor.chain().focus().setTextAlign("left").run(),
4325
4436
  is_active: editor.isActive({ textAlign: "left" }),
4326
- tooltip: t4("rte.align_left"),
4437
+ tooltip: t("rte.align_left"),
4327
4438
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignLeft, { className: "h-4 w-4" })
4328
4439
  },
4329
4440
  "align-left"
@@ -4333,7 +4444,7 @@ var Toolbar = ({
4333
4444
  {
4334
4445
  onClick: () => editor.chain().focus().setTextAlign("center").run(),
4335
4446
  is_active: editor.isActive({ textAlign: "center" }),
4336
- tooltip: t4("rte.align_center"),
4447
+ tooltip: t("rte.align_center"),
4337
4448
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignCenter, { className: "h-4 w-4" })
4338
4449
  },
4339
4450
  "align-center"
@@ -4343,7 +4454,7 @@ var Toolbar = ({
4343
4454
  {
4344
4455
  onClick: () => editor.chain().focus().setTextAlign("right").run(),
4345
4456
  is_active: editor.isActive({ textAlign: "right" }),
4346
- tooltip: t4("rte.align_right"),
4457
+ tooltip: t("rte.align_right"),
4347
4458
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignRight, { className: "h-4 w-4" })
4348
4459
  },
4349
4460
  "align-right"
@@ -4353,7 +4464,7 @@ var Toolbar = ({
4353
4464
  {
4354
4465
  onClick: () => editor.chain().focus().setTextAlign("justify").run(),
4355
4466
  is_active: editor.isActive({ textAlign: "justify" }),
4356
- tooltip: t4("rte.justify"),
4467
+ tooltip: t("rte.justify"),
4357
4468
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignJustify, { className: "h-4 w-4" })
4358
4469
  },
4359
4470
  "align-justify"
@@ -4369,7 +4480,7 @@ var Toolbar = ({
4369
4480
  {
4370
4481
  onClick: () => editor.chain().focus().toggleBulletList().run(),
4371
4482
  is_active: editor.isActive("bulletList"),
4372
- tooltip: t4("rte.bullet_list"),
4483
+ tooltip: t("rte.bullet_list"),
4373
4484
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuList, { className: "h-4 w-4" })
4374
4485
  },
4375
4486
  "bullet"
@@ -4383,7 +4494,7 @@ var Toolbar = ({
4383
4494
  {
4384
4495
  onClick: () => editor.chain().focus().toggleOrderedList().run(),
4385
4496
  is_active: editor.isActive("orderedList"),
4386
- tooltip: t4("rte.ordered_list"),
4497
+ tooltip: t("rte.ordered_list"),
4387
4498
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuListOrdered, { className: "h-4 w-4" })
4388
4499
  },
4389
4500
  "ordered"
@@ -4397,7 +4508,7 @@ var Toolbar = ({
4397
4508
  {
4398
4509
  onClick: () => editor.chain().focus().toggleTaskList().run(),
4399
4510
  is_active: editor.isActive("taskList"),
4400
- tooltip: t4("rte.checklist"),
4511
+ tooltip: t("rte.checklist"),
4401
4512
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuListChecks, { className: "h-4 w-4" })
4402
4513
  },
4403
4514
  "task"
@@ -4419,7 +4530,7 @@ var Toolbar = ({
4419
4530
  }
4420
4531
  },
4421
4532
  disabled: !editor.can().liftListItem("listItem") && !editor.can().liftListItem("taskItem"),
4422
- tooltip: t4("rte.decrease_indent"),
4533
+ tooltip: t("rte.decrease_indent"),
4423
4534
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuIndentDecrease, { className: "h-4 w-4" })
4424
4535
  },
4425
4536
  "indent-dec"
@@ -4435,7 +4546,7 @@ var Toolbar = ({
4435
4546
  }
4436
4547
  },
4437
4548
  disabled: !editor.can().sinkListItem("listItem") && !editor.can().sinkListItem("taskItem"),
4438
- tooltip: t4("rte.increase_indent"),
4549
+ tooltip: t("rte.increase_indent"),
4439
4550
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuIndentIncrease, { className: "h-4 w-4" })
4440
4551
  },
4441
4552
  "indent-inc"
@@ -4446,7 +4557,7 @@ var Toolbar = ({
4446
4557
  const items = [];
4447
4558
  if (tb.horizontal_rule) {
4448
4559
  items.push(
4449
- /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { onClick: handle_hr_insert, tooltip: t4("rte.horizontal_rule"), children: /* @__PURE__ */ jsxRuntime.jsx(rx.RxDividerHorizontal, { className: "h-4 w-4" }) }, "hr")
4560
+ /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { onClick: handle_hr_insert, tooltip: t("rte.horizontal_rule"), children: /* @__PURE__ */ jsxRuntime.jsx(rx.RxDividerHorizontal, { className: "h-4 w-4" }) }, "hr")
4450
4561
  );
4451
4562
  }
4452
4563
  if (tb.image) {
@@ -4455,7 +4566,7 @@ var Toolbar = ({
4455
4566
  ToolbarButton,
4456
4567
  {
4457
4568
  onClick: () => image_input_ref.current?.click(),
4458
- tooltip: t4("rte.insert_image"),
4569
+ tooltip: t("rte.insert_image"),
4459
4570
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuImage, { className: "h-4 w-4" })
4460
4571
  },
4461
4572
  "image"
@@ -4469,14 +4580,14 @@ var Toolbar = ({
4469
4580
  ToolbarButton,
4470
4581
  {
4471
4582
  is_active: editor.isActive("table"),
4472
- tooltip: t4("rte.table"),
4583
+ tooltip: t("rte.table"),
4473
4584
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuTable, { className: "h-4 w-4" })
4474
4585
  }
4475
4586
  ) }),
4476
4587
  /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "w-auto p-3", align: "start", children: editor.isActive("table") ? (
4477
4588
  // Table editing controls when inside a table
4478
4589
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
4479
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-medium mb-1", children: "Table Operations" }),
4590
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-medium mb-1", children: t("rte.table_operations") }),
4480
4591
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-1", children: [
4481
4592
  /* @__PURE__ */ jsxRuntime.jsxs(
4482
4593
  Button,
@@ -4487,7 +4598,7 @@ var Toolbar = ({
4487
4598
  onClick: handle_add_row_before,
4488
4599
  children: [
4489
4600
  /* @__PURE__ */ jsxRuntime.jsx(lu.LuTableRowsSplit, { className: "h-3 w-3 mr-1" }),
4490
- "Add row above"
4601
+ t("rte.add_row_above")
4491
4602
  ]
4492
4603
  }
4493
4604
  ),
@@ -4500,7 +4611,7 @@ var Toolbar = ({
4500
4611
  onClick: handle_add_row_after,
4501
4612
  children: [
4502
4613
  /* @__PURE__ */ jsxRuntime.jsx(lu.LuTableRowsSplit, { className: "h-3 w-3 mr-1" }),
4503
- "Add row below"
4614
+ t("rte.add_row_below")
4504
4615
  ]
4505
4616
  }
4506
4617
  ),
@@ -4513,7 +4624,7 @@ var Toolbar = ({
4513
4624
  onClick: handle_add_col_before,
4514
4625
  children: [
4515
4626
  /* @__PURE__ */ jsxRuntime.jsx(lu.LuTableColumnsSplit, { className: "h-3 w-3 mr-1" }),
4516
- "Add col left"
4627
+ t("rte.add_col_left")
4517
4628
  ]
4518
4629
  }
4519
4630
  ),
@@ -4526,7 +4637,7 @@ var Toolbar = ({
4526
4637
  onClick: handle_add_col_after,
4527
4638
  children: [
4528
4639
  /* @__PURE__ */ jsxRuntime.jsx(lu.LuTableColumnsSplit, { className: "h-3 w-3 mr-1" }),
4529
- "Add col right"
4640
+ t("rte.add_col_right")
4530
4641
  ]
4531
4642
  }
4532
4643
  ),
@@ -4539,7 +4650,7 @@ var Toolbar = ({
4539
4650
  onClick: handle_delete_row,
4540
4651
  children: [
4541
4652
  /* @__PURE__ */ jsxRuntime.jsx(lu.LuTrash2, { className: "h-3 w-3 mr-1" }),
4542
- "Delete row"
4653
+ t("rte.delete_row")
4543
4654
  ]
4544
4655
  }
4545
4656
  ),
@@ -4552,7 +4663,7 @@ var Toolbar = ({
4552
4663
  onClick: handle_delete_col,
4553
4664
  children: [
4554
4665
  /* @__PURE__ */ jsxRuntime.jsx(lu.LuTrash2, { className: "h-3 w-3 mr-1" }),
4555
- "Delete col"
4666
+ t("rte.delete_col")
4556
4667
  ]
4557
4668
  }
4558
4669
  )
@@ -4566,7 +4677,7 @@ var Toolbar = ({
4566
4677
  onClick: handle_delete_table,
4567
4678
  children: [
4568
4679
  /* @__PURE__ */ jsxRuntime.jsx(lu.LuTrash2, { className: "h-3 w-3 mr-1" }),
4569
- "Delete table"
4680
+ t("rte.delete_table")
4570
4681
  ]
4571
4682
  }
4572
4683
  )
@@ -4574,7 +4685,7 @@ var Toolbar = ({
4574
4685
  ) : (
4575
4686
  // Table size picker when not in a table
4576
4687
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
4577
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-medium mb-1", children: "Insert Table" }),
4688
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-medium mb-1", children: t("rte.insert_table_heading") }),
4578
4689
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-0.5", children: Array.from({ length: 6 }).map((_, row_idx) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-0.5", children: Array.from({ length: 6 }).map((_2, col_idx) => /* @__PURE__ */ jsxRuntime.jsx(
4579
4690
  "div",
4580
4691
  {
@@ -4588,9 +4699,9 @@ var Toolbar = ({
4588
4699
  },
4589
4700
  col_idx
4590
4701
  )) }, row_idx)) }),
4591
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-center text-muted-foreground", children: hovered_cell ? `${hovered_cell.col} x ${hovered_cell.row}` : "Select size" }),
4702
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-center text-muted-foreground", children: hovered_cell ? `${hovered_cell.col} x ${hovered_cell.row}` : t("rte.select_size") }),
4592
4703
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t pt-2 mt-1", children: [
4593
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground mb-2", children: "Custom size" }),
4704
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground mb-2", children: t("rte.custom_size") }),
4594
4705
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
4595
4706
  /* @__PURE__ */ jsxRuntime.jsx(
4596
4707
  Input,
@@ -4623,7 +4734,7 @@ var Toolbar = ({
4623
4734
  onClick: () => handle_table_insert(table_rows, table_cols),
4624
4735
  children: [
4625
4736
  /* @__PURE__ */ jsxRuntime.jsx(lu.LuGrid3X3, { className: "h-3 w-3 mr-1" }),
4626
- "Insert"
4737
+ t("rte.insert_table")
4627
4738
  ]
4628
4739
  }
4629
4740
  )
@@ -4641,11 +4752,11 @@ var Toolbar = ({
4641
4752
  if (tb.variables && variables.length > 0) {
4642
4753
  items.push(
4643
4754
  /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: variables_menu_open, onOpenChange: set_variables_menu_open, children: [
4644
- /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { tooltip: t4("rte.insert_variable"), children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuVariable, { className: "h-4 w-4" }) }) }),
4755
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { tooltip: t("rte.insert_variable"), children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuVariable, { className: "h-4 w-4" }) }) }),
4645
4756
  /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "w-64 p-0", align: "start", children: /* @__PURE__ */ jsxRuntime.jsxs(Command, { children: [
4646
- /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: "Search variables...", className: "h-8 text-xs" }),
4757
+ /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: t("rte.search_variables"), className: "h-8 text-xs" }),
4647
4758
  /* @__PURE__ */ jsxRuntime.jsxs(CommandList, { children: [
4648
- /* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: "No variables found." }),
4759
+ /* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: t("rte.no_variables") }),
4649
4760
  /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { children: variables.map((variable) => /* @__PURE__ */ jsxRuntime.jsx(
4650
4761
  CommandItem,
4651
4762
  {
@@ -4670,7 +4781,7 @@ var Toolbar = ({
4670
4781
  ToolbarButton,
4671
4782
  {
4672
4783
  onClick: () => file_input_ref.current?.click(),
4673
- tooltip: t4("rte.attach_file"),
4784
+ tooltip: t("rte.attach_file"),
4674
4785
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuPaperclip, { className: "h-4 w-4" })
4675
4786
  },
4676
4787
  "attach"
@@ -4958,7 +5069,7 @@ var HazoUiRte = ({
4958
5069
  attachments: initial_attachments = [],
4959
5070
  variables = [],
4960
5071
  on_change,
4961
- placeholder = "Start typing...",
5072
+ placeholder,
4962
5073
  min_height = "200px",
4963
5074
  max_height = "400px",
4964
5075
  disabled = false,
@@ -4967,6 +5078,8 @@ var HazoUiRte = ({
4967
5078
  toolbar,
4968
5079
  font_families
4969
5080
  }) => {
5081
+ const t = useHazoUiT();
5082
+ const resolved_placeholder = placeholder ?? t("rte.placeholder");
4970
5083
  const [attachments, set_attachments] = React27__namespace.useState(
4971
5084
  initial_attachments
4972
5085
  );
@@ -5016,7 +5129,7 @@ var HazoUiRte = ({
5016
5129
  }
5017
5130
  }),
5018
5131
  Placeholder__default.default.configure({
5019
- placeholder
5132
+ placeholder: resolved_placeholder
5020
5133
  }),
5021
5134
  HorizontalRule__default.default,
5022
5135
  extensionTable.Table.configure({
@@ -5160,9 +5273,9 @@ var HazoUiRte = ({
5160
5273
  }
5161
5274
  ),
5162
5275
  show_output_viewer && editor && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_rte_tabs border-b border-border px-2 pt-2", children: /* @__PURE__ */ jsxRuntime.jsx(Tabs, { value: active_tab, onValueChange: (v) => set_active_tab(v), children: /* @__PURE__ */ jsxRuntime.jsxs(TabsList, { className: "h-9", children: [
5163
- /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: "html", className: "text-sm", children: "HTML" }),
5164
- /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: "plain_text", className: "text-sm", children: "Plain Text" }),
5165
- /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: "raw_html", className: "text-sm", children: "Raw HTML" })
5276
+ /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: "html", className: "text-sm", children: t("rte.tab_html") }),
5277
+ /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: "plain_text", className: "text-sm", children: t("rte.tab_plain_text") }),
5278
+ /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: "raw_html", className: "text-sm", children: t("rte.tab_raw_html") })
5166
5279
  ] }) }) }),
5167
5280
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { minHeight: min_height, maxHeight: max_height }, className: "overflow-auto", children: [
5168
5281
  active_tab === "html" && /* @__PURE__ */ jsxRuntime.jsx(
@@ -5175,8 +5288,8 @@ var HazoUiRte = ({
5175
5288
  )
5176
5289
  }
5177
5290
  ),
5178
- active_tab === "plain_text" && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "cls_rte_plain_text p-4 text-sm whitespace-pre-wrap font-mono h-full", children: editor?.getText() || "(empty)" }),
5179
- active_tab === "raw_html" && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "cls_rte_raw_html p-4 text-xs whitespace-pre-wrap font-mono text-muted-foreground h-full", children: format_html(editor?.getHTML() || "") || "(empty)" })
5291
+ active_tab === "plain_text" && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "cls_rte_plain_text p-4 text-sm whitespace-pre-wrap font-mono h-full", children: editor?.getText() || t("rte.empty_content") }),
5292
+ active_tab === "raw_html" && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "cls_rte_raw_html p-4 text-xs whitespace-pre-wrap font-mono text-muted-foreground h-full", children: format_html(editor?.getHTML() || "") || t("rte.empty_content") })
5180
5293
  ] }),
5181
5294
  /* @__PURE__ */ jsxRuntime.jsx(
5182
5295
  AttachmentsList,
@@ -5191,7 +5304,6 @@ var HazoUiRte = ({
5191
5304
  );
5192
5305
  };
5193
5306
  HazoUiRte.displayName = "HazoUiRte";
5194
- var t5 = i18n.createPackageT("hazo_ui", en_default);
5195
5307
  function CanvasTextToolbar({
5196
5308
  bold,
5197
5309
  italic,
@@ -5212,6 +5324,7 @@ function CanvasTextToolbar({
5212
5324
  className,
5213
5325
  style
5214
5326
  }) {
5327
+ const t = useHazoUiT();
5215
5328
  return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { delayDuration: 300, children: /* @__PURE__ */ jsxRuntime.jsxs(
5216
5329
  "div",
5217
5330
  {
@@ -5222,14 +5335,14 @@ function CanvasTextToolbar({
5222
5335
  ),
5223
5336
  style,
5224
5337
  children: [
5225
- /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { is_active: bold, onClick: onBold, tooltip: t5("canvas_toolbar.bold"), children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuBold, { className: "h-4 w-4" }) }),
5226
- /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { is_active: italic, onClick: onItalic, tooltip: t5("canvas_toolbar.italic"), children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuItalic, { className: "h-4 w-4" }) }),
5338
+ /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { is_active: bold, onClick: onBold, tooltip: t("canvas_toolbar.bold"), children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuBold, { className: "h-4 w-4" }) }),
5339
+ /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { is_active: italic, onClick: onItalic, tooltip: t("canvas_toolbar.italic"), children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuItalic, { className: "h-4 w-4" }) }),
5227
5340
  /* @__PURE__ */ jsxRuntime.jsx(
5228
5341
  ToolbarButton,
5229
5342
  {
5230
5343
  is_active: underline,
5231
5344
  onClick: onUnderline,
5232
- tooltip: t5("canvas_toolbar.underline"),
5345
+ tooltip: t("canvas_toolbar.underline"),
5233
5346
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuUnderline, { className: "h-4 w-4" })
5234
5347
  }
5235
5348
  ),
@@ -5239,7 +5352,7 @@ function CanvasTextToolbar({
5239
5352
  {
5240
5353
  is_active: align === "left",
5241
5354
  onClick: () => onAlign?.("left"),
5242
- tooltip: t5("canvas_toolbar.align_left"),
5355
+ tooltip: t("canvas_toolbar.align_left"),
5243
5356
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignLeft, { className: "h-4 w-4" })
5244
5357
  }
5245
5358
  ),
@@ -5248,7 +5361,7 @@ function CanvasTextToolbar({
5248
5361
  {
5249
5362
  is_active: align === "center",
5250
5363
  onClick: () => onAlign?.("center"),
5251
- tooltip: t5("canvas_toolbar.align_center"),
5364
+ tooltip: t("canvas_toolbar.align_center"),
5252
5365
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignCenter, { className: "h-4 w-4" })
5253
5366
  }
5254
5367
  ),
@@ -5257,7 +5370,7 @@ function CanvasTextToolbar({
5257
5370
  {
5258
5371
  is_active: align === "right",
5259
5372
  onClick: () => onAlign?.("right"),
5260
- tooltip: t5("canvas_toolbar.align_right"),
5373
+ tooltip: t("canvas_toolbar.align_right"),
5261
5374
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignRight, { className: "h-4 w-4" })
5262
5375
  }
5263
5376
  ),
@@ -5266,7 +5379,7 @@ function CanvasTextToolbar({
5266
5379
  "label",
5267
5380
  {
5268
5381
  className: "relative flex h-8 w-8 cursor-pointer items-center justify-center rounded-md hover:bg-accent",
5269
- title: t5("canvas_toolbar.text_color"),
5382
+ title: t("canvas_toolbar.text_color"),
5270
5383
  children: [
5271
5384
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
5272
5385
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-bold text-muted-foreground", children: "A" }),
@@ -5296,7 +5409,7 @@ function CanvasTextToolbar({
5296
5409
  {
5297
5410
  is_active: verticalAlign === "top",
5298
5411
  onClick: () => onVerticalAlign?.("top"),
5299
- tooltip: t5("canvas_toolbar.align_top"),
5412
+ tooltip: t("canvas_toolbar.align_top"),
5300
5413
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignVerticalJustifyStart, { className: "h-4 w-4" })
5301
5414
  }
5302
5415
  ),
@@ -5305,7 +5418,7 @@ function CanvasTextToolbar({
5305
5418
  {
5306
5419
  is_active: verticalAlign === "middle",
5307
5420
  onClick: () => onVerticalAlign?.("middle"),
5308
- tooltip: t5("canvas_toolbar.align_middle"),
5421
+ tooltip: t("canvas_toolbar.align_middle"),
5309
5422
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignVerticalJustifyCenter, { className: "h-4 w-4" })
5310
5423
  }
5311
5424
  ),
@@ -5314,7 +5427,7 @@ function CanvasTextToolbar({
5314
5427
  {
5315
5428
  is_active: verticalAlign === "bottom",
5316
5429
  onClick: () => onVerticalAlign?.("bottom"),
5317
- tooltip: t5("canvas_toolbar.align_bottom"),
5430
+ tooltip: t("canvas_toolbar.align_bottom"),
5318
5431
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignVerticalJustifyEnd, { className: "h-4 w-4" })
5319
5432
  }
5320
5433
  ),
@@ -5325,11 +5438,11 @@ function CanvasTextToolbar({
5325
5438
  value: font,
5326
5439
  onChange: (e) => onFont?.(e.target.value),
5327
5440
  className: "h-8 text-xs rounded-md border border-border bg-background px-1 text-foreground focus:outline-none",
5328
- title: t5("canvas_toolbar.font_family"),
5441
+ title: t("canvas_toolbar.font_family"),
5329
5442
  children: [
5330
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "sans-serif", children: "Sans" }),
5331
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "serif", children: "Serif" }),
5332
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "monospace", children: "Mono" }),
5443
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "sans-serif", children: t("canvas_toolbar.font_sans") }),
5444
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "serif", children: t("canvas_toolbar.font_serif") }),
5445
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "monospace", children: t("canvas_toolbar.font_mono") }),
5333
5446
  /* @__PURE__ */ jsxRuntime.jsx("option", { value: "Arial", children: "Arial" }),
5334
5447
  /* @__PURE__ */ jsxRuntime.jsx("option", { value: "Georgia", children: "Georgia" }),
5335
5448
  /* @__PURE__ */ jsxRuntime.jsx("option", { value: "Courier New", children: "Courier" })
@@ -5337,12 +5450,11 @@ function CanvasTextToolbar({
5337
5450
  }
5338
5451
  ),
5339
5452
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-1 h-6 w-px bg-border" }),
5340
- /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { is_active: bullet, onClick: onBullet, tooltip: t5("canvas_toolbar.bullet_list"), children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuList, { className: "h-4 w-4" }) })
5453
+ /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { is_active: bullet, onClick: onBullet, tooltip: t("canvas_toolbar.bullet_list"), children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuList, { className: "h-4 w-4" }) })
5341
5454
  ]
5342
5455
  }
5343
5456
  ) });
5344
5457
  }
5345
- var t6 = i18n.createPackageT("hazo_ui", en_default);
5346
5458
  var MdEditorLazy = React27.lazy(() => import('@uiw/react-md-editor'));
5347
5459
  var EDITOR_TEXTAREA_SELECTOR = ".w-md-editor-text-input";
5348
5460
  function MarkdownEditor({
@@ -5359,6 +5471,7 @@ function MarkdownEditor({
5359
5471
  renderPreview,
5360
5472
  showPreview = true
5361
5473
  }) {
5474
+ const t = useHazoUiT();
5362
5475
  const [mounted, setMounted] = React27.useState(false);
5363
5476
  React27.useEffect(() => setMounted(true), []);
5364
5477
  const valueRef = React27.useRef(value);
@@ -5426,19 +5539,19 @@ function MarkdownEditor({
5426
5539
  const current = valueRef.current;
5427
5540
  const before = current.slice(0, start);
5428
5541
  const after = current.slice(end);
5429
- onChange(before + "![uploading\u2026]()" + after);
5542
+ onChange(before + "![" + t("markdown.upload_placeholder") + "]()" + after);
5430
5543
  setUploading(true);
5431
5544
  setError("");
5432
5545
  try {
5433
5546
  const url = await onImageUpload(file);
5434
5547
  if (!url) {
5435
- setError(t6("markdown.upload_failed"));
5548
+ setError(t("markdown.upload_failed"));
5436
5549
  onChange(before + after);
5437
5550
  return;
5438
5551
  }
5439
5552
  onChange(before + `![](${url})` + after);
5440
5553
  } catch {
5441
- setError(t6("markdown.upload_failed"));
5554
+ setError(t("markdown.upload_failed"));
5442
5555
  onChange(before + after);
5443
5556
  } finally {
5444
5557
  setUploading(false);
@@ -5462,7 +5575,7 @@ function MarkdownEditor({
5462
5575
  {
5463
5576
  className: "flex items-center justify-center rounded-md border border-border bg-muted/30 text-sm text-muted-foreground",
5464
5577
  style: { height },
5465
- children: t6("markdown.loading_editor")
5578
+ children: t("markdown.loading_editor")
5466
5579
  }
5467
5580
  ),
5468
5581
  children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -5474,7 +5587,7 @@ function MarkdownEditor({
5474
5587
  preview: effectivePreview,
5475
5588
  visibleDragbar: false,
5476
5589
  commands: editorCommands,
5477
- textareaProps: { placeholder: placeholder ?? t6("markdown.placeholder"), onPaste: handlePaste }
5590
+ textareaProps: { placeholder: placeholder ?? t("markdown.placeholder"), onPaste: handlePaste }
5478
5591
  }
5479
5592
  )
5480
5593
  }
@@ -5483,7 +5596,7 @@ function MarkdownEditor({
5483
5596
  {
5484
5597
  className: "flex items-center justify-center rounded-md border border-border bg-muted/30 text-sm text-muted-foreground",
5485
5598
  style: { height },
5486
- children: t6("markdown.loading_editor")
5599
+ children: t("markdown.loading_editor")
5487
5600
  }
5488
5601
  ) }),
5489
5602
  useCustomPreview && showPreview && /* @__PURE__ */ jsxRuntime.jsx(
@@ -5497,7 +5610,7 @@ function MarkdownEditor({
5497
5610
  ]
5498
5611
  }
5499
5612
  ),
5500
- uploading && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: t6("markdown.uploading_image") }),
5613
+ uploading && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: t("markdown.uploading_image") }),
5501
5614
  error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-xs text-destructive", children: error })
5502
5615
  ] });
5503
5616
  }
@@ -6233,7 +6346,7 @@ var HazoUiTextbox = ({
6233
6346
  value,
6234
6347
  default_value,
6235
6348
  prefixes,
6236
- placeholder = "Type here...",
6349
+ placeholder,
6237
6350
  disabled = false,
6238
6351
  className,
6239
6352
  pill_variant = "default",
@@ -6244,6 +6357,8 @@ var HazoUiTextbox = ({
6244
6357
  on_command_change,
6245
6358
  on_command_remove
6246
6359
  }) => {
6360
+ const t = useHazoUiT();
6361
+ const resolved_placeholder = placeholder ?? t("textbox.placeholder");
6247
6362
  const generated_instance_id = React27__namespace.useId();
6248
6363
  const instance_id = provided_instance_id || generated_instance_id;
6249
6364
  const [suggestion_state, set_suggestion_state] = React27__namespace.useState(null);
@@ -6276,7 +6391,7 @@ var HazoUiTextbox = ({
6276
6391
  index_default2,
6277
6392
  index_default3,
6278
6393
  Placeholder__default.default.configure({
6279
- placeholder
6394
+ placeholder: resolved_placeholder
6280
6395
  }),
6281
6396
  CommandNodeExtension.configure({}),
6282
6397
  ...suggestion_extensions
@@ -6655,7 +6770,7 @@ var HazoUiTextbox = ({
6655
6770
  edit_selected_index === edit_commands.length && "bg-destructive/10"
6656
6771
  ),
6657
6772
  onClick: handle_command_remove,
6658
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Remove" })
6773
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: t("common.remove") })
6659
6774
  }
6660
6775
  )
6661
6776
  ] })
@@ -6787,7 +6902,7 @@ var HazoUiTextarea = ({
6787
6902
  value,
6788
6903
  default_value,
6789
6904
  prefixes,
6790
- placeholder = "Type here...",
6905
+ placeholder,
6791
6906
  disabled = false,
6792
6907
  className,
6793
6908
  pill_variant = "default",
@@ -6801,6 +6916,8 @@ var HazoUiTextarea = ({
6801
6916
  on_command_change,
6802
6917
  on_command_remove
6803
6918
  }) => {
6919
+ const t = useHazoUiT();
6920
+ const resolved_placeholder = placeholder ?? t("textarea.placeholder");
6804
6921
  const generated_instance_id = React27__namespace.useId();
6805
6922
  const instance_id = provided_instance_id || generated_instance_id;
6806
6923
  const [suggestion_state, set_suggestion_state] = React27__namespace.useState(null);
@@ -6835,7 +6952,7 @@ var HazoUiTextarea = ({
6835
6952
  index_default3,
6836
6953
  index_default4,
6837
6954
  Placeholder__default.default.configure({
6838
- placeholder
6955
+ placeholder: resolved_placeholder
6839
6956
  }),
6840
6957
  CommandNodeExtension.configure({}),
6841
6958
  ...suggestion_extensions
@@ -7225,7 +7342,7 @@ var HazoUiTextarea = ({
7225
7342
  backgroundColor: edit_selected_index === edit_commands.length ? "rgba(239, 68, 68, 0.1)" : "inherit"
7226
7343
  },
7227
7344
  onClick: handle_command_remove,
7228
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Remove" })
7345
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: t("common.remove") })
7229
7346
  }
7230
7347
  )
7231
7348
  ] })
@@ -7285,7 +7402,6 @@ function resolve_animation_classes(open_anim = "zoom", close_anim = "zoom") {
7285
7402
  const close_classes = close_anim in ANIMATION_PRESETS ? ANIMATION_PRESETS[close_anim].close : close_anim;
7286
7403
  return `${open_classes} ${close_classes}`;
7287
7404
  }
7288
- var t7 = i18n.createPackageT("hazo_ui", en_default);
7289
7405
  var VARIANT_PRESETS = {
7290
7406
  info: {
7291
7407
  header_background_color: "var(--dialog-info-bg)",
@@ -7372,6 +7488,7 @@ function HazoUiDialog({
7372
7488
  showCloseButton = true,
7373
7489
  kind
7374
7490
  }) {
7491
+ const t = useHazoUiT();
7375
7492
  const config = get_hazo_ui_config();
7376
7493
  const is_confirm_kind = kind === "confirm";
7377
7494
  const is_status_kind = kind === "status";
@@ -7379,11 +7496,11 @@ function HazoUiDialog({
7379
7496
  const cancel_ref = React27__namespace.useRef(null);
7380
7497
  const variant_preset = variant !== "default" ? VARIANT_PRESETS[variant] : is_status_kind || is_confirm_kind ? NEUTRAL_VARIANT_PRESET : void 0;
7381
7498
  const resolved_action_button_variant = actionButtonVariant ?? variant_preset?.action_button_variant ?? "default";
7382
- const resolved_title = title ?? t7("dialog.default_title");
7383
- const resolved_cancel_text = cancelButtonText ?? t7("dialog.cancel");
7499
+ const resolved_title = title ?? t("dialog.default_title");
7500
+ const resolved_cancel_text = cancelButtonText ?? t("dialog.cancel");
7384
7501
  const showCancelButton = showCancelButtonProp ?? (is_status_kind ? false : true);
7385
7502
  const closeOnConfirm = closeOnConfirmProp ?? (is_status_kind || is_confirm_kind ? true : false);
7386
- const actionButtonText = actionButtonTextProp ?? (is_status_kind ? t7("dialog.ok") : is_confirm_kind ? showCancelButton ? t7("dialog.confirm") : t7("dialog.ok") : t7("dialog.confirm"));
7503
+ const actionButtonText = actionButtonTextProp ?? (is_status_kind ? t("dialog.ok") : is_confirm_kind ? showCancelButton ? t("dialog.confirm") : t("dialog.ok") : t("dialog.confirm"));
7387
7504
  const actionButtonLoading = actionButtonLoadingProp ?? (is_confirm_kind ? internal_confirm_loading : false);
7388
7505
  const handleConfirm = () => {
7389
7506
  if (is_confirm_kind) {
@@ -7710,7 +7827,7 @@ function HazoUiDialog({
7710
7827
  style: headerBar ? { color: "var(--dialog-header-bar-fg)" } : finalHeaderTextColor ? { color: finalHeaderTextColor } : void 0,
7711
7828
  children: [
7712
7829
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" }),
7713
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: t7("dialog.close") })
7830
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: t("dialog.close") })
7714
7831
  ]
7715
7832
  }
7716
7833
  )
@@ -7719,7 +7836,6 @@ function HazoUiDialog({
7719
7836
  )
7720
7837
  ] }) });
7721
7838
  }
7722
- var t8 = i18n.createPackageT("hazo_ui", en_default);
7723
7839
  function HazoUiConfirmDialog({
7724
7840
  open,
7725
7841
  onOpenChange,
@@ -7728,7 +7844,7 @@ function HazoUiConfirmDialog({
7728
7844
  children,
7729
7845
  variant = "default",
7730
7846
  confirmLabel,
7731
- cancelLabel = t8("confirm.cancel"),
7847
+ cancelLabel: cancelLabelProp,
7732
7848
  showCancelButton = true,
7733
7849
  onConfirm,
7734
7850
  onCancel,
@@ -7739,6 +7855,8 @@ function HazoUiConfirmDialog({
7739
7855
  openAnimation = "zoom",
7740
7856
  closeAnimation = "zoom"
7741
7857
  }) {
7858
+ const t = useHazoUiT();
7859
+ const cancelLabel = cancelLabelProp ?? t("confirm.cancel");
7742
7860
  const resolved_accent_color = confirmButtonColor ?? accentColor;
7743
7861
  return /* @__PURE__ */ jsxRuntime.jsx(
7744
7862
  HazoUiDialog,
@@ -7777,7 +7895,6 @@ var Slider = React27__namespace.forwardRef(({ className, ...props }, ref) => /*
7777
7895
  }
7778
7896
  ));
7779
7897
  Slider.displayName = SliderPrimitive__namespace.Root.displayName;
7780
- var t9 = i18n.createPackageT("hazo_ui", en_default);
7781
7898
  async function getCroppedImg(imageSrc, areaPixels, outputSize, quality) {
7782
7899
  const img = await new Promise((resolve, reject) => {
7783
7900
  const image = new Image();
@@ -7826,12 +7943,13 @@ var HazoUiImageCropper = React27__namespace.forwardRef(function HazoUiImageCropp
7826
7943
  zoomLabel,
7827
7944
  className
7828
7945
  }, ref) {
7946
+ const t = useHazoUiT();
7829
7947
  const [crop, set_crop] = React27__namespace.useState({
7830
7948
  x: 0,
7831
7949
  y: 0
7832
7950
  });
7833
7951
  const [zoom, set_zoom] = React27__namespace.useState(1);
7834
- const resolved_zoom_label = zoomLabel ?? t9("cropper.zoom");
7952
+ const resolved_zoom_label = zoomLabel ?? t("cropper.zoom");
7835
7953
  const cropped_area_pixels_ref = React27__namespace.useRef(null);
7836
7954
  const handle_crop_complete = React27__namespace.useCallback(
7837
7955
  (_croppedArea, croppedAreaPixels) => {
@@ -7906,7 +8024,6 @@ var HazoUiImageCropper = React27__namespace.forwardRef(function HazoUiImageCropp
7906
8024
  ] });
7907
8025
  });
7908
8026
  HazoUiImageCropper.displayName = "HazoUiImageCropper";
7909
- var t10 = i18n.createPackageT("hazo_ui", en_default);
7910
8027
  function HazoUiImageCropperDialog({
7911
8028
  open,
7912
8029
  onOpenChange,
@@ -7920,10 +8037,11 @@ function HazoUiImageCropperDialog({
7920
8037
  outputSize = 512,
7921
8038
  quality = 0.9
7922
8039
  }) {
7923
- const resolved_title = title ?? t10("cropper.title");
7924
- const resolved_confirm_label = confirmLabel ?? t10("cropper.save");
7925
- const resolved_cancel_label = cancelLabel ?? t10("cropper.cancel");
7926
- const resolved_zoom_label = zoomLabel ?? t10("cropper.zoom");
8040
+ const t = useHazoUiT();
8041
+ const resolved_title = title ?? t("cropper.title");
8042
+ const resolved_confirm_label = confirmLabel ?? t("cropper.save");
8043
+ const resolved_cancel_label = cancelLabel ?? t("cropper.cancel");
8044
+ const resolved_zoom_label = zoomLabel ?? t("cropper.zoom");
7927
8045
  const cropper_ref = React27__namespace.useRef(null);
7928
8046
  const [image_src, set_image_src] = React27__namespace.useState(null);
7929
8047
  const [is_confirming, set_is_confirming] = React27__namespace.useState(false);
@@ -8410,14 +8528,15 @@ var CardFooter = React27__namespace.forwardRef(
8410
8528
  );
8411
8529
  CardFooter.displayName = "CardFooter";
8412
8530
  function Spinner({ className, size = "md" }) {
8531
+ const t = useHazoUiT();
8413
8532
  const sizeClasses = { sm: "h-4 w-4", md: "h-8 w-8", lg: "h-12 w-12" };
8414
8533
  return /* @__PURE__ */ jsxRuntime.jsx(
8415
8534
  "div",
8416
8535
  {
8417
8536
  className: cn("animate-spin rounded-full border-2 border-current border-t-transparent text-primary", sizeClasses[size], className),
8418
8537
  role: "status",
8419
- "aria-label": "Loading",
8420
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading..." })
8538
+ "aria-label": t("spinner.loading"),
8539
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: t("spinner.loading_text") })
8421
8540
  }
8422
8541
  );
8423
8542
  }
@@ -8594,18 +8713,20 @@ function SkeletonRect({ width = "100%", height = 96, radius = 6, className }) {
8594
8713
  }
8595
8714
  );
8596
8715
  }
8597
- function SkeletonGroup({ label = "Loading content", children, className, ...rest }) {
8716
+ function SkeletonGroup({ label, children, className, ...rest }) {
8717
+ const t = useHazoUiT();
8718
+ const resolved_label = label ?? t("skeleton.loading_content");
8598
8719
  return /* @__PURE__ */ jsxRuntime.jsxs(
8599
8720
  "div",
8600
8721
  {
8601
8722
  role: "status",
8602
8723
  "aria-busy": "true",
8603
- "aria-label": label,
8724
+ "aria-label": resolved_label,
8604
8725
  className: cn("space-y-2", className),
8605
8726
  ...rest,
8606
8727
  children: [
8607
8728
  children,
8608
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: label })
8729
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: resolved_label })
8609
8730
  ]
8610
8731
  }
8611
8732
  );
@@ -8640,7 +8761,6 @@ function EmptyState({
8640
8761
  }
8641
8762
  );
8642
8763
  }
8643
- var t11 = i18n.createPackageT("hazo_ui", en_default);
8644
8764
  function ErrorBanner({
8645
8765
  severity = "error",
8646
8766
  title,
@@ -8650,6 +8770,7 @@ function ErrorBanner({
8650
8770
  onDismiss,
8651
8771
  className
8652
8772
  }) {
8773
+ const t = useHazoUiT();
8653
8774
  const palette = severity === "warning" ? "border-amber-300 bg-amber-50 text-amber-900 dark:border-amber-700 dark:bg-amber-950 dark:text-amber-100" : "border-destructive/40 bg-destructive/10 text-destructive-foreground";
8654
8775
  const iconColor = severity === "warning" ? "text-amber-600" : "text-destructive";
8655
8776
  const resolvedIcon = icon ?? (severity === "warning" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: cn("h-5 w-5", iconColor), "aria-hidden": "true" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.OctagonAlert, { className: cn("h-5 w-5", iconColor), "aria-hidden": "true" }));
@@ -8675,7 +8796,7 @@ function ErrorBanner({
8675
8796
  {
8676
8797
  type: "button",
8677
8798
  onClick: onDismiss,
8678
- "aria-label": t11("error.dismiss"),
8799
+ "aria-label": t("error.dismiss"),
8679
8800
  className: "flex-shrink-0 rounded p-1 hover:bg-black/5 focus:outline-none focus:ring-2 focus:ring-offset-2 dark:hover:bg-white/5",
8680
8801
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4", "aria-hidden": "true" })
8681
8802
  }
@@ -8684,9 +8805,8 @@ function ErrorBanner({
8684
8805
  }
8685
8806
  );
8686
8807
  }
8687
- var t12 = i18n.createPackageT("hazo_ui", en_default);
8688
8808
  function ErrorPage({
8689
- title = t12("error.something_went_wrong"),
8809
+ title,
8690
8810
  description,
8691
8811
  errorCode,
8692
8812
  correlationId,
@@ -8694,6 +8814,8 @@ function ErrorPage({
8694
8814
  illustration,
8695
8815
  className
8696
8816
  }) {
8817
+ const t = useHazoUiT();
8818
+ const resolved_title = title ?? t("error.something_went_wrong");
8697
8819
  return /* @__PURE__ */ jsxRuntime.jsxs(
8698
8820
  "div",
8699
8821
  {
@@ -8706,10 +8828,10 @@ function ErrorPage({
8706
8828
  children: [
8707
8829
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-destructive", children: illustration ?? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.OctagonAlert, { className: "h-16 w-16", "aria-hidden": "true" }) }),
8708
8830
  errorCode ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-full bg-muted px-3 py-1 text-xs font-mono uppercase tracking-wider text-muted-foreground", children: errorCode }) : null,
8709
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-semibold text-foreground", children: title }),
8831
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-semibold text-foreground", children: resolved_title }),
8710
8832
  description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground", children: description }) : null,
8711
8833
  correlationId ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full rounded-md border bg-muted/40 px-3 py-2 text-left", children: [
8712
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] uppercase tracking-wider text-muted-foreground", children: "Correlation ID" }),
8834
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] uppercase tracking-wider text-muted-foreground", children: t("error.correlation_id") }),
8713
8835
  /* @__PURE__ */ jsxRuntime.jsx("code", { className: "break-all text-xs", children: correlationId })
8714
8836
  ] }) : null,
8715
8837
  actions ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 flex flex-wrap items-center justify-center gap-2", children: actions }) : null
@@ -8717,16 +8839,17 @@ function ErrorPage({
8717
8839
  }
8718
8840
  );
8719
8841
  }
8720
- var t13 = i18n.createPackageT("hazo_ui", en_default);
8721
8842
  function LoadingTimeout({
8722
8843
  active,
8723
8844
  children,
8724
8845
  skeleton,
8725
8846
  onRetry,
8726
8847
  thresholds,
8727
- label = "content",
8848
+ label,
8728
8849
  className
8729
8850
  }) {
8851
+ const t = useHazoUiT();
8852
+ const resolved_label = label ?? t("loading.default_label");
8730
8853
  const timeouts = {
8731
8854
  gentle: thresholds?.gentle ?? 5e3,
8732
8855
  firm: thresholds?.firm ?? 15e3,
@@ -8756,15 +8879,15 @@ function LoadingTimeout({
8756
8879
  ErrorBanner,
8757
8880
  {
8758
8881
  severity: "error",
8759
- title: t13("loading.taking_longer"),
8760
- message: `We're still trying to load the ${label}. The connection may be slow.`,
8882
+ title: t("loading.taking_longer"),
8883
+ message: t("loading.still_loading", { label: resolved_label }),
8761
8884
  action: onRetry ? /* @__PURE__ */ jsxRuntime.jsx(
8762
8885
  "button",
8763
8886
  {
8764
8887
  type: "button",
8765
8888
  onClick: onRetry,
8766
8889
  className: "rounded bg-foreground/10 px-3 py-1.5 text-sm font-medium hover:bg-foreground/15",
8767
- children: "Try again"
8890
+ children: t("loading.try_again")
8768
8891
  }
8769
8892
  ) : null
8770
8893
  }
@@ -8772,12 +8895,8 @@ function LoadingTimeout({
8772
8895
  }
8773
8896
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, role: "status", "aria-busy": "true", "aria-live": "polite", children: [
8774
8897
  skeleton,
8775
- phase === "gentle" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 text-center text-sm text-muted-foreground", children: [
8776
- "Loading ",
8777
- label,
8778
- "\u2026"
8779
- ] }) : null,
8780
- phase === "firm" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 text-center text-sm text-muted-foreground", children: "Still working on it \u2014 almost there." }) : null
8898
+ phase === "gentle" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 text-center text-sm text-muted-foreground", children: t("loading.gentle_message", { label: resolved_label }) }) : null,
8899
+ phase === "firm" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 text-center text-sm text-muted-foreground", children: t("loading.firm_message") }) : null
8781
8900
  ] });
8782
8901
  }
8783
8902
  function ProgressiveImage({
@@ -8838,13 +8957,14 @@ function NotificationCountBadge({
8838
8957
  max = 9,
8839
8958
  className
8840
8959
  }) {
8960
+ const t = useHazoUiT();
8841
8961
  if (count <= 0) return null;
8842
8962
  const isOverflow = count > max;
8843
8963
  const label = isOverflow ? `${max}+` : String(count);
8844
8964
  return /* @__PURE__ */ jsxRuntime.jsx(
8845
8965
  "span",
8846
8966
  {
8847
- "aria-label": `${count} unread`,
8967
+ "aria-label": t("notification.unread_count", { count }),
8848
8968
  className: cn(
8849
8969
  "cls_notification_count_badge",
8850
8970
  "inline-flex items-center justify-center",
@@ -8858,7 +8978,6 @@ function NotificationCountBadge({
8858
8978
  }
8859
8979
  );
8860
8980
  }
8861
- var t14 = i18n.createPackageT("hazo_ui", en_default);
8862
8981
  function NotificationItem({
8863
8982
  isRead,
8864
8983
  timestamp,
@@ -8869,6 +8988,7 @@ function NotificationItem({
8869
8988
  onMarkRead,
8870
8989
  markReadLabel
8871
8990
  }) {
8991
+ const t = useHazoUiT();
8872
8992
  const handleMarkRead = (e) => {
8873
8993
  e.stopPropagation();
8874
8994
  onMarkRead?.();
@@ -8889,7 +9009,7 @@ function NotificationItem({
8889
9009
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_notification_item_dot_col flex-shrink-0 pt-1.5", children: !isRead ? /* @__PURE__ */ jsxRuntime.jsx(
8890
9010
  "span",
8891
9011
  {
8892
- "aria-label": t14("notification.unread"),
9012
+ "aria-label": t("notification.unread"),
8893
9013
  className: "cls_notification_item_dot block w-2 h-2 rounded-full bg-primary"
8894
9014
  }
8895
9015
  ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block w-2 h-2", "aria-hidden": "true" }) }),
@@ -8913,13 +9033,13 @@ function NotificationItem({
8913
9033
  }
8914
9034
  );
8915
9035
  }
8916
- var t15 = i18n.createPackageT("hazo_ui", en_default);
8917
9036
  function LoadingSkeletons() {
9037
+ const t = useHazoUiT();
8918
9038
  return /* @__PURE__ */ jsxRuntime.jsx(
8919
9039
  "div",
8920
9040
  {
8921
9041
  "aria-busy": "true",
8922
- "aria-label": t15("notification.loading"),
9042
+ "aria-label": t("notification.loading"),
8923
9043
  className: "cls_notification_panel_loading space-y-0",
8924
9044
  children: [0, 1, 2].map((i) => /* @__PURE__ */ jsxRuntime.jsxs(
8925
9045
  "div",
@@ -8978,7 +9098,6 @@ function NotificationPanel({
8978
9098
  }
8979
9099
  );
8980
9100
  }
8981
- var t16 = i18n.createPackageT("hazo_ui", en_default);
8982
9101
  function HazoUiToaster({
8983
9102
  position = "bottom-right",
8984
9103
  closeButton = true,
@@ -9022,14 +9141,17 @@ function permissionToast({
9022
9141
  missingPermissions,
9023
9142
  descriptions,
9024
9143
  action,
9025
- duration = 5e3
9144
+ duration = 5e3,
9145
+ t = defaultHazoUiT
9026
9146
  }) {
9027
- const description = missingPermissions.length === 0 ? t16("toast.permission_denied_message") : `Missing: ${missingPermissions.map((key) => {
9028
- const label = descriptions?.[key];
9029
- return label ? `\`${key}\` \u2014 ${label}` : `\`${key}\``;
9030
- }).join("; ")}`;
9147
+ const description = missingPermissions.length === 0 ? t("toast.permission_denied_message") : t("toast.missing_prefix", {
9148
+ items: missingPermissions.map((key) => {
9149
+ const label = descriptions?.[key];
9150
+ return label ? `\`${key}\` \u2014 ${label}` : `\`${key}\``;
9151
+ }).join("; ")
9152
+ });
9031
9153
  return errorToast({
9032
- title: t16("toast.permission_required"),
9154
+ title: t("toast.permission_required"),
9033
9155
  description,
9034
9156
  action,
9035
9157
  duration
@@ -9295,6 +9417,7 @@ function KanbanCard({
9295
9417
  showEdit = false,
9296
9418
  onEditRequest
9297
9419
  }) {
9420
+ const t = useHazoUiT();
9298
9421
  const {
9299
9422
  attributes,
9300
9423
  listeners,
@@ -9348,7 +9471,7 @@ function KanbanCard({
9348
9471
  ...listeners,
9349
9472
  role: "button",
9350
9473
  tabIndex: 0,
9351
- "aria-roledescription": "draggable card",
9474
+ "aria-roledescription": t("kanban.draggable_card"),
9352
9475
  "aria-grabbed": isDragging,
9353
9476
  onDoubleClick: () => {
9354
9477
  if (showEdit && onEditRequest && !dragging) onEditRequest(item);
@@ -9365,7 +9488,7 @@ function KanbanCard({
9365
9488
  e.stopPropagation();
9366
9489
  onEditRequest(item);
9367
9490
  },
9368
- "aria-label": `Edit ${item.id}`,
9491
+ "aria-label": t("kanban.edit_fallback", { id: item.id }),
9369
9492
  className: cn(
9370
9493
  "cls_hazo_kanban_card_edit absolute top-1.5 right-1.5",
9371
9494
  "p-1 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent",
@@ -9673,12 +9796,11 @@ function KanbanLaneStrip({
9673
9796
  }
9674
9797
  );
9675
9798
  }
9676
- var t17 = i18n.createPackageT("hazo_ui", en_default);
9677
9799
  var DEFAULT_PRIORITIES = ["P0", "P1", "P2", "P3"];
9678
9800
  function humanize(key) {
9679
9801
  return key.replace(/[_\-]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\s+/g, " ").trim().split(" ").map((w) => w ? w[0].toUpperCase() + w.slice(1) : w).join(" ");
9680
9802
  }
9681
- function auto_detect_fields(item, columns) {
9803
+ function auto_detect_fields(item, columns, t) {
9682
9804
  const skip = /* @__PURE__ */ new Set(["id", "columnKey", "priority"]);
9683
9805
  const out = [];
9684
9806
  for (const [key, value] of Object.entries(item)) {
@@ -9688,7 +9810,7 @@ function auto_detect_fields(item, columns) {
9688
9810
  }
9689
9811
  }
9690
9812
  if (columns.length > 0) {
9691
- out.push({ key: "columnKey", type: "status", label: t17("kanban.status_label") });
9813
+ out.push({ key: "columnKey", type: "status", label: t("kanban.status_label") });
9692
9814
  }
9693
9815
  return out;
9694
9816
  }
@@ -9703,6 +9825,7 @@ function KanbanEditor({
9703
9825
  onSave,
9704
9826
  onClose
9705
9827
  }) {
9828
+ const t = useHazoUiT();
9706
9829
  const [draft, set_draft] = React27__namespace.useState(item);
9707
9830
  const [saving, set_saving] = React27__namespace.useState(false);
9708
9831
  const [error, set_error] = React27__namespace.useState(null);
@@ -9717,7 +9840,7 @@ function KanbanEditor({
9717
9840
  const resolved_fields = React27__namespace.useMemo(() => {
9718
9841
  if (fields) return fields;
9719
9842
  if (!item) return [];
9720
- return auto_detect_fields(item, resolved_columns);
9843
+ return auto_detect_fields(item, resolved_columns, t);
9721
9844
  }, [fields, item, resolved_columns]);
9722
9845
  const required_keys = React27__namespace.useMemo(
9723
9846
  () => resolved_fields.filter(
@@ -9785,7 +9908,7 @@ function KanbanEditor({
9785
9908
  isDirty: is_dirty
9786
9909
  };
9787
9910
  const open = item !== null;
9788
- const title = item && titleFn ? titleFn(item) : item ? t17("kanban.edit_fallback", { id: item.id }) : "";
9911
+ const title = item && titleFn ? titleFn(item) : item ? t("kanban.edit_fallback", { id: item.id }) : "";
9789
9912
  const priority_var = item?.priority ? `--hazo-kanban-priority-${String(item.priority).toLowerCase()}` : null;
9790
9913
  const header_bar_color = priority_var ? `hsl(var(${priority_var}))` : void 0;
9791
9914
  const use_default_footer = !(renderBody && hideFooter);
@@ -9797,18 +9920,18 @@ function KanbanEditor({
9797
9920
  if (!o && !saving) onClose();
9798
9921
  },
9799
9922
  title,
9800
- description: t17("kanban.update_description"),
9923
+ description: t("kanban.update_description"),
9801
9924
  sizeWidth: "min(90vw, 480px)",
9802
9925
  openAnimation: "none",
9803
9926
  closeAnimation: "none",
9804
9927
  headerBar: !!priority_var,
9805
9928
  headerBarColor: header_bar_color,
9806
9929
  contentClassName: cn("cls_hazo_kanban_editor", priority_var && "pt-0"),
9807
- actionButtonText: saving ? t17("kanban.saving") : t17("kanban.save"),
9930
+ actionButtonText: saving ? t("kanban.saving") : t("kanban.save"),
9808
9931
  actionButtonIcon: saving ? void 0 : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4 mr-2" }),
9809
9932
  actionButtonLoading: saving,
9810
9933
  actionButtonDisabled: !is_dirty || !all_required_filled || saving,
9811
- cancelButtonText: t17("kanban.cancel"),
9934
+ cancelButtonText: t("kanban.cancel"),
9812
9935
  showCancelButton: true,
9813
9936
  onConfirm: handle_save,
9814
9937
  onCancel: onClose,
@@ -9846,6 +9969,7 @@ function KanbanEditorFieldRow({
9846
9969
  priorities,
9847
9970
  columns
9848
9971
  }) {
9972
+ const t = useHazoUiT();
9849
9973
  const id = `kanban-editor-${field.key}`;
9850
9974
  const label = field.label ?? humanize(field.key);
9851
9975
  const value = draft[field.key];
@@ -9913,7 +10037,7 @@ function KanbanEditorFieldRow({
9913
10037
  /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { id, children: /* @__PURE__ */ jsxRuntime.jsx(
9914
10038
  SelectValue,
9915
10039
  {
9916
- placeholder: field.placeholder ?? t17("kanban.select_placeholder", { label })
10040
+ placeholder: field.placeholder ?? t("kanban.select_placeholder", { label })
9917
10041
  }
9918
10042
  ) }),
9919
10043
  /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: (field.options ?? []).map((opt) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: opt, children: opt }, opt)) })
@@ -9929,7 +10053,7 @@ function KanbanEditorFieldRow({
9929
10053
  /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { id, children: /* @__PURE__ */ jsxRuntime.jsx(
9930
10054
  SelectValue,
9931
10055
  {
9932
- placeholder: field.placeholder ?? t17("kanban.select_priority")
10056
+ placeholder: field.placeholder ?? t("kanban.select_priority")
9933
10057
  }
9934
10058
  ) }),
9935
10059
  /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: priorities.map((p) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: p, children: p }, p)) })
@@ -9945,7 +10069,7 @@ function KanbanEditorFieldRow({
9945
10069
  /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { id, children: /* @__PURE__ */ jsxRuntime.jsx(
9946
10070
  SelectValue,
9947
10071
  {
9948
- placeholder: field.placeholder ?? t17("kanban.select_status")
10072
+ placeholder: field.placeholder ?? t("kanban.select_status")
9949
10073
  }
9950
10074
  ) }),
9951
10075
  /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: col.key, children: col.title }, col.key)) })
@@ -9961,7 +10085,7 @@ var EMPTY_FILTER = {
9961
10085
  };
9962
10086
  function HazoUiKanbanFilter({
9963
10087
  search = true,
9964
- searchPlaceholder = "Search...",
10088
+ searchPlaceholder,
9965
10089
  categories,
9966
10090
  priorities,
9967
10091
  value,
@@ -9969,6 +10093,8 @@ function HazoUiKanbanFilter({
9969
10093
  onChange,
9970
10094
  className
9971
10095
  }) {
10096
+ const t = useHazoUiT();
10097
+ const resolved_search_placeholder = searchPlaceholder ?? t("common.search");
9972
10098
  const is_controlled = value !== void 0;
9973
10099
  const [internal, set_internal] = React27__namespace.useState(
9974
10100
  defaultValue ?? EMPTY_FILTER
@@ -9995,7 +10121,7 @@ function HazoUiKanbanFilter({
9995
10121
  {
9996
10122
  value: current.search,
9997
10123
  onChange: (e) => update({ ...current, search: e.target.value }),
9998
- placeholder: searchPlaceholder,
10124
+ placeholder: resolved_search_placeholder,
9999
10125
  className: "cls_hazo_kanban_filter_search w-full sm:w-64"
10000
10126
  }
10001
10127
  ),
@@ -10049,7 +10175,7 @@ function HazoUiKanbanFilter({
10049
10175
  className: "cls_hazo_kanban_filter_clear",
10050
10176
  children: [
10051
10177
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4 mr-1" }),
10052
- "Clear"
10178
+ t("kanban.clear")
10053
10179
  ]
10054
10180
  }
10055
10181
  )
@@ -10084,12 +10210,20 @@ var UNMATCHED_LANE_KEY = "__hazo_lane_unmatched__";
10084
10210
  function bucket_key(lane_key, column_key) {
10085
10211
  return lane_key == null ? column_key : `${lane_key}\0${column_key}`;
10086
10212
  }
10087
- function default_announcements(itemLabel) {
10213
+ function default_announcements(itemLabel, t) {
10088
10214
  return {
10089
- onDragStart: ({ item, fromColumn }) => `Picked up ${itemLabel(item)}. Currently in ${fromColumn}. Use arrow keys to choose a different column. Press space to drop, escape to cancel.`,
10090
- onDragOver: ({ item, overColumn }) => overColumn ? `${itemLabel(item)} over ${overColumn}.` : "",
10091
- onDragEnd: ({ item, fromColumn, toColumn, newIndex }) => fromColumn === toColumn ? `${itemLabel(item)} reordered to position ${newIndex + 1} in ${toColumn}.` : `${itemLabel(item)} dropped in ${toColumn}, position ${newIndex + 1}.`,
10092
- onDragCancel: ({ item, fromColumn }) => `Movement cancelled. ${itemLabel(item)} returned to ${fromColumn}.`
10215
+ onDragStart: ({ item, fromColumn }) => t("kanban.dnd_pickup", { item: itemLabel(item), column: fromColumn }),
10216
+ onDragOver: ({ item, overColumn }) => overColumn ? t("kanban.dnd_over", { item: itemLabel(item), column: overColumn }) : "",
10217
+ onDragEnd: ({ item, fromColumn, toColumn, newIndex }) => fromColumn === toColumn ? t("kanban.dnd_reorder", {
10218
+ item: itemLabel(item),
10219
+ pos: newIndex + 1,
10220
+ column: toColumn
10221
+ }) : t("kanban.dnd_drop", {
10222
+ item: itemLabel(item),
10223
+ column: toColumn,
10224
+ pos: newIndex + 1
10225
+ }),
10226
+ onDragCancel: ({ item, fromColumn }) => t("kanban.dnd_cancel", { item: itemLabel(item), column: fromColumn })
10093
10227
  };
10094
10228
  }
10095
10229
  function group_items_by_column(items, overlay, columns, lanes) {
@@ -10156,6 +10290,7 @@ function HazoUiKanban({
10156
10290
  onCardSave,
10157
10291
  disableEdit = false
10158
10292
  }) {
10293
+ const t = useHazoUiT();
10159
10294
  const label_fn = React27__namespace.useCallback(
10160
10295
  (item) => itemLabel ? itemLabel(item) : item.id,
10161
10296
  [itemLabel]
@@ -10213,7 +10348,7 @@ function HazoUiKanban({
10213
10348
  return core$1.closestCorners(args);
10214
10349
  }, []);
10215
10350
  const merged_announcements = React27__namespace.useMemo(() => {
10216
- const defaults = default_announcements(label_fn);
10351
+ const defaults = default_announcements(label_fn, t);
10217
10352
  return {
10218
10353
  onDragStart: announcements?.onDragStart ?? defaults.onDragStart,
10219
10354
  onDragOver: announcements?.onDragOver ?? defaults.onDragOver,
@@ -10893,8 +11028,8 @@ function serializeFilter(filter) {
10893
11028
  const fields = (filter.fields ?? []).map((f) => `${f.field}:${f.operator ?? ""}:${String(f.value)}`).join(",");
10894
11029
  return `${filter.search ?? ""}|${fields}`;
10895
11030
  }
10896
- var t18 = i18n.createPackageT("hazo_ui", en_default);
10897
11031
  function HazoUiTable(props) {
11032
+ const t = useHazoUiT();
10898
11033
  const state = useTableState(props);
10899
11034
  const { columns, rows, getRowKey, className, caption } = props;
10900
11035
  const mobileBreakpoint = props.mobileBreakpoint ?? 768;
@@ -10925,15 +11060,15 @@ function HazoUiTable(props) {
10925
11060
  /* @__PURE__ */ jsxRuntime.jsx(SkeletonBar, { className: "w-1/2" })
10926
11061
  ] })
10927
11062
  ] }, `mloader-${i}`)
10928
- ) }) : state.serverError != null ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_hazo_ui_table_mobile_error py-6", children: renderErrorState(props.error, state.serverError) }) : state.displayed.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_hazo_ui_table_mobile_empty py-6", children: noActiveFilters(state.filter) && rows.length === 0 ? typeof props.empty === "string" || props.empty === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
11063
+ ) }) : state.serverError != null ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_hazo_ui_table_mobile_error py-6", children: renderErrorState(props.error, state.serverError, t) }) : state.displayed.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_hazo_ui_table_mobile_empty py-6", children: noActiveFilters(state.filter) && rows.length === 0 ? typeof props.empty === "string" || props.empty === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
10929
11064
  EmptyState,
10930
11065
  {
10931
- title: typeof props.empty === "string" && props.empty || t18("table.empty")
11066
+ title: typeof props.empty === "string" && props.empty || t("table.empty")
10932
11067
  }
10933
11068
  ) : props.empty : typeof props.noResults === "string" || props.noResults === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
10934
11069
  EmptyState,
10935
11070
  {
10936
- title: typeof props.noResults === "string" && props.noResults || t18("table.no_results")
11071
+ title: typeof props.noResults === "string" && props.noResults || t("table.no_results")
10937
11072
  }
10938
11073
  ) : props.noResults }) : /* @__PURE__ */ jsxRuntime.jsx(
10939
11074
  TableMobileCards,
@@ -10956,7 +11091,7 @@ function HazoUiTable(props) {
10956
11091
  {
10957
11092
  type: "button",
10958
11093
  onClick: (e) => state.cycleHeaderSort(c.key, e.shiftKey),
10959
- title: t18("table.sort_tooltip"),
11094
+ title: t("table.sort_tooltip"),
10960
11095
  className: "cls_hazo_ui_table_sort_btn inline-flex items-center gap-1 hover:text-foreground",
10961
11096
  children: [
10962
11097
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: c.label }),
@@ -10978,7 +11113,7 @@ function HazoUiTable(props) {
10978
11113
  {
10979
11114
  colSpan: columns.length,
10980
11115
  className: "cls_hazo_ui_table_error_cell p-0",
10981
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_hazo_ui_table_error_wrap py-6", children: renderErrorState(props.error, state.serverError) })
11116
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_hazo_ui_table_error_wrap py-6", children: renderErrorState(props.error, state.serverError, t) })
10982
11117
  }
10983
11118
  ) }) : state.displayed.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(TableRow2, { children: /* @__PURE__ */ jsxRuntime.jsx(
10984
11119
  TableCell2,
@@ -10988,12 +11123,12 @@ function HazoUiTable(props) {
10988
11123
  children: noActiveFilters(state.filter) && rows.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_hazo_ui_table_empty_wrap py-6", children: typeof props.empty === "string" || props.empty === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
10989
11124
  EmptyState,
10990
11125
  {
10991
- title: typeof props.empty === "string" && props.empty || t18("table.empty")
11126
+ title: typeof props.empty === "string" && props.empty || t("table.empty")
10992
11127
  }
10993
11128
  ) : props.empty }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_hazo_ui_table_no_results_wrap py-6", children: typeof props.noResults === "string" || props.noResults === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
10994
11129
  EmptyState,
10995
11130
  {
10996
- title: typeof props.noResults === "string" && props.noResults || t18("table.no_results")
11131
+ title: typeof props.noResults === "string" && props.noResults || t("table.no_results")
10997
11132
  }
10998
11133
  ) : props.noResults })
10999
11134
  }
@@ -11103,11 +11238,12 @@ function PaginationFooter({
11103
11238
  total,
11104
11239
  onPageChange
11105
11240
  }) {
11241
+ const t = useHazoUiT();
11106
11242
  const start = total === 0 ? 0 : page * pageSize + 1;
11107
11243
  const end = Math.min((page + 1) * pageSize, total);
11108
11244
  const lastPage = Math.max(0, Math.ceil(total / pageSize) - 1);
11109
11245
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_hazo_ui_table_pagination flex items-center justify-between gap-3 pt-2 text-sm", children: [
11110
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cls_hazo_ui_table_page_counter text-muted-foreground", children: t18("table.showing", {
11246
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cls_hazo_ui_table_page_counter text-muted-foreground", children: t("table.showing", {
11111
11247
  start: String(start),
11112
11248
  end: String(end),
11113
11249
  total: String(total)
@@ -11120,8 +11256,8 @@ function PaginationFooter({
11120
11256
  size: "sm",
11121
11257
  onClick: () => onPageChange(Math.max(0, page - 1)),
11122
11258
  disabled: page === 0,
11123
- "aria-label": t18("table.prev_aria"),
11124
- children: t18("table.prev")
11259
+ "aria-label": t("table.prev_aria"),
11260
+ children: t("table.prev")
11125
11261
  }
11126
11262
  ),
11127
11263
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -11131,14 +11267,15 @@ function PaginationFooter({
11131
11267
  size: "sm",
11132
11268
  onClick: () => onPageChange(Math.min(lastPage, page + 1)),
11133
11269
  disabled: page >= lastPage,
11134
- "aria-label": t18("table.next_aria"),
11135
- children: t18("table.next")
11270
+ "aria-label": t("table.next_aria"),
11271
+ children: t("table.next")
11136
11272
  }
11137
11273
  )
11138
11274
  ] })
11139
11275
  ] });
11140
11276
  }
11141
11277
  function Toolbar2(props) {
11278
+ const t = useHazoUiT();
11142
11279
  const {
11143
11280
  columns,
11144
11281
  sort,
@@ -11176,7 +11313,7 @@ function Toolbar2(props) {
11176
11313
  setSearchValue(v);
11177
11314
  onSearchChange(v);
11178
11315
  },
11179
- placeholder: searchPlaceholder ?? t18("table.search_placeholder"),
11316
+ placeholder: searchPlaceholder ?? t("table.search_placeholder"),
11180
11317
  className: "cls_hazo_ui_table_search w-full sm:max-w-xs"
11181
11318
  }
11182
11319
  ) : /* @__PURE__ */ jsxRuntime.jsx("div", {}),
@@ -11217,15 +11354,15 @@ function LoadingRows({
11217
11354
  function noActiveFilters(filter) {
11218
11355
  return !filter.search && (!filter.fields || filter.fields.length === 0);
11219
11356
  }
11220
- function renderErrorState(error, serverError) {
11357
+ function renderErrorState(error, serverError, t) {
11221
11358
  if (typeof error === "function") return error(serverError);
11222
11359
  if (error !== void 0 && error !== null) return error;
11223
11360
  const msg = serverError instanceof Error ? serverError.message : String(serverError);
11224
11361
  return /* @__PURE__ */ jsxRuntime.jsx(
11225
11362
  EmptyState,
11226
11363
  {
11227
- title: t18("table.error_title"),
11228
- description: msg || t18("table.error_description")
11364
+ title: t("table.error_title"),
11365
+ description: msg || t("table.error_description")
11229
11366
  }
11230
11367
  );
11231
11368
  }
@@ -11461,7 +11598,6 @@ function StackedBars({
11461
11598
  }
11462
11599
  );
11463
11600
  }
11464
- var t19 = i18n.createPackageT("hazo_ui", en_default);
11465
11601
  function DateRangeSelector({
11466
11602
  value,
11467
11603
  onChange,
@@ -11469,7 +11605,8 @@ function DateRangeSelector({
11469
11605
  className,
11470
11606
  ariaLabel
11471
11607
  }) {
11472
- const resolved_aria = ariaLabel ?? t19("charts.date_range");
11608
+ const t = useHazoUiT();
11609
+ const resolved_aria = ariaLabel ?? t("charts.date_range");
11473
11610
  return /* @__PURE__ */ jsxRuntime.jsx(
11474
11611
  "div",
11475
11612
  {
@@ -11525,6 +11662,7 @@ function FunnelChart({
11525
11662
  showTooltip = true,
11526
11663
  className
11527
11664
  }) {
11665
+ const t = useHazoUiT();
11528
11666
  const [hover_idx, set_hover_idx] = React27__namespace.useState(null);
11529
11667
  const fmt = valueFormat ?? format_num;
11530
11668
  const totals = steps.map(step_total);
@@ -11651,12 +11789,12 @@ function FunnelChart({
11651
11789
  const bubble_anchor_y = bar_y + BAR_H / 2;
11652
11790
  const lines = [
11653
11791
  { text: step.label, accent: true },
11654
- { text: `Total: ${fmt(total)}`, accent: false },
11655
- { text: `% of first: ${pct_first}%`, accent: false }
11792
+ { text: t("charts.total", { value: fmt(total) }), accent: false },
11793
+ { text: t("charts.pct_of_first", { pct: pct_first }), accent: false }
11656
11794
  ];
11657
11795
  if (i > 0) {
11658
- lines.push({ text: `% of prev: ${pct_prev}%`, accent: false });
11659
- lines.push({ text: `Drop-off: \u2212${fmt(dropoff)}`, accent: false });
11796
+ lines.push({ text: t("charts.pct_of_prev", { pct: pct_prev }), accent: false });
11797
+ lines.push({ text: t("charts.dropoff", { value: fmt(dropoff) }), accent: false });
11660
11798
  }
11661
11799
  if (step.segments) {
11662
11800
  step.segments.forEach((seg) => {
@@ -11717,7 +11855,6 @@ function FunnelChart({
11717
11855
 
11718
11856
  // src/assets/celebration-chime.mp3
11719
11857
  var celebration_chime_default = "data:text/plain;charset=utf-8,";
11720
- var t20 = i18n.createPackageT("hazo_ui", en_default);
11721
11858
  var CELEBRATION_GRADIENT = "linear-gradient(135deg, #667eea 0%, #764ba2 100%)";
11722
11859
  var CARD_SIZE = 1080;
11723
11860
  var PREVIEW_SIZE = 400;
@@ -11769,6 +11906,7 @@ function CelebrationModalInner({
11769
11906
  payload,
11770
11907
  onClose
11771
11908
  }) {
11909
+ const t = useHazoUiT();
11772
11910
  const {
11773
11911
  id,
11774
11912
  title,
@@ -11915,7 +12053,7 @@ function CelebrationModalInner({
11915
12053
  {
11916
12054
  className: "cls_celebration_close_btn absolute top-3 right-3 z-10 p-1.5 rounded-full hover:bg-black/10 transition-colors",
11917
12055
  onClick: close_modal,
11918
- "aria-label": t20("celebration.close"),
12056
+ "aria-label": t("celebration.close"),
11919
12057
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4 text-gray-600" })
11920
12058
  }
11921
12059
  ),
@@ -11978,21 +12116,21 @@ function CelebrationModalInner({
11978
12116
  disabled: is_downloading,
11979
12117
  children: [
11980
12118
  is_downloading ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-3.5 w-3.5 mr-1.5 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { className: "h-3.5 w-3.5 mr-1.5" }),
11981
- t20("celebration.download_png")
12119
+ t("celebration.download_png")
11982
12120
  ]
11983
12121
  }
11984
12122
  ),
11985
12123
  can_share && /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "outline", size: "sm", onClick: handle_share, children: [
11986
12124
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Share2, { className: "h-3.5 w-3.5 mr-1.5" }),
11987
- t20("celebration.share")
12125
+ t("celebration.share")
11988
12126
  ] }),
11989
12127
  /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "outline", size: "sm", onClick: handle_copy, children: [
11990
12128
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "h-3.5 w-3.5 mr-1.5" }),
11991
- t20("celebration.copy_image")
12129
+ t("celebration.copy_image")
11992
12130
  ] })
11993
12131
  ] })
11994
12132
  ] }),
11995
- !shareableCard && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_celebration_footer pb-8", children: /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", onClick: close_modal, children: t20("celebration.dismiss") }) })
12133
+ !shareableCard && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_celebration_footer pb-8", children: /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", onClick: close_modal, children: t("celebration.dismiss") }) })
11996
12134
  ]
11997
12135
  }
11998
12136
  )
@@ -12014,8 +12152,8 @@ function computeEta(durationWindow, unitCount, concurrency = 1, fallbackUnitMs =
12014
12152
  }
12015
12153
  function easeToward(elapsed, eta, maxCap = 0.95) {
12016
12154
  if (eta <= 0 || elapsed <= 0) return 0;
12017
- const t22 = elapsed / eta;
12018
- return maxCap * (1 - Math.exp(-1.5 * t22));
12155
+ const t = elapsed / eta;
12156
+ return maxCap * (1 - Math.exp(-1.5 * t));
12019
12157
  }
12020
12158
  function HazoUiProgressBar({
12021
12159
  value,
@@ -12191,7 +12329,6 @@ function upsertEntry(entries, entry) {
12191
12329
  function removeEntry(entries, id) {
12192
12330
  return entries.filter((e) => e.id !== id);
12193
12331
  }
12194
- var t21 = i18n.createPackageT("hazo_ui", en_default);
12195
12332
  function HazoUiMemoryDropdown({
12196
12333
  history_key,
12197
12334
  placeholder,
@@ -12199,8 +12336,9 @@ function HazoUiMemoryDropdown({
12199
12336
  add_entry,
12200
12337
  empty_label
12201
12338
  }) {
12202
- const resolved_placeholder = placeholder ?? t21("memory.search_placeholder");
12203
- const resolved_empty_label = empty_label ?? t21("memory.no_history");
12339
+ const t = useHazoUiT();
12340
+ const resolved_placeholder = placeholder ?? t("memory.search_placeholder");
12341
+ const resolved_empty_label = empty_label ?? t("memory.no_history");
12204
12342
  const { value: stored, setValue } = client$2.useHazoState(history_key, {
12205
12343
  level: "scope",
12206
12344
  fallback: []
@@ -12286,6 +12424,7 @@ function HazoUiMemoryDropdown({
12286
12424
  );
12287
12425
  }
12288
12426
  function EntryRow({ entry, on_select, onDelete }) {
12427
+ const t = useHazoUiT();
12289
12428
  const [deleteHovered, setDeleteHovered] = React27__namespace.useState(false);
12290
12429
  const [rowHovered, setRowHovered] = React27__namespace.useState(false);
12291
12430
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -12325,7 +12464,7 @@ function EntryRow({ entry, on_select, onDelete }) {
12325
12464
  onClick: (e) => onDelete(entry.id, e),
12326
12465
  onMouseEnter: () => setDeleteHovered(true),
12327
12466
  onMouseLeave: () => setDeleteHovered(false),
12328
- "aria-label": t21("memory.remove_aria", { label: entry.label }),
12467
+ "aria-label": t("memory.remove_aria", { label: entry.label }),
12329
12468
  style: {
12330
12469
  flexShrink: 0,
12331
12470
  background: "none",
@@ -12353,7 +12492,8 @@ function Logo({
12353
12492
  className,
12354
12493
  imgClassName
12355
12494
  }) {
12356
- const alt = appTitle ?? "Logo";
12495
+ const t = useHazoUiT();
12496
+ const alt = appTitle ?? t("app_logo.alt_fallback");
12357
12497
  let content = null;
12358
12498
  if (logoUrl) {
12359
12499
  content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -12389,10 +12529,11 @@ function Logo({
12389
12529
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("inline-flex items-center gap-2", className), children: content });
12390
12530
  }
12391
12531
  function AppHeader({ identity, homeHref, navItems, actions, className }) {
12532
+ const t = useHazoUiT();
12392
12533
  return /* @__PURE__ */ jsxRuntime.jsxs(
12393
12534
  "header",
12394
12535
  {
12395
- "aria-label": "Application header",
12536
+ "aria-label": t("app_header.aria_label"),
12396
12537
  className: cn(
12397
12538
  "flex w-full items-center justify-between gap-4 border-b bg-navbar text-navbar-fg border-navbar-border px-4 py-2.5",
12398
12539
  className
@@ -12845,6 +12986,7 @@ function HazoBrowserTab({
12845
12986
  add_menu,
12846
12987
  className
12847
12988
  }) {
12989
+ const t = useHazoUiT();
12848
12990
  const handle_close = (e, id) => {
12849
12991
  e.stopPropagation();
12850
12992
  on_close?.(id);
@@ -12884,7 +13026,7 @@ function HazoBrowserTab({
12884
13026
  "button",
12885
13027
  {
12886
13028
  type: "button",
12887
- "aria-label": `Close ${tab.label}`,
13029
+ "aria-label": t("browser_tab.close_aria", { label: tab.label }),
12888
13030
  onClick: (e) => handle_close(e, tab.id),
12889
13031
  className: "cls_hazo_browser_tab_close flex-shrink-0 rounded p-0.5 text-muted-foreground opacity-0 group-hover:opacity-100 hover:bg-muted hover:text-foreground focus:opacity-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary",
12890
13032
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3 w-3" })
@@ -12971,9 +13113,11 @@ function LocalePicker({
12971
13113
  flags = false,
12972
13114
  alternates,
12973
13115
  activeLocale,
12974
- triggerLabel = "Change language",
13116
+ triggerLabel,
12975
13117
  className
12976
13118
  }) {
13119
+ const t = useHazoUiT();
13120
+ const resolved_trigger_label = triggerLabel ?? t("locale_picker.change_language");
12977
13121
  const options = React27__namespace.useMemo(() => {
12978
13122
  return Object.entries(alternates ?? {}).map(([code, url]) => {
12979
13123
  const href = safeHref(url);
@@ -12988,7 +13132,7 @@ function LocalePicker({
12988
13132
  return /* @__PURE__ */ jsxRuntime.jsx(
12989
13133
  "nav",
12990
13134
  {
12991
- "aria-label": triggerLabel,
13135
+ "aria-label": resolved_trigger_label,
12992
13136
  className: cn("cls_locale_picker_inline flex items-center gap-1", className),
12993
13137
  children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
12994
13138
  "a",
@@ -13018,7 +13162,7 @@ function LocalePicker({
13018
13162
  variant: "outline",
13019
13163
  size: "sm",
13020
13164
  lang: activeLocale,
13021
- "aria-label": triggerLabel,
13165
+ "aria-label": resolved_trigger_label,
13022
13166
  className: cn("cls_locale_picker_trigger gap-1.5", className),
13023
13167
  children: [
13024
13168
  flags && /* @__PURE__ */ jsxRuntime.jsx(FlagIcon, { code: active_option?.code ?? options[0].code }),
@@ -13156,6 +13300,7 @@ exports.HazoUiDialogTrigger = DialogTrigger;
13156
13300
  exports.HazoUiEtaProgress = HazoUiEtaProgress;
13157
13301
  exports.HazoUiFlexInput = HazoUiFlexInput;
13158
13302
  exports.HazoUiFlexRadio = HazoUiFlexRadio;
13303
+ exports.HazoUiI18nProvider = HazoUiI18nProvider;
13159
13304
  exports.HazoUiIcon = HazoUiIcon;
13160
13305
  exports.HazoUiIconPicker = HazoUiIconPicker;
13161
13306
  exports.HazoUiImageCropper = HazoUiImageCropper;
@@ -13250,6 +13395,7 @@ exports.celebrate = celebrate;
13250
13395
  exports.cn = cn;
13251
13396
  exports.computeEta = computeEta;
13252
13397
  exports.create_command_suggestion_extension = create_command_suggestion_extension;
13398
+ exports.defaultHazoUiT = defaultHazoUiT;
13253
13399
  exports.easeToward = easeToward;
13254
13400
  exports.errorToast = errorToast;
13255
13401
  exports.format_num = format_num;
@@ -13279,6 +13425,7 @@ exports.useDebounce = useDebounce;
13279
13425
  exports.useErrorDisplay = useErrorDisplay;
13280
13426
  exports.useEtaProgress = useEtaProgress;
13281
13427
  exports.useFullscreen = useFullscreen;
13428
+ exports.useHazoUiT = useHazoUiT;
13282
13429
  exports.useIsMobile = useIsMobile;
13283
13430
  exports.useLoadingState = useLoadingState;
13284
13431
  exports.useLocalStorage = useLocalStorage;