hazo_ui 6.10.0 → 6.11.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
@@ -181,8 +181,8 @@ var require_extends = __commonJS({
181
181
  function _extends11() {
182
182
  return module.exports = _extends11 = Object.assign ? Object.assign.bind() : function(n) {
183
183
  for (var e = 1; e < arguments.length; e++) {
184
- var t = arguments[e];
185
- for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
184
+ var t4 = arguments[e];
185
+ for (var r in t4) ({}).hasOwnProperty.call(t4, r) && (n[r] = t4[r]);
186
186
  }
187
187
  return n;
188
188
  }, module.exports.__esModule = true, module.exports["default"] = module.exports, _extends11.apply(null, arguments);
@@ -196,12 +196,12 @@ var require_objectWithoutPropertiesLoose = __commonJS({
196
196
  "../node_modules/@babel/runtime/helpers/objectWithoutPropertiesLoose.js"(exports, module) {
197
197
  function _objectWithoutPropertiesLoose10(r, e) {
198
198
  if (null == r) return {};
199
- var t = {};
199
+ var t4 = {};
200
200
  for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
201
201
  if (-1 !== e.indexOf(n)) continue;
202
- t[n] = r[n];
202
+ t4[n] = r[n];
203
203
  }
204
- return t;
204
+ return t4;
205
205
  }
206
206
  module.exports = _objectWithoutPropertiesLoose10, module.exports.__esModule = true, module.exports["default"] = module.exports;
207
207
  }
@@ -712,6 +712,122 @@ function Calendar({
712
712
  );
713
713
  }
714
714
  Calendar.displayName = "Calendar";
715
+ var hazo_i18n_module = null;
716
+ void client$1.optional_import("hazo_i18n").then((mod) => {
717
+ hazo_i18n_module = mod;
718
+ }).catch(() => {
719
+ hazo_i18n_module = null;
720
+ });
721
+ function interpolate(template, vars) {
722
+ if (!vars) return template;
723
+ return template.replace(
724
+ /\{\{\s*(\w+)\s*\}\}/g,
725
+ (whole, name) => Object.prototype.hasOwnProperty.call(vars, name) ? vars[name] : whole
726
+ );
727
+ }
728
+ function createPackageT(namespace, fallbackCatalog) {
729
+ return function t4(key, vars) {
730
+ const mod = hazo_i18n_module;
731
+ if (mod && typeof mod.t === "function") {
732
+ try {
733
+ const translated = mod.t(`${namespace}.${key}`, vars);
734
+ if (typeof translated === "string" && translated.length > 0) {
735
+ return translated;
736
+ }
737
+ } catch {
738
+ }
739
+ }
740
+ const template = fallbackCatalog[key];
741
+ if (template === void 0) return key;
742
+ return interpolate(template, vars);
743
+ };
744
+ }
745
+ function resolvePackageLocale(defaultLocale) {
746
+ const mod = hazo_i18n_module;
747
+ if (mod && typeof mod.getStaticLocale === "function") {
748
+ try {
749
+ const locale = mod.getStaticLocale();
750
+ if (typeof locale === "string" && locale.length > 0) return locale;
751
+ } catch {
752
+ }
753
+ }
754
+ return defaultLocale;
755
+ }
756
+
757
+ // src/locales/en.json
758
+ var en_default = {
759
+ "table.showing": "Showing {{start}}\u2013{{end}} of {{total}}",
760
+ "table.prev": "\u2039 Prev",
761
+ "table.prev_aria": "Previous page",
762
+ "table.next": "Next \u203A",
763
+ "table.next_aria": "Next page",
764
+ "table.search_placeholder": "Search...",
765
+ "table.sort_tooltip": "Click to sort; shift-click to append a secondary sort",
766
+ "table.empty": "No items",
767
+ "table.no_results": "No matches \u2014 adjust your filters",
768
+ "table.error_title": "Couldn't load data",
769
+ "table.error_description": "The data source rejected the request.",
770
+ "rte.undo": "Undo",
771
+ "rte.redo": "Redo",
772
+ "rte.decrease_font_size": "Decrease font size",
773
+ "rte.increase_font_size": "Increase font size",
774
+ "rte.bold": "Bold",
775
+ "rte.italic": "Italic",
776
+ "rte.underline": "Underline",
777
+ "rte.strikethrough": "Strikethrough",
778
+ "rte.subscript": "Subscript",
779
+ "rte.superscript": "Superscript",
780
+ "rte.link": "Link",
781
+ "rte.clear_formatting": "Clear formatting",
782
+ "rte.text_color": "Text color",
783
+ "rte.highlight_color": "Highlight color",
784
+ "rte.align_left": "Align left",
785
+ "rte.align_center": "Align center",
786
+ "rte.align_right": "Align right",
787
+ "rte.justify": "Justify",
788
+ "rte.bullet_list": "Bullet list",
789
+ "rte.ordered_list": "Numbered list",
790
+ "rte.checklist": "Checklist",
791
+ "rte.decrease_indent": "Decrease indent",
792
+ "rte.increase_indent": "Increase indent",
793
+ "rte.horizontal_rule": "Horizontal rule",
794
+ "rte.insert_image": "Insert image",
795
+ "rte.table": "Table",
796
+ "rte.insert_variable": "Insert variable",
797
+ "rte.attach_file": "Attach file",
798
+ "rte.block_type.paragraph": "Paragraph",
799
+ "rte.block_type.heading_1": "Heading 1",
800
+ "rte.block_type.heading_2": "Heading 2",
801
+ "rte.block_type.heading_3": "Heading 3",
802
+ "rte.block_type.ordered_list": "Numbered List",
803
+ "rte.block_type.bullet_list": "Bulleted List",
804
+ "rte.block_type.task_list": "Check List",
805
+ "rte.block_type.code_block": "Code Block",
806
+ "rte.block_type.blockquote": "Quote",
807
+ "filter.title": "Filter",
808
+ "filter.description": "Add fields to filter by. Select a field and set its value.",
809
+ "filter.text_placeholder": "Enter text...",
810
+ "filter.number_placeholder": "Value",
811
+ "filter.select_option_placeholder": "Select option...",
812
+ "filter.select_placeholder": "Select...",
813
+ "filter.pick_date": "Pick a date",
814
+ "filter.on": "On",
815
+ "filter.off": "Off",
816
+ "filter.remove_field_aria": "Remove {{field}} filter",
817
+ "filter.active_filters": "Active filters",
818
+ "filter.no_active_filters": "No active filters",
819
+ "filter.open_dialog_aria": "Open filter dialog",
820
+ "filter.button_label": "Filter",
821
+ "filter.empty_fields": "No filters yet. Add one below to narrow down the results.",
822
+ "filter.all_fields_added": "All fields added",
823
+ "filter.add_filter_field": "Add filter field",
824
+ "filter.search_fields_placeholder": "Search fields...",
825
+ "filter.no_fields_available": "No fields available.",
826
+ "filter.clear_all": "Clear all",
827
+ "filter.cancel": "Cancel",
828
+ "filter.apply": "Apply"
829
+ };
830
+ var t = createPackageT("hazo_ui", en_default);
715
831
  function FilterFieldItem({
716
832
  filterConfig,
717
833
  fieldConfig,
@@ -735,7 +851,7 @@ function FilterFieldItem({
735
851
  }
736
852
  onValueChange(value);
737
853
  },
738
- placeholder: "Enter text...",
854
+ placeholder: t("filter.text_placeholder"),
739
855
  minLength: fieldConfig.textConfig?.minLength,
740
856
  maxLength: fieldConfig.textConfig?.maxLength,
741
857
  className: "cls_filter_text_input h-8 w-full min-w-0 text-sm"
@@ -787,7 +903,7 @@ function FilterFieldItem({
787
903
  }
788
904
  onValueChange(numValue);
789
905
  },
790
- placeholder: "Value",
906
+ placeholder: t("filter.number_placeholder"),
791
907
  min: fieldConfig.numberConfig?.min,
792
908
  max: fieldConfig.numberConfig?.max,
793
909
  step: fieldConfig.numberConfig?.allowDecimal ? 0.01 : 1,
@@ -803,21 +919,21 @@ function FilterFieldItem({
803
919
  value: filterConfig.value || "",
804
920
  onValueChange: (value) => onValueChange(value),
805
921
  children: [
806
- /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "cls_filter_combobox_select h-8 w-full min-w-0 text-sm", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "Select option..." }) }),
922
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "cls_filter_combobox_select h-8 w-full min-w-0 text-sm", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: t("filter.select_option_placeholder") }) }),
807
923
  /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: fieldConfig.comboboxOptions?.map((option) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
808
924
  ]
809
925
  }
810
926
  );
811
927
  case "boolean": {
812
- const trueLabel = fieldConfig.booleanLabels?.trueLabel || "On";
813
- const falseLabel = fieldConfig.booleanLabels?.falseLabel || "Off";
928
+ const trueLabel = fieldConfig.booleanLabels?.trueLabel || t("filter.on");
929
+ const falseLabel = fieldConfig.booleanLabels?.falseLabel || t("filter.off");
814
930
  return /* @__PURE__ */ jsxRuntime.jsxs(
815
931
  Select,
816
932
  {
817
933
  value: filterConfig.value !== void 0 && filterConfig.value !== null ? String(filterConfig.value) : "",
818
934
  onValueChange: (value) => onValueChange(value === "true"),
819
935
  children: [
820
- /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "cls_filter_boolean_select h-8 w-full min-w-0 text-sm", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "Select..." }) }),
936
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "cls_filter_boolean_select h-8 w-full min-w-0 text-sm", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: t("filter.select_placeholder") }) }),
821
937
  /* @__PURE__ */ jsxRuntime.jsxs(SelectContent, { children: [
822
938
  /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "true", children: trueLabel }),
823
939
  /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: "false", children: falseLabel })
@@ -859,7 +975,7 @@ function FilterFieldItem({
859
975
  ),
860
976
  children: [
861
977
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { className: "cls_calendar_icon h-3.5 w-3.5 shrink-0" }),
862
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cls_date_text truncate", children: selectedDate ? dateFns.format(selectedDate, "MMM d, yyyy") : "Pick a date" })
978
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cls_date_text truncate", children: selectedDate ? dateFns.format(selectedDate, "MMM d, yyyy") : t("filter.pick_date") })
863
979
  ]
864
980
  }
865
981
  ) }),
@@ -893,7 +1009,7 @@ function FilterFieldItem({
893
1009
  size: "sm",
894
1010
  onClick: onDelete,
895
1011
  className: "cls_delete_btn h-7 w-7 shrink-0 p-0 text-muted-foreground/60 hover:bg-destructive/10 hover:text-destructive",
896
- "aria-label": `Remove ${fieldConfig.label} filter`,
1012
+ "aria-label": t("filter.remove_field_aria", { field: fieldConfig.label }),
897
1013
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "cls_delete_icon h-3.5 w-3.5" })
898
1014
  }
899
1015
  )
@@ -904,8 +1020,8 @@ function HazoUiMultiFilterDialog({
904
1020
  availableFields,
905
1021
  onFilterChange,
906
1022
  initialFilters = [],
907
- title = "Filter",
908
- description = "Add fields to filter by. Select a field and set its value.",
1023
+ title = t("filter.title"),
1024
+ description = t("filter.description"),
909
1025
  headerBackgroundColor,
910
1026
  headerTextColor,
911
1027
  submitButtonBackgroundColor,
@@ -1010,13 +1126,13 @@ function HazoUiMultiFilterDialog({
1010
1126
  };
1011
1127
  const hasActiveFilters = initialFilters.length > 0;
1012
1128
  const tooltipContent = hasActiveFilters ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_filter_tooltip_content space-y-1", children: [
1013
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_tooltip_title text-xs font-semibold mb-1", children: "Active filters" }),
1129
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_tooltip_title text-xs font-semibold mb-1", children: t("filter.active_filters") }),
1014
1130
  initialFilters.map((filterConfig) => {
1015
1131
  const fieldConfig = getFieldConfig(filterConfig.field);
1016
1132
  if (!fieldConfig) return null;
1017
1133
  let displayValue = String(filterConfig.value);
1018
1134
  if (fieldConfig.type === "boolean") {
1019
- displayValue = filterConfig.value ? fieldConfig.booleanLabels?.trueLabel || "On" : fieldConfig.booleanLabels?.falseLabel || "Off";
1135
+ displayValue = filterConfig.value ? fieldConfig.booleanLabels?.trueLabel || t("filter.on") : fieldConfig.booleanLabels?.falseLabel || t("filter.off");
1020
1136
  } else if (fieldConfig.type === "combobox") {
1021
1137
  const option = fieldConfig.comboboxOptions?.find((opt) => opt.value === filterConfig.value);
1022
1138
  displayValue = option?.label || displayValue;
@@ -1034,7 +1150,7 @@ function HazoUiMultiFilterDialog({
1034
1150
  displayValue
1035
1151
  ] }, filterConfig.field);
1036
1152
  })
1037
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_filter_tooltip_content text-xs", children: "No active filters" });
1153
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_filter_tooltip_content text-xs", children: t("filter.no_active_filters") });
1038
1154
  return /* @__PURE__ */ jsxRuntime.jsxs(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: [
1039
1155
  /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
1040
1156
  /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
@@ -1043,7 +1159,7 @@ function HazoUiMultiFilterDialog({
1043
1159
  variant: "outline",
1044
1160
  size: "sm",
1045
1161
  className: "cls_filter_button",
1046
- "aria-label": "Open filter dialog",
1162
+ "aria-label": t("filter.open_dialog_aria"),
1047
1163
  children: [
1048
1164
  /* @__PURE__ */ jsxRuntime.jsx(
1049
1165
  lucideReact.Filter,
@@ -1054,7 +1170,7 @@ function HazoUiMultiFilterDialog({
1054
1170
  )
1055
1171
  }
1056
1172
  ),
1057
- "Filter",
1173
+ t("filter.button_label"),
1058
1174
  hasActiveFilters && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cls_filter_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: initialFilters.length })
1059
1175
  ]
1060
1176
  }
@@ -1088,7 +1204,7 @@ function HazoUiMultiFilterDialog({
1088
1204
  },
1089
1205
  filterConfig.field
1090
1206
  );
1091
- }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_empty_filter_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 filters yet. Add one below to narrow down the results." }),
1207
+ }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_empty_filter_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("filter.empty_fields") }),
1092
1208
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_add_field_section", children: /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: isComboboxOpen, onOpenChange: setIsComboboxOpen, children: [
1093
1209
  /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
1094
1210
  Button,
@@ -1100,13 +1216,13 @@ function HazoUiMultiFilterDialog({
1100
1216
  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",
1101
1217
  children: [
1102
1218
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "cls_plus_icon h-4 w-4" }),
1103
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: availableFieldsToAdd.length === 0 ? "All fields added" : "Add filter field" })
1219
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: availableFieldsToAdd.length === 0 ? t("filter.all_fields_added") : t("filter.add_filter_field") })
1104
1220
  ]
1105
1221
  }
1106
1222
  ) }),
1107
1223
  /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "cls_combobox_popover w-[var(--radix-popover-trigger-width)] p-0", align: "start", children: /* @__PURE__ */ jsxRuntime.jsxs(Command, { children: [
1108
- /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: "Search fields...", className: "cls_command_input" }),
1109
- /* @__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(
1224
+ /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: t("filter.search_fields_placeholder"), className: "cls_command_input" }),
1225
+ /* @__PURE__ */ jsxRuntime.jsx(CommandList, { children: availableFieldsToAdd.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: t("filter.no_fields_available") }) : /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { children: availableFieldsToAdd.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
1110
1226
  CommandItem,
1111
1227
  {
1112
1228
  value: field.label,
@@ -1128,7 +1244,7 @@ function HazoUiMultiFilterDialog({
1128
1244
  onClick: handleClearAll,
1129
1245
  className: "cls_clear_all_btn text-muted-foreground hover:text-foreground",
1130
1246
  style: clearButtonStyles,
1131
- children: "Clear all"
1247
+ children: t("filter.clear_all")
1132
1248
  }
1133
1249
  ) }),
1134
1250
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_footer_right flex items-center gap-2", children: [
@@ -1140,7 +1256,7 @@ function HazoUiMultiFilterDialog({
1140
1256
  onClick: handleCancel,
1141
1257
  className: "cls_cancel_btn",
1142
1258
  style: cancelButtonStyles,
1143
- children: "Cancel"
1259
+ children: t("filter.cancel")
1144
1260
  }
1145
1261
  ),
1146
1262
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1150,7 +1266,7 @@ function HazoUiMultiFilterDialog({
1150
1266
  onClick: handleApply,
1151
1267
  className: "cls_apply_btn",
1152
1268
  style: submitButtonStyles,
1153
- children: "Apply"
1269
+ children: t("filter.apply")
1154
1270
  }
1155
1271
  )
1156
1272
  ] })
@@ -3624,6 +3740,23 @@ var BLOCK_TYPES = [
3624
3740
  { label: "Code Block", value: "code-block", icon: "code" },
3625
3741
  { label: "Quote", value: "blockquote", icon: "quote" }
3626
3742
  ];
3743
+ var BLOCK_TYPE_LABEL_KEYS = {
3744
+ paragraph: "rte.block_type.paragraph",
3745
+ "heading-1": "rte.block_type.heading_1",
3746
+ "heading-2": "rte.block_type.heading_2",
3747
+ "heading-3": "rte.block_type.heading_3",
3748
+ "ordered-list": "rte.block_type.ordered_list",
3749
+ "bullet-list": "rte.block_type.bullet_list",
3750
+ "task-list": "rte.block_type.task_list",
3751
+ "code-block": "rte.block_type.code_block",
3752
+ blockquote: "rte.block_type.blockquote"
3753
+ };
3754
+ function get_translated_block_types(t4) {
3755
+ return BLOCK_TYPES.map((type) => ({
3756
+ ...type,
3757
+ label: t4(BLOCK_TYPE_LABEL_KEYS[type.value])
3758
+ }));
3759
+ }
3627
3760
 
3628
3761
  // src/components/hazo_ui_rte/utils.ts
3629
3762
  function file_to_base64(file) {
@@ -3668,6 +3801,7 @@ function get_file_extension(filename) {
3668
3801
  function is_image_file(mime_type) {
3669
3802
  return mime_type.startsWith("image/");
3670
3803
  }
3804
+ var t2 = createPackageT("hazo_ui", en_default);
3671
3805
  var ALL_ON = {
3672
3806
  undo_redo: true,
3673
3807
  block_type: true,
@@ -3722,6 +3856,7 @@ var Toolbar = ({
3722
3856
  }
3723
3857
  const tb = { ...ALL_ON, ...toolbar };
3724
3858
  const font_family_options = font_families && font_families.length > 0 ? font_families : FONT_FAMILIES;
3859
+ const block_type_options = get_translated_block_types(t2);
3725
3860
  const get_current_font_size = () => {
3726
3861
  const attrs = editor.getAttributes("textStyle");
3727
3862
  return attrs.fontSize || FONT_SIZE_CONFIG.default;
@@ -3865,7 +4000,7 @@ var Toolbar = ({
3865
4000
  {
3866
4001
  onClick: () => editor.chain().focus().undo().run(),
3867
4002
  disabled: !editor.can().undo(),
3868
- tooltip: "Undo",
4003
+ tooltip: t2("rte.undo"),
3869
4004
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuUndo2, { className: "h-4 w-4" })
3870
4005
  },
3871
4006
  "undo"
@@ -3875,7 +4010,7 @@ var Toolbar = ({
3875
4010
  {
3876
4011
  onClick: () => editor.chain().focus().redo().run(),
3877
4012
  disabled: !editor.can().redo(),
3878
- tooltip: "Redo",
4013
+ tooltip: t2("rte.redo"),
3879
4014
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuRedo2, { className: "h-4 w-4" })
3880
4015
  },
3881
4016
  "redo"
@@ -3886,7 +4021,7 @@ var Toolbar = ({
3886
4021
  sections.push([
3887
4022
  /* @__PURE__ */ jsxRuntime.jsxs(Select, { value: get_current_block_type(), onValueChange: handle_block_type_change, children: [
3888
4023
  /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "h-8 w-[130px] text-xs", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, {}) }),
3889
- /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: BLOCK_TYPES.map((type) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: type.value, className: "text-xs", children: type.label }, type.value)) })
4024
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: block_type_options.map((type) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: type.value, className: "text-xs", children: type.label }, type.value)) })
3890
4025
  ] }, "block")
3891
4026
  ]);
3892
4027
  }
@@ -3916,7 +4051,7 @@ var Toolbar = ({
3916
4051
  ToolbarButton,
3917
4052
  {
3918
4053
  onClick: () => handle_font_size_change(-2),
3919
- tooltip: "Decrease font size",
4054
+ tooltip: t2("rte.decrease_font_size"),
3920
4055
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuMinus, { className: "h-3 w-3" })
3921
4056
  }
3922
4057
  ),
@@ -3925,7 +4060,7 @@ var Toolbar = ({
3925
4060
  ToolbarButton,
3926
4061
  {
3927
4062
  onClick: () => handle_font_size_change(FONT_SIZE_CONFIG.step),
3928
- tooltip: "Increase font size",
4063
+ tooltip: t2("rte.increase_font_size"),
3929
4064
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuPlus, { className: "h-3 w-3" })
3930
4065
  }
3931
4066
  )
@@ -3943,7 +4078,7 @@ var Toolbar = ({
3943
4078
  {
3944
4079
  onClick: () => editor.chain().focus().toggleBold().run(),
3945
4080
  is_active: editor.isActive("bold"),
3946
- tooltip: "Bold",
4081
+ tooltip: t2("rte.bold"),
3947
4082
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuBold, { className: "h-4 w-4" })
3948
4083
  },
3949
4084
  "bold"
@@ -3957,7 +4092,7 @@ var Toolbar = ({
3957
4092
  {
3958
4093
  onClick: () => editor.chain().focus().toggleItalic().run(),
3959
4094
  is_active: editor.isActive("italic"),
3960
- tooltip: "Italic",
4095
+ tooltip: t2("rte.italic"),
3961
4096
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuItalic, { className: "h-4 w-4" })
3962
4097
  },
3963
4098
  "italic"
@@ -3971,7 +4106,7 @@ var Toolbar = ({
3971
4106
  {
3972
4107
  onClick: () => editor.chain().focus().toggleUnderline().run(),
3973
4108
  is_active: editor.isActive("underline"),
3974
- tooltip: "Underline",
4109
+ tooltip: t2("rte.underline"),
3975
4110
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuUnderline, { className: "h-4 w-4" })
3976
4111
  },
3977
4112
  "underline"
@@ -3985,7 +4120,7 @@ var Toolbar = ({
3985
4120
  {
3986
4121
  onClick: () => editor.chain().focus().toggleStrike().run(),
3987
4122
  is_active: editor.isActive("strike"),
3988
- tooltip: "Strikethrough",
4123
+ tooltip: t2("rte.strikethrough"),
3989
4124
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuStrikethrough, { className: "h-4 w-4" })
3990
4125
  },
3991
4126
  "strike"
@@ -3999,7 +4134,7 @@ var Toolbar = ({
3999
4134
  {
4000
4135
  onClick: () => editor.chain().focus().toggleSubscript().run(),
4001
4136
  is_active: editor.isActive("subscript"),
4002
- tooltip: "Subscript",
4137
+ tooltip: t2("rte.subscript"),
4003
4138
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuSubscript, { className: "h-4 w-4" })
4004
4139
  },
4005
4140
  "sub"
@@ -4013,7 +4148,7 @@ var Toolbar = ({
4013
4148
  {
4014
4149
  onClick: () => editor.chain().focus().toggleSuperscript().run(),
4015
4150
  is_active: editor.isActive("superscript"),
4016
- tooltip: "Superscript",
4151
+ tooltip: t2("rte.superscript"),
4017
4152
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuSuperscript, { className: "h-4 w-4" })
4018
4153
  },
4019
4154
  "super"
@@ -4027,7 +4162,7 @@ var Toolbar = ({
4027
4162
  if (tb.link) {
4028
4163
  items.push(
4029
4164
  /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: link_popover_open, onOpenChange: set_link_popover_open, children: [
4030
- /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { is_active: editor.isActive("link"), tooltip: "Link", children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuLink, { className: "h-4 w-4" }) }) }),
4165
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { is_active: editor.isActive("link"), tooltip: t2("rte.link"), children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuLink, { className: "h-4 w-4" }) }) }),
4031
4166
  /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "w-80 p-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
4032
4167
  /* @__PURE__ */ jsxRuntime.jsx(
4033
4168
  Input,
@@ -4063,7 +4198,7 @@ var Toolbar = ({
4063
4198
  ToolbarButton,
4064
4199
  {
4065
4200
  onClick: () => editor.chain().focus().unsetAllMarks().clearNodes().run(),
4066
- tooltip: "Clear formatting",
4201
+ tooltip: t2("rte.clear_formatting"),
4067
4202
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuRemoveFormatting, { className: "h-4 w-4" })
4068
4203
  },
4069
4204
  "clear"
@@ -4077,7 +4212,7 @@ var Toolbar = ({
4077
4212
  if (tb.text_color) {
4078
4213
  items.push(
4079
4214
  /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: text_color_open, onOpenChange: set_text_color_open, children: [
4080
- /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { tooltip: "Text color", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
4215
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { tooltip: t2("rte.text_color"), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
4081
4216
  /* @__PURE__ */ jsxRuntime.jsx(lu.LuPalette, { className: "h-4 w-4" }),
4082
4217
  /* @__PURE__ */ jsxRuntime.jsx(
4083
4218
  "div",
@@ -4120,7 +4255,7 @@ var Toolbar = ({
4120
4255
  if (tb.highlight_color) {
4121
4256
  items.push(
4122
4257
  /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: highlight_color_open, onOpenChange: set_highlight_color_open, children: [
4123
- /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { tooltip: "Highlight color", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
4258
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { tooltip: t2("rte.highlight_color"), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
4124
4259
  /* @__PURE__ */ jsxRuntime.jsx(lu.LuHighlighter, { className: "h-4 w-4" }),
4125
4260
  /* @__PURE__ */ jsxRuntime.jsx(
4126
4261
  "div",
@@ -4163,7 +4298,7 @@ var Toolbar = ({
4163
4298
  {
4164
4299
  onClick: () => editor.chain().focus().setTextAlign("left").run(),
4165
4300
  is_active: editor.isActive({ textAlign: "left" }),
4166
- tooltip: "Align left",
4301
+ tooltip: t2("rte.align_left"),
4167
4302
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignLeft, { className: "h-4 w-4" })
4168
4303
  },
4169
4304
  "align-left"
@@ -4173,7 +4308,7 @@ var Toolbar = ({
4173
4308
  {
4174
4309
  onClick: () => editor.chain().focus().setTextAlign("center").run(),
4175
4310
  is_active: editor.isActive({ textAlign: "center" }),
4176
- tooltip: "Align center",
4311
+ tooltip: t2("rte.align_center"),
4177
4312
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignCenter, { className: "h-4 w-4" })
4178
4313
  },
4179
4314
  "align-center"
@@ -4183,7 +4318,7 @@ var Toolbar = ({
4183
4318
  {
4184
4319
  onClick: () => editor.chain().focus().setTextAlign("right").run(),
4185
4320
  is_active: editor.isActive({ textAlign: "right" }),
4186
- tooltip: "Align right",
4321
+ tooltip: t2("rte.align_right"),
4187
4322
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignRight, { className: "h-4 w-4" })
4188
4323
  },
4189
4324
  "align-right"
@@ -4193,7 +4328,7 @@ var Toolbar = ({
4193
4328
  {
4194
4329
  onClick: () => editor.chain().focus().setTextAlign("justify").run(),
4195
4330
  is_active: editor.isActive({ textAlign: "justify" }),
4196
- tooltip: "Justify",
4331
+ tooltip: t2("rte.justify"),
4197
4332
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignJustify, { className: "h-4 w-4" })
4198
4333
  },
4199
4334
  "align-justify"
@@ -4209,7 +4344,7 @@ var Toolbar = ({
4209
4344
  {
4210
4345
  onClick: () => editor.chain().focus().toggleBulletList().run(),
4211
4346
  is_active: editor.isActive("bulletList"),
4212
- tooltip: "Bullet list",
4347
+ tooltip: t2("rte.bullet_list"),
4213
4348
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuList, { className: "h-4 w-4" })
4214
4349
  },
4215
4350
  "bullet"
@@ -4223,7 +4358,7 @@ var Toolbar = ({
4223
4358
  {
4224
4359
  onClick: () => editor.chain().focus().toggleOrderedList().run(),
4225
4360
  is_active: editor.isActive("orderedList"),
4226
- tooltip: "Numbered list",
4361
+ tooltip: t2("rte.ordered_list"),
4227
4362
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuListOrdered, { className: "h-4 w-4" })
4228
4363
  },
4229
4364
  "ordered"
@@ -4237,7 +4372,7 @@ var Toolbar = ({
4237
4372
  {
4238
4373
  onClick: () => editor.chain().focus().toggleTaskList().run(),
4239
4374
  is_active: editor.isActive("taskList"),
4240
- tooltip: "Checklist",
4375
+ tooltip: t2("rte.checklist"),
4241
4376
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuListChecks, { className: "h-4 w-4" })
4242
4377
  },
4243
4378
  "task"
@@ -4259,7 +4394,7 @@ var Toolbar = ({
4259
4394
  }
4260
4395
  },
4261
4396
  disabled: !editor.can().liftListItem("listItem") && !editor.can().liftListItem("taskItem"),
4262
- tooltip: "Decrease indent",
4397
+ tooltip: t2("rte.decrease_indent"),
4263
4398
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuIndentDecrease, { className: "h-4 w-4" })
4264
4399
  },
4265
4400
  "indent-dec"
@@ -4275,7 +4410,7 @@ var Toolbar = ({
4275
4410
  }
4276
4411
  },
4277
4412
  disabled: !editor.can().sinkListItem("listItem") && !editor.can().sinkListItem("taskItem"),
4278
- tooltip: "Increase indent",
4413
+ tooltip: t2("rte.increase_indent"),
4279
4414
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuIndentIncrease, { className: "h-4 w-4" })
4280
4415
  },
4281
4416
  "indent-inc"
@@ -4286,7 +4421,7 @@ var Toolbar = ({
4286
4421
  const items = [];
4287
4422
  if (tb.horizontal_rule) {
4288
4423
  items.push(
4289
- /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { onClick: handle_hr_insert, tooltip: "Horizontal rule", children: /* @__PURE__ */ jsxRuntime.jsx(rx.RxDividerHorizontal, { className: "h-4 w-4" }) }, "hr")
4424
+ /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { onClick: handle_hr_insert, tooltip: t2("rte.horizontal_rule"), children: /* @__PURE__ */ jsxRuntime.jsx(rx.RxDividerHorizontal, { className: "h-4 w-4" }) }, "hr")
4290
4425
  );
4291
4426
  }
4292
4427
  if (tb.image) {
@@ -4295,7 +4430,7 @@ var Toolbar = ({
4295
4430
  ToolbarButton,
4296
4431
  {
4297
4432
  onClick: () => image_input_ref.current?.click(),
4298
- tooltip: "Insert image",
4433
+ tooltip: t2("rte.insert_image"),
4299
4434
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuImage, { className: "h-4 w-4" })
4300
4435
  },
4301
4436
  "image"
@@ -4309,7 +4444,7 @@ var Toolbar = ({
4309
4444
  ToolbarButton,
4310
4445
  {
4311
4446
  is_active: editor.isActive("table"),
4312
- tooltip: "Table",
4447
+ tooltip: t2("rte.table"),
4313
4448
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuTable, { className: "h-4 w-4" })
4314
4449
  }
4315
4450
  ) }),
@@ -4481,7 +4616,7 @@ var Toolbar = ({
4481
4616
  if (tb.variables && variables.length > 0) {
4482
4617
  items.push(
4483
4618
  /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: variables_menu_open, onOpenChange: set_variables_menu_open, children: [
4484
- /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { tooltip: "Insert variable", children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuVariable, { className: "h-4 w-4" }) }) }),
4619
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { tooltip: t2("rte.insert_variable"), children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuVariable, { className: "h-4 w-4" }) }) }),
4485
4620
  /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "w-64 p-0", align: "start", children: /* @__PURE__ */ jsxRuntime.jsxs(Command, { children: [
4486
4621
  /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: "Search variables...", className: "h-8 text-xs" }),
4487
4622
  /* @__PURE__ */ jsxRuntime.jsxs(CommandList, { children: [
@@ -4510,7 +4645,7 @@ var Toolbar = ({
4510
4645
  ToolbarButton,
4511
4646
  {
4512
4647
  onClick: () => file_input_ref.current?.click(),
4513
- tooltip: "Attach file",
4648
+ tooltip: t2("rte.attach_file"),
4514
4649
  children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuPaperclip, { className: "h-4 w-4" })
4515
4650
  },
4516
4651
  "attach"
@@ -8551,7 +8686,7 @@ function LoadingTimeout({
8551
8686
  label = "content",
8552
8687
  className
8553
8688
  }) {
8554
- const t = {
8689
+ const t4 = {
8555
8690
  gentle: thresholds?.gentle ?? 5e3,
8556
8691
  firm: thresholds?.firm ?? 15e3,
8557
8692
  expired: thresholds?.expired ?? 3e4
@@ -8563,15 +8698,15 @@ function LoadingTimeout({
8563
8698
  return;
8564
8699
  }
8565
8700
  setPhase("silent");
8566
- const gentleTimer = window.setTimeout(() => setPhase("gentle"), t.gentle);
8567
- const firmTimer = window.setTimeout(() => setPhase("firm"), t.firm);
8568
- const expiredTimer = window.setTimeout(() => setPhase("expired"), t.expired);
8701
+ const gentleTimer = window.setTimeout(() => setPhase("gentle"), t4.gentle);
8702
+ const firmTimer = window.setTimeout(() => setPhase("firm"), t4.firm);
8703
+ const expiredTimer = window.setTimeout(() => setPhase("expired"), t4.expired);
8569
8704
  return () => {
8570
8705
  window.clearTimeout(gentleTimer);
8571
8706
  window.clearTimeout(firmTimer);
8572
8707
  window.clearTimeout(expiredTimer);
8573
8708
  };
8574
- }, [active, t.gentle, t.firm, t.expired]);
8709
+ }, [active, t4.gentle, t4.firm, t4.expired]);
8575
8710
  if (!active) {
8576
8711
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
8577
8712
  }
@@ -9442,6 +9577,7 @@ function KanbanLaneHead({
9442
9577
  "div",
9443
9578
  {
9444
9579
  ref: setNodeRef,
9580
+ "data-lane-key": lane.key,
9445
9581
  className: cn(
9446
9582
  "cls_hazo_kanban_lane_head mb-2 flex items-center gap-3 rounded-sm px-1 py-1",
9447
9583
  isOver && "cls_hazo_kanban_lane_head_over bg-accent/30 ring-1 ring-ring/40"
@@ -9467,6 +9603,7 @@ function KanbanLaneStrip({
9467
9603
  "div",
9468
9604
  {
9469
9605
  ref: setNodeRef,
9606
+ "data-lane-key": lane.key,
9470
9607
  className: cn(
9471
9608
  "cls_hazo_kanban_lane_strip mb-2 flex items-center gap-3 rounded-md border border-dashed border-border px-2 py-1 text-[11px] uppercase tracking-wider text-muted-foreground",
9472
9609
  isOver && "cls_hazo_kanban_lane_strip_over border-solid bg-accent/30 text-foreground ring-1 ring-ring/30"
@@ -10226,7 +10363,7 @@ function HazoUiKanban({
10226
10363
  if (lane.collapseWhenEmpty && count === 0) {
10227
10364
  return /* @__PURE__ */ jsxRuntime.jsx(KanbanLaneStrip, { lane, treeKey: tree_key }, lane.key);
10228
10365
  }
10229
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_hazo_kanban_lane", children: [
10366
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-lane-key": lane.key, className: "cls_hazo_kanban_lane", children: [
10230
10367
  /* @__PURE__ */ jsxRuntime.jsx(KanbanLaneHead, { lane, count, treeKey: tree_key }),
10231
10368
  only_column ? render_column(only_column, tree_key, lane.key) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_hazo_kanban_lane_grid grid gap-3", style: grid_style, children: columns.map((col) => render_column(col, tree_key, lane.key)) })
10232
10369
  ] }, lane.key);
@@ -10697,6 +10834,7 @@ function serializeFilter(filter) {
10697
10834
  const fields = (filter.fields ?? []).map((f) => `${f.field}:${f.operator ?? ""}:${String(f.value)}`).join(",");
10698
10835
  return `${filter.search ?? ""}|${fields}`;
10699
10836
  }
10837
+ var t3 = createPackageT("hazo_ui", en_default);
10700
10838
  function HazoUiTable(props) {
10701
10839
  const state = useTableState(props);
10702
10840
  const { columns, rows, getRowKey, className, caption } = props;
@@ -10731,12 +10869,12 @@ function HazoUiTable(props) {
10731
10869
  ) }) : 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(
10732
10870
  EmptyState,
10733
10871
  {
10734
- title: typeof props.empty === "string" && props.empty || "No items"
10872
+ title: typeof props.empty === "string" && props.empty || t3("table.empty")
10735
10873
  }
10736
10874
  ) : props.empty : typeof props.noResults === "string" || props.noResults === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
10737
10875
  EmptyState,
10738
10876
  {
10739
- title: typeof props.noResults === "string" && props.noResults || "No matches \u2014 adjust your filters"
10877
+ title: typeof props.noResults === "string" && props.noResults || t3("table.no_results")
10740
10878
  }
10741
10879
  ) : props.noResults }) : /* @__PURE__ */ jsxRuntime.jsx(
10742
10880
  TableMobileCards,
@@ -10759,7 +10897,7 @@ function HazoUiTable(props) {
10759
10897
  {
10760
10898
  type: "button",
10761
10899
  onClick: (e) => state.cycleHeaderSort(c.key, e.shiftKey),
10762
- title: "Click to sort; shift-click to append a secondary sort",
10900
+ title: t3("table.sort_tooltip"),
10763
10901
  className: "cls_hazo_ui_table_sort_btn inline-flex items-center gap-1 hover:text-foreground",
10764
10902
  children: [
10765
10903
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: c.label }),
@@ -10791,12 +10929,12 @@ function HazoUiTable(props) {
10791
10929
  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(
10792
10930
  EmptyState,
10793
10931
  {
10794
- title: typeof props.empty === "string" && props.empty || "No items"
10932
+ title: typeof props.empty === "string" && props.empty || t3("table.empty")
10795
10933
  }
10796
10934
  ) : 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(
10797
10935
  EmptyState,
10798
10936
  {
10799
- title: typeof props.noResults === "string" && props.noResults || "No matches \u2014 adjust your filters"
10937
+ title: typeof props.noResults === "string" && props.noResults || t3("table.no_results")
10800
10938
  }
10801
10939
  ) : props.noResults })
10802
10940
  }
@@ -10835,7 +10973,7 @@ function renderCell(c, row, i) {
10835
10973
  var DEFAULT_NUMBER_LOCALE = "en-US";
10836
10974
  function formatValue(value, formatter, currency, locale) {
10837
10975
  if (value === null || value === void 0 || value === "") return "\u2014";
10838
- const lc = locale ?? DEFAULT_NUMBER_LOCALE;
10976
+ const lc = locale ?? resolvePackageLocale(DEFAULT_NUMBER_LOCALE);
10839
10977
  switch (formatter) {
10840
10978
  case "date": {
10841
10979
  const d = value instanceof Date ? value : new Date(value);
@@ -10910,14 +11048,11 @@ function PaginationFooter({
10910
11048
  const end = Math.min((page + 1) * pageSize, total);
10911
11049
  const lastPage = Math.max(0, Math.ceil(total / pageSize) - 1);
10912
11050
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_hazo_ui_table_pagination flex items-center justify-between gap-3 pt-2 text-sm", children: [
10913
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "cls_hazo_ui_table_page_counter text-muted-foreground", children: [
10914
- "Showing ",
10915
- start,
10916
- "\u2013",
10917
- end,
10918
- " of ",
10919
- total
10920
- ] }),
11051
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cls_hazo_ui_table_page_counter text-muted-foreground", children: t3("table.showing", {
11052
+ start: String(start),
11053
+ end: String(end),
11054
+ total: String(total)
11055
+ }) }),
10921
11056
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_hazo_ui_table_page_buttons flex items-center gap-2", children: [
10922
11057
  /* @__PURE__ */ jsxRuntime.jsx(
10923
11058
  Button,
@@ -10926,8 +11061,8 @@ function PaginationFooter({
10926
11061
  size: "sm",
10927
11062
  onClick: () => onPageChange(Math.max(0, page - 1)),
10928
11063
  disabled: page === 0,
10929
- "aria-label": "Previous page",
10930
- children: "\u2039 Prev"
11064
+ "aria-label": t3("table.prev_aria"),
11065
+ children: t3("table.prev")
10931
11066
  }
10932
11067
  ),
10933
11068
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -10937,8 +11072,8 @@ function PaginationFooter({
10937
11072
  size: "sm",
10938
11073
  onClick: () => onPageChange(Math.min(lastPage, page + 1)),
10939
11074
  disabled: page >= lastPage,
10940
- "aria-label": "Next page",
10941
- children: "Next \u203A"
11075
+ "aria-label": t3("table.next_aria"),
11076
+ children: t3("table.next")
10942
11077
  }
10943
11078
  )
10944
11079
  ] })
@@ -10982,7 +11117,7 @@ function Toolbar2(props) {
10982
11117
  setSearchValue(v);
10983
11118
  onSearchChange(v);
10984
11119
  },
10985
- placeholder: searchPlaceholder ?? "Search...",
11120
+ placeholder: searchPlaceholder ?? t3("table.search_placeholder"),
10986
11121
  className: "cls_hazo_ui_table_search w-full sm:max-w-xs"
10987
11122
  }
10988
11123
  ) : /* @__PURE__ */ jsxRuntime.jsx("div", {}),
@@ -11030,8 +11165,8 @@ function renderErrorState(error, serverError) {
11030
11165
  return /* @__PURE__ */ jsxRuntime.jsx(
11031
11166
  EmptyState,
11032
11167
  {
11033
- title: "Couldn't load data",
11034
- description: msg || "The data source rejected the request."
11168
+ title: t3("table.error_title"),
11169
+ description: msg || t3("table.error_description")
11035
11170
  }
11036
11171
  );
11037
11172
  }
@@ -11817,8 +11952,8 @@ function computeEta(durationWindow, unitCount, concurrency = 1, fallbackUnitMs =
11817
11952
  }
11818
11953
  function easeToward(elapsed, eta, maxCap = 0.95) {
11819
11954
  if (eta <= 0 || elapsed <= 0) return 0;
11820
- const t = elapsed / eta;
11821
- return maxCap * (1 - Math.exp(-1.5 * t));
11955
+ const t4 = elapsed / eta;
11956
+ return maxCap * (1 - Math.exp(-1.5 * t4));
11822
11957
  }
11823
11958
  function HazoUiProgressBar({
11824
11959
  value,
@@ -12634,6 +12769,211 @@ function makeStatusBadge(statusMap, fallback) {
12634
12769
  Component.displayName = "StatusBadge(bound)";
12635
12770
  return Component;
12636
12771
  }
12772
+ function HazoBrowserTab({
12773
+ tabs,
12774
+ on_select,
12775
+ on_close,
12776
+ add_menu,
12777
+ className
12778
+ }) {
12779
+ const handle_close = (e, id) => {
12780
+ e.stopPropagation();
12781
+ on_close?.(id);
12782
+ };
12783
+ return /* @__PURE__ */ jsxRuntime.jsxs(
12784
+ "div",
12785
+ {
12786
+ role: "tablist",
12787
+ className: cn(
12788
+ "cls_hazo_browser_tab flex items-end gap-0.5 bg-muted px-1.5 pt-1.5",
12789
+ className
12790
+ ),
12791
+ children: [
12792
+ tabs.map((tab) => {
12793
+ const is_active = !!tab.active;
12794
+ const is_closable = tab.closable !== false;
12795
+ return /* @__PURE__ */ jsxRuntime.jsxs(
12796
+ "div",
12797
+ {
12798
+ role: "tab",
12799
+ "aria-selected": is_active,
12800
+ tabIndex: 0,
12801
+ onClick: () => on_select?.(tab.id),
12802
+ onKeyDown: (e) => {
12803
+ if (e.key === "Enter" || e.key === " ") {
12804
+ e.preventDefault();
12805
+ on_select?.(tab.id);
12806
+ }
12807
+ },
12808
+ className: cn(
12809
+ "cls_hazo_browser_tab_tab group flex items-center gap-1.5 rounded-t-md border border-b-0 px-3 py-1.5 text-sm cursor-pointer select-none max-w-[200px]",
12810
+ is_active ? "bg-background text-foreground font-semibold border-border" : "bg-transparent text-muted-foreground border-transparent hover:bg-background/60 hover:text-foreground"
12811
+ ),
12812
+ children: [
12813
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cls_hazo_browser_tab_label truncate", children: tab.label }),
12814
+ is_closable ? /* @__PURE__ */ jsxRuntime.jsx(
12815
+ "button",
12816
+ {
12817
+ type: "button",
12818
+ "aria-label": `Close ${tab.label}`,
12819
+ onClick: (e) => handle_close(e, tab.id),
12820
+ 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",
12821
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3 w-3" })
12822
+ }
12823
+ ) : null
12824
+ ]
12825
+ },
12826
+ tab.id
12827
+ );
12828
+ }),
12829
+ add_menu ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cls_hazo_browser_tab_add_menu flex items-center pb-1.5 pl-1", children: add_menu }) : null
12830
+ ]
12831
+ }
12832
+ );
12833
+ }
12834
+ var native_name_cache = /* @__PURE__ */ new Map();
12835
+ function get_native_name(code) {
12836
+ const cached = native_name_cache.get(code);
12837
+ if (cached !== void 0) return cached;
12838
+ let name = code;
12839
+ if (typeof Intl !== "undefined" && "DisplayNames" in Intl) {
12840
+ try {
12841
+ const display_names = new Intl.DisplayNames([code], {
12842
+ type: "language",
12843
+ languageDisplay: "standard"
12844
+ });
12845
+ name = display_names.of(code) ?? code;
12846
+ } catch {
12847
+ name = code;
12848
+ }
12849
+ }
12850
+ native_name_cache.set(code, name);
12851
+ return name;
12852
+ }
12853
+ function build_label(code, display) {
12854
+ if (display === "code") return code.toUpperCase();
12855
+ const native = get_native_name(code);
12856
+ if (display === "native+code") return `${native} (${code.toUpperCase()})`;
12857
+ return native;
12858
+ }
12859
+ var STRIPE_FLAGS = {
12860
+ de: { dir: "h", colors: ["#000000", "#DD0000", "#FFCE00"] },
12861
+ fr: { dir: "v", colors: ["#0055A4", "#FFFFFF", "#EF4135"] },
12862
+ it: { dir: "v", colors: ["#009246", "#FFFFFF", "#CE2B37"] },
12863
+ es: { dir: "h", colors: ["#AA151B", "#F1BF00", "#AA151B"] },
12864
+ pt: { dir: "v", colors: ["#046A38", "#FFFFFF", "#DA291C"] },
12865
+ nl: { dir: "h", colors: ["#AE1C28", "#FFFFFF", "#21468B"] }
12866
+ };
12867
+ var NORDIC_CROSS_FLAGS = {
12868
+ sv: { bg: "#006AA7", cross: "#FECC00" },
12869
+ fi: { bg: "#FFFFFF", cross: "#003580" }
12870
+ };
12871
+ function StripeFlag({
12872
+ dir,
12873
+ colors
12874
+ }) {
12875
+ const band = 12 / colors.length;
12876
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 16 12", width: "16", height: "12", "aria-hidden": "true", focusable: "false", children: colors.map(
12877
+ (color2, i) => dir === "h" ? /* @__PURE__ */ jsxRuntime.jsx("rect", { x: 0, y: i * band, width: 16, height: band, fill: color2 }, i) : /* @__PURE__ */ jsxRuntime.jsx("rect", { x: i * (16 / colors.length), y: 0, width: 16 / colors.length, height: 12, fill: color2 }, i)
12878
+ ) });
12879
+ }
12880
+ function NordicCrossFlag({ bg, cross }) {
12881
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 16 12", width: "16", height: "12", "aria-hidden": "true", focusable: "false", children: [
12882
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "16", height: "12", fill: bg }),
12883
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "5", width: "2", height: "12", fill: cross }),
12884
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { y: "5", width: "16", height: "2", fill: cross })
12885
+ ] });
12886
+ }
12887
+ function get_flag_node(code) {
12888
+ const lang = code.toLowerCase().split(/[-_]/)[0];
12889
+ const cross = NORDIC_CROSS_FLAGS[lang];
12890
+ if (cross) return /* @__PURE__ */ jsxRuntime.jsx(NordicCrossFlag, { ...cross });
12891
+ const stripes = STRIPE_FLAGS[lang];
12892
+ if (stripes) return /* @__PURE__ */ jsxRuntime.jsx(StripeFlag, { ...stripes });
12893
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { className: "h-3 w-3", "aria-hidden": "true" });
12894
+ }
12895
+ function FlagIcon({ code }) {
12896
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cls_locale_picker_flag inline-flex h-3.5 w-4 shrink-0 items-center justify-center overflow-hidden rounded-[2px]", children: get_flag_node(code) });
12897
+ }
12898
+ function LocalePicker({
12899
+ variant = "dropdown",
12900
+ show = "auto",
12901
+ display = "native",
12902
+ flags = false,
12903
+ alternates,
12904
+ activeLocale,
12905
+ triggerLabel = "Change language",
12906
+ className
12907
+ }) {
12908
+ const options = React27__namespace.useMemo(() => {
12909
+ return Object.entries(alternates ?? {}).map(([code, url]) => {
12910
+ const href = safeHref(url);
12911
+ if (!href) return null;
12912
+ return { code, href, label: build_label(code, display) };
12913
+ }).filter((o) => o !== null);
12914
+ }, [alternates, display]);
12915
+ if (show === "never") return null;
12916
+ if (options.length === 0) return null;
12917
+ if (show === "auto" && options.length < 2) return null;
12918
+ if (variant === "inline") {
12919
+ return /* @__PURE__ */ jsxRuntime.jsx(
12920
+ "nav",
12921
+ {
12922
+ "aria-label": triggerLabel,
12923
+ className: cn("cls_locale_picker_inline flex items-center gap-1", className),
12924
+ children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
12925
+ "a",
12926
+ {
12927
+ href: opt.href,
12928
+ lang: opt.code,
12929
+ "aria-current": opt.code === activeLocale ? "true" : void 0,
12930
+ className: cn(
12931
+ "cls_locale_picker_inline_item inline-flex items-center gap-1.5 rounded-md px-2 py-1 text-sm transition-colors hover:bg-accent hover:text-accent-foreground",
12932
+ opt.code === activeLocale && "bg-accent font-medium text-accent-foreground"
12933
+ ),
12934
+ children: [
12935
+ flags && /* @__PURE__ */ jsxRuntime.jsx(FlagIcon, { code: opt.code }),
12936
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: opt.label })
12937
+ ]
12938
+ },
12939
+ opt.code
12940
+ ))
12941
+ }
12942
+ );
12943
+ }
12944
+ const active_option = options.find((o) => o.code === activeLocale);
12945
+ return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
12946
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
12947
+ Button,
12948
+ {
12949
+ variant: "outline",
12950
+ size: "sm",
12951
+ lang: activeLocale,
12952
+ "aria-label": triggerLabel,
12953
+ className: cn("cls_locale_picker_trigger gap-1.5", className),
12954
+ children: [
12955
+ flags && /* @__PURE__ */ jsxRuntime.jsx(FlagIcon, { code: active_option?.code ?? options[0].code }),
12956
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cls_locale_picker_trigger_label", children: variant === "compact" ? (active_option ?? options[0]).code.toUpperCase() : (active_option ?? options[0]).label }),
12957
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3.5 w-3.5 opacity-60", "aria-hidden": "true" })
12958
+ ]
12959
+ }
12960
+ ) }),
12961
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "end", className: "cls_locale_picker_content", children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuRadioGroup, { value: activeLocale, children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive__namespace.RadioItem, { value: opt.code, asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
12962
+ "a",
12963
+ {
12964
+ href: opt.href,
12965
+ lang: opt.code,
12966
+ className: "cls_locale_picker_radio_item relative flex cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
12967
+ children: [
12968
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive__namespace.ItemIndicator, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Circle, { className: "h-2 w-2 fill-current" }) }) }),
12969
+ flags && /* @__PURE__ */ jsxRuntime.jsx(FlagIcon, { code: opt.code }),
12970
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: opt.label })
12971
+ ]
12972
+ }
12973
+ ) }, opt.code)) }) })
12974
+ ] });
12975
+ }
12976
+ LocalePicker.displayName = "LocalePicker";
12637
12977
 
12638
12978
  Object.defineProperty(exports, "rawToast", {
12639
12979
  enumerable: true,
@@ -12730,6 +13070,7 @@ exports.EmptyState = EmptyState;
12730
13070
  exports.ErrorBanner = ErrorBanner;
12731
13071
  exports.ErrorPage = ErrorPage;
12732
13072
  exports.FunnelChart = FunnelChart;
13073
+ exports.HazoBrowserTab = HazoBrowserTab;
12733
13074
  exports.HazoContextProvider = HazoContextProvider;
12734
13075
  exports.HazoUiConfirmDialog = HazoUiConfirmDialog;
12735
13076
  exports.HazoUiDialog = HazoUiDialog;
@@ -12771,6 +13112,7 @@ exports.InverseSparkline = InverseSparkline;
12771
13112
  exports.Label = Label3;
12772
13113
  exports.LiveRegion = LiveRegion;
12773
13114
  exports.LoadingTimeout = LoadingTimeout;
13115
+ exports.LocalePicker = LocalePicker;
12774
13116
  exports.Logo = Logo;
12775
13117
  exports.MarkdownEditor = MarkdownEditor;
12776
13118
  exports.NotificationCountBadge = NotificationCountBadge;