@nixweb/nixloc-ui 1.1.0 → 1.3.0

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": "@nixweb/nixloc-ui",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "Componentes UI",
5
5
  "author": "Fábio Ávila <fabio@nixweb.com.br>",
6
6
  "private": false,
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div class="c-div-button" v-b-tooltip.hover :title="tooltip">
3
- <button :style="'background-color:' + backGroundColor + ';color:' + color" class="button" :class="{
3
+ <button :id="_key" :style="'background-color:' + backGroundColor + ';color:' + color" class="button" :class="{
4
4
  small: size === 'small',
5
5
  medium: size === 'medium',
6
6
  large: size === 'large',
@@ -1,48 +1,77 @@
1
1
  <template>
2
2
  <div>
3
3
  <div class="btn-container side-by-side text-center">
4
- <div v-for="option in options" class="btn-item-button-filter side-by-side"
5
- :class="{ 'selected-button-filter': option.value == selected }" @click="execute(option)" :key="option.title">
4
+ <div v-for="option in options" :key="option.value || option.title" class="btn-item-button-filter side-by-side"
5
+ :class="{ 'selected-button-filter': option.value === selected }" @click="execute(option)">
6
6
  <i :class="option.classIcon"></i>
7
7
  <span class="btn-title">{{ option.title }}</span>
8
8
  </div>
9
9
  </div>
10
10
  </div>
11
11
  </template>
12
+
12
13
  <script>
13
14
  import { mapMutations } from "vuex";
14
15
 
15
16
  export default {
16
17
  name: "ButtonFilter",
17
- props: {
18
- initialOption: String,
19
- options: {
20
- type: Array,
21
- default: [],
22
- },
23
- value: String,
24
- params: Object,
25
- clicked: Function,
26
- },
18
+ props: ["initialOption", "options", "value", "params", "clicked"],
27
19
  data() {
28
20
  return {
29
- selected: "",
21
+ selected: null,
30
22
  };
31
23
  },
32
24
  created() {
33
- if (this.initialOption) this.selected = this.initialOption;
25
+ this.setSelectedFromProps();
26
+ },
27
+ watch: {
28
+ // se o pai atualizar o v-model (prop value), sincroniza
29
+ value() {
30
+ this.setSelectedFromProps();
31
+ },
32
+ // se o pai trocar a initialOption depois, sincroniza também
33
+ initialOption() {
34
+ this.setSelectedFromProps();
35
+ },
34
36
  },
35
37
  methods: {
36
38
  ...mapMutations("generic", ["addEvent"]),
39
+
40
+ setSelectedFromProps() {
41
+ // prioridade para v-model (value)
42
+ if (this.value !== undefined) {
43
+ this.selected = this.value;
44
+ return;
45
+ }
46
+
47
+ // aceita initialOption como valor (0, "", "x", etc.) ou como objeto { value: ... }
48
+ if (this.initialOption !== undefined && this.initialOption !== null) {
49
+ this.selected =
50
+ typeof this.initialOption === "object"
51
+ ? this.initialOption.value
52
+ : this.initialOption;
53
+ }
54
+ },
55
+
37
56
  execute(option) {
38
- if (this.initialOption) this.selected = option.value;
39
- this.addEvent({ name: option.eventName, data: option });
57
+ // SEMPRE atualiza o selecionado
58
+ this.selected = option.value;
59
+
60
+ // eventos
61
+ if (option.eventName) {
62
+ this.addEvent({ name: option.eventName, data: option });
63
+ }
64
+
65
+ // emite para v-model do pai
40
66
  this.$emit("input", option.value);
67
+
68
+ // callback opcional
41
69
  if (this.clicked) this.clicked(this.params);
42
70
  },
43
71
  },
44
72
  };
45
73
  </script>
74
+
46
75
  <style scoped>
47
76
  .btn-container {
48
77
  margin-left: 10px;
@@ -66,10 +95,10 @@ export default {
66
95
  }
67
96
 
68
97
  .selected-button-filter {
69
- background-color: #4BB4E2;
70
- color: white;
98
+ background-color: #4bb4e2;
99
+ color: #fff;
71
100
  padding-left: 10px;
72
101
  padding-right: 10px;
73
102
  border-radius: 15px;
74
103
  }
75
- </style>
104
+ </style>
@@ -33,7 +33,7 @@ export default {
33
33
  };
34
34
  </script>
35
35
 
36
- <style scoped>
36
+ <style scoped>
37
37
  .input {
38
38
  width: 90%;
39
39
  border: none;
@@ -3,7 +3,7 @@
3
3
  <vodal :duration="80" :show="modal.open" @hide="hide()" :width="width" :height="height" :closeOnEsc="closeOnEsc"
4
4
  :closeButton="closeButton" :closeOnClickMask="false">
5
5
  <div class="d-block text-left">
6
- <Messages v-if="!vodal.open" />
6
+ <Messages v-if="!vodal.open && showValidation" />
7
7
  <div class="title">{{ title }}</div>
8
8
  <hr class="hr" />
9
9
  <slot></slot>
@@ -33,6 +33,10 @@ export default {
33
33
  type: Boolean,
34
34
  default: true,
35
35
  },
36
+ showValidation: {
37
+ type: Boolean,
38
+ default: true,
39
+ },
36
40
  onHideModal: Function,
37
41
  },
38
42
  components: { Messages, Vodal },
@@ -78,13 +78,6 @@ export default {
78
78
  };
79
79
  </script>
80
80
  <style>
81
- .custom-control-label {
82
- font-size: 13px !important;
83
- font-weight: 400 !important;
84
- text-transform: uppercase;
85
- color: #778498;
86
- }
87
-
88
81
  .options {
89
82
  margin-top: 5px;
90
83
  }
@@ -0,0 +1,193 @@
1
+ <template>
2
+ <transition name="slide-up">
3
+ <section v-if="isOpen" class="bab-container">
4
+ <header class="bab-header">
5
+ <div class="bab-left">
6
+ <div class="bab-icon-wrapper">
7
+ <i class="fas fa-list-check bab-icon"></i>
8
+ <span class="bab-count">{{ selected.length }}</span>
9
+ </div>
10
+ <strong class="bab-title title">
11
+ <span>selecionados</span>
12
+ </strong>
13
+ </div>
14
+
15
+ <div class="bab-actions">
16
+ <button type="button" class="bab-btn-close" @click="close">
17
+ <i class="fas fa-times"></i>
18
+ </button>
19
+ </div>
20
+ </header>
21
+ <main class="bab-content">
22
+ <slot />
23
+ </main>
24
+ </section>
25
+ </transition>
26
+ </template>
27
+
28
+ <script>
29
+
30
+ import { mapMutations } from "vuex";
31
+
32
+ export default {
33
+ name: "BottomActionsBar",
34
+ props: {
35
+ selected: { type: Array, default: () => [] }
36
+ },
37
+ computed: {
38
+ isOpen() {
39
+ return Array.isArray(this.selected) && this.selected.length > 0;
40
+ }
41
+ },
42
+ mounted() {
43
+ document.addEventListener("keydown", this.onKeydown);
44
+ },
45
+ beforeDestroy() {
46
+ document.removeEventListener("keydown", this.onKeydown);
47
+ },
48
+ methods: {
49
+ ...mapMutations("generic", ["addEvent"]),
50
+ close() {
51
+ this.$emit("close");
52
+ this.addEvent({ name: "deselectAll" });
53
+ },
54
+ onKeydown(e) {
55
+ if (e.key === "Escape" && this.isOpen) this.close();
56
+ }
57
+ }
58
+ };
59
+ </script>
60
+
61
+ <style>
62
+ .bab-container {
63
+ position: fixed;
64
+ left: 0;
65
+ right: 0;
66
+ bottom: 0;
67
+ height: 200px;
68
+
69
+ border-top-left-radius: 18px;
70
+ border-top-right-radius: 18px;
71
+ box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.25);
72
+ z-index: 9999;
73
+ display: flex;
74
+ flex-direction: column;
75
+ animation: elevate 0.2s ease-in-out;
76
+ }
77
+
78
+ .bab-header {
79
+ display: flex;
80
+ align-items: center;
81
+ justify-content: space-between;
82
+ padding: 12px 16px;
83
+ border-bottom: 1px solid #eef2f7;
84
+ }
85
+
86
+ .bab-left {
87
+ display: flex;
88
+ align-items: center;
89
+ gap: 10px;
90
+ }
91
+
92
+ .bab-icon-wrapper {
93
+ position: relative;
94
+ width: 38px;
95
+ height: 38px;
96
+ border-radius: 50%;
97
+ background: #D98621;
98
+ display: flex;
99
+ align-items: center;
100
+ justify-content: center;
101
+ color: #fff;
102
+ }
103
+
104
+ .bab-icon {
105
+ font-size: 16px;
106
+ }
107
+
108
+ .bab-count {
109
+ position: absolute;
110
+ top: -5px;
111
+ right: -5px;
112
+ background: #fff;
113
+ color: #D98621;
114
+ font-size: 11px;
115
+ font-weight: bold;
116
+ border-radius: 50%;
117
+ width: 18px;
118
+ height: 18px;
119
+ display: flex;
120
+ align-items: center;
121
+ justify-content: center;
122
+ border: 2px solid #D98621;
123
+ }
124
+
125
+ .bab-title {
126
+ font-size: 14px;
127
+ font-weight: 500;
128
+ color: #0f172a;
129
+ }
130
+
131
+ .bab-actions {
132
+ display: flex;
133
+ align-items: center;
134
+ }
135
+
136
+ .bab-btn-close {
137
+ background: transparent;
138
+ border: none;
139
+ color: #9ca3af;
140
+ font-size: 18px;
141
+ cursor: pointer;
142
+ transition: color 0.2s ease;
143
+ }
144
+
145
+ .bab-btn-close:hover {
146
+ color: #6b7280;
147
+ }
148
+
149
+ .bab-content {
150
+ flex: 1;
151
+ padding: 12px 16px;
152
+ overflow: auto;
153
+ display: grid;
154
+ grid-auto-flow: column;
155
+ grid-auto-columns: minmax(220px, 1fr);
156
+ gap: 12px;
157
+ }
158
+
159
+ .slide-up-enter-active,
160
+ .slide-up-leave-active {
161
+ transition: transform 200ms ease-in-out, opacity 200ms ease-in-out;
162
+ }
163
+
164
+ .slide-up-enter,
165
+ .slide-up-leave-to {
166
+ transform: translateY(16px);
167
+ opacity: 0;
168
+ }
169
+
170
+ @keyframes elevate {
171
+ from {
172
+ transform: translateY(20px);
173
+ opacity: 0.5;
174
+ }
175
+
176
+ to {
177
+ transform: translateY(0);
178
+ opacity: 1;
179
+ }
180
+ }
181
+
182
+ @media (max-width: 640px) {
183
+ .bab-container {
184
+ height: 220px;
185
+ border-top-left-radius: 14px;
186
+ border-top-right-radius: 14px;
187
+ }
188
+
189
+ .bab-content {
190
+ grid-auto-columns: minmax(160px, 1fr);
191
+ }
192
+ }
193
+ </style>
@@ -0,0 +1,175 @@
1
+ <template>
2
+ <div class="color-picker" ref="root">
3
+ <div v-if="title" class="color-picker__title">{{ title }}</div>
4
+
5
+ <div class="color-picker__trigger" :style="{ backgroundColor: innerValue }" role="button" tabindex="0"
6
+ @click="toggle()" @keydown.enter.prevent="toggle()" @keydown.space.prevent="toggle()"
7
+ aria-haspopup="listbox" :aria-expanded="open ? 'true' : 'false'"></div>
8
+
9
+ <transition name="color-picker--fade">
10
+ <div v-show="open" class="color-picker__menu" role="listbox" :aria-label="title || 'Escolher cor'">
11
+ <div class="color-picker__grid">
12
+ <div v-for="c in colors" :key="c" class="color-picker__item" :style="{ backgroundColor: c }"
13
+ role="option" :aria-selected="c === innerValue ? 'true' : 'false'" tabindex="0"
14
+ @click="choose(c)" @keydown.enter.prevent="choose(c)" @keydown.space.prevent="choose(c)">
15
+ <span v-if="c === innerValue" class="color-picker__check"></span>
16
+ </div>
17
+ </div>
18
+ </div>
19
+ </transition>
20
+ </div>
21
+ </template>
22
+
23
+ <script>
24
+ export default {
25
+ name: "ColorPicker",
26
+ model: { prop: "value", event: "input" },
27
+ props: {
28
+ value: { type: String, default: "" },
29
+ defaultColor: { type: String, default: "#64B5F6" },
30
+ title: { type: String, default: "" },
31
+ colors: {
32
+ type: Array,
33
+ default: function () {
34
+ return [
35
+ "#E57373", "#F06292", "#FF6F61",
36
+ "#BA68C8", "#9575CD", "#8E24AA",
37
+ "#64B5F6", "#4FC3F7", "#3949AB",
38
+ "#039BE5", "#1976D2", "#1E88E5",
39
+ "#4DB6AC", "#81C784", "#AED581",
40
+ "#26A69A", "#2E7D32", "#0097A7",
41
+ "#7CB342", "#C0CA33", "#9CCC65",
42
+ "#FFD54F", "#FFB74D", "#FDD835",
43
+ "#FB8C00", "#FF8A65", "#F4511E",
44
+ "#A1887F", "#6D4C41", "#795548",
45
+ "#90A4AE", "#546E7A", "#9E9E9E",
46
+ "#000000", "#FFFFFF", "#B0BEC5"
47
+ ];
48
+ },
49
+ },
50
+ },
51
+ data() {
52
+ return { innerValue: "", open: false };
53
+ },
54
+ created() {
55
+ this.initialize();
56
+ },
57
+ watch: {
58
+ value(v) {
59
+ if (this.isEmpty(v)) {
60
+ const fallback = this.normalizeHex(this.defaultColor);
61
+ this.innerValue = fallback;
62
+ this.$emit("input", fallback);
63
+ } else if (v !== this.innerValue) {
64
+ this.innerValue = this.normalizeHex(v);
65
+ }
66
+ }
67
+ },
68
+ mounted() {
69
+ document.addEventListener("click", this.onClickOutside, { passive: true });
70
+ },
71
+ beforeDestroy() {
72
+ document.removeEventListener("click", this.onClickOutside);
73
+ },
74
+ methods: {
75
+ initialize() {
76
+ const start = this.isEmpty(this.value)
77
+ ? this.normalizeHex(this.defaultColor)
78
+ : this.normalizeHex(this.value);
79
+ this.innerValue = start;
80
+ if (this.isEmpty(this.value)) this.$emit("input", start);
81
+ },
82
+ isEmpty(v) {
83
+ return v === null || v === undefined || String(v).trim() === "";
84
+ },
85
+ normalizeHex(v) {
86
+ const s = String(v || "").trim().toUpperCase();
87
+ const hex = /^#([0-9A-F]{6}|[0-9A-F]{3})$/i;
88
+ return hex.test(s) ? s : "#64B5F6";
89
+ },
90
+ toggle() { this.open = !this.open; },
91
+ close() { this.open = false; },
92
+ choose(c) {
93
+ const val = this.normalizeHex(c);
94
+ this.innerValue = val;
95
+ this.$emit("input", val);
96
+ this.close();
97
+ },
98
+ onClickOutside(e) {
99
+ const root = this.$refs.root;
100
+ if (this.open && root && !root.contains(e.target)) this.close();
101
+ },
102
+ },
103
+ };
104
+ </script>
105
+
106
+ <style scoped>
107
+ .color-picker {
108
+ position: relative;
109
+ display: inline-grid;
110
+ gap: .375rem;
111
+ }
112
+
113
+ .color-picker__title {
114
+ font-weight: 500;
115
+ }
116
+
117
+ .color-picker__trigger {
118
+ width: 22px;
119
+ height: 22px;
120
+ border-radius: 50%;
121
+ cursor: pointer;
122
+ user-select: none;
123
+ }
124
+
125
+ .color-picker__menu {
126
+ position: absolute;
127
+ z-index: 40;
128
+ top: calc(100% + 8px);
129
+ left: 0;
130
+ min-width: 400px;
131
+ max-width: 90vw;
132
+ background: #fff;
133
+ border: 1px solid #e5e7eb;
134
+ border-radius: 10px;
135
+ box-shadow: 0 10px 24px rgba(0, 0, 0, .12);
136
+ padding: .5rem;
137
+ }
138
+
139
+ .color-picker__grid {
140
+ display: grid;
141
+ grid-template-columns: repeat(12, 28px);
142
+ gap: .5rem;
143
+ }
144
+
145
+ .color-picker__item {
146
+ width: 28px;
147
+ height: 28px;
148
+ border-radius: 50%;
149
+ cursor: pointer;
150
+ position: relative;
151
+ border: 1px solid rgba(0, 0, 0, .1);
152
+ }
153
+
154
+ .color-picker__check {
155
+ position: absolute;
156
+ width: 10px;
157
+ height: 10px;
158
+ background: white;
159
+ border-radius: 50%;
160
+ top: 50%;
161
+ left: 50%;
162
+ transform: translate(-50%, -50%);
163
+ }
164
+
165
+ .color-picker--fade-enter-active,
166
+ .color-picker--fade-leave-active {
167
+ transition: all .14s ease;
168
+ }
169
+
170
+ .color-picker--fade-enter,
171
+ .color-picker--fade-leave-to {
172
+ opacity: 0;
173
+ transform: translateY(-4px) scale(.98);
174
+ }
175
+ </style>
@@ -0,0 +1,161 @@
1
+ <template>
2
+ <div class="icon-picker" ref="root">
3
+ <div v-if="title" class="icon-picker__title">{{ title }}</div>
4
+
5
+ <div class="icon-picker__trigger" :style="{ backgroundColor: color }" role="button" tabindex="0"
6
+ @click="toggle()" @keydown.enter.prevent="toggle()" @keydown.space.prevent="toggle()"
7
+ aria-haspopup="listbox" :aria-expanded="open ? 'true' : 'false'">
8
+ <i :class="innerValue || 'far fa-square'"></i>
9
+ </div>
10
+
11
+ <transition name="icon-picker--fade">
12
+ <div v-show="open" class="icon-picker__menu" role="listbox" :aria-label="title || 'Escolher ícone'">
13
+ <div class="icon-picker__grid">
14
+ <div v-for="ic in icons" :key="ic" class="icon-picker__item"
15
+ :class="{ 'icon-picker__item--selected': ic === innerValue }" role="option"
16
+ :aria-selected="ic === innerValue ? 'true' : 'false'" tabindex="0" @click="choose(ic)"
17
+ @keydown.enter.prevent="choose(ic)" @keydown.space.prevent="choose(ic)"
18
+ :style="ic === innerValue ? { backgroundColor: color } : {}">
19
+ <i :class="ic"></i>
20
+ </div>
21
+ </div>
22
+ </div>
23
+ </transition>
24
+ </div>
25
+ </template>
26
+
27
+ <script>
28
+ export default {
29
+ name: "IconPicker",
30
+ model: { prop: "value", event: "input" },
31
+ props: {
32
+ value: { type: String, default: "fas fa-wallet" },
33
+ title: { type: String, default: "" },
34
+ color: { type: String, default: "#64B5F6" },
35
+ icons: {
36
+ type: Array,
37
+ default: function () {
38
+ return [
39
+ "fas fa-wallet", "fas fa-cash-register", "fas fa-shopping-cart", "fas fa-receipt", "fas fa-credit-card", "fas fa-money-bill", "fas fa-coins", "fas fa-percentage", "fas fa-dollar-sign", "fas fa-file-invoice", "fas fa-chart-line",
40
+ "fas fa-box-open", "fas fa-box", "fas fa-truck", "fas fa-warehouse", "fas fa-shipping-fast", "fas fa-dolly", "fas fa-pallet", "fas fa-trailer", "fas fa-clipboard-list",
41
+ "fas fa-building", "fas fa-city", "fas fa-home", "fas fa-briefcase", "fas fa-sitemap", "fas fa-industry", "fas fa-store", "fas fa-store-alt", "fas fa-landmark", "fas fa-hotel",
42
+ "fas fa-users", "fas fa-user-tie", "fas fa-user", "fas fa-user-friends", "fas fa-user-cog", "fas fa-user-shield", "fas fa-user-circle", "fas fa-id-badge", "fas fa-id-card",
43
+ "fas fa-cogs", "fas fa-tools", "fas fa-desktop", "fas fa-laptop", "fas fa-server", "fas fa-database", "fas fa-cloud", "fas fa-network-wired", "fas fa-microchip", "fas fa-robot",
44
+ "fas fa-shield-alt", "fas fa-lock", "fas fa-balance-scale", "fas fa-file-contract", "fas fa-gavel", "fas fa-passport", "fas fa-clipboard-check",
45
+ "fas fa-bullhorn", "fas fa-ad", "fas fa-mail-bulk", "fas fa-envelope", "fas fa-comments", "fas fa-headset", "fas fa-phone-alt", "fas fa-share-alt", "fas fa-at",
46
+ "fas fa-graduation-cap", "fas fa-book", "fas fa-book-open", "fas fa-chalkboard-teacher", "fas fa-lightbulb", "fas fa-brain", "fas fa-project-diagram",
47
+ "fas fa-car", "fas fa-gas-pump", "fas fa-utensils", "fas fa-coffee", "fas fa-gift", "fas fa-tag", "fas fa-leaf", "fas fa-seedling", "fas fa-heart", "fas fa-music", "fas fa-paw", "fas fa-plane"
48
+ ];
49
+ },
50
+ },
51
+ },
52
+ data() {
53
+ return {
54
+ innerValue: this.value || "",
55
+ open: false,
56
+ };
57
+ },
58
+ watch: {
59
+ value(v) { this.innerValue = v; }
60
+ },
61
+ mounted() {
62
+ document.addEventListener("click", this.onClickOutside, { passive: true });
63
+ },
64
+ beforeDestroy() {
65
+ document.removeEventListener("click", this.onClickOutside);
66
+ },
67
+ methods: {
68
+ toggle() { this.open = !this.open; },
69
+ close() { this.open = false; },
70
+ choose(ic) {
71
+ this.innerValue = ic;
72
+ this.$emit("input", ic);
73
+ this.close();
74
+ },
75
+ onClickOutside(e) {
76
+ const root = this.$refs.root;
77
+ if (this.open && root && !root.contains(e.target)) this.close();
78
+ }
79
+ }
80
+ };
81
+ </script>
82
+
83
+ <style scoped>
84
+ .icon-picker {
85
+ position: relative;
86
+ display: inline-grid;
87
+ gap: .375rem;
88
+ margin-bottom: 10px;
89
+ }
90
+
91
+ .icon-picker__title {
92
+ font-weight: 500;
93
+ }
94
+
95
+ .icon-picker__trigger {
96
+ width: 56px;
97
+ height: 56px;
98
+ border-radius: 50%;
99
+ display: grid;
100
+ place-items: center;
101
+ cursor: pointer;
102
+ user-select: none;
103
+ }
104
+
105
+ .icon-picker__trigger i {
106
+ font-size: 22px;
107
+ color: #fff;
108
+ }
109
+
110
+ .icon-picker__menu {
111
+ position: absolute;
112
+ z-index: 40;
113
+ top: calc(100% + 8px);
114
+ left: 0;
115
+ width: 540px;
116
+ height: 320px;
117
+ overflow-y: auto;
118
+ background: #fff;
119
+ border: 1px solid #e5e7eb;
120
+ border-radius: 10px;
121
+ box-shadow: 0 10px 24px rgba(0, 0, 0, .12);
122
+ padding: .5rem .5rem .6rem;
123
+ }
124
+
125
+ .icon-picker__grid {
126
+ display: grid;
127
+ grid-template-columns: repeat(12, 36px);
128
+ gap: .5rem;
129
+ justify-content: start;
130
+ }
131
+
132
+ .icon-picker__item {
133
+ width: 36px;
134
+ height: 36px;
135
+ border-radius: 50%;
136
+ background: #f3f4f6;
137
+ display: grid;
138
+ place-items: center;
139
+ cursor: pointer;
140
+ }
141
+
142
+ .icon-picker__item i {
143
+ font-size: 14px;
144
+ color: #6b7280;
145
+ }
146
+
147
+ .icon-picker__item--selected i {
148
+ color: #fff;
149
+ }
150
+
151
+ .icon-picker--fade-enter-active,
152
+ .icon-picker--fade-leave-active {
153
+ transition: all .14s ease;
154
+ }
155
+
156
+ .icon-picker--fade-enter,
157
+ .icon-picker--fade-leave-to {
158
+ opacity: 0;
159
+ transform: translateY(-4px) scale(.98);
160
+ }
161
+ </style>