From 53fca4f3408fd4b1d7e8167b08e9061abef5ccaa Mon Sep 17 00:00:00 2001 From: Samuel Lorch Date: Tue, 11 Apr 2023 19:43:09 +0200 Subject: [PATCH] Feat custom multiselect (#12) * WIP Multiselect * Reworked Multiselect into multiple Components - Also finished feature implementation --------- Co-authored-by: adroslice --- .../src/components/inputs/DropdownInput.vue | 208 ++++++++++++++++++ client/src/components/inputs/MultiSelect.vue | 38 ++++ client/src/components/inputs/SingleSelect.vue | 38 ++++ client/src/global-styles/components.css | 8 +- client/src/global-styles/transitions.css | 7 + client/src/pages/index.vue | 3 +- client/src/util.ts | 16 ++ 7 files changed, 315 insertions(+), 3 deletions(-) create mode 100644 client/src/components/inputs/DropdownInput.vue create mode 100644 client/src/components/inputs/MultiSelect.vue create mode 100644 client/src/components/inputs/SingleSelect.vue create mode 100644 client/src/util.ts diff --git a/client/src/components/inputs/DropdownInput.vue b/client/src/components/inputs/DropdownInput.vue new file mode 100644 index 0000000..36b5972 --- /dev/null +++ b/client/src/components/inputs/DropdownInput.vue @@ -0,0 +1,208 @@ + + + + + + \ No newline at end of file diff --git a/client/src/components/inputs/MultiSelect.vue b/client/src/components/inputs/MultiSelect.vue new file mode 100644 index 0000000..a7f6327 --- /dev/null +++ b/client/src/components/inputs/MultiSelect.vue @@ -0,0 +1,38 @@ + + + diff --git a/client/src/components/inputs/SingleSelect.vue b/client/src/components/inputs/SingleSelect.vue new file mode 100644 index 0000000..74b375f --- /dev/null +++ b/client/src/components/inputs/SingleSelect.vue @@ -0,0 +1,38 @@ + + + diff --git a/client/src/global-styles/components.css b/client/src/global-styles/components.css index 1ba83ee..a67580b 100644 --- a/client/src/global-styles/components.css +++ b/client/src/global-styles/components.css @@ -20,6 +20,11 @@ button, .button { min-height: 1.5rem; } +input { + height: 1.5rem; + padding: 0.25rem; +} + form { display: grid; grid-template-columns: auto 1fr; @@ -67,7 +72,8 @@ button, .button { .nav-body .button { background-color: var(--cl-bg); } -.button:hover, button:hover { +.button:hover, button:hover, +.button:focus, button:focus { background-color: var(--cl-bg-hl); } diff --git a/client/src/global-styles/transitions.css b/client/src/global-styles/transitions.css index 87dc1bc..dc53338 100644 --- a/client/src/global-styles/transitions.css +++ b/client/src/global-styles/transitions.css @@ -3,4 +3,11 @@ } .fade-enter-from, .fade-leave-to { opacity: 0; +} + +.fade-fast-enter-active, .fade-fast-leave-active { + transition: all 0.1s ease-out !important; +} +.fade-fast-enter-from, .fade-fast-leave-to { + opacity: 0; } \ No newline at end of file diff --git a/client/src/pages/index.vue b/client/src/pages/index.vue index 429f8f4..2bc6b18 100644 --- a/client/src/pages/index.vue +++ b/client/src/pages/index.vue @@ -23,7 +23,7 @@ onMounted(async() => { diff --git a/client/src/util.ts b/client/src/util.ts new file mode 100644 index 0000000..2d8b29e --- /dev/null +++ b/client/src/util.ts @@ -0,0 +1,16 @@ +// Performs a type-agnostic deep comparison of two values by process of elimination. This mainly covers the use cases of Primitives, Objects and Arrays, but not certain builtins like Dates. +export function equals(a: any, b: any): boolean { + if (typeof a !== typeof b) return false; // Different types can't be equal, except number and bigint but who cares. Null and undefined are considered different. + if (typeof a !== 'object') return a === b; // A simple comparison suffices for non-objects + if (isNullish(a) !== isNullish(b)) return false; // A common use case is checking for something to exist vs. not, so it's covered explicitly here + if (isNullish(a) && isNullish(b)) return true; + if (a instanceof Array && !(b instanceof Array)) return false; // Could be generalized with Object.getPrototypeOf, but I think it's preferable to have "pure" and regular objects match (Look up Object.create(null)) + if (a?.length !== b?.length) return false; // Another not technically necessary but common point of comparison. + for (const key of new Set(Object.keys(a).concat(Object.keys(b)))) // All there's left is to deep-compare what are clearly objects. The keys of both need to be merged to prevent an extra key on one side being ignored. + if (!equals(a[key], b[key])) return false; + return true; // Only once all points of inequality are rules out can we say for certain that the two values are equal. +} + +export function isNullish(value: any) { + return !!(value === null || value === undefined); +} \ No newline at end of file