@bagelink/vue 0.0.282 → 0.0.284

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,137 +1,142 @@
1
1
  <template>
2
- <Dropdown placement="auto-start" class="bagel-input combobox">
3
- <button type="button" class="combobox-btn" @click="toggle">
4
- {{ valueToLabel(selectedItem) || placeholder || 'Select' }}
5
- <MaterialIcon v-bind="{ 'icon': open ? 'unfold_less' : 'unfold_more' }" />
6
- </button>
7
- <input style="width: 0; height: 0; position: absolute; opacity: 0; z-index: -1;" v-if="required"
8
- v-model="selectedItem" required>
9
- <template #popper="{ hide }">
10
- <Card thin class="combobox-options">
11
- <TextInput v-if="searchable" ref="searchInput" dense :placeholder="'Search'" icon="search" v-model="search" />
12
- <div class="combobox-option" v-for="(option, i) in filteredOptions" :key="`${option}${i}`" @click="() => {
13
- select(option)
14
- hide();
15
- }" :class="{ selected: option === selectedItem }">
16
- <span>
17
- {{ label(option) }}
18
- </span>
19
- <Icon v-if="isSelected(option)" icon="check" />
20
- </div>
21
- </Card>
22
- </template>
23
- </Dropdown>
2
+ <Dropdown placement="auto-start" class="bagel-input combobox">
3
+ <button type="button" class="combobox-btn" @click="toggle">
4
+ {{ valueToLabel(selectedItem) || placeholder || 'Select' }}
5
+ <MaterialIcon v-bind="{ 'icon': open ? 'unfold_less' : 'unfold_more' }" />
6
+ </button>
7
+ <input style="width: 0; height: 0; position: absolute; opacity: 0; z-index: -1;" v-if="required"
8
+ v-model="selectedItem" required>
9
+ <template #popper="{ hide }">
10
+ <Card thin class="combobox-options">
11
+ <TextInput v-if="searchable" ref="searchInput" dense :placeholder="'Search'" icon="search" v-model="search" />
12
+ <div class="combobox-option" v-for="(option, i) in filteredOptions" :key="`${option}${i}`" @click="() => {
13
+ select(option)
14
+ hide();
15
+ }" :class="{ selected: option === selectedItem }">
16
+ <span>
17
+ {{ label(option) }}
18
+ </span>
19
+ <Icon v-if="isSelected(option)" icon="check" />
20
+ </div>
21
+ </Card>
22
+ </template>
23
+ </Dropdown>
24
24
  </template>
25
25
 
26
26
  <script lang="ts" setup>
27
+ import { watch } from 'vue';
27
28
  import { Dropdown } from 'floating-vue';
28
29
  import 'floating-vue/style.css';
29
30
  import {
30
- TextInput, Card, Icon, MaterialIcon,
31
+ TextInput, Card, Icon, MaterialIcon,
31
32
  } from '@bagelink/vue';
32
33
 
33
34
  type Option = string | number | Record<string, any> | { label: string, value: string | number };
34
35
  let open = $ref(false);
35
- let selectedItem = $ref<Option>();
36
36
 
37
37
  const searchInput = $ref<HTMLInputElement | null>(null);
38
38
 
39
39
  const props = defineProps<{
40
- options: Option[];
41
- placeholder?: string;
42
- disabled?: boolean;
43
- modelValue?: Option;
44
- searchable?: boolean;
45
- required?: boolean;
40
+ options: Option[];
41
+ placeholder?: string;
42
+ disabled?: boolean;
43
+ modelValue?: Option;
44
+ searchable?: boolean;
45
+ required?: boolean;
46
46
  }>();
47
+ let selectedItem = $ref<Option>();
47
48
  let search = $ref('');
48
49
 
49
50
  const toggle = () => {
50
- open = !open;
51
- if (!open) search = '';
52
- if (open) setTimeout(() => (searchInput as any)?.$el?.querySelector('input')?.focus(), 100);
51
+ open = !open;
52
+ if (!open) search = '';
53
+ if (open) setTimeout(() => (searchInput as any)?.$el?.querySelector('input')?.focus(), 100);
53
54
  };
54
55
 
55
56
  const valueToLabel = (value?: Option) => {
56
- if (!value) return '';
57
- const option = props.options.find((option) => {
58
- if (typeof option === 'string' || typeof option === 'number') return option === value;
59
- return option.value === value;
60
- });
61
- if (!option) return value;
62
- return label(option);
57
+ if (!value) return '';
58
+ const option = props.options.find((option) => {
59
+ if (typeof option === 'string' || typeof option === 'number') return option === value;
60
+ return option.value === value;
61
+ });
62
+ if (!option) return value;
63
+ return label(option);
63
64
  };
64
65
 
65
66
  const emit = defineEmits(['update:modelValue']);
66
67
 
67
68
  const label = (option: Option) => {
68
- if (typeof option === 'string') return option;
69
- if (typeof option === 'number') return `${option}`;
70
- return option.label;
69
+ if (typeof option === 'string') return option;
70
+ if (typeof option === 'number') return `${option}`;
71
+ return option.label;
71
72
  };
72
73
 
73
74
  const isSelected = (option: Option) => {
74
- if (typeof option === 'string' || typeof option === 'number') return option === selectedItem;
75
- return option.value === selectedItem;
75
+ if (typeof option === 'string' || typeof option === 'number') return option === selectedItem;
76
+ return option.value === selectedItem;
76
77
  };
77
78
 
78
79
  const filteredOptions = $computed(() => props.options.filter((option) => {
79
- const searchTerm = new RegExp(search, 'gi');
80
- if (typeof option === 'string') return option.match(searchTerm);
81
- if (typeof option === 'number') return `${option}`.match(searchTerm);
82
- return option.label.match(searchTerm);
80
+ const searchTerm = new RegExp(search, 'gi');
81
+ if (typeof option === 'string') return option.match(searchTerm);
82
+ if (typeof option === 'number') return `${option}`.match(searchTerm);
83
+ return option.label.match(searchTerm);
83
84
  }));
84
85
 
85
86
  const select = (option: Option) => {
86
- if (typeof option === 'string') selectedItem = option;
87
- else if (typeof option === 'number') selectedItem = option;
88
- else selectedItem = option.value;
89
- emit('update:modelValue', selectedItem);
90
- open = false;
87
+ if (typeof option === 'string') selectedItem = option;
88
+ else if (typeof option === 'number') selectedItem = option;
89
+ else selectedItem = option.value;
90
+ emit('update:modelValue', selectedItem);
91
+ open = false;
91
92
  };
93
+
94
+ watch(() => props.modelValue, (value) => {
95
+ if (value !== selectedItem) selectedItem = value;
96
+ }, { immediate: true });
92
97
  </script>
93
98
 
94
99
  <style scoped>
95
100
  .combobox {
96
- width: 100%;
101
+ width: 100%;
97
102
  }
98
103
 
99
104
  .combobox-option {
100
- padding: 6px 12px;
101
- cursor: pointer;
102
- border-radius: 5px;
103
- transition: all 0.2s;
104
- display: flex;
105
- justify-content: space-between;
106
- width: 100%;
105
+ padding: 6px 12px;
106
+ cursor: pointer;
107
+ border-radius: 5px;
108
+ transition: all 0.2s;
109
+ display: flex;
110
+ justify-content: space-between;
111
+ width: 100%;
107
112
  }
108
113
 
109
114
  .combobox-options {
110
- max-height: 300px;
111
- overflow-y: auto;
115
+ max-height: 300px;
116
+ overflow-y: auto;
112
117
  }
113
118
 
114
119
  .combobox-option:hover {
115
- background: var(--bgl-gray-20);
120
+ background: var(--bgl-gray-20);
116
121
  }
117
122
  </style>
118
123
 
119
124
  <style>
120
125
  .combobox-btn {
121
- display: flex;
122
- justify-content: space-between;
123
- align-items: center;
124
- height: var(--input-height);
125
- border-radius: var(--input-border-radius);
126
+ display: flex;
127
+ justify-content: space-between;
128
+ align-items: center;
129
+ height: var(--input-height);
130
+ border-radius: var(--input-border-radius);
126
131
  }
127
132
 
128
133
  .v-popper__arrow-container {
129
- display: none;
134
+ display: none;
130
135
  }
131
136
 
132
137
  .v-popper--theme-dropdown .v-popper__inner {
133
- border: none;
134
- background: transparent;
135
- border-radius: var(--card-border-radius);
138
+ border: none;
139
+ background: transparent;
140
+ border-radius: var(--card-border-radius);
136
141
  }
137
142
  </style>
@@ -1,12 +1,14 @@
1
1
  <template>
2
- <div class="pb-1">
3
- <label class="txt-start" :for="id">
4
- {{ label }}
5
- <Multiselect ref="multiselect" :id="id" label="label" trackBy="value" :options="optionList" :required="required"
6
- :placeholder="placeholder" v-model="seletValue" :close-on-select="true" v-bind="extraProps" />
7
- <!-- <input v-model="dataValue" type="hidden" :name="id" :required v-bind="extraProps"> -->
8
- </label>
9
- </div>
2
+ <div>
3
+ <label class="txt-start" :for="id">
4
+ {{ label }}
5
+ <Multiselect
6
+ ref="multiselect" :id="id" label="label" trackBy="value" :options="optionList" :required="required"
7
+ :placeholder="placeholder" v-model="seletValue" :close-on-select="true" v-bind="extraProps"
8
+ />
9
+ <!-- <input v-model="dataValue" type="hidden" :name="id" :required v-bind="extraProps"> -->
10
+ </label>
11
+ </div>
10
12
  </template>
11
13
 
12
14
  <script lang="ts" setup>
@@ -36,24 +38,24 @@ const emit = defineEmits(['update:modelValue']);
36
38
  const optionList = $ref<Option[]>([]);
37
39
 
38
40
  const seletValue = $computed({
39
- get: () => optionList.find((opt) => opt.value === dataValue),
40
- set: (val?: Option) => {
41
- dataValue = val?.value;
42
- emit('update:modelValue', dataValue);
43
- },
41
+ get: () => optionList.find((opt) => opt.value === dataValue),
42
+ set: (val?: Option) => {
43
+ dataValue = val?.value;
44
+ emit('update:modelValue', dataValue);
45
+ },
44
46
  });
45
47
 
46
48
  function optnToValueLabel(option: RawOption): Option {
47
- if (typeof option === 'string' || typeof option === 'number') {
48
- return { label: `${option}`, value: option };
49
- }
50
- return option;
49
+ if (typeof option === 'string' || typeof option === 'number') {
50
+ return { label: `${option}`, value: option };
51
+ }
52
+ return option;
51
53
  }
52
54
 
53
55
  function updateOptionList() {
54
- const { options } = props;
55
- const optnLst = typeof options === 'string' ? options.split('\n|,') : options || [];
56
- optionList.push(...optnLst.map(optnToValueLabel));
56
+ const { options } = props;
57
+ const optnLst = typeof options === 'string' ? options.split('\n|,') : options || [];
58
+ optionList.push(...optnLst.map(optnToValueLabel));
57
59
  }
58
60
 
59
61
  watch(() => props.options, updateOptionList, { immediate: true });
@@ -344,7 +346,7 @@ fieldset[disabled] .multiselect {
344
346
  border-top: none;
345
347
  border-bottom-left-radius: 5px;
346
348
  border-bottom-right-radius: 5px;
347
- z-index: 50;
349
+ z-index: 150;
348
350
  -webkit-overflow-scrolling: touch;
349
351
  }
350
352
 
@@ -81,10 +81,6 @@
81
81
  grid-auto-columns: max-content;
82
82
  }
83
83
 
84
- .w-100 {
85
- width: 100%;
86
- }
87
-
88
84
  .col-gap-1 {
89
85
  column-gap: 1rem;
90
86
  }
@@ -164,7 +160,12 @@
164
160
  .w550,
165
161
  .w600,
166
162
  .w650,
167
- .w700 {
163
+ .w700,
164
+ .w770,
165
+ .w900,
166
+ .w970,
167
+ .w1030,
168
+ .w1170 {
168
169
  margin-left: auto;
169
170
  margin-right: auto;
170
171
  width: 98%;
@@ -206,6 +207,26 @@
206
207
  max-width: 700px;
207
208
  }
208
209
 
210
+ .w770 {
211
+ max-width: 770px;
212
+ }
213
+
214
+ .w900 {
215
+ max-width: 900px;
216
+ }
217
+
218
+ .w970 {
219
+ max-width: 970px;
220
+ }
221
+
222
+ .w1030 {
223
+ max-width: 1030px;
224
+ }
225
+
226
+ .w1170 {
227
+ max-width: 1170px;
228
+ }
229
+
209
230
  .gap-1 {
210
231
  gap: 0.25rem;
211
232
  }
@@ -2745,6 +2745,7 @@ export type MaterialIcons =
2745
2745
  | 'tools_pliers_wire_stripper'
2746
2746
  | 'tools_power_drill'
2747
2747
  | 'tools_wrench'
2748
+ | 'tooltip'
2748
2749
  | 'top_panel_close'
2749
2750
  | 'top_panel_open'
2750
2751
  | 'topic'