@sustaina/shared-ui 1.36.0 → 1.37.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
@@ -1,10 +1,12 @@
1
1
  'use strict';
2
2
 
3
+ var React25 = require('react');
4
+ var reactRouter = require('@tanstack/react-router');
5
+ var zustand = require('zustand');
3
6
  var clsx2 = require('clsx');
4
7
  var tailwindMerge = require('tailwind-merge');
5
8
  var jsxRuntime = require('react/jsx-runtime');
6
9
  var AccordionPrimitive = require('@radix-ui/react-accordion');
7
- var React25 = require('react');
8
10
  var lucideReact = require('lucide-react');
9
11
  var reactDom = require('react-dom');
10
12
  var SelectPrimitive = require('@radix-ui/react-select');
@@ -20,7 +22,6 @@ var reactTable = require('@tanstack/react-table');
20
22
  var SheetPrimitive = require('@radix-ui/react-dialog');
21
23
  var reactI18next = require('react-i18next');
22
24
  var i18n = require('i18next');
23
- var zustand = require('zustand');
24
25
  var StarterKit = require('@tiptap/starter-kit');
25
26
  var react = require('@tiptap/react');
26
27
  var ReactDOM = require('react-dom/client');
@@ -82,9 +83,9 @@ function _interopNamespace(e) {
82
83
  return Object.freeze(n);
83
84
  }
84
85
 
86
+ var React25__namespace = /*#__PURE__*/_interopNamespace(React25);
85
87
  var clsx2__default = /*#__PURE__*/_interopDefault(clsx2);
86
88
  var AccordionPrimitive__namespace = /*#__PURE__*/_interopNamespace(AccordionPrimitive);
87
- var React25__namespace = /*#__PURE__*/_interopNamespace(React25);
88
89
  var SelectPrimitive__namespace = /*#__PURE__*/_interopNamespace(SelectPrimitive);
89
90
  var LabelPrimitive__namespace = /*#__PURE__*/_interopNamespace(LabelPrimitive);
90
91
  var PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespace(PopoverPrimitive);
@@ -265,6 +266,82 @@ function formatISODate(isoDate, format5 = "d/m/Y H:i") {
265
266
  return partKey ? parts[partKey] : match;
266
267
  });
267
268
  }
269
+ function useSafeBlocker({
270
+ shouldBlockFn,
271
+ enableBeforeUnload = true,
272
+ disabled = false,
273
+ withResolver = false
274
+ }) {
275
+ const router = reactRouter.useRouter({ warn: false });
276
+ const [resolver, setResolver] = React25.useState({
277
+ status: "idle",
278
+ proceed: void 0,
279
+ reset: void 0
280
+ });
281
+ React25.useEffect(() => {
282
+ if (disabled || !router?.history?.block) {
283
+ return;
284
+ }
285
+ return router.history.block({
286
+ enableBeforeUnload,
287
+ blockerFn: async () => {
288
+ const shouldBlock = await shouldBlockFn();
289
+ if (!withResolver) {
290
+ return shouldBlock;
291
+ }
292
+ if (!shouldBlock) {
293
+ return false;
294
+ }
295
+ const canNavigate = await new Promise((resolve) => {
296
+ setResolver({
297
+ status: "blocked",
298
+ proceed: () => resolve(false),
299
+ reset: () => resolve(true)
300
+ });
301
+ });
302
+ setResolver({
303
+ status: "idle",
304
+ proceed: void 0,
305
+ reset: void 0
306
+ });
307
+ return canNavigate;
308
+ }
309
+ });
310
+ }, [disabled, enableBeforeUnload, router, shouldBlockFn, withResolver]);
311
+ React25.useEffect(() => {
312
+ if (disabled || router?.history || typeof window === "undefined") {
313
+ return;
314
+ }
315
+ const shouldEnable = enableBeforeUnload;
316
+ if (!shouldEnable) {
317
+ return;
318
+ }
319
+ const handler = (event) => {
320
+ const shouldBlock = typeof shouldEnable === "function" ? shouldEnable() : shouldEnable;
321
+ if (!shouldBlock) {
322
+ return;
323
+ }
324
+ event.preventDefault();
325
+ event.returnValue = "";
326
+ };
327
+ window.addEventListener("beforeunload", handler, { capture: true });
328
+ return () => window.removeEventListener("beforeunload", handler, { capture: true });
329
+ }, [disabled, enableBeforeUnload, router]);
330
+ return resolver;
331
+ }
332
+ var useDraftGuardStore = zustand.create((set) => ({
333
+ isDirty: false,
334
+ source: null,
335
+ isInitialized: false,
336
+ markDirty: (source) => set((state) => {
337
+ if (!state.isInitialized || !source) {
338
+ return state;
339
+ }
340
+ return { ...state, isDirty: true, source };
341
+ }),
342
+ clearDraft: () => set({ isDirty: false, source: null }),
343
+ markInitialized: () => set({ isInitialized: true })
344
+ }));
268
345
  function cn(...args) {
269
346
  return tailwindMerge.twMerge(clsx2.clsx(args));
270
347
  }
@@ -3234,6 +3311,7 @@ var LookupSelect = ({
3234
3311
  }) => {
3235
3312
  const [inputValue, setInputValue] = React25.useState("");
3236
3313
  const inputRef = React25.useRef(null);
3314
+ const [inputFocused, setInputFocused] = React25.useState(false);
3237
3315
  const [suggestions, setSuggestions] = React25.useState([]);
3238
3316
  const [optionLabels, setOptionLabels] = React25.useState({});
3239
3317
  const [loading, setLoading] = React25.useState(false);
@@ -3284,8 +3362,6 @@ var LookupSelect = ({
3284
3362
  onChange([trimmed]);
3285
3363
  }
3286
3364
  setInputValue("");
3287
- setSuggestions([]);
3288
- setIsDropdownOpen(false);
3289
3365
  },
3290
3366
  [value, onChange, maxTags, multiple]
3291
3367
  );
@@ -3294,12 +3370,15 @@ var LookupSelect = ({
3294
3370
  if (index < 0) return;
3295
3371
  const newTags = value.filter((_, i) => i !== index);
3296
3372
  onChange(newTags);
3373
+ setIsDropdownOpen(false);
3374
+ setInputFocused(false);
3297
3375
  },
3298
3376
  [value, onChange]
3299
3377
  );
3300
3378
  const handleClear = React25.useCallback(() => {
3301
3379
  setInputValue("");
3302
3380
  setSuggestions([]);
3381
+ setInputFocused(false);
3303
3382
  setIsDropdownOpen(false);
3304
3383
  setFetchError(null);
3305
3384
  if (onClear) onClear();
@@ -3315,7 +3394,10 @@ var LookupSelect = ({
3315
3394
  }, 100);
3316
3395
  } else {
3317
3396
  inputRef.current?.blur();
3397
+ setInputFocused(false);
3398
+ setIsDropdownOpen(false);
3318
3399
  }
3400
+ inputRef.current.value = "";
3319
3401
  },
3320
3402
  [addTag, multiple, upsertOptionLabels]
3321
3403
  );
@@ -3358,16 +3440,16 @@ var LookupSelect = ({
3358
3440
  });
3359
3441
  }, [dropdownPortalElement]);
3360
3442
  React25.useEffect(() => {
3361
- if (!fetchSuggestions) return;
3443
+ if (!fetchSuggestions || !inputFocused) return;
3362
3444
  if (fetchDelayRef.current) {
3363
3445
  clearTimeout(fetchDelayRef.current);
3364
3446
  }
3365
3447
  const query = inputValue.trim();
3366
3448
  if (!query) {
3367
- setSuggestions([]);
3368
- setIsDropdownOpen(false);
3369
3449
  setLoading(false);
3370
3450
  setFetchError(null);
3451
+ setSuggestions([]);
3452
+ setIsDropdownOpen(false);
3371
3453
  return;
3372
3454
  }
3373
3455
  setLoading(true);
@@ -3397,7 +3479,7 @@ var LookupSelect = ({
3397
3479
  clearTimeout(fetchDelayRef.current);
3398
3480
  }
3399
3481
  };
3400
- }, [inputValue, fetchSuggestions, suggestionDebounce, upsertOptionLabels]);
3482
+ }, [inputValue, fetchSuggestions, suggestionDebounce, upsertOptionLabels, inputFocused]);
3401
3483
  React25.useEffect(() => {
3402
3484
  if (!fetchSuggestions) return;
3403
3485
  if (value.length === 0) return;
@@ -3414,6 +3496,7 @@ var LookupSelect = ({
3414
3496
  if (containerRef.current?.contains(target)) return;
3415
3497
  if (dropdownContentRef.current?.contains(target)) return;
3416
3498
  setIsDropdownOpen(false);
3499
+ setInputFocused(false);
3417
3500
  };
3418
3501
  document.addEventListener("mousedown", handleDocumentClick);
3419
3502
  return () => {
@@ -3435,7 +3518,7 @@ var LookupSelect = ({
3435
3518
  window.removeEventListener("resize", handleReposition);
3436
3519
  window.removeEventListener("scroll", handleReposition, true);
3437
3520
  };
3438
- }, [dropdownPortalElement, isDropdownOpen, updateDropdownPosition]);
3521
+ }, [dropdownPortalElement, isDropdownOpen, updateDropdownPosition, value]);
3439
3522
  React25.useEffect(() => {
3440
3523
  if (suggestions.length === 0) {
3441
3524
  setActiveSuggestionIndex(-1);
@@ -3490,7 +3573,7 @@ var LookupSelect = ({
3490
3573
  return /* @__PURE__ */ jsxRuntime.jsxs(
3491
3574
  "span",
3492
3575
  {
3493
- className: "flex items-center gap-1 rounded-lg border border-[#f0f0f0] bg-[#f9f9f9] px-2 py-1 my-1 text-sm text-inherit max-w-full wrap-break-word",
3576
+ className: "flex items-center gap-1 rounded-lg border border-sus-secondary-gray-3 bg-sus-secondary-gray-2 px-2 py-1 my-1 text-sm text-inherit max-w-full wrap-break-word",
3494
3577
  children: [
3495
3578
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "whitespace-pre-wrap break-all", children: label }),
3496
3579
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -3518,9 +3601,7 @@ var LookupSelect = ({
3518
3601
  onChange: (e) => setInputValue(e.target.value),
3519
3602
  onKeyDown: handleKeyDown,
3520
3603
  onFocus: () => {
3521
- if (suggestions.length > 0 && !fetchError) {
3522
- setIsDropdownOpen(true);
3523
- }
3604
+ setInputFocused(true);
3524
3605
  },
3525
3606
  hidden: !multiple && selectedLabel !== void 0,
3526
3607
  placeholder: value.length === 0 && resolvedPlaceholder || "",
@@ -5774,151 +5855,6 @@ function DialogDescription2({
5774
5855
  // src/components/dialog-alert/lib/constants.ts
5775
5856
  var DIALOG_ALERT_I18N_SUBNAMESPACE = "dialog_alert";
5776
5857
  var i18nPrefix = `translation:${DIALOG_ALERT_I18N_SUBNAMESPACE}.`;
5777
-
5778
- // src/components/dialog-alert/locale/default.ts
5779
- var defaultResource = {
5780
- sharedui: {
5781
- translation: {
5782
- [DIALOG_ALERT_I18N_SUBNAMESPACE]: {
5783
- ok: "OK",
5784
- cancel: "Cancel",
5785
- close: "Close",
5786
- "success.saved": {
5787
- title: "Successfully",
5788
- description: "Data has been successfully saved"
5789
- },
5790
- "success.deleted": {
5791
- title: "Successfully",
5792
- description: "Data has been successfully deleted"
5793
- },
5794
- "success.removed": {
5795
- title: "Successfully",
5796
- description: "Data has been successfully removed"
5797
- },
5798
- "error.api_db_error": {
5799
- title: "API/Database Error",
5800
- description: "Failed to connect to the system. Please check API or database connection."
5801
- },
5802
- "error.permission_denied": {
5803
- title: "Permission Denied",
5804
- description: "You do not have permission to perform this action.",
5805
- confirm_text: "Discard"
5806
- },
5807
- "error.session_expired": {
5808
- title: "Session Expired",
5809
- description: "Your session has expired or you have been logged out. Please sign in again.",
5810
- confirm_text: "Logout"
5811
- },
5812
- "error.user_not_found": {
5813
- title: "User Not Found",
5814
- description: "The system could not locate the user account.",
5815
- confirm_text: "Logout"
5816
- },
5817
- "error.data_not_found": {
5818
- title: "Data Not Found",
5819
- description: "The data has already been deleted or does not exist in the system."
5820
- },
5821
- "error.data_restrict_editing": {
5822
- title: "Data Status Restricts Editing",
5823
- description: "Data status does not allow editing."
5824
- },
5825
- "error.network_timeout_error": {
5826
- title: "Network Error / Timeout",
5827
- description: "The system could not connect to the network or the request took too long to process."
5828
- },
5829
- "error.queue_full": {
5830
- title: "Queue Full",
5831
- description: "The notification queue has reached its limit. Please try again later."
5832
- },
5833
- "error.invalid_data_format": {
5834
- title: "Invalid Data Format",
5835
- description: "Data creation failed due to invalid or incorrectly formatted data."
5836
- },
5837
- "error.data_linked_to_system_data": {
5838
- title: "Data Linked to System Data",
5839
- description: "Cannot delete data because they are linked to existing system data."
5840
- },
5841
- "error.pending_workflow_conflict": {
5842
- title: "Pending Workflow Conflict ",
5843
- description: "The data is currently involved in a pending workflow or approval process and cannot be deactivated."
5844
- },
5845
- "error.invalid_incomplete_data": {
5846
- title: "Invalid or Incomplete Data",
5847
- description: "Data status cannot be changed due to incomplete or invalid information."
5848
- },
5849
- "error.client_side_error": {
5850
- title: "Client-Side Error",
5851
- description: "An error occurred on the client side. Please refresh the page or try again."
5852
- },
5853
- "error.system_limitation": {
5854
- title: "System Limitation",
5855
- description: "The search cannot be completed due to system limitations. Please simplify your query."
5856
- },
5857
- "error.timeout": {
5858
- title: "Timeout",
5859
- description: "Request failed due to a system error or timeout. Please try again."
5860
- },
5861
- "error.duplicate_data": {
5862
- title: "Duplicate Data",
5863
- description: "The data you entered already exists in the system."
5864
- },
5865
- "error.something_went_wrong": {
5866
- title: "Something Went Wrong",
5867
- description: "An unknown error occurred."
5868
- },
5869
- "confirm.delete": {
5870
- title: "Confirmation",
5871
- description: "Are you sure you want to delete this item?",
5872
- confirm_text: "Delete"
5873
- },
5874
- "confirm.inactive": {
5875
- title: "Confirmation",
5876
- description: "Are you sure you want to inactive this item?",
5877
- confirm_text: "Inactive"
5878
- },
5879
- "confirm.active": {
5880
- variant: "confirm-green",
5881
- title: "Confirmation",
5882
- description: "Are you sure you want to active this item?",
5883
- confirm_text: "Active"
5884
- },
5885
- "confirm.leave_page": {
5886
- title: "Confirmation",
5887
- description: "Unsaved changes. Do you want to leave this page?",
5888
- confirm_text: "Leave"
5889
- },
5890
- "confirm.reset_form": {
5891
- title: "Confirmation",
5892
- description: "Unsaved changes. If you continue, all changes will be lost.",
5893
- confirm_text: "Reset"
5894
- },
5895
- "confirm.remove": {
5896
- title: "Confirmation",
5897
- description: "Are you sure you want to remove this item?",
5898
- confirm_text: "Remove"
5899
- },
5900
- "confirm.logout": {
5901
- title: "Confirmation",
5902
- description: "Do you want to log out?",
5903
- confirm_text: "Logout"
5904
- }
5905
- }
5906
- }
5907
- }
5908
- };
5909
-
5910
- // src/components/dialog-alert/locale/i18n.ts
5911
- var instance = i18n__default.default.createInstance({
5912
- resources: defaultResource,
5913
- lng: "sharedui",
5914
- fallbackLng: "sharedui",
5915
- defaultNS: "translation",
5916
- interpolation: {
5917
- escapeValue: false
5918
- }
5919
- }).use(reactI18next.initReactI18next);
5920
- instance.init();
5921
- var i18n_default = instance;
5922
5858
  var titleColorVariant = {
5923
5859
  default: "",
5924
5860
  success: "text-sus-button-green-3",
@@ -6150,6 +6086,151 @@ var DIALOG_ALERT_TEMPLATES = {
6150
6086
  confirmText: "confirm.logout.confirm_text"
6151
6087
  }
6152
6088
  };
6089
+
6090
+ // src/components/dialog-alert/locale/default.ts
6091
+ var defaultResource = {
6092
+ sharedui: {
6093
+ translation: {
6094
+ [DIALOG_ALERT_I18N_SUBNAMESPACE]: {
6095
+ ok: "OK",
6096
+ cancel: "Cancel",
6097
+ close: "Close",
6098
+ "success.saved": {
6099
+ title: "Successfully",
6100
+ description: "Data has been successfully saved"
6101
+ },
6102
+ "success.deleted": {
6103
+ title: "Successfully",
6104
+ description: "Data has been successfully deleted"
6105
+ },
6106
+ "success.removed": {
6107
+ title: "Successfully",
6108
+ description: "Data has been successfully removed"
6109
+ },
6110
+ "error.api_db_error": {
6111
+ title: "API/Database Error",
6112
+ description: "Failed to connect to the system. Please check API or database connection."
6113
+ },
6114
+ "error.permission_denied": {
6115
+ title: "Permission Denied",
6116
+ description: "You do not have permission to perform this action.",
6117
+ confirm_text: "Discard"
6118
+ },
6119
+ "error.session_expired": {
6120
+ title: "Session Expired",
6121
+ description: "Your session has expired or you have been logged out. Please sign in again.",
6122
+ confirm_text: "Logout"
6123
+ },
6124
+ "error.user_not_found": {
6125
+ title: "User Not Found",
6126
+ description: "The system could not locate the user account.",
6127
+ confirm_text: "Logout"
6128
+ },
6129
+ "error.data_not_found": {
6130
+ title: "Data Not Found",
6131
+ description: "The data has already been deleted or does not exist in the system."
6132
+ },
6133
+ "error.data_restrict_editing": {
6134
+ title: "Data Status Restricts Editing",
6135
+ description: "Data status does not allow editing."
6136
+ },
6137
+ "error.network_timeout_error": {
6138
+ title: "Network Error / Timeout",
6139
+ description: "The system could not connect to the network or the request took too long to process."
6140
+ },
6141
+ "error.queue_full": {
6142
+ title: "Queue Full",
6143
+ description: "The notification queue has reached its limit. Please try again later."
6144
+ },
6145
+ "error.invalid_data_format": {
6146
+ title: "Invalid Data Format",
6147
+ description: "Data creation failed due to invalid or incorrectly formatted data."
6148
+ },
6149
+ "error.data_linked_to_system_data": {
6150
+ title: "Data Linked to System Data",
6151
+ description: "Cannot delete data because they are linked to existing system data."
6152
+ },
6153
+ "error.pending_workflow_conflict": {
6154
+ title: "Pending Workflow Conflict ",
6155
+ description: "The data is currently involved in a pending workflow or approval process and cannot be deactivated."
6156
+ },
6157
+ "error.invalid_incomplete_data": {
6158
+ title: "Invalid or Incomplete Data",
6159
+ description: "Data status cannot be changed due to incomplete or invalid information."
6160
+ },
6161
+ "error.client_side_error": {
6162
+ title: "Client-Side Error",
6163
+ description: "An error occurred on the client side. Please refresh the page or try again."
6164
+ },
6165
+ "error.system_limitation": {
6166
+ title: "System Limitation",
6167
+ description: "The search cannot be completed due to system limitations. Please simplify your query."
6168
+ },
6169
+ "error.timeout": {
6170
+ title: "Timeout",
6171
+ description: "Request failed due to a system error or timeout. Please try again."
6172
+ },
6173
+ "error.duplicate_data": {
6174
+ title: "Duplicate Data",
6175
+ description: "The data you entered already exists in the system."
6176
+ },
6177
+ "error.something_went_wrong": {
6178
+ title: "Something Went Wrong",
6179
+ description: "An unknown error occurred."
6180
+ },
6181
+ "confirm.delete": {
6182
+ title: "Confirmation",
6183
+ description: "Are you sure you want to delete this item?",
6184
+ confirm_text: "Delete"
6185
+ },
6186
+ "confirm.inactive": {
6187
+ title: "Confirmation",
6188
+ description: "Are you sure you want to inactive this item?",
6189
+ confirm_text: "Inactive"
6190
+ },
6191
+ "confirm.active": {
6192
+ variant: "confirm-green",
6193
+ title: "Confirmation",
6194
+ description: "Are you sure you want to active this item?",
6195
+ confirm_text: "Active"
6196
+ },
6197
+ "confirm.leave_page": {
6198
+ title: "Confirmation",
6199
+ description: "Unsaved changes. Do you want to leave this page?",
6200
+ confirm_text: "Leave"
6201
+ },
6202
+ "confirm.reset_form": {
6203
+ title: "Confirmation",
6204
+ description: "Unsaved changes. If you continue, all changes will be lost.",
6205
+ confirm_text: "Reset"
6206
+ },
6207
+ "confirm.remove": {
6208
+ title: "Confirmation",
6209
+ description: "Are you sure you want to remove this item?",
6210
+ confirm_text: "Remove"
6211
+ },
6212
+ "confirm.logout": {
6213
+ title: "Confirmation",
6214
+ description: "Do you want to log out?",
6215
+ confirm_text: "Logout"
6216
+ }
6217
+ }
6218
+ }
6219
+ }
6220
+ };
6221
+
6222
+ // src/components/dialog-alert/locale/i18n.ts
6223
+ var instance = i18n__default.default.createInstance({
6224
+ resources: defaultResource,
6225
+ lng: "sharedui",
6226
+ fallbackLng: "sharedui",
6227
+ defaultNS: "translation",
6228
+ interpolation: {
6229
+ escapeValue: false
6230
+ }
6231
+ }).use(reactI18next.initReactI18next);
6232
+ instance.init();
6233
+ var i18n_default = instance;
6153
6234
  var useDialogAlertStore = zustand.create((set, get) => ({
6154
6235
  open: false,
6155
6236
  dialogProps: {},
@@ -6202,7 +6283,7 @@ var DialogAlertProvider = ({ children, i18nResource, i18nLang }) => {
6202
6283
  return;
6203
6284
  }
6204
6285
  }, [i18nLang, i18nResource]);
6205
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6286
+ return /* @__PURE__ */ jsxRuntime.jsxs(reactI18next.I18nextProvider, { i18n: i18n_default, children: [
6206
6287
  children,
6207
6288
  /* @__PURE__ */ jsxRuntime.jsx(DialogAlert, { open, onOpenChange: setOpen, ...dialogProps })
6208
6289
  ] });
@@ -12049,6 +12130,7 @@ exports.stripNullishObject = stripNullishObject;
12049
12130
  exports.throttle = throttle;
12050
12131
  exports.tokenizeFormulaString = tokenizeFormulaString;
12051
12132
  exports.useControllableState = useControllableState_default;
12133
+ exports.useDraftGuardStore = useDraftGuardStore;
12052
12134
  exports.useFormField = useFormField;
12053
12135
  exports.useGridSettingsStore = useGridSettingsStore_default;
12054
12136
  exports.useHover = useHover_default;
@@ -12057,6 +12139,7 @@ exports.useIsomorphicLayoutEffect = useIsomorphicLayoutEffect;
12057
12139
  exports.useMediaQuery = useMediaQuery_default;
12058
12140
  exports.usePreventPageLeave = usePreventPageLeave_default;
12059
12141
  exports.usePreventPageLeaveStore = usePreventPageLeaveStore_default;
12142
+ exports.useSafeBlocker = useSafeBlocker;
12060
12143
  exports.useScreenSize = useScreenSize_default;
12061
12144
  exports.useSidebar = useSidebar;
12062
12145
  exports.useTruncated = useTruncated_default;