@itfin/components 1.0.77 → 1.0.81

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itfin/components",
3
- "version": "1.0.77",
3
+ "version": "1.0.81",
4
4
  "main": "dist/itfin-components.umd.js",
5
5
  "unpkg": "dist/itfin-components.common.js",
6
6
  "author": "Vitalii Savchuk <esvit666@gmail.com>",
@@ -7,7 +7,9 @@
7
7
  >
8
8
  <div class="modal-content itf-append-context" ref="content">
9
9
  <div class="modal-header">
10
- <h5 class="modal-title" :id="modalId">{{title}}</h5>
10
+ <slot name="title">
11
+ <h5 class="modal-title" :id="modalId">{{title}}</h5>
12
+ </slot>
11
13
  <itf-button icon data-bs-dismiss="modal" aria-label="Close" class="btn-close"></itf-button>
12
14
  </div>
13
15
  <div class="modal-body" v-if="value">
@@ -96,7 +98,7 @@ class itfModal extends Vue {
96
98
  setTimeout(() => {
97
99
  this.modalEl.show();
98
100
  modalStack.push(this);
99
- }, 500);
101
+ }, modalStack.length ? 500 : 0);
100
102
  } else {
101
103
  this.modalEl.hide();
102
104
  modalStack.pop();
@@ -104,7 +106,7 @@ class itfModal extends Vue {
104
106
  setTimeout(() => {
105
107
  modalStack[modalStack.length - 1].show();
106
108
  modalStack[modalStack.length - 1].bindEvents();
107
- }, 500);
109
+ }, modalStack.length ? 500 : 0);
108
110
  }
109
111
  }
110
112
  }
@@ -131,12 +133,16 @@ class itfModal extends Vue {
131
133
 
132
134
  bindEvents() {
133
135
  this.preventEvents = false;
134
- this.$refs.modal.addEventListener('hidden.bs.modal', this.onClose);
136
+ if (this.$refs.modal) {
137
+ this.$refs.modal.addEventListener('hidden.bs.modal', this.onClose);
138
+ }
135
139
  }
136
140
 
137
141
  unbindEvents() {
138
142
  this.preventEvents = true;
139
- this.$refs.modal.removeEventListener('hidden.bs.modal', this.onClose);
143
+ if (this.$refs.modal) {
144
+ this.$refs.modal.removeEventListener('hidden.bs.modal', this.onClose);
145
+ }
140
146
  }
141
147
 
142
148
  show() {
@@ -165,6 +165,8 @@ class itfSegmentedControl extends Vue {
165
165
  @Prop({ type: Boolean, default: false }) returnObject;
166
166
  @Prop({ type: Boolean, default: false }) disabled;
167
167
 
168
+ timers = [];
169
+
168
170
  get name () {
169
171
  return `sc${this._uid}`;
170
172
  }
@@ -210,20 +212,25 @@ class itfSegmentedControl extends Vue {
210
212
  updatePillPosition(this);
211
213
 
212
214
  function updatePillPosition (component) {
215
+ component.timers.forEach((timer) => {
216
+ clearTimeout(timer);
217
+ });
218
+ component.timers = [];
213
219
  component.$refs.input.forEach((elem, index) => {
214
220
  if (elem.checked) {
215
221
  component.$nextTick(() => moveBackgroundPillToElement(component, elem, index));
216
- setTimeout(() => moveBackgroundPillToElement(component, elem, index), 500);
217
- setTimeout(() => moveBackgroundPillToElement(component, elem, index), 750);
218
- setTimeout(() => moveBackgroundPillToElement(component, elem, index), 1500);
219
- setTimeout(() => moveBackgroundPillToElement(component, elem, index), 3000);
222
+ component.timers = [
223
+ setTimeout(() => moveBackgroundPillToElement(component, elem, index), 500),
224
+ setTimeout(() => moveBackgroundPillToElement(component, elem, index), 750),
225
+ setTimeout(() => moveBackgroundPillToElement(component, elem, index), 1500),
226
+ setTimeout(() => moveBackgroundPillToElement(component, elem, index), 3000)
227
+ ];
220
228
  }
221
229
  })
222
230
  }
223
231
 
224
232
  function moveBackgroundPillToElement (component, elem, index) {
225
233
  const slider = component.$refs.slider;
226
- console.info('init 2', slider);
227
234
  if (slider) {
228
235
  slider.style.transform = 'translateX(' + (elem.offsetWidth * index) + 'px)';
229
236
  }
@@ -14,7 +14,7 @@
14
14
 
15
15
  <slot
16
16
  v-if="!isValueEmpty && !multiple && customRender"
17
- v-bind="getOption(localValue)"
17
+ :option="getOption(localValue)"
18
18
  />
19
19
  <template v-else>
20
20
  {{ getOptionLabel(localValue) }}
@@ -28,13 +28,11 @@
28
28
  >
29
29
  <slot
30
30
  v-if="customRender"
31
- v-bind="{
32
- ...getOption(optionValue),
33
- optionValue,
34
- remove: removeOptionValue
35
- }"
31
+ :option="getOption(optionValue)"
32
+ :value="optionValue"
33
+ :remove="removeOptionValue"
36
34
  />
37
- <div v-else class="valueMultiItem text-textDarkest">
35
+ <div v-else class="valueMultiItem text-textDarkest" :style="getOptionColor(optionValue) ? `background-color: #${getOptionColor(optionValue)}; color: #fff` : ''">
38
36
  <div class="valueMultiItemLabel">
39
37
  {{ getOptionLabel(optionValue) }}
40
38
  </div>
@@ -68,11 +66,11 @@
68
66
  </div>
69
67
  </div>
70
68
 
71
- <j-icon
69
+ <icon
72
70
  v-if="(!multiple || isValueEmpty) && variant !== 'empty'"
73
71
  class="ml-auto mr-1"
74
- name="chevron-down"
75
- ></j-icon>
72
+ name="chevron_down"
73
+ ></icon>
76
74
  </div>
77
75
 
78
76
  <Dropdown
@@ -86,13 +84,15 @@
86
84
  :deactivateDropdown="deactivateDropdown"
87
85
  :options="options"
88
86
  :multiple="multiple"
87
+ :item-key="itemKey"
88
+ :item-text="itemText"
89
89
  :withClearValue="withClearValue"
90
90
  @change="handleChange"
91
91
  @searchValueChange="handleSearchValueChange"
92
92
  >
93
- <template v-slot:option="props">
94
- <slot v-if="customRenderOption" name="option" v-bind="props" />
95
- <slot v-else v-bind="props" />
93
+ <template #option="{ option }">
94
+ <slot v-if="customRenderOption" name="option" :option="option" />
95
+ <slot v-else :option="option" />
96
96
  </template>
97
97
  </Dropdown>
98
98
  </div>
@@ -101,6 +101,7 @@
101
101
  <script>
102
102
  import { Component, Model, Prop, Ref } from 'vue-property-decorator';
103
103
  import Vue from 'vue';
104
+ import Icon from '../icon/Icon.vue';
104
105
  import Dropdown from './Dropdown.vue';
105
106
  import { useOutsideClick } from './useOutsideClick';
106
107
 
@@ -108,7 +109,7 @@ const { bind, unbind } = useOutsideClick();
108
109
 
109
110
  export default @Component({
110
111
  name: 'itfAirSelect',
111
- components: { Dropdown },
112
+ components: { Dropdown, Icon },
112
113
  })
113
114
  class itfAirSelect extends Vue {
114
115
  @Model('input', { type: [Array, String, Number], default: undefined }) value;
@@ -117,6 +118,10 @@ class itfAirSelect extends Vue {
117
118
 
118
119
  @Prop({ type: String, default: 'normal' }) variant;
119
120
 
121
+ @Prop({ type: String, default: 'value' }) itemKey;
122
+ @Prop({ type: String, default: 'label' }) itemText;
123
+ @Prop({ type: String, default: 'color' }) itemColor;
124
+
120
125
  @Prop({ type: String, default: undefined }) name;
121
126
 
122
127
  @Prop({ type: Boolean, default: false }) searchable;
@@ -133,6 +138,9 @@ class itfAirSelect extends Vue {
133
138
 
134
139
  @Prop({ type: Boolean, default: false }) withClearValue;
135
140
 
141
+ @Prop({ type: Boolean, default: false }) customRender;
142
+ @Prop({ type: Boolean, default: false }) customRenderOption;
143
+
136
144
  @Ref('selectRef') selectRef;
137
145
 
138
146
  @Ref('dropdownRef') dropdownRef;
@@ -141,14 +149,6 @@ class itfAirSelect extends Vue {
141
149
 
142
150
  searchValue = '';
143
151
 
144
- get customRender() {
145
- return !!this.$slots.default;
146
- }
147
-
148
- get customRenderOption() {
149
- return !!this.$slots.option;
150
- }
151
-
152
152
  data() {
153
153
  return {
154
154
  stateValue: this.defaultValue || (this.multiple ? [] : null),
@@ -156,11 +156,15 @@ class itfAirSelect extends Vue {
156
156
  }
157
157
 
158
158
  getOption(optionValue) {
159
- return this.options.find((option) => option.value === optionValue);
159
+ return this.options.find((option) => option[this.itemKey] === optionValue);
160
160
  }
161
161
 
162
162
  getOptionLabel(optionValue) {
163
- return (this.getOption(optionValue) || { label: '' }).label;
163
+ return (this.getOption(optionValue) || { [this.itemText]: '' })[this.itemText];
164
+ }
165
+
166
+ getOptionColor(optionValue) {
167
+ return (this.getOption(optionValue) || { [this.itemColor]: '' })[this.itemColor];
164
168
  }
165
169
 
166
170
  get isControlled() {
@@ -173,7 +177,7 @@ class itfAirSelect extends Vue {
173
177
 
174
178
  preserveValueType(newValue) {
175
179
  const areOptionValuesNumbers = this.options.some(
176
- (option) => typeof option.value === 'number',
180
+ (option) => typeof option[this.itemKey] === 'number',
177
181
  );
178
182
  if (areOptionValuesNumbers) {
179
183
  if (this.multiple) {
@@ -256,6 +260,7 @@ class itfAirSelect extends Vue {
256
260
  align-items: center;
257
261
  width: 100%;
258
262
  min-height: 32px;
263
+ justify-content: space-between;
259
264
  }
260
265
  .placeholder {
261
266
  color: #8993a4;
@@ -14,13 +14,13 @@
14
14
  <div
15
15
  class="option text-textDarkest"
16
16
  v-for="option in filteredOptions"
17
- :key="option.value"
18
- :data-select-option-value="option.value"
19
- :data-testid="`select-option:${option.label}`"
17
+ :key="option[itemKey]"
18
+ :data-select-option-value="option[itemKey]"
19
+ :data-testid="`select-option:${option[itemText]}`"
20
20
  @mouseenter="handleOptionMouseEnter"
21
- @click="selectOptionValue(option.value)"
21
+ @click="selectOptionValue(option[itemKey])"
22
22
  >
23
- <slot name="option" v-bind="option">{{ option.label }}</slot>
23
+ <slot name="option" :option="option">{{ option[itemText] }}</slot>
24
24
  </div>
25
25
 
26
26
  <div
@@ -60,6 +60,8 @@ class itfSegmentedControl extends Vue {
60
60
  @Prop({ type: [Array, String, Number], default: undefined }) value;
61
61
  @Prop({ type: Boolean }) isValueEmpty;
62
62
  @Prop({ type: Boolean }) searchable;
63
+ @Prop({ type: String, default: 'value' }) itemKey;
64
+ @Prop({ type: String, default: 'label' }) itemText;
63
65
  @Prop({ type: String, default: '' }) searchValue;
64
66
  @Prop({ type: Function, required: true }) deactivateDropdown;
65
67
  @Prop({ type: Array, required: true }) options;
@@ -73,7 +75,7 @@ class itfSegmentedControl extends Vue {
73
75
  isCreatingOption = false;
74
76
 
75
77
  get optionsFilteredBySearchValue() {
76
- return this.options.filter((option) => option.label
78
+ return this.options.filter((option) => option[this.itemText]
77
79
  .toString()
78
80
  .toLowerCase()
79
81
  .includes(this.searchValue.toLowerCase()));
@@ -82,21 +84,21 @@ class itfSegmentedControl extends Vue {
82
84
  get filteredOptions() {
83
85
  return this.multiple
84
86
  ? this.optionsFilteredBySearchValue.filter(
85
- (option) => !(this.value).includes(option.value),
87
+ (option) => !(this.value).includes(option[this.itemKey]),
86
88
  )
87
89
  : this.optionsFilteredBySearchValue.filter(
88
- (option) => this.value !== option.value,
90
+ (option) => this.value !== option[this.itemKey],
89
91
  );
90
92
  }
91
93
 
92
94
  get isOptionCreatable() {
93
95
  return this.onCreate
94
96
  && this.searchValue
95
- && !this.options.map((option) => option.label).includes(this.searchValue);
97
+ && !this.options.map((option) => option[this.itemText]).includes(this.searchValue);
96
98
  }
97
99
 
98
100
  handleSearchValueChange(event) {
99
- this.$emit('searchValueChange', (event.target).value);
101
+ this.$emit('searchValueChange', (event.target)[this.itemKey]);
100
102
  }
101
103
 
102
104
  async getActiveOptionNode() {
@@ -1,5 +1,5 @@
1
1
  export const useOutsideClick = () => {
2
- const root = document.body;
2
+ const root = typeof document !== 'undefined' ? document.body : null;
3
3
  let handleClickOutside = null;
4
4
  let handleKeydown = null;
5
5
 
@@ -15,18 +15,22 @@ export const useOutsideClick = () => {
15
15
  onOutsideClick();
16
16
  }
17
17
  };
18
- root.addEventListener(
19
- 'mousedown',
20
- handleClickOutside,
21
- );
22
- root.addEventListener('keydown', handleKeydown);
18
+ if (root) {
19
+ root.addEventListener(
20
+ 'mousedown',
21
+ handleClickOutside,
22
+ );
23
+ root.addEventListener('keydown', handleKeydown);
24
+ }
23
25
  },
24
26
  unbind() {
25
- root.removeEventListener(
26
- 'mousedown',
27
- handleClickOutside,
28
- );
29
- root.removeEventListener('keydown', handleKeydown);
27
+ if (root) {
28
+ root.removeEventListener(
29
+ 'mousedown',
30
+ handleClickOutside,
31
+ );
32
+ root.removeEventListener('keydown', handleKeydown);
33
+ }
30
34
  }
31
35
  };
32
36
  };