@saasmakers/ui 1.4.30 → 1.4.31

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.
@@ -1,6 +1,6 @@
1
1
  <script lang="ts" setup>
2
+ import type { FieldInput } from '#components'
2
3
  import { vOnClickOutside } from '@vueuse/components'
3
- import { refDebounced } from '@vueuse/core'
4
4
  import type { FieldSelect, FieldSelectOption } from '../../types/fields'
5
5
 
6
6
  const props = withDefaults(defineProps<Omit<FieldSelect, 'modelValue'>>(), {
@@ -41,11 +41,16 @@ const modelValue = defineModel<FieldSelect['modelValue']>({ default: '' })
41
41
 
42
42
  const opened = ref(false)
43
43
  const searchRaw = ref('')
44
- const searchQuery = refDebounced(searchRaw, 250)
45
44
 
46
- const searchInput = ref<{
47
- focus: () => void
48
- }>()
45
+ const searchInput = ref<InstanceType<typeof FieldInput>>()
46
+
47
+ const computedColumns = computed(() => {
48
+ if (props.columns.length > 0) {
49
+ return props.columns
50
+ }
51
+
52
+ return [{ options: computedOptions.value }]
53
+ })
49
54
 
50
55
  const computedOptions = computed(() => {
51
56
  const options: FieldSelectOption[] = []
@@ -67,33 +72,22 @@ const computedOptions = computed(() => {
67
72
  return options
68
73
  })
69
74
 
70
- const computedColumns = computed(() => {
71
- if (props.columns.length > 0) {
72
- return props.columns
73
- }
74
-
75
- return [{ options: computedOptions.value }]
76
- })
77
-
78
- const selectedOption = computed(() => {
79
- return computedOptions.value.find((option) => {
80
- return option.value === modelValue.value
81
- })
75
+ const searchQueryCleaned = computed(() => {
76
+ return normalizeText(searchRaw.value.trim())
82
77
  })
83
78
 
84
79
  const filteredColumns = computed(() => {
85
- const searchQueryCleaned = normalizeText(searchQuery.value.trim())
86
-
87
- if (!props.searchable || !searchQueryCleaned) {
80
+ if (!props.searchable || !searchQueryCleaned.value) {
88
81
  return computedColumns.value
89
82
  }
90
83
 
91
84
  return computedColumns.value
92
85
  .map(column => ({
93
86
  ...column,
94
- options: column.options.filter(option =>
95
- normalizeText(option.text).includes(searchQueryCleaned),
96
- ),
87
+ options: column.options.filter((option) => {
88
+ return normalizeText(option.text).includes(searchQueryCleaned.value)
89
+ || normalizeText(option.value).includes(searchQueryCleaned.value)
90
+ }),
97
91
  }))
98
92
  .filter(column => column.options.length > 0)
99
93
  })
@@ -102,6 +96,16 @@ const hasFilteredResults = computed(() => {
102
96
  return filteredColumns.value.some(column => column.options.length > 0)
103
97
  })
104
98
 
99
+ const selectedOption = computed(() => {
100
+ return computedOptions.value.find((option) => {
101
+ return option.value === modelValue.value
102
+ })
103
+ })
104
+
105
+ const showNoResults = computed(() => {
106
+ return props.searchable && !!searchQueryCleaned.value && !hasFilteredResults.value
107
+ })
108
+
105
109
  watch(opened, (isOpened) => {
106
110
  if (isOpened && props.searchable) {
107
111
  nextTick(() => {
@@ -168,6 +172,12 @@ function onOptionKeyDown(event: KeyboardEvent) {
168
172
  }
169
173
  }
170
174
 
175
+ function onSearchKeyup(event: KeyboardEvent) {
176
+ if (event.key === 'Escape') {
177
+ reset()
178
+ }
179
+ }
180
+
171
181
  function reset() {
172
182
  opened.value = false
173
183
  searchRaw.value = ''
@@ -296,16 +306,19 @@ function selectOption(event: MouseEvent, value: string) {
296
306
  <FieldInput
297
307
  ref="searchInput"
298
308
  v-model="searchRaw"
309
+ :autocomplete="false"
310
+ background="white"
299
311
  border="none"
300
312
  class="px-3"
301
313
  :placeholder="searchPlaceholder || t('search')"
302
- size="sm"
314
+ :size="size"
303
315
  type="search"
316
+ @keyup="onSearchKeyup"
304
317
  />
305
318
  </div>
306
319
 
307
320
  <div
308
- v-if="searchable && !hasFilteredResults"
321
+ v-if="showNoResults"
309
322
  class="px-3 py-2 text-center text-gray-600 dark:text-gray-400"
310
323
  >
311
324
  {{ t('noResults') }}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saasmakers/ui",
3
- "version": "1.4.30",
3
+ "version": "1.4.31",
4
4
  "private": false,
5
5
  "description": "Reusable Nuxt UI components for SaaS Makers projects",
6
6
  "license": "MIT",