@appscode/design-system 2.4.1 → 2.4.3

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": "@appscode/design-system",
3
- "version": "2.4.1",
3
+ "version": "2.4.3",
4
4
  "description": "A design system for Appscode websites and dashboards made using Bulma",
5
5
  "main": "main.scss",
6
6
  "scripts": {
@@ -2,11 +2,40 @@
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
+
23
+ &:hover {
24
+ border: 1px solid $ac-primary;
25
+ }
26
+ }
27
+
9
28
  &.is-extra-small {
29
+ height: 32px;
30
+
31
+ .custom-select-placeholder {
32
+ height: 32px;
33
+ }
34
+
35
+ .ac-field {
36
+ top: 5px;
37
+ }
38
+
10
39
  .buttons {
11
40
  .button {
12
41
  height: 28px;
@@ -34,6 +63,7 @@
34
63
  right: 2px;
35
64
  top: 2px;
36
65
  margin: 0;
66
+ z-index: 9;
37
67
 
38
68
  .button {
39
69
  margin: 0 !important;
@@ -54,7 +84,7 @@
54
84
  width: 100%;
55
85
  max-height: 500px;
56
86
  overflow-y: auto;
57
- transition: 0.3s ease-in-out;
87
+ // transition: 0.2s ease-in-out;
58
88
  opacity: 0;
59
89
  visibility: hidden;
60
90
 
@@ -75,7 +105,7 @@
75
105
  li {
76
106
  display: flex;
77
107
 
78
- &:hover:not(.is-active) {
108
+ &:hover:not(.is-active, .is-disabled) {
79
109
  background-color: $primary-light-gray;
80
110
  color: $color-heading;
81
111
 
@@ -103,7 +133,7 @@
103
133
  cursor: pointer;
104
134
  }
105
135
 
106
- &:hover:not(.group li, .is-active) {
136
+ &:hover:not(.group li, .is-active, .is-disabled) {
107
137
  background-color: $primary-light-gray;
108
138
  color: $color-heading;
109
139
 
@@ -129,6 +159,9 @@
129
159
  &.is-disabled {
130
160
  opacity: 0.6;
131
161
  cursor: not-allowed;
162
+ label {
163
+ cursor: not-allowed;
164
+ }
132
165
  }
133
166
  }
134
167
  }
@@ -284,7 +284,7 @@
284
284
  color: $color-heading;
285
285
  position: absolute;
286
286
  z-index: 2;
287
- transition: 0.3s ease-in-out;
287
+ transition: 0.1s ease-in-out;
288
288
 
289
289
  .is-required {
290
290
  color: $danger;
@@ -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
- <input type="text" value="Select" />
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>