learningequality / kolibri-design-system

Kolibri Design System
https://design-system.learningequality.org
27 stars 65 forks source link

Proposal: Reconsider the interface of dropdown menus #634

Open AlexVelezLl opened 4 months ago

AlexVelezLl commented 4 months ago

Product

Kolibri, Studio.

Description

In #583 we discussed how KDS should expose dropdown menus and context menus. We currently have a KDropdownMenu component that can behave like a contextMenu if we pass it an isContextMenu prop (see the description of #583). However, this can be very tightly coupled if we want to extend dropdown functionality later to render more than just menus.

There are proposals to improve this, such as using composables const { isOpen, open, close, positionX, positionY } = useKDropdown(); to decouple the functionality, this could bring several benefits (see this comment), but research is needed to determine if it is technically feasible.

Another proposal suggests maintaining the Components interface and creating separate components: KDropdown, KMenu, KContextClick, while keeping KDropdownMenu as a reusable component for the most common use case. This approach would provide us with a more flexible interface while maintaining its simplicity, allowing us to use the base components in other contexts if needed.

We still need to investigate further into the possibilities of improving the dropdown menu implementation and determine what steps we can take in KDS.

MisRob commented 3 months ago

For the current interface see "Context menu" section in the KDropdownMenu and isContextMenu prop. The main advantages for this API are

and disadvantages are

One of the promising improvements resolving the disadvantages could be an API similar to (originally suggested by @bjester):

<template>
  <div>
    <KIconButton
        @click="open" 
    />
    <KMenu
        v-if="isOpen"
        :options="menuOptions" 
        :positionX="positionX" 
        :positionY="positionY" 
    />
  </div>
</template>
<script>
    import useKDropdown from './useKDropdown';

    export default {
        setup() {
            const { isOpen, open, close, positionX, positionY } = useKDropdown();
            const menuOptions = computed(() => [
                { text: 'Item 1', onClick: close },
                { text: 'Item 2', onClick: close },
                { text: 'Item 3', onClick: close },
            ]);
            return { isOpen, open, close, positionX, positionY, menuOptions };
        }
    }
</script>

For moving on, we need to