@veritree/ui 0.21.1-0 → 0.21.1-10
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/mixins/floating-ui-content.js +102 -0
- package/mixins/floating-ui-item.js +216 -0
- package/mixins/floating-ui.js +14 -6
- package/mixins/form-control.js +72 -0
- package/package.json +2 -2
- package/src/components/Avatar/VTAvatar.vue +32 -29
- package/src/components/DropdownMenu/VTDropdownMenu.vue +5 -16
- package/src/components/DropdownMenu/VTDropdownMenuContent.vue +17 -65
- package/src/components/DropdownMenu/VTDropdownMenuDivider.vue +8 -5
- package/src/components/DropdownMenu/VTDropdownMenuItem.vue +9 -143
- package/src/components/DropdownMenu/VTDropdownMenuLabel.vue +3 -3
- package/src/components/DropdownMenu/VTDropdownMenuTrigger.vue +67 -103
- package/src/components/Form/VTInput.vue +28 -40
- package/src/components/Form/VTInputQty.vue +165 -0
- package/src/components/Form/VTTextarea.vue +22 -0
- package/src/components/Listbox/VTListbox.vue +6 -11
- package/src/components/Listbox/VTListboxContent.vue +11 -76
- package/src/components/Listbox/VTListboxItem.vue +9 -181
- package/src/components/Listbox/VTListboxLabel.vue +0 -10
- package/src/components/Listbox/VTListboxList.vue +24 -33
- package/src/components/Listbox/VTListboxSearch.vue +21 -18
- package/src/components/Listbox/VTListboxTrigger.vue +58 -97
- package/src/components/Popover/VTPopover.vue +1 -14
- package/src/components/Popover/VTPopoverContent.vue +14 -65
- package/src/components/Popover/VTPopoverDivider.vue +4 -11
- package/src/components/Popover/VTPopoverItem.vue +16 -13
- package/src/components/Popover/VTPopoverTrigger.vue +118 -21
- package/src/components/Utils/FloatingUi.vue +6 -1
- package/src/utils/components.js +0 -18
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
:class="{
|
|
4
4
|
PopoverDivider: headless,
|
|
5
5
|
'-mx-3 my-2 h-[1px]': !headless,
|
|
6
|
-
'bg-gray-200': !dark,
|
|
7
|
-
'bg-fd-500': dark,
|
|
8
6
|
}"
|
|
9
7
|
></div>
|
|
10
8
|
</template>
|
|
@@ -13,15 +11,20 @@
|
|
|
13
11
|
export default {
|
|
14
12
|
name: 'VTDropdownMenuDivider',
|
|
15
13
|
|
|
16
|
-
inject: ['
|
|
14
|
+
inject: ['apiDropdownMenu'],
|
|
15
|
+
|
|
16
|
+
headless: {
|
|
17
|
+
type: Boolean,
|
|
18
|
+
default: false,
|
|
19
|
+
},
|
|
17
20
|
|
|
18
21
|
computed: {
|
|
19
22
|
dark() {
|
|
20
|
-
return this.
|
|
23
|
+
return this.apiDropdownMenu().isDark;
|
|
21
24
|
},
|
|
22
25
|
|
|
23
26
|
headless() {
|
|
24
|
-
return this.
|
|
27
|
+
return this.apiDropdownMenu().isHeadless;
|
|
25
28
|
},
|
|
26
29
|
},
|
|
27
30
|
};
|
|
@@ -3,17 +3,10 @@
|
|
|
3
3
|
:is="as"
|
|
4
4
|
:id="id"
|
|
5
5
|
:to="to"
|
|
6
|
-
:class="
|
|
7
|
-
MenuItem: headless,
|
|
8
|
-
'-mx-3 flex min-w-max items-center gap-2 px-3 py-2 text-inherit no-underline':
|
|
9
|
-
!headless,
|
|
10
|
-
'hover:bg-secondary-200/10': !dark && !headless,
|
|
11
|
-
'text-white': dark && !headless,
|
|
12
|
-
'pointer-events-none opacity-75': disabled && !headless,
|
|
13
|
-
'bg-secondary-200/10': selected && !headless,
|
|
14
|
-
}"
|
|
15
|
-
:tabindex="tabIndex"
|
|
6
|
+
:class="classComputed"
|
|
16
7
|
:aria-disabled="disabled"
|
|
8
|
+
:tabindex="tabIndex"
|
|
9
|
+
class="-mx-3"
|
|
17
10
|
role="menuitem"
|
|
18
11
|
@click.stop.prevent="onClick"
|
|
19
12
|
@keydown.down.prevent="focusPreviousItem"
|
|
@@ -29,12 +22,14 @@
|
|
|
29
22
|
</template>
|
|
30
23
|
|
|
31
24
|
<script>
|
|
32
|
-
import {
|
|
25
|
+
import { floatingUiItemMixin } from '../../../mixins/floating-ui-item';
|
|
33
26
|
|
|
34
27
|
export default {
|
|
35
28
|
name: 'VTDropdownMenuItem',
|
|
36
29
|
|
|
37
|
-
|
|
30
|
+
mixins: [floatingUiItemMixin],
|
|
31
|
+
|
|
32
|
+
inject: ['apiDropdownMenu'],
|
|
38
33
|
|
|
39
34
|
props: {
|
|
40
35
|
to: {
|
|
@@ -45,148 +40,19 @@ export default {
|
|
|
45
40
|
type: String,
|
|
46
41
|
default: null,
|
|
47
42
|
},
|
|
48
|
-
disabled: {
|
|
49
|
-
type: Boolean,
|
|
50
|
-
default: false,
|
|
51
|
-
},
|
|
52
43
|
},
|
|
53
44
|
|
|
54
45
|
data() {
|
|
55
46
|
return {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
tabIndex: 0,
|
|
47
|
+
apiInjected: this.apiDropdownMenu,
|
|
48
|
+
componentName: 'dropdown-menu-item',
|
|
59
49
|
};
|
|
60
50
|
},
|
|
61
51
|
|
|
62
52
|
computed: {
|
|
63
|
-
id() {
|
|
64
|
-
return `dropdown-menu-item-${this.api().id}-${genId()}`;
|
|
65
|
-
},
|
|
66
|
-
|
|
67
|
-
dark() {
|
|
68
|
-
return this.api().isDark;
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
headless() {
|
|
72
|
-
return this.api().isHeadless;
|
|
73
|
-
},
|
|
74
|
-
|
|
75
53
|
as() {
|
|
76
54
|
return this.href ? 'a' : this.to ? 'NuxtLink' : 'button';
|
|
77
55
|
},
|
|
78
|
-
|
|
79
|
-
items() {
|
|
80
|
-
return this.api().items;
|
|
81
|
-
},
|
|
82
|
-
|
|
83
|
-
el() {
|
|
84
|
-
return this.$el;
|
|
85
|
-
},
|
|
86
|
-
|
|
87
|
-
componentTrigger() {
|
|
88
|
-
return this.api().componentTrigger;
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
componentContent() {
|
|
92
|
-
return this.api().componentContent;
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
|
-
|
|
96
|
-
mounted() {
|
|
97
|
-
const item = {
|
|
98
|
-
select: this.select,
|
|
99
|
-
unselect: this.unselect,
|
|
100
|
-
focus: this.focus,
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
this.api().registerItem(item);
|
|
104
|
-
|
|
105
|
-
this.index = this.items.length - 1;
|
|
106
|
-
},
|
|
107
|
-
|
|
108
|
-
methods: {
|
|
109
|
-
select() {
|
|
110
|
-
this.selected = true;
|
|
111
|
-
},
|
|
112
|
-
|
|
113
|
-
unselect() {
|
|
114
|
-
this.selected = false;
|
|
115
|
-
},
|
|
116
|
-
|
|
117
|
-
focus() {
|
|
118
|
-
if (!this.el) return;
|
|
119
|
-
|
|
120
|
-
this.tabIndex = -1;
|
|
121
|
-
this.selected = true;
|
|
122
|
-
this.el.focus();
|
|
123
|
-
},
|
|
124
|
-
|
|
125
|
-
focusFirstItem() {
|
|
126
|
-
this.setFocusToItem(0);
|
|
127
|
-
},
|
|
128
|
-
|
|
129
|
-
focusLastItem() {
|
|
130
|
-
this.setFocusToItem(this.items.length - 1);
|
|
131
|
-
},
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Focus the previous item in the menu.
|
|
135
|
-
* If is the first item, jump to the last item.
|
|
136
|
-
*/
|
|
137
|
-
focusPreviousItem() {
|
|
138
|
-
const isLast = this.index === this.items.length - 1;
|
|
139
|
-
const goToIndex = isLast ? 0 : this.index + 1;
|
|
140
|
-
|
|
141
|
-
this.setFocusToItem(goToIndex);
|
|
142
|
-
},
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Focus the next item in the menu.
|
|
146
|
-
* If is the last item, jump to the first item.
|
|
147
|
-
*/
|
|
148
|
-
focusNextItem() {
|
|
149
|
-
const isFirst = this.index === 0;
|
|
150
|
-
const goToIndex = isFirst ? this.items.length - 1 : this.index - 1;
|
|
151
|
-
|
|
152
|
-
this.setFocusToItem(goToIndex);
|
|
153
|
-
},
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Focus item by remove its tabindex and calling
|
|
157
|
-
* focus to the element.
|
|
158
|
-
*
|
|
159
|
-
* @param {Number, String} goToIndex
|
|
160
|
-
*/
|
|
161
|
-
setFocusToItem(goToIndex) {
|
|
162
|
-
this.tabIndex = 0;
|
|
163
|
-
this.selected = false;
|
|
164
|
-
|
|
165
|
-
// set all selected to false
|
|
166
|
-
this.items.forEach((item) => item.unselect());
|
|
167
|
-
|
|
168
|
-
// focus item
|
|
169
|
-
this.items[goToIndex].focus();
|
|
170
|
-
},
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Hides content/menu and focus on trigger
|
|
174
|
-
*/
|
|
175
|
-
leaveMenu() {
|
|
176
|
-
if (this.componentContent) this.componentContent.hide();
|
|
177
|
-
if (this.componentTrigger) this.componentTrigger.focus();
|
|
178
|
-
},
|
|
179
|
-
|
|
180
|
-
onKeyEsc() {
|
|
181
|
-
this.leaveMenu();
|
|
182
|
-
},
|
|
183
|
-
|
|
184
|
-
onClick() {
|
|
185
|
-
if (this.disabled) return;
|
|
186
|
-
|
|
187
|
-
this.$emit('click');
|
|
188
|
-
this.$nextTick(() => this.leaveMenu());
|
|
189
|
-
},
|
|
190
56
|
},
|
|
191
57
|
};
|
|
192
58
|
</script>
|
|
@@ -15,15 +15,15 @@
|
|
|
15
15
|
export default {
|
|
16
16
|
name: 'VTDropdownMenuLabel',
|
|
17
17
|
|
|
18
|
-
inject: ['
|
|
18
|
+
inject: ['apiDropdownMenu'],
|
|
19
19
|
|
|
20
20
|
computed: {
|
|
21
21
|
dark() {
|
|
22
|
-
return this.
|
|
22
|
+
return this.apiDropdownMenu().isDark;
|
|
23
23
|
},
|
|
24
24
|
|
|
25
25
|
headless() {
|
|
26
|
-
return this.
|
|
26
|
+
return this.apiDropdownMenu().isHeadless;
|
|
27
27
|
},
|
|
28
28
|
},
|
|
29
29
|
};
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
:aria-haspopup="hasPopup"
|
|
5
5
|
:aria-expanded="expanded"
|
|
6
6
|
:aria-controls="controls"
|
|
7
|
-
@keydown.down.prevent="
|
|
8
|
-
@keydown.up.prevent="
|
|
9
|
-
@keydown.esc.stop="
|
|
7
|
+
@keydown.down.prevent="onKeyDownOrUp"
|
|
8
|
+
@keydown.up.prevent="onKeyDownOrUp"
|
|
9
|
+
@keydown.esc.stop="onKeyEsc"
|
|
10
10
|
>
|
|
11
11
|
<slot></slot>
|
|
12
12
|
</div>
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
export default {
|
|
17
17
|
name: 'VTDropdownMenuTrigger',
|
|
18
18
|
|
|
19
|
-
inject: ['
|
|
19
|
+
inject: ['apiDropdownMenu'],
|
|
20
20
|
|
|
21
21
|
data() {
|
|
22
22
|
return {
|
|
@@ -29,15 +29,15 @@ export default {
|
|
|
29
29
|
|
|
30
30
|
computed: {
|
|
31
31
|
id() {
|
|
32
|
-
return `dropdown-menu-trigger-${this.
|
|
32
|
+
return `dropdown-menu-trigger-${this.apiDropdownMenu().id}`;
|
|
33
33
|
},
|
|
34
34
|
|
|
35
35
|
componentContent() {
|
|
36
|
-
return this.
|
|
36
|
+
return this.apiDropdownMenu().componentContent;
|
|
37
37
|
},
|
|
38
38
|
|
|
39
39
|
items() {
|
|
40
|
-
return this.
|
|
40
|
+
return this.apiDropdownMenu().items;
|
|
41
41
|
},
|
|
42
42
|
|
|
43
43
|
firstMenuItem() {
|
|
@@ -49,17 +49,21 @@ export default {
|
|
|
49
49
|
},
|
|
50
50
|
},
|
|
51
51
|
|
|
52
|
+
watch: {
|
|
53
|
+
expanded() {
|
|
54
|
+
this.toggleAriaHasPopup();
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
|
|
52
58
|
mounted() {
|
|
53
59
|
const trigger = {
|
|
54
|
-
|
|
55
|
-
hideExpanded: this.hideExpanded,
|
|
60
|
+
id: this.id,
|
|
56
61
|
el: this.$el,
|
|
62
|
+
cancel: this.cancel,
|
|
57
63
|
focus: this.focus,
|
|
58
|
-
id: this.id,
|
|
59
|
-
onClick: this.onClick,
|
|
60
64
|
};
|
|
61
65
|
|
|
62
|
-
this.
|
|
66
|
+
this.apiDropdownMenu().registerTrigger(trigger);
|
|
63
67
|
|
|
64
68
|
this.setTrigger();
|
|
65
69
|
this.addTriggerEvents();
|
|
@@ -90,128 +94,88 @@ export default {
|
|
|
90
94
|
});
|
|
91
95
|
},
|
|
92
96
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
this.expanded = true;
|
|
98
|
-
this.componentContent.show();
|
|
99
|
-
},
|
|
97
|
+
init(e) {
|
|
98
|
+
if (!this.componentContent) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
100
101
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (this.trigger) this.trigger.focus();
|
|
106
|
-
},
|
|
102
|
+
if (this.expanded) {
|
|
103
|
+
this.cancel();
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
107
106
|
|
|
108
|
-
|
|
109
|
-
toggleExpanded() {
|
|
110
|
-
if (!this.expanded) return;
|
|
111
|
-
this.expanded = false;
|
|
112
|
-
},
|
|
107
|
+
this.expanded = true;
|
|
113
108
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
this.
|
|
109
|
+
// delay stop propagation to close other visible
|
|
110
|
+
// dropdowns and delay click event to control
|
|
111
|
+
// this dropdown visibility
|
|
112
|
+
setTimeout(() => e.stopImmediatePropagation(), 50);
|
|
113
|
+
setTimeout(() => this.showComponentContent(), 100);
|
|
119
114
|
},
|
|
120
115
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
*/
|
|
124
|
-
toggleHasPopup() {
|
|
125
|
-
if (!this.componentContent) return;
|
|
126
|
-
|
|
127
|
-
this.hasPopup = !this.hasPopup;
|
|
128
|
-
|
|
129
|
-
if (!this.hasPopup) {
|
|
130
|
-
this.controls = null;
|
|
116
|
+
cancel() {
|
|
117
|
+
if (!this.componentContent) {
|
|
131
118
|
return;
|
|
132
119
|
}
|
|
133
120
|
|
|
134
|
-
this.
|
|
121
|
+
this.expanded = false;
|
|
122
|
+
|
|
123
|
+
this.hideComponentContent();
|
|
135
124
|
},
|
|
136
125
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
*/
|
|
141
|
-
hide() {
|
|
142
|
-
this.hideExpanded();
|
|
126
|
+
focus() {
|
|
127
|
+
if (this.trigger) this.trigger.focus();
|
|
128
|
+
},
|
|
143
129
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
});
|
|
130
|
+
showComponentContent() {
|
|
131
|
+
this.componentContent.show();
|
|
147
132
|
},
|
|
148
133
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
* 1. Toggle aria expanded attribute/state
|
|
153
|
-
* 2. Open the menu if it's closed
|
|
154
|
-
* 3. Close the menu if it's open
|
|
155
|
-
*/
|
|
156
|
-
onClick(e) {
|
|
157
|
-
if (!this.componentContent) return;
|
|
134
|
+
hideComponentContent() {
|
|
135
|
+
this.componentContent.hide();
|
|
136
|
+
},
|
|
158
137
|
|
|
138
|
+
toggleAriaHasPopup() {
|
|
159
139
|
if (this.expanded) {
|
|
160
|
-
this.componentContent
|
|
140
|
+
this.hasPopup = this.componentContent !== null;
|
|
141
|
+
this.controls = this.hasPopup ? this.componentContent.id : null;
|
|
142
|
+
|
|
161
143
|
return;
|
|
162
144
|
}
|
|
163
145
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
// this dropdown visibility
|
|
167
|
-
setTimeout(() => e.stopImmediatePropagation(), 50);
|
|
168
|
-
setTimeout(() => this.showContent(), 100);
|
|
146
|
+
this.hasPopup = null;
|
|
147
|
+
this.controls = null;
|
|
169
148
|
},
|
|
170
149
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
*
|
|
174
|
-
* 1. if the menu is not expanded, expand it and focus the first menu item
|
|
175
|
-
* 2. if the menu is expanded, focus the first menu item
|
|
176
|
-
*/
|
|
177
|
-
onKeyArrowDown() {
|
|
178
|
-
if (!this.componentContent) return;
|
|
179
|
-
|
|
180
|
-
this.showContent();
|
|
181
|
-
|
|
182
|
-
// settimeout here is delaying the focusing the element
|
|
183
|
-
// since it is not rendered yet. All items will only
|
|
184
|
-
// be available when the content is fully visible.
|
|
185
|
-
this.$nextTick(() => {
|
|
186
|
-
setTimeout(() => this.firstMenuItem.focus(), 150);
|
|
187
|
-
});
|
|
150
|
+
onClick(e) {
|
|
151
|
+
this.init(e);
|
|
188
152
|
},
|
|
189
153
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
* 2. if the menu is expanded, focus the last menu item
|
|
195
|
-
*/
|
|
196
|
-
onKeyArrowUp() {
|
|
197
|
-
if (!this.componentContent) return;
|
|
154
|
+
onKeyDownOrUp(e) {
|
|
155
|
+
if (!this.expanded) {
|
|
156
|
+
this.$el.click(e);
|
|
157
|
+
}
|
|
198
158
|
|
|
199
|
-
|
|
159
|
+
const keyCode = e.code;
|
|
160
|
+
const listItemPosition =
|
|
161
|
+
keyCode === 'ArrowDown'
|
|
162
|
+
? 'firstMenuItem'
|
|
163
|
+
: keyCode === 'ArrowUp'
|
|
164
|
+
? 'lastMenuItem'
|
|
165
|
+
: null;
|
|
200
166
|
|
|
201
167
|
// settimeout here is delaying the focusing the element
|
|
202
168
|
// since it is not rendered yet. All items will only
|
|
203
169
|
// be available when the content is fully visible.
|
|
204
170
|
this.$nextTick(() => {
|
|
205
|
-
setTimeout(() => this.
|
|
171
|
+
setTimeout(() => this[listItemPosition].focus(), 100);
|
|
206
172
|
});
|
|
207
173
|
},
|
|
208
174
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
this.componentContent.hide();
|
|
214
|
-
}
|
|
175
|
+
// change it to a better name or move the methods inside to another function
|
|
176
|
+
onKeyEsc() {
|
|
177
|
+
this.cancel();
|
|
178
|
+
this.focus();
|
|
215
179
|
},
|
|
216
180
|
},
|
|
217
181
|
};
|
|
@@ -1,52 +1,40 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<input
|
|
3
|
-
|
|
4
|
-
:class="[
|
|
5
|
-
headless
|
|
6
|
-
? 'form-control'
|
|
7
|
-
: 'border border-solid py-2 px-3 rounded text-inherit',
|
|
8
|
-
headless
|
|
9
|
-
? `form-control--${variant}`
|
|
10
|
-
: isError
|
|
11
|
-
? 'border-error-300'
|
|
12
|
-
: 'border-gray-300',
|
|
13
|
-
]"
|
|
3
|
+
:class="classComputed"
|
|
14
4
|
:value="value"
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
:disabled="disabled"
|
|
6
|
+
v-on="listeners"
|
|
17
7
|
/>
|
|
18
8
|
</template>
|
|
19
9
|
|
|
20
10
|
<script>
|
|
21
|
-
|
|
22
|
-
model: {
|
|
23
|
-
prop: 'value',
|
|
24
|
-
event: 'input',
|
|
25
|
-
},
|
|
11
|
+
import { formControlMixin } from '../../../mixins/form-control';
|
|
26
12
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
type: Boolean,
|
|
30
|
-
default: false,
|
|
31
|
-
},
|
|
32
|
-
value: {
|
|
33
|
-
type: [String, Number, Object, Array],
|
|
34
|
-
default: null,
|
|
35
|
-
},
|
|
36
|
-
variant: {
|
|
37
|
-
type: [String, Object, Function],
|
|
38
|
-
default: '',
|
|
39
|
-
},
|
|
40
|
-
headless: {
|
|
41
|
-
type: Boolean,
|
|
42
|
-
default: false,
|
|
43
|
-
},
|
|
44
|
-
},
|
|
13
|
+
export default {
|
|
14
|
+
mixins: [formControlMixin],
|
|
45
15
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
16
|
+
data() {
|
|
17
|
+
return {
|
|
18
|
+
name: 'input',
|
|
19
|
+
};
|
|
50
20
|
},
|
|
51
21
|
};
|
|
52
22
|
</script>
|
|
23
|
+
|
|
24
|
+
<style scoped>
|
|
25
|
+
input[type='date']::-webkit-inner-spin-button,
|
|
26
|
+
input[type='date']::-webkit-calendar-picker-indicator {
|
|
27
|
+
position: absolute;
|
|
28
|
+
opacity: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
input[type='number'] {
|
|
32
|
+
appearance: textfield;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
input[type='number']::-webkit-inner-spin-button,
|
|
36
|
+
input[type='number']::-webkit-outer-spin-button {
|
|
37
|
+
appearance: none;
|
|
38
|
+
-webkit-appearance: none;
|
|
39
|
+
}
|
|
40
|
+
</style>
|