@pallasoft/ps-core-components 2.22.1 → 2.23.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.
- package/dist/components/ps-drag-grip.d.ts +1 -0
- package/dist/components/ps-drag-grip.js +6 -0
- package/dist/components/ps-drag-overlay.d.ts +7 -0
- package/dist/components/ps-drag-overlay.js +34 -0
- package/dist/components/ps-draggable-grid.js +16 -39
- package/dist/components/ps-sortable-list.d.ts +22 -0
- package/dist/components/ps-sortable-list.js +79 -0
- package/dist/constants/ps-drag-config.d.ts +18 -0
- package/dist/constants/ps-drag-config.js +30 -0
- package/dist/constants/ps-draggable-grid.js +4 -18
- package/dist/esm/components/ps-drag-grip.js +2 -0
- package/dist/esm/components/ps-drag-overlay.js +30 -0
- package/dist/esm/components/ps-draggable-grid.js +20 -43
- package/dist/esm/components/ps-sortable-list.js +75 -0
- package/dist/esm/constants/ps-drag-config.js +27 -0
- package/dist/esm/constants/ps-draggable-grid.js +4 -18
- package/dist/esm/hooks/use-ps-drag-sensors.js +11 -0
- package/dist/esm/hooks/use-ps-reduced-motion.js +14 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/models/ps-sortable-list.js +1 -0
- package/dist/hooks/use-ps-drag-sensors.d.ts +2 -0
- package/dist/hooks/use-ps-drag-sensors.js +15 -0
- package/dist/hooks/use-ps-reduced-motion.d.ts +1 -0
- package/dist/hooks/use-ps-reduced-motion.js +18 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/models/ps-sortable-list.d.ts +32 -0
- package/dist/models/ps-sortable-list.js +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const PsDragGrip: () => import("react").JSX.Element;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsDragGrip = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const PsDragGrip = () => ((0, jsx_runtime_1.jsx)("span", { "aria-hidden": 'true', className: 'grid grid-cols-2 gap-[0.1875rem]', children: Array.from({ length: 6 }).map((_, index) => ((0, jsx_runtime_1.jsx)("span", { className: 'h-[3px] w-[3px] rounded-full bg-current' }, index))) }));
|
|
6
|
+
exports.PsDragGrip = PsDragGrip;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export interface PsDragOverlayProps {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
className: string;
|
|
5
|
+
frames: Keyframe[];
|
|
6
|
+
}
|
|
7
|
+
export declare const PsDragOverlay: ({ children, className, frames }: PsDragOverlayProps) => import("react").ReactPortal | null;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsDragOverlay = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const core_1 = require("@dnd-kit/core");
|
|
7
|
+
const react_dom_1 = require("react-dom");
|
|
8
|
+
const ps_drag_config_1 = require("../constants/ps-drag-config");
|
|
9
|
+
const use_ps_reduced_motion_1 = require("../hooks/use-ps-reduced-motion");
|
|
10
|
+
const dropAnimation = {
|
|
11
|
+
duration: ps_drag_config_1.PsDragConfig.dropDuration,
|
|
12
|
+
easing: ps_drag_config_1.PsDragConfig.dropEasing,
|
|
13
|
+
sideEffects: (0, core_1.defaultDropAnimationSideEffects)({
|
|
14
|
+
styles: { active: { opacity: ps_drag_config_1.PsDragConfig.placeholderOpacity } },
|
|
15
|
+
}),
|
|
16
|
+
};
|
|
17
|
+
const PsDragOverlay = ({ children, className, frames }) => {
|
|
18
|
+
const [isMounted, setIsMounted] = (0, react_1.useState)(false);
|
|
19
|
+
const isReduced = (0, use_ps_reduced_motion_1.usePsReducedMotion)();
|
|
20
|
+
(0, react_1.useEffect)(() => setIsMounted(true), []);
|
|
21
|
+
if (!isMounted)
|
|
22
|
+
return null;
|
|
23
|
+
const lift = (element) => {
|
|
24
|
+
if (element === null || isReduced || typeof element.animate !== 'function')
|
|
25
|
+
return;
|
|
26
|
+
element.animate(frames, {
|
|
27
|
+
duration: ps_drag_config_1.PsDragConfig.liftDuration,
|
|
28
|
+
easing: ps_drag_config_1.PsDragConfig.liftEasing,
|
|
29
|
+
fill: 'forwards',
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
return (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)(core_1.DragOverlay, { dropAnimation: isReduced ? null : dropAnimation, children: children === null ? null : ((0, jsx_runtime_1.jsx)("div", { className: className, ref: lift, children: children })) }), document.body);
|
|
33
|
+
};
|
|
34
|
+
exports.PsDragOverlay = PsDragOverlay;
|
|
@@ -6,26 +6,12 @@ const react_1 = require("react");
|
|
|
6
6
|
const core_1 = require("@dnd-kit/core");
|
|
7
7
|
const sortable_1 = require("@dnd-kit/sortable");
|
|
8
8
|
const utilities_1 = require("@dnd-kit/utilities");
|
|
9
|
-
const
|
|
9
|
+
const ps_drag_config_1 = require("../constants/ps-drag-config");
|
|
10
10
|
const ps_draggable_grid_1 = require("../constants/ps-draggable-grid");
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
duration: ps_draggable_grid_1.PsDraggableGridConfig.liftDuration,
|
|
16
|
-
easing: ps_draggable_grid_1.PsDraggableGridConfig.liftEasing,
|
|
17
|
-
fill: 'forwards',
|
|
18
|
-
});
|
|
19
|
-
};
|
|
20
|
-
const dropAnimation = {
|
|
21
|
-
duration: ps_draggable_grid_1.PsDraggableGridConfig.dropDuration,
|
|
22
|
-
easing: ps_draggable_grid_1.PsDraggableGridConfig.dropEasing,
|
|
23
|
-
sideEffects: (0, core_1.defaultDropAnimationSideEffects)({
|
|
24
|
-
styles: { active: { opacity: ps_draggable_grid_1.PsDraggableGridConfig.placeholderOpacity } },
|
|
25
|
-
}),
|
|
26
|
-
};
|
|
27
|
-
const DragHandleIcon = () => ((0, jsx_runtime_1.jsx)("span", { "aria-hidden": 'true', className: 'grid grid-cols-2 gap-[0.1875rem]', children: Array.from({ length: 6 }).map((_, index) => ((0, jsx_runtime_1.jsx)("span", { className: 'h-[3px] w-[3px] rounded-full bg-current' }, index))) }));
|
|
28
|
-
const PsDraggableGridHandle = ({ attributes, label, listeners, setActivatorNodeRef, }) => ((0, jsx_runtime_1.jsx)("button", { ...attributes, ...listeners, "aria-label": `Move ${label}`, className: ps_draggable_grid_1.PsDraggableGridClasses.handle, ref: setActivatorNodeRef, title: `Move ${label}`, type: 'button', children: (0, jsx_runtime_1.jsx)(DragHandleIcon, {}) }));
|
|
11
|
+
const use_ps_drag_sensors_1 = require("../hooks/use-ps-drag-sensors");
|
|
12
|
+
const ps_drag_grip_1 = require("./ps-drag-grip");
|
|
13
|
+
const ps_drag_overlay_1 = require("./ps-drag-overlay");
|
|
14
|
+
const PsDraggableGridHandle = ({ attributes, label, listeners, setActivatorNodeRef, }) => ((0, jsx_runtime_1.jsx)("button", { ...attributes, ...listeners, "aria-label": `Move ${label}`, className: ps_draggable_grid_1.PsDraggableGridClasses.handle, ref: setActivatorNodeRef, title: `Move ${label}`, type: 'button', children: (0, jsx_runtime_1.jsx)(ps_drag_grip_1.PsDragGrip, {}) }));
|
|
29
15
|
const PsSortableGridItem = ({ className, index, item, renderItem, }) => {
|
|
30
16
|
const { attributes, isDragging, listeners, setActivatorNodeRef, setNodeRef, transform, transition, } = (0, sortable_1.useSortable)({ id: item.id });
|
|
31
17
|
const rendered = renderItem({
|
|
@@ -38,23 +24,14 @@ const PsSortableGridItem = ({ className, index, item, renderItem, }) => {
|
|
|
38
24
|
if (!rendered)
|
|
39
25
|
return null;
|
|
40
26
|
return ((0, jsx_runtime_1.jsx)("div", { className: `${ps_draggable_grid_1.PsDraggableGridClasses.item} ${className} ${isDragging ? ps_draggable_grid_1.PsDraggableGridClasses.placeholder : ''}`, ref: setNodeRef, style: {
|
|
41
|
-
opacity: isDragging ?
|
|
27
|
+
opacity: isDragging ? ps_drag_config_1.PsDragConfig.placeholderOpacity : undefined,
|
|
42
28
|
transform: utilities_1.CSS.Translate.toString(transform),
|
|
43
29
|
transition,
|
|
44
30
|
}, children: rendered }));
|
|
45
31
|
};
|
|
46
32
|
const PsDraggableGrid = ({ getItemClassName, items, onReorder, onReorderEnd, renderItem, }) => {
|
|
47
33
|
const [activeId, setActiveId] = (0, react_1.useState)(null);
|
|
48
|
-
const
|
|
49
|
-
(0, react_1.useEffect)(() => setIsMounted(true), []);
|
|
50
|
-
const sensors = (0, core_1.useSensors)((0, core_1.useSensor)(core_1.MouseSensor, {
|
|
51
|
-
activationConstraint: { distance: ps_draggable_grid_1.PsDraggableGridConfig.activationDistance },
|
|
52
|
-
}), (0, core_1.useSensor)(core_1.TouchSensor, {
|
|
53
|
-
activationConstraint: {
|
|
54
|
-
delay: ps_draggable_grid_1.PsDraggableGridConfig.touchDelay,
|
|
55
|
-
tolerance: ps_draggable_grid_1.PsDraggableGridConfig.touchTolerance,
|
|
56
|
-
},
|
|
57
|
-
}), (0, core_1.useSensor)(core_1.KeyboardSensor, { coordinateGetter: sortable_1.sortableKeyboardCoordinates }));
|
|
34
|
+
const sensors = (0, use_ps_drag_sensors_1.usePsDragSensors)();
|
|
58
35
|
const className = (item) => getItemClassName !== undefined ? getItemClassName(item) : '';
|
|
59
36
|
const activeIndex = items.findIndex((item) => item.id === activeId);
|
|
60
37
|
const activeItem = activeIndex >= 0 ? items[activeIndex] : null;
|
|
@@ -71,14 +48,14 @@ const PsDraggableGrid = ({ getItemClassName, items, onReorder, onReorderEnd, ren
|
|
|
71
48
|
if (onReorderEnd !== undefined)
|
|
72
49
|
onReorderEnd(nextItems);
|
|
73
50
|
};
|
|
74
|
-
return ((0, jsx_runtime_1.jsxs)(core_1.DndContext, { collisionDetection: core_1.closestCenter, onDragCancel: () => setActiveId(null), onDragEnd: handleDragEnd, onDragStart: (event) => setActiveId(String(event.active.id)), sensors: sensors, children: [(0, jsx_runtime_1.jsx)(sortable_1.SortableContext, { items: items.map((item) => item.id), strategy: sortable_1.rectSortingStrategy, children: items.map((item, index) => ((0, jsx_runtime_1.jsx)(PsSortableGridItem, { className: className(item), index: index, item: item, renderItem: renderItem }, item.id))) }),
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
51
|
+
return ((0, jsx_runtime_1.jsxs)(core_1.DndContext, { collisionDetection: core_1.closestCenter, onDragCancel: () => setActiveId(null), onDragEnd: handleDragEnd, onDragStart: (event) => setActiveId(String(event.active.id)), sensors: sensors, children: [(0, jsx_runtime_1.jsx)(sortable_1.SortableContext, { items: items.map((item) => item.id), strategy: sortable_1.rectSortingStrategy, children: items.map((item, index) => ((0, jsx_runtime_1.jsx)(PsSortableGridItem, { className: className(item), index: index, item: item, renderItem: renderItem }, item.id))) }), (0, jsx_runtime_1.jsx)(ps_drag_overlay_1.PsDragOverlay, { className: ps_draggable_grid_1.PsDraggableGridClasses.lifted, frames: ps_draggable_grid_1.PsDraggableGridLiftFrames, children: activeItem !== null
|
|
52
|
+
? renderItem({
|
|
53
|
+
handle: (0, jsx_runtime_1.jsx)(PsDraggableGridHandle, { label: activeItem.label }),
|
|
54
|
+
index: activeIndex,
|
|
55
|
+
isDragging: true,
|
|
56
|
+
isOverlay: true,
|
|
57
|
+
item: activeItem,
|
|
58
|
+
})
|
|
59
|
+
: null })] }));
|
|
83
60
|
};
|
|
84
61
|
exports.PsDraggableGrid = PsDraggableGrid;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type JSX } from 'react';
|
|
2
|
+
import { useSortable } from '@dnd-kit/sortable';
|
|
3
|
+
import type { PsSortableListItem, PsSortableListProps, PsSortableListRenderOptions } from '../models/ps-sortable-list';
|
|
4
|
+
export interface PsSortableListHandleProps {
|
|
5
|
+
className?: string;
|
|
6
|
+
icon?: JSX.Element;
|
|
7
|
+
attributes?: ReturnType<typeof useSortable>['attributes'];
|
|
8
|
+
label: string;
|
|
9
|
+
listeners?: ReturnType<typeof useSortable>['listeners'];
|
|
10
|
+
setActivatorNodeRef?: (element: HTMLElement | null) => void;
|
|
11
|
+
}
|
|
12
|
+
export interface PsSortableListRowProps<TItem extends PsSortableListItem> {
|
|
13
|
+
className: string;
|
|
14
|
+
handleClassName?: string;
|
|
15
|
+
handleIcon?: JSX.Element;
|
|
16
|
+
getHandleLabel: (label: string) => string;
|
|
17
|
+
index: number;
|
|
18
|
+
isDisabled: boolean;
|
|
19
|
+
item: TItem;
|
|
20
|
+
renderItem: (options: PsSortableListRenderOptions<TItem>) => JSX.Element | null;
|
|
21
|
+
}
|
|
22
|
+
export declare const PsSortableList: <TItem extends PsSortableListItem>({ announcements: texts, className, getHandleLabel, getItemClassName, handleClassName, handleIcon, instructions, role, items, onMove, renderItem, }: PsSortableListProps<TItem>) => JSX.Element;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsSortableList = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const core_1 = require("@dnd-kit/core");
|
|
7
|
+
const sortable_1 = require("@dnd-kit/sortable");
|
|
8
|
+
const utilities_1 = require("@dnd-kit/utilities");
|
|
9
|
+
const ps_drag_config_1 = require("../constants/ps-drag-config");
|
|
10
|
+
const use_ps_drag_sensors_1 = require("../hooks/use-ps-drag-sensors");
|
|
11
|
+
const use_ps_reduced_motion_1 = require("../hooks/use-ps-reduced-motion");
|
|
12
|
+
const ps_drag_grip_1 = require("./ps-drag-grip");
|
|
13
|
+
const ps_drag_overlay_1 = require("./ps-drag-overlay");
|
|
14
|
+
const PsSortableListHandle = ({ attributes, className, icon, label, listeners, setActivatorNodeRef, }) => ((0, jsx_runtime_1.jsx)("button", { ...attributes, ...listeners, "aria-label": label, className: className === undefined ? ps_drag_config_1.PsDragClasses.handle : className, ref: setActivatorNodeRef, title: label, type: 'button', children: icon === undefined ? (0, jsx_runtime_1.jsx)(ps_drag_grip_1.PsDragGrip, {}) : icon }));
|
|
15
|
+
const PsSortableListRow = ({ className, handleClassName, handleIcon, getHandleLabel, index, isDisabled, item, renderItem, }) => {
|
|
16
|
+
const isReduced = (0, use_ps_reduced_motion_1.usePsReducedMotion)();
|
|
17
|
+
const { attributes, isDragging, listeners, setActivatorNodeRef, setNodeRef, transform, transition, } = (0, sortable_1.useSortable)({ disabled: isDisabled, id: item.id });
|
|
18
|
+
const rendered = renderItem({
|
|
19
|
+
handle: ((0, jsx_runtime_1.jsx)(PsSortableListHandle, { attributes: attributes, className: handleClassName, icon: handleIcon, label: getHandleLabel(item.label), listeners: listeners, setActivatorNodeRef: setActivatorNodeRef })),
|
|
20
|
+
index,
|
|
21
|
+
isDragging,
|
|
22
|
+
isOverlay: false,
|
|
23
|
+
item,
|
|
24
|
+
});
|
|
25
|
+
if (!rendered)
|
|
26
|
+
return null;
|
|
27
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: `${ps_drag_config_1.PsDragClasses.listItem} ${className} ${isDragging ? ps_drag_config_1.PsDragClasses.placeholder : ''}`, ref: setNodeRef, style: {
|
|
28
|
+
opacity: isDragging ? ps_drag_config_1.PsDragConfig.placeholderOpacity : undefined,
|
|
29
|
+
transform: utilities_1.CSS.Translate.toString(transform),
|
|
30
|
+
transition: isReduced ? undefined : transition,
|
|
31
|
+
}, children: rendered }));
|
|
32
|
+
};
|
|
33
|
+
const PsSortableList = ({ announcements: texts, className, getHandleLabel, getItemClassName, handleClassName, handleIcon, instructions, role, items, onMove, renderItem, }) => {
|
|
34
|
+
const [activeId, setActiveId] = (0, react_1.useState)(null);
|
|
35
|
+
const sensors = (0, use_ps_drag_sensors_1.usePsDragSensors)();
|
|
36
|
+
const activeIndex = items.findIndex((item) => item.id === activeId);
|
|
37
|
+
const activeItem = activeIndex >= 0 ? items[activeIndex] : null;
|
|
38
|
+
const itemClassName = (item) => getItemClassName === undefined ? '' : getItemClassName(item);
|
|
39
|
+
const groupOf = (id) => {
|
|
40
|
+
const found = items.find((item) => item.id === id);
|
|
41
|
+
return found === undefined ? undefined : found.groupKey;
|
|
42
|
+
};
|
|
43
|
+
const labelOf = (id) => {
|
|
44
|
+
const found = items.find((item) => item.id === id);
|
|
45
|
+
return found === undefined ? id : found.label;
|
|
46
|
+
};
|
|
47
|
+
const positionOf = (id) => items.findIndex((item) => item.id === id) + 1;
|
|
48
|
+
const announcements = {
|
|
49
|
+
onDragCancel: ({ active }) => texts.cancelled(labelOf(String(active.id))),
|
|
50
|
+
onDragEnd: ({ active, over }) => over === null
|
|
51
|
+
? texts.cancelled(labelOf(String(active.id)))
|
|
52
|
+
: texts.dropped(labelOf(String(active.id)), positionOf(String(over.id)), items.length),
|
|
53
|
+
onDragOver: ({ active, over }) => over === null
|
|
54
|
+
? undefined
|
|
55
|
+
: texts.moved(labelOf(String(active.id)), positionOf(String(over.id)), items.length),
|
|
56
|
+
onDragStart: ({ active }) => texts.lifted(labelOf(String(active.id)), positionOf(String(active.id)), items.length),
|
|
57
|
+
};
|
|
58
|
+
const handleDragEnd = ({ active, over }) => {
|
|
59
|
+
setActiveId(null);
|
|
60
|
+
if (over === null || active.id === over.id)
|
|
61
|
+
return;
|
|
62
|
+
const from = items.findIndex((item) => item.id === active.id);
|
|
63
|
+
const to = items.findIndex((item) => item.id === over.id);
|
|
64
|
+
if (from < 0 || to < 0 || groupOf(String(active.id)) !== groupOf(String(over.id)))
|
|
65
|
+
return;
|
|
66
|
+
onMove(String(active.id), from, to);
|
|
67
|
+
};
|
|
68
|
+
const activeGroup = activeItem === null ? undefined : activeItem.groupKey;
|
|
69
|
+
return ((0, jsx_runtime_1.jsxs)(core_1.DndContext, { accessibility: { announcements, screenReaderInstructions: { draggable: instructions } }, collisionDetection: core_1.closestCenter, onDragCancel: () => setActiveId(null), onDragEnd: handleDragEnd, onDragStart: ({ active }) => setActiveId(String(active.id)), sensors: sensors, children: [(0, jsx_runtime_1.jsx)(sortable_1.SortableContext, { items: items.map((item) => item.id), strategy: sortable_1.verticalListSortingStrategy, children: (0, jsx_runtime_1.jsx)("div", { className: className, role: role, children: items.map((item, index) => ((0, jsx_runtime_1.jsx)(PsSortableListRow, { className: itemClassName(item), getHandleLabel: getHandleLabel, handleClassName: handleClassName, handleIcon: handleIcon, index: index, isDisabled: activeItem !== null && item.groupKey !== activeGroup, item: item, renderItem: renderItem }, item.id))) }) }), (0, jsx_runtime_1.jsx)(ps_drag_overlay_1.PsDragOverlay, { className: ps_drag_config_1.PsDragClasses.lifted, frames: ps_drag_config_1.PsDragListLiftFrames, children: activeItem !== null
|
|
70
|
+
? renderItem({
|
|
71
|
+
handle: ((0, jsx_runtime_1.jsx)(PsSortableListHandle, { className: handleClassName, icon: handleIcon, label: getHandleLabel(activeItem.label) })),
|
|
72
|
+
index: activeIndex,
|
|
73
|
+
isDragging: true,
|
|
74
|
+
isOverlay: true,
|
|
75
|
+
item: activeItem,
|
|
76
|
+
})
|
|
77
|
+
: null })] }));
|
|
78
|
+
};
|
|
79
|
+
exports.PsSortableList = PsSortableList;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const PsDragConfig: {
|
|
2
|
+
readonly activationDistance: 6;
|
|
3
|
+
readonly dropDuration: 220;
|
|
4
|
+
readonly dropEasing: "cubic-bezier(0.2, 0.8, 0.2, 1)";
|
|
5
|
+
readonly liftDuration: 200;
|
|
6
|
+
readonly liftEasing: "cubic-bezier(0.2, 0.9, 0.3, 1.2)";
|
|
7
|
+
readonly placeholderOpacity: "0.4";
|
|
8
|
+
readonly touchDelay: 180;
|
|
9
|
+
readonly touchTolerance: 6;
|
|
10
|
+
};
|
|
11
|
+
export declare const PsDragClasses: {
|
|
12
|
+
readonly handle: "ps-focus-ring inline-flex h-7 w-7 shrink-0 cursor-grab touch-none items-center justify-center rounded-full text-slate-400/70 transition hover:bg-white/36 hover:text-slate-600 active:cursor-grabbing dark:text-slate-300/55 dark:hover:bg-white/8 dark:hover:text-slate-100";
|
|
13
|
+
readonly listItem: "min-w-0";
|
|
14
|
+
readonly lifted: "cursor-grabbing rounded-xl bg-surface ring-1 ring-primary/30";
|
|
15
|
+
readonly placeholder: "outline-dashed outline-2 outline-offset-[-2px] outline-primary/35";
|
|
16
|
+
};
|
|
17
|
+
export declare const PsDragLiftFrames: Keyframe[];
|
|
18
|
+
export declare const PsDragListLiftFrames: Keyframe[];
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsDragListLiftFrames = exports.PsDragLiftFrames = exports.PsDragClasses = exports.PsDragConfig = void 0;
|
|
4
|
+
exports.PsDragConfig = {
|
|
5
|
+
activationDistance: 6,
|
|
6
|
+
dropDuration: 220,
|
|
7
|
+
dropEasing: 'cubic-bezier(0.2, 0.8, 0.2, 1)',
|
|
8
|
+
liftDuration: 200,
|
|
9
|
+
liftEasing: 'cubic-bezier(0.2, 0.9, 0.3, 1.2)',
|
|
10
|
+
placeholderOpacity: '0.4',
|
|
11
|
+
touchDelay: 180,
|
|
12
|
+
touchTolerance: 6,
|
|
13
|
+
};
|
|
14
|
+
exports.PsDragClasses = {
|
|
15
|
+
handle: 'ps-focus-ring inline-flex h-7 w-7 shrink-0 cursor-grab touch-none items-center justify-center rounded-full text-slate-400/70 transition hover:bg-white/36 hover:text-slate-600 active:cursor-grabbing dark:text-slate-300/55 dark:hover:bg-white/8 dark:hover:text-slate-100',
|
|
16
|
+
listItem: 'min-w-0',
|
|
17
|
+
lifted: 'cursor-grabbing rounded-xl bg-surface ring-1 ring-primary/30',
|
|
18
|
+
placeholder: 'outline-dashed outline-2 outline-offset-[-2px] outline-primary/35',
|
|
19
|
+
};
|
|
20
|
+
exports.PsDragLiftFrames = [
|
|
21
|
+
{ boxShadow: '0 0 0 0 rgb(15 23 42 / 0)', transform: 'scale(1) rotate(0deg)' },
|
|
22
|
+
{
|
|
23
|
+
boxShadow: '0 28px 64px -18px rgb(15 23 42 / 0.5)',
|
|
24
|
+
transform: 'scale(1.035) rotate(-1.2deg)',
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
exports.PsDragListLiftFrames = [
|
|
28
|
+
{ boxShadow: '0 0 0 0 rgb(15 23 42 / 0)', transform: 'scale(1)' },
|
|
29
|
+
{ boxShadow: '0 18px 40px -16px rgb(15 23 42 / 0.45)', transform: 'scale(1.015)' },
|
|
30
|
+
];
|
|
@@ -1,26 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PsDraggableGridLiftFrames = exports.PsDraggableGridClasses = exports.PsDraggableGridConfig = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
dropDuration: 220,
|
|
7
|
-
dropEasing: 'cubic-bezier(0.2, 0.8, 0.2, 1)',
|
|
8
|
-
liftDuration: 200,
|
|
9
|
-
liftEasing: 'cubic-bezier(0.2, 0.9, 0.3, 1.2)',
|
|
10
|
-
placeholderOpacity: '0.4',
|
|
11
|
-
touchDelay: 180,
|
|
12
|
-
touchTolerance: 6,
|
|
13
|
-
};
|
|
4
|
+
const ps_drag_config_1 = require("./ps-drag-config");
|
|
5
|
+
exports.PsDraggableGridConfig = ps_drag_config_1.PsDragConfig;
|
|
14
6
|
exports.PsDraggableGridClasses = {
|
|
15
|
-
handle:
|
|
7
|
+
handle: ps_drag_config_1.PsDragClasses.handle,
|
|
16
8
|
item: 'min-w-0 rounded-[1.7rem]',
|
|
17
9
|
lifted: 'cursor-grabbing rounded-[1.7rem] ring-1 ring-primary/30',
|
|
18
10
|
placeholder: 'rounded-[1.7rem] outline-dashed outline-2 outline-offset-[-2px] outline-primary/35',
|
|
19
11
|
};
|
|
20
|
-
exports.PsDraggableGridLiftFrames =
|
|
21
|
-
{ boxShadow: '0 0 0 0 rgb(15 23 42 / 0)', transform: 'scale(1) rotate(0deg)' },
|
|
22
|
-
{
|
|
23
|
-
boxShadow: '0 28px 64px -18px rgb(15 23 42 / 0.5)',
|
|
24
|
-
transform: 'scale(1.035) rotate(-1.2deg)',
|
|
25
|
-
},
|
|
26
|
-
];
|
|
12
|
+
exports.PsDraggableGridLiftFrames = ps_drag_config_1.PsDragLiftFrames;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
export const PsDragGrip = () => (_jsx("span", { "aria-hidden": 'true', className: 'grid grid-cols-2 gap-[0.1875rem]', children: Array.from({ length: 6 }).map((_, index) => (_jsx("span", { className: 'h-[3px] w-[3px] rounded-full bg-current' }, index))) }));
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { DragOverlay, defaultDropAnimationSideEffects } from '@dnd-kit/core';
|
|
4
|
+
import { createPortal } from 'react-dom';
|
|
5
|
+
import { PsDragConfig } from '../constants/ps-drag-config';
|
|
6
|
+
import { usePsReducedMotion } from '../hooks/use-ps-reduced-motion';
|
|
7
|
+
const dropAnimation = {
|
|
8
|
+
duration: PsDragConfig.dropDuration,
|
|
9
|
+
easing: PsDragConfig.dropEasing,
|
|
10
|
+
sideEffects: defaultDropAnimationSideEffects({
|
|
11
|
+
styles: { active: { opacity: PsDragConfig.placeholderOpacity } },
|
|
12
|
+
}),
|
|
13
|
+
};
|
|
14
|
+
export const PsDragOverlay = ({ children, className, frames }) => {
|
|
15
|
+
const [isMounted, setIsMounted] = useState(false);
|
|
16
|
+
const isReduced = usePsReducedMotion();
|
|
17
|
+
useEffect(() => setIsMounted(true), []);
|
|
18
|
+
if (!isMounted)
|
|
19
|
+
return null;
|
|
20
|
+
const lift = (element) => {
|
|
21
|
+
if (element === null || isReduced || typeof element.animate !== 'function')
|
|
22
|
+
return;
|
|
23
|
+
element.animate(frames, {
|
|
24
|
+
duration: PsDragConfig.liftDuration,
|
|
25
|
+
easing: PsDragConfig.liftEasing,
|
|
26
|
+
fill: 'forwards',
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
return createPortal(_jsx(DragOverlay, { dropAnimation: isReduced ? null : dropAnimation, children: children === null ? null : (_jsx("div", { className: className, ref: lift, children: children })) }), document.body);
|
|
30
|
+
};
|
|
@@ -1,28 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import { DndContext,
|
|
4
|
-
import { SortableContext, arrayMove, rectSortingStrategy,
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { DndContext, closestCenter } from '@dnd-kit/core';
|
|
4
|
+
import { SortableContext, arrayMove, rectSortingStrategy, useSortable } from '@dnd-kit/sortable';
|
|
5
5
|
import { CSS } from '@dnd-kit/utilities';
|
|
6
|
-
import {
|
|
7
|
-
import { PsDraggableGridClasses,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
duration: PsDraggableGridConfig.liftDuration,
|
|
13
|
-
easing: PsDraggableGridConfig.liftEasing,
|
|
14
|
-
fill: 'forwards',
|
|
15
|
-
});
|
|
16
|
-
};
|
|
17
|
-
const dropAnimation = {
|
|
18
|
-
duration: PsDraggableGridConfig.dropDuration,
|
|
19
|
-
easing: PsDraggableGridConfig.dropEasing,
|
|
20
|
-
sideEffects: defaultDropAnimationSideEffects({
|
|
21
|
-
styles: { active: { opacity: PsDraggableGridConfig.placeholderOpacity } },
|
|
22
|
-
}),
|
|
23
|
-
};
|
|
24
|
-
const DragHandleIcon = () => (_jsx("span", { "aria-hidden": 'true', className: 'grid grid-cols-2 gap-[0.1875rem]', children: Array.from({ length: 6 }).map((_, index) => (_jsx("span", { className: 'h-[3px] w-[3px] rounded-full bg-current' }, index))) }));
|
|
25
|
-
const PsDraggableGridHandle = ({ attributes, label, listeners, setActivatorNodeRef, }) => (_jsx("button", { ...attributes, ...listeners, "aria-label": `Move ${label}`, className: PsDraggableGridClasses.handle, ref: setActivatorNodeRef, title: `Move ${label}`, type: 'button', children: _jsx(DragHandleIcon, {}) }));
|
|
6
|
+
import { PsDragConfig } from '../constants/ps-drag-config';
|
|
7
|
+
import { PsDraggableGridClasses, PsDraggableGridLiftFrames } from '../constants/ps-draggable-grid';
|
|
8
|
+
import { usePsDragSensors } from '../hooks/use-ps-drag-sensors';
|
|
9
|
+
import { PsDragGrip } from './ps-drag-grip';
|
|
10
|
+
import { PsDragOverlay } from './ps-drag-overlay';
|
|
11
|
+
const PsDraggableGridHandle = ({ attributes, label, listeners, setActivatorNodeRef, }) => (_jsx("button", { ...attributes, ...listeners, "aria-label": `Move ${label}`, className: PsDraggableGridClasses.handle, ref: setActivatorNodeRef, title: `Move ${label}`, type: 'button', children: _jsx(PsDragGrip, {}) }));
|
|
26
12
|
const PsSortableGridItem = ({ className, index, item, renderItem, }) => {
|
|
27
13
|
const { attributes, isDragging, listeners, setActivatorNodeRef, setNodeRef, transform, transition, } = useSortable({ id: item.id });
|
|
28
14
|
const rendered = renderItem({
|
|
@@ -35,23 +21,14 @@ const PsSortableGridItem = ({ className, index, item, renderItem, }) => {
|
|
|
35
21
|
if (!rendered)
|
|
36
22
|
return null;
|
|
37
23
|
return (_jsx("div", { className: `${PsDraggableGridClasses.item} ${className} ${isDragging ? PsDraggableGridClasses.placeholder : ''}`, ref: setNodeRef, style: {
|
|
38
|
-
opacity: isDragging ?
|
|
24
|
+
opacity: isDragging ? PsDragConfig.placeholderOpacity : undefined,
|
|
39
25
|
transform: CSS.Translate.toString(transform),
|
|
40
26
|
transition,
|
|
41
27
|
}, children: rendered }));
|
|
42
28
|
};
|
|
43
29
|
export const PsDraggableGrid = ({ getItemClassName, items, onReorder, onReorderEnd, renderItem, }) => {
|
|
44
30
|
const [activeId, setActiveId] = useState(null);
|
|
45
|
-
const
|
|
46
|
-
useEffect(() => setIsMounted(true), []);
|
|
47
|
-
const sensors = useSensors(useSensor(MouseSensor, {
|
|
48
|
-
activationConstraint: { distance: PsDraggableGridConfig.activationDistance },
|
|
49
|
-
}), useSensor(TouchSensor, {
|
|
50
|
-
activationConstraint: {
|
|
51
|
-
delay: PsDraggableGridConfig.touchDelay,
|
|
52
|
-
tolerance: PsDraggableGridConfig.touchTolerance,
|
|
53
|
-
},
|
|
54
|
-
}), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }));
|
|
31
|
+
const sensors = usePsDragSensors();
|
|
55
32
|
const className = (item) => getItemClassName !== undefined ? getItemClassName(item) : '';
|
|
56
33
|
const activeIndex = items.findIndex((item) => item.id === activeId);
|
|
57
34
|
const activeItem = activeIndex >= 0 ? items[activeIndex] : null;
|
|
@@ -68,13 +45,13 @@ export const PsDraggableGrid = ({ getItemClassName, items, onReorder, onReorderE
|
|
|
68
45
|
if (onReorderEnd !== undefined)
|
|
69
46
|
onReorderEnd(nextItems);
|
|
70
47
|
};
|
|
71
|
-
return (_jsxs(DndContext, { collisionDetection: closestCenter, onDragCancel: () => setActiveId(null), onDragEnd: handleDragEnd, onDragStart: (event) => setActiveId(String(event.active.id)), sensors: sensors, children: [_jsx(SortableContext, { items: items.map((item) => item.id), strategy: rectSortingStrategy, children: items.map((item, index) => (_jsx(PsSortableGridItem, { className: className(item), index: index, item: item, renderItem: renderItem }, item.id))) }),
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
48
|
+
return (_jsxs(DndContext, { collisionDetection: closestCenter, onDragCancel: () => setActiveId(null), onDragEnd: handleDragEnd, onDragStart: (event) => setActiveId(String(event.active.id)), sensors: sensors, children: [_jsx(SortableContext, { items: items.map((item) => item.id), strategy: rectSortingStrategy, children: items.map((item, index) => (_jsx(PsSortableGridItem, { className: className(item), index: index, item: item, renderItem: renderItem }, item.id))) }), _jsx(PsDragOverlay, { className: PsDraggableGridClasses.lifted, frames: PsDraggableGridLiftFrames, children: activeItem !== null
|
|
49
|
+
? renderItem({
|
|
50
|
+
handle: _jsx(PsDraggableGridHandle, { label: activeItem.label }),
|
|
51
|
+
index: activeIndex,
|
|
52
|
+
isDragging: true,
|
|
53
|
+
isOverlay: true,
|
|
54
|
+
item: activeItem,
|
|
55
|
+
})
|
|
56
|
+
: null })] }));
|
|
80
57
|
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { DndContext, closestCenter, } from '@dnd-kit/core';
|
|
4
|
+
import { SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable';
|
|
5
|
+
import { CSS } from '@dnd-kit/utilities';
|
|
6
|
+
import { PsDragClasses, PsDragConfig, PsDragListLiftFrames } from '../constants/ps-drag-config';
|
|
7
|
+
import { usePsDragSensors } from '../hooks/use-ps-drag-sensors';
|
|
8
|
+
import { usePsReducedMotion } from '../hooks/use-ps-reduced-motion';
|
|
9
|
+
import { PsDragGrip } from './ps-drag-grip';
|
|
10
|
+
import { PsDragOverlay } from './ps-drag-overlay';
|
|
11
|
+
const PsSortableListHandle = ({ attributes, className, icon, label, listeners, setActivatorNodeRef, }) => (_jsx("button", { ...attributes, ...listeners, "aria-label": label, className: className === undefined ? PsDragClasses.handle : className, ref: setActivatorNodeRef, title: label, type: 'button', children: icon === undefined ? _jsx(PsDragGrip, {}) : icon }));
|
|
12
|
+
const PsSortableListRow = ({ className, handleClassName, handleIcon, getHandleLabel, index, isDisabled, item, renderItem, }) => {
|
|
13
|
+
const isReduced = usePsReducedMotion();
|
|
14
|
+
const { attributes, isDragging, listeners, setActivatorNodeRef, setNodeRef, transform, transition, } = useSortable({ disabled: isDisabled, id: item.id });
|
|
15
|
+
const rendered = renderItem({
|
|
16
|
+
handle: (_jsx(PsSortableListHandle, { attributes: attributes, className: handleClassName, icon: handleIcon, label: getHandleLabel(item.label), listeners: listeners, setActivatorNodeRef: setActivatorNodeRef })),
|
|
17
|
+
index,
|
|
18
|
+
isDragging,
|
|
19
|
+
isOverlay: false,
|
|
20
|
+
item,
|
|
21
|
+
});
|
|
22
|
+
if (!rendered)
|
|
23
|
+
return null;
|
|
24
|
+
return (_jsx("div", { className: `${PsDragClasses.listItem} ${className} ${isDragging ? PsDragClasses.placeholder : ''}`, ref: setNodeRef, style: {
|
|
25
|
+
opacity: isDragging ? PsDragConfig.placeholderOpacity : undefined,
|
|
26
|
+
transform: CSS.Translate.toString(transform),
|
|
27
|
+
transition: isReduced ? undefined : transition,
|
|
28
|
+
}, children: rendered }));
|
|
29
|
+
};
|
|
30
|
+
export const PsSortableList = ({ announcements: texts, className, getHandleLabel, getItemClassName, handleClassName, handleIcon, instructions, role, items, onMove, renderItem, }) => {
|
|
31
|
+
const [activeId, setActiveId] = useState(null);
|
|
32
|
+
const sensors = usePsDragSensors();
|
|
33
|
+
const activeIndex = items.findIndex((item) => item.id === activeId);
|
|
34
|
+
const activeItem = activeIndex >= 0 ? items[activeIndex] : null;
|
|
35
|
+
const itemClassName = (item) => getItemClassName === undefined ? '' : getItemClassName(item);
|
|
36
|
+
const groupOf = (id) => {
|
|
37
|
+
const found = items.find((item) => item.id === id);
|
|
38
|
+
return found === undefined ? undefined : found.groupKey;
|
|
39
|
+
};
|
|
40
|
+
const labelOf = (id) => {
|
|
41
|
+
const found = items.find((item) => item.id === id);
|
|
42
|
+
return found === undefined ? id : found.label;
|
|
43
|
+
};
|
|
44
|
+
const positionOf = (id) => items.findIndex((item) => item.id === id) + 1;
|
|
45
|
+
const announcements = {
|
|
46
|
+
onDragCancel: ({ active }) => texts.cancelled(labelOf(String(active.id))),
|
|
47
|
+
onDragEnd: ({ active, over }) => over === null
|
|
48
|
+
? texts.cancelled(labelOf(String(active.id)))
|
|
49
|
+
: texts.dropped(labelOf(String(active.id)), positionOf(String(over.id)), items.length),
|
|
50
|
+
onDragOver: ({ active, over }) => over === null
|
|
51
|
+
? undefined
|
|
52
|
+
: texts.moved(labelOf(String(active.id)), positionOf(String(over.id)), items.length),
|
|
53
|
+
onDragStart: ({ active }) => texts.lifted(labelOf(String(active.id)), positionOf(String(active.id)), items.length),
|
|
54
|
+
};
|
|
55
|
+
const handleDragEnd = ({ active, over }) => {
|
|
56
|
+
setActiveId(null);
|
|
57
|
+
if (over === null || active.id === over.id)
|
|
58
|
+
return;
|
|
59
|
+
const from = items.findIndex((item) => item.id === active.id);
|
|
60
|
+
const to = items.findIndex((item) => item.id === over.id);
|
|
61
|
+
if (from < 0 || to < 0 || groupOf(String(active.id)) !== groupOf(String(over.id)))
|
|
62
|
+
return;
|
|
63
|
+
onMove(String(active.id), from, to);
|
|
64
|
+
};
|
|
65
|
+
const activeGroup = activeItem === null ? undefined : activeItem.groupKey;
|
|
66
|
+
return (_jsxs(DndContext, { accessibility: { announcements, screenReaderInstructions: { draggable: instructions } }, collisionDetection: closestCenter, onDragCancel: () => setActiveId(null), onDragEnd: handleDragEnd, onDragStart: ({ active }) => setActiveId(String(active.id)), sensors: sensors, children: [_jsx(SortableContext, { items: items.map((item) => item.id), strategy: verticalListSortingStrategy, children: _jsx("div", { className: className, role: role, children: items.map((item, index) => (_jsx(PsSortableListRow, { className: itemClassName(item), getHandleLabel: getHandleLabel, handleClassName: handleClassName, handleIcon: handleIcon, index: index, isDisabled: activeItem !== null && item.groupKey !== activeGroup, item: item, renderItem: renderItem }, item.id))) }) }), _jsx(PsDragOverlay, { className: PsDragClasses.lifted, frames: PsDragListLiftFrames, children: activeItem !== null
|
|
67
|
+
? renderItem({
|
|
68
|
+
handle: (_jsx(PsSortableListHandle, { className: handleClassName, icon: handleIcon, label: getHandleLabel(activeItem.label) })),
|
|
69
|
+
index: activeIndex,
|
|
70
|
+
isDragging: true,
|
|
71
|
+
isOverlay: true,
|
|
72
|
+
item: activeItem,
|
|
73
|
+
})
|
|
74
|
+
: null })] }));
|
|
75
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const PsDragConfig = {
|
|
2
|
+
activationDistance: 6,
|
|
3
|
+
dropDuration: 220,
|
|
4
|
+
dropEasing: 'cubic-bezier(0.2, 0.8, 0.2, 1)',
|
|
5
|
+
liftDuration: 200,
|
|
6
|
+
liftEasing: 'cubic-bezier(0.2, 0.9, 0.3, 1.2)',
|
|
7
|
+
placeholderOpacity: '0.4',
|
|
8
|
+
touchDelay: 180,
|
|
9
|
+
touchTolerance: 6,
|
|
10
|
+
};
|
|
11
|
+
export const PsDragClasses = {
|
|
12
|
+
handle: 'ps-focus-ring inline-flex h-7 w-7 shrink-0 cursor-grab touch-none items-center justify-center rounded-full text-slate-400/70 transition hover:bg-white/36 hover:text-slate-600 active:cursor-grabbing dark:text-slate-300/55 dark:hover:bg-white/8 dark:hover:text-slate-100',
|
|
13
|
+
listItem: 'min-w-0',
|
|
14
|
+
lifted: 'cursor-grabbing rounded-xl bg-surface ring-1 ring-primary/30',
|
|
15
|
+
placeholder: 'outline-dashed outline-2 outline-offset-[-2px] outline-primary/35',
|
|
16
|
+
};
|
|
17
|
+
export const PsDragLiftFrames = [
|
|
18
|
+
{ boxShadow: '0 0 0 0 rgb(15 23 42 / 0)', transform: 'scale(1) rotate(0deg)' },
|
|
19
|
+
{
|
|
20
|
+
boxShadow: '0 28px 64px -18px rgb(15 23 42 / 0.5)',
|
|
21
|
+
transform: 'scale(1.035) rotate(-1.2deg)',
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
export const PsDragListLiftFrames = [
|
|
25
|
+
{ boxShadow: '0 0 0 0 rgb(15 23 42 / 0)', transform: 'scale(1)' },
|
|
26
|
+
{ boxShadow: '0 18px 40px -16px rgb(15 23 42 / 0.45)', transform: 'scale(1.015)' },
|
|
27
|
+
];
|
|
@@ -1,23 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
dropDuration: 220,
|
|
4
|
-
dropEasing: 'cubic-bezier(0.2, 0.8, 0.2, 1)',
|
|
5
|
-
liftDuration: 200,
|
|
6
|
-
liftEasing: 'cubic-bezier(0.2, 0.9, 0.3, 1.2)',
|
|
7
|
-
placeholderOpacity: '0.4',
|
|
8
|
-
touchDelay: 180,
|
|
9
|
-
touchTolerance: 6,
|
|
10
|
-
};
|
|
1
|
+
import { PsDragClasses, PsDragConfig, PsDragLiftFrames } from './ps-drag-config';
|
|
2
|
+
export const PsDraggableGridConfig = PsDragConfig;
|
|
11
3
|
export const PsDraggableGridClasses = {
|
|
12
|
-
handle:
|
|
4
|
+
handle: PsDragClasses.handle,
|
|
13
5
|
item: 'min-w-0 rounded-[1.7rem]',
|
|
14
6
|
lifted: 'cursor-grabbing rounded-[1.7rem] ring-1 ring-primary/30',
|
|
15
7
|
placeholder: 'rounded-[1.7rem] outline-dashed outline-2 outline-offset-[-2px] outline-primary/35',
|
|
16
8
|
};
|
|
17
|
-
export const PsDraggableGridLiftFrames =
|
|
18
|
-
{ boxShadow: '0 0 0 0 rgb(15 23 42 / 0)', transform: 'scale(1) rotate(0deg)' },
|
|
19
|
-
{
|
|
20
|
-
boxShadow: '0 28px 64px -18px rgb(15 23 42 / 0.5)',
|
|
21
|
-
transform: 'scale(1.035) rotate(-1.2deg)',
|
|
22
|
-
},
|
|
23
|
-
];
|
|
9
|
+
export const PsDraggableGridLiftFrames = PsDragLiftFrames;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { KeyboardSensor, MouseSensor, TouchSensor, useSensor, useSensors, } from '@dnd-kit/core';
|
|
2
|
+
import { sortableKeyboardCoordinates } from '@dnd-kit/sortable';
|
|
3
|
+
import { PsDragConfig } from '../constants/ps-drag-config';
|
|
4
|
+
export const usePsDragSensors = () => useSensors(useSensor(MouseSensor, {
|
|
5
|
+
activationConstraint: { distance: PsDragConfig.activationDistance },
|
|
6
|
+
}), useSensor(TouchSensor, {
|
|
7
|
+
activationConstraint: {
|
|
8
|
+
delay: PsDragConfig.touchDelay,
|
|
9
|
+
tolerance: PsDragConfig.touchTolerance,
|
|
10
|
+
},
|
|
11
|
+
}), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }));
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
export const usePsReducedMotion = () => {
|
|
3
|
+
const [isReduced, setIsReduced] = useState(false);
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
if (typeof window.matchMedia !== 'function')
|
|
6
|
+
return;
|
|
7
|
+
const query = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
8
|
+
const update = () => setIsReduced(query.matches);
|
|
9
|
+
update();
|
|
10
|
+
query.addEventListener('change', update);
|
|
11
|
+
return () => query.removeEventListener('change', update);
|
|
12
|
+
}, []);
|
|
13
|
+
return isReduced;
|
|
14
|
+
};
|
package/dist/esm/index.js
CHANGED
|
@@ -12,6 +12,9 @@ export * from './constants/ps-pallasoft-mark-config';
|
|
|
12
12
|
export * from './components/ps-card';
|
|
13
13
|
export * from './components/ps-client-only';
|
|
14
14
|
export * from './components/ps-draggable-grid';
|
|
15
|
+
export * from './components/ps-sortable-list';
|
|
16
|
+
export * from './constants/ps-drag-config';
|
|
17
|
+
export * from './models/ps-sortable-list';
|
|
15
18
|
export * from './components/ps-empty-state';
|
|
16
19
|
export * from './components/ps-fab';
|
|
17
20
|
export * from './components/ps-infinite-scroll';
|
|
@@ -126,3 +129,7 @@ export * from './models/ps-detail-list-item';
|
|
|
126
129
|
export * from './models/ps-start-panel-step';
|
|
127
130
|
export * from './models/ps-step-list-item';
|
|
128
131
|
export * from './models/ps-summary-item';
|
|
132
|
+
export * from './components/ps-drag-grip';
|
|
133
|
+
export * from './components/ps-drag-overlay';
|
|
134
|
+
export * from './hooks/use-ps-drag-sensors';
|
|
135
|
+
export * from './hooks/use-ps-reduced-motion';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.usePsDragSensors = void 0;
|
|
4
|
+
const core_1 = require("@dnd-kit/core");
|
|
5
|
+
const sortable_1 = require("@dnd-kit/sortable");
|
|
6
|
+
const ps_drag_config_1 = require("../constants/ps-drag-config");
|
|
7
|
+
const usePsDragSensors = () => (0, core_1.useSensors)((0, core_1.useSensor)(core_1.MouseSensor, {
|
|
8
|
+
activationConstraint: { distance: ps_drag_config_1.PsDragConfig.activationDistance },
|
|
9
|
+
}), (0, core_1.useSensor)(core_1.TouchSensor, {
|
|
10
|
+
activationConstraint: {
|
|
11
|
+
delay: ps_drag_config_1.PsDragConfig.touchDelay,
|
|
12
|
+
tolerance: ps_drag_config_1.PsDragConfig.touchTolerance,
|
|
13
|
+
},
|
|
14
|
+
}), (0, core_1.useSensor)(core_1.KeyboardSensor, { coordinateGetter: sortable_1.sortableKeyboardCoordinates }));
|
|
15
|
+
exports.usePsDragSensors = usePsDragSensors;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const usePsReducedMotion: () => boolean;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.usePsReducedMotion = void 0;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const usePsReducedMotion = () => {
|
|
6
|
+
const [isReduced, setIsReduced] = (0, react_1.useState)(false);
|
|
7
|
+
(0, react_1.useEffect)(() => {
|
|
8
|
+
if (typeof window.matchMedia !== 'function')
|
|
9
|
+
return;
|
|
10
|
+
const query = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
11
|
+
const update = () => setIsReduced(query.matches);
|
|
12
|
+
update();
|
|
13
|
+
query.addEventListener('change', update);
|
|
14
|
+
return () => query.removeEventListener('change', update);
|
|
15
|
+
}, []);
|
|
16
|
+
return isReduced;
|
|
17
|
+
};
|
|
18
|
+
exports.usePsReducedMotion = usePsReducedMotion;
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,9 @@ export * from './constants/ps-pallasoft-mark-config';
|
|
|
12
12
|
export * from './components/ps-card';
|
|
13
13
|
export * from './components/ps-client-only';
|
|
14
14
|
export * from './components/ps-draggable-grid';
|
|
15
|
+
export * from './components/ps-sortable-list';
|
|
16
|
+
export * from './constants/ps-drag-config';
|
|
17
|
+
export * from './models/ps-sortable-list';
|
|
15
18
|
export * from './components/ps-empty-state';
|
|
16
19
|
export * from './components/ps-fab';
|
|
17
20
|
export * from './components/ps-infinite-scroll';
|
|
@@ -126,3 +129,7 @@ export * from './models/ps-detail-list-item';
|
|
|
126
129
|
export * from './models/ps-start-panel-step';
|
|
127
130
|
export * from './models/ps-step-list-item';
|
|
128
131
|
export * from './models/ps-summary-item';
|
|
132
|
+
export * from './components/ps-drag-grip';
|
|
133
|
+
export * from './components/ps-drag-overlay';
|
|
134
|
+
export * from './hooks/use-ps-drag-sensors';
|
|
135
|
+
export * from './hooks/use-ps-reduced-motion';
|
package/dist/index.js
CHANGED
|
@@ -28,6 +28,9 @@ __exportStar(require("./constants/ps-pallasoft-mark-config"), exports);
|
|
|
28
28
|
__exportStar(require("./components/ps-card"), exports);
|
|
29
29
|
__exportStar(require("./components/ps-client-only"), exports);
|
|
30
30
|
__exportStar(require("./components/ps-draggable-grid"), exports);
|
|
31
|
+
__exportStar(require("./components/ps-sortable-list"), exports);
|
|
32
|
+
__exportStar(require("./constants/ps-drag-config"), exports);
|
|
33
|
+
__exportStar(require("./models/ps-sortable-list"), exports);
|
|
31
34
|
__exportStar(require("./components/ps-empty-state"), exports);
|
|
32
35
|
__exportStar(require("./components/ps-fab"), exports);
|
|
33
36
|
__exportStar(require("./components/ps-infinite-scroll"), exports);
|
|
@@ -142,3 +145,7 @@ __exportStar(require("./models/ps-detail-list-item"), exports);
|
|
|
142
145
|
__exportStar(require("./models/ps-start-panel-step"), exports);
|
|
143
146
|
__exportStar(require("./models/ps-step-list-item"), exports);
|
|
144
147
|
__exportStar(require("./models/ps-summary-item"), exports);
|
|
148
|
+
__exportStar(require("./components/ps-drag-grip"), exports);
|
|
149
|
+
__exportStar(require("./components/ps-drag-overlay"), exports);
|
|
150
|
+
__exportStar(require("./hooks/use-ps-drag-sensors"), exports);
|
|
151
|
+
__exportStar(require("./hooks/use-ps-reduced-motion"), exports);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { JSX } from 'react';
|
|
2
|
+
export interface PsSortableListItem {
|
|
3
|
+
groupKey?: string;
|
|
4
|
+
id: string;
|
|
5
|
+
label: string;
|
|
6
|
+
}
|
|
7
|
+
export interface PsSortableListAnnouncements {
|
|
8
|
+
cancelled: (label: string) => string;
|
|
9
|
+
dropped: (label: string, position: number, count: number) => string;
|
|
10
|
+
lifted: (label: string, position: number, count: number) => string;
|
|
11
|
+
moved: (label: string, position: number, count: number) => string;
|
|
12
|
+
}
|
|
13
|
+
export interface PsSortableListRenderOptions<TItem extends PsSortableListItem> {
|
|
14
|
+
handle: JSX.Element;
|
|
15
|
+
index: number;
|
|
16
|
+
isDragging: boolean;
|
|
17
|
+
isOverlay: boolean;
|
|
18
|
+
item: TItem;
|
|
19
|
+
}
|
|
20
|
+
export interface PsSortableListProps<TItem extends PsSortableListItem> {
|
|
21
|
+
announcements: PsSortableListAnnouncements;
|
|
22
|
+
className?: string;
|
|
23
|
+
role?: string;
|
|
24
|
+
getHandleLabel: (label: string) => string;
|
|
25
|
+
getItemClassName?: (item: TItem) => string;
|
|
26
|
+
handleClassName?: string;
|
|
27
|
+
handleIcon?: JSX.Element;
|
|
28
|
+
instructions: string;
|
|
29
|
+
items: TItem[];
|
|
30
|
+
onMove: (itemId: string, fromIndex: number, toIndex: number) => void;
|
|
31
|
+
renderItem: (options: PsSortableListRenderOptions<TItem>) => JSX.Element | null;
|
|
32
|
+
}
|