@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.
@@ -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 react_dom_1 = require("react-dom");
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 liftCard = (element) => {
12
- if (element === null)
13
- return;
14
- element.animate(ps_draggable_grid_1.PsDraggableGridLiftFrames, {
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 ? ps_draggable_grid_1.PsDraggableGridConfig.placeholderOpacity : undefined,
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 [isMounted, setIsMounted] = (0, react_1.useState)(false);
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))) }), isMounted
75
- ? (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)(core_1.DragOverlay, { dropAnimation: dropAnimation, children: activeItem !== null ? ((0, jsx_runtime_1.jsx)("div", { className: ps_draggable_grid_1.PsDraggableGridClasses.lifted, ref: liftCard, children: renderItem({
76
- handle: (0, jsx_runtime_1.jsx)(PsDraggableGridHandle, { label: activeItem.label }),
77
- index: activeIndex,
78
- isDragging: true,
79
- isOverlay: true,
80
- item: activeItem,
81
- }) })) : null }), document.body)
82
- : null] }));
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
- exports.PsDraggableGridConfig = {
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
- };
4
+ const ps_drag_config_1 = require("./ps-drag-config");
5
+ exports.PsDraggableGridConfig = ps_drag_config_1.PsDragConfig;
14
6
  exports.PsDraggableGridClasses = {
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',
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 { useEffect, useState } from 'react';
3
- import { DndContext, DragOverlay, KeyboardSensor, MouseSensor, TouchSensor, closestCenter, defaultDropAnimationSideEffects, useSensor, useSensors, } from '@dnd-kit/core';
4
- import { SortableContext, arrayMove, rectSortingStrategy, sortableKeyboardCoordinates, useSortable, } from '@dnd-kit/sortable';
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 { createPortal } from 'react-dom';
7
- import { PsDraggableGridClasses, PsDraggableGridConfig, PsDraggableGridLiftFrames, } from '../constants/ps-draggable-grid';
8
- const liftCard = (element) => {
9
- if (element === null)
10
- return;
11
- element.animate(PsDraggableGridLiftFrames, {
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 ? PsDraggableGridConfig.placeholderOpacity : undefined,
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 [isMounted, setIsMounted] = useState(false);
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))) }), isMounted
72
- ? createPortal(_jsx(DragOverlay, { dropAnimation: dropAnimation, children: activeItem !== null ? (_jsx("div", { className: PsDraggableGridClasses.lifted, ref: liftCard, children: renderItem({
73
- handle: _jsx(PsDraggableGridHandle, { label: activeItem.label }),
74
- index: activeIndex,
75
- isDragging: true,
76
- isOverlay: true,
77
- item: activeItem,
78
- }) })) : null }), document.body)
79
- : null] }));
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
- export const PsDraggableGridConfig = {
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
- };
1
+ import { PsDragClasses, PsDragConfig, PsDragLiftFrames } from './ps-drag-config';
2
+ export const PsDraggableGridConfig = PsDragConfig;
11
3
  export const PsDraggableGridClasses = {
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',
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,2 @@
1
+ import { type SensorDescriptor, type SensorOptions } from '@dnd-kit/core';
2
+ export declare const usePsDragSensors: () => SensorDescriptor<SensorOptions>[];
@@ -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
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pallasoft/ps-core-components",
3
- "version": "2.22.1",
3
+ "version": "2.23.0",
4
4
  "private": false,
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/esm/index.js",