@blockbite/libraries 0.11.6 → 0.12.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,19 @@
1
+ declare module '../@wordpress/element' {
2
+ export * from '@wordpress/element';
3
+ }
4
+
5
+ declare module '../@wordpress/element/jsx-runtime' {
6
+ export const jsx: any;
7
+ export const jsxs: any;
8
+ export const jsxDEV: any;
9
+ }
10
+
11
+ declare module 'react' {
12
+ import React = require('wp.element');
13
+ export = React;
14
+ }
15
+
16
+ declare module 'react/jsx-runtime' {
17
+ import * as ReactJSX from 'wp.element/jsx-runtime';
18
+ export = ReactJSX;
19
+ }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@blockbite/libraries",
3
3
  "title": "react-bundled-libraries",
4
- "version": "0.11.6",
5
- "website": "https://github.com/xachary/react-grid-drag-resize",
4
+ "version": "0.12.0",
5
+ "website": "",
6
6
  "sideEffects": false,
7
7
  "type": "module",
8
8
  "main": "./dist/libraries.cjs.js",
@@ -23,14 +23,19 @@
23
23
  "LICENSE"
24
24
  ],
25
25
  "dependencies": {
26
+ "@dnd-kit/core": "^6.3.1",
27
+ "@dnd-kit/sortable": "^10.0.0",
28
+ "@dnd-kit/utilities": "^3.2.2",
26
29
  "@tailwindcss/vite": "^4.1.11",
27
30
  "@vitejs/plugin-react": "^5.0.0",
31
+ "@wordpress/element": "^6.36.0",
28
32
  "allotment": "^1.20.4",
33
+ "classnames": "^2.5.1",
29
34
  "react-grid-drag-resize": "^0.12.4",
30
35
  "rollup-plugin-external-globals": "^0.13.0",
31
36
  "vite-plugin-dts": "^4.5.3",
32
- "@blockbite/shared-utils": "2.0.6",
33
- "@blockbite/types": "0.1.6"
37
+ "@blockbite/shared-utils": "2.1.0",
38
+ "@blockbite/types": "0.2.0"
34
39
  },
35
40
  "peerDependencies": {
36
41
  "tailwindcss": "^4.0.0",
@@ -0,0 +1,257 @@
1
+ import {
2
+ closestCenter,
3
+ DndContext,
4
+ DragOverlay,
5
+ KeyboardSensor,
6
+ PointerSensor,
7
+ useSensor,
8
+ useSensors,
9
+ type DragEndEvent,
10
+ type DragStartEvent,
11
+ type UniqueIdentifier,
12
+ } from '@dnd-kit/core';
13
+ import {
14
+ arrayMove,
15
+ SortableContext,
16
+ sortableKeyboardCoordinates,
17
+ useSortable,
18
+ verticalListSortingStrategy,
19
+ } from '@dnd-kit/sortable';
20
+ import { CSS } from '@dnd-kit/utilities';
21
+ import { useMemo, useState } from '@wordpress/element';
22
+ import classNames from 'classnames';
23
+
24
+ export type SortableListRenderCtx = {
25
+ /** Spread these on the element you want to use as the drag handle */
26
+ dragHandleProps: Record<string, any>;
27
+ /** True when this specific item is being dragged */
28
+ isDragging: boolean;
29
+ /** True when another item is being dragged over this one */
30
+ isDragOver: boolean;
31
+ };
32
+
33
+ export type SortableListProps<T> = {
34
+ items: T[];
35
+ onChange: (next: T[]) => void;
36
+
37
+ /** Must be stable across renders and reorders */
38
+ getId: (item: T) => UniqueIdentifier;
39
+
40
+ /** Render any component for the row */
41
+ renderItem: (item: T, ctx: SortableListRenderCtx) => React.ReactNode;
42
+
43
+ /** Optional: validate proposed new order; return string to block reorder */
44
+ validateReorder?: (next: T[]) => string | null;
45
+
46
+ /** Optional: render an error message somewhere */
47
+ renderError?: (msg: string) => React.ReactNode;
48
+
49
+ disabled?: boolean;
50
+
51
+ className?: string;
52
+ itemWrapperClassName?: string;
53
+ /** @deprecated No longer used with dnd-kit (uses CSS transforms instead) */
54
+ dragOverClassName?: string;
55
+ };
56
+
57
+ type SortableItemProps<T> = {
58
+ id: UniqueIdentifier;
59
+ item: T;
60
+ renderItem: SortableListProps<T>['renderItem'];
61
+ disabled: boolean;
62
+ itemWrapperClassName?: string;
63
+ activeId: UniqueIdentifier | null;
64
+ };
65
+
66
+ function SortableItem<T>({
67
+ id,
68
+ item,
69
+ renderItem,
70
+ disabled,
71
+ itemWrapperClassName,
72
+ activeId,
73
+ }: SortableItemProps<T>) {
74
+ const {
75
+ attributes,
76
+ listeners,
77
+ setNodeRef,
78
+ setActivatorNodeRef,
79
+ transform,
80
+ transition,
81
+ isDragging,
82
+ over,
83
+ } = useSortable({ id, disabled });
84
+
85
+ const style: React.CSSProperties = {
86
+ transform: CSS.Transform.toString(transform),
87
+ transition,
88
+ opacity: isDragging ? 0.5 : 1,
89
+ zIndex: isDragging ? 1 : 0,
90
+ };
91
+
92
+ const isDragOver = over?.id === id && activeId !== id;
93
+
94
+ // Create drag handle props that can be spread on any element
95
+ const dragHandleProps = {
96
+ ref: setActivatorNodeRef,
97
+ ...listeners,
98
+ ...attributes,
99
+ };
100
+
101
+ return (
102
+ <div
103
+ ref={setNodeRef}
104
+ style={style}
105
+ className={classNames(itemWrapperClassName)}
106
+ data-sortable-wrapper="true"
107
+ >
108
+ {renderItem(item, { dragHandleProps, isDragging, isDragOver })}
109
+ </div>
110
+ );
111
+ }
112
+
113
+ // Drag overlay item - rendered in a portal during drag
114
+ function DragOverlayItem<T>({
115
+ item,
116
+ renderItem,
117
+ itemWrapperClassName,
118
+ }: {
119
+ item: T;
120
+ renderItem: SortableListProps<T>['renderItem'];
121
+ itemWrapperClassName?: string;
122
+ }) {
123
+ // Dummy handle props for the overlay (not interactive)
124
+ const dragHandleProps: Record<string, any> = {};
125
+
126
+ return (
127
+ <div
128
+ className={classNames(itemWrapperClassName, 'bg-white')}
129
+ style={{
130
+ boxShadow: '0 4px 12px rgba(0,0,0,0.15)',
131
+ transform: 'scale(1.02)',
132
+ cursor: 'grabbing',
133
+ }}
134
+ >
135
+ {renderItem(item, {
136
+ dragHandleProps,
137
+ isDragging: true,
138
+ isDragOver: false,
139
+ })}
140
+ </div>
141
+ );
142
+ }
143
+
144
+ export function SortableList<T>(props: SortableListProps<T>) {
145
+ const {
146
+ items,
147
+ onChange,
148
+ getId,
149
+ renderItem,
150
+ validateReorder,
151
+ renderError,
152
+ disabled = false,
153
+ className,
154
+ itemWrapperClassName,
155
+ } = props;
156
+
157
+ const [activeId, setActiveId] = useState<UniqueIdentifier | null>(null);
158
+ const [error, setError] = useState<string | null>(null);
159
+
160
+ const ids = useMemo(() => items.map(getId), [items, getId]);
161
+
162
+ const sensors = useSensors(
163
+ useSensor(PointerSensor, {
164
+ activationConstraint: {
165
+ distance: 5, // 5px movement required before drag starts
166
+ },
167
+ }),
168
+ useSensor(KeyboardSensor, {
169
+ coordinateGetter: sortableKeyboardCoordinates,
170
+ })
171
+ );
172
+
173
+ const handleDragStart = (event: DragStartEvent) => {
174
+ setActiveId(event.active.id);
175
+ setError(null);
176
+ };
177
+
178
+ const handleDragEnd = (event: DragEndEvent) => {
179
+ const { active, over } = event;
180
+
181
+ setActiveId(null);
182
+
183
+ if (!over || active.id === over.id) {
184
+ return;
185
+ }
186
+
187
+ const oldIndex = ids.indexOf(active.id);
188
+ const newIndex = ids.indexOf(over.id);
189
+
190
+ if (oldIndex === -1 || newIndex === -1) {
191
+ return;
192
+ }
193
+
194
+ const next = arrayMove(items, oldIndex, newIndex);
195
+
196
+ if (validateReorder) {
197
+ const msg = validateReorder(next);
198
+ if (msg) {
199
+ setError(msg);
200
+ return;
201
+ }
202
+ }
203
+
204
+ setError(null);
205
+ onChange(next);
206
+ };
207
+
208
+ const handleDragCancel = () => {
209
+ setActiveId(null);
210
+ };
211
+
212
+ const activeItem =
213
+ activeId !== null ? items.find((item) => getId(item) === activeId) : null;
214
+
215
+ return (
216
+ <div className={className}>
217
+ {error && renderError ? renderError(error) : null}
218
+
219
+ <DndContext
220
+ sensors={sensors}
221
+ collisionDetection={closestCenter}
222
+ onDragStart={handleDragStart}
223
+ onDragEnd={handleDragEnd}
224
+ onDragCancel={handleDragCancel}
225
+ >
226
+ <SortableContext items={ids} strategy={verticalListSortingStrategy}>
227
+ <div className="flex flex-col gap-2">
228
+ {items.map((item) => {
229
+ const id = getId(item);
230
+ return (
231
+ <SortableItem
232
+ key={id}
233
+ id={id}
234
+ item={item}
235
+ renderItem={renderItem}
236
+ disabled={disabled}
237
+ itemWrapperClassName={itemWrapperClassName}
238
+ activeId={activeId}
239
+ />
240
+ );
241
+ })}
242
+ </div>
243
+ </SortableContext>
244
+
245
+ <DragOverlay>
246
+ {activeItem ? (
247
+ <DragOverlayItem
248
+ item={activeItem}
249
+ renderItem={renderItem}
250
+ itemWrapperClassName={itemWrapperClassName}
251
+ />
252
+ ) : null}
253
+ </DragOverlay>
254
+ </DndContext>
255
+ </div>
256
+ );
257
+ }
package/src/index.ts CHANGED
@@ -1,10 +1,8 @@
1
1
  import { Allotment } from 'allotment';
2
- import { GridDragResize } from 'react-grid-drag-resize';
2
+ import 'allotment/dist/style.css';
3
3
 
4
- export type { GridDragResizeProps as ExternalGridDragResizeProps } from 'react-grid-drag-resize';
5
-
6
- // provide both
7
- export { Allotment, GridDragResize };
8
- export default GridDragResize;
4
+ import { SortableList } from './Sortable.js';
5
+ export { Allotment, SortableList };
9
6
 
10
7
  export type { AllotmentProps as ExternalAllotmentProps } from 'allotment';
8
+ export type { SortableListProps as ExternalSortableListProps } from './Sortable.js';
@@ -0,0 +1,19 @@
1
+ declare module 'wp.element' {
2
+ export * from '@wordpress/element';
3
+ }
4
+
5
+ declare module 'wp.element/jsx-runtime' {
6
+ export const jsx: any;
7
+ export const jsxs: any;
8
+ export const jsxDEV: any;
9
+ }
10
+
11
+ declare module 'react' {
12
+ import React = require('wp.element');
13
+ export = React;
14
+ }
15
+
16
+ declare module 'react/jsx-runtime' {
17
+ import * as ReactJSX from 'wp.element/jsx-runtime';
18
+ export = ReactJSX;
19
+ }