@marianmeres/stuic 1.64.0 → 1.65.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,27 @@
1
+ /// <reference types="svelte" />
2
+ import type { Writable } from 'svelte/store';
3
+ export type EffectAllowed = 'copy' | 'none' | 'copyLink' | 'copyMove' | 'link' | 'linkMove' | 'move' | 'all' | 'uninitialized';
4
+ export type DropEffect = 'copy' | 'none' | 'link' | 'move';
5
+ export interface DraggableOptions {
6
+ id?: string;
7
+ enabled?: boolean;
8
+ payload?: any;
9
+ effectAllowed?: EffectAllowed;
10
+ isDragged?: Writable<Record<string, boolean>>;
11
+ }
12
+ export declare const draggable: (node: HTMLElement, options: DraggableOptions) => {
13
+ update(newOptions?: DraggableOptions): void;
14
+ destroy(): void;
15
+ };
16
+ export interface DroppableOptions {
17
+ id?: string;
18
+ enabled?: boolean;
19
+ onDrop: (data: any, e: DragEvent) => void;
20
+ onDragover?: (data: any) => void;
21
+ dropEffect?: DropEffect;
22
+ isDraggedOver?: Writable<Record<string, boolean>>;
23
+ }
24
+ export declare const droppable: (node: HTMLElement, options: DroppableOptions) => {
25
+ update(newOptions?: DroppableOptions): void;
26
+ destroy(): void;
27
+ };
@@ -0,0 +1,130 @@
1
+ import { createClog } from '@marianmeres/clog';
2
+ const clog = createClog('drag-drop');
3
+ const _isFn = (v) => typeof v === 'function';
4
+ export const draggable = (node, options) => {
5
+ const DEFAULT_OPTIONS = {
6
+ id: 'draggable-' + Math.random().toString(36).slice(2),
7
+ enabled: true,
8
+ effectAllowed: 'all',
9
+ };
10
+ options = { ...DEFAULT_OPTIONS, ...options };
11
+ // initalizer
12
+ const _init = (_opts) => {
13
+ if (_opts.enabled) {
14
+ node.setAttribute('draggable', 'true');
15
+ node.setAttribute('aria-grabbed', 'false');
16
+ }
17
+ else {
18
+ node.removeAttribute('draggable');
19
+ }
20
+ };
21
+ // init now
22
+ _init(options);
23
+ const _payload = () => (_isFn(options?.payload) ? options.payload() : options.payload);
24
+ //
25
+ const onDragstart = (e) => {
26
+ const pld = _payload();
27
+ if (pld !== undefined) {
28
+ // add "stuic" as a custom data format
29
+ e.dataTransfer?.setData('stuic', JSON.stringify({ id: options.id, payload: pld }));
30
+ e.dataTransfer.effectAllowed = options.effectAllowed;
31
+ }
32
+ options?.isDragged?.update((old) => ({ ...old, [options.id]: true }));
33
+ node.setAttribute('aria-grabbed', 'true');
34
+ };
35
+ const onDrag = (e) => {
36
+ // const el: HTMLElement = e.currentTarget as HTMLElement;
37
+ // clog(el);
38
+ // ?
39
+ };
40
+ const onDragend = (e) => {
41
+ // e.preventDefault();
42
+ options?.isDragged?.update((old) => ({ ...old, [options.id]: false }));
43
+ node.setAttribute('aria-grabbed', 'false');
44
+ };
45
+ node.addEventListener('dragstart', onDragstart);
46
+ node.addEventListener('drag', onDrag);
47
+ node.addEventListener('dragend', onDragend);
48
+ return {
49
+ update(newOptions) {
50
+ options = { ...options, ...(newOptions || {}) };
51
+ // reinit maybe
52
+ _init(options);
53
+ },
54
+ destroy() {
55
+ node.removeEventListener('dragstart', onDragstart);
56
+ node.removeEventListener('drag', onDrag);
57
+ node.removeEventListener('dragend', onDragend);
58
+ },
59
+ };
60
+ };
61
+ export const droppable = (node, options) => {
62
+ const DEFAULT_OPTIONS = {
63
+ id: 'droppable-' + Math.random().toString(36).slice(2),
64
+ enabled: true,
65
+ dropEffect: 'move',
66
+ };
67
+ options = { ...DEFAULT_OPTIONS, ...options };
68
+ //
69
+ const onDragenter = (e) => {
70
+ // e.preventDefault();
71
+ // console.log('dragover', e.dataTransfer);
72
+ e.dataTransfer.dropEffect = options.dropEffect;
73
+ options?.isDraggedOver?.update((old) => ({ ...old, [options.id]: true }));
74
+ };
75
+ const onDragover = (e) => {
76
+ e.preventDefault(); // this prevents animation
77
+ };
78
+ const onDragleave = (e) => {
79
+ // e.preventDefault();
80
+ options?.isDraggedOver?.update((old) => ({ ...old, [options.id]: false }));
81
+ };
82
+ const onDrop = (e) => {
83
+ e.preventDefault();
84
+ const target = e.target;
85
+ e.dataTransfer.dropEffect = options.dropEffect;
86
+ options?.isDraggedOver?.update((old) => ({ ...old, [options.id]: false }));
87
+ if (_isFn(options.onDrop)) {
88
+ let stuicData = e.dataTransfer?.getData('stuic');
89
+ // prettier-ignore
90
+ try {
91
+ stuicData = JSON.parse(stuicData);
92
+ }
93
+ catch (e) { }
94
+ return options.onDrop(stuicData, e);
95
+ }
96
+ };
97
+ const _removeListeners = () => {
98
+ node.removeEventListener('dragenter', onDragenter);
99
+ node.removeEventListener('dragover', onDragover);
100
+ node.removeEventListener('dragleave', onDragleave);
101
+ node.removeEventListener('drop', onDrop);
102
+ };
103
+ //
104
+ let _listens = false;
105
+ const _init = (_opts) => {
106
+ if (_opts.enabled && !_listens) {
107
+ node.addEventListener('dragenter', onDragenter);
108
+ node.addEventListener('dragover', onDragover);
109
+ node.addEventListener('dragleave', onDragleave);
110
+ node.addEventListener('drop', onDrop);
111
+ _listens = true;
112
+ }
113
+ else if (!_opts.enabled && _listens) {
114
+ _removeListeners();
115
+ _listens = false;
116
+ }
117
+ };
118
+ // init now
119
+ _init(options);
120
+ return {
121
+ update(newOptions) {
122
+ options = { ...options, ...(newOptions || {}) };
123
+ // reinit maybe
124
+ _init(options);
125
+ },
126
+ destroy() {
127
+ _removeListeners();
128
+ },
129
+ };
130
+ };
@@ -114,6 +114,7 @@ parent, div, arrow, opts, log) => {
114
114
  };
115
115
  // log('applying arrowStyles', arrowStyles);
116
116
  Object.entries(arrowStyles).forEach(([k, v]) => {
117
+ // @ts-ignore
117
118
  arrow.style[k] = v;
118
119
  });
119
120
  //
package/dist/index.d.ts CHANGED
@@ -21,6 +21,7 @@ export { default as Switch, SwitchConfig } from './components/Switch/Switch.svel
21
21
  export { default as Thc, type THC, isTHCNotEmpty } from './components/Thc/Thc.svelte';
22
22
  export { default as X } from './components/X/X.svelte';
23
23
  export { autogrow } from './actions/autogrow.js';
24
+ export { draggable, droppable, type DraggableOptions, type DroppableOptions, } from './actions/drag-drop.js';
24
25
  export { focusTrap } from './actions/focus-trap.js';
25
26
  export { onOutside } from './actions/on-outside.js';
26
27
  export { preSubmitValidityCheck } from './actions/pre-submit-validity-check.js';
package/dist/index.js CHANGED
@@ -36,6 +36,7 @@ export { default as Thc, isTHCNotEmpty } from './components/Thc/Thc.svelte';
36
36
  export { default as X } from './components/X/X.svelte';
37
37
  // actions
38
38
  export { autogrow } from './actions/autogrow.js';
39
+ export { draggable, droppable, } from './actions/drag-drop.js';
39
40
  export { focusTrap } from './actions/focus-trap.js';
40
41
  export { onOutside } from './actions/on-outside.js';
41
42
  export { preSubmitValidityCheck } from './actions/pre-submit-validity-check.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marianmeres/stuic",
3
- "version": "1.64.0",
3
+ "version": "1.65.0",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run package && node ./scripts/date.js",