@dragonmastery/zinia-forms-core 0.3.13 → 0.3.16

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,4 +1,4 @@
1
- import { provide, ref, computed, unref, inject, getCurrentInstance, watch, reactive, nextTick, Teleport } from 'vue';
1
+ import { reactive, watch, provide, ref, computed, unref, inject, getCurrentInstance, nextTick, Teleport } from 'vue';
2
2
  import { z } from 'zod';
3
3
  import { jsxs, jsx, Fragment } from 'vue/jsx-runtime';
4
4
 
@@ -1612,7 +1612,16 @@ function useFormState(initialData, options) {
1612
1612
  isReady: !options?.hasFetchData,
1613
1613
  isLoading: !!options?.hasFetchData,
1614
1614
  loadError: null,
1615
- extraData: options?.extraData || {}
1615
+ extraData: options?.extraData || {},
1616
+ // Async cascading selection state
1617
+ fetchedOptions: {},
1618
+ loadingOptions: {},
1619
+ asyncCascadingParents: {},
1620
+ // Track child → parent relationships
1621
+ // Auto-population loading state
1622
+ loadingAutoPopulate: {},
1623
+ populatingFields: {}
1624
+ // Track which target fields are being populated
1616
1625
  });
1617
1626
  if (options?.calculationFn) {
1618
1627
  const reactiveUpdater = ReactiveUpdater.getInstance(options.storeName, options.debug || false);
@@ -2000,6 +2009,8 @@ function useForm(schema, options) {
2000
2009
  storeName: options.storeName,
2001
2010
  // Direct access to the reactive form data
2002
2011
  values: formState.state.data,
2012
+ // Direct access to full state (for async cascading selects and advanced features)
2013
+ state: formState.state,
2003
2014
  // Access to calculated values (now a computed property)
2004
2015
  get calculatedValues() {
2005
2016
  return formState.calculatedValues.value;
@@ -2094,6 +2105,137 @@ function useForm(schema, options) {
2094
2105
  swapArrayItemIds: (path, indexA, indexB) => swapArrayItemIds(formState.state, path, indexA, indexB),
2095
2106
  syncArrayItemIds: (path) => syncArrayItemIds(formState.state, path)
2096
2107
  };
2108
+ const getNestedValue = (obj, path) => {
2109
+ return path.split(".").reduce((current, key) => current?.[key], obj);
2110
+ };
2111
+ if (options.asyncCascadingSelects) {
2112
+ Object.entries(options.asyncCascadingSelects).forEach(([_key, config]) => {
2113
+ const { parentField, childField, fetchOptionsFn, clearOnParentChange = true } = config;
2114
+ formState.state.asyncCascadingParents[childField] = parentField;
2115
+ let abortController = null;
2116
+ const fetchOptions = async (parentValue) => {
2117
+ if (abortController) abortController.abort();
2118
+ if (!parentValue) {
2119
+ formState.state.fetchedOptions[childField] = [];
2120
+ formState.state.loadingOptions[childField] = false;
2121
+ return;
2122
+ }
2123
+ formState.state.loadingOptions[childField] = true;
2124
+ abortController = new AbortController();
2125
+ try {
2126
+ const options2 = await fetchOptionsFn(parentValue);
2127
+ if (!abortController.signal.aborted) {
2128
+ formState.state.fetchedOptions[childField] = options2 || [];
2129
+ }
2130
+ } catch (error) {
2131
+ if (error.name !== "AbortError" && !abortController.signal.aborted) {
2132
+ formState.state.fetchedOptions[childField] = [];
2133
+ }
2134
+ } finally {
2135
+ if (!abortController.signal.aborted) {
2136
+ formState.state.loadingOptions[childField] = false;
2137
+ }
2138
+ }
2139
+ };
2140
+ const initialParent = getFieldValue(formState.state, parentField);
2141
+ if (initialParent) {
2142
+ fetchOptions(initialParent);
2143
+ }
2144
+ watch(
2145
+ () => getFieldValue(formState.state, parentField),
2146
+ (newVal, oldVal) => {
2147
+ if (oldVal === void 0) return;
2148
+ if (newVal === oldVal) return;
2149
+ fetchOptions(newVal);
2150
+ if (clearOnParentChange) {
2151
+ setFieldValue(formState.state, initialFormData, childField, "", schema, schemaCache);
2152
+ }
2153
+ }
2154
+ );
2155
+ });
2156
+ }
2157
+ if (options.autoPopulate) {
2158
+ Object.entries(options.autoPopulate).forEach(([sourceField, config]) => {
2159
+ if (!config) return;
2160
+ const autoPopulateConfig = config;
2161
+ if (!autoPopulateConfig || !autoPopulateConfig.fields) return;
2162
+ watch(
2163
+ () => getFieldValue(formState.state, sourceField),
2164
+ async (newValue, oldValue) => {
2165
+ if (oldValue === void 0) return;
2166
+ if (newValue === oldValue) return;
2167
+ if (!newValue) {
2168
+ if (autoPopulateConfig.fields) {
2169
+ const targetFields2 = Object.keys(autoPopulateConfig.fields);
2170
+ targetFields2.forEach((fieldName) => {
2171
+ setFieldValue(formState.state, initialFormData, fieldName, "", schema, schemaCache);
2172
+ formState.state.populatingFields[fieldName] = false;
2173
+ });
2174
+ }
2175
+ return;
2176
+ }
2177
+ const fetchedOptions = formState.state.fetchedOptions[sourceField] || [];
2178
+ const fetchedOption = fetchedOptions.find((opt) => opt.value === newValue);
2179
+ const fieldMetadata = fieldsMetadata[sourceField];
2180
+ const schemaOption = fieldMetadata?.options?.find((opt) => opt.value === newValue);
2181
+ const isValueFromOption = !!fetchedOption || !!schemaOption;
2182
+ if (!isValueFromOption) {
2183
+ return;
2184
+ }
2185
+ let optionData = null;
2186
+ const targetFields = autoPopulateConfig.fields ? Object.keys(autoPopulateConfig.fields) : [];
2187
+ if (autoPopulateConfig.fetchDataFn) {
2188
+ formState.state.loadingAutoPopulate[sourceField] = true;
2189
+ targetFields.forEach((fieldName) => {
2190
+ formState.state.populatingFields[fieldName] = true;
2191
+ });
2192
+ try {
2193
+ optionData = await autoPopulateConfig.fetchDataFn(newValue);
2194
+ } catch (error) {
2195
+ console.error(`Error fetching auto-populate data for ${sourceField}:`, error);
2196
+ formState.state.loadingAutoPopulate[sourceField] = false;
2197
+ targetFields.forEach((fieldName) => {
2198
+ formState.state.populatingFields[fieldName] = false;
2199
+ });
2200
+ return;
2201
+ } finally {
2202
+ formState.state.loadingAutoPopulate[sourceField] = false;
2203
+ }
2204
+ } else {
2205
+ if (fetchedOption?.data) {
2206
+ optionData = fetchedOption.data;
2207
+ } else if (schemaOption && "data" in schemaOption && schemaOption.data) {
2208
+ optionData = schemaOption.data;
2209
+ }
2210
+ targetFields.forEach((fieldName) => {
2211
+ formState.state.populatingFields[fieldName] = true;
2212
+ });
2213
+ }
2214
+ if (optionData && autoPopulateConfig.fields) {
2215
+ Object.entries(autoPopulateConfig.fields).forEach(([fieldName, mapping]) => {
2216
+ let value;
2217
+ if (typeof mapping === "function") {
2218
+ try {
2219
+ value = mapping(optionData);
2220
+ } catch (error) {
2221
+ console.warn(`Auto-populate transform error for ${fieldName}:`, error);
2222
+ value = "";
2223
+ }
2224
+ } else {
2225
+ value = getNestedValue(optionData, mapping) || "";
2226
+ }
2227
+ setFieldValue(formState.state, initialFormData, fieldName, value, schema, schemaCache);
2228
+ formState.state.populatingFields[fieldName] = false;
2229
+ });
2230
+ } else {
2231
+ targetFields.forEach((fieldName) => {
2232
+ formState.state.populatingFields[fieldName] = false;
2233
+ });
2234
+ }
2235
+ }
2236
+ );
2237
+ });
2238
+ }
2097
2239
  if (options.autoProvide !== false) {
2098
2240
  provide(ZINIA_FORM_SCHEMA_KEY, schema);
2099
2241
  provide(ZINIA_FORM_KEY, form);
@@ -2579,6 +2721,7 @@ function useDataTableState(initialData = [], options = {}) {
2579
2721
  totalRows: 0
2580
2722
  });
2581
2723
  const sortDrawerOpen = ref(false);
2724
+ const filterDrawerOpen = ref(false);
2582
2725
  const sorting = reactive({
2583
2726
  field: null,
2584
2727
  direction: "asc"
@@ -2705,6 +2848,7 @@ function useDataTableState(initialData = [], options = {}) {
2705
2848
  selection,
2706
2849
  // UI state
2707
2850
  sortDrawerOpen,
2851
+ filterDrawerOpen,
2708
2852
  // Computed properties
2709
2853
  hasData,
2710
2854
  isEmpty,
@@ -3062,7 +3206,10 @@ function useDataTable(schema, options) {
3062
3206
  ui: {
3063
3207
  sortDrawerOpen: tableState.state.sortDrawerOpen,
3064
3208
  openSortDrawer: () => tableState.state.sortDrawerOpen.value = true,
3065
- closeSortDrawer: () => tableState.state.sortDrawerOpen.value = false
3209
+ closeSortDrawer: () => tableState.state.sortDrawerOpen.value = false,
3210
+ filterDrawerOpen: tableState.state.filterDrawerOpen,
3211
+ openFilterDrawer: () => tableState.state.filterDrawerOpen.value = true,
3212
+ closeFilterDrawer: () => tableState.state.filterDrawerOpen.value = false
3066
3213
  },
3067
3214
  // Metadata
3068
3215
  fieldsMetadata,
@@ -3136,6 +3283,7 @@ function useCursorDataTableState(initialData = [], options = {}) {
3136
3283
  // Track which page we're conceptually on
3137
3284
  });
3138
3285
  const sortDrawerOpen = ref(false);
3286
+ const filterDrawerOpen = ref(false);
3139
3287
  const sorting = reactive({
3140
3288
  field: null,
3141
3289
  direction: "asc"
@@ -3279,6 +3427,7 @@ function useCursorDataTableState(initialData = [], options = {}) {
3279
3427
  selection,
3280
3428
  // UI state
3281
3429
  sortDrawerOpen,
3430
+ filterDrawerOpen,
3282
3431
  // Computed properties
3283
3432
  hasData,
3284
3433
  isEmpty,
@@ -3637,7 +3786,10 @@ function useCursorDataTable(schema, options) {
3637
3786
  ui: {
3638
3787
  sortDrawerOpen: tableState.state.sortDrawerOpen,
3639
3788
  openSortDrawer: () => tableState.state.sortDrawerOpen.value = true,
3640
- closeSortDrawer: () => tableState.state.sortDrawerOpen.value = false
3789
+ closeSortDrawer: () => tableState.state.sortDrawerOpen.value = false,
3790
+ filterDrawerOpen: tableState.state.filterDrawerOpen,
3791
+ openFilterDrawer: () => tableState.state.filterDrawerOpen.value = true,
3792
+ closeFilterDrawer: () => tableState.state.filterDrawerOpen.value = false
3641
3793
  },
3642
3794
  // Metadata
3643
3795
  fieldsMetadata,
@@ -4637,6 +4789,7 @@ function createDaisyUICheckboxField() {
4637
4789
  };
4638
4790
  const hasErrors = formState.hasError(props.name);
4639
4791
  const isTouched2 = formState.isTouched(props.name);
4792
+ const isBeingPopulated = formState.state?.populatingFields?.[props.name] || false;
4640
4793
  const inputClass = [
4641
4794
  "checkbox",
4642
4795
  props.size ? `checkbox-${props.size}` : "",
@@ -4645,15 +4798,17 @@ function createDaisyUICheckboxField() {
4645
4798
  isTouched2 && hasErrors ? "checkbox-error" : "",
4646
4799
  props.class
4647
4800
  ].filter(Boolean).join(" ");
4801
+ const isDisabled = props.disabled || isBeingPopulated;
4802
+ const descriptionText = isBeingPopulated ? "Loading..." : props.description;
4648
4803
  return /* @__PURE__ */ jsxs("div", { class: "form-control", children: [
4649
4804
  /* @__PURE__ */ jsxs("label", { class: "label cursor-pointer justify-start gap-2", children: [
4650
- /* @__PURE__ */ jsx("input", { class: inputClass, disabled: props.disabled, readonly: props.readonly, "data-testid": `${formState.storeName}-checkbox-field-${String(props.name)}`, ...inputProps }),
4805
+ /* @__PURE__ */ jsx("input", { class: inputClass, disabled: isDisabled, readonly: props.readonly, "data-testid": `${formState.storeName}-checkbox-field-${String(props.name)}`, ...inputProps }),
4651
4806
  !props.hideLabel && /* @__PURE__ */ jsxs("span", { class: "label-text", children: [
4652
4807
  props.label || fieldMetadata.label,
4653
4808
  fieldMetadata.isRequired && /* @__PURE__ */ jsx("span", { class: "text-error", children: " *" })
4654
4809
  ] })
4655
4810
  ] }),
4656
- props.description && /* @__PURE__ */ jsx("p", { class: "text-sm mt-1", children: props.description }),
4811
+ descriptionText && /* @__PURE__ */ jsx("p", { class: "text-sm mt-1", children: descriptionText }),
4657
4812
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-sm text-error mt-1", children: formState.getError(props.name) })
4658
4813
  ] });
4659
4814
  };
@@ -4748,7 +4903,31 @@ function createDaisyUIComboboxField() {
4748
4903
  const fieldMetadata = formState.fieldsMetadata[props.name] || {};
4749
4904
  const normalizedProps = normalizePropsFromAttrs(props, propsDefinition, attrs);
4750
4905
  const allowCreate = computed(() => normalizedProps.allowCreate === true);
4906
+ const fetchedOptions = computed(() => formState.state?.fetchedOptions?.[props.name] || []);
4907
+ const isLoadingOptions = computed(() => formState.state?.loadingOptions?.[props.name] || false);
4908
+ const isBeingPopulated = computed(() => formState.state?.populatingFields?.[props.name] || false);
4909
+ const asyncCascadingParent = computed(() => formState.state?.asyncCascadingParents?.[props.name]);
4910
+ const parentFieldName = computed(() => normalizedProps.dependsOn || asyncCascadingParent.value);
4911
+ const parentValue = computed(() => {
4912
+ if (parentFieldName.value) {
4913
+ return formState.getValue(parentFieldName.value);
4914
+ }
4915
+ return null;
4916
+ });
4917
+ const isDisabled = computed(() => {
4918
+ if (props.disabled) return true;
4919
+ if (isLoadingOptions.value) return true;
4920
+ if (isBeingPopulated.value) return true;
4921
+ if (parentFieldName.value) {
4922
+ const parentVal = parentValue.value;
4923
+ return parentVal === null || parentVal === void 0 || parentVal === "";
4924
+ }
4925
+ return false;
4926
+ });
4751
4927
  const getOptions = computed(() => {
4928
+ if (fetchedOptions.value.length > 0) {
4929
+ return fetchedOptions.value;
4930
+ }
4752
4931
  if (normalizedProps.selectOptions) {
4753
4932
  return normalizedProps.selectOptions;
4754
4933
  }
@@ -5080,9 +5259,9 @@ function createDaisyUIComboboxField() {
5080
5259
  {
5081
5260
  ref: inputElement,
5082
5261
  class: inputClass,
5083
- placeholder: props.placeholder || "Search or type new value",
5084
- disabled: props.disabled,
5085
- autocomplete: "off",
5262
+ placeholder: isBeingPopulated.value ? "Loading..." : isLoadingOptions.value ? "Loading options..." : parentFieldName.value && !parentValue.value ? "Select parent field first" : props.placeholder || "Search or type new value",
5263
+ disabled: isDisabled.value,
5264
+ autocomplete: "nope",
5086
5265
  "data-testid": `${formState.storeName}-combobox-field-${String(props.name)}`,
5087
5266
  ...inputProps
5088
5267
  }
@@ -5192,7 +5371,7 @@ function createDaisyUIComboboxField() {
5192
5371
  ]
5193
5372
  }
5194
5373
  ),
5195
- props.description && /* @__PURE__ */ jsx("p", { class: "text-sm mt-1", children: props.description }),
5374
+ (isBeingPopulated.value ? "Loading..." : props.description) && /* @__PURE__ */ jsx("p", { class: "text-sm mt-1", children: isBeingPopulated.value ? "Loading..." : props.description }),
5196
5375
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-error text-xs", children: formState.getError(props.name) }),
5197
5376
  isNewValue.value && displayText.value && !hasErrors && /* @__PURE__ */ jsxs("p", { class: "text-success text-xs", children: [
5198
5377
  '\u2713 New value "',
@@ -5234,6 +5413,7 @@ function createDaisyUICurrencyField() {
5234
5413
  };
5235
5414
  const hasErrors = formState.hasError(props.name);
5236
5415
  const isTouched2 = formState.isTouched(props.name);
5416
+ const isBeingPopulated = formState.state?.populatingFields?.[props.name] || false;
5237
5417
  const inputClass = [
5238
5418
  "input",
5239
5419
  props.size ? `input-${props.size}` : "",
@@ -5242,6 +5422,8 @@ function createDaisyUICurrencyField() {
5242
5422
  isTouched2 && hasErrors ? "input-error" : "",
5243
5423
  props.class
5244
5424
  ].filter(Boolean).join(" ");
5425
+ const isDisabled = props.disabled || isBeingPopulated;
5426
+ const descriptionText = isBeingPopulated ? "Loading..." : props.description;
5245
5427
  return /* @__PURE__ */ jsxs("label", { class: "floating-label", children: [
5246
5428
  !props.hideLabel && /* @__PURE__ */ jsxs("span", { children: [
5247
5429
  props.label || fieldMetadata.label,
@@ -5252,7 +5434,7 @@ function createDaisyUICurrencyField() {
5252
5434
  {
5253
5435
  class: inputClass,
5254
5436
  placeholder: props.placeholder,
5255
- disabled: props.disabled,
5437
+ disabled: isDisabled,
5256
5438
  readonly: props.readonly,
5257
5439
  min: fieldMetadata.min,
5258
5440
  max: fieldMetadata.max,
@@ -5261,7 +5443,7 @@ function createDaisyUICurrencyField() {
5261
5443
  ...inputProps
5262
5444
  }
5263
5445
  ),
5264
- props.description && /* @__PURE__ */ jsx("p", { class: "", children: props.description }),
5446
+ descriptionText && /* @__PURE__ */ jsx("p", { class: "", children: descriptionText }),
5265
5447
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-error text-xs", children: formState.getError(props.name) })
5266
5448
  ] });
5267
5449
  };
@@ -5330,6 +5512,7 @@ function createDaisyUIDateField() {
5330
5512
  };
5331
5513
  const hasErrors = formState.hasError(props.name);
5332
5514
  const isTouched2 = formState.isTouched(props.name);
5515
+ const isBeingPopulated = formState.state?.populatingFields?.[props.name] || false;
5333
5516
  const inputClass = [
5334
5517
  "input",
5335
5518
  props.size ? `input-${props.size}` : "",
@@ -5338,6 +5521,8 @@ function createDaisyUIDateField() {
5338
5521
  isTouched2 && hasErrors ? "input-error" : "",
5339
5522
  props.class
5340
5523
  ].filter(Boolean).join(" ");
5524
+ const isDisabled = props.disabled || isBeingPopulated;
5525
+ const descriptionText = isBeingPopulated ? "Loading..." : props.description;
5341
5526
  return /* @__PURE__ */ jsxs("label", { class: "floating-label", children: [
5342
5527
  !props.hideLabel && /* @__PURE__ */ jsxs("span", { children: [
5343
5528
  props.label || fieldMetadata.label,
@@ -5348,7 +5533,7 @@ function createDaisyUIDateField() {
5348
5533
  {
5349
5534
  class: inputClass,
5350
5535
  placeholder: props.placeholder,
5351
- disabled: props.disabled,
5536
+ disabled: isDisabled,
5352
5537
  readonly: props.readonly,
5353
5538
  min: props.min,
5354
5539
  max: props.max,
@@ -5356,7 +5541,7 @@ function createDaisyUIDateField() {
5356
5541
  ...inputProps
5357
5542
  }
5358
5543
  ),
5359
- props.description && /* @__PURE__ */ jsx("p", { class: "", children: props.description }),
5544
+ descriptionText && /* @__PURE__ */ jsx("p", { class: "", children: descriptionText }),
5360
5545
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-error text-xs", children: formState.getError(props.name) })
5361
5546
  ] });
5362
5547
  };
@@ -5425,6 +5610,7 @@ function createDaisyUIDateTimeLocalField() {
5425
5610
  };
5426
5611
  const hasErrors = formState.hasError(props.name);
5427
5612
  const isTouched2 = formState.isTouched(props.name);
5613
+ const isBeingPopulated = formState.state?.populatingFields?.[props.name] || false;
5428
5614
  const inputClass = [
5429
5615
  "input",
5430
5616
  props.size ? `input-${props.size}` : "",
@@ -5433,6 +5619,8 @@ function createDaisyUIDateTimeLocalField() {
5433
5619
  isTouched2 && hasErrors ? "input-error" : "",
5434
5620
  props.class
5435
5621
  ].filter(Boolean).join(" ");
5622
+ const isDisabled = props.disabled || isBeingPopulated;
5623
+ const descriptionText = isBeingPopulated ? "Loading..." : props.description;
5436
5624
  return /* @__PURE__ */ jsxs("label", { class: "floating-label", children: [
5437
5625
  !props.hideLabel && /* @__PURE__ */ jsxs("span", { children: [
5438
5626
  props.label || fieldMetadata.label,
@@ -5443,13 +5631,13 @@ function createDaisyUIDateTimeLocalField() {
5443
5631
  {
5444
5632
  class: inputClass,
5445
5633
  placeholder: props.placeholder,
5446
- disabled: props.disabled,
5634
+ disabled: isDisabled,
5447
5635
  readonly: props.readonly,
5448
5636
  "data-testid": `${formState.storeName}-datetime-local-field-${String(props.name)}`,
5449
5637
  ...inputProps
5450
5638
  }
5451
5639
  ),
5452
- props.description && /* @__PURE__ */ jsx("p", { class: "", children: props.description }),
5640
+ descriptionText && /* @__PURE__ */ jsx("p", { class: "", children: descriptionText }),
5453
5641
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-error text-xs", children: formState.getError(props.name) })
5454
5642
  ] });
5455
5643
  };
@@ -5497,6 +5685,7 @@ function createDaisyUIEmailField() {
5497
5685
  };
5498
5686
  const hasErrors = formState.hasError(props.name);
5499
5687
  const isTouched2 = formState.isTouched(props.name);
5688
+ const isBeingPopulated = formState.state?.populatingFields?.[props.name] || false;
5500
5689
  const inputClass = [
5501
5690
  "input",
5502
5691
  props.size ? `input-${props.size}` : "",
@@ -5505,6 +5694,8 @@ function createDaisyUIEmailField() {
5505
5694
  isTouched2 && hasErrors ? "input-error" : "",
5506
5695
  props.class
5507
5696
  ].filter(Boolean).join(" ");
5697
+ const isDisabled = props.disabled || isBeingPopulated;
5698
+ const descriptionText = isBeingPopulated ? "Loading..." : props.description;
5508
5699
  return /* @__PURE__ */ jsxs("label", { class: "floating-label", children: [
5509
5700
  !props.hideLabel && /* @__PURE__ */ jsxs("span", { children: [
5510
5701
  props.label || fieldMetadata.label,
@@ -5515,13 +5706,13 @@ function createDaisyUIEmailField() {
5515
5706
  {
5516
5707
  class: inputClass,
5517
5708
  placeholder: props.placeholder,
5518
- disabled: props.disabled,
5709
+ disabled: isDisabled,
5519
5710
  readonly: props.readonly,
5520
5711
  "data-testid": `${formState.storeName}-email-field-${String(props.name)}`,
5521
5712
  ...inputProps
5522
5713
  }
5523
5714
  ),
5524
- props.description && /* @__PURE__ */ jsx("p", { class: "", children: props.description }),
5715
+ descriptionText && /* @__PURE__ */ jsx("p", { class: "", children: descriptionText }),
5525
5716
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-error text-xs", children: formState.getError(props.name) })
5526
5717
  ] });
5527
5718
  };
@@ -5566,6 +5757,7 @@ function createDaisyUIFileField() {
5566
5757
  };
5567
5758
  const hasErrors = formState.hasError(props.name);
5568
5759
  const isTouched2 = formState.isTouched(props.name);
5760
+ const isBeingPopulated = formState.state?.populatingFields?.[props.name] || false;
5569
5761
  const inputClass = [
5570
5762
  "file-input",
5571
5763
  props.size ? `file-input-${props.size}` : "",
@@ -5574,13 +5766,15 @@ function createDaisyUIFileField() {
5574
5766
  isTouched2 && hasErrors ? "file-input-error" : "",
5575
5767
  props.class
5576
5768
  ].filter(Boolean).join(" ");
5769
+ const isDisabled = props.disabled || isBeingPopulated;
5770
+ const descriptionText = isBeingPopulated ? "Loading..." : props.description;
5577
5771
  return /* @__PURE__ */ jsxs("div", { class: "form-control", children: [
5578
5772
  !props.hideLabel && /* @__PURE__ */ jsx("label", { class: "label", children: /* @__PURE__ */ jsxs("span", { class: "label-text", children: [
5579
5773
  props.label || fieldMetadata.label,
5580
5774
  fieldMetadata.isRequired && /* @__PURE__ */ jsx("span", { class: "text-error", children: " *" })
5581
5775
  ] }) }),
5582
- /* @__PURE__ */ jsx("input", { class: inputClass, disabled: props.disabled, readonly: props.readonly, "data-testid": `${formState.storeName}-file-field-${String(props.name)}`, ...inputProps }),
5583
- props.description && /* @__PURE__ */ jsx("p", { class: "text-sm mt-1", children: props.description }),
5776
+ /* @__PURE__ */ jsx("input", { class: inputClass, disabled: isDisabled, readonly: props.readonly, "data-testid": `${formState.storeName}-file-field-${String(props.name)}`, ...inputProps }),
5777
+ descriptionText && /* @__PURE__ */ jsx("p", { class: "text-sm mt-1", children: descriptionText }),
5584
5778
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-sm text-error mt-1", children: formState.getError(props.name) })
5585
5779
  ] });
5586
5780
  };
@@ -5777,6 +5971,7 @@ function createDaisyUINumberField() {
5777
5971
  };
5778
5972
  const hasErrors = formState.hasError(props.name);
5779
5973
  const isTouched2 = formState.isTouched(props.name);
5974
+ const isBeingPopulated = formState.state?.populatingFields?.[props.name] || false;
5780
5975
  const inputClass = [
5781
5976
  "input",
5782
5977
  props.size ? `input-${props.size}` : "",
@@ -5785,6 +5980,8 @@ function createDaisyUINumberField() {
5785
5980
  isTouched2 && hasErrors ? "input-error" : "",
5786
5981
  props.class
5787
5982
  ].filter(Boolean).join(" ");
5983
+ const isDisabled = props.disabled || isBeingPopulated;
5984
+ const descriptionText = isBeingPopulated ? "Loading..." : props.description;
5788
5985
  return /* @__PURE__ */ jsxs("label", { class: "floating-label", children: [
5789
5986
  !props.hideLabel && /* @__PURE__ */ jsxs("span", { children: [
5790
5987
  props.label || fieldMetadata.label,
@@ -5795,7 +5992,7 @@ function createDaisyUINumberField() {
5795
5992
  {
5796
5993
  class: inputClass,
5797
5994
  placeholder: props.placeholder,
5798
- disabled: props.disabled,
5995
+ disabled: isDisabled,
5799
5996
  readonly: props.readonly,
5800
5997
  min: fieldMetadata.min,
5801
5998
  max: fieldMetadata.max,
@@ -5804,7 +6001,7 @@ function createDaisyUINumberField() {
5804
6001
  ...inputProps
5805
6002
  }
5806
6003
  ),
5807
- props.description && /* @__PURE__ */ jsx("p", { class: "", children: props.description }),
6004
+ descriptionText && /* @__PURE__ */ jsx("p", { class: "", children: descriptionText }),
5808
6005
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-error text-xs", children: formState.getError(props.name) })
5809
6006
  ] });
5810
6007
  };
@@ -5851,6 +6048,7 @@ function createDaisyUIPasswordField() {
5851
6048
  };
5852
6049
  const hasErrors = formState.hasError(props.name);
5853
6050
  const isTouched2 = formState.isTouched(props.name);
6051
+ const isBeingPopulated = formState.state?.populatingFields?.[props.name] || false;
5854
6052
  const inputClass = [
5855
6053
  "input",
5856
6054
  props.size ? `input-${props.size}` : "",
@@ -5859,6 +6057,8 @@ function createDaisyUIPasswordField() {
5859
6057
  isTouched2 && hasErrors ? "input-error" : "",
5860
6058
  props.class
5861
6059
  ].filter(Boolean).join(" ");
6060
+ const isDisabled = props.disabled || isBeingPopulated;
6061
+ const descriptionText = isBeingPopulated ? "Loading..." : props.description;
5862
6062
  return /* @__PURE__ */ jsxs("label", { class: "floating-label", children: [
5863
6063
  !props.hideLabel && /* @__PURE__ */ jsxs("span", { children: [
5864
6064
  props.label || fieldMetadata.label,
@@ -5869,13 +6069,13 @@ function createDaisyUIPasswordField() {
5869
6069
  {
5870
6070
  class: inputClass,
5871
6071
  placeholder: props.placeholder,
5872
- disabled: props.disabled,
6072
+ disabled: isDisabled,
5873
6073
  readonly: props.readonly,
5874
6074
  "data-testid": `${formState.storeName}-password-field-${String(props.name)}`,
5875
6075
  ...inputProps
5876
6076
  }
5877
6077
  ),
5878
- props.description && /* @__PURE__ */ jsx("p", { class: "", children: props.description }),
6078
+ descriptionText && /* @__PURE__ */ jsx("p", { class: "", children: descriptionText }),
5879
6079
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-error text-xs", children: formState.getError(props.name) })
5880
6080
  ] });
5881
6081
  };
@@ -5907,6 +6107,7 @@ function createDaisyUIRadioField() {
5907
6107
  const currentValue = formState.getValue(props.name);
5908
6108
  const hasErrors = formState.hasError(props.name);
5909
6109
  const isTouched2 = formState.isTouched(props.name);
6110
+ const isBeingPopulated = formState.state?.populatingFields?.[props.name] || false;
5910
6111
  const radioClass = [
5911
6112
  "radio",
5912
6113
  props.size ? `radio-${props.size}` : "",
@@ -5914,6 +6115,8 @@ function createDaisyUIRadioField() {
5914
6115
  isTouched2 && !hasErrors ? "radio-success" : "",
5915
6116
  isTouched2 && hasErrors ? "radio-error" : ""
5916
6117
  ].filter(Boolean).join(" ");
6118
+ const isDisabled = props.disabled || isBeingPopulated;
6119
+ const descriptionText = isBeingPopulated ? "Loading..." : props.description;
5917
6120
  const handleChange = (value) => {
5918
6121
  formState.setValue(props.name, value);
5919
6122
  formState.touchField(props.name);
@@ -5945,7 +6148,7 @@ function createDaisyUIRadioField() {
5945
6148
  checked: currentValue === option.value,
5946
6149
  onChange: () => handleChange(option.value),
5947
6150
  onBlur: handleBlur,
5948
- disabled: props.disabled,
6151
+ disabled: isDisabled,
5949
6152
  readonly: props.readonly,
5950
6153
  name: props.name,
5951
6154
  "data-testid": `${formState.storeName}-radio-field-${String(props.name)}-${option.value}`,
@@ -5956,7 +6159,7 @@ function createDaisyUIRadioField() {
5956
6159
  ]
5957
6160
  }
5958
6161
  ) }, option.value)) }),
5959
- props.description && /* @__PURE__ */ jsx("p", { class: "label mt-2 text-sm text-base-content/70", children: props.description }),
6162
+ descriptionText && /* @__PURE__ */ jsx("p", { class: "label mt-2 text-sm text-base-content/70", children: descriptionText }),
5960
6163
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-sm text-error mt-2", children: formState.getError(props.name) })
5961
6164
  ] }) });
5962
6165
  };
@@ -6005,6 +6208,7 @@ function createDaisyUIRangeField() {
6005
6208
  };
6006
6209
  const hasErrors = formState.hasError(props.name);
6007
6210
  const isTouched2 = formState.isTouched(props.name);
6211
+ const isBeingPopulated = formState.state?.populatingFields?.[props.name] || false;
6008
6212
  const inputClass = [
6009
6213
  "range",
6010
6214
  props.size ? `range-${props.size}` : "",
@@ -6013,6 +6217,8 @@ function createDaisyUIRangeField() {
6013
6217
  isTouched2 && hasErrors ? "range-error" : "",
6014
6218
  props.class
6015
6219
  ].filter(Boolean).join(" ");
6220
+ const isDisabled = props.disabled || isBeingPopulated;
6221
+ const descriptionText = isBeingPopulated ? "Loading..." : props.description;
6016
6222
  return /* @__PURE__ */ jsxs("div", { class: "form-control", children: [
6017
6223
  !props.hideLabel && /* @__PURE__ */ jsxs("label", { class: "label", children: [
6018
6224
  /* @__PURE__ */ jsxs("span", { class: "label-text", children: [
@@ -6021,8 +6227,8 @@ function createDaisyUIRangeField() {
6021
6227
  ] }),
6022
6228
  props.showValue && /* @__PURE__ */ jsx("span", { class: "label-text-alt", children: currentValue })
6023
6229
  ] }),
6024
- /* @__PURE__ */ jsx("input", { class: inputClass, disabled: props.disabled, readonly: props.readonly, "data-testid": `${formState.storeName}-range-field-${String(props.name)}`, ...inputProps }),
6025
- props.description && /* @__PURE__ */ jsx("p", { class: "text-sm mt-1", children: props.description }),
6230
+ /* @__PURE__ */ jsx("input", { class: inputClass, disabled: isDisabled, readonly: props.readonly, "data-testid": `${formState.storeName}-range-field-${String(props.name)}`, ...inputProps }),
6231
+ descriptionText && /* @__PURE__ */ jsx("p", { class: "text-sm mt-1", children: descriptionText }),
6026
6232
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-sm text-error mt-1", children: formState.getError(props.name) })
6027
6233
  ] });
6028
6234
  };
@@ -6099,6 +6305,7 @@ function createDaisyUISearchField() {
6099
6305
  };
6100
6306
  const hasErrors = formState.hasError(props.name);
6101
6307
  const isTouched2 = formState.isTouched(props.name);
6308
+ const isBeingPopulated = formState.state?.populatingFields?.[props.name] || false;
6102
6309
  const inputClass = [
6103
6310
  "input",
6104
6311
  props.size ? `input-${props.size}` : "",
@@ -6107,6 +6314,8 @@ function createDaisyUISearchField() {
6107
6314
  isTouched2 && hasErrors ? "input-error" : "",
6108
6315
  props.class
6109
6316
  ].filter(Boolean).join(" ");
6317
+ const isDisabled = props.disabled || isBeingPopulated;
6318
+ const descriptionText = isBeingPopulated ? "Loading..." : props.description;
6110
6319
  return /* @__PURE__ */ jsxs("label", { class: "floating-label", children: [
6111
6320
  !props.hideLabel && /* @__PURE__ */ jsxs("span", { children: [
6112
6321
  props.label || fieldMetadata.label,
@@ -6117,13 +6326,13 @@ function createDaisyUISearchField() {
6117
6326
  {
6118
6327
  class: inputClass,
6119
6328
  placeholder: props.placeholder,
6120
- disabled: props.disabled,
6329
+ disabled: isDisabled,
6121
6330
  readonly: props.readonly,
6122
6331
  "data-testid": `${formState.storeName}-search-field-${String(props.name)}`,
6123
6332
  ...inputProps
6124
6333
  }
6125
6334
  ),
6126
- props.description && /* @__PURE__ */ jsx("p", { class: "", children: props.description }),
6335
+ descriptionText && /* @__PURE__ */ jsx("p", { class: "", children: descriptionText }),
6127
6336
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-error text-xs", children: formState.getError(props.name) })
6128
6337
  ] });
6129
6338
  };
@@ -6174,13 +6383,20 @@ function createDaisyUISelectField() {
6174
6383
  }
6175
6384
  const fieldMetadata = formState.fieldsMetadata[props.name] || {};
6176
6385
  const normalizedProps = normalizePropsFromAttrs(props, propsDefinition, attrs);
6386
+ const asyncCascadingParent = computed(() => formState.state?.asyncCascadingParents?.[props.name]);
6387
+ const parentFieldName = computed(() => normalizedProps.dependsOn || asyncCascadingParent.value);
6177
6388
  const parentValue = computed(() => {
6178
- if (normalizedProps.dependsOn) {
6179
- return formState.getValue(normalizedProps.dependsOn);
6389
+ if (parentFieldName.value) {
6390
+ return formState.getValue(parentFieldName.value);
6180
6391
  }
6181
6392
  return null;
6182
6393
  });
6394
+ const fetchedOptions = computed(() => formState.state?.fetchedOptions?.[props.name] || []);
6395
+ const isLoadingOptions = computed(() => formState.state?.loadingOptions?.[props.name] || false);
6183
6396
  const allOptions = computed(() => {
6397
+ if (fetchedOptions.value.length > 0) {
6398
+ return fetchedOptions.value;
6399
+ }
6184
6400
  if (normalizedProps.selectOptions) {
6185
6401
  return normalizedProps.selectOptions;
6186
6402
  }
@@ -6226,14 +6442,26 @@ function createDaisyUISelectField() {
6226
6442
  { immediate: false }
6227
6443
  );
6228
6444
  }
6445
+ const isBeingPopulated = computed(() => formState.state?.populatingFields?.[props.name] || false);
6229
6446
  const isDisabled = computed(() => {
6230
6447
  if (props.disabled) return true;
6231
- if (normalizedProps.dependsOn) {
6448
+ if (isLoadingOptions.value) return true;
6449
+ if (isBeingPopulated.value) return true;
6450
+ if (parentFieldName.value) {
6232
6451
  const parentVal = parentValue.value;
6233
6452
  return parentVal === null || parentVal === void 0 || parentVal === "";
6234
6453
  }
6235
6454
  return false;
6236
6455
  });
6456
+ const placeholderText = computed(() => {
6457
+ if (isLoadingOptions.value) {
6458
+ return props.placeholder ? `${props.placeholder} (Loading...)` : "Loading...";
6459
+ }
6460
+ if (isBeingPopulated.value) {
6461
+ return props.placeholder ? `${props.placeholder} (Loading...)` : "Loading...";
6462
+ }
6463
+ return props.placeholder;
6464
+ });
6237
6465
  const htmlAttrs = filterComponentPropsFromAttrs(propsDefinition, attrs);
6238
6466
  const selectProps = {
6239
6467
  value: formState.getValue(props.name),
@@ -6265,11 +6493,20 @@ function createDaisyUISelectField() {
6265
6493
  props.label || fieldMetadata.label,
6266
6494
  fieldMetadata.isRequired && /* @__PURE__ */ jsx("span", { class: "text-error", children: " *" })
6267
6495
  ] }),
6268
- /* @__PURE__ */ jsxs("select", { class: selectClass, disabled: isDisabled.value, "data-testid": `${formState.storeName}-select-field-${String(props.name)}`, ...selectProps, children: [
6269
- props.placeholder && /* @__PURE__ */ jsx("option", { value: "", disabled: true, selected: true, children: props.placeholder }),
6270
- getOptions.value.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
6271
- ] }),
6272
- props.description && /* @__PURE__ */ jsx("p", { class: "", children: props.description }),
6496
+ /* @__PURE__ */ jsxs(
6497
+ "select",
6498
+ {
6499
+ class: selectClass,
6500
+ disabled: isDisabled.value,
6501
+ "data-testid": `${formState.storeName}-select-field-${String(props.name)}`,
6502
+ ...selectProps,
6503
+ children: [
6504
+ placeholderText.value && /* @__PURE__ */ jsx("option", { value: "", disabled: true, selected: true, children: placeholderText.value }),
6505
+ getOptions.value.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
6506
+ ]
6507
+ }
6508
+ ),
6509
+ (isBeingPopulated.value ? "Loading..." : props.description) && /* @__PURE__ */ jsx("p", { class: "", children: isBeingPopulated.value ? "Loading..." : props.description }),
6273
6510
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-error text-xs", children: formState.getError(props.name) })
6274
6511
  ] });
6275
6512
  };
@@ -6318,6 +6555,7 @@ function createDaisyUITelField() {
6318
6555
  };
6319
6556
  const hasErrors = formState.hasError(props.name);
6320
6557
  const isTouched2 = formState.isTouched(props.name);
6558
+ const isBeingPopulated = formState.state?.populatingFields?.[props.name] || false;
6321
6559
  const inputClass = [
6322
6560
  "input",
6323
6561
  props.size ? `input-${props.size}` : "",
@@ -6326,6 +6564,8 @@ function createDaisyUITelField() {
6326
6564
  isTouched2 && hasErrors ? "input-error" : "",
6327
6565
  props.class
6328
6566
  ].filter(Boolean).join(" ");
6567
+ const isDisabled = props.disabled || isBeingPopulated;
6568
+ const descriptionText = isBeingPopulated ? "Loading..." : props.description;
6329
6569
  return /* @__PURE__ */ jsxs("label", { class: "floating-label", children: [
6330
6570
  !props.hideLabel && /* @__PURE__ */ jsxs("span", { children: [
6331
6571
  props.label || fieldMetadata.label,
@@ -6336,13 +6576,13 @@ function createDaisyUITelField() {
6336
6576
  {
6337
6577
  class: inputClass,
6338
6578
  placeholder: props.placeholder,
6339
- disabled: props.disabled,
6579
+ disabled: isDisabled,
6340
6580
  readonly: props.readonly,
6341
6581
  "data-testid": `${formState.storeName}-tel-field-${String(props.name)}`,
6342
6582
  ...inputProps
6343
6583
  }
6344
6584
  ),
6345
- props.description && /* @__PURE__ */ jsx("p", { class: "", children: props.description }),
6585
+ descriptionText && /* @__PURE__ */ jsx("p", { class: "", children: descriptionText }),
6346
6586
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-error text-xs", children: formState.getError(props.name) })
6347
6587
  ] });
6348
6588
  };
@@ -6422,6 +6662,7 @@ function createDaisyUITextareaField() {
6422
6662
  };
6423
6663
  const hasErrors = formState.hasError(props.name);
6424
6664
  const isTouched2 = formState.isTouched(props.name);
6665
+ const isBeingPopulated = formState.state?.populatingFields?.[props.name] || false;
6425
6666
  const textareaClass = [
6426
6667
  "textarea",
6427
6668
  props.size ? `textarea-${props.size}` : "",
@@ -6430,6 +6671,8 @@ function createDaisyUITextareaField() {
6430
6671
  isTouched2 && hasErrors ? "textarea-error" : "",
6431
6672
  props.class
6432
6673
  ].filter(Boolean).join(" ");
6674
+ const isDisabled = props.disabled || isBeingPopulated;
6675
+ const descriptionText = isBeingPopulated ? "Loading..." : props.description;
6433
6676
  return /* @__PURE__ */ jsxs("label", { class: "floating-label", children: [
6434
6677
  !props.hideLabel && /* @__PURE__ */ jsxs("span", { children: [
6435
6678
  props.label || fieldMetadata.label,
@@ -6441,14 +6684,14 @@ function createDaisyUITextareaField() {
6441
6684
  ref: setTextareaRef,
6442
6685
  class: textareaClass,
6443
6686
  placeholder: props.placeholder,
6444
- disabled: props.disabled,
6687
+ disabled: isDisabled,
6445
6688
  readonly: props.readonly,
6446
6689
  rows: props.rows || 3,
6447
6690
  "data-testid": `${formState.storeName}-textarea-field-${String(props.name)}`,
6448
6691
  ...textareaProps
6449
6692
  }
6450
6693
  ),
6451
- props.description && /* @__PURE__ */ jsx("p", { class: "", children: props.description }),
6694
+ descriptionText && /* @__PURE__ */ jsx("p", { class: "", children: descriptionText }),
6452
6695
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-error text-xs", children: formState.getError(props.name) })
6453
6696
  ] });
6454
6697
  };
@@ -6496,6 +6739,7 @@ function createDaisyUITextField() {
6496
6739
  };
6497
6740
  const hasErrors = formState.hasError(props.name);
6498
6741
  const isTouched2 = formState.isTouched(props.name);
6742
+ const isBeingPopulated = formState.state?.populatingFields?.[props.name] || false;
6499
6743
  const inputClass = [
6500
6744
  "input",
6501
6745
  props.size ? `input-${props.size}` : "",
@@ -6504,6 +6748,8 @@ function createDaisyUITextField() {
6504
6748
  isTouched2 && hasErrors ? "input-error" : "",
6505
6749
  props.class
6506
6750
  ].filter(Boolean).join(" ");
6751
+ const isDisabled = props.disabled || isBeingPopulated;
6752
+ const descriptionText = isBeingPopulated ? "Loading..." : props.description;
6507
6753
  return /* @__PURE__ */ jsxs("label", { class: "floating-label", children: [
6508
6754
  !props.hideLabel && /* @__PURE__ */ jsxs("span", { children: [
6509
6755
  props.label || fieldMetadata.label,
@@ -6514,13 +6760,13 @@ function createDaisyUITextField() {
6514
6760
  {
6515
6761
  class: inputClass,
6516
6762
  placeholder: props.placeholder,
6517
- disabled: props.disabled,
6763
+ disabled: isDisabled,
6518
6764
  readonly: props.readonly,
6519
6765
  "data-testid": `${formState.storeName}-text-field-${String(props.name)}`,
6520
6766
  ...inputProps
6521
6767
  }
6522
6768
  ),
6523
- props.description && /* @__PURE__ */ jsx("p", { class: "", children: props.description }),
6769
+ descriptionText && /* @__PURE__ */ jsx("p", { class: "", children: descriptionText }),
6524
6770
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-error text-xs", children: formState.getError(props.name) })
6525
6771
  ] });
6526
6772
  };
@@ -6567,6 +6813,7 @@ function createDaisyUITimeField() {
6567
6813
  };
6568
6814
  const hasErrors = formState.hasError(props.name);
6569
6815
  const isTouched2 = formState.isTouched(props.name);
6816
+ const isBeingPopulated = formState.state?.populatingFields?.[props.name] || false;
6570
6817
  const inputClass = [
6571
6818
  "input",
6572
6819
  props.size ? `input-${props.size}` : "",
@@ -6575,6 +6822,8 @@ function createDaisyUITimeField() {
6575
6822
  isTouched2 && hasErrors ? "input-error" : "",
6576
6823
  props.class
6577
6824
  ].filter(Boolean).join(" ");
6825
+ const isDisabled = props.disabled || isBeingPopulated;
6826
+ const descriptionText = isBeingPopulated ? "Loading..." : props.description;
6578
6827
  return /* @__PURE__ */ jsxs("label", { class: "floating-label", children: [
6579
6828
  !props.hideLabel && /* @__PURE__ */ jsxs("span", { children: [
6580
6829
  props.label || fieldMetadata.label,
@@ -6585,13 +6834,13 @@ function createDaisyUITimeField() {
6585
6834
  {
6586
6835
  class: inputClass,
6587
6836
  placeholder: props.placeholder,
6588
- disabled: props.disabled,
6837
+ disabled: isDisabled,
6589
6838
  readonly: props.readonly,
6590
6839
  "data-testid": `${formState.storeName}-time-field-${String(props.name)}`,
6591
6840
  ...inputProps
6592
6841
  }
6593
6842
  ),
6594
- props.description && /* @__PURE__ */ jsx("p", { class: "", children: props.description }),
6843
+ descriptionText && /* @__PURE__ */ jsx("p", { class: "", children: descriptionText }),
6595
6844
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-error text-xs", children: formState.getError(props.name) })
6596
6845
  ] });
6597
6846
  };
@@ -7127,6 +7376,7 @@ function createDaisyUIUrlField() {
7127
7376
  };
7128
7377
  const hasErrors = formState.hasError(props.name);
7129
7378
  const isTouched2 = formState.isTouched(props.name);
7379
+ const isBeingPopulated = formState.state?.populatingFields?.[props.name] || false;
7130
7380
  const inputClass = [
7131
7381
  "input",
7132
7382
  props.size ? `input-${props.size}` : "",
@@ -7135,6 +7385,8 @@ function createDaisyUIUrlField() {
7135
7385
  isTouched2 && hasErrors ? "input-error" : "",
7136
7386
  props.class
7137
7387
  ].filter(Boolean).join(" ");
7388
+ const isDisabled = props.disabled || isBeingPopulated;
7389
+ const descriptionText = isBeingPopulated ? "Loading..." : props.description;
7138
7390
  return /* @__PURE__ */ jsxs("label", { class: "floating-label", children: [
7139
7391
  !props.hideLabel && /* @__PURE__ */ jsxs("span", { children: [
7140
7392
  props.label || fieldMetadata.label,
@@ -7145,13 +7397,13 @@ function createDaisyUIUrlField() {
7145
7397
  {
7146
7398
  class: inputClass,
7147
7399
  placeholder: props.placeholder,
7148
- disabled: props.disabled,
7400
+ disabled: isDisabled,
7149
7401
  readonly: props.readonly,
7150
7402
  "data-testid": `${formState.storeName}-url-field-${String(props.name)}`,
7151
7403
  ...inputProps
7152
7404
  }
7153
7405
  ),
7154
- props.description && /* @__PURE__ */ jsx("p", { class: "", children: props.description }),
7406
+ descriptionText && /* @__PURE__ */ jsx("p", { class: "", children: descriptionText }),
7155
7407
  isTouched2 && hasErrors && /* @__PURE__ */ jsx("p", { class: "text-error text-xs", children: formState.getError(props.name) })
7156
7408
  ] });
7157
7409
  };
@@ -7497,6 +7749,8 @@ function getFilterType(field, column, fieldsMetadata) {
7497
7749
  return "number";
7498
7750
  case "checkbox":
7499
7751
  return "boolean";
7752
+ case "combobox":
7753
+ return "combobox";
7500
7754
  case "select":
7501
7755
  case "radio":
7502
7756
  return column.filterOptions || fieldMetadata?.options ? "select" : "text";
@@ -7833,20 +8087,19 @@ var SelectFilter = (props) => {
7833
8087
  return /* @__PURE__ */ jsxs(
7834
8088
  "select",
7835
8089
  {
7836
- value: props.value,
8090
+ value: props.value || "",
7837
8091
  onChange: (e) => {
7838
8092
  const value = e.target.value;
7839
8093
  props.onFilterChange(props.field, value, "eq");
7840
8094
  },
7841
- class: "select select-bordered flex-1 sm:flex-none sm:w-auto",
8095
+ class: "select select-bordered select-sm w-full",
7842
8096
  disabled: props.isLoading || props.isOptionsLoading,
7843
8097
  "data-testid": `datatable-filter-${props.field}-input`,
7844
8098
  children: [
7845
8099
  /* @__PURE__ */ jsx("option", { value: "", children: props.isOptionsLoading ? "Loading options..." : `All ${props.label}` }),
7846
8100
  props.options.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
7847
8101
  ]
7848
- },
7849
- props.field
8102
+ }
7850
8103
  );
7851
8104
  };
7852
8105
 
@@ -7865,7 +8118,7 @@ function debounce(key, callback, delay = 300) {
7865
8118
  }
7866
8119
  var TextFilter = (props) => {
7867
8120
  const currentOperator = props.filterOperators.value[props.field] || "contains";
7868
- return /* @__PURE__ */ jsxs("div", { class: "flex gap-2 flex-1 sm:flex-none", children: [
8121
+ return /* @__PURE__ */ jsxs("div", { class: "flex gap-1.5 md:gap-2 w-full items-center", children: [
7869
8122
  /* @__PURE__ */ jsxs(
7870
8123
  "select",
7871
8124
  {
@@ -7878,7 +8131,7 @@ var TextFilter = (props) => {
7878
8131
  props.onFilterChange(props.field, currentValue, newOperator);
7879
8132
  }
7880
8133
  },
7881
- class: "select select-bordered select-sm w-28",
8134
+ class: "select select-bordered select-sm w-24 md:w-32 flex-shrink-0 text-xs",
7882
8135
  "data-testid": `datatable-filter-${props.field}-operator`,
7883
8136
  children: [
7884
8137
  /* @__PURE__ */ jsx("option", { value: "contains", children: "Contains" }),
@@ -7910,16 +8163,15 @@ var TextFilter = (props) => {
7910
8163
  }
7911
8164
  },
7912
8165
  placeholder: `Filter by ${props.label}`,
7913
- class: "input input-bordered input-sm flex-1",
8166
+ class: "input input-bordered input-sm flex-1 min-w-0",
7914
8167
  "data-testid": `datatable-filter-${props.field}-input`
7915
- },
7916
- props.field
8168
+ }
7917
8169
  )
7918
8170
  ] });
7919
8171
  };
7920
8172
  var NumberFilter = (props) => {
7921
8173
  const currentOperator = props.filterOperators.value[props.field] || "eq";
7922
- return /* @__PURE__ */ jsxs("div", { class: "flex gap-2 flex-1 sm:flex-none", children: [
8174
+ return /* @__PURE__ */ jsxs("div", { class: "flex gap-1.5 md:gap-2 w-full items-center", children: [
7923
8175
  /* @__PURE__ */ jsxs(
7924
8176
  "select",
7925
8177
  {
@@ -7932,7 +8184,7 @@ var NumberFilter = (props) => {
7932
8184
  props.onFilterChange(props.field, currentValue, newOperator);
7933
8185
  }
7934
8186
  },
7935
- class: "select select-bordered select-sm w-16",
8187
+ class: "select select-bordered select-sm w-16 md:w-20 flex-shrink-0 text-xs font-medium",
7936
8188
  "data-testid": `datatable-filter-${props.field}-operator`,
7937
8189
  children: [
7938
8190
  /* @__PURE__ */ jsx("option", { value: "eq", children: "=" }),
@@ -7965,10 +8217,9 @@ var NumberFilter = (props) => {
7965
8217
  }
7966
8218
  },
7967
8219
  placeholder: `Filter by ${props.label}`,
7968
- class: "input input-bordered input-sm flex-1",
8220
+ class: "input input-bordered input-sm flex-1 min-w-0",
7969
8221
  "data-testid": `datatable-filter-${props.field}-input`
7970
- },
7971
- props.field
8222
+ }
7972
8223
  )
7973
8224
  ] });
7974
8225
  };
@@ -7976,13 +8227,13 @@ var BooleanFilter = (props) => {
7976
8227
  return /* @__PURE__ */ jsxs(
7977
8228
  "select",
7978
8229
  {
7979
- value: props.value,
8230
+ value: props.value || "",
7980
8231
  onChange: (e) => {
7981
8232
  const stringValue = e.target.value;
7982
8233
  const value = stringValue === "true" ? true : stringValue === "false" ? false : stringValue;
7983
8234
  props.onFilterChange(props.field, value, "eq");
7984
8235
  },
7985
- class: "select select-bordered flex-1 sm:flex-none sm:w-auto",
8236
+ class: "select select-bordered select-sm w-full",
7986
8237
  disabled: props.isLoading,
7987
8238
  "data-testid": `datatable-filter-${props.field}-input`,
7988
8239
  children: [
@@ -7990,89 +8241,640 @@ var BooleanFilter = (props) => {
7990
8241
  /* @__PURE__ */ jsx("option", { value: "true", children: "Yes" }),
7991
8242
  /* @__PURE__ */ jsx("option", { value: "false", children: "No" })
7992
8243
  ]
7993
- },
7994
- props.field
8244
+ }
7995
8245
  );
7996
8246
  };
7997
- var FiltersRow = (props) => {
7998
- const filterOptionsState = inject(ZINIA_DATA_TABLE_FILTER_OPTIONS_STATE_KEY);
7999
- const filterOptionsLoading = inject(ZINIA_DATA_TABLE_FILTER_OPTIONS_LOADING_KEY);
8000
- return /* @__PURE__ */ jsx("div", { class: "mb-4", children: /* @__PURE__ */ jsxs("div", { class: "flex flex-col sm:flex-row gap-3 sm:items-center", children: [
8001
- /* @__PURE__ */ jsx("div", { class: "flex flex-col sm:flex-row gap-2 sm:gap-3 flex-1", children: Object.entries(props.columns).map(([field, column]) => {
8002
- if (!column?.filterable) return null;
8003
- const currentFilter = props.activeFilters[field];
8004
- const currentValue = currentFilter?.value ?? "";
8005
- const filterType = getFilterType(field, column, props.fieldsMetadata);
8006
- if (filterType === "select") {
8007
- const filterOptions = getFilterOptions(field, column, props.fieldsMetadata, filterOptionsState?.value);
8008
- return /* @__PURE__ */ jsx(
8009
- SelectFilter,
8010
- {
8011
- field,
8012
- value: currentValue,
8013
- options: filterOptions,
8014
- label: column.label,
8015
- isLoading: props.isLoading,
8016
- isOptionsLoading: filterOptionsLoading?.value?.[field] ?? false,
8017
- onFilterChange: props.onFilterChange
8018
- },
8019
- field
8020
- );
8247
+ var comboboxState = reactive({});
8248
+ var ComboboxFilter = (props) => {
8249
+ if (!comboboxState[props.field]) {
8250
+ comboboxState[props.field] = {
8251
+ isOpen: false,
8252
+ selectedIndex: -1
8253
+ };
8254
+ }
8255
+ const state = comboboxState[props.field];
8256
+ const searchQuery = computed(() => props.filterInputValues.value[props.field] || "");
8257
+ const selectedOption = computed(() => {
8258
+ if (!props.value) return "";
8259
+ return props.options.find((opt) => opt.value === props.value)?.label || String(props.value);
8260
+ });
8261
+ if (!(props.field in props.filterInputValues.value) && props.value) {
8262
+ const label = selectedOption.value;
8263
+ if (label) {
8264
+ props.filterInputValues.value[props.field] = label;
8265
+ }
8266
+ }
8267
+ const filteredOptions = computed(() => {
8268
+ const query = searchQuery.value.trim().toLowerCase();
8269
+ if (!query) {
8270
+ return props.options;
8271
+ }
8272
+ return props.options.filter((opt) => opt.label.toLowerCase().includes(query));
8273
+ });
8274
+ const isNewValue = computed(() => {
8275
+ if (!props.allowCreate || !searchQuery.value.trim()) return false;
8276
+ const query = searchQuery.value.trim();
8277
+ return !props.options.some((opt) => opt.label.toLowerCase() === query.toLowerCase());
8278
+ });
8279
+ const isInvalidValue = computed(() => {
8280
+ if (!searchQuery.value.trim()) return false;
8281
+ if (props.allowCreate) return false;
8282
+ const query = searchQuery.value.trim();
8283
+ return !props.options.some((opt) => opt.label.toLowerCase() === query.toLowerCase());
8284
+ });
8285
+ const handleInput = (e) => {
8286
+ const value = e.target.value;
8287
+ props.filterInputValues.value[props.field] = value;
8288
+ state.isOpen = true;
8289
+ state.selectedIndex = -1;
8290
+ const exactMatch = props.options.find((opt) => opt.label.toLowerCase() === value.toLowerCase().trim());
8291
+ if (exactMatch) {
8292
+ props.onFilterChange(props.field, exactMatch.value, "eq");
8293
+ }
8294
+ };
8295
+ const handleSelectOption = (option) => {
8296
+ props.filterInputValues.value[props.field] = option.label;
8297
+ props.onFilterChange(props.field, option.value, "eq");
8298
+ state.isOpen = false;
8299
+ state.selectedIndex = -1;
8300
+ };
8301
+ const handleSelectNewValue = () => {
8302
+ const newValue = searchQuery.value.trim();
8303
+ if (newValue) {
8304
+ props.onFilterChange(props.field, newValue, "eq");
8305
+ state.isOpen = false;
8306
+ state.selectedIndex = -1;
8307
+ }
8308
+ };
8309
+ const handleKeyDown = (e) => {
8310
+ if (e.key === "Escape") {
8311
+ e.preventDefault();
8312
+ e.stopPropagation();
8313
+ state.isOpen = false;
8314
+ state.selectedIndex = -1;
8315
+ if (props.value) {
8316
+ props.filterInputValues.value[props.field] = selectedOption.value;
8317
+ } else {
8318
+ props.filterInputValues.value[props.field] = "";
8021
8319
  }
8022
- if (filterType === "text") {
8023
- return /* @__PURE__ */ jsx(
8024
- TextFilter,
8025
- {
8026
- field,
8027
- value: currentValue,
8028
- label: column.label,
8029
- filterInputValues: props.filterInputValues,
8030
- filterOperators: props.filterOperators,
8031
- onFilterChange: props.onFilterChange
8032
- },
8033
- field
8034
- );
8320
+ return;
8321
+ }
8322
+ if (e.key === "Enter") {
8323
+ e.preventDefault();
8324
+ e.stopPropagation();
8325
+ if (state.selectedIndex >= 0 && state.selectedIndex < filteredOptions.value.length) {
8326
+ handleSelectOption(filteredOptions.value[state.selectedIndex]);
8327
+ return;
8035
8328
  }
8036
- if (filterType === "number") {
8037
- return /* @__PURE__ */ jsx(
8038
- NumberFilter,
8039
- {
8040
- field,
8041
- value: currentValue,
8042
- label: column.label,
8043
- filterInputValues: props.filterInputValues,
8044
- filterOperators: props.filterOperators,
8045
- onFilterChange: props.onFilterChange
8046
- },
8047
- field
8048
- );
8329
+ if (state.selectedIndex === filteredOptions.value.length && isNewValue.value && props.allowCreate) {
8330
+ handleSelectNewValue();
8331
+ return;
8049
8332
  }
8050
- if (filterType === "boolean") {
8051
- return /* @__PURE__ */ jsx(
8052
- BooleanFilter,
8053
- {
8054
- field,
8055
- value: currentValue,
8056
- label: column.label,
8057
- isLoading: props.isLoading,
8058
- onFilterChange: props.onFilterChange
8059
- },
8060
- field
8061
- );
8333
+ if (searchQuery.value.trim() === "") {
8334
+ state.isOpen = false;
8335
+ state.selectedIndex = -1;
8336
+ if (props.value) {
8337
+ props.onFilterChange(props.field, "", "eq");
8338
+ props.filterInputValues.value[props.field] = "";
8339
+ }
8340
+ return;
8341
+ }
8342
+ const currentLabel = selectedOption.value;
8343
+ const queryMatchesCurrentValue = currentLabel && searchQuery.value.trim().toLowerCase() === currentLabel.toLowerCase();
8344
+ if (queryMatchesCurrentValue) {
8345
+ state.isOpen = false;
8346
+ state.selectedIndex = -1;
8347
+ return;
8348
+ }
8349
+ if (isInvalidValue.value) {
8350
+ state.isOpen = false;
8351
+ state.selectedIndex = -1;
8352
+ const currentLabel2 = selectedOption.value;
8353
+ if (currentLabel2) {
8354
+ props.filterInputValues.value[props.field] = currentLabel2;
8355
+ } else {
8356
+ props.filterInputValues.value[props.field] = "";
8357
+ }
8358
+ return;
8359
+ }
8360
+ if (isNewValue.value && state.selectedIndex < 0 && props.allowCreate) {
8361
+ handleSelectNewValue();
8362
+ return;
8363
+ }
8364
+ const matchingOption = props.options.find(
8365
+ (opt) => opt.label.toLowerCase() === searchQuery.value.trim().toLowerCase()
8366
+ );
8367
+ if (matchingOption) {
8368
+ handleSelectOption(matchingOption);
8369
+ return;
8370
+ }
8371
+ state.isOpen = false;
8372
+ state.selectedIndex = -1;
8373
+ return;
8374
+ }
8375
+ if (e.key === "ArrowDown") {
8376
+ e.preventDefault();
8377
+ e.stopPropagation();
8378
+ state.isOpen = true;
8379
+ const totalOptions = filteredOptions.value.length + (isNewValue.value && props.allowCreate ? 1 : 0);
8380
+ if (totalOptions > 0) {
8381
+ const currentIndex = state.selectedIndex;
8382
+ const newIndex = currentIndex < 0 ? 0 : (currentIndex + 1) % totalOptions;
8383
+ state.selectedIndex = newIndex;
8384
+ nextTick(() => {
8385
+ scrollToSelectedOption(newIndex);
8386
+ });
8387
+ }
8388
+ return;
8389
+ }
8390
+ if (e.key === "ArrowUp") {
8391
+ e.preventDefault();
8392
+ e.stopPropagation();
8393
+ state.isOpen = true;
8394
+ const totalOptions = filteredOptions.value.length + (isNewValue.value && props.allowCreate ? 1 : 0);
8395
+ if (totalOptions > 0) {
8396
+ const currentIndex = state.selectedIndex;
8397
+ const newIndex = currentIndex < 0 ? totalOptions - 1 : (currentIndex - 1 + totalOptions) % totalOptions;
8398
+ state.selectedIndex = newIndex;
8399
+ nextTick(() => {
8400
+ scrollToSelectedOption(newIndex);
8401
+ });
8402
+ }
8403
+ return;
8404
+ }
8405
+ };
8406
+ const handleFocus = () => {
8407
+ state.isOpen = true;
8408
+ };
8409
+ const scrollToSelectedOption = (index) => {
8410
+ const container = document.querySelector(`[data-combobox-dropdown="${props.field}"]`);
8411
+ if (!container) return;
8412
+ const optionId = index === filteredOptions.value.length ? "option-new" : `option-${index}`;
8413
+ const selectedElement = container.querySelector(`#${optionId}`);
8414
+ if (!selectedElement) return;
8415
+ const elementTop = selectedElement.offsetTop;
8416
+ const elementHeight = selectedElement.offsetHeight;
8417
+ const containerHeight = container.clientHeight;
8418
+ const containerScrollTop = container.scrollTop;
8419
+ if (elementTop < containerScrollTop) {
8420
+ container.scrollTop = elementTop;
8421
+ } else if (elementTop + elementHeight > containerScrollTop + containerHeight) {
8422
+ container.scrollTop = elementTop + elementHeight - containerHeight;
8423
+ }
8424
+ };
8425
+ const handleBlur = (e) => {
8426
+ const relatedTarget = e.relatedTarget || document.activeElement;
8427
+ const container = document.querySelector(`[data-combobox-container="${props.field}"]`);
8428
+ if (container && container.contains(relatedTarget)) {
8429
+ return;
8430
+ }
8431
+ state.isOpen = false;
8432
+ const currentQuery = searchQuery.value.trim();
8433
+ const currentValue = props.value;
8434
+ const currentLabel = selectedOption.value;
8435
+ if (currentQuery === "") {
8436
+ if (currentValue) {
8437
+ props.onFilterChange(props.field, "", "eq");
8438
+ props.filterInputValues.value[props.field] = "";
8439
+ }
8440
+ } else {
8441
+ const queryMatchesCurrentValue = currentLabel && currentQuery.toLowerCase() === currentLabel.toLowerCase();
8442
+ if (isInvalidValue.value) {
8443
+ if (currentLabel) {
8444
+ props.filterInputValues.value[props.field] = currentLabel;
8445
+ } else {
8446
+ props.filterInputValues.value[props.field] = "";
8447
+ }
8448
+ return;
8449
+ }
8450
+ if (!queryMatchesCurrentValue) {
8451
+ const matchingOption = props.options.find((opt) => opt.label.toLowerCase() === currentQuery.toLowerCase());
8452
+ if (matchingOption) {
8453
+ props.onFilterChange(props.field, matchingOption.value, "eq");
8454
+ } else if (props.allowCreate) {
8455
+ props.onFilterChange(props.field, currentQuery, "eq");
8456
+ } else {
8457
+ if (currentLabel) {
8458
+ props.filterInputValues.value[props.field] = currentLabel;
8459
+ }
8460
+ }
8461
+ } else {
8462
+ if (currentLabel && currentQuery !== currentLabel) {
8463
+ props.filterInputValues.value[props.field] = currentLabel;
8464
+ }
8465
+ }
8466
+ }
8467
+ };
8468
+ return /* @__PURE__ */ jsxs("div", { class: "relative w-full", "data-combobox-container": props.field, children: [
8469
+ /* @__PURE__ */ jsx(
8470
+ "input",
8471
+ {
8472
+ type: "text",
8473
+ value: searchQuery.value,
8474
+ onInput: handleInput,
8475
+ onKeydown: handleKeyDown,
8476
+ onFocus: handleFocus,
8477
+ onBlur: handleBlur,
8478
+ placeholder: props.isOptionsLoading ? "Loading options..." : `Search ${props.label}`,
8479
+ class: "input input-bordered input-sm w-full",
8480
+ disabled: props.isLoading || props.isOptionsLoading,
8481
+ "data-testid": `datatable-filter-${props.field}-input`
8482
+ }
8483
+ ),
8484
+ /* @__PURE__ */ jsx("div", { class: "absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none", children: /* @__PURE__ */ jsx(
8485
+ "svg",
8486
+ {
8487
+ xmlns: "http://www.w3.org/2000/svg",
8488
+ class: "h-4 w-4 text-base-content/50",
8489
+ fill: "none",
8490
+ viewBox: "0 0 24 24",
8491
+ stroke: "currentColor",
8492
+ "stroke-width": "2",
8493
+ children: /* @__PURE__ */ jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", d: "M8 9l4-4 4 4m0 6l-4 4-4-4" })
8494
+ }
8495
+ ) }),
8496
+ state.isOpen && /* @__PURE__ */ jsx(
8497
+ "div",
8498
+ {
8499
+ "data-combobox-dropdown": props.field,
8500
+ class: "absolute z-50 mt-1 bg-base-100 border border-base-300 rounded-box shadow-lg max-h-60 overflow-auto w-full",
8501
+ children: /* @__PURE__ */ jsx("ul", { class: "menu w-full", role: "listbox", id: `combobox-listbox-${props.field}`, children: props.isOptionsLoading ? /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("span", { class: "text-sm text-base-content/70 p-2", children: "Loading options..." }) }) : filteredOptions.value.length === 0 && !isNewValue.value && !isInvalidValue.value ? /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("span", { class: "text-sm text-base-content/70 p-2", children: "No options available" }) }) : isInvalidValue.value ? /* @__PURE__ */ jsx("li", { class: "bg-error/10 border-l-4 border-error", children: /* @__PURE__ */ jsx("div", { class: "p-2", children: /* @__PURE__ */ jsxs("div", { class: "flex items-center gap-2", children: [
8502
+ /* @__PURE__ */ jsx(
8503
+ "svg",
8504
+ {
8505
+ xmlns: "http://www.w3.org/2000/svg",
8506
+ class: "h-4 w-4 text-error flex-shrink-0",
8507
+ fill: "none",
8508
+ viewBox: "0 0 24 24",
8509
+ stroke: "currentColor",
8510
+ "stroke-width": "2",
8511
+ children: /* @__PURE__ */ jsx(
8512
+ "path",
8513
+ {
8514
+ "stroke-linecap": "round",
8515
+ "stroke-linejoin": "round",
8516
+ d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
8517
+ }
8518
+ )
8519
+ }
8520
+ ),
8521
+ /* @__PURE__ */ jsxs("div", { class: "text-sm", children: [
8522
+ /* @__PURE__ */ jsx("p", { class: "font-medium text-error", children: "Invalid value" }),
8523
+ /* @__PURE__ */ jsxs("p", { class: "text-error/80", children: [
8524
+ '"',
8525
+ searchQuery.value,
8526
+ '" is not a valid option. Please select from the list.'
8527
+ ] })
8528
+ ] })
8529
+ ] }) }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
8530
+ filteredOptions.value.map((option, index) => /* @__PURE__ */ jsx(
8531
+ "li",
8532
+ {
8533
+ id: `option-${index}`,
8534
+ role: "option",
8535
+ "aria-selected": index === state.selectedIndex,
8536
+ class: index === state.selectedIndex ? "bg-base-200" : "",
8537
+ children: /* @__PURE__ */ jsx(
8538
+ "a",
8539
+ {
8540
+ href: "#",
8541
+ tabindex: 0,
8542
+ onClick: (e) => {
8543
+ e.preventDefault();
8544
+ e.stopPropagation();
8545
+ handleSelectOption(option);
8546
+ },
8547
+ onMousedown: (e) => {
8548
+ e.preventDefault();
8549
+ },
8550
+ class: "w-full",
8551
+ children: option.label
8552
+ }
8553
+ )
8554
+ },
8555
+ option.value
8556
+ )),
8557
+ isNewValue.value && props.allowCreate && /* @__PURE__ */ jsx(
8558
+ "li",
8559
+ {
8560
+ id: "option-new",
8561
+ role: "option",
8562
+ "aria-selected": state.selectedIndex === filteredOptions.value.length,
8563
+ class: state.selectedIndex === filteredOptions.value.length ? "bg-base-200" : "",
8564
+ children: /* @__PURE__ */ jsx(
8565
+ "a",
8566
+ {
8567
+ href: "#",
8568
+ tabindex: 0,
8569
+ onClick: (e) => {
8570
+ e.preventDefault();
8571
+ e.stopPropagation();
8572
+ handleSelectNewValue();
8573
+ },
8574
+ onMousedown: (e) => {
8575
+ e.preventDefault();
8576
+ },
8577
+ class: "w-full",
8578
+ children: /* @__PURE__ */ jsxs("div", { class: "flex items-center gap-2", children: [
8579
+ /* @__PURE__ */ jsx(
8580
+ "svg",
8581
+ {
8582
+ xmlns: "http://www.w3.org/2000/svg",
8583
+ class: "h-4 w-4 text-success",
8584
+ fill: "none",
8585
+ viewBox: "0 0 24 24",
8586
+ stroke: "currentColor",
8587
+ "stroke-width": "2",
8588
+ children: /* @__PURE__ */ jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", d: "M12 4v16m8-8H4" })
8589
+ }
8590
+ ),
8591
+ /* @__PURE__ */ jsxs("span", { class: "text-sm", children: [
8592
+ /* @__PURE__ */ jsx("span", { class: "font-medium text-success", children: "New value:" }),
8593
+ ' "',
8594
+ searchQuery.value,
8595
+ '"'
8596
+ ] })
8597
+ ] })
8598
+ }
8599
+ )
8600
+ }
8601
+ )
8602
+ ] }) })
8062
8603
  }
8604
+ )
8605
+ ] });
8606
+ };
8607
+ var FilterDrawer = (props) => {
8608
+ const injectedFilterOptionsState = inject(
8609
+ ZINIA_DATA_TABLE_FILTER_OPTIONS_STATE_KEY,
8610
+ void 0
8611
+ );
8612
+ const injectedFilterOptionsLoading = inject(
8613
+ ZINIA_DATA_TABLE_FILTER_OPTIONS_LOADING_KEY,
8614
+ void 0
8615
+ );
8616
+ const filterOptionsState = props.filterOptionsState || injectedFilterOptionsState;
8617
+ const filterOptionsLoading = props.filterOptionsLoading || injectedFilterOptionsLoading;
8618
+ const filterableColumns = Object.entries(props.columns).filter(([_, column]) => column?.filterable);
8619
+ return /* @__PURE__ */ jsxs(
8620
+ "div",
8621
+ {
8622
+ class: `absolute inset-0 z-50 pointer-events-none ${props.isOpen ? "" : "hidden"}`,
8623
+ style: { display: props.isOpen ? "block" : "none" },
8624
+ children: [
8625
+ /* @__PURE__ */ jsx(
8626
+ "div",
8627
+ {
8628
+ class: "absolute inset-0 bg-black/50 transition-opacity opacity-100 pointer-events-auto",
8629
+ onClick: () => props.onClose()
8630
+ }
8631
+ ),
8632
+ /* @__PURE__ */ jsxs(
8633
+ "aside",
8634
+ {
8635
+ class: "absolute top-0 left-0 h-full h-[600px] max-h-[90vh] w-full md:w-80 bg-base-100 flex flex-col shadow-xl transform transition-transform duration-300 ease-out translate-x-0 pointer-events-auto",
8636
+ onClick: (e) => e.stopPropagation(),
8637
+ "data-testid": `${props.tableName || "datatable"}-filter-drawer`,
8638
+ children: [
8639
+ /* @__PURE__ */ jsxs("div", { class: "flex items-center justify-between p-2 md:p-3 border-b border-base-300 bg-base-200/50 flex-shrink-0", children: [
8640
+ /* @__PURE__ */ jsxs("div", { class: "flex items-center gap-2", children: [
8641
+ /* @__PURE__ */ jsx("h3", { class: "text-sm md:text-base font-semibold", children: "Filters" }),
8642
+ Object.keys(props.activeFilters).length > 0 && /* @__PURE__ */ jsx("span", { class: "badge badge-primary badge-sm", children: Object.keys(props.activeFilters).length })
8643
+ ] }),
8644
+ /* @__PURE__ */ jsxs("div", { class: "flex items-center gap-2", children: [
8645
+ Object.keys(props.activeFilters).length > 0 && /* @__PURE__ */ jsxs(
8646
+ "button",
8647
+ {
8648
+ onClick: () => props.onClearAllFilters(),
8649
+ class: "btn btn-ghost btn-sm",
8650
+ disabled: props.isLoading,
8651
+ title: "Clear all filters",
8652
+ "data-testid": `${props.tableName || "datatable"}-filter-drawer-clear-all`,
8653
+ children: [
8654
+ /* @__PURE__ */ jsx(
8655
+ "svg",
8656
+ {
8657
+ xmlns: "http://www.w3.org/2000/svg",
8658
+ class: "h-4 w-4 mr-1",
8659
+ fill: "none",
8660
+ viewBox: "0 0 24 24",
8661
+ stroke: "currentColor",
8662
+ children: /* @__PURE__ */ jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", "stroke-width": "2", d: "M6 18L18 6M6 6l12 12" })
8663
+ }
8664
+ ),
8665
+ "Clear All"
8666
+ ]
8667
+ }
8668
+ ),
8669
+ /* @__PURE__ */ jsx(
8670
+ "button",
8671
+ {
8672
+ class: "btn btn-ghost btn-sm btn-circle hover:bg-base-300",
8673
+ onClick: () => props.onClose(),
8674
+ "aria-label": "Close filters",
8675
+ children: /* @__PURE__ */ jsx(
8676
+ "svg",
8677
+ {
8678
+ xmlns: "http://www.w3.org/2000/svg",
8679
+ class: "h-5 w-5",
8680
+ fill: "none",
8681
+ viewBox: "0 0 24 24",
8682
+ stroke: "currentColor",
8683
+ children: /* @__PURE__ */ jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", "stroke-width": "2", d: "M6 18L18 6M6 6l12 12" })
8684
+ }
8685
+ )
8686
+ }
8687
+ )
8688
+ ] })
8689
+ ] }),
8690
+ /* @__PURE__ */ jsx("div", { class: "p-2 flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx("div", { class: "space-y-2", children: filterableColumns.map(([field, column]) => {
8691
+ const currentFilter = props.activeFilters[field];
8692
+ const currentValue = currentFilter?.value ?? "";
8693
+ const filterType = getFilterType(field, column, props.fieldsMetadata);
8694
+ const hasValue = currentValue !== "" && currentValue !== null && currentValue !== void 0;
8695
+ return /* @__PURE__ */ jsxs(
8696
+ "div",
8697
+ {
8698
+ class: `space-y-1.5 md:space-y-2 p-2 md:p-2.5 rounded-lg transition-colors ${hasValue ? "bg-primary/10 border border-primary/20" : "bg-base-200/30 border border-base-300/50"}`,
8699
+ children: [
8700
+ /* @__PURE__ */ jsxs("label", { class: "text-xs md:text-sm font-semibold text-base-content flex items-center gap-1.5", children: [
8701
+ /* @__PURE__ */ jsx("span", { children: column.label }),
8702
+ hasValue && /* @__PURE__ */ jsx("span", { class: "badge badge-primary badge-xs", children: "Active" })
8703
+ ] }),
8704
+ filterType === "select" && /* @__PURE__ */ jsx(
8705
+ SelectFilter,
8706
+ {
8707
+ field,
8708
+ value: currentValue,
8709
+ options: getFilterOptions(
8710
+ field,
8711
+ column,
8712
+ props.fieldsMetadata,
8713
+ filterOptionsState?.value || {}
8714
+ ),
8715
+ label: column.label,
8716
+ isLoading: props.isLoading,
8717
+ isOptionsLoading: filterOptionsLoading?.value?.[field] ?? false,
8718
+ onFilterChange: props.onFilterChange
8719
+ }
8720
+ ),
8721
+ filterType === "text" && /* @__PURE__ */ jsx(
8722
+ TextFilter,
8723
+ {
8724
+ field,
8725
+ value: currentValue,
8726
+ label: column.label,
8727
+ filterInputValues: props.filterInputValues,
8728
+ filterOperators: props.filterOperators,
8729
+ onFilterChange: props.onFilterChange
8730
+ }
8731
+ ),
8732
+ filterType === "number" && /* @__PURE__ */ jsx(
8733
+ NumberFilter,
8734
+ {
8735
+ field,
8736
+ value: currentValue,
8737
+ label: column.label,
8738
+ filterInputValues: props.filterInputValues,
8739
+ filterOperators: props.filterOperators,
8740
+ onFilterChange: props.onFilterChange
8741
+ }
8742
+ ),
8743
+ filterType === "boolean" && /* @__PURE__ */ jsx(
8744
+ BooleanFilter,
8745
+ {
8746
+ field,
8747
+ value: currentValue,
8748
+ label: column.label,
8749
+ isLoading: props.isLoading,
8750
+ onFilterChange: props.onFilterChange
8751
+ }
8752
+ ),
8753
+ filterType === "combobox" && /* @__PURE__ */ jsx(
8754
+ ComboboxFilter,
8755
+ {
8756
+ field,
8757
+ value: currentValue,
8758
+ options: getFilterOptions(
8759
+ field,
8760
+ column,
8761
+ props.fieldsMetadata,
8762
+ filterOptionsState?.value || {}
8763
+ ),
8764
+ label: column.label,
8765
+ isLoading: props.isLoading,
8766
+ isOptionsLoading: filterOptionsLoading?.value?.[field] ?? false,
8767
+ allowCreate: column.filterAllowCreate ?? false,
8768
+ filterInputValues: props.filterInputValues,
8769
+ onFilterChange: props.onFilterChange
8770
+ }
8771
+ )
8772
+ ]
8773
+ },
8774
+ field
8775
+ );
8776
+ }) }) }),
8777
+ /* @__PURE__ */ jsx("div", { class: "p-2 md:p-3 border-t border-base-300 bg-base-200/50 flex-shrink-0", children: /* @__PURE__ */ jsx(
8778
+ "button",
8779
+ {
8780
+ class: "btn btn-primary w-full btn-sm text-xs md:text-sm",
8781
+ onClick: () => props.onClose(),
8782
+ "data-testid": `${props.tableName || "datatable"}-filter-drawer-apply`,
8783
+ children: "Done"
8784
+ }
8785
+ ) })
8786
+ ]
8787
+ }
8788
+ )
8789
+ ]
8790
+ }
8791
+ );
8792
+ };
8793
+ function formatFilterValue(field, value, column, fieldsMetadata, filterOptionsState) {
8794
+ if (value === "" || value === null || value === void 0) return "";
8795
+ if (typeof value === "boolean") {
8796
+ return value ? "Yes" : "No";
8797
+ }
8798
+ const options = getFilterOptions(field, column, fieldsMetadata, filterOptionsState);
8799
+ if (options.length > 0) {
8800
+ const option = options.find((opt) => opt.value === value);
8801
+ if (option) return option.label;
8802
+ }
8803
+ if (value instanceof Date) {
8804
+ return value.toLocaleDateString();
8805
+ }
8806
+ const strValue = String(value);
8807
+ return strValue.length > 20 ? strValue.substring(0, 20) + "..." : strValue;
8808
+ }
8809
+ function getOperatorLabel(operator) {
8810
+ const labels = {
8811
+ eq: "=",
8812
+ contains: "contains",
8813
+ gt: ">",
8814
+ lt: "<",
8815
+ in: "in",
8816
+ between: "between"
8817
+ };
8818
+ return labels[operator] || operator;
8819
+ }
8820
+ var FiltersRow = (props) => {
8821
+ const filterableColumns = Object.entries(props.columns).filter(([_, column]) => column?.filterable);
8822
+ const activeFilterBadges = filterableColumns.map(([field, column]) => {
8823
+ const filter = props.activeFilters[field];
8824
+ if (!filter || filter.value === "" || filter.value === null || filter.value === void 0) {
8063
8825
  return null;
8064
- }) }),
8065
- /* @__PURE__ */ jsxs("div", { class: "flex gap-2 sm:gap-3", children: [
8826
+ }
8827
+ const displayValue = formatFilterValue(
8828
+ field,
8829
+ filter.value,
8830
+ column,
8831
+ props.fieldsMetadata,
8832
+ props.filterOptionsState?.value
8833
+ );
8834
+ const operator = filter.operator || "eq";
8835
+ const operatorLabel = getOperatorLabel(operator);
8836
+ return {
8837
+ field,
8838
+ label: column.label,
8839
+ value: filter.value,
8840
+ displayValue,
8841
+ operator,
8842
+ operatorLabel
8843
+ };
8844
+ }).filter((badge) => badge !== null);
8845
+ const handleRemoveFilter = (field) => {
8846
+ props.filterInputValues.value[field] = "";
8847
+ if (props.filterOperators.value[field]) {
8848
+ delete props.filterOperators.value[field];
8849
+ }
8850
+ props.onFilterChange(field, "", "eq");
8851
+ };
8852
+ return /* @__PURE__ */ jsxs("div", { class: "mb-4 space-y-2", children: [
8853
+ /* @__PURE__ */ jsxs("div", { class: "flex items-center gap-2", children: [
8066
8854
  /* @__PURE__ */ jsxs(
8067
8855
  "button",
8068
8856
  {
8069
- onClick: () => props.onClearAllFilters(),
8070
- class: "btn btn-outline flex-1 sm:flex-none",
8071
- disabled: props.isLoading || props.filterCount === 0,
8072
- "data-testid": `${props.tableName || "datatable"}-filters-clear-all`,
8857
+ onClick: () => {
8858
+ if (props.filterDrawerOpen.value) {
8859
+ props.onCloseFilterDrawer();
8860
+ } else {
8861
+ props.onOpenFilterDrawer();
8862
+ }
8863
+ },
8864
+ class: "btn btn-outline btn-sm",
8865
+ "data-testid": `${props.tableName || "datatable"}-filters-toggle`,
8073
8866
  children: [
8074
- /* @__PURE__ */ jsx("span", { class: "hidden sm:inline", children: "Clear Filters" }),
8075
- /* @__PURE__ */ jsx("span", { class: "sm:hidden", children: "Clear" })
8867
+ /* @__PURE__ */ jsx("svg", { class: "w-4 h-4 mr-1", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx(
8868
+ "path",
8869
+ {
8870
+ "stroke-linecap": "round",
8871
+ "stroke-linejoin": "round",
8872
+ "stroke-width": "2",
8873
+ d: "M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"
8874
+ }
8875
+ ) }),
8876
+ "Filters",
8877
+ props.filterCount > 0 && /* @__PURE__ */ jsx("span", { class: "badge badge-primary badge-sm ml-1", children: props.filterCount })
8076
8878
  ]
8077
8879
  }
8078
8880
  ),
@@ -8080,55 +8882,43 @@ var FiltersRow = (props) => {
8080
8882
  "button",
8081
8883
  {
8082
8884
  onClick: () => props.onRefresh(),
8083
- class: "btn btn-primary flex-1 sm:flex-none",
8885
+ class: "btn btn-primary btn-sm ml-auto",
8084
8886
  disabled: props.isLoading,
8085
8887
  "data-testid": `${props.tableName || "datatable"}-refresh`,
8086
8888
  children: [
8087
- props.isLoading && /* @__PURE__ */ jsxs(
8088
- "svg",
8089
- {
8090
- class: "animate-spin -ml-1 mr-2 h-4 w-4",
8091
- xmlns: "http://www.w3.org/2000/svg",
8092
- fill: "none",
8093
- viewBox: "0 0 24 24",
8094
- children: [
8095
- /* @__PURE__ */ jsx(
8096
- "circle",
8097
- {
8098
- class: "opacity-25",
8099
- cx: "12",
8100
- cy: "12",
8101
- r: "10",
8102
- stroke: "currentColor",
8103
- "stroke-width": "4"
8104
- }
8105
- ),
8106
- /* @__PURE__ */ jsx(
8107
- "path",
8108
- {
8109
- class: "opacity-75",
8110
- fill: "currentColor",
8111
- d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
8112
- }
8113
- )
8114
- ]
8115
- }
8116
- ),
8117
- /* @__PURE__ */ jsx("span", { class: "hidden sm:inline", children: props.isLoading ? "Loading..." : "Refresh" }),
8118
- /* @__PURE__ */ jsx("span", { class: "sm:hidden", children: !props.isLoading && /* @__PURE__ */ jsx("svg", { class: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx(
8119
- "path",
8120
- {
8121
- "stroke-linecap": "round",
8122
- "stroke-linejoin": "round",
8123
- "stroke-width": "2",
8124
- d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
8125
- }
8126
- ) }) })
8889
+ props.isLoading && /* @__PURE__ */ jsx("span", { class: "loading loading-spinner loading-xs mr-2" }),
8890
+ props.isLoading ? "Loading..." : "Refresh"
8127
8891
  ]
8128
8892
  }
8129
8893
  )
8130
- ] })
8131
- ] }) });
8894
+ ] }),
8895
+ activeFilterBadges.length > 0 && /* @__PURE__ */ jsx("div", { class: "flex flex-wrap items-center gap-2", children: activeFilterBadges.map((badge) => /* @__PURE__ */ jsxs(
8896
+ "div",
8897
+ {
8898
+ class: "badge badge-primary badge-lg gap-1.5 px-3 py-2",
8899
+ "data-testid": `${props.tableName || "datatable"}-filter-badge-${badge.field}`,
8900
+ children: [
8901
+ /* @__PURE__ */ jsxs("span", { class: "font-medium", children: [
8902
+ badge.label,
8903
+ ":"
8904
+ ] }),
8905
+ badge.operator !== "eq" && badge.operator !== "contains" && /* @__PURE__ */ jsx("span", { class: "opacity-70", children: badge.operatorLabel }),
8906
+ /* @__PURE__ */ jsx("span", { children: badge.displayValue }),
8907
+ /* @__PURE__ */ jsx(
8908
+ "button",
8909
+ {
8910
+ class: "btn btn-ghost btn-xs btn-circle h-4 w-4 min-h-0 p-0 ml-1",
8911
+ onClick: () => handleRemoveFilter(badge.field),
8912
+ title: `Remove ${badge.label} filter`,
8913
+ "data-testid": `${props.tableName || "datatable"}-filter-badge-${badge.field}-remove`,
8914
+ children: /* @__PURE__ */ jsx("svg", { class: "w-3 h-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", "stroke-width": "2", d: "M6 18L18 6M6 6l12 12" }) })
8915
+ }
8916
+ )
8917
+ ]
8918
+ },
8919
+ badge.field
8920
+ )) })
8921
+ ] });
8132
8922
  };
8133
8923
  var LoadingSkeletons = (props) => {
8134
8924
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -8575,7 +9365,9 @@ function createDaisyUIDataTable() {
8575
9365
  const actions = inject(ZINIA_DATA_TABLE_ACTIONS_KEY);
8576
9366
  const searchInputValue = inject(ZINIA_DATA_TABLE_SEARCH_INPUT_KEY);
8577
9367
  const filterInputValues = inject(ZINIA_DATA_TABLE_FILTER_INPUTS_KEY);
8578
- const filterOperators = inject(ZINIA_DATA_TABLE_FILTER_OPERATORS_KEY);
9368
+ const filterOperators = inject(
9369
+ ZINIA_DATA_TABLE_FILTER_OPERATORS_KEY
9370
+ );
8579
9371
  const filterOptionsState = inject(ZINIA_DATA_TABLE_FILTER_OPTIONS_STATE_KEY);
8580
9372
  const filterOptionsLoading = inject(ZINIA_DATA_TABLE_FILTER_OPTIONS_LOADING_KEY);
8581
9373
  const tableName = inject(ZINIA_DATA_TABLE_NAME_KEY);
@@ -8602,6 +9394,27 @@ function createDaisyUIDataTable() {
8602
9394
  });
8603
9395
  const selectionMode = computed(() => options.selection?.mode ?? "none");
8604
9396
  const hasSelection = computed(() => selectionMode.value !== "none");
9397
+ const containerHeightClasses = computed(() => {
9398
+ const height = props.height ?? "auto";
9399
+ if (height === "fixed") {
9400
+ return "relative h-[850px] max-h-[90vh] flex flex-col";
9401
+ } else if (height === "auto") {
9402
+ return "relative flex-1 min-h-[670px] flex flex-col";
9403
+ } else if (typeof height === "number") {
9404
+ return `relative flex flex-col`;
9405
+ } else {
9406
+ return "relative flex flex-col";
9407
+ }
9408
+ });
9409
+ const containerHeightStyle = computed(() => {
9410
+ const height = props.height;
9411
+ if (typeof height === "number") {
9412
+ return { height: `${height}px` };
9413
+ } else if (typeof height === "string" && height !== "auto" && height !== "fixed") {
9414
+ return { height };
9415
+ }
9416
+ return {};
9417
+ });
8605
9418
  if (filterInputValues && Object.keys(filterInputValues.value).length === 0) {
8606
9419
  Object.entries(columns).forEach(([field, column]) => {
8607
9420
  if (column?.filterable) {
@@ -8627,7 +9440,7 @@ function createDaisyUIDataTable() {
8627
9440
  table.sort(field);
8628
9441
  }
8629
9442
  };
8630
- return /* @__PURE__ */ jsxs("div", { class: props.class, children: [
9443
+ return /* @__PURE__ */ jsxs("div", { class: `relative ${props.class || ""}`, children: [
8631
9444
  options.search?.searchableFields && options.search.searchableFields.length > 0 && searchInputValue && /* @__PURE__ */ jsx(
8632
9445
  SearchInput,
8633
9446
  {
@@ -8642,23 +9455,6 @@ function createDaisyUIDataTable() {
8642
9455
  }
8643
9456
  }
8644
9457
  ),
8645
- Object.values(columns).some((col) => col?.filterable) && filterInputValues && filterOperators && /* @__PURE__ */ jsx(
8646
- FiltersRow,
8647
- {
8648
- columns,
8649
- activeFilters: table.filters.active,
8650
- filterInputValues,
8651
- filterOperators,
8652
- filterOptionsState,
8653
- filterOptionsLoading,
8654
- fieldsMetadata: table.fieldsMetadata,
8655
- isLoading: table.isLoading,
8656
- filterCount: table.filters.count,
8657
- onFilterChange: (field, value, operator) => table.setFilter(field, value, operator),
8658
- onClearAllFilters: () => table.clearAllFilters(),
8659
- onRefresh: () => table.refresh()
8660
- }
8661
- ),
8662
9458
  hasSelection.value && slots["selection-actions"] && /* @__PURE__ */ jsx(
8663
9459
  SelectionActions,
8664
9460
  {
@@ -8670,92 +9466,107 @@ function createDaisyUIDataTable() {
8670
9466
  triggerBulkAction: table.triggerBulkAction
8671
9467
  }
8672
9468
  ),
8673
- table.isLoading ? /* @__PURE__ */ jsx(
8674
- LoadingSkeletons,
8675
- {
8676
- pageSize: table.pagination.pageSize,
8677
- columnKeys: columnKeys.value,
8678
- hasSelection: hasSelection.value
8679
- }
8680
- ) : table.hasError ? (
8681
- /* Show error state */
8682
- /* @__PURE__ */ jsxs("div", { class: "mt-4", children: [
8683
- /* @__PURE__ */ jsx(ErrorDisplay, { error: table.error || "An error occurred while loading data" }),
8684
- /* @__PURE__ */ jsx("div", { class: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxs(
8685
- "button",
8686
- {
8687
- onClick: () => table.refresh(),
8688
- class: "btn btn-primary",
8689
- children: [
8690
- /* @__PURE__ */ jsx("svg", { class: "w-4 h-4 mr-2", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx(
8691
- "path",
8692
- {
8693
- "stroke-linecap": "round",
8694
- "stroke-linejoin": "round",
8695
- "stroke-width": "2",
8696
- d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
8697
- }
8698
- ) }),
8699
- "Try Again"
8700
- ]
8701
- }
8702
- ) })
8703
- ] })
8704
- ) : /* @__PURE__ */ jsxs(Fragment, { children: [
8705
- /* @__PURE__ */ jsx(
8706
- MobileCards,
9469
+ /* @__PURE__ */ jsxs("div", { class: containerHeightClasses.value, style: containerHeightStyle.value, children: [
9470
+ Object.values(columns).some((col) => col?.filterable) && filterInputValues && filterOperators && /* @__PURE__ */ jsx(
9471
+ FiltersRow,
8707
9472
  {
8708
- data: table.data,
8709
9473
  columns,
8710
- columnKeys: columnKeys.value,
8711
- actions,
8712
- hasSelection: hasSelection.value,
8713
- selectionMode: selectionMode.value,
8714
- isAllSelected: table.selection.isAllSelected,
8715
- hasData: table.hasData,
8716
- isLoading: table.isLoading,
8717
- isEmpty: table.isEmpty,
8718
- sortingField: table.sorting.field,
8719
- sortingDirection: table.sorting.direction,
8720
- sortDrawerOpen: table.ui.sortDrawerOpen.value,
9474
+ activeFilters: table.filters.active,
9475
+ filterInputValues,
9476
+ filterOperators,
9477
+ filterOptionsState,
9478
+ filterOptionsLoading,
8721
9479
  fieldsMetadata: table.fieldsMetadata,
8722
- slots,
8723
- tableName,
8724
- isRowSelected: (row) => table.isRowSelected(row),
8725
- onSelectAll: () => table.selectAll(),
8726
- onClearSelection: () => table.clearSelection(),
8727
- onSelectRow: (row) => table.selectRow(row),
8728
- onOpenSortDrawer: () => table.ui.openSortDrawer(),
8729
- onCloseSortDrawer: () => table.ui.closeSortDrawer(),
8730
- onClearSort: () => table.clearSort(),
8731
- onSort: (field, direction) => table.sort(field, direction)
9480
+ isLoading: table.isLoading,
9481
+ filterCount: table.filters.count,
9482
+ filterDrawerOpen: table.ui.filterDrawerOpen,
9483
+ onFilterChange: (field, value, operator) => table.setFilter(field, value, operator),
9484
+ onClearAllFilters: () => table.clearAllFilters(),
9485
+ onRefresh: () => table.refresh(),
9486
+ onOpenFilterDrawer: () => table.ui.openFilterDrawer(),
9487
+ onCloseFilterDrawer: () => table.ui.closeFilterDrawer()
8732
9488
  }
8733
9489
  ),
8734
- /* @__PURE__ */ jsx(
8735
- DesktopTable,
9490
+ /* @__PURE__ */ jsx("div", { class: "w-full flex-1 min-h-0 overflow-auto", children: table.isLoading ? /* @__PURE__ */ jsx(
9491
+ LoadingSkeletons,
8736
9492
  {
8737
- data: table.data,
8738
- columns,
9493
+ pageSize: table.pagination.pageSize,
8739
9494
  columnKeys: columnKeys.value,
8740
- actions,
8741
- hasSelection: hasSelection.value,
8742
- selectionMode: selectionMode.value,
8743
- isAllSelected: table.selection.isAllSelected,
8744
- hasData: table.hasData,
8745
- isLoading: table.isLoading,
8746
- isEmpty: table.isEmpty,
8747
- sortingField: table.sorting.field,
8748
- sortingDirection: table.sorting.direction,
8749
- slots,
8750
- tableName,
8751
- isRowSelected: (row) => table.isRowSelected(row),
8752
- onSelectAll: () => table.selectAll(),
8753
- onClearSelection: () => table.clearSelection(),
8754
- onSelectRow: (row) => table.selectRow(row),
8755
- onSort: (field) => handleSort(field)
9495
+ hasSelection: hasSelection.value
8756
9496
  }
8757
- ),
8758
- table.hasData && !table.isLoading && /* @__PURE__ */ jsx(
9497
+ ) : table.hasError ? (
9498
+ /* Show error state */
9499
+ /* @__PURE__ */ jsxs("div", { class: "mt-4", children: [
9500
+ /* @__PURE__ */ jsx(ErrorDisplay, { error: table.error || "An error occurred while loading data" }),
9501
+ /* @__PURE__ */ jsx("div", { class: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxs("button", { onClick: () => table.refresh(), class: "btn btn-primary", children: [
9502
+ /* @__PURE__ */ jsx("svg", { class: "w-4 h-4 mr-2", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx(
9503
+ "path",
9504
+ {
9505
+ "stroke-linecap": "round",
9506
+ "stroke-linejoin": "round",
9507
+ "stroke-width": "2",
9508
+ d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
9509
+ }
9510
+ ) }),
9511
+ "Try Again"
9512
+ ] }) })
9513
+ ] })
9514
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
9515
+ /* @__PURE__ */ jsx(
9516
+ MobileCards,
9517
+ {
9518
+ data: table.data,
9519
+ columns,
9520
+ columnKeys: columnKeys.value,
9521
+ actions,
9522
+ hasSelection: hasSelection.value,
9523
+ selectionMode: selectionMode.value,
9524
+ isAllSelected: table.selection.isAllSelected,
9525
+ hasData: table.hasData,
9526
+ isLoading: table.isLoading,
9527
+ isEmpty: table.isEmpty,
9528
+ sortingField: table.sorting.field,
9529
+ sortingDirection: table.sorting.direction,
9530
+ sortDrawerOpen: table.ui.sortDrawerOpen.value,
9531
+ fieldsMetadata: table.fieldsMetadata,
9532
+ slots,
9533
+ tableName,
9534
+ isRowSelected: (row) => table.isRowSelected(row),
9535
+ onSelectAll: () => table.selectAll(),
9536
+ onClearSelection: () => table.clearSelection(),
9537
+ onSelectRow: (row) => table.selectRow(row),
9538
+ onOpenSortDrawer: () => table.ui.openSortDrawer(),
9539
+ onCloseSortDrawer: () => table.ui.closeSortDrawer(),
9540
+ onClearSort: () => table.clearSort(),
9541
+ onSort: (field, direction) => table.sort(field, direction)
9542
+ }
9543
+ ),
9544
+ /* @__PURE__ */ jsx(
9545
+ DesktopTable,
9546
+ {
9547
+ data: table.data,
9548
+ columns,
9549
+ columnKeys: columnKeys.value,
9550
+ actions,
9551
+ hasSelection: hasSelection.value,
9552
+ selectionMode: selectionMode.value,
9553
+ isAllSelected: table.selection.isAllSelected,
9554
+ hasData: table.hasData,
9555
+ isLoading: table.isLoading,
9556
+ isEmpty: table.isEmpty,
9557
+ sortingField: table.sorting.field,
9558
+ sortingDirection: table.sorting.direction,
9559
+ slots,
9560
+ tableName,
9561
+ isRowSelected: (row) => table.isRowSelected(row),
9562
+ onSelectAll: () => table.selectAll(),
9563
+ onClearSelection: () => table.clearSelection(),
9564
+ onSelectRow: (row) => table.selectRow(row),
9565
+ onSort: (field) => handleSort(field)
9566
+ }
9567
+ )
9568
+ ] }) }),
9569
+ table.hasData && !table.isLoading && /* @__PURE__ */ jsx("div", { class: "flex-shrink-0 mt-4", children: /* @__PURE__ */ jsx(
8759
9570
  Pagination,
8760
9571
  {
8761
9572
  currentPage: table.pagination.currentPage,
@@ -8774,11 +9585,29 @@ function createDaisyUIDataTable() {
8774
9585
  onNextPage: () => table.nextPage(),
8775
9586
  onSetPageSize: (size) => table.setPageSize(size)
8776
9587
  }
9588
+ ) }),
9589
+ Object.values(columns).some((col) => col?.filterable) && filterInputValues && filterOperators && /* @__PURE__ */ jsx(
9590
+ FilterDrawer,
9591
+ {
9592
+ isOpen: table.ui.filterDrawerOpen.value,
9593
+ columns,
9594
+ activeFilters: table.filters.active,
9595
+ filterInputValues,
9596
+ filterOperators,
9597
+ filterOptionsState,
9598
+ filterOptionsLoading,
9599
+ fieldsMetadata: table.fieldsMetadata,
9600
+ isLoading: table.isLoading,
9601
+ tableName,
9602
+ onClose: () => table.ui.closeFilterDrawer(),
9603
+ onFilterChange: (field, value, operator) => table.setFilter(field, value, operator),
9604
+ onClearAllFilters: () => table.clearAllFilters()
9605
+ }
8777
9606
  )
8778
9607
  ] })
8779
9608
  ] });
8780
9609
  };
8781
- DaisyUIDataTable.props = ["class"];
9610
+ DaisyUIDataTable.props = ["class", "name", "height"];
8782
9611
  return DaisyUIDataTable;
8783
9612
  }
8784
9613