@eturnity/eturnity_reusable_components 1.0.45 → 1.0.49
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 +1 -1
- package/src/App.vue +5 -16
- package/src/assets/icons/collapse_arrow_icon.svg +1 -0
- package/src/assets/icons/search_icon_black.svg +3 -0
- package/src/components/inputs/inputNumber/index.vue +1 -0
- package/src/components/inputs/searchInput/index.vue +84 -0
- package/src/components/spinner/index.vue +1 -0
- package/src/components/tableDropdown.vue/index.vue +286 -0
- package/src/components/tables/mainTable/index.vue +1 -3
package/package.json
CHANGED
package/src/App.vue
CHANGED
|
@@ -13,20 +13,6 @@
|
|
|
13
13
|
</thead>
|
|
14
14
|
<tbody>
|
|
15
15
|
<tr>
|
|
16
|
-
<td>
|
|
17
|
-
<input-number
|
|
18
|
-
placeholder="Enter distance"
|
|
19
|
-
:isError="false"
|
|
20
|
-
:numberPrecision="2"
|
|
21
|
-
unitName="pc"
|
|
22
|
-
:value="inputValue"
|
|
23
|
-
@input-change="onInputChange($event)"
|
|
24
|
-
errorMessage="Enter a number between 1 and 10"
|
|
25
|
-
:disabled="false"
|
|
26
|
-
:noBorder="true"
|
|
27
|
-
textAlign="left"
|
|
28
|
-
/>
|
|
29
|
-
</td>
|
|
30
16
|
<td class="text">Body 2</td>
|
|
31
17
|
<td class="text">Body 3</td>
|
|
32
18
|
<td class="text">Body 4</td>
|
|
@@ -36,6 +22,9 @@
|
|
|
36
22
|
</tr>
|
|
37
23
|
</tbody>
|
|
38
24
|
</main-table>
|
|
25
|
+
<br />
|
|
26
|
+
<br />
|
|
27
|
+
<search-input :value="inputValue" @on-change="onInputChange" :disabled="false" placeholder="Search..." />
|
|
39
28
|
</page-container>
|
|
40
29
|
</ThemeProvider>
|
|
41
30
|
</template>
|
|
@@ -46,7 +35,7 @@ import theme from "./assets/theme"
|
|
|
46
35
|
import styled from "vue-styled-components"
|
|
47
36
|
import MainTable from "@/components/tables/mainTable"
|
|
48
37
|
import ThreeDots from "@/components/threeDots"
|
|
49
|
-
import
|
|
38
|
+
import SearchInput from "@/components/inputs/searchInput"
|
|
50
39
|
|
|
51
40
|
const PageContainer = styled.div`
|
|
52
41
|
padding: 40px;
|
|
@@ -59,7 +48,7 @@ export default {
|
|
|
59
48
|
PageContainer,
|
|
60
49
|
MainTable,
|
|
61
50
|
ThreeDots,
|
|
62
|
-
|
|
51
|
+
SearchInput,
|
|
63
52
|
},
|
|
64
53
|
data() {
|
|
65
54
|
return {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 5"><g data-name="Layer 2"><path fill="#263238" d="M0 0h8L4 5 0 0z" data-name="Layer 1"/></g></svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M14.9751 13.6383L11.3396 9.9957C12.0755 8.94938 12.4395 7.6858 12.3731 6.40752C12.3068 5.12923 11.8141 3.91027 10.9739 2.94605C10.1337 1.98183 8.9947 1.3282 7.73954 1.08993C6.48437 0.85166 5.1857 1.04256 4.05173 1.63202C2.91776 2.22148 2.01415 3.17536 1.48577 4.34076C0.957383 5.50615 0.834825 6.81556 1.13774 8.05906C1.44065 9.30257 2.1515 10.4082 3.15631 11.1986C4.16113 11.989 5.40173 12.4185 6.67922 12.4183C7.86776 12.418 9.02614 12.0434 9.99056 11.3474L13.626 14.9901L14.9751 13.6383ZM3.98109 9.38128C3.44671 8.84727 3.08262 8.16629 2.93499 7.42469C2.78736 6.68309 2.86284 5.91427 3.15185 5.2157C3.44086 4.51713 3.93039 3.92029 4.55837 3.50084C5.18635 3.08139 5.9245 2.85823 6.67922 2.85965C7.40253 2.85844 8.11118 3.06399 8.72198 3.45218C9.33279 3.84037 9.8204 4.39508 10.1276 5.05121C10.4348 5.70735 10.5488 6.43766 10.4562 7.15645C10.3637 7.87523 10.0684 8.55264 9.60512 9.10918L9.09703 9.61827C8.37063 10.2302 7.44086 10.5457 6.49283 10.5017C5.54479 10.4578 4.64804 10.0578 3.98109 9.38128Z" fill="#263238"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<container>
|
|
3
|
+
<input-wrapper>
|
|
4
|
+
<input-container
|
|
5
|
+
:placeholder="placeholder"
|
|
6
|
+
:value="value"
|
|
7
|
+
@input="onChangeHandler($event)"
|
|
8
|
+
:disabled="disabled"
|
|
9
|
+
:isDisabled="disabled"
|
|
10
|
+
/>
|
|
11
|
+
<img
|
|
12
|
+
class="search-icn"
|
|
13
|
+
:src="require('../../../assets/icons/search_icon_black.svg')"
|
|
14
|
+
/>
|
|
15
|
+
</input-wrapper>
|
|
16
|
+
</container>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<script>
|
|
20
|
+
// import SearchInput from "@eturnity/eturnity_reusable_components/src/components/inputs/searchInput"
|
|
21
|
+
import styled from 'vue-styled-components'
|
|
22
|
+
|
|
23
|
+
const Container = styled.div`
|
|
24
|
+
width: 100%;
|
|
25
|
+
position: relative;
|
|
26
|
+
`
|
|
27
|
+
|
|
28
|
+
const inputAttrs = { isDisabled: Boolean }
|
|
29
|
+
const InputContainer = styled('input', inputAttrs)`
|
|
30
|
+
border: 1px solid ${(props) => props.theme.colors.mediumGray};
|
|
31
|
+
padding: 11px 30px 11px 10px;
|
|
32
|
+
border-radius: 4px;
|
|
33
|
+
font-size: 16px;
|
|
34
|
+
color: ${(props) => props.theme.colors.black};
|
|
35
|
+
width: 100%;
|
|
36
|
+
box-sizing: border-box;
|
|
37
|
+
cursor: ${props => props.isDisabled ? 'not-allowed' : 'auto'};
|
|
38
|
+
|
|
39
|
+
&::placeholder {
|
|
40
|
+
color: ${(props) => props.theme.colors.darkGray};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&:focus {
|
|
44
|
+
outline: none;
|
|
45
|
+
}
|
|
46
|
+
`
|
|
47
|
+
|
|
48
|
+
const InputWrapper = styled.span`
|
|
49
|
+
position: relative;
|
|
50
|
+
|
|
51
|
+
img {
|
|
52
|
+
position: absolute;
|
|
53
|
+
right: 10px;
|
|
54
|
+
top: 0;
|
|
55
|
+
}
|
|
56
|
+
`
|
|
57
|
+
|
|
58
|
+
export default {
|
|
59
|
+
name: "search-input",
|
|
60
|
+
components: {
|
|
61
|
+
InputContainer,
|
|
62
|
+
InputWrapper,
|
|
63
|
+
Container
|
|
64
|
+
},
|
|
65
|
+
props: {
|
|
66
|
+
value: {
|
|
67
|
+
required: true
|
|
68
|
+
},
|
|
69
|
+
disabled: {
|
|
70
|
+
required: false,
|
|
71
|
+
default: false
|
|
72
|
+
},
|
|
73
|
+
placeholder: {
|
|
74
|
+
required: false,
|
|
75
|
+
default: ''
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
methods: {
|
|
79
|
+
onChangeHandler(event) {
|
|
80
|
+
this.$emit('on-change', event)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
</script>
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<dropdown-row :colspan="colSpan" @click="toggleOpen" ref="dropdownItem">
|
|
3
|
+
<component-container :colSpan="colSpan">
|
|
4
|
+
<component-item v-for="(item, index) in tableItems" :key="index">
|
|
5
|
+
{{ item.value }}
|
|
6
|
+
</component-item>
|
|
7
|
+
<et-popover
|
|
8
|
+
v-if="showArchived"
|
|
9
|
+
style="position: absolute; left: 5px; top: 13px; z-index: 99"
|
|
10
|
+
button-class="error"
|
|
11
|
+
:text="$gettext(`Component has been archived and shouldn't be used`)"
|
|
12
|
+
triggerType="hover"
|
|
13
|
+
></et-popover>
|
|
14
|
+
<arrow-down
|
|
15
|
+
v-if="!isOpen"
|
|
16
|
+
class="arrow-dropdown"
|
|
17
|
+
:src="require('../../assets/images/collapse_arrow_icon.svg')"
|
|
18
|
+
/>
|
|
19
|
+
<arrow-up
|
|
20
|
+
v-else
|
|
21
|
+
:src="require('../../assets/images/collapse_arrow_icon.svg')"
|
|
22
|
+
/>
|
|
23
|
+
</component-container>
|
|
24
|
+
<options-container
|
|
25
|
+
v-if="isOpen"
|
|
26
|
+
:top="getItemLocation('top')"
|
|
27
|
+
:width="getItemLocation('width')"
|
|
28
|
+
ref="optionsContainer"
|
|
29
|
+
>
|
|
30
|
+
<options-wrapper @click.prevent.stop>
|
|
31
|
+
<search-container @click.prevent.stop>
|
|
32
|
+
<search-input
|
|
33
|
+
:value="inputText"
|
|
34
|
+
:placeholder="$gettext('Keyword') + '...'"
|
|
35
|
+
@click.prevent.stop
|
|
36
|
+
@on-change="onSearch($event)"
|
|
37
|
+
ref="searchInput"
|
|
38
|
+
/>
|
|
39
|
+
</search-container>
|
|
40
|
+
<spinner v-if="optionsLoading" />
|
|
41
|
+
<empty-text v-else-if="!optionsLoading && !optionItems.length">
|
|
42
|
+
{{ emptyText ? emptyText : $gettext("No components found.") }}
|
|
43
|
+
</empty-text>
|
|
44
|
+
<options-item
|
|
45
|
+
v-else
|
|
46
|
+
:colSpan="colSpan"
|
|
47
|
+
v-for="(item, index) in optionItems"
|
|
48
|
+
:key="index"
|
|
49
|
+
@click="onItemClick(item)"
|
|
50
|
+
:tabindex="0"
|
|
51
|
+
@keyup.enter.native="onItemClick(item)"
|
|
52
|
+
>
|
|
53
|
+
<span v-for="(option, idx) in optionsDisplay" :key="idx">
|
|
54
|
+
{{ item[option] }}
|
|
55
|
+
</span>
|
|
56
|
+
</options-item>
|
|
57
|
+
</options-wrapper>
|
|
58
|
+
</options-container>
|
|
59
|
+
</dropdown-row>
|
|
60
|
+
</template>
|
|
61
|
+
|
|
62
|
+
<script>
|
|
63
|
+
// import TableDropdown from "@eturnity/eturnity_reusable_components/src/components/tableDropdown"
|
|
64
|
+
// To use:
|
|
65
|
+
// <table-dropdown
|
|
66
|
+
// :colSpan="2"
|
|
67
|
+
// :tableItems="getDropdownValues(row)"
|
|
68
|
+
// :showArchived="
|
|
69
|
+
// row.selectedValue
|
|
70
|
+
// ? row.selectedValue.status_active === false
|
|
71
|
+
// : row.status_active === false
|
|
72
|
+
// "
|
|
73
|
+
// @toggle-dropdown-open="toggleDropdownOpen(row.id, $event)"
|
|
74
|
+
// @dropdown-search="onDropdownSearch($event)"
|
|
75
|
+
// @item-selected="onItemSelected({ item: $event, index })"
|
|
76
|
+
// :isOpen="isDropdownOpen(row)"
|
|
77
|
+
// :optionItems="groupComponents" // list of options
|
|
78
|
+
// :optionsLoading="dropdownOptionsLoading"
|
|
79
|
+
// :optionsDisplay="['display_name', 'company_item_number']" // Array. what should be displayed
|
|
80
|
+
// />
|
|
81
|
+
import styled from "vue-styled-components"
|
|
82
|
+
import Spinner from "@eturnity/eturnity_reusable_components/src/components/spinner"
|
|
83
|
+
import SearchInput from "@eturnity/eturnity_reusable_components/src/components/inputs/searchInput"
|
|
84
|
+
|
|
85
|
+
const DropdownRow = styled.td``
|
|
86
|
+
|
|
87
|
+
const ComponentItem = styled.div`
|
|
88
|
+
padding-left: 12px;
|
|
89
|
+
overflow: hidden;
|
|
90
|
+
text-overflow: ellipsis;
|
|
91
|
+
`
|
|
92
|
+
|
|
93
|
+
const containerAttrs = { colSpan: Number }
|
|
94
|
+
const ComponentContainer = styled("div", containerAttrs)`
|
|
95
|
+
display: grid;
|
|
96
|
+
grid-template-columns: repeat(${(props) => props.colSpan}, minmax(0, 1fr)) auto;
|
|
97
|
+
grid-gap: 12px;
|
|
98
|
+
align-items: center;
|
|
99
|
+
background-color: #fff;
|
|
100
|
+
border-radius: 4px;
|
|
101
|
+
padding: 5px 4px;
|
|
102
|
+
`
|
|
103
|
+
|
|
104
|
+
const ArrowDown = styled.img`
|
|
105
|
+
width: 8px;
|
|
106
|
+
transform: rotate(0deg);
|
|
107
|
+
transition: transform 150ms ease;
|
|
108
|
+
`
|
|
109
|
+
|
|
110
|
+
const ArrowUp = styled.img`
|
|
111
|
+
width: 8px;
|
|
112
|
+
transform: rotate(180deg);
|
|
113
|
+
transition: transform 150ms ease;
|
|
114
|
+
`
|
|
115
|
+
|
|
116
|
+
const optionsAttrs = { top: Number, width: Number }
|
|
117
|
+
const OptionsContainer = styled("div", optionsAttrs)`
|
|
118
|
+
position: absolute;
|
|
119
|
+
display: grid;
|
|
120
|
+
top: ${(props) => props.top + "px"};
|
|
121
|
+
width: ${(props) => props.width + "px"};
|
|
122
|
+
max-height: 360px;
|
|
123
|
+
min-height: 200px;
|
|
124
|
+
overflow: auto;
|
|
125
|
+
border: 1px solid ${(props) => props.theme.colors.grey3};
|
|
126
|
+
z-index: 9999;
|
|
127
|
+
background: #fff;
|
|
128
|
+
border-radius: 4px;
|
|
129
|
+
`
|
|
130
|
+
|
|
131
|
+
const EmptyText = styled.div`
|
|
132
|
+
align-self: center;
|
|
133
|
+
justify-self: center;
|
|
134
|
+
height: 100px;
|
|
135
|
+
display: grid;
|
|
136
|
+
align-content: center;
|
|
137
|
+
`
|
|
138
|
+
|
|
139
|
+
const OptionsWrapper = styled.div`
|
|
140
|
+
display: grid;
|
|
141
|
+
position: relative;
|
|
142
|
+
padding: 12px;
|
|
143
|
+
grid-gap: 4px;
|
|
144
|
+
font-size: 14px;
|
|
145
|
+
grid-template-rows: max-content;
|
|
146
|
+
height: max-content;
|
|
147
|
+
`
|
|
148
|
+
|
|
149
|
+
const OptionsItem = styled("div", containerAttrs)`
|
|
150
|
+
display: grid;
|
|
151
|
+
grid-template-columns: repeat(${(props) => props.colSpan}, minmax(0, 1fr));
|
|
152
|
+
grid-gap: 12px;
|
|
153
|
+
overflow: hidden;
|
|
154
|
+
text-overflow: ellipsis;
|
|
155
|
+
padding: 10px;
|
|
156
|
+
height: max-content;
|
|
157
|
+
|
|
158
|
+
&:hover {
|
|
159
|
+
background-color: ${(props) => props.theme.colors.grey5};
|
|
160
|
+
}
|
|
161
|
+
`
|
|
162
|
+
|
|
163
|
+
const SearchContainer = styled.div`
|
|
164
|
+
position: sticky;
|
|
165
|
+
top: 0;
|
|
166
|
+
padding-top: 6px;
|
|
167
|
+
background: #fff;
|
|
168
|
+
height: 40px;
|
|
169
|
+
`
|
|
170
|
+
|
|
171
|
+
export default {
|
|
172
|
+
name: "table-dropdown",
|
|
173
|
+
components: {
|
|
174
|
+
DropdownRow,
|
|
175
|
+
ComponentItem,
|
|
176
|
+
ComponentContainer,
|
|
177
|
+
ArrowDown,
|
|
178
|
+
ArrowUp,
|
|
179
|
+
OptionsContainer,
|
|
180
|
+
Spinner,
|
|
181
|
+
EmptyText,
|
|
182
|
+
SearchInput,
|
|
183
|
+
OptionsWrapper,
|
|
184
|
+
OptionsItem,
|
|
185
|
+
SearchContainer,
|
|
186
|
+
},
|
|
187
|
+
props: {
|
|
188
|
+
colSpan: {
|
|
189
|
+
required: false,
|
|
190
|
+
default: 1,
|
|
191
|
+
},
|
|
192
|
+
tableItems: {
|
|
193
|
+
required: true,
|
|
194
|
+
},
|
|
195
|
+
showArchived: {
|
|
196
|
+
required: false,
|
|
197
|
+
default: false,
|
|
198
|
+
},
|
|
199
|
+
isOpen: {
|
|
200
|
+
required: true,
|
|
201
|
+
default: false,
|
|
202
|
+
},
|
|
203
|
+
optionsLoading: {
|
|
204
|
+
required: false,
|
|
205
|
+
default: false,
|
|
206
|
+
},
|
|
207
|
+
emptyText: {
|
|
208
|
+
required: false,
|
|
209
|
+
default: null,
|
|
210
|
+
},
|
|
211
|
+
optionItems: {
|
|
212
|
+
required: true,
|
|
213
|
+
},
|
|
214
|
+
optionsDisplay: {
|
|
215
|
+
required: true,
|
|
216
|
+
default: [], // should be like ['display_name', 'company_item_number', 'description']
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
data() {
|
|
220
|
+
return {
|
|
221
|
+
inputText: "",
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
methods: {
|
|
225
|
+
toggleOpen() {
|
|
226
|
+
if (!this.isOpen) {
|
|
227
|
+
document.addEventListener("click", this.clickOutside)
|
|
228
|
+
this.$emit("dropdown-search", "")
|
|
229
|
+
this.$nextTick(() => {
|
|
230
|
+
this.scrollToItem()
|
|
231
|
+
})
|
|
232
|
+
this.$emit("toggle-dropdown-open", { close: false })
|
|
233
|
+
this.$nextTick(() => {
|
|
234
|
+
this.$refs.searchInput.$el.children[0].children[0].focus()
|
|
235
|
+
})
|
|
236
|
+
} else {
|
|
237
|
+
document.removeEventListener("click", this.clickOutside)
|
|
238
|
+
this.$emit("toggle-dropdown-open", { close: true })
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
scrollToItem() {
|
|
242
|
+
this.$refs.optionsContainer.$el.scrollIntoView({
|
|
243
|
+
behavior: "smooth",
|
|
244
|
+
block: "center",
|
|
245
|
+
})
|
|
246
|
+
},
|
|
247
|
+
onItemClick(item) {
|
|
248
|
+
this.$emit("item-selected", item)
|
|
249
|
+
},
|
|
250
|
+
onSearch(value) {
|
|
251
|
+
this.$emit("dropdown-search", value)
|
|
252
|
+
},
|
|
253
|
+
getItemLocation(value) {
|
|
254
|
+
let ref = this.$refs.dropdownItem
|
|
255
|
+
let location = ref.$el.getBoundingClientRect()[value]
|
|
256
|
+
if (value === "top") {
|
|
257
|
+
location = location + window.scrollY + 40
|
|
258
|
+
}
|
|
259
|
+
return location
|
|
260
|
+
},
|
|
261
|
+
clickOutside(event) {
|
|
262
|
+
if (event.target === this.$el || this.$el.contains(event.target)) {
|
|
263
|
+
return
|
|
264
|
+
}
|
|
265
|
+
// 'close: true' is needed in case a box is open and another box is clicked on
|
|
266
|
+
// so this one will close properly
|
|
267
|
+
document.removeEventListener("click", this.clickOutside)
|
|
268
|
+
this.$emit("toggle-dropdown-open", { close: true })
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
watch: {
|
|
272
|
+
isOpen(newVal) {
|
|
273
|
+
if (newVal) {
|
|
274
|
+
document.addEventListener("click", this.clickOutside)
|
|
275
|
+
this.$emit("dropdown-search", "")
|
|
276
|
+
this.$nextTick(() => {
|
|
277
|
+
this.$refs.searchInput.$el.children[0].children[0].focus()
|
|
278
|
+
})
|
|
279
|
+
this.$nextTick(() => {
|
|
280
|
+
this.scrollToItem()
|
|
281
|
+
})
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
}
|
|
286
|
+
</script>
|
|
@@ -31,7 +31,7 @@ const TableTitle = styled.div`
|
|
|
31
31
|
`
|
|
32
32
|
|
|
33
33
|
const TableScroll = styled.div`
|
|
34
|
-
position: relative;
|
|
34
|
+
/* position: relative; */
|
|
35
35
|
max-width: 100%;
|
|
36
36
|
`
|
|
37
37
|
|
|
@@ -155,8 +155,6 @@ const TableContainer = styled.table`
|
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
tr {
|
|
158
|
-
position: relative;
|
|
159
|
-
|
|
160
158
|
&.disabled {
|
|
161
159
|
cursor: not-allowed;
|
|
162
160
|
}
|