ketekny-ui-kit 1.0.141 → 1.0.142

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/ui/kSelect.vue +19 -5
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ketekny-ui-kit",
3
3
  "type": "module",
4
- "version": "1.0.141",
4
+ "version": "1.0.142",
5
5
  "description": "A Vue 3 UI component library with Tailwind CSS styling",
6
6
  "main": "index.js",
7
7
  "files": [
@@ -74,6 +74,7 @@
74
74
  ref="searchInput"
75
75
  type="text"
76
76
  v-model="searchQuery"
77
+ autofocus
77
78
  placeholder="Αναζήτηση..."
78
79
  class="w-full pl-9 pr-3 py-2 text-base border border-gray-200 rounded-lg focus-visible:outline-none focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/20 transition-colors placeholder-gray-400 dark:bg-slate-700 dark:text-slate-100 dark:border-slate-600 dark:placeholder-slate-500"
79
80
  role="searchbox"
@@ -94,17 +95,20 @@
94
95
  v-for="(option, index) in filteredOptions"
95
96
  :key="option[optionValue]"
96
97
  :value="option[optionValue]"
97
- class="select-item relative flex items-center gap-1.5 rounded-[4px] py-2.5 pl-8 pr-3 text-base cursor-pointer outline-none select-none text-slate-700 dark:text-slate-200
98
+ class="select-item relative flex items-center gap-1.5 rounded-[4px] py-2.5 pl-3 pr-8 text-base cursor-pointer outline-none select-none text-slate-700 dark:text-slate-200
98
99
  data-[highlighted]:bg-primary data-[highlighted]:text-white
99
100
  data-[state=checked]:bg-primary/5 data-[state=checked]:text-primary dark:data-[state=checked]:bg-slate-700 dark:data-[state=checked]:text-primary
100
101
  data-[state=checked]:data-[highlighted]:bg-primary data-[state=checked]:data-[highlighted]:text-white"
101
102
  >
102
- <span class="absolute left-2 flex items-center justify-center w-4 h-4 shrink-0">
103
+ <span v-if="hasOptionIcons" class="flex items-center justify-center w-4 h-4 shrink-0">
104
+ <kIcon v-if="option[optionIcon]" :name="option[optionIcon]" class="w-4 h-4 !text-current" />
105
+ </span>
106
+ <SelectItemText class="truncate">{{ option[optionLabel] }}</SelectItemText>
107
+ <span class="absolute right-2 flex items-center justify-center w-5 h-5 shrink-0">
103
108
  <SelectItemIndicator>
104
- <Check class="w-3.5 h-3.5" />
109
+ <Check class="w-4 h-4 stroke-[2.5]" />
105
110
  </SelectItemIndicator>
106
111
  </span>
107
- <SelectItemText class="truncate">{{ option[optionLabel] }}</SelectItemText>
108
112
  </SelectItem>
109
113
 
110
114
  <div v-if="filteredOptions.length === 0" class="flex flex-col items-center gap-1.5 px-3 py-4 text-base text-gray-400 text-center dark:text-slate-500">
@@ -149,6 +153,7 @@ import {
149
153
  } from "reka-ui";
150
154
  import { X, ChevronDown, Check, Search, SearchX } from "@lucide/vue";
151
155
  import kChip from "./kChip.vue";
156
+ import kIcon from "./kIcon.vue";
152
157
 
153
158
  const props = defineProps({
154
159
  options: { type: Array, required: true },
@@ -156,6 +161,7 @@ const props = defineProps({
156
161
  multiple: { type: Boolean, default: false },
157
162
  optionValue: { type: String, default: "value" },
158
163
  optionLabel: { type: String, default: "label" },
164
+ optionIcon: { type: String, default: "icon" },
159
165
  label: String,
160
166
  info: String,
161
167
  error: [String, Boolean],
@@ -224,6 +230,7 @@ const isSelectionSet = computed(() => {
224
230
  return props.modelValue !== null && props.modelValue !== undefined && props.modelValue !== "";
225
231
  });
226
232
  const resolvedDropdownHeight = computed(() => normalizeDropdownHeight(props.dropdownHeight));
233
+ const hasOptionIcons = computed(() => props.options.some((option) => Boolean(option?.[props.optionIcon])));
227
234
  const selectedOptions = computed(() => {
228
235
  if (!props.multiple || !Array.isArray(props.modelValue)) return [];
229
236
  return props.modelValue
@@ -294,10 +301,17 @@ const filteredOptions = computed(() => {
294
301
  watch(open, (val) => {
295
302
  if (val) {
296
303
  nextTick(() => {
297
- if (props.searchable) searchInput.value?.focus();
298
304
  const el = viewportRef.value?.$el ?? viewportRef.value;
299
305
  const checked = el?.querySelector('[data-state="checked"]');
300
306
  checked?.scrollIntoView({ block: "nearest" });
307
+
308
+ if (props.searchable) {
309
+ requestAnimationFrame(() => {
310
+ requestAnimationFrame(() => {
311
+ if (open.value) searchInput.value?.focus({ preventScroll: true });
312
+ });
313
+ });
314
+ }
301
315
  });
302
316
  return;
303
317
  }