Proposal: rebuild Studio's drag-and-drop as Vue composables #539
Labels
category: supporting code
Implementation of the system
product: KDP
Relevant to a specific in KDP
product: Kolibri
Relevant to a specific issue in Kolibri
product: Studio
Relevant to a specific issue in Studio
TAG: design system
type: proposal
New feature or request
Summary
A drag-and-drop utility was built into Studio with its Vue refactor. It uses a combination of Vue component mixins, components, and Vuex to implement its behavior. We also have a drag-and-drop implementation in Kolibri, for sorting, which leverages the
Sortable
library.With the deprecation of IE 11, it's more than feasible to integrate a broadly supported utility / mini-library that uses native browser capabilities for drag-and-drop and sorting functionality. If the implementation of it in Studio is viewed as a prototype, various improvements can be made to make it a utility that would be useful for all of our products. In addition, there are clear touch points in the Studio prototype for developing accessibility features-- allowing its functionality to be driven not only by mouse or touch, but keyboards too.
The Studio prototype was built to accommodate for nested collection + document structures, such as those we have in channels, i.e. folders and resources. This accommodation allows for straightforward integration into the codebase where may define these types of structures in templates/components, and for collection specific features such as the ability to drag a whole collection of draggable items and drop zones such as first or last child of a collection.
The architecture is broken down into a few different structures:
Universes are given an ID / name and define DOM areas that contain Regions, Collections and Items. Collections and Items represent structures that can be dragged and dropped, but only within the same Universe (by name). For this reason, Collections and Items can only be implemented within the DOM area of a Universe. Multiple Universes can coexist on a page, without mixing the drag-and-drop functionality between them.
Regions define the actual drag-and-drop dropzone areas. There may be multiple Regions defined in a Universe. Regions can contain Collections or Items. Collections contain Items as children, where Items are the individual elemental items that can be dragged and dropped.
Collections and Items can be given a Handle through which drag-and-drop functionality can be invoked. A Handle could be the entire Item's element, or a descendant element serving as the handle. Collections aren't required to have Handles but can be defined similarly as Items.
Product
Kolibri, Studio, KDP, ++
Desired behavior
Using Studio's prototype, we could develop the following composables to replace the mixture of Vue components, mixins, and Vuex:
useDraggableUniverse(id: string, ...)
useDraggableRegion(id: string, ...)
useDraggableCollection(id: string, ...)
useDraggableItem(id: string, ...)
The above could connect directly to the component's element, or be used in combination with directives (there are some usages on Studio where the draggable components are used that aren't the immediate child of the component, meaning they would require refactoring into separate components to use the composables). Additionally, defining draggable handles could be another composable, or simply a directive.
The composables could manage state directly, instead of using Vuex.
A primary area for improvement over the existing functionality is the rendering of drop placeholders. The components and mixins modified the render function of components to modify the dom and inject dynamic drop placeholders when the user is dragging things. Perhaps one way to accomplish this is to use Shadow DOM to inject these placeholders without modifying Vue component rendering, but it needs some research and investigation.
Current behavior
Studio has a set of components which leverage the majority of their functionality from the draggable mixins. In order to manage state across many components, there's also a draggable Vuex module.
Kolibri has a set of components primarily geared for sorting implementations
Things the author wasn't pleased with in the initial Studio prototype:
(Optional) The Value Add
(Optional) Possible Tradeoffs
Sortable
but the complexities in providing the same featureset may be more work than implementing directly on top of native capabilitiesThe text was updated successfully, but these errors were encountered: