From 2f20a834d06d875bcedd894666e95dd055088305 Mon Sep 17 00:00:00 2001
From: Carol Soliman <17387510+carsoli@users.noreply.github.com>
Date: Fri, 20 May 2022 23:06:43 +0200
Subject: [PATCH] WIP AAAAAAAAAA
---
.../components/GenericSelectField.vue | 152 ++++++++----------
.../hooks/use-select-tippy.ts | 7 +-
.../source/kotti-field-select/todo.md | 22 +--
3 files changed, 77 insertions(+), 104 deletions(-)
diff --git a/packages/kotti-ui/source/kotti-field-select/components/GenericSelectField.vue b/packages/kotti-ui/source/kotti-field-select/components/GenericSelectField.vue
index c988c13d45..c3af8a0eba 100644
--- a/packages/kotti-ui/source/kotti-field-select/components/GenericSelectField.vue
+++ b/packages/kotti-ui/source/kotti-field-select/components/GenericSelectField.vue
@@ -8,44 +8,27 @@
>
import { Yoco } from '@3yourmind/yoco'
import { computed, defineComponent, ref, watch } from '@vue/composition-api'
-import Vue from 'vue'
import { z } from 'zod'
import { KtField } from '../../kotti-field'
@@ -164,9 +146,11 @@ export default defineComponent<
const { forceUpdateKey, forceUpdate } = useForceUpdate()
- watch(isDropdownMounted, (newValue) => {
+ watch(isDropdownMounted, (isMounted) => {
+ if (isMounted) return
+
if (props.isRemote) {
- if (!newValue && props.query !== null) emit(UPDATE_QUERY, null)
+ if (props.query !== null) emit(UPDATE_QUERY, null)
} else localQuery.value = null
})
@@ -191,7 +175,7 @@ export default defineComponent<
forceUpdateKey: forceUpdateKey.value,
placeholder: props.placeholder ?? undefined,
size: 1,
- style: !isDropdownOpen.value ? 'flex: 1' : undefined,
+ style: 'flex: 1',
type: 'text',
value: (() => {
if (isDropdownOpen.value)
@@ -213,6 +197,7 @@ export default defineComponent<
onOptionsInput: (value: MultiValue) => {
field.setValue(props.isMultiple ? value : value?.[0] ?? null)
+ inputRef.value?.focus()
// single select: close the tippy instance whenever a selection is made.
// This (watcher on isDropdownMounted) also intentionally resets the query
// so that the api-call (for example) can already trigger and load the non-filtered options
@@ -282,84 +267,75 @@ export default defineComponent<
margin-bottom: 0.8rem;
}
- &__input-and-tags {
- display: flex;
- align-items: center;
-
- > *:not(:first-child) {
- margin-left: var(--unit-1);
- }
- }
-
&__query {
display: flex;
+ flex: 1;
width: 100%;
padding: 0;
margin: 0;
line-height: 1.6;
border: 0;
- flex: 1;
}
- &__tags {
- $vertical-tag-gap: 2px;
- $horizontal-tag-gap: 4px;
- $tag-padding: 0.4em;
- $tag-border: 1px;
+ $vertical-tag-gap: 2px;
+ $horizontal-tag-gap: 4px;
+ $tag-padding: 0.4em;
+ $tag-border: 1px;
+ &__input-and-tags {
display: flex;
flex-wrap: wrap;
// HACK: use negative margins to align multi-line grids of tags
margin: #{-$vertical-tag-gap + 4px} #{-$horizontal-tag-gap};
+ }
+
+ &__tag {
+ display: flex;
+ align-items: center;
+ padding: $tag-padding;
+ margin: $vertical-tag-gap $horizontal-tag-gap;
+
+ font-size: 0.875em;
+
+ color: var(--text-02);
+ text-transform: capitalize;
+ white-space: nowrap;
+ background-color: var(--interactive-02);
+ border: $tag-border solid var(--ui-02);
+ border-radius: var(--field-border-radius);
+
+ &-icon {
+ $size: 1.25em;
- &__tag {
display: flex;
align-items: center;
- padding: $tag-padding;
- margin: $vertical-tag-gap $horizontal-tag-gap;
-
- font-size: 0.875em;
-
- color: var(--text-02);
- text-transform: capitalize;
- white-space: nowrap;
- background-color: var(--interactive-02);
- border: $tag-border solid var(--ui-02);
- border-radius: var(--field-border-radius);
-
- &-icon {
- $size: 1.25em;
-
- display: flex;
- align-items: center;
- justify-content: center;
- width: $size;
- height: $size;
- margin-left: 4px;
- cursor: pointer;
-
- background-color: var(--ui-02);
- border-radius: 50%;
-
- // clipping also affects the clickable area
- @supports (clip-path: circle(#{$size / 2} at center)) {
- clip-path: circle(#{$size / 2} at center);
- border-radius: 0;
- }
-
- &:hover {
- background-color: var(--interactive-02-hover);
- }
+ justify-content: center;
+ width: $size;
+ height: $size;
+ margin-left: 4px;
+ cursor: pointer;
+
+ background-color: var(--ui-02);
+ border-radius: 50%;
+
+ // clipping also affects the clickable area
+ @supports (clip-path: circle(#{$size / 2} at center)) {
+ clip-path: circle(#{$size / 2} at center);
+ border-radius: 0;
+ }
+
+ &:hover {
+ background-color: var(--interactive-02-hover);
}
}
}
&__wrapper {
display: flex;
+ min-width: 30%; /* TODO: necessary? */
padding: 0;
margin: 0;
- min-width: 30%; /* TODO: necessary? */
line-height: 1.6;
border: 0;
}
diff --git a/packages/kotti-ui/source/kotti-field-select/hooks/use-select-tippy.ts b/packages/kotti-ui/source/kotti-field-select/hooks/use-select-tippy.ts
index ccb632dcc5..583432f8f3 100644
--- a/packages/kotti-ui/source/kotti-field-select/hooks/use-select-tippy.ts
+++ b/packages/kotti-ui/source/kotti-field-select/hooks/use-select-tippy.ts
@@ -24,10 +24,13 @@ export const useSelectTippy = () => {
arrow: roundArrow,
content: tippyContentRef.value,
// hides the tippy if we click-away from the tippy
- hideOnClick: true,
+ hideOnClick: false,
interactive: true,
maxWidth: 'none',
offset: [0, ARROW_HEIGHT],
+ onClickOutside: () => {
+ setIsDropdownOpen(false)
+ },
onShow: () => {
// More correct here, don't move to `onShown()`
isDropdownMounted.value = true
@@ -45,7 +48,7 @@ export const useSelectTippy = () => {
modifiers: [sameWidth],
},
theme: 'light-border',
- trigger: 'click',
+ trigger: 'click focusin',
})),
)
diff --git a/packages/kotti-ui/source/kotti-field-select/todo.md b/packages/kotti-ui/source/kotti-field-select/todo.md
index db616d7726..457512287f 100644
--- a/packages/kotti-ui/source/kotti-field-select/todo.md
+++ b/packages/kotti-ui/source/kotti-field-select/todo.md
@@ -1,18 +1,12 @@
-- [x] `:helpTextSlot="$slots.helpText"`
-- [ ] clicking an option counts as blur haha
-
-- [ ] FIX: if field is multi and not empty and not interacting, hide input
+## TODOs
+- [x] `:helpTextSlot="$slots.helpText"`
+- [x] double clicking should keep it open
+- [x] selecting an option needs to refocus the field
+- [x] if field is multi and not empty and not interacting, hide input (not needed anymore)
- [ ] restore arrow-key navigation for options (isHovered)
- [ ] (optional) add slot support for options
- [ ] check that `enter` from `input` doesn't trigger the submit (of a form it's used within)
-
-## 2022-04-20
-
-- Honestly, the most realistic and sustainable solution is to either move the search query inside the dropdown or to not show the tags
-
-## V2
-
-1. Clickoutside
-2. support `tabIndex`
-3. check if data-test is implemented sufficiently
+- [x] Clickoutside (done with tippy callbacks)
+- [ ] support `tabIndex`
+- [ ] check if data-test is implemented sufficiently