@appscode/design-system 2.4.4-alpha → 2.4.5
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/main.scss +0 -3
- package/package.json +1 -1
- package/vue-components/styles/base/utilities/_global.scss +0 -87
- package/vue-components/styles/components/form-fields/_check-radio-switch.scss +45 -44
- package/vue-components/styles/components/form-fields/_custom-selectbox.scss +39 -3
- package/vue-components/styles/components/form-fields/_input.scss +1 -1
- package/vue-components/v3/form-fields/CustomSelect.vue +7 -1
- package/vue-components/v3/icons/ArrowDownIcon.vue +7 -0
- package/vue-components/v3/icons/CloseIcon.vue +7 -0
- package/vue-components/v3/upcoming/SimpleSelect.vue +134 -0
package/main.scss
CHANGED
|
@@ -4,9 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
// Third party CSS
|
|
6
6
|
@import "../node_modules/bulma/bulma.sass";
|
|
7
|
-
// @import "bulma-checkradio";
|
|
8
|
-
// @import "bulma-switch";
|
|
9
|
-
@import "bulma-tooltip";
|
|
10
7
|
@import "font-awesome/css/font-awesome.min.css";
|
|
11
8
|
@import "vue-multiselect/dist/vue-multiselect.css";
|
|
12
9
|
|
package/package.json
CHANGED
|
@@ -418,93 +418,6 @@ button {
|
|
|
418
418
|
animation-iteration-count: 20;
|
|
419
419
|
}
|
|
420
420
|
|
|
421
|
-
// Customize tooltip start
|
|
422
|
-
$background_color_1: #585d6e;
|
|
423
|
-
$border_color_1: #585d6e transparent transparent transparent;
|
|
424
|
-
$border_color_2: transparent #585d6e transparent transparent;
|
|
425
|
-
$border_color_3: transparent transparent transparent #585d6e;
|
|
426
|
-
$border_color_4: transparent transparent #585d6e transparent;
|
|
427
|
-
|
|
428
|
-
[data-tooltip] {
|
|
429
|
-
&:not(.is-loading) {
|
|
430
|
-
&::after {
|
|
431
|
-
border-color: $border_color_1;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
&::before {
|
|
435
|
-
background-color: $background_color_1;
|
|
436
|
-
font-size: 12px;
|
|
437
|
-
font-weight: 500;
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
&:not(.is-disabled) {
|
|
442
|
-
&::after {
|
|
443
|
-
border-color: $border_color_1;
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
&:not([disabled]) {
|
|
448
|
-
&::after {
|
|
449
|
-
border-color: $border_color_1;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
&:not(.is-loading).has-tooltip-right {
|
|
454
|
-
&::after {
|
|
455
|
-
border-color: $border_color_2;
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
&:not(.is-disabled).has-tooltip-right {
|
|
460
|
-
&::after {
|
|
461
|
-
border-color: $border_color_2;
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
&:not([disabled]).has-tooltip-right {
|
|
466
|
-
&::after {
|
|
467
|
-
border-color: $border_color_2;
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
&:not(.is-loading).has-tooltip-left {
|
|
472
|
-
&::after {
|
|
473
|
-
border-color: $border_color_3;
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
&:not(.is-disabled).has-tooltip-left {
|
|
478
|
-
&::after {
|
|
479
|
-
border-color: $border_color_3;
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
&:not([disabled]).has-tooltip-left {
|
|
484
|
-
&::after {
|
|
485
|
-
border-color: $border_color_3;
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
&:not(.is-loading).has-tooltip-bottom {
|
|
490
|
-
&::after {
|
|
491
|
-
border-color: $border_color_4;
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
&:not(.is-disabled).has-tooltip-bottom {
|
|
496
|
-
&::after {
|
|
497
|
-
border-color: $border_color_4;
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
&:not([disabled]).has-tooltip-bottom {
|
|
502
|
-
&::after {
|
|
503
|
-
border-color: $border_color_4;
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
|
|
508
421
|
// tooltip in vue-open-api
|
|
509
422
|
.tooltip {
|
|
510
423
|
display: block !important;
|
|
@@ -1,47 +1,48 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
1
|
+
// Old Third party dependency modification | Remove it, when 2024 AppsCode Custom Checkbox, Radio, Switch used everywhere
|
|
2
|
+
.is-checkradio.is-primary[type="checkbox"].is-primary:checked.has-background-color + label::before,
|
|
3
|
+
.is-checkradio.is-primary[type="checkbox"].is-primary:checked.has-background-color + label:before,
|
|
4
|
+
.is-checkradio.is-primary[type="checkbox"].is-primary:checked.has-background-color + label::after,
|
|
5
|
+
.is-checkradio.is-primary[type="checkbox"].is-primary:checked.has-background-color + label:after {
|
|
6
|
+
background-color: $ac-primary !important;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.is-checkradio[type="checkbox"] + label::after,
|
|
10
|
+
.is-checkradio[type="checkbox"] + label:after {
|
|
11
|
+
border-color: $ac-primary;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.is-checkradio[type="checkbox"]:checked + label::before,
|
|
15
|
+
.is-checkradio[type="checkbox"]:checked + label:before {
|
|
16
|
+
border: 1px solid $ac-primary;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.is-checkradio.is-primary[type="radio"] + label::after,
|
|
20
|
+
.is-checkradio.is-primary[type="radio"] + label:after {
|
|
21
|
+
background: $ac-primary !important;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.is-checkradio.is-primary[type="checkbox"]:checked + label::before,
|
|
25
|
+
.is-checkradio.is-primary[type="checkbox"]:checked + label:before,
|
|
26
|
+
.is-checkradio.is-primary[type="radio"]:checked + label::before,
|
|
27
|
+
.is-checkradio.is-primary[type="radio"]:checked + label:before {
|
|
28
|
+
border-color: $ac-primary;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.is-checkradio[type="radio"].is-primary:checked + label::after,
|
|
32
|
+
.is-checkradio[type="radio"].is-primary:checked + label:after {
|
|
33
|
+
background-color: $ac-primary !important;
|
|
34
|
+
border-color: $ac-primary;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.switch[type="checkbox"].is-primary:checked + label::before,
|
|
38
|
+
.switch[type="checkbox"].is-primary:checked + label:before {
|
|
39
|
+
background-color: $ac-primary;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.is-checkradio[type="radio"] + label::after,
|
|
43
|
+
.is-checkradio[type="radio"] + label:after {
|
|
44
|
+
background-color: $ac-primary;
|
|
45
|
+
}
|
|
45
46
|
|
|
46
47
|
// 2024 AppsCode Custom Checkbox, Radio, Switch style
|
|
47
48
|
// checkbox
|
|
@@ -2,11 +2,43 @@
|
|
|
2
2
|
position: relative;
|
|
3
3
|
z-index: 9;
|
|
4
4
|
|
|
5
|
+
&.is-disabled {
|
|
6
|
+
pointer-events: none;
|
|
7
|
+
}
|
|
8
|
+
|
|
5
9
|
input[type="text"] {
|
|
6
10
|
padding-right: 32px;
|
|
7
11
|
}
|
|
8
12
|
|
|
13
|
+
.custom-select-placeholder {
|
|
14
|
+
border: 1px solid $color-border-dark;
|
|
15
|
+
padding: 8px 15px;
|
|
16
|
+
border-radius: 4px;
|
|
17
|
+
line-height: 1;
|
|
18
|
+
// cursor: pointer;
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
height: 36px;
|
|
22
|
+
span {
|
|
23
|
+
line-height: 1.2;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&:hover {
|
|
27
|
+
border: 1px solid $ac-primary;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
9
31
|
&.is-extra-small {
|
|
32
|
+
height: 32px;
|
|
33
|
+
|
|
34
|
+
.custom-select-placeholder {
|
|
35
|
+
height: 32px;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.ac-field {
|
|
39
|
+
top: 5px;
|
|
40
|
+
}
|
|
41
|
+
|
|
10
42
|
.buttons {
|
|
11
43
|
.button {
|
|
12
44
|
height: 28px;
|
|
@@ -34,6 +66,7 @@
|
|
|
34
66
|
right: 2px;
|
|
35
67
|
top: 2px;
|
|
36
68
|
margin: 0;
|
|
69
|
+
z-index: 9;
|
|
37
70
|
|
|
38
71
|
.button {
|
|
39
72
|
margin: 0 !important;
|
|
@@ -54,7 +87,7 @@
|
|
|
54
87
|
width: 100%;
|
|
55
88
|
max-height: 500px;
|
|
56
89
|
overflow-y: auto;
|
|
57
|
-
transition: 0.
|
|
90
|
+
// transition: 0.2s ease-in-out;
|
|
58
91
|
opacity: 0;
|
|
59
92
|
visibility: hidden;
|
|
60
93
|
|
|
@@ -75,7 +108,7 @@
|
|
|
75
108
|
li {
|
|
76
109
|
display: flex;
|
|
77
110
|
|
|
78
|
-
&:hover:not(.is-active) {
|
|
111
|
+
&:hover:not(.is-active, .is-disabled) {
|
|
79
112
|
background-color: $primary-light-gray;
|
|
80
113
|
color: $color-heading;
|
|
81
114
|
|
|
@@ -103,7 +136,7 @@
|
|
|
103
136
|
cursor: pointer;
|
|
104
137
|
}
|
|
105
138
|
|
|
106
|
-
&:hover:not(.group li, .is-active) {
|
|
139
|
+
&:hover:not(.group li, .is-active, .is-disabled) {
|
|
107
140
|
background-color: $primary-light-gray;
|
|
108
141
|
color: $color-heading;
|
|
109
142
|
|
|
@@ -129,6 +162,9 @@
|
|
|
129
162
|
&.is-disabled {
|
|
130
163
|
opacity: 0.6;
|
|
131
164
|
cursor: not-allowed;
|
|
165
|
+
label {
|
|
166
|
+
cursor: not-allowed;
|
|
167
|
+
}
|
|
132
168
|
}
|
|
133
169
|
}
|
|
134
170
|
}
|
|
@@ -27,7 +27,13 @@ const CloseIcon = defineAsyncComponent(() => import("../icons/CloseIcon.vue"));
|
|
|
27
27
|
<div class="ac-single-input is-small is-selectbox" :class="[isOpen ? 'is-open' : '']" style="z-index: 2">
|
|
28
28
|
<!-- add 'show-label' class for move top -->
|
|
29
29
|
<label for="custom-select" class="ac-label show-label">Select Option</label>
|
|
30
|
-
|
|
30
|
+
|
|
31
|
+
<!-- <input type="text" value="Select" /> -->
|
|
32
|
+
<p class="custom-select-placeholder">
|
|
33
|
+
<span class="is-ellipsis-1">
|
|
34
|
+
Select Value Select ValueSelect ValueSelect ValueSelect ValueSelect ValueSelect Value
|
|
35
|
+
</span>
|
|
36
|
+
</p>
|
|
31
37
|
|
|
32
38
|
<div v-if="multiselect" class="ac-field field is-grouped is-clipped">
|
|
33
39
|
<div class="control">
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
withDefaults(defineProps<{ direction?: "up" | "down" }>(), {
|
|
3
|
+
direction: "up",
|
|
4
|
+
});
|
|
5
|
+
</script>
|
|
6
|
+
|
|
1
7
|
<template>
|
|
2
8
|
<svg
|
|
3
9
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -8,6 +14,7 @@
|
|
|
8
14
|
stroke-width="1.5"
|
|
9
15
|
stroke="currentColor"
|
|
10
16
|
class="size-6"
|
|
17
|
+
:style="direction === 'up' ? 'transform: rotate(0deg)' : 'transform: rotate(-180deg)'"
|
|
11
18
|
>
|
|
12
19
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
|
|
13
20
|
</svg>
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
withDefaults(defineProps<{ direction?: "up" | "down" }>(), {
|
|
3
|
+
direction: "up",
|
|
4
|
+
});
|
|
5
|
+
</script>
|
|
6
|
+
|
|
1
7
|
<template>
|
|
2
8
|
<svg
|
|
3
9
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -8,6 +14,7 @@
|
|
|
8
14
|
stroke-width="1.5"
|
|
9
15
|
stroke="currentColor"
|
|
10
16
|
class="size-6"
|
|
17
|
+
:style="direction === 'up' ? 'transform: rotate(0deg)' : 'transform: rotate(-180deg)'"
|
|
11
18
|
>
|
|
12
19
|
<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
|
|
13
20
|
</svg>
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, defineAsyncComponent, ref, watch } from "vue";
|
|
3
|
+
import { onClickOutside, useFocus } from "@vueuse/core";
|
|
4
|
+
|
|
5
|
+
import AcButton from "../button/Button.vue";
|
|
6
|
+
import AcButtons from "../button/Buttons.vue";
|
|
7
|
+
|
|
8
|
+
const ArrowDownIcon = defineAsyncComponent(() => import("../icons/ArrowDownIcon.vue"));
|
|
9
|
+
const RefreshIcon = defineAsyncComponent(() => import("../icons/RefreshIcon.vue"));
|
|
10
|
+
const CloseIcon = defineAsyncComponent(() => import("../icons/CloseIcon.vue"));
|
|
11
|
+
|
|
12
|
+
type Option = { text: string; value: string };
|
|
13
|
+
interface prop {
|
|
14
|
+
custom?: boolean;
|
|
15
|
+
options?: Array<Option>;
|
|
16
|
+
isLoading?: boolean;
|
|
17
|
+
optionType?: "simple" | "custom";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const props = withDefaults(defineProps<prop>(), {
|
|
21
|
+
custom: false,
|
|
22
|
+
options: () => [],
|
|
23
|
+
isLoading: false,
|
|
24
|
+
optionType: "simple",
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
defineEmits(["onRefreshClick"]);
|
|
28
|
+
|
|
29
|
+
const selectedValue = ref<Option>();
|
|
30
|
+
const labelHoisted = ref(false);
|
|
31
|
+
const searchText = ref("");
|
|
32
|
+
const isOpen = ref(false);
|
|
33
|
+
|
|
34
|
+
// handle outside box
|
|
35
|
+
const selectBox = ref(null);
|
|
36
|
+
onClickOutside(selectBox, () => (isOpen.value = false));
|
|
37
|
+
|
|
38
|
+
// handle input click
|
|
39
|
+
const searchInput = ref(null);
|
|
40
|
+
const { focused } = useFocus(searchInput, { initialValue: true });
|
|
41
|
+
|
|
42
|
+
// filter options based on search text
|
|
43
|
+
const filteredOptions = computed(() => {
|
|
44
|
+
if (searchText.value) {
|
|
45
|
+
return props.options.filter((op) => op.text.includes(searchText.value));
|
|
46
|
+
} else return props.options || [];
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// handle selection
|
|
50
|
+
const onLabelClick = (op: Option) => {
|
|
51
|
+
selectedValue.value = op;
|
|
52
|
+
isOpen.value = false;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// handle label click
|
|
56
|
+
const selectClick = () => {
|
|
57
|
+
isOpen.value = true;
|
|
58
|
+
focused.value = true;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// handle clear btn
|
|
62
|
+
const handleClear = () => {
|
|
63
|
+
selectedValue.value = undefined;
|
|
64
|
+
searchText.value = "";
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// handle depend on selected data
|
|
68
|
+
watch(selectedValue, (n) => {
|
|
69
|
+
if (n) labelHoisted.value = true;
|
|
70
|
+
else labelHoisted.value = false;
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
watch(isOpen, (n) => {
|
|
74
|
+
if (n) searchText.value = "";
|
|
75
|
+
else {
|
|
76
|
+
if (!selectedValue.value?.value) labelHoisted.value = false;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<template>
|
|
82
|
+
<div
|
|
83
|
+
ref="selectBox"
|
|
84
|
+
class="ac-single-input is-small is-selectbox"
|
|
85
|
+
:class="{ 'is-open': isOpen, 'is-disabled': isLoading }"
|
|
86
|
+
:style="[isOpen ? { 'z-index': 2 } : '']"
|
|
87
|
+
>
|
|
88
|
+
<label for="custom-select" class="ac-label" :class="{ 'show-label': labelHoisted || isOpen }" @click="selectClick">
|
|
89
|
+
Select Option
|
|
90
|
+
</label>
|
|
91
|
+
|
|
92
|
+
<input
|
|
93
|
+
v-if="isOpen"
|
|
94
|
+
v-model="searchText"
|
|
95
|
+
type="text"
|
|
96
|
+
ref="searchInput"
|
|
97
|
+
placeholder="Select One"
|
|
98
|
+
@click="selectClick"
|
|
99
|
+
/>
|
|
100
|
+
|
|
101
|
+
<p v-else class="custom-select-placeholder" @click="selectClick">
|
|
102
|
+
<span class="is-ellipsis-1">{{ selectedValue?.text }}</span>
|
|
103
|
+
</p>
|
|
104
|
+
|
|
105
|
+
<ac-buttons>
|
|
106
|
+
<button class="button ac-button is-white" @click="handleClear">
|
|
107
|
+
<ArrowDownIcon />
|
|
108
|
+
</button>
|
|
109
|
+
|
|
110
|
+
<ac-button modifier-classes="is-white" @click="$emit('onRefreshClick')">
|
|
111
|
+
<RefreshIcon :class="{ 'is-spin': isLoading }" />
|
|
112
|
+
</ac-button>
|
|
113
|
+
|
|
114
|
+
<ac-button modifier-classes="is-white" @click="isOpen = !isOpen">
|
|
115
|
+
<CloseIcon :direction="isOpen ? 'down' : 'up'" />
|
|
116
|
+
</ac-button>
|
|
117
|
+
</ac-buttons>
|
|
118
|
+
|
|
119
|
+
<div v-if="optionType === 'custom'" class="custom-select options">
|
|
120
|
+
<slot />
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<ul v-else class="options">
|
|
124
|
+
<template v-for="op in filteredOptions" :key="op.value">
|
|
125
|
+
<li @click="onLabelClick(op)" :class="{ 'is-active': selectedValue?.value === op.value }">
|
|
126
|
+
<label for="opt-one">{{ op.text }}</label>
|
|
127
|
+
</li>
|
|
128
|
+
</template>
|
|
129
|
+
<li v-if="filteredOptions.length <= 0" class="is-disabled">
|
|
130
|
+
<label>No element found. Consider changing the search text</label>
|
|
131
|
+
</li>
|
|
132
|
+
</ul>
|
|
133
|
+
</div>
|
|
134
|
+
</template>
|