@magnit-ce/task-list
TypeScript icon, indicating that this package has built-in type declarations

0.0.10 • Public • Published

magnitce-task-list

A custom HTMLElement that provides features and events for managing custom <task-card> elements.

Package size: ~11kb minified, ~14kb verbose.

Quick Reference

<task-list>
    <task-card value="Dishes" is-finished="true"></task-card>
    <task-card value="Laundry" color="#FF00FF"></task-card>
    <task-card value="Sweeping"></task-card>
    <task-card value="Cocktail (margarita:)">
        <textarea slot="description">
    1 part  lime juice
    1 part  orange liqueur (grand marnier/cointreau/triple sec/etc)
    3 parts tequila

    1 twist of lime peel
    1 tbsp rimming salt

    1/2 shaker of ice
    1 serving glass "on the rocks" (a serving amount of ice)

    combine lime juice, orange liquer, and tequila in shaker
    shake well for 10-20 seconds
    strain liquid into serving glass
    express oils from lime peel and wet serving glass rim with them
    apply rimming salt to wetted rim of glass
        </textarea>
    </task-card>
<task-list>
<script type="module" src="/path/to/task-list[.min].js"></script>

Demos

https://catapart.github.io/magnitce-task-list/demo/

Support

  • Firefox
  • Chrome
  • Edge
  • Safari (Has not been tested; should be supported, based on custom element support)

Getting Started

  1. Install/Reference the library

Reference/Install

HTML Import (not required for vanilla js/ts; alternative to import statement)

<script type="module" src="/path/to/task-list[.min].js"></script>

npm

npm install @magnit-ce/task-list

Import

Vanilla js/ts

import "/path/to/task-list[.min].js"; // if you didn't reference from a <script>, reference with an import like this

import { TaskCardElement, TaskListElement } from "/path/to/task-list[.min].js";

npm

import "@magnit-ce/task-list"; // if you didn't reference from a <script>, reference with an import like this

import { TaskCardElement, TaskListElement } from "@magnit-ce/task-list";



Overview

The <task-list> element is a container element for <task-card> elements. It provides some basic task list features, like a customizeable header, an add button, the ability to show and hide its items, and a drag-and-drop feature. It also dispatches events when the list contents change.

Attributes

Attribute Effect
name Sets the title of the list. Displays as the value of the text input in the list header.
description Sets the title text of the list's header. Displays as "title text". Visible upon hovering a pointer over the header.
color A color to represent the list. Displays as the value of the color input in the list header. A categorization feature.
collapsed If true, hides the list items. If false, displays the list items.
drag-drop Enables drag-and-drop functionality for the list items.

Drag and Drop

The <task-list> element implements drag-and-drop features by using the native browser events dragstart, dragend, dragover, and drop. These events require non-trivial handlers, so the library expects <task-card> elements as its list-items. While custom item types can be used, it is not recommended and may not have all of the features.

dragAndDropQueryParent and parentScopeSelector

Facilitating moving items between lists means querying outside of the <task-list> elements, themselves.
The dragAndDropQueryParent is an element which has a querySelector() function run on it to determine valid items for the drag target's (possible) siblings. In effect, this dragAndDropQueryParent is any element that contains all of the <task-list> elements which items will be able to be dragged-and-dropped between. By default, the dragAndDropQueryParent is set to the document's <body> element. This means that any <task-list> in the document will be considered as a drop target.
To scope the query smaller, set the dragAndDropQueryParent to the first ancestor element that contains all of the <task-list> elements on your page.

The parentScopeSelector serves the same function as the dragAndDropQueryParent, but it is a string value that is used in the selector query. For reference, this is how the actual query looks:

this.dragAndDropQueryParent.querySelector(`${this.parentScopeSelector}${this.TASKCARD_TAG_NAME}[data-drag-id]`);

From that snippet, you can see that the two features can actually work together, if you need to dynamically narrow scope from a larger parent scope. But the simplification of all of this is that you can use either an element reference, or a css selector, or both, as a away to scope the <task-list> elements when dragging and dropping.

Customization

[TaskListElement].TASKCARD_TAG_NAME

The TASKCARD_TAG_NAME property of a <task-list> element determines the string that will be used to match "card" child elements. By default, this value is set to <task-card>, with the expectation of matching <task-card> elements.
To be clear: this is only referenced by the drag-and-drop functionality and can otherwise be ignored.

To use a custom list item, replace the TASKCARD_TAG_NAME with whatever the tag name is for the custom list item element.

Parts

The <task-list> element uses the part attribute to expose its shadow DOM content to the light DOM both for styling and selecting in javascript.

Part Name Description
header A <header> element containting inputs for the list's color and name, as well as a collapse button, and a title attribute set to the list's description property.
color-container A container for the list's color input. May be used, with custom styling, to display the color while hiding the color input, itself.
color An <input type="color"> element that displays the list's color property.
name An <input type="text"> element that displays the list's name property.
collapse-button A button that toggles the list's collapsed status.
collapse-icon An icon on the collapse button to indicate "collapse". Default is .
tasks The <ul> element containing all of the list's items.
add-button A button that dispatches the add event.
add-icon An icon on the add button to indicate "add". Default is +.
add-label The text on the add button to indicate "add". Default is Add Task.

findPart() and getPart()

In addition to being able to select an element from the <task-list> element's shadowRoot reference, this element provides a function for selecting one of its parts by using the findPart() function.

In this example, the same part is selected with the default shadowRoot reference, and by using the findPart() function:

const  = document.querySelector('header');
findPart('').addEventListener('input', (event) =>
{
    // queries the shadowRoot for an element with a part attribute of ""
});
shadowRoot.querySelector('[part="header"]').addEventListener('input', (event) =>
{
    // queries the shadowRoot for an element with a part attribute of ""
});

(note: these two calls do exactly the same thing)

If one of this element's parts are going to be referenced frequently, the <task-list> element's getPart() function can be used instead.

With getPart(), the element will be cached in RAM for immediate access witout having to perform a DOM query on the shadowRoot.

const  = document.querySelector('');
taskCard.getPart(header'').addEventListener('input', (event) =>
{
    // gets cached element and, if null: queries the shadowRoot for an element with a part attribute of ""
});
taskCard.shadowRoot.querySelector('[part="header"]').addEventListener('input', (event) =>
{
    // queries the shadowRoot for an element with a part attribute of ""
});

(note: these two calls do two different things)

For event-based or initialization code, findPart() should be fine for performance. But if the <task-list> element is going to be updated multiple times in a row, the getPart() function will provide a smoother experience.

Events

change

Detail

{ 
  target: HTMLElement,
  order?: number,
  previousOrder?: number,
}

Description

Fires when either the list's name or color changes, and whenever a list item is dropped in the same list it was dragged from.

  • order:
    provides an integer of the item's index in the <task-list> element.
  • previousOrder:
    provides an integer of the item's index in the <task-list> element before it was moved to its current position.
  • target:
    provides the <task-list> element or list item that invoked the change.

add

Detail

{ 
  order: number
}

Description

Fires when the "Add" button is clicked.

  • order:
    provides an integer for assigning to a new task.

added

Detail

{ 
  target: HTMLElement,
  order: number,
}

Description

Fires when a new item is added to a list.

  • order:
    provides an integer of the item's index in the <task-list> element the item was added to.
  • target:
    provides the <task-list> element that the item was added to.

removed

Detail

{ 
  target: HTMLElement,
  order: number
}

Description

Fires when an item is removed from a list.

  • order:
    provides an integer of the item's index in the <task-list> element the item was removed from.
  • target:
    provides the <task-list> element that the item was removed from.

nested

Detail

{ 
  target: TaskListElement,
}

Description

Fires when a new <task-list> element is added to a parent <task-list> element.

  • target:
    provides the <task-list> element that was nested within the parent.

collapse

Detail

undefined

Description

Fires when the <task-list> element is collapsed and uncollapsed.

Slots

The <task-list> element allows customization by using slots to inject custom html content into its shadowRoot.

The <task-list> element exposes the following slots:

Slot Name Description Default
header A heading that describes and distinguishes the list's items from other elements on the page. [HTMLHeaderElement]
[Default] Slot that holds all of the list items.(note: this slot has no name; all children of the <task-list> element that do not specificy a slot attribute value will be placed in this default slot.) [empty]
add-button A button that is used to invoke the add event, and indicate that the list needs to have a new item injected. [HTMLButtonElement]
footer An area to include additional content or data about the list. Can also be used for nested <task-list> elements. [empty]

Styling

The <task-list> element itself, and its items, can all be styled with CSS, normally. Each of the elements in the <task-list> element's shadowRoot can be selected for styling, directly, by using the ::part() selector.

In this example, the header part is being selected for styling:

task-list::part(header)
{
    /* styling */
}

For a list of all part names, see the parts section.

<task-card> and <task-board> elements

The <task-list> element is designed as a parent to the <task-card> element and a child for the <task-board> element.

Neither the <task-board> or the <task-card> elements are required for the <task-list> element to function, but design decisions were made around how these three elements are expected to work together.

For developing custom implementations, the <task-board> demo page gives examples of the three elements used as expected.

License

This library is in the public domain. You do not need permission, nor do you need to provide attribution, in order to use, modify, reproduce, publish, or sell it or any works using it or derived from it.

Dependents (0)

Package Sidebar

Install

npm i @magnit-ce/task-list

Weekly Downloads

3

Version

0.0.10

License

CC0-1.0

Unpacked Size

45.7 kB

Total Files

7

Last publish

Collaborators

  • catapart