Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add options for constrain by each axis #429

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,18 @@ npm install --save-dev svelte-dnd-action

An options-object with the following attributes:
| Name | Type | Required? | Default Value | Description |
| ------------------------- | -------------- | ------------------------------------------------------------ | ------------------------------------------------- | ------------------------------------------------------------ |
| ------------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `items` | Array<Object> | Yes. Each object in the array **has to have** an `id` property (key name can be overridden globally) with a unique value (within all dnd-zones of the same type) | N/A | The data array that is used to produce the list with the draggable items (the same thing you run your #each block on). The dndzone should not have children that don't originate in `items` |
| `flipDurationMs` | Number | No | `0` | The same value you give the flip animation on the items (to make them animated as they "make space" for the dragged item). Set to zero or leave out if you don't want animations |
| `type` | String | No | Internal | dnd-zones that share the same type can have elements from one dragged into another. By default, all dnd-zones have the same type |
| `constrainAxisX` | Boolean | No | `false` | Constrain dragging by X axis. Drag will be allowed only by Y axis. |
| `constrainAxisY` | Boolean | No | `false` | Constrain dragging by Y axis. Drag will be allowed only by X axis. |
| `dragDisabled` | Boolean | No | `false` | Setting it to true will make it impossible to drag elements out of the dnd-zone. You can change it at any time, and the zone will adjust on the fly |
| `morphDisabled` | Boolean | No | `false` | By default, when dragging over a zone, the dragged element is morphed to look like it would if dropped. You can prevent it by setting this option. |
| `dropFromOthersDisabled` | Boolean | No | `false` | Setting it to true will make it impossible to drop elements from other dnd-zones of the same type. Can be useful if you want to limit the max number of items for example. You can change it at any time, and the zone will adjust on the fly |
| `zoneTabIndex` | Number | No | `0` | Allow user to set custom tabindex to the list container when not dragging. Can be useful if you want to make the screen reader to skip the list container. You can change it at any time. |
| `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 into 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 |
| `dropTargetClasses`| Array<String> | No | `[]` | A list of classes to apply to the dnd-zone when items can be dragged into it. Note: make sure the classes you use are global. |
| `dropTargetClasses` | Array<String> | No | `[]` | A list of classes to apply to the dnd-zone when items can be dragged into it. Note: make sure the classes you use are global. |
| `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. If what you are after is altering styles, do it to the children, not to the dragged element itself |
| `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. |
| `centreDraggedOnCursor` | Boolean | No | `false` | Setting it to true will cause elements from this dnd-zone to position their center on the cursor on drag start, effectively turning the cursor to the focal point that triggers all the dnd events (ex: entering another zone). Useful for dnd-zones with large items that can be dragged over small items. |
Expand Down Expand Up @@ -235,15 +237,14 @@ setDebugMode(true);
If you are using Typescript, you will need to add the following block to your `global.d.ts` (at least until [this svelte issue](https://github.com/sveltejs/language-tools/issues/431) is resolved):

```typescript
declare type Item = import('svelte-dnd-action').Item;
declare type DndEvent<ItemType = Item> = import('svelte-dnd-action').DndEvent<ItemType>;
declare type Item = import("svelte-dnd-action").Item;
declare type DndEvent<ItemType = Item> = import("svelte-dnd-action").DndEvent<ItemType>;
declare namespace svelte.JSX {
interface HTMLAttributes<T> {
onconsider?: (event: CustomEvent<DndEvent<ItemType>> & { target: EventTarget & T }) => void;
onfinalize?: (event: CustomEvent<DndEvent<ItemType>> & { target: EventTarget & T }) => void;
}
interface HTMLAttributes<T> {
onconsider?: (event: CustomEvent<DndEvent<ItemType>> & {target: EventTarget & T}) => void;
onfinalize?: (event: CustomEvent<DndEvent<ItemType>> & {target: EventTarget & T}) => void;
}
}

```

You may need to edit `tsconfig.json` to include `global.d.ts` if it doesn't already: "include": ["src/**/*", "global.d.ts"].
Expand Down Expand Up @@ -307,15 +308,14 @@ You can use generics to set the type of `items` you are expecting in `DndEvent`.
items = e.detail.items;
}

let items: Dog[] = [
{ id: 1, name: 'Fido', breed: 'bulldog' },
{ id: 2, name: 'Spot', breed: 'labrador' },
{ id: 3, name: 'Jacky', breed: 'golden retriever' }
];
let items: Dog[] = [
{id: 1, name: "Fido", breed: "bulldog"},
{id: 2, name: "Spot", breed: "labrador"},
{id: 3, name: "Jacky", breed: "golden retriever"}
];
</script>
```


### Contributing [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/isaacHagoel/svelte-dnd-action/issues)

There is still quite a lot to do. If you'd like to contribute please get in touch (raise an issue or comment on an existing one).
Expand Down
11 changes: 10 additions & 1 deletion src/action.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {toString} from "./helpers/util";
* @property {array} items - the list of items that was used to generate the children of the given node (the list used in the #each block
* @property {string} [type] - the type of the dnd zone. children dragged from here can only be dropped in other zones of the same type, default to a base type
* @property {number} [flipDurationMs] - if the list animated using flip (recommended), specifies the flip duration such that everything syncs with it without conflict, defaults to zero
* @property {boolean} [constrainAxisX] - Constrain dragging by X axis. Drag will be allowed only by Y axis.
* @property {boolean} [constrainAxisY] - Constrain dragging by Y axis. Drag will be allowed only by X axis.
* @property {boolean} [dragDisabled]
* @property {boolean} [morphDisabled] - whether dragged element should morph to zone dimensions
* @property {boolean} [dropFromOthersDisabled]
Expand Down Expand Up @@ -47,6 +49,8 @@ function validateOptions(options) {
items,
flipDurationMs,
type,
constrainAxisX,
constrainAxisY,
dragDisabled,
morphDisabled,
dropFromOthersDisabled,
Expand Down Expand Up @@ -78,5 +82,10 @@ function validateOptions(options) {
}

function isInt(value) {
return !isNaN(value) && (function(x) { return (x | 0) === x; })(parseFloat(value));
return (
!isNaN(value) &&
(function (x) {
return (x | 0) === x;
})(parseFloat(value))
);
}
12 changes: 11 additions & 1 deletion src/pointerAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,11 @@ function handleDraggedIsOverIndex(e) {
function handleMouseMove(e) {
e.preventDefault();
const c = e.touches ? e.touches[0] : e;
currentMousePosition = {x: c.clientX, y: c.clientY};
const {constrainAxisX, constrainAxisY} = dzToConfig.get(originDropZone);
currentMousePosition = {
x: constrainAxisX ? dragStartMousePosition.x : c.clientX,
y: constrainAxisY ? dragStartMousePosition.y : c.clientY
};
draggedEl.style.transform = `translate3d(${currentMousePosition.x - dragStartMousePosition.x}px, ${
currentMousePosition.y - dragStartMousePosition.y
}px, 0)`;
Expand Down Expand Up @@ -322,6 +326,8 @@ export function dndzone(node, options) {
items: undefined,
type: undefined,
flipDurationMs: 0,
constrainAxisX: false,
constrainAxisY: false,
dragDisabled: false,
morphDisabled: false,
dropFromOthersDisabled: false,
Expand Down Expand Up @@ -445,6 +451,8 @@ export function dndzone(node, options) {
items = undefined,
flipDurationMs: dropAnimationDurationMs = 0,
type: newType = DEFAULT_DROP_ZONE_TYPE,
constrainAxisX = false,
constrainAxisY = false,
dragDisabled = false,
morphDisabled = false,
dropFromOthersDisabled = false,
Expand All @@ -460,6 +468,8 @@ export function dndzone(node, options) {
config.type = newType;
registerDropZone(node, newType);
config.items = [...items];
config.constrainAxisX = constrainAxisX;
config.constrainAxisY = constrainAxisY;
config.dragDisabled = dragDisabled;
config.morphDisabled = morphDisabled;
config.transformDraggedElement = transformDraggedElement;
Expand Down
2 changes: 2 additions & 0 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export interface Options {
items: Item[]; // the list of items that was used to generate the children of the given node
type?: string; // the type of the dnd zone. children dragged from here can only be dropped in other zones of the same type, defaults to a base type
flipDurationMs?: number; // if the list animated using flip (recommended), specifies the flip duration such that everything syncs with it without conflict
constrainAxisX?: boolean; // Constrain dragging by X axis. Drag will be allowed only by Y axis.
constrainAxisY?: boolean; // Constrain dragging by Y axis. Drag will be allowed only by X axis.
dragDisabled?: boolean;
morphDisabled?: boolean;
dropFromOthersDisabled?: boolean;
Expand Down