@hardanonymous/marquee-selector 0.0.1 → 0.0.3
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/README.md +3 -1
- package/examples/index.html +65 -0
- package/examples/package-lock.json +987 -0
- package/examples/package.json +14 -0
- package/examples/react/index.html +61 -0
- package/examples/react/main.js +109 -0
- package/examples/vanilla/index.html +58 -0
- package/examples/vanilla/main.js +67 -0
- package/examples/vue/index.html +70 -0
- package/examples/vue/main.js +72 -0
- package/package.json +6 -5
|
@@ -0,0 +1,61 @@
|
|
|
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.0" />
|
|
6
|
+
<title>Marquee Selector - React Example</title>
|
|
7
|
+
<script
|
|
8
|
+
crossorigin
|
|
9
|
+
src="https://unpkg.com/react@18/umd/react.development.js"
|
|
10
|
+
></script>
|
|
11
|
+
<script
|
|
12
|
+
crossorigin
|
|
13
|
+
src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"
|
|
14
|
+
></script>
|
|
15
|
+
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
|
16
|
+
<style>
|
|
17
|
+
body {
|
|
18
|
+
font-family: Arial, sans-serif;
|
|
19
|
+
padding: 20px;
|
|
20
|
+
}
|
|
21
|
+
.container {
|
|
22
|
+
position: relative;
|
|
23
|
+
width: 600px;
|
|
24
|
+
height: 400px;
|
|
25
|
+
border: 1px solid #ccc;
|
|
26
|
+
margin: 20px 0;
|
|
27
|
+
}
|
|
28
|
+
.item {
|
|
29
|
+
position: absolute;
|
|
30
|
+
width: 50px;
|
|
31
|
+
height: 50px;
|
|
32
|
+
background-color: #007bff;
|
|
33
|
+
border-radius: 4px;
|
|
34
|
+
display: flex;
|
|
35
|
+
align-items: center;
|
|
36
|
+
justify-content: center;
|
|
37
|
+
color: white;
|
|
38
|
+
font-weight: bold;
|
|
39
|
+
cursor: pointer;
|
|
40
|
+
}
|
|
41
|
+
.selected {
|
|
42
|
+
background-color: #28a745 !important;
|
|
43
|
+
}
|
|
44
|
+
</style>
|
|
45
|
+
</head>
|
|
46
|
+
<body>
|
|
47
|
+
<a
|
|
48
|
+
href="/"
|
|
49
|
+
style="
|
|
50
|
+
display: inline-block;
|
|
51
|
+
margin: 20px;
|
|
52
|
+
color: #007bff;
|
|
53
|
+
text-decoration: none;
|
|
54
|
+
"
|
|
55
|
+
>← Back to Examples</a
|
|
56
|
+
>
|
|
57
|
+
<div id="root"></div>
|
|
58
|
+
|
|
59
|
+
<script type="module" src="./main.js"></script>
|
|
60
|
+
</body>
|
|
61
|
+
</html>
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import "@hardanonymous/marquee-selector/style.css";
|
|
2
|
+
import MarqueeSelector from "@hardanonymous/marquee-selector";
|
|
3
|
+
|
|
4
|
+
const { useState, useEffect, useRef } = React;
|
|
5
|
+
|
|
6
|
+
function App() {
|
|
7
|
+
const containerRef = useRef(null);
|
|
8
|
+
const [items, setItems] = useState([]);
|
|
9
|
+
const [selectedCount, setSelectedCount] = useState(0);
|
|
10
|
+
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
// Create sample items
|
|
13
|
+
const newItems = [];
|
|
14
|
+
for (let i = 0; i < 20; i++) {
|
|
15
|
+
newItems.push({
|
|
16
|
+
id: i + 1,
|
|
17
|
+
x: Math.random() * 500,
|
|
18
|
+
y: Math.random() * 300,
|
|
19
|
+
selected: false,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
setItems(newItems);
|
|
23
|
+
|
|
24
|
+
// Initialize Marquee Selector
|
|
25
|
+
if (containerRef.current) {
|
|
26
|
+
const selector = new MarqueeSelector({
|
|
27
|
+
container: containerRef.current,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
selector.addTarget({
|
|
31
|
+
selector: ".item",
|
|
32
|
+
onSelectionStart: (target) => {
|
|
33
|
+
console.log("Selection started on:", target);
|
|
34
|
+
},
|
|
35
|
+
onSelectionChange: (selectedElements) => {
|
|
36
|
+
console.log("Selected elements:", selectedElements.length);
|
|
37
|
+
setItems((prevItems) =>
|
|
38
|
+
prevItems.map((item) => ({
|
|
39
|
+
...item,
|
|
40
|
+
selected: selectedElements.some(
|
|
41
|
+
(el) =>
|
|
42
|
+
el ===
|
|
43
|
+
containerRef.current.querySelector(
|
|
44
|
+
`[data-id="${item.id}"]`
|
|
45
|
+
)
|
|
46
|
+
),
|
|
47
|
+
}))
|
|
48
|
+
);
|
|
49
|
+
setSelectedCount(selectedElements.length);
|
|
50
|
+
},
|
|
51
|
+
onSelectionEnd: (selectedElements) => {
|
|
52
|
+
console.log(
|
|
53
|
+
"Selection ended with",
|
|
54
|
+
selectedElements.length,
|
|
55
|
+
"elements"
|
|
56
|
+
);
|
|
57
|
+
},
|
|
58
|
+
onClearClick: () => {
|
|
59
|
+
console.log("Selection cleared");
|
|
60
|
+
setItems((prevItems) =>
|
|
61
|
+
prevItems.map((item) => ({ ...item, selected: false }))
|
|
62
|
+
);
|
|
63
|
+
setSelectedCount(0);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
// Enable the marquee selector
|
|
67
|
+
selector.enable();
|
|
68
|
+
}
|
|
69
|
+
}, []);
|
|
70
|
+
|
|
71
|
+
const resetSelection = () => {
|
|
72
|
+
setItems((prevItems) =>
|
|
73
|
+
prevItems.map((item) => ({ ...item, selected: false }))
|
|
74
|
+
);
|
|
75
|
+
setSelectedCount(0);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
return React.createElement(
|
|
79
|
+
"div",
|
|
80
|
+
{ className: "app" },
|
|
81
|
+
React.createElement("h1", null, "Marquee Selector - React Example"),
|
|
82
|
+
React.createElement("p", null, "Drag to select multiple items:"),
|
|
83
|
+
React.createElement(
|
|
84
|
+
"div",
|
|
85
|
+
{ ref: containerRef, className: "container" },
|
|
86
|
+
items.map((item) =>
|
|
87
|
+
React.createElement(
|
|
88
|
+
"div",
|
|
89
|
+
{
|
|
90
|
+
key: item.id,
|
|
91
|
+
"data-id": item.id,
|
|
92
|
+
className: `item ${item.selected ? "selected" : ""}`,
|
|
93
|
+
style: { left: item.x, top: item.y },
|
|
94
|
+
},
|
|
95
|
+
item.id
|
|
96
|
+
)
|
|
97
|
+
)
|
|
98
|
+
),
|
|
99
|
+
React.createElement(
|
|
100
|
+
"button",
|
|
101
|
+
{ onClick: resetSelection },
|
|
102
|
+
"Reset Selection"
|
|
103
|
+
),
|
|
104
|
+
React.createElement("p", null, `Selected: ${selectedCount}`)
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const root = ReactDOM.createRoot(document.getElementById("root"));
|
|
109
|
+
root.render(React.createElement(App));
|
|
@@ -0,0 +1,58 @@
|
|
|
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.0" />
|
|
6
|
+
<title>Marquee Selector - Vanilla JS Example</title>
|
|
7
|
+
<style>
|
|
8
|
+
body {
|
|
9
|
+
font-family: Arial, sans-serif;
|
|
10
|
+
padding: 20px;
|
|
11
|
+
}
|
|
12
|
+
.container {
|
|
13
|
+
position: relative;
|
|
14
|
+
width: 600px;
|
|
15
|
+
height: 400px;
|
|
16
|
+
border: 1px solid #ccc;
|
|
17
|
+
margin: 20px 0;
|
|
18
|
+
}
|
|
19
|
+
.item {
|
|
20
|
+
position: absolute;
|
|
21
|
+
width: 50px;
|
|
22
|
+
height: 50px;
|
|
23
|
+
background-color: #007bff;
|
|
24
|
+
border-radius: 4px;
|
|
25
|
+
display: flex;
|
|
26
|
+
align-items: center;
|
|
27
|
+
justify-content: center;
|
|
28
|
+
color: white;
|
|
29
|
+
font-weight: bold;
|
|
30
|
+
cursor: pointer;
|
|
31
|
+
}
|
|
32
|
+
.selected {
|
|
33
|
+
background-color: #28a745 !important;
|
|
34
|
+
}
|
|
35
|
+
</style>
|
|
36
|
+
</head>
|
|
37
|
+
<body>
|
|
38
|
+
<a
|
|
39
|
+
href="/"
|
|
40
|
+
style="
|
|
41
|
+
display: inline-block;
|
|
42
|
+
margin-bottom: 10px;
|
|
43
|
+
color: #007bff;
|
|
44
|
+
text-decoration: none;
|
|
45
|
+
"
|
|
46
|
+
>← Back to Examples</a
|
|
47
|
+
>
|
|
48
|
+
<h1>Marquee Selector - Vanilla JS Example</h1>
|
|
49
|
+
<p>Drag to select multiple items:</p>
|
|
50
|
+
<div class="container" id="container">
|
|
51
|
+
<!-- Items will be added by JavaScript -->
|
|
52
|
+
</div>
|
|
53
|
+
<button onclick="resetSelection()">Reset Selection</button>
|
|
54
|
+
<p>Selected: <span id="selectedCount">0</span></p>
|
|
55
|
+
|
|
56
|
+
<script type="module" src="./main.js"></script>
|
|
57
|
+
</body>
|
|
58
|
+
</html>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import "@hardanonymous/marquee-selector/style.css";
|
|
2
|
+
import MarqueeSelector from "@hardanonymous/marquee-selector";
|
|
3
|
+
|
|
4
|
+
// Get container element
|
|
5
|
+
const container = document.getElementById("container");
|
|
6
|
+
|
|
7
|
+
// Create some sample items
|
|
8
|
+
for (let i = 0; i < 20; i++) {
|
|
9
|
+
const item = document.createElement("div");
|
|
10
|
+
item.className = "item";
|
|
11
|
+
item.textContent = i + 1;
|
|
12
|
+
item.setAttribute("data-id", (i + 1).toString());
|
|
13
|
+
item.style.left = Math.random() * 500 + "px";
|
|
14
|
+
item.style.top = Math.random() * 300 + "px";
|
|
15
|
+
container.appendChild(item);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Initialize Marquee Selector
|
|
19
|
+
const selector = new MarqueeSelector({
|
|
20
|
+
container: container,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
selector.addTarget({
|
|
24
|
+
selector: ".item",
|
|
25
|
+
onSelectionStart: (target) => {
|
|
26
|
+
console.log("Selection started on:", target);
|
|
27
|
+
},
|
|
28
|
+
onSelectionChange: (selectedElements) => {
|
|
29
|
+
console.log("Selected elements:", selectedElements.length);
|
|
30
|
+
// Remove previous selection
|
|
31
|
+
document.querySelectorAll(".selected").forEach((el) => {
|
|
32
|
+
el.classList.remove("selected");
|
|
33
|
+
});
|
|
34
|
+
// Add new selection
|
|
35
|
+
selectedElements.forEach((el) => {
|
|
36
|
+
el.classList.add("selected");
|
|
37
|
+
});
|
|
38
|
+
// Update selected count
|
|
39
|
+
document.getElementById("selectedCount").textContent = selectedElements.length;
|
|
40
|
+
},
|
|
41
|
+
onSelectionEnd: (selectedElements) => {
|
|
42
|
+
console.log(
|
|
43
|
+
"Selection ended with",
|
|
44
|
+
selectedElements.length,
|
|
45
|
+
"elements"
|
|
46
|
+
);
|
|
47
|
+
},
|
|
48
|
+
onClearClick: () => {
|
|
49
|
+
console.log("Selection cleared");
|
|
50
|
+
document.querySelectorAll(".selected").forEach((el) => {
|
|
51
|
+
el.classList.remove("selected");
|
|
52
|
+
});
|
|
53
|
+
document.getElementById("selectedCount").textContent = 0;
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Enable the marquee selector
|
|
58
|
+
selector.enable();
|
|
59
|
+
|
|
60
|
+
// Reset function
|
|
61
|
+
window.resetSelection = () => {
|
|
62
|
+
document.querySelectorAll(".selected").forEach((el) => {
|
|
63
|
+
el.classList.remove("selected");
|
|
64
|
+
});
|
|
65
|
+
document.getElementById("selectedCount").textContent = 0;
|
|
66
|
+
console.log("Selection reset");
|
|
67
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
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.0" />
|
|
6
|
+
<title>Marquee Selector - Vue Example</title>
|
|
7
|
+
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
|
|
8
|
+
<style>
|
|
9
|
+
body {
|
|
10
|
+
font-family: Arial, sans-serif;
|
|
11
|
+
padding: 20px;
|
|
12
|
+
}
|
|
13
|
+
.container {
|
|
14
|
+
position: relative;
|
|
15
|
+
width: 600px;
|
|
16
|
+
height: 400px;
|
|
17
|
+
border: 1px solid #ccc;
|
|
18
|
+
margin: 20px 0;
|
|
19
|
+
}
|
|
20
|
+
.item {
|
|
21
|
+
position: absolute;
|
|
22
|
+
width: 50px;
|
|
23
|
+
height: 50px;
|
|
24
|
+
background-color: #007bff;
|
|
25
|
+
border-radius: 4px;
|
|
26
|
+
display: flex;
|
|
27
|
+
align-items: center;
|
|
28
|
+
justify-content: center;
|
|
29
|
+
color: white;
|
|
30
|
+
font-weight: bold;
|
|
31
|
+
cursor: pointer;
|
|
32
|
+
}
|
|
33
|
+
.selected {
|
|
34
|
+
background-color: #28a745 !important;
|
|
35
|
+
}
|
|
36
|
+
</style>
|
|
37
|
+
</head>
|
|
38
|
+
<body>
|
|
39
|
+
<div id="app">
|
|
40
|
+
<a
|
|
41
|
+
href="/"
|
|
42
|
+
style="
|
|
43
|
+
display: inline-block;
|
|
44
|
+
margin-bottom: 10px;
|
|
45
|
+
color: #007bff;
|
|
46
|
+
text-decoration: none;
|
|
47
|
+
"
|
|
48
|
+
>← Back to Examples</a
|
|
49
|
+
>
|
|
50
|
+
<h1>Marquee Selector - Vue Example</h1>
|
|
51
|
+
<p>Drag to select multiple items:</p>
|
|
52
|
+
<div ref="container" class="container">
|
|
53
|
+
<div
|
|
54
|
+
v-for="item in items"
|
|
55
|
+
:key="item.id"
|
|
56
|
+
:data-id="item.id"
|
|
57
|
+
class="item"
|
|
58
|
+
:class="{ selected: item.selected }"
|
|
59
|
+
:style="{ left: item.x + 'px', top: item.y + 'px' }"
|
|
60
|
+
>
|
|
61
|
+
{{ item.id }}
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
<button @click="resetSelection">Reset Selection</button>
|
|
65
|
+
<p>Selected: {{ selectedCount }}</p>
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
<script type="module" src="./main.js"></script>
|
|
69
|
+
</body>
|
|
70
|
+
</html>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import "@hardanonymous/marquee-selector/style.css";
|
|
2
|
+
import MarqueeSelector from "@hardanonymous/marquee-selector";
|
|
3
|
+
|
|
4
|
+
const { createApp } = Vue;
|
|
5
|
+
|
|
6
|
+
createApp({
|
|
7
|
+
data() {
|
|
8
|
+
return {
|
|
9
|
+
items: [],
|
|
10
|
+
selectedCount: 0,
|
|
11
|
+
};
|
|
12
|
+
},
|
|
13
|
+
mounted() {
|
|
14
|
+
// Create sample items
|
|
15
|
+
for (let i = 0; i < 20; i++) {
|
|
16
|
+
this.items.push({
|
|
17
|
+
id: i + 1,
|
|
18
|
+
x: Math.random() * 500,
|
|
19
|
+
y: Math.random() * 300,
|
|
20
|
+
selected: false,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Initialize Marquee Selector
|
|
25
|
+
this.selector = new MarqueeSelector({
|
|
26
|
+
container: this.$refs.container,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
this.selector.addTarget({
|
|
30
|
+
selector: ".item",
|
|
31
|
+
onSelectionStart: (target) => {
|
|
32
|
+
console.log("Selection started on:", target);
|
|
33
|
+
},
|
|
34
|
+
onSelectionChange: (selectedElements) => {
|
|
35
|
+
console.log("Selected elements:", selectedElements.length);
|
|
36
|
+
// Update selection state
|
|
37
|
+
this.items.forEach((item) => {
|
|
38
|
+
const itemEl = this.$refs.container.querySelector(
|
|
39
|
+
`[data-id="${item.id}"]`
|
|
40
|
+
);
|
|
41
|
+
item.selected = selectedElements.includes(itemEl);
|
|
42
|
+
});
|
|
43
|
+
this.selectedCount = selectedElements.length;
|
|
44
|
+
},
|
|
45
|
+
onSelectionEnd: (selectedElements) => {
|
|
46
|
+
console.log(
|
|
47
|
+
"Selection ended with",
|
|
48
|
+
selectedElements.length,
|
|
49
|
+
"elements"
|
|
50
|
+
);
|
|
51
|
+
},
|
|
52
|
+
onClearClick: () => {
|
|
53
|
+
console.log("Selection cleared");
|
|
54
|
+
this.items.forEach((item) => {
|
|
55
|
+
item.selected = false;
|
|
56
|
+
});
|
|
57
|
+
this.selectedCount = 0;
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Enable the marquee selector
|
|
62
|
+
this.selector.enable();
|
|
63
|
+
},
|
|
64
|
+
methods: {
|
|
65
|
+
resetSelection() {
|
|
66
|
+
this.items.forEach((item) => {
|
|
67
|
+
item.selected = false;
|
|
68
|
+
});
|
|
69
|
+
this.selectedCount = 0;
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
}).mount("#app");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hardanonymous/marquee-selector",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "A framework-agnostic marquee selection library with drag & text selection protection",
|
|
5
5
|
"author": "hardanonymous <hard25670559@gmail.com>",
|
|
6
6
|
"publishConfig": {
|
|
@@ -21,13 +21,14 @@
|
|
|
21
21
|
"files": [
|
|
22
22
|
"dist",
|
|
23
23
|
"docs",
|
|
24
|
+
"examples",
|
|
24
25
|
"README.md",
|
|
25
26
|
"LICENSE"
|
|
26
27
|
],
|
|
27
28
|
"scripts": {
|
|
28
29
|
"build": "rollup -c",
|
|
29
30
|
"dev": "rollup -c -w",
|
|
30
|
-
"prepublishOnly": "npm run build"
|
|
31
|
+
"prepublishOnly": "rm -rf examples/node_modules && npm run build"
|
|
31
32
|
},
|
|
32
33
|
"keywords": [
|
|
33
34
|
"marquee",
|
|
@@ -44,12 +45,12 @@
|
|
|
44
45
|
"license": "MIT",
|
|
45
46
|
"repository": {
|
|
46
47
|
"type": "git",
|
|
47
|
-
"url": "https://github.com/
|
|
48
|
+
"url": "https://github.com/hard25670559/marquee-selector.git"
|
|
48
49
|
},
|
|
49
50
|
"bugs": {
|
|
50
|
-
"url": "https://github.com/
|
|
51
|
+
"url": "https://github.com/hard25670559/marquee-selection/issues"
|
|
51
52
|
},
|
|
52
|
-
"homepage": "https://github.
|
|
53
|
+
"homepage": "https://hard25670559.github.io/MarqueeSelectorVanillaJSExample",
|
|
53
54
|
"devDependencies": {
|
|
54
55
|
"@rollup/plugin-terser": "^0.4.4",
|
|
55
56
|
"@rollup/plugin-typescript": "^11.1.5",
|