edvoyui-component-library-test-flight 0.0.149 → 0.0.151

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.
@@ -0,0 +1,167 @@
1
+ <template>
2
+ <div class="relative h-10 rounded-full">
3
+ <template v-if="icon">
4
+ <div
5
+ v-if="icon"
6
+ class="absolute flex items-center justify-center w-6 h-6 top-2 left-4"
7
+ >
8
+ <component
9
+ :is="icon"
10
+ :class="[
11
+ 'w-5 h-5',
12
+ { 'text-gray-800': inputValue },
13
+ hasError ? 'text-red-500' : 'text-gray-400',
14
+ ]"
15
+ aria-hidden="true"
16
+ />
17
+ </div>
18
+ </template>
19
+ <input
20
+ ref="searchInput"
21
+ type="text"
22
+ :class="['search-input', hasError ? 'error-state' : '']"
23
+ :placeholder="placeholder"
24
+ :value="modelValue"
25
+ @input="emitInput"
26
+ @focus="onFocus"
27
+ @blur="onBlur"
28
+ @click="onClick"
29
+ />
30
+ <div
31
+ v-if="inputValue"
32
+ class="absolute flex items-center justify-center w-6 h-6 text-gray-400 transition-colors duration-150 ease-in bg-gray-100 cursor-pointer hover:text-gray-700 rounded-xl top-2 right-2"
33
+ @click.stop="clearSearch"
34
+ >
35
+ <XMarkIcon class="w-3 h-3 text-current" />
36
+ </div>
37
+ </div>
38
+ </template>
39
+
40
+ <script setup lang="ts">
41
+ import { computed, nextTick, onMounted, ref } from "vue";
42
+ import { XMarkIcon } from "@heroicons/vue/20/solid";
43
+
44
+ const props = defineProps({
45
+ modelValue: {
46
+ type: [String, Number],
47
+ default: "",
48
+ },
49
+ isToFocus: {
50
+ type: Boolean,
51
+ required: false,
52
+ default: false,
53
+ },
54
+ placeholder: {
55
+ type: String,
56
+ required: false,
57
+ default: "",
58
+ },
59
+ icon: {
60
+ type: [Object, Function],
61
+ required: false,
62
+ },
63
+ hasError: {
64
+ type: Boolean,
65
+ required: false,
66
+ default: false,
67
+ },
68
+ disabled: {
69
+ type: Boolean,
70
+ required: false,
71
+ default: false,
72
+ },
73
+ });
74
+
75
+ const searchInput = ref<HTMLInputElement>();
76
+ const hasFocus = ref(false);
77
+ const emit = defineEmits([
78
+ "update:modelValue",
79
+ "blur",
80
+ "cleared",
81
+ "focus",
82
+ "click",
83
+ ]);
84
+
85
+ const emitInput = (event: Event) => {
86
+ const inputElement = event.target as HTMLInputElement;
87
+ let newValue = inputElement.value;
88
+ if (newValue !== undefined) {
89
+ //TODO: firstlater is uppercase added
90
+ const selectionStart = inputElement.selectionStart;
91
+ const selectionEnd = inputElement.selectionEnd;
92
+ if (typeof newValue === "string" && newValue.length > 0) {
93
+ if (newValue[0] !== newValue[0].toUpperCase()) {
94
+ newValue = newValue.charAt(0).toUpperCase() + newValue.slice(1);
95
+ }
96
+ }
97
+ emit("update:modelValue", newValue);
98
+
99
+ nextTick(() => {
100
+ if (searchInput.value) {
101
+ if (searchInput.value.value === newValue) {
102
+ searchInput.value.setSelectionRange(selectionStart, selectionEnd);
103
+ }
104
+ }
105
+ });
106
+ }
107
+ };
108
+
109
+ const inputValue = computed(() => {
110
+ return props.modelValue === 0 ? true : !!props.modelValue;
111
+ });
112
+
113
+ const onFocus = () => {
114
+ hasFocus.value = true;
115
+ emit("focus");
116
+ };
117
+
118
+ const onBlur = () => {
119
+ hasFocus.value = false;
120
+ emit("blur");
121
+ };
122
+
123
+ const onClick = () => {
124
+ emit("click");
125
+ };
126
+
127
+ const clearSearch = () => {
128
+ emit("update:modelValue", null);
129
+ emit("cleared");
130
+ nextTick(() => {
131
+ searchInput.value?.focus();
132
+ });
133
+ };
134
+
135
+ onMounted(() => {
136
+ if (props?.isToFocus) {
137
+ searchInput?.value?.focus();
138
+ }
139
+ });
140
+
141
+ // Expose the searchInput ref for parent components to access
142
+ defineExpose({
143
+ searchInput,
144
+ });
145
+ </script>
146
+
147
+ <style lang="scss" scoped>
148
+ :deep(input.search-input) {
149
+ transition: 0.2s;
150
+ @apply w-full pl-12 pr-2 py-2 text-sm text-gray-700 border-none rounded-full h-10 ring-1 ring-gray-200 ring-opacity-75 focus:ring-2 font-medium focus:ring-purple-400 focus:outline-none outline-none appearance-none ring-inset;
151
+
152
+ &::placeholder {
153
+ @apply font-normal text-gray-400;
154
+ }
155
+ &:focus::placeholder {
156
+ @apply opacity-0 invisible;
157
+ }
158
+
159
+ &.error-state {
160
+ @apply ring-1 ring-red-500;
161
+ }
162
+
163
+ &.error-state::placeholder {
164
+ @apply text-red-500;
165
+ }
166
+ }
167
+ </style>
@@ -140,17 +140,7 @@ import { computed, PropType } from "vue";
140
140
 
141
141
  const props = defineProps({
142
142
  stepStatus: {
143
- type: String as PropType<
144
- | "contact"
145
- | "MQL"
146
- | "SAL"
147
- | "SQL"
148
- | "opportunity"
149
- | "Prospect"
150
- | "Prospect Paid"
151
- | "Prospect Enrolled"
152
- | "Customer"
153
- >,
143
+ type: String,
154
144
  default: "contact",
155
145
  },
156
146
  steps: {
@@ -169,7 +159,7 @@ const props = defineProps({
169
159
  },
170
160
  history: {
171
161
  type: Array as PropType<
172
- Array<{ lifecycleStage?: string; updatedAt?: string }>
162
+ Array<{ lifecycleStage?: string; updatedAt?: string; updatedBy?: { email?: string } }>
173
163
  >,
174
164
  default: () => [],
175
165
  },
@@ -215,36 +205,10 @@ const getStatus = computed(() => {
215
205
  };
216
206
  });
217
207
 
218
- function normalizeStage(value?: string) {
219
- if (!value) return undefined;
220
- const v = value.toUpperCase();
221
- switch (v) {
222
- case "CONTACT":
223
- return "contact";
224
- case "MQL":
225
- return "MQL";
226
- case "SAL":
227
- return "SAL";
228
- case "SQL":
229
- return "SQL";
230
- case "OPPORTUNITY":
231
- return "opportunity";
232
- case "PROSPECT":
233
- return "Prospect";
234
- case "PROSPECT PAID":
235
- return "Prospect Paid";
236
- case "PROSPECT ENROLLED":
237
- return "Prospect Enrolled";
238
- case "CUSTOMER":
239
- return "Customer";
240
- default:
241
- return undefined;
242
- }
243
- }
244
208
 
245
209
  function getFormattedDate(stepValue: string) {
246
210
  const match = props.history.find(
247
- (h) => normalizeStage(h.lifecycleStage) === stepValue
211
+ (h) => h.lifecycleStage === stepValue
248
212
  );
249
213
  if (!match?.updatedAt) return "";
250
214
  try {
@@ -269,10 +233,10 @@ function getFormattedDate(stepValue: string) {
269
233
 
270
234
  function getUpdatedByEmail(stepValue: string) {
271
235
  const match = props.history.find(
272
- (h) => normalizeStage(h.lifecycleStage) === stepValue
236
+ (h) => h.lifecycleStage === stepValue
273
237
  );
274
- const email = (match as any)?.updatedBy?.email as string | undefined;
275
- return email ? `Updatead by ${email}` : "";
238
+ const email = match?.updatedBy?.email as string | undefined;
239
+ return email ? `Updated by ${email}` : "";
276
240
  }
277
241
  </script>
278
242
  <style lang="scss"></style>
@@ -1,21 +1,23 @@
1
1
  <template>
2
2
  <div
3
3
  :class="[
4
- 'inline-flex items-center px-2 py-1 rounded-md gap-x-1 bg-gray-50 ring-1 ring-inset ring-gray-400/10 max-w-xs w-auto',
5
- {'pointer-events-none select-none cursor-none': disabled}
4
+ 'inline-flex items-center max-w-xs w-auto',
5
+ {'pointer-events-none select-none': disabled},
6
+ tagClass
6
7
  ]"
7
8
  >
8
- <div class="text-sm font-medium text-gray-600 truncate cursor-pointer"><slot /></div>
9
+ <div class="text-current truncate cursor-pointer" :class="[props.size === 'lg'? 'text-base font-semibold':'text-sm font-medium']"><slot /></div>
9
10
  <button
10
11
  v-if="closeIcon"
11
12
  type="button"
12
- class="relative -mr-1 size-3.5 group rounded hover:bg-red-300/50 active:bg-red-300"
13
+ class="relative -mr-1 rounded group hover:bg-red-300/50 active:bg-red-300"
14
+ :class="[props.size === 'lg' ? 'size-6' : props.size === 'md'? 'size-5' : 'size-3.5']"
13
15
  @click.stop="removeTag"
14
16
  >
15
17
  <span class="sr-only">Remove</span>
16
18
  <svg
17
19
  viewBox="0 0 14 14"
18
- class="size-3.5 stroke-gray-400 group-hover:stroke-red-600/75"
20
+ class="stroke-gray-400 group-hover:stroke-red-600/75"
19
21
  >
20
22
  <path d="M4 4l6 6m0-6l-6 6" />
21
23
  </svg>
@@ -24,7 +26,7 @@
24
26
  </template>
25
27
 
26
28
  <script setup lang="ts">
27
- import { toRefs } from "vue";
29
+ import { computed, PropType, reactive, toRefs } from "vue";
28
30
 
29
31
  const props = defineProps({
30
32
  closeIcon: {
@@ -36,6 +38,15 @@ const props = defineProps({
36
38
  type: Boolean,
37
39
  default: false,
38
40
  },
41
+ size: {
42
+ type: String as PropType<"sm" | "md" | "lg">, //28,40, 48
43
+ default: "sm",
44
+ },
45
+ color: {
46
+ type: String as PropType<
47
+ "white" | "secondary" | 'tertiary'>,
48
+ default: "tertiary",
49
+ },
39
50
  });
40
51
  const { closeIcon } = toRefs(props);
41
52
  const emit = defineEmits(["remove"]);
@@ -43,6 +54,35 @@ const emit = defineEmits(["remove"]);
43
54
  const removeTag = () => {
44
55
  emit("remove");
45
56
  };
57
+
58
+ const sizeClasses = reactive({
59
+ sm: "px-2 py-1 rounded-md gap-x-1", // 32
60
+ md: "px-4 py-2 rounded-full gap-2", // 40
61
+ lg: "px-6 py-3 rounded-full gap-2", // 48
62
+ });
63
+
64
+ const tagClass = computed(() => {
65
+ const btnDisabled = props.disabled;
66
+ const btnColor = {
67
+ white: btnDisabled
68
+ ? "bg-opacity-80 cursor-not-allowed text-gray-400 bg-gray-200"
69
+ : "bg-white hover:bg-gray-100 text-black cursor-pointer active:shadow-white/50 active:bg-transparent",
70
+ secondary: btnDisabled
71
+ ? "bg-opacity-75 cursor-not-allowed text-gray-400 bg-purple-50"
72
+ : "bg-purple-100 hover:bg-purple-50 active:bg-purple-100 cursor-pointer text-gray-700 active:shadow-purple-200",
73
+ tertiary: btnDisabled
74
+ ? "bg-opacity-75 cursor-not-allowed text-gray-400 bg-gray-50 ring-1 ring-gray-400/20"
75
+ : "bg-gray-100 hover:bg-gray-50 active:bg-gray-100 text-gray-700 cursor-pointer active:shadow-bg-gray-200/50 ring-1 ring-gray-200",
76
+ }
77
+ const disabledClass =
78
+ props.disabled === true
79
+ ? "active:!translate-y-0 active:!scale-100 active:!shadow-none"
80
+ : "";
81
+
82
+ const colorClass = btnColor[props.color] || "";
83
+ const sizeClass = sizeClasses[props.size] || "";
84
+ return `${colorClass} ${sizeClass} ${disabledClass}`;
85
+ })
46
86
  </script>
47
87
 
48
88
  <style scoped></style>
@@ -1 +0,0 @@
1
- {"version":3,"file":"EUITelephone.vue.d.ts","sourceRoot":"","sources":["../src/components/telephone/EUITelephone.vue"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,8GAA8G,CAAC;AACrI,cAAc,8GAA8G,CAAC;AAC7H,OAAO,4GAA4G,CAAC;AACpH,eAAe,SAAS,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"EUIButton.vue.d.ts","sourceRoot":"","sources":["../../src/components/button/EUIButton.vue"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,wGAAwG,CAAC;AAC/H,cAAc,wGAAwG,CAAC;AACvH,OAAO,sGAAsG,CAAC;AAC9G,eAAe,SAAS,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"EUIButtonGroup.vue.d.ts","sourceRoot":"","sources":["../../src/components/button/EUIButtonGroup.vue"],"names":[],"mappings":"AACA,cAAc,6GAA6G,CAAC;AAC5H,OAAO,2HAA2H,CAAC;;AAEnI,wBAA0F"}