Skip to content

Commit e9ebe2f

Browse files
author
Hesam Bahrami
authored
chore: release 4.1.0 (#14)
* docs: improving the readme file (#13) * feat: improving styling capability (#12)
1 parent 03374bc commit e9ebe2f

File tree

8 files changed

+214
-22
lines changed

8 files changed

+214
-22
lines changed

README.md

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,39 @@
11
# Nested Sort
22

3-
A JavaScript library to create a nested list of elements
3+
Nested Sort is a vanilla JavaScript library, without any dependencies, which helps you to sort a nested list of items via drag and drop. Unfortunately, it does not support touch screens yet.
4+
5+
![](demo.gif)
6+
7+
## Docs
8+
9+
[https://gilgaz.com/demo/nested-sort](https://gilgaz.com/demo/nested-sort)
410

511
## Download
612

713
* [CDN copies](https://www.jsdelivr.com/package/npm/nested-sort) [![](https://data.jsdelivr.com/v1/package/npm/nested-sort/badge)](https://www.jsdelivr.com/package/npm/nested-sort)
814

9-
1015
## Installation
1116

1217
Using npm:
1318
```shell
14-
$ npm i nested-sort
19+
$ npm install nested-sort
1520
```
1621

17-
## Developer environment requirements
22+
Using yarn:
23+
```shell
24+
$ yarn add nested-sort
25+
```
26+
27+
## Contribution
28+
29+
### Developer environment requirements
1830

1931
To run this project, you will need:
2032

2133
- Node.js >= v10.5.0, use nvm - [install instructions](https://github.com/creationix/nvm#install-script)
2234
- Yarn >= v1.7.0 - [install instructions ("Alternatives" tab)](https://yarnpkg.com/en/docs/install#alternatives-rc)
2335

24-
## Running tests
36+
### Running tests
2537

2638
```sh
2739
yarn
@@ -30,7 +42,7 @@ yarn test --watch
3042
yarn test:coverage
3143
```
3244

33-
## Dev mode
45+
### Dev mode
3446

3547
When developing you can run:
3648

@@ -40,10 +52,4 @@ yarn watch
4052

4153
This will regenerate the build files each time a source file is changed and serve on http://127.0.0.1:5000.
4254

43-
### Previewing umd build in the browser
44-
45-
If your package works in the browser, you can open `dev/index.html` to try it out.
46-
47-
## Demo
48-
49-
There are some samples in the `dev` folder. In order to see them in action, first run `yarn watch` and then navigate to: `http://127.0.0.1:5000/dev/`
55+
You can navigate to http://127.0.0.1:5000/dev/ in order to see the samples.

demo.gif

4.35 MB
Loading

dev/css/main.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,11 @@ body {
2727
.nested-sort .ns-targeted {
2828
outline: 2px solid green;
2929
}
30+
31+
.list-group .ns-dragged {
32+
background-color: rgb(255, 255, 115);
33+
}
34+
35+
.list-group .ns-targeted {
36+
background-color: rgb(115, 255, 117);
37+
}

dev/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ <h1>Samples</h1>
1818
<li><a href="server-rendered-multiple-lists.html" target="_blank">Server-rendered Multiple Lists</a></li>
1919
<li><a href="data-driven-list.html" target="_blank">Data-driven List</a></li>
2020
<li><a href="mapped-data-driven-list.html" target="_blank">Mapped Data-driven List</a></li>
21+
<li><a href="styling-data-driven-list.html" target="_blank">Styling</a></li>
2122
</ol>
2223

2324
</div>

dev/styling-data-driven-list.html

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
7+
<title>Nested Sort Styling</title>
8+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
9+
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap" rel="stylesheet">
10+
<link href="css/main.css" rel="stylesheet">
11+
</head>
12+
<body>
13+
14+
<div class="container">
15+
<h1>Styling</h1>
16+
17+
<p>The main goal is to create a tree-like list of nested items. You should be able to achieve that by simply dragging and dropping the items using your mouse. Touch screens are not supported yet! 😐</p>
18+
19+
<p>
20+
You can use the listClassNames and listItemClassNames props on the Config object to assign custom class names to
21+
your list and list items. This helps with integrating your preferred front-end toolkit styling into your
22+
Nested Sort lists. Below, you can see an example for Twitter Bootstrap v4 styling:
23+
</p>
24+
25+
<h2>Twitter Bootstrap [Data-driven List]</h2>
26+
<div id="bootstrap"></div>
27+
28+
</div>
29+
30+
<!-- Scripts -->
31+
<script src="../dist/nested-sort.umd.js"></script>
32+
<script>
33+
(function() {
34+
const data = [
35+
{ id: 1, text: 'One' },
36+
{ id: 11, text: 'One-One', parent: 1 },
37+
{ id: 2, text: 'Two' },
38+
{ id: 3, text: 'Three' },
39+
{ id: 12, text: 'One-Two', parent: 1 },
40+
{ id: 111, text: 'One-One-One', parent: 11 },
41+
{ id: 112, text: 'One-One-Two', parent: 11 },
42+
{ id: 113, text: 'One-One-Three', parent: 11 },
43+
]
44+
45+
new NestedSort({
46+
actions: {
47+
onDrop: function (data) {
48+
console.log(data)
49+
}
50+
},
51+
data: data,
52+
el: '#bootstrap',
53+
listClassNames: ['list-group'],
54+
listItemClassNames: ['list-group-item']
55+
});
56+
})();
57+
</script>
58+
</body>
59+
</html>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nested-sort",
3-
"version": "4.0.0",
3+
"version": "4.1.0",
44
"author": "Hesam Bahrami (Genzo)",
55
"description": "A JavaScript library to create a nested list of elements",
66
"main": "dist/nested-sort.cjs.js",

src/main.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class NestedSort {
99
* @param {number} droppingEdge
1010
* @param {string} el
1111
* @param {array|string} listClassNames
12+
* @param {array|string} listItemClassNames
1213
* @param {object} [propertyMap={}]
1314
*/
1415
constructor({
@@ -17,6 +18,7 @@ class NestedSort {
1718
droppingEdge = 15,
1819
el,
1920
listClassNames,
21+
listItemClassNames,
2022
propertyMap = {}
2123
} = {}) {
2224
this.data = data;
@@ -27,6 +29,7 @@ class NestedSort {
2729
this.draggedNode = null;
2830
this.targetedNode = null;
2931
this.listClassNames = this.createListClassNamesArray(listClassNames)
32+
this.listItemClassNames = this.createListClassNamesArray(listItemClassNames)
3033
this.propertyMap = propertyMap
3134
this.actions = {
3235
onDrop
@@ -101,7 +104,16 @@ class NestedSort {
101104
}
102105

103106
addListAttributes() {
104-
this.getSortableList().classList.add(...this.listClassNames)
107+
const list = this.getSortableList()
108+
109+
list.classList.add(...this.listClassNames)
110+
list.querySelectorAll('ul').forEach(ul => {
111+
ul.classList.add(...this.listClassNames)
112+
})
113+
114+
list.querySelectorAll('li').forEach(li => {
115+
li.classList.add(...this.listItemClassNames)
116+
})
105117
}
106118

107119
initDragAndDrop() {
@@ -339,8 +351,8 @@ class NestedSort {
339351
}
340352

341353
initPlaceholderList() {
342-
this.placeholderUl = document.createElement('ul');
343-
this.placeholderUl.classList.add(this.classNames.placeholder);
354+
this.placeholderUl = document.createElement('ul')
355+
this.placeholderUl.classList.add(this.classNames.placeholder, ...this.listClassNames)
344356
}
345357

346358
getPlaceholderList() {

src/main.test.js

Lines changed: 111 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,113 @@
11
import NestedSort from './main'
22

3-
describe('sample', () => {
4-
it('should work', () => {
5-
expect(true).toBeTruthy();
6-
});
7-
});
3+
describe('NestedSort', () => {
4+
const dynamicListWrapperId = 'dynamic-list-wrapper-id'
5+
6+
beforeEach(() => {
7+
document.body.innerHTML = `<div id="${dynamicListWrapperId}"></div>`
8+
})
9+
10+
describe('How it deals with List Class Names', () => {
11+
it('should convert the listClassNames prop on the initialisation and assign it to this.listClassNames', () => {
12+
[
13+
'class1 class2',
14+
['class1', 'class2'],
15+
].forEach(listClassNames => {
16+
const ns = new NestedSort({
17+
data: [
18+
{ id: 1, text: 'Item 1' }
19+
],
20+
el: `#${dynamicListWrapperId}`,
21+
listClassNames,
22+
})
23+
24+
expect(ns.listClassNames).toEqual([
25+
'class1',
26+
'class2',
27+
])
28+
})
29+
})
30+
31+
it('should assign the class names to the main list and all the nested ones', () => {
32+
const listClassNames = ['class1', 'class2']
33+
const ns = new NestedSort({
34+
data: [
35+
{ id: 1, text: 'Item 1' },
36+
{ id: 11, text: 'Item 1-1', parent: 1 },
37+
{ id: 2, text: 'Item 2' },
38+
{ id: 21, text: 'Item 2-1', parent: 2 },
39+
{ id: 3, text: 'Item 3' },
40+
],
41+
el: `#${dynamicListWrapperId}`,
42+
listClassNames,
43+
})
44+
45+
const list = ns.getSortableList()
46+
const nestedLists = list.querySelectorAll('ul')
47+
const lists = [
48+
list,
49+
...nestedLists
50+
]
51+
52+
expect(nestedLists.length).toBe(2)
53+
lists.forEach(ul => {
54+
expect(Object.values(ul.classList)).toEqual(listClassNames)
55+
})
56+
})
57+
58+
it('should assign the class names to the placeholder list when initialising it', () => {
59+
const listClassNames = ['class1', 'class2']
60+
const ns = new NestedSort({
61+
data: [
62+
{ id: 1, text: 'Item 1' }
63+
],
64+
el: `#${dynamicListWrapperId}`,
65+
listClassNames,
66+
})
67+
68+
ns.initPlaceholderList()
69+
70+
expect(ns.placeholderUl.nodeName).toBe('UL')
71+
expect(Object.values(ns.placeholderUl.classList)).toEqual(expect.arrayContaining(listClassNames))
72+
})
73+
})
74+
75+
describe('How it deals with List Item Class Names', () => {
76+
it('should convert the listItemClassNames prop on the initialisation and assign it to this.listItemClassNames', () => {
77+
[
78+
'class1 class2',
79+
['class1', 'class2'],
80+
].forEach(listItemClassNames => {
81+
const ns = new NestedSort({
82+
data: [
83+
{ id: 1, text: 'Item 1' }
84+
],
85+
el: `#${dynamicListWrapperId}`,
86+
listItemClassNames,
87+
})
88+
expect(ns.listItemClassNames).toEqual([
89+
'class1',
90+
'class2',
91+
])
92+
})
93+
})
94+
95+
it('should assign the listItemClassNames to all the list items', () => {
96+
const listItemClassNames = ['class1', 'class2']
97+
const ns = new NestedSort({
98+
data: [
99+
{ id: 1, text: 'Item 1' },
100+
{ id: 2, text: 'Item 2' },
101+
{ id: 3, text: 'Item 3' },
102+
],
103+
el: `#${dynamicListWrapperId}`,
104+
listItemClassNames,
105+
})
106+
107+
const list = ns.getSortableList()
108+
list.querySelectorAll('li').forEach(li => {
109+
expect(Object.values(li.classList)).toEqual(listItemClassNames)
110+
})
111+
})
112+
})
113+
})

0 commit comments

Comments
 (0)