hazo_ui 4.9.0 → 4.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -138,6 +138,18 @@ var require_objectWithoutPropertiesLoose = __commonJS({
138
138
  function cn(...inputs) {
139
139
  return twMerge(clsx(inputs));
140
140
  }
141
+ function safeHref(url) {
142
+ if (!url) return void 0;
143
+ const trimmed = url.trim();
144
+ const lower = trimmed.toLowerCase();
145
+ if (lower.startsWith("http://") || lower.startsWith("https://") || lower.startsWith("mailto:")) {
146
+ return trimmed;
147
+ }
148
+ if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
149
+ return trimmed;
150
+ }
151
+ return void 0;
152
+ }
141
153
  function HazoContextProvider({
142
154
  correlationId,
143
155
  userId,
@@ -6697,39 +6709,47 @@ function resolve_animation_classes(open_anim = "zoom", close_anim = "zoom") {
6697
6709
  }
6698
6710
  var VARIANT_PRESETS = {
6699
6711
  info: {
6700
- header_background_color: "rgb(191, 219, 254)",
6701
- description_background_color: "rgb(219, 234, 254)",
6702
- header_text_color: "rgb(30, 58, 138)",
6703
- border_color: "rgb(59, 130, 246)",
6704
- accent_color: "rgb(59, 130, 246)",
6712
+ header_background_color: "var(--dialog-info-bg)",
6713
+ description_background_color: "var(--dialog-info-bg)",
6714
+ header_text_color: "var(--dialog-info-fg)",
6715
+ border_color: "var(--dialog-info-fg)",
6716
+ accent_color: "var(--dialog-info-fg)",
6705
6717
  overlay_class_name: "bg-blue-950/50"
6706
6718
  },
6707
6719
  success: {
6708
- header_background_color: "rgb(187, 247, 208)",
6709
- description_background_color: "rgb(220, 252, 231)",
6710
- header_text_color: "rgb(22, 101, 52)",
6711
- border_color: "rgb(34, 197, 94)",
6712
- accent_color: "rgb(34, 197, 94)",
6720
+ header_background_color: "var(--dialog-success-bg)",
6721
+ description_background_color: "var(--dialog-success-bg)",
6722
+ header_text_color: "var(--dialog-success-fg)",
6723
+ border_color: "var(--dialog-success-fg)",
6724
+ accent_color: "var(--dialog-success-fg)",
6713
6725
  overlay_class_name: "bg-green-950/50"
6714
6726
  },
6715
6727
  warning: {
6716
- header_background_color: "rgb(253, 230, 138)",
6717
- description_background_color: "rgb(254, 249, 195)",
6718
- header_text_color: "rgb(113, 63, 18)",
6719
- border_color: "rgb(234, 179, 8)",
6720
- accent_color: "rgb(234, 179, 8)",
6728
+ header_background_color: "var(--dialog-warning-bg)",
6729
+ description_background_color: "var(--dialog-warning-bg)",
6730
+ header_text_color: "var(--dialog-warning-fg)",
6731
+ border_color: "var(--dialog-warning-fg)",
6732
+ accent_color: "var(--dialog-warning-fg)",
6721
6733
  overlay_class_name: "bg-yellow-950/50"
6722
6734
  },
6723
6735
  destructive: {
6724
- header_background_color: "rgb(254, 202, 202)",
6725
- description_background_color: "rgb(254, 226, 226)",
6726
- header_text_color: "rgb(127, 29, 29)",
6727
- border_color: "rgb(239, 68, 68)",
6728
- accent_color: "rgb(239, 68, 68)",
6736
+ header_background_color: "var(--dialog-destructive-bg)",
6737
+ description_background_color: "var(--dialog-destructive-bg)",
6738
+ header_text_color: "var(--dialog-destructive-fg)",
6739
+ border_color: "var(--dialog-destructive-fg)",
6740
+ accent_color: "var(--dialog-destructive-fg)",
6729
6741
  overlay_class_name: "bg-red-950/50",
6730
6742
  action_button_variant: "destructive"
6731
6743
  }
6732
6744
  };
6745
+ var NEUTRAL_VARIANT_PRESET = {
6746
+ header_background_color: "hsl(var(--dialog-border) / 0.12)",
6747
+ description_background_color: "hsl(var(--dialog-border) / 0.12)",
6748
+ header_text_color: "hsl(var(--dialog-fg))",
6749
+ border_color: "hsl(var(--dialog-border))",
6750
+ accent_color: "hsl(var(--dialog-border))",
6751
+ overlay_class_name: "bg-black/50"
6752
+ };
6733
6753
  function HazoUiDialog({
6734
6754
  open,
6735
6755
  onOpenChange,
@@ -6738,13 +6758,13 @@ function HazoUiDialog({
6738
6758
  onCancel,
6739
6759
  title = "Action required",
6740
6760
  description,
6741
- actionButtonText = "Confirm",
6761
+ actionButtonText: actionButtonTextProp,
6742
6762
  actionButtonVariant,
6743
6763
  cancelButtonText = "Cancel",
6744
- showCancelButton = true,
6764
+ showCancelButton: showCancelButtonProp,
6745
6765
  showActionButton = true,
6746
- closeOnConfirm = false,
6747
- actionButtonLoading = false,
6766
+ closeOnConfirm: closeOnConfirmProp,
6767
+ actionButtonLoading: actionButtonLoadingProp,
6748
6768
  actionButtonDisabled = false,
6749
6769
  actionButtonIcon,
6750
6770
  footerContent,
@@ -6764,18 +6784,46 @@ function HazoUiDialog({
6764
6784
  borderColor,
6765
6785
  accentColor,
6766
6786
  headerBar = false,
6767
- headerBarColor = "#1e293b",
6787
+ headerBarColor,
6768
6788
  className,
6769
6789
  contentClassName,
6770
6790
  overlayClassName,
6771
6791
  headerClassName,
6772
6792
  footerClassName,
6773
- showCloseButton = true
6793
+ showCloseButton = true,
6794
+ kind
6774
6795
  }) {
6775
6796
  const config = get_hazo_ui_config();
6776
- const variant_preset = variant !== "default" ? VARIANT_PRESETS[variant] : void 0;
6797
+ const is_confirm_kind = kind === "confirm";
6798
+ const is_status_kind = kind === "status";
6799
+ const [internal_confirm_loading, set_internal_confirm_loading] = React26.useState(false);
6800
+ const cancel_ref = React26.useRef(null);
6801
+ const variant_preset = variant !== "default" ? VARIANT_PRESETS[variant] : is_status_kind || is_confirm_kind ? NEUTRAL_VARIANT_PRESET : void 0;
6777
6802
  const resolved_action_button_variant = actionButtonVariant ?? variant_preset?.action_button_variant ?? "default";
6803
+ const showCancelButton = showCancelButtonProp ?? (is_status_kind ? false : true);
6804
+ const closeOnConfirm = closeOnConfirmProp ?? (is_status_kind || is_confirm_kind ? true : false);
6805
+ const actionButtonText = actionButtonTextProp ?? (is_status_kind ? "OK" : is_confirm_kind ? showCancelButton ? "Confirm" : "OK" : "Confirm");
6806
+ const actionButtonLoading = actionButtonLoadingProp ?? (is_confirm_kind ? internal_confirm_loading : false);
6778
6807
  const handleConfirm = () => {
6808
+ if (is_confirm_kind) {
6809
+ try {
6810
+ const result = onConfirm?.();
6811
+ if (result instanceof Promise) {
6812
+ if (actionButtonLoadingProp === void 0) set_internal_confirm_loading(true);
6813
+ result.then(() => {
6814
+ if (closeOnConfirm) onOpenChange?.(false);
6815
+ }).catch(() => {
6816
+ }).finally(() => {
6817
+ if (actionButtonLoadingProp === void 0) set_internal_confirm_loading(false);
6818
+ });
6819
+ return;
6820
+ }
6821
+ } catch {
6822
+ return;
6823
+ }
6824
+ if (closeOnConfirm) onOpenChange?.(false);
6825
+ return;
6826
+ }
6779
6827
  onConfirm?.();
6780
6828
  if (closeOnConfirm) {
6781
6829
  onOpenChange?.(false);
@@ -6795,12 +6843,14 @@ function HazoUiDialog({
6795
6843
  const finalHeaderBackgroundColor = headerBackgroundColor ?? variant_preset?.header_background_color ?? config.header_background_color;
6796
6844
  const finalDescriptionBgColor = descriptionBackgroundColor ?? variant_preset?.description_background_color;
6797
6845
  const finalHeaderTextColor = headerTextColor ?? variant_preset?.header_text_color ?? config.header_text_color;
6798
- const is_variant_active = variant !== "default";
6846
+ const is_variant_active = variant !== "default" || is_status_kind;
6799
6847
  const has_split_header = splitHeader && !headerBar && !!finalDescriptionBgColor && !!description;
6800
6848
  const has_merged_variant_header = !splitHeader && is_variant_active && !headerBar && !!description;
6849
+ const resolvedHeaderBarColor = headerBarColor ?? (variant !== "default" && variant_preset ? variant_preset.header_text_color : "var(--dialog-header-bar-bg)");
6801
6850
  const headerStyles = {
6802
6851
  ...headerBar && {
6803
- backgroundColor: headerBarColor,
6852
+ backgroundColor: resolvedHeaderBarColor,
6853
+ color: "var(--dialog-header-bar-fg)",
6804
6854
  paddingTop: compact ? "0.625rem" : "1.5rem",
6805
6855
  paddingBottom: compact ? "0.625rem" : "1.5rem",
6806
6856
  paddingLeft: "1.5rem",
@@ -6810,15 +6860,19 @@ function HazoUiDialog({
6810
6860
  ...!has_split_header && finalHeaderTextColor && { color: finalHeaderTextColor }
6811
6861
  };
6812
6862
  const titleClassName = cn(
6813
- "cls_dialog_title",
6814
- headerBar && "!text-white"
6863
+ "cls_dialog_title"
6815
6864
  );
6816
6865
  const descriptionClassName = cn(
6817
- "cls_dialog_description",
6818
- headerBar && "!text-white/80"
6866
+ "cls_dialog_description"
6819
6867
  );
6820
6868
  const bodyStyles = {
6821
- ...bodyBackgroundColor && { backgroundColor: bodyBackgroundColor }
6869
+ ...bodyBackgroundColor && { backgroundColor: bodyBackgroundColor },
6870
+ // kind="form" gets a comfortable body/label typography scale via the
6871
+ // hazo_theme --dialog-body-size token. --dialog-label-size is intentionally
6872
+ // not re-applied here: CSS custom properties inherit, so a consumer's own
6873
+ // <label> elements inside `children` can reference var(--dialog-label-size)
6874
+ // directly without any extra plumbing from this component.
6875
+ ...kind === "form" && { fontSize: "var(--dialog-body-size)" }
6822
6876
  };
6823
6877
  const footerStyles = {
6824
6878
  ...footerBackgroundColor && { backgroundColor: footerBackgroundColor }
@@ -6842,6 +6896,86 @@ function HazoUiDialog({
6842
6896
  ...finalCancelTextColor && { color: finalCancelTextColor },
6843
6897
  ...finalCancelBorderColor && { borderColor: finalCancelBorderColor }
6844
6898
  };
6899
+ if (is_confirm_kind) {
6900
+ const top_border_color = resolved_border_color ?? "hsl(var(--dialog-border))";
6901
+ return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogPortal, { children: [
6902
+ /* @__PURE__ */ jsx(
6903
+ DialogOverlay,
6904
+ {
6905
+ className: cn(
6906
+ "cls_confirm_dialog_overlay",
6907
+ overlayClassName ?? variant_preset?.overlay_class_name
6908
+ ),
6909
+ style: { backdropFilter: "blur(4px)" }
6910
+ }
6911
+ ),
6912
+ /* @__PURE__ */ jsxs(
6913
+ DialogPrimitive.Content,
6914
+ {
6915
+ className: cn(
6916
+ "cls_confirm_dialog_content",
6917
+ "fixed left-[50%] top-[50%] z-50",
6918
+ "translate-x-[-50%] translate-y-[-50%]",
6919
+ "bg-background shadow-lg",
6920
+ "duration-200",
6921
+ animationClasses,
6922
+ "overflow-hidden",
6923
+ className
6924
+ ),
6925
+ style: {
6926
+ width: "min(90vw, 420px)",
6927
+ borderRadius: "12px",
6928
+ borderTop: `4px solid ${top_border_color}`,
6929
+ boxShadow: "0 20px 60px rgba(0,0,0,0.15)",
6930
+ outline: "none"
6931
+ },
6932
+ onOpenAutoFocus: (e) => {
6933
+ if ((variant === "destructive" || variant === "warning") && showCancelButton && cancel_ref.current) {
6934
+ e.preventDefault();
6935
+ cancel_ref.current.focus();
6936
+ }
6937
+ },
6938
+ children: [
6939
+ /* @__PURE__ */ jsxs("div", { className: "cls_confirm_dialog_body px-6 pt-7 pb-5", children: [
6940
+ /* @__PURE__ */ jsx(DialogPrimitive.Title, { className: "cls_confirm_dialog_title text-[17px] font-semibold text-foreground mb-2.5", children: title }),
6941
+ children ? /* @__PURE__ */ jsx(DialogPrimitive.Description, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: "cls_confirm_dialog_children text-sm text-muted-foreground leading-relaxed", children }) }) : description ? /* @__PURE__ */ jsx(DialogPrimitive.Description, { className: "cls_confirm_dialog_description text-sm text-muted-foreground leading-relaxed", children: description }) : null
6942
+ ] }),
6943
+ /* @__PURE__ */ jsx("div", { className: "cls_confirm_dialog_separator border-t border-border" }),
6944
+ /* @__PURE__ */ jsxs("div", { className: "cls_confirm_dialog_actions px-6 py-4 flex justify-end gap-3", children: [
6945
+ showCancelButton && /* @__PURE__ */ jsx(
6946
+ Button,
6947
+ {
6948
+ ref: cancel_ref,
6949
+ type: "button",
6950
+ className: "cls_confirm_cancel_button focus-visible:ring-0 focus-visible:ring-offset-0",
6951
+ variant: "outline",
6952
+ onClick: handleCancel,
6953
+ disabled: actionButtonLoading,
6954
+ style: cancelButtonStyles,
6955
+ children: cancelButtonText
6956
+ }
6957
+ ),
6958
+ showActionButton && /* @__PURE__ */ jsxs(
6959
+ Button,
6960
+ {
6961
+ type: "button",
6962
+ className: "cls_confirm_action_button",
6963
+ variant: resolved_action_button_variant,
6964
+ onClick: handleConfirm,
6965
+ disabled: actionButtonLoading || actionButtonDisabled,
6966
+ style: actionButtonStyles,
6967
+ children: [
6968
+ actionButtonLoading && /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }),
6969
+ actionButtonText
6970
+ ]
6971
+ }
6972
+ )
6973
+ ] })
6974
+ ]
6975
+ }
6976
+ )
6977
+ ] }) });
6978
+ }
6845
6979
  return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogPortal, { children: [
6846
6980
  /* @__PURE__ */ jsx(
6847
6981
  DialogOverlay,
@@ -6916,10 +7050,17 @@ function HazoUiDialog({
6916
7050
  style: headerStyles,
6917
7051
  children: [
6918
7052
  /* @__PURE__ */ jsx(DialogTitle, { className: titleClassName, children: title }),
6919
- description && /* @__PURE__ */ jsx(DialogDescription, { className: cn(
6920
- descriptionClassName,
6921
- has_merged_variant_header && "italic text-xs mt-1"
6922
- ), children: description })
7053
+ description && /* @__PURE__ */ jsx(
7054
+ DialogDescription,
7055
+ {
7056
+ className: cn(
7057
+ descriptionClassName,
7058
+ has_merged_variant_header && "italic text-xs mt-1"
7059
+ ),
7060
+ style: headerBar ? { opacity: 0.8 } : void 0,
7061
+ children: description
7062
+ }
7063
+ )
6923
7064
  ]
6924
7065
  }
6925
7066
  )
@@ -6985,7 +7126,7 @@ function HazoUiDialog({
6985
7126
  DialogPrimitive.Close,
6986
7127
  {
6987
7128
  className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",
6988
- style: headerBar ? { color: "white" } : finalHeaderTextColor ? { color: finalHeaderTextColor } : void 0,
7129
+ style: headerBar ? { color: "var(--dialog-header-bar-fg)" } : finalHeaderTextColor ? { color: finalHeaderTextColor } : void 0,
6989
7130
  children: [
6990
7131
  /* @__PURE__ */ jsx(X, { className: "h-4 w-4" }),
6991
7132
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
@@ -6997,28 +7138,6 @@ function HazoUiDialog({
6997
7138
  )
6998
7139
  ] }) });
6999
7140
  }
7000
- var CONFIRM_VARIANT_PRESETS = {
7001
- destructive: {
7002
- accent_color: "rgb(220, 38, 38)",
7003
- confirm_button_color: "rgb(220, 38, 38)",
7004
- overlay_class_name: "bg-red-950/50"
7005
- },
7006
- warning: {
7007
- accent_color: "rgb(245, 158, 11)",
7008
- confirm_button_color: "rgb(245, 158, 11)",
7009
- overlay_class_name: "bg-yellow-950/50"
7010
- },
7011
- info: {
7012
- accent_color: "rgb(37, 99, 235)",
7013
- confirm_button_color: "rgb(37, 99, 235)",
7014
- overlay_class_name: "bg-blue-950/50"
7015
- },
7016
- success: {
7017
- accent_color: "rgb(22, 163, 74)",
7018
- confirm_button_color: "rgb(22, 163, 74)",
7019
- overlay_class_name: "bg-green-950/50"
7020
- }
7021
- };
7022
7141
  function HazoUiConfirmDialog({
7023
7142
  open,
7024
7143
  onOpenChange,
@@ -7031,126 +7150,37 @@ function HazoUiConfirmDialog({
7031
7150
  showCancelButton = true,
7032
7151
  onConfirm,
7033
7152
  onCancel,
7034
- loading: external_loading,
7153
+ loading,
7035
7154
  disabled = false,
7036
7155
  accentColor,
7037
7156
  confirmButtonColor,
7038
7157
  openAnimation = "zoom",
7039
7158
  closeAnimation = "zoom"
7040
7159
  }) {
7041
- const [internal_loading, set_internal_loading] = React26.useState(false);
7042
- const config = get_hazo_ui_config();
7043
- const variant_preset = variant !== "default" ? CONFIRM_VARIANT_PRESETS[variant] : void 0;
7044
- const is_loading = external_loading ?? internal_loading;
7045
- const resolved_confirm_label = confirmLabel ?? (showCancelButton ? "Confirm" : "OK");
7046
- const resolved_accent_color = accentColor ?? variant_preset?.accent_color ?? "rgb(148, 163, 184)";
7047
- const resolved_confirm_button_color = confirmButtonColor ?? variant_preset?.confirm_button_color ?? config.submit_button_background_color;
7048
- const cancel_button_styles = {
7049
- ...config.cancel_button_background_color && { backgroundColor: config.cancel_button_background_color },
7050
- ...config.cancel_button_text_color && { color: config.cancel_button_text_color },
7051
- ...config.cancel_button_border_color && { borderColor: config.cancel_button_border_color }
7052
- };
7053
- const confirm_button_styles = {
7054
- ...resolved_confirm_button_color && {
7055
- backgroundColor: resolved_confirm_button_color,
7056
- borderColor: resolved_confirm_button_color,
7057
- color: "white"
7058
- }
7059
- };
7060
- const animation_classes = resolve_animation_classes(openAnimation, closeAnimation);
7061
- const handle_confirm = async () => {
7062
- try {
7063
- const result = onConfirm();
7064
- if (result instanceof Promise) {
7065
- set_internal_loading(true);
7066
- await result;
7067
- }
7068
- onOpenChange(false);
7069
- } catch {
7070
- } finally {
7071
- set_internal_loading(false);
7160
+ const resolved_accent_color = confirmButtonColor ?? accentColor;
7161
+ return /* @__PURE__ */ jsx(
7162
+ HazoUiDialog,
7163
+ {
7164
+ kind: "confirm",
7165
+ open,
7166
+ onOpenChange,
7167
+ title,
7168
+ description,
7169
+ variant,
7170
+ actionButtonText: confirmLabel,
7171
+ cancelButtonText: cancelLabel,
7172
+ showCancelButton,
7173
+ onConfirm,
7174
+ onCancel,
7175
+ actionButtonLoading: loading,
7176
+ actionButtonDisabled: disabled,
7177
+ accentColor: resolved_accent_color,
7178
+ openAnimation,
7179
+ closeAnimation,
7180
+ closeOnConfirm: true,
7181
+ children
7072
7182
  }
7073
- };
7074
- const handle_cancel = () => {
7075
- onCancel?.();
7076
- onOpenChange(false);
7077
- };
7078
- const cancel_ref = React26.useRef(null);
7079
- return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogPortal, { children: [
7080
- /* @__PURE__ */ jsx(
7081
- DialogOverlay,
7082
- {
7083
- className: cn(
7084
- "cls_confirm_dialog_overlay",
7085
- variant_preset?.overlay_class_name
7086
- ),
7087
- style: { backdropFilter: "blur(4px)" }
7088
- }
7089
- ),
7090
- /* @__PURE__ */ jsxs(
7091
- DialogPrimitive.Content,
7092
- {
7093
- className: cn(
7094
- "cls_confirm_dialog_content",
7095
- "fixed left-[50%] top-[50%] z-50",
7096
- "translate-x-[-50%] translate-y-[-50%]",
7097
- "bg-background shadow-lg",
7098
- "duration-200",
7099
- animation_classes,
7100
- "overflow-hidden"
7101
- ),
7102
- style: {
7103
- width: "min(90vw, 420px)",
7104
- borderRadius: "12px",
7105
- borderTop: `4px solid ${resolved_accent_color}`,
7106
- boxShadow: "0 20px 60px rgba(0,0,0,0.15)",
7107
- outline: "none"
7108
- },
7109
- onOpenAutoFocus: (e) => {
7110
- if ((variant === "destructive" || variant === "warning") && showCancelButton && cancel_ref.current) {
7111
- e.preventDefault();
7112
- cancel_ref.current.focus();
7113
- }
7114
- },
7115
- children: [
7116
- /* @__PURE__ */ jsxs("div", { className: "cls_confirm_dialog_body px-6 pt-7 pb-5", children: [
7117
- /* @__PURE__ */ jsx(DialogPrimitive.Title, { className: "cls_confirm_dialog_title text-[17px] font-semibold text-foreground mb-2.5", children: title }),
7118
- children ? /* @__PURE__ */ jsx(DialogPrimitive.Description, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: "cls_confirm_dialog_children text-sm text-muted-foreground leading-relaxed", children }) }) : description ? /* @__PURE__ */ jsx(DialogPrimitive.Description, { className: "cls_confirm_dialog_description text-sm text-muted-foreground leading-relaxed", children: description }) : null
7119
- ] }),
7120
- /* @__PURE__ */ jsx("div", { className: "cls_confirm_dialog_separator border-t border-border" }),
7121
- /* @__PURE__ */ jsxs("div", { className: "cls_confirm_dialog_actions px-6 py-4 flex justify-end gap-3", children: [
7122
- showCancelButton && /* @__PURE__ */ jsx(
7123
- Button,
7124
- {
7125
- ref: cancel_ref,
7126
- type: "button",
7127
- className: "cls_confirm_cancel_button focus-visible:ring-0 focus-visible:ring-offset-0",
7128
- variant: "outline",
7129
- onClick: handle_cancel,
7130
- disabled: is_loading,
7131
- style: cancel_button_styles,
7132
- children: cancelLabel
7133
- }
7134
- ),
7135
- /* @__PURE__ */ jsxs(
7136
- Button,
7137
- {
7138
- type: "button",
7139
- className: "cls_confirm_action_button",
7140
- onClick: handle_confirm,
7141
- disabled: is_loading || disabled,
7142
- style: confirm_button_styles,
7143
- children: [
7144
- is_loading && /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }),
7145
- resolved_confirm_label
7146
- ]
7147
- }
7148
- )
7149
- ] })
7150
- ]
7151
- }
7152
- )
7153
- ] }) });
7183
+ );
7154
7184
  }
7155
7185
  var Slider = React26.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(
7156
7186
  SliderPrimitive.Root,
@@ -11382,7 +11412,174 @@ var ThemeToggle = React26.forwardRef(
11382
11412
  }
11383
11413
  );
11384
11414
  ThemeToggle.displayName = "ThemeToggle";
11415
+ function Logo({
11416
+ logoUrl,
11417
+ logoUrlDark,
11418
+ appTitle,
11419
+ href,
11420
+ height = 28,
11421
+ className,
11422
+ imgClassName
11423
+ }) {
11424
+ const alt = appTitle ?? "Logo";
11425
+ let content = null;
11426
+ if (logoUrl) {
11427
+ content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
11428
+ /* @__PURE__ */ jsx(
11429
+ "img",
11430
+ {
11431
+ src: logoUrl,
11432
+ alt,
11433
+ height,
11434
+ style: { height },
11435
+ className: cn("object-contain", logoUrlDark && "dark:hidden", imgClassName)
11436
+ }
11437
+ ),
11438
+ logoUrlDark ? /* @__PURE__ */ jsx(
11439
+ "img",
11440
+ {
11441
+ src: logoUrlDark,
11442
+ alt,
11443
+ height,
11444
+ style: { height },
11445
+ className: cn("hidden object-contain dark:block", imgClassName)
11446
+ }
11447
+ ) : null
11448
+ ] });
11449
+ } else if (appTitle) {
11450
+ content = /* @__PURE__ */ jsx("span", { className: "font-semibold text-navbar-fg", children: appTitle });
11451
+ }
11452
+ if (content === null) return /* @__PURE__ */ jsx(Fragment$1, {});
11453
+ const resolvedHref = safeHref(href);
11454
+ if (resolvedHref) {
11455
+ return /* @__PURE__ */ jsx("a", { href: resolvedHref, className: cn("inline-flex items-center gap-2", className), children: content });
11456
+ }
11457
+ return /* @__PURE__ */ jsx("div", { className: cn("inline-flex items-center gap-2", className), children: content });
11458
+ }
11459
+ function AppHeader({ identity, homeHref, navItems, actions, className }) {
11460
+ return /* @__PURE__ */ jsxs(
11461
+ "header",
11462
+ {
11463
+ "aria-label": "Application header",
11464
+ className: cn(
11465
+ "flex w-full items-center justify-between gap-4 border-b bg-navbar text-navbar-fg border-navbar-border px-4 py-2.5",
11466
+ className
11467
+ ),
11468
+ children: [
11469
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
11470
+ /* @__PURE__ */ jsx(
11471
+ Logo,
11472
+ {
11473
+ logoUrl: identity?.logoUrl,
11474
+ logoUrlDark: identity?.logoUrlDark,
11475
+ appTitle: identity?.appTitle,
11476
+ href: homeHref
11477
+ }
11478
+ ),
11479
+ navItems
11480
+ ] }),
11481
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-4", children: actions })
11482
+ ]
11483
+ }
11484
+ );
11485
+ }
11486
+ function AppFooter({ variant, footer, identity, className }) {
11487
+ const cfg = footer ?? identity?.footer?.[variant];
11488
+ if (variant === "app") {
11489
+ const links = cfg?.columns?.[0]?.links;
11490
+ return /* @__PURE__ */ jsxs(
11491
+ "footer",
11492
+ {
11493
+ className: cn(
11494
+ "flex w-full items-center justify-between gap-4 border-t bg-footer-app text-footer-app-fg border-footer-app-border px-4 py-2 text-sm",
11495
+ className
11496
+ ),
11497
+ children: [
11498
+ /* @__PURE__ */ jsx("div", { className: "text-footer-app-fg-muted", children: cfg?.copyright }),
11499
+ links && links.length > 0 ? /* @__PURE__ */ jsx("div", { className: "flex items-center gap-4", children: links.map((link, i) => /* @__PURE__ */ jsx(
11500
+ "a",
11501
+ {
11502
+ href: safeHref(link.href),
11503
+ className: "text-footer-app-fg-muted hover:text-footer-app-fg",
11504
+ children: link.label
11505
+ },
11506
+ `${link.href}-${i}`
11507
+ )) }) : null
11508
+ ]
11509
+ }
11510
+ );
11511
+ }
11512
+ const showBrandRow = Boolean(identity?.logoUrl || identity?.appTitle);
11513
+ return /* @__PURE__ */ jsxs(
11514
+ "footer",
11515
+ {
11516
+ className: cn(
11517
+ "w-full border-t bg-footer-public text-footer-public-fg border-footer-public-border px-6 py-10",
11518
+ className
11519
+ ),
11520
+ children: [
11521
+ showBrandRow ? /* @__PURE__ */ jsx("div", { className: "mb-8", children: /* @__PURE__ */ jsx(
11522
+ Logo,
11523
+ {
11524
+ logoUrl: identity?.logoUrl,
11525
+ logoUrlDark: identity?.logoUrlDark,
11526
+ appTitle: identity?.appTitle
11527
+ }
11528
+ ) }) : null,
11529
+ cfg?.columns && cfg.columns.length > 0 ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-8 md:grid-cols-4", children: cfg.columns.map((column, idx) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
11530
+ column.heading ? /* @__PURE__ */ jsx("div", { className: "font-medium text-footer-public-fg", children: column.heading }) : null,
11531
+ column.links.map((link, i) => /* @__PURE__ */ jsx(
11532
+ "a",
11533
+ {
11534
+ href: safeHref(link.href),
11535
+ className: "text-footer-public-fg-muted hover:text-footer-public-fg",
11536
+ children: link.label
11537
+ },
11538
+ `${link.href}-${i}`
11539
+ ))
11540
+ ] }, column.heading ?? idx)) }) : null,
11541
+ /* @__PURE__ */ jsxs("div", { className: "mt-8 flex flex-wrap items-center justify-between gap-4", children: [
11542
+ /* @__PURE__ */ jsx("div", { className: "text-sm text-footer-public-fg-muted", children: cfg?.copyright }),
11543
+ cfg?.social ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
11544
+ cfg.social.github ? /* @__PURE__ */ jsx(
11545
+ "a",
11546
+ {
11547
+ href: safeHref(cfg.social.github),
11548
+ className: "text-footer-public-fg-muted hover:text-footer-public-fg",
11549
+ children: "GitHub"
11550
+ }
11551
+ ) : null,
11552
+ cfg.social.twitter ? /* @__PURE__ */ jsx(
11553
+ "a",
11554
+ {
11555
+ href: safeHref(cfg.social.twitter),
11556
+ className: "text-footer-public-fg-muted hover:text-footer-public-fg",
11557
+ children: "Twitter"
11558
+ }
11559
+ ) : null,
11560
+ cfg.social.linkedin ? /* @__PURE__ */ jsx(
11561
+ "a",
11562
+ {
11563
+ href: safeHref(cfg.social.linkedin),
11564
+ className: "text-footer-public-fg-muted hover:text-footer-public-fg",
11565
+ children: "LinkedIn"
11566
+ }
11567
+ ) : null,
11568
+ cfg.social.website ? /* @__PURE__ */ jsx(
11569
+ "a",
11570
+ {
11571
+ href: safeHref(cfg.social.website),
11572
+ className: "text-footer-public-fg-muted hover:text-footer-public-fg",
11573
+ children: "Website"
11574
+ }
11575
+ ) : null
11576
+ ] }) : null
11577
+ ] })
11578
+ ]
11579
+ }
11580
+ );
11581
+ }
11385
11582
 
11386
- export { ANIMATION_PRESETS, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CELEBRATION_GRADIENT, Calendar, CanvasTextToolbar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CelebrationProvider, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, CommandNodeExtension, CommandPill, CommandPopover, DateRangeSelector, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, ErrorBanner, ErrorPage, FunnelChart, HazoContextProvider, HazoThemeProvider, HazoUiConfirmDialog, HazoUiDialog, DialogClose as HazoUiDialogClose, DialogContent as HazoUiDialogContent, DialogDescription as HazoUiDialogDescription, DialogFooter as HazoUiDialogFooter, DialogHeader as HazoUiDialogHeader, DialogOverlay as HazoUiDialogOverlay, DialogPortal as HazoUiDialogPortal, Dialog as HazoUiDialogRoot, DialogTitle as HazoUiDialogTitle, DialogTrigger as HazoUiDialogTrigger, HazoUiEtaProgress, HazoUiFlexInput, HazoUiFlexRadio, HazoUiImageCropper, HazoUiImageCropperDialog, HazoUiKanban, HazoUiKanbanFilter, HazoUiMemoryDropdown, HazoUiMultiFilterDialog, HazoUiMultiSortDialog, HazoUiPillRadio, HazoUiProgressBar, HazoUiRte, HazoUiTable, HazoUiTextarea, HazoUiTextbox, HazoUiToaster, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputAffix, InverseSparkline, Label3 as Label, LoadingTimeout, MarkdownEditor, NotificationCountBadge, NotificationItem, NotificationPanel, Popover, PopoverContent, PopoverTrigger, ProgressiveImage, RadioGroup, RadioGroupItem, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Command as ShadcnCommand, CommandEmpty as ShadcnCommandEmpty, CommandGroup as ShadcnCommandGroup, CommandInput as ShadcnCommandInput, CommandItem as ShadcnCommandItem, CommandList as ShadcnCommandList, Skeleton, SkeletonBar, SkeletonCircle, SkeletonGroup, SkeletonRect, Slider, Sparkline, Spinner, StackedBars, Switch, Table2 as Table, TableBody, TableCaption, TableCell2 as TableCell, TableFooter, TableHead, TableHeader2 as TableHeader, TableRow2 as TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeScript, ThemeToggle, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, applyKanbanFilter, buttonGroupVariants, celebrate, cn, computeEta, create_command_suggestion_extension, easeToward, errorToast, format_num, generateUUID, get_hazo_ui_config, get_logger, median, parse_commands_from_text, pick_x_label_indices, reset_hazo_ui_config, resolve_animation_classes, set_hazo_ui_config, set_logger, successToast, text_to_tiptap_content, toggleVariants, upsertEntry as upsertMemoryEntry, useClickOutside, useCopyToClipboard, useDebounce, useErrorDisplay, useEtaProgress, useFullscreen, useIsMobile, useLoadingState, useLocalStorage, useMediaQuery, useSessionStorage, useTheme, useViewport, useWakeLock, use_fullscreen, use_wake_lock };
11583
+ export { ANIMATION_PRESETS, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AppFooter, AppHeader, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CELEBRATION_GRADIENT, Calendar, CanvasTextToolbar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CelebrationProvider, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, CommandNodeExtension, CommandPill, CommandPopover, DateRangeSelector, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, ErrorBanner, ErrorPage, FunnelChart, HazoContextProvider, HazoThemeProvider, HazoUiConfirmDialog, HazoUiDialog, DialogClose as HazoUiDialogClose, DialogContent as HazoUiDialogContent, DialogDescription as HazoUiDialogDescription, DialogFooter as HazoUiDialogFooter, DialogHeader as HazoUiDialogHeader, DialogOverlay as HazoUiDialogOverlay, DialogPortal as HazoUiDialogPortal, Dialog as HazoUiDialogRoot, DialogTitle as HazoUiDialogTitle, DialogTrigger as HazoUiDialogTrigger, HazoUiEtaProgress, HazoUiFlexInput, HazoUiFlexRadio, HazoUiImageCropper, HazoUiImageCropperDialog, HazoUiKanban, HazoUiKanbanFilter, HazoUiMemoryDropdown, HazoUiMultiFilterDialog, HazoUiMultiSortDialog, HazoUiPillRadio, HazoUiProgressBar, HazoUiRte, HazoUiTable, HazoUiTextarea, HazoUiTextbox, HazoUiToaster, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputAffix, InverseSparkline, Label3 as Label, LoadingTimeout, Logo, MarkdownEditor, NotificationCountBadge, NotificationItem, NotificationPanel, Popover, PopoverContent, PopoverTrigger, ProgressiveImage, RadioGroup, RadioGroupItem, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Command as ShadcnCommand, CommandEmpty as ShadcnCommandEmpty, CommandGroup as ShadcnCommandGroup, CommandInput as ShadcnCommandInput, CommandItem as ShadcnCommandItem, CommandList as ShadcnCommandList, Skeleton, SkeletonBar, SkeletonCircle, SkeletonGroup, SkeletonRect, Slider, Sparkline, Spinner, StackedBars, Switch, Table2 as Table, TableBody, TableCaption, TableCell2 as TableCell, TableFooter, TableHead, TableHeader2 as TableHeader, TableRow2 as TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeScript, ThemeToggle, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, applyKanbanFilter, buttonGroupVariants, celebrate, cn, computeEta, create_command_suggestion_extension, easeToward, errorToast, format_num, generateUUID, get_hazo_ui_config, get_logger, median, parse_commands_from_text, pick_x_label_indices, reset_hazo_ui_config, resolve_animation_classes, safeHref, set_hazo_ui_config, set_logger, successToast, text_to_tiptap_content, toggleVariants, upsertEntry as upsertMemoryEntry, useClickOutside, useCopyToClipboard, useDebounce, useErrorDisplay, useEtaProgress, useFullscreen, useIsMobile, useLoadingState, useLocalStorage, useMediaQuery, useSessionStorage, useTheme, useViewport, useWakeLock, use_fullscreen, use_wake_lock };
11387
11584
  //# sourceMappingURL=index.js.map
11388
11585
  //# sourceMappingURL=index.js.map