@muenchen/muc-patternlab-vue 1.13.0-beta.3 → 1.13.0-beta.4

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.
Files changed (43) hide show
  1. package/dist/components/Banner/MucBanner.vue.d.ts +12 -11
  2. package/dist/components/Banner/index.d.ts +0 -1
  3. package/dist/components/BuisnessHours/MucBusinessHours.vue.d.ts +74 -0
  4. package/dist/components/Button/MucButton.vue.d.ts +11 -11
  5. package/dist/components/Button/index.d.ts +0 -1
  6. package/dist/components/Callout/MucCallout.vue.d.ts +11 -11
  7. package/dist/components/Callout/index.d.ts +0 -1
  8. package/dist/components/Card/MucCard.vue.d.ts +8 -8
  9. package/dist/components/Card/index.d.ts +0 -1
  10. package/dist/components/Comment/MucComment.vue.d.ts +11 -12
  11. package/dist/components/Comment/MucCommentText.vue.d.ts +11 -12
  12. package/dist/components/Comment/index.d.ts +0 -1
  13. package/dist/components/Divider/index.d.ts +0 -1
  14. package/dist/components/Form/MucCheckbox.stories.d.ts +8 -2
  15. package/dist/components/Form/MucCheckbox.vue.d.ts +22 -14
  16. package/dist/components/Form/MucCheckboxGroup.stories.d.ts +24 -6
  17. package/dist/components/Form/MucCheckboxGroup.vue.d.ts +8 -8
  18. package/dist/components/Form/MucErrorList.vue.d.ts +3 -3
  19. package/dist/components/Form/MucInput.stories.d.ts +22 -8
  20. package/dist/components/Form/MucInput.vue.d.ts +66 -58
  21. package/dist/components/Form/MucRadioButton.stories.d.ts +30 -16
  22. package/dist/components/Form/MucRadioButton.vue.d.ts +11 -11
  23. package/dist/components/Form/MucRadioButtonGroup.vue.d.ts +38 -21
  24. package/dist/components/Form/MucRadioButtonTypes.d.ts +0 -1
  25. package/dist/components/Form/MucSelect.stories.d.ts +21 -4
  26. package/dist/components/Form/MucSelect.vue.d.ts +54 -33
  27. package/dist/components/Form/MucTextArea.stories.d.ts +14 -6
  28. package/dist/components/Form/MucTextArea.vue.d.ts +57 -45
  29. package/dist/components/Form/index.d.ts +0 -1
  30. package/dist/components/Icon/MucIcon.vue.d.ts +3 -3
  31. package/dist/components/Icon/index.d.ts +0 -1
  32. package/dist/components/Intro/MucIntro.vue.d.ts +8 -8
  33. package/dist/components/Intro/index.d.ts +0 -1
  34. package/dist/components/Link/MucLink.vue.d.ts +11 -11
  35. package/dist/components/Link/index.d.ts +0 -1
  36. package/dist/components/index.d.ts +0 -1
  37. package/dist/composables/useOnClickOutside.d.ts +3 -0
  38. package/dist/index.d.ts +0 -1
  39. package/dist/muc-patternlab-vue.es.js +425 -387
  40. package/dist/style.css +1 -1
  41. package/package.json +2 -2
  42. package/src/components/Form/MucSelect.vue +82 -7
  43. package/src/composables/useOnClickOutside.ts +24 -0
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .m-banner--success[data-v-53bc7eca]{background-color:#f1f6f3;border-bottom:1px solid #3a7f53}.m-callout--success[data-v-e6cf4104]{background-color:#f1f6f3;border-color:#95b9a2}.m-callout--success .m-callout__icon[data-v-e6cf4104]{background-color:#3a7f53;box-shadow:0 .3125rem .625rem #005a9f33}.m-callout--error[data-v-e6cf4104]{background-color:#f8f2f2;border-color:#c79a9b}.m-callout--error .m-callout__icon[data-v-e6cf4104]{background-color:#984447;box-shadow:0 .3125rem .625rem #005a9f33}.card[data-v-acf0a1dd]{cursor:pointer;border:solid 1px var(--color-neutrals-blue);border-bottom:solid 5px var(--color-brand-main-blue);transition:background-color ease-in .15s}.card[data-v-acf0a1dd]:hover{background-color:#f1f1f1}.card-content[data-v-acf0a1dd]{padding:32px 24px}.card-header[data-v-acf0a1dd]{display:flex}.card-tagline[data-v-acf0a1dd]{font-size:16px;font-family:Open Sans,sans-serif;color:#005a9f;font-weight:700;line-height:24px;word-wrap:break-word;padding-bottom:4px}.muc-divider[data-v-acf0a1dd]{margin-top:16px;margin-bottom:16px}@media all and (min-width: 992px){.card-container[data-v-6740df8f]{padding-left:0;padding-right:0;display:grid;grid-template-columns:repeat(auto-fit,384px);grid-column-gap:32px;grid-row-gap:32px}}@media all and (max-width: 992px){.card-container[data-v-6740df8f]{padding-left:0;padding-right:0;display:inline-grid;grid-template-columns:1fr;grid-row-gap:32px}}.divider-border[data-v-a2b37f5b]{border-bottom:1px solid var(--color-neutrals-blue)}.display-listbox[data-v-d28d341e]{display:block!important}.muc-divider[data-v-9ad3adc7]{margin-top:8px;margin-bottom:16px}
1
+ .m-banner--success[data-v-53bc7eca]{background-color:#f1f6f3;border-bottom:1px solid #3a7f53}.m-callout--success[data-v-e6cf4104]{background-color:#f1f6f3;border-color:#95b9a2}.m-callout--success .m-callout__icon[data-v-e6cf4104]{background-color:#3a7f53;box-shadow:0 .3125rem .625rem #005a9f33}.m-callout--error[data-v-e6cf4104]{background-color:#f8f2f2;border-color:#c79a9b}.m-callout--error .m-callout__icon[data-v-e6cf4104]{background-color:#984447;box-shadow:0 .3125rem .625rem #005a9f33}.card[data-v-acf0a1dd]{cursor:pointer;border:solid 1px var(--color-neutrals-blue);border-bottom:solid 5px var(--color-brand-main-blue);transition:background-color ease-in .15s}.card[data-v-acf0a1dd]:hover{background-color:#f1f1f1}.card-content[data-v-acf0a1dd]{padding:32px 24px}.card-header[data-v-acf0a1dd]{display:flex}.card-tagline[data-v-acf0a1dd]{font-size:16px;font-family:Open Sans,sans-serif;color:#005a9f;font-weight:700;line-height:24px;word-wrap:break-word;padding-bottom:4px}.muc-divider[data-v-acf0a1dd]{margin-top:16px;margin-bottom:16px}@media all and (min-width: 992px){.card-container[data-v-6740df8f]{padding-left:0;padding-right:0;display:grid;grid-template-columns:repeat(auto-fit,384px);grid-column-gap:32px;grid-row-gap:32px}}@media all and (max-width: 992px){.card-container[data-v-6740df8f]{padding-left:0;padding-right:0;display:inline-grid;grid-template-columns:1fr;grid-row-gap:32px}}.divider-border[data-v-a2b37f5b]{border-bottom:1px solid var(--color-neutrals-blue)}.display-listbox[data-v-0f229e1b]{display:block!important}.muc-divider[data-v-9ad3adc7]{margin-top:8px;margin-bottom:16px}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "author": "FabianWilms",
4
4
  "description": "A vue component library of some of the components available from https://patternlab.muenchen.space",
5
5
  "license": "MIT",
6
- "version": "1.13.0-beta.3",
6
+ "version": "1.13.0-beta.4",
7
7
  "private": false,
8
8
  "module": "./dist/muc-patternlab-vue.es.js",
9
9
  "types": "./dist/types/index.d.ts",
@@ -77,7 +77,7 @@
77
77
  "storybook": "^8.0.9",
78
78
  "typescript": "~5.5.0",
79
79
  "vite": "^5.0.11",
80
- "vite-plugin-dts": "^3.0.0",
80
+ "vite-plugin-dts": "^4.0.0",
81
81
  "vitest": "^2.0.0",
82
82
  "vue-tsc": "^2.0.0"
83
83
  }
@@ -1,5 +1,8 @@
1
1
  <template>
2
- <div class="m-form-group">
2
+ <div
3
+ class="m-form-group"
4
+ ref="selectComponentRef"
5
+ >
3
6
  <label class="m-label">
4
7
  {{ label }}
5
8
  </label>
@@ -10,9 +13,8 @@
10
13
  <input
11
14
  type="text"
12
15
  class="m-input m-combobox m-combobox--single"
13
- :value="outputTransformed"
14
- @click="toggleItemList"
15
- readonly
16
+ v-model="searchValue"
17
+ @click="openItemList"
16
18
  />
17
19
  <span
18
20
  class="m-input__trigger"
@@ -32,7 +34,7 @@
32
34
  @mouseleave="emptyActiveItem"
33
35
  >
34
36
  <li
35
- v-for="(option, index) in props.items"
37
+ v-for="(option, index) in displayedItems"
36
38
  :key="index"
37
39
  class="option"
38
40
  @mouseenter="activeItem = option"
@@ -41,6 +43,12 @@
41
43
  >
42
44
  {{ option }}
43
45
  </li>
46
+ <li
47
+ v-if="noItemsFound"
48
+ class="option"
49
+ >
50
+ {{ noItemFoundMessage }}
51
+ </li>
44
52
  </ul>
45
53
  </div>
46
54
  <p
@@ -53,7 +61,14 @@
53
61
  </template>
54
62
 
55
63
  <script setup lang="ts">
56
- import { computed, ref } from "vue";
64
+ import { computed, ref, watch } from "vue";
65
+
66
+ import useOnClickOutside from "../../composables/useOnClickOutside";
67
+
68
+ /**
69
+ * Ref ot the component
70
+ */
71
+ const selectComponentRef = ref();
57
72
 
58
73
  /**
59
74
  * Exposed selected value / values
@@ -72,6 +87,11 @@ const showItems = ref<boolean>(false);
72
87
  */
73
88
  const lastClickedItem = ref<string>();
74
89
 
90
+ /**
91
+ * If no items found after filtering
92
+ */
93
+ const noItemsFound = ref<boolean>(false);
94
+
75
95
  /**
76
96
  * Index of currently actively hovered item or selected item
77
97
  */
@@ -98,9 +118,15 @@ const props = withDefaults(
98
118
  * Allow multiple selectable items
99
119
  */
100
120
  multiple?: boolean;
121
+
122
+ /**
123
+ * Optional message shown no item is found after filtering
124
+ */
125
+ noItemFoundMessage?: string;
101
126
  }>(),
102
127
  {
103
128
  multiple: false,
129
+ noItemFoundMessage: "No items found.",
104
130
  }
105
131
  );
106
132
 
@@ -112,6 +138,23 @@ const toggleItemList = () => {
112
138
  activeItem.value = lastClickedItem.value;
113
139
  };
114
140
 
141
+ /**
142
+ * Opens the list of items and sets the previously selected item as active
143
+ */
144
+ const openItemList = () => {
145
+ showItems.value = true;
146
+ activeItem.value = lastClickedItem.value;
147
+ searchValue.value = "";
148
+ };
149
+
150
+ /**
151
+ * Closes the list after clicking outside the component
152
+ */
153
+ useOnClickOutside(selectComponentRef, () => {
154
+ showItems.value = false;
155
+ searchValue.value = outputTransformed.value;
156
+ });
157
+
115
158
  /**
116
159
  * Actions upon clicking an item
117
160
  * @param clickedValue clicked item value
@@ -158,6 +201,38 @@ const outputTransformed = computed(() => {
158
201
  return selectedValues.value.join(props.multiple ? ", " : " ");
159
202
  });
160
203
 
204
+ watch(outputTransformed, (newOutput) => {
205
+ searchValue.value = newOutput;
206
+ });
207
+
208
+ /**
209
+ * Current search value
210
+ */
211
+ const searchValue = ref<string>(outputTransformed.value);
212
+
213
+ /**
214
+ * Determines whether all or only the searched elements are displayed
215
+ */
216
+ const displayedItems = computed(() =>
217
+ searchValue.value == outputTransformed.value
218
+ ? props.items
219
+ : updateDisplayedItems(searchValue.value)
220
+ );
221
+
222
+ /**
223
+ * Filters the list of elements after entering the search string
224
+ * @param search the search string
225
+ * @return list of searched items
226
+ */
227
+ const updateDisplayedItems = (search: string) => {
228
+ noItemsFound.value = false;
229
+ const filteredItems = props.items.filter((item) => item.includes(search));
230
+ if (filteredItems.length === 0) {
231
+ noItemsFound.value = true;
232
+ }
233
+ return filteredItems;
234
+ };
235
+
161
236
  /**
162
237
  * Apply active class to hovered item
163
238
  * @param value of item
@@ -188,7 +263,7 @@ const displayOptions = computed(() =>
188
263
  * Switches between the selection modes according to multiple. Checkboxes are shown on the multiple select
189
264
  */
190
265
  const selectType = computed(() =>
191
- props.multiple
266
+ props.multiple && !noItemsFound.value
192
267
  ? "m-input-wrapper--multiselect multiselect"
193
268
  : "m-input-wrapper--select"
194
269
  );
@@ -0,0 +1,24 @@
1
+ import { onBeforeUnmount, onMounted } from "vue";
2
+
3
+ export default function useOnClickOutside(component: any, callback: any) {
4
+ if (!component) return;
5
+ const listener = (event: any) => {
6
+ if (
7
+ event.target !== component.value &&
8
+ event.composedPath().includes(component.value)
9
+ ) {
10
+ return;
11
+ }
12
+ if (typeof callback === "function") {
13
+ callback();
14
+ }
15
+ };
16
+ onMounted(() => {
17
+ window.addEventListener("click", listener);
18
+ });
19
+ onBeforeUnmount(() => {
20
+ window.removeEventListener("click", listener);
21
+ });
22
+
23
+ return { listener };
24
+ }