Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

enhance: Introduce Dokan Draggable/Sortable List Component. #2521

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f177dae
feat: introduce dataviews from dokan free.
MdAsifHossainNadim Dec 31, 2024
eefed6b
feat: introduce dataviews from dokan free.
MdAsifHossainNadim Jan 1, 2025
29c723d
revert: add dokan category comission js.
MdAsifHossainNadim Jan 1, 2025
b423324
update: remove category commission js updates.
MdAsifHossainNadim Jan 1, 2025
5e00deb
remove: revert component package js file.
MdAsifHossainNadim Jan 1, 2025
cb605ad
remove: dokan sidebar class from data view table.
MdAsifHossainNadim Jan 1, 2025
a3852e8
enhance: update dataviews doc.
MdAsifHossainNadim Jan 1, 2025
4915962
update: filter naming convension for dataviews property.
MdAsifHossainNadim Jan 2, 2025
f3d3cc2
remove: module federation node package from json file.
MdAsifHossainNadim Jan 2, 2025
0f89a6b
remove: example dataviews table usage component.
MdAsifHossainNadim Jan 2, 2025
c8bb6e1
remove: example dataviews table usage component.
MdAsifHossainNadim Jan 2, 2025
ec87691
update: button class name for color scheme customizer.
MdAsifHossainNadim Jan 3, 2025
68c108c
update: split webpack entries, use change-case for namespace cases, h…
MdAsifHossainNadim Jan 6, 2025
36d3b9a
Merge branch 'update/vendor-dashboard-structure' into enhance/introdu…
MdAsifHossainNadim Jan 6, 2025
f1dd3df
update: introduce utilities directory, make exporter from dokan free …
MdAsifHossainNadim Jan 7, 2025
cca9989
update: routing folder naming convesional stuff.
MdAsifHossainNadim Jan 8, 2025
6d2d608
update: add component and utilities accessor doc for dokan free.
MdAsifHossainNadim Jan 8, 2025
a8fb22b
Add router param
Aunshon Jan 14, 2025
c84d06d
Merge branch 'refs/heads/update/vendor-dashboard-structure' into enha…
MdAsifHossainNadim Jan 14, 2025
d524e67
fix: add file exists check before register components scripts.
MdAsifHossainNadim Jan 14, 2025
d6d63ed
revert: remove default config from webpack entries.
MdAsifHossainNadim Jan 14, 2025
c12dd7b
Merge branch 'refs/heads/update/vendor-dashboard-structure' into enha…
MdAsifHossainNadim Jan 15, 2025
c7746bc
enhance: Introduce dokan Draggable/Sortable list component.
MdAsifHossainNadim Jan 20, 2025
90e0960
Merge branch 'refs/heads/update/vendor-dashboard-structure' into enha…
MdAsifHossainNadim Jan 20, 2025
bf39b77
revert: remove viewport dimension hook.
MdAsifHossainNadim Jan 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 192 additions & 0 deletions docs/frontend/sortable-list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
# Dokan Sortable List Component Documentation

- [Introduction](#introduction)
- [Data Structures](#data-structures)
- [Important Dependencies](#important-dependencies)
- [Quick Overview](#quick-overview)
- [Key Features](#key-features)
- [Component Properties](#component-properties)

## Introduction
The Dokan `SortableList` component provide a `flexible` and `reusable` `drag-and-drop` interface for managing `sortable lists`, `grids`, and `horizontal` layouts. Built on top of `@dnd-kit`, these components offer seamless integration with Dokan's existing component ecosystem.

## Data Structures
The `SortableList` component accommodates an `array` data type for its `items` property, which can follow `three primary array data structure patterns`:

### 1. Simple Array
Basic array of `primitive` values without additional `properties`.

```tsx
const simpleItems = [
__( 'Item 1', 'dokan-lite' ),
__( 'Item 2', 'dokan-lite' ),
__( 'Item 3', 'dokan-lite' )
];

const handleOrderUpdate = ( updatedItems ) => {
console.log( updatedItems ); // Get updated items array.
// Handle any additional logic after order update
};

<SortableList
items={ simpleItems }
onChange={ handleOrderUpdate }
namespace={ 'dokan-sortable-list' } // Unique namespace
renderItem={ ( item ) => (
<div className='p-4 bg-white shadow rounded'>
{ item }
</div>
)}
...
/>
```

### 2. Array of Objects (Without Order)
`Array of objects` with basic properties but `no explicit order tracking`.

```tsx
const objectItems = [
{ id: 1, name: __( 'Item 1', 'dokan-lite' ) },
{ id: 2, name: __( 'Item 2', 'dokan-lite' ) },
{ id: 3, name: __( 'Item 3', 'dokan-lite' ) }
];

const handleOrderUpdate = ( updatedItems ) => {
console.log( updatedItems ); // Get updated items array.
// Handle any additional logic after order update
};

<SortableList
items={ objectItems }
onChange={ handleOrderUpdate }
namespace={ 'dokan-sortable-list' } // Unique namespace
renderItem={ ( item ) => (
<div className='p-4 bg-white shadow rounded'>
{ item.name }
</div>
)}
...
/>
```

### 3. Array of Objects (With Order)
`Array of objects` that include an order property for `explicit order tracking`.

```tsx
const orderedItems = [
{ id: 1, title: 'First Task', content: __( 'Do something', 'dokan-lite' ), sort_order: 1 },
{ id: 2, title: 'Second Task', content: __( 'Do something else', 'dokan-lite' ), sort_order: 2 },
{ id: 3, title: 'Third Task', content: __( 'Another task', 'dokan-lite' ), sort_order: 3 }
];

const handleOrderUpdate = ( updatedItems ) => {
console.log( updatedItems ); // Get updated items array.
// Handle any additional logic after order update
};

<SortableList
items={ orderedItems }
orderProperty='sort_order'
onChange={ handleOrderUpdate }
namespace={ 'dokan-sortable-list' } // Unique namespace
renderItem={ ( item ) => (
<div className='p-4 bg-white shadow rounded'>
<h3>{ item.title }</h3>
<p>{ item.content }</p>
<span>{ item.sort_order }</span>
</div>
)}
...
/>
```

## Important Dependencies
For both `Dokan Free and Pro` versions, we must register the `dokan-react-components` dependency when using `global` components.

## Quick Overview

#### Step 1: Import the Required Components

```tsx
import { useState } from '@wordpress/element';
import SortableList from '@/components/sortable-list';
```

#### Step 2: Set Up Your State Management

```tsx
// DS-1: Example for single array
// const [ items, setItems ] = useState( [ 1, 2, 3, 4, 5 ] ); // Example for single array

// DS-2: Example for single array of objects without ordering.
// const [ items, setItems ] = useState([
// { id: 1, name: 'Item 1' },
// { id: 2, name: 'Item 2' },
// { id: 3, name: 'Item 3' },
// ]);

// DS-3: Example for single array of objects with ordering.
const [ items, setItems ] = useState([
{ id: 1, title: 'First Task', content: 'Do something', sort_order: 1 },
{ id: 2, title: 'Second Task', content: 'Do something else', sort_order: 2 },
]);

const handleOrderUpdate = ( updatedItems ) => {
setItems( updatedItems );
// Handle any additional logic after order update
};
```

#### Step 3: Implement the Render Function

```tsx
const renderItem = ( item ) => (
<div className="p-4 bg-white shadow rounded border">
<h3 className="font-bold">{ item.title }</h3>
<p className="text-gray-600">{ item.content }</p>
</div>
);
```

#### Step 4: Use the SortableList Component

```tsx
<SortableList
items={ items }
namespace="your-unique-namespace"
onChange={ handleOrderUpdate }
renderItem={ renderItem }
strategy="horizontal" // default is "vertical", other options are "grid".
className="w-full max-w-md mx-auto"
orderProperty="sort_order"
/>
```

### Key Features

- **Drag and Drop Interface**
- **Multiple Layouts (Vertical List, Horizontal List, Grid Layout)**
- **Sorting Order Management**
- **Customizable Items**

### Component Properties

#### SortableList Props

**items (array):** The data array to be `rendered` in the `sortable` list. Can be an array of `single items`, array of `objects` with or without `ordering`.

**namespace (string):** Unique identifier for the `sortable container`. Used for filtering and slots.

**onChange (function):** Callback function triggered when `item order changes`. Receives the `updated items array` as an argument.

**renderItem (function):** Function to `render individual items`. Receives the `item` as an argument.

**orderProperty (string):** Property name used to track item `order` in `array of objects`.

**strategy (string):** `Layout strategy` for the `list`. Options are `vertical`, `horizontal`, and `grid`.

**className (string):** `Additional CSS classes` for the `container`.

**gridColumns (string):** `Number of columns` for `grid layout`. Default is `4`.

**id (string | number):** `Unique identifier` for the `sortable item`. Optional property.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
"wp-readme-to-markdown": "^1.0.1"
},
"dependencies": {
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@getdokan/dokan-ui": "^1.0.18",
"@wordpress/dataviews": "^4.10.0",
"@wordpress/dom-ready": "^4.9.0",
Expand Down
1 change: 1 addition & 0 deletions src/components/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default as DataViews } from './dataviews/DataViewTable';
export { default as SortableList } from './sortable-list';

export {
DataForm,
Expand Down
32 changes: 32 additions & 0 deletions src/components/sortable-list/SortableItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useSortable } from '@dnd-kit/sortable';

interface SortableItemProps {
id: string | number;
renderItem: () => JSX.Element;
}

const SortableItem = ( { id, renderItem }: SortableItemProps ) => {
const {
attributes,
listeners,
setNodeRef,
transform,
transition,
isDragging,
} = useSortable( { id } );

const style = {
transform: transform ? `translate3d(${transform.x}px, ${transform.y}px, 0)` : undefined,
opacity: isDragging ? 0.6 : 1,
touchAction: 'none',
transition,
};

return (
<div ref={ setNodeRef } style={{ ...style }} { ...attributes } { ...listeners }>
{ renderItem ? renderItem( id ) : id }
</div>
);
};

export default SortableItem;
Loading
Loading