svelte-dnd-action
Advanced tools
Comparing version 0.6.3 to 0.6.4
@@ -30,3 +30,3 @@ { | ||
"description": "*An awesome drag and drop library for Svelte 3 (not using the browser's built-in dnd, thanks god): Rich animations, nested containers, touch support and more *", | ||
"version": "0.6.3", | ||
"version": "0.6.4", | ||
"repository": { | ||
@@ -33,0 +33,0 @@ "type": "git", |
@@ -100,3 +100,4 @@ # SVELTE DND ACTION [![Known Vulnerabilities](https://snyk.io/test/github/isaacHagoel/svelte-dnd-action/badge.svg?targetFile=package.json)](https://snyk.io/test/github/isaacHagoel/svelte-dnd-action?targetFile=package.json) | ||
| `dropTargetStyle` | Object<String> | No | `{outline: 'rgba(255, 255, 102, 0.7) solid 2px'}` | An object of styles to apply to the dnd-zone when items can be dragged in to it. Note: the styles override any inline styles applied to the dnd-zone. When the styles are removed, any original inline styles will be lost | | ||
| `transformDraggedElement` | Function | No | `() => {}` | A function that is invoked when the draggable element enters the dnd-zone or hover overs a new index in the current dnd-zone. <br />Signature:<br />function(element, data, index) {}<br />**element**: The dragged element. <br />**data**: The data of the item from the items array.<br />**index**: The index the dragged element will become in the new dnd-zone.<br /><br />This allows you to override properties on the dragged element, such as innerHTML to change how it displays. | | ||
| `transformDraggedElement` | Function | No | `() => {}` | A function that is invoked when the draggable element enters the dnd-zone or hover overs a new index in the current dnd-zone. <br />Signature:<br />function(element, data, index) {}<br />**element**: The dragged element. <br />**data**: The data of the item from the items array.<br />**index**: The index the dragged element will become in the new dnd-zone.<br /><br />This allows you to override properties on the dragged element, such as innerHTML to change how it displays. | | ||
| `autoAriaDisabled` | Boolean | No | `false` | Setting it to true will disable all the automatically added aria attributes and aria alerts (for example when the user starts/ stops dragging using the keyboard).<br /> **Use it only if you intend to implement your own custom instructions, roles and alerts.** In such a case, you might find the exported function `alertToScreenReader(string)` useful. | | ||
@@ -136,2 +137,3 @@ ##### Output: | ||
*Note*: in general you probably want to use semantic-html (ex: `ol` and `li` elements rather than `section` and `div`) but the library is screen readers friendly regardless (or at least that's the goal :)). | ||
If you want to implement your own custom screen-reader alerts, roles and instructions, you can use the `autoAriaDisabled` options and wire everything up yourself using markup and the `consider` and `finalize` handlers (example coming soon). | ||
@@ -138,0 +140,0 @@ ##### Keyboard support |
import {dndzone as pointerDndZone} from "./pointerAction"; | ||
import {dndzone as keyboardDndZone} from "./keyboardAction"; | ||
import {ITEM_ID_KEY} from "./constants"; | ||
import {toString} from "./helpers/util"; | ||
@@ -23,2 +25,3 @@ /** | ||
export function dndzone(node, options) { | ||
validateOptions(options); | ||
const pointerZone = pointerDndZone(node, options); | ||
@@ -28,2 +31,3 @@ const keyboardZone = keyboardDndZone(node, options); | ||
update: newOptions => { | ||
validateOptions(newOptions); | ||
pointerZone.update(newOptions); | ||
@@ -37,2 +41,26 @@ keyboardZone.update(newOptions); | ||
} | ||
} | ||
function validateOptions(options) { | ||
const { | ||
items, | ||
flipDurationMs, | ||
type, | ||
dragDisabled, | ||
dropFromOthersDisabled, | ||
dropTargetStyle, | ||
transformDraggedElement, | ||
autoAriaDisabled, | ||
...rest | ||
} = options; | ||
if (Object.keys(rest).length > 0) { | ||
console.warn(`dndzone will ignore unknown options`, rest); | ||
} | ||
if (!items) { | ||
throw new Error("no 'items' key provided to dndzone"); | ||
} | ||
const itemWithMissingId = items.find(item => !item.hasOwnProperty(ITEM_ID_KEY)); | ||
if (itemWithMissingId) { | ||
throw new Error(`missing '${ITEM_ID_KEY}' property for item ${toString(itemWithMissingId)}`); | ||
} | ||
} |
export { dndzone } from './action.js'; | ||
export {TRIGGERS, SOURCES, SHADOW_ITEM_MARKER_PROPERTY_NAME, overrideItemIdKeyNameBeforeInitialisingDndZones} from './constants'; | ||
export { alertToScreenReader } from './helpers/aria'; | ||
export { TRIGGERS, SOURCES, SHADOW_ITEM_MARKER_PROPERTY_NAME, overrideItemIdKeyNameBeforeInitialisingDndZones } from './constants'; |
import {decrementActiveDropZoneCount, incrementActiveDropZoneCount, ITEM_ID_KEY, SOURCES, TRIGGERS} from "./constants"; | ||
import {styleActiveDropZones, styleInactiveDropZones} from "./helpers/styler"; | ||
import {dispatchConsiderEvent, dispatchFinalizeEvent} from "./helpers/dispatcher"; | ||
import {createInstructions, tellUser} from "./helpers/instructions"; | ||
import {createInstructions, alertToScreenReader} from "./helpers/aria"; | ||
import {toString} from "./helpers/util"; | ||
@@ -61,9 +61,13 @@ | ||
const itemToMove = originItems.splice(originIdx, 1)[0]; | ||
const {items:targetItems} = dzToConfig.get(e.currentTarget); | ||
const {items:targetItems, autoAriaDisabled} = dzToConfig.get(e.currentTarget); | ||
if (e.currentTarget.getBoundingClientRect().top < focusedDz.getBoundingClientRect().top || e.currentTarget.getBoundingClientRect().left < focusedDz.getBoundingClientRect().left) { | ||
targetItems.push(itemToMove); | ||
tellUser(`moved item ${focusedItemLabel} to the end of the list ${focusedDzLabel}`); | ||
if (!autoAriaDisabled) { | ||
alertToScreenReader(`Moved item ${focusedItemLabel} to the end of the list ${focusedDzLabel}`); | ||
} | ||
} else { | ||
targetItems.unshift(itemToMove); | ||
tellUser(`moved item ${focusedItemLabel} to the beginning of the list ${focusedDzLabel}`); | ||
if (!autoAriaDisabled) { | ||
alertToScreenReader(`Moved item ${focusedItemLabel} to the beginning of the list ${focusedDzLabel}`); | ||
} | ||
} | ||
@@ -103,3 +107,5 @@ const dzFrom = focusedDz; | ||
console.debug("drop"); | ||
tellUser(`stopped dragging item ${focusedItemLabel}`); | ||
if (!dzToConfig.get(focusedDz).autoAriaDisabled) { | ||
alertToScreenReader(`Stopped dragging item ${focusedItemLabel}`); | ||
} | ||
if (allDragTargets.has(document.activeElement)) { | ||
@@ -125,3 +131,4 @@ document.activeElement.blur(); | ||
dropFromOthersDisabled: false, | ||
dropTargetStyle: DEFAULT_DROP_TARGET_STYLE | ||
dropTargetStyle: DEFAULT_DROP_TARGET_STYLE, | ||
autoAriaDisabled: false | ||
}; | ||
@@ -160,3 +167,5 @@ | ||
if (idx < children.length - 1) { | ||
tellUser(`moved item ${focusedItemLabel} to position ${idx + 2} in the list ${focusedDzLabel}`); | ||
if (!config.autoAriaDisabled) { | ||
alertToScreenReader(`Moved item ${focusedItemLabel} to position ${idx + 2} in the list ${focusedDzLabel}`); | ||
} | ||
swap(items, idx, idx + 1); | ||
@@ -177,3 +186,5 @@ dispatchFinalizeEvent(node, items, {trigger: TRIGGERS.DROPPED_INTO_ZONE, id: focusedItemId, source: SOURCES.KEYBOARD}); | ||
if (idx > 0) { | ||
tellUser(`moved item ${focusedItemLabel} to position ${idx} in the list ${focusedDzLabel}`); | ||
if (!config.autoAriaDisabled) { | ||
alertToScreenReader(`Moved item ${focusedItemLabel} to position ${idx} in the list ${focusedDzLabel}`); | ||
} | ||
swap(items, idx, idx - 1); | ||
@@ -188,3 +199,5 @@ dispatchFinalizeEvent(node, items, {trigger: TRIGGERS.DROPPED_INTO_ZONE, id: focusedItemId, source: SOURCES.KEYBOARD}); | ||
console.debug("drag start"); | ||
tellUser(`Started dragging item ${focusedItemLabel}. Use the arrow keys to move it within its list ${focusedDzLabel}, or tab to another list in order to move it into it`); | ||
if (!config.autoAriaDisabled) { | ||
alertToScreenReader(`Started dragging item ${focusedItemLabel}. Use the arrow keys to move it within its list ${focusedDzLabel}, or tab to another list in order to move the item into it`); | ||
} | ||
setCurrentFocusedItem(e.currentTarget); | ||
@@ -223,3 +236,4 @@ focusedDz = node; | ||
dropFromOthersDisabled = false, | ||
dropTargetStyle = DEFAULT_DROP_TARGET_STYLE | ||
dropTargetStyle = DEFAULT_DROP_TARGET_STYLE, | ||
autoAriaDisabled = false | ||
}) { | ||
@@ -230,7 +244,8 @@ config.items = [...items]; | ||
config.dropTargetStyle = dropTargetStyle; | ||
node.setAttribute("aria-disabled", dragDisabled); | ||
node.setAttribute("role", "list"); | ||
node.setAttribute("aria-describedby", dragDisabled? INSTRUCTION_IDs.DND_ZONE_DRAG_DISABLED : INSTRUCTION_IDs.DND_ZONE_ACTIVE); | ||
//// | ||
config.autoAriaDisabled = autoAriaDisabled; | ||
if (!autoAriaDisabled) { | ||
node.setAttribute("aria-disabled", dragDisabled); | ||
node.setAttribute("role", "list"); | ||
node.setAttribute("aria-describedby", dragDisabled? INSTRUCTION_IDs.DND_ZONE_DRAG_DISABLED : INSTRUCTION_IDs.DND_ZONE_ACTIVE); | ||
} | ||
node.tabIndex = isDragging && (node === focusedDz || config.dropFromOthersDisabled || (focusedDz && config.type!==dzToConfig.get(focusedDz).type)) ? -1 : 0; | ||
@@ -250,3 +265,5 @@ node.addEventListener('focus', handleZoneFocus); | ||
draggableEl.tabIndex = (isDragging) ? -1 : 0; | ||
draggableEl.setAttribute("role", "listitem"); | ||
if (!autoAriaDisabled) { | ||
draggableEl.setAttribute("role", "listitem"); | ||
} | ||
draggableEl.removeEventListener("keyDown", elToKeyDownListeners.get(draggableEl)); | ||
@@ -253,0 +270,0 @@ draggableEl.removeEventListener("click", elToFocusListeners.get(draggableEl)); |
@@ -339,14 +339,3 @@ import { | ||
transformDraggedElement = () => {}, | ||
...rest | ||
}) { | ||
if (Object.keys(rest).length > 0) { | ||
console.warn(`dndzone will ignore unknown options`, rest); | ||
} | ||
if (!items) { | ||
throw new Error("no 'items' key provided to dndzone"); | ||
} | ||
const itemWithMissingId = items.find(item => !item.hasOwnProperty(ITEM_ID_KEY)); | ||
if (itemWithMissingId) { | ||
throw new Error(`missing '${ITEM_ID_KEY}' property for item ${toString(itemWithMissingId)}`); | ||
} | ||
config.dropAnimationDurationMs = dropAnimationDurationMs; | ||
@@ -353,0 +342,0 @@ if (config.type && newType !== config.type) { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
76859
1390
189