Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
FlorianWendelborn committed Nov 24, 2021
1 parent b894056 commit ecd4dc9
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,12 @@
</template>
</KtField>
</div>

<div ref="tippyContentRef" class="kt-field-select--single-remote__tippy">
<IconTextItem
v-for="(option, index) in modifiedOptions"
:key="index"
:isDisabled="option.isDisabled"
:isSelected="option.isSelected"
:label="option.label"
@click.stop="() => selectOption(option)"
<div ref="tippyContentRef">
<FieldSelectOptions
:isDisabled="field.isDisabled"
:options="options"
:value="field.currentValue === null ? [] : [field.currentValue]"
@input="(e) => selectOption(e.length === 0 ? null : e[0])"
/>
</div>
</div>
Expand All @@ -51,10 +48,9 @@ import { KtField } from '../kotti-field'
import { KOTTI_FIELD_PROPS } from '../kotti-field/constants'
import { useField } from '../kotti-field/hooks'
import { useForceUpdate } from '../kotti-field/hooks'
import { useTranslationNamespace } from '../kotti-i18n/hooks'
import IconTextItem from '../kotti-popover/components/IconTextItem.vue'
import ActionIconNext from './components/ActionIconNext.vue'
import FieldSelectOptions from './components/Options.vue'
import {
KOTTI_FIELD_REMOTE_SINGLE_SELECT_PROPS,
KOTTI_FIELD_REMOTE_SELECT_SUPPORTS,
Expand All @@ -63,38 +59,33 @@ import { KottiFieldSingleSelectRemote } from './types'
import { sameWidth } from './utils/tippy-utils'
const ARROW_HEIGHT = 7
const NO_DATA = Symbol('NO_DATA')
const UPDATE_QUERY = 'update:query'
const isTippyOrInTippy = (element: Element, tippy: Element | null): boolean => {
if (tippy === null) return false
let currentElement = element
return true // FIXME
while (currentElement) {
if (currentElement.isSameNode(tippy)) return true
currentElement = currentElement?.parentElement
}
// let currentElement = element
return false
// while (currentElement) {
// if (currentElement.isSameNode(tippy)) return true
// currentElement = currentElement?.parentElement
// }
// return false
}
const isEqualValue = (
currentValue: KottiFieldSingleSelectRemote.Value,
newValue: KottiFieldSingleSelectRemote.Value,
) => currentValue === newValue
type ModifiedOptions = Array<
KottiFieldSingleSelectRemote.Props['options'][number] & {
isSelected: boolean
}
>
export default defineComponent({
name: 'KtFieldSingleSelectRemote',
components: {
ActionIconNext,
IconTextItem,
FieldSelectOptions,
KtField,
},
props: {
Expand All @@ -113,7 +104,6 @@ export default defineComponent({
props,
supports: KOTTI_FIELD_REMOTE_SELECT_SUPPORTS,
})
const translations = useTranslationNamespace('KtFieldSelects')
const tippyTriggerRef = ref<Element | null>(null)
const tippyContentRef = ref<Element | null>(null)
Expand Down Expand Up @@ -209,33 +199,15 @@ export default defineComponent({
})(),
})),
isDropdownOpen,
modifiedOptions: computed<ModifiedOptions>(() =>
props.options.length > 0
? props.options.map((option) => ({
...option,
isDisabled: (field.isDisabled || option.isDisabled) ?? false,
isSelected: isEqualValue(field.currentValue, option.value),
}))
: [
{
label: translations.value.noDataText,
isDisabled: true,
isSelected: false,
value: NO_DATA,
},
],
),
tippyTriggerRef,
tippyContentRef,
selectOption: (
option: KottiFieldSingleSelectRemote.Props['options'][number],
value: KottiFieldSingleSelectRemote.Props['options'][number]['value'],
) => {
// ignore disabled options
if (option.isDisabled) return
console.debug('setting value', value, field.currentValue)
// optimization: no need to change the value if it’s already set
if (!isEqualValue(field.currentValue, option.value))
field.setValue(option.value)
if (!isEqualValue(field.currentValue, value)) field.setValue(value)
// close the tippy instance whenever a selection is made
setIsDropdownOpen(false)
Expand Down Expand Up @@ -267,16 +239,5 @@ export default defineComponent({
line-height: 1.6;
border: 0;
}
&__tippy {
max-height: 40vh;
/*
undo padding from theme,
alternatively fork theme and remove the left/right padding
*/
margin-right: -9px;
margin-left: -9px;
overflow-y: auto;
}
}
</style>
95 changes: 95 additions & 0 deletions packages/kotti-ui/source/kotti-field-select/components/Options.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<template>
<div class="kt-field-select__options">
<IconTextItem
v-for="(option, index) in modifiedOptions"
:key="index"
:isDisabled="option.isDisabled"
:isSelected="option.isSelected"
:label="option.label"
@click.stop="() => selectOption(option)"
/>
</div>
</template>

<script lang="ts">
import { computed, defineComponent } from '@vue/composition-api'
import { z } from 'zod'
import { useTranslationNamespace } from '../../kotti-i18n/hooks'
import IconTextItem from '../../kotti-popover/components/IconTextItem.vue'
import { makeProps } from '../../make-props'
// type ModifiedOption =
// KottiFieldSingleSelectRemote.Props['options'][number] & {
// isSelected: boolean
// }
const NO_DATA = Symbol('NO_DATA')
const propsSchema = z.object({
isDisabled: z.boolean().default(false),
isMultiple: z.boolean().default(false),
options: z.array(z.any()), // FIXME
value: z.array(z.unknown()), // FIXME
})
export default defineComponent<z.output<typeof propsSchema>>({
name: 'FieldSelectOptions',
components: {
IconTextItem,
},
props: makeProps(propsSchema),
setup(props, { emit }) {
const translations = useTranslationNamespace('KtFieldSelects')
return {
modifiedOptions: computed(() =>
props.options.length > 0
? props.options.map((option) => ({
...option,
isDisabled: (props.isDisabled || option.isDisabled) ?? false,
isSelected: props.value.includes(option.value),
}))
: [
{
label: translations.value.noDataText,
isDisabled: true,
isSelected: false,
value: NO_DATA,
},
],
),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
selectOption: (option: any /* FIXME */) => {
if (option.isDisabled) return
if (props.isMultiple)
emit(
'input',
props.value.includes(option.value)
? props.value.filter((v) => v !== option.value)
: [...props.value, option.value],
)
else
emit(
'input',
props.value.includes(option.value) ? [] : [option.value],
)
},
}
},
})
</script>

<style lang="scss" scoped>
.kt-field-select__options {
max-height: 40vh;
/*
undo padding from theme,
alternatively fork theme and remove the left/right padding
*/
margin-right: -9px;
margin-left: -9px;
overflow-y: auto;
}
</style>
1 change: 1 addition & 0 deletions packages/kotti-ui/source/kotti-field-select/todo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
option and field level support for data test

0 comments on commit ecd4dc9

Please sign in to comment.