@wxn0brp/nya-dock 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 CHANGED
@@ -1,4 +1,4 @@
1
- # Nyadock
1
+ # NyaDock
2
2
 
3
3
  A dock panel component library. Currently in early development stage.
4
4
 
@@ -14,12 +14,12 @@ A dock panel component library. Currently in early development stage.
14
14
 
15
15
  ## Demo
16
16
 
17
- [https://wxn0brp.github.io/Nyadock/demo](https://wxn0brp.github.io/Nyadock/demo)
17
+ [https://wxn0brp.github.io/NyaDock/demo](https://wxn0brp.github.io/NyaDock/demo)
18
18
 
19
19
  ## Installation
20
20
 
21
21
  ```bash
22
- yarn add github:wxn0brP/Nyadock#dist
22
+ npm i @wxn0brp/nya-dock
23
23
  ```
24
24
 
25
25
  ## Usage
@@ -34,14 +34,20 @@ First, you need a container element in your HTML to host the dock layout, and in
34
34
  <!-- The main container for the dock layout -->
35
35
  <div id="app"></div>
36
36
 
37
- <!-- Your panel content (can be hidden initially) -->
38
- <div id="panel1-content" style="display: none;">
39
- <h2>Panel 1</h2>
40
- <p>Content for the first panel.</p>
37
+ <!-- Your panel content -->
38
+ <div class="panel" id="panel1">
39
+ <div class="panel-header">Panel 1</div>
40
+ <div class="panel-content">
41
+ <h2>Panel 1</h2>
42
+ <p>Content for the first panel.</p>
43
+ </div>
41
44
  </div>
42
- <div id="panel2-content" style="display: none;">
43
- <h2>Panel 2</h2>
44
- <p>Content for the second panel.</p>
45
+ <div class="panel" id="panel2">
46
+ <div class="panel-header">Panel 2</div>
47
+ <div class="panel-content">
48
+ <h2>Panel 2</h2>
49
+ <p>Content for the second panel.</p>
50
+ </div>
45
51
  </div>
46
52
  ```
47
53
 
@@ -51,21 +57,21 @@ Import the `controller` and use it to configure and initialize the layout. Note
51
57
 
52
58
  ```typescript
53
59
  import { controller } from "@wxn0brp/nya-dock/state";
54
- import "@wxn0brp/nya-dock/style.css";
60
+ import "@wxn0brp/nya-dock/style.css"; // or in html: <link rel="stylesheet" href="node_modules/@wxn0brp/nya-dock/dist/style.css">
55
61
 
56
62
  // 1. Get the master container element
57
63
  const appContainer = document.querySelector("#app");
58
64
 
59
- // 2. Get your panel content elements
60
- const panel1 = document.querySelector("#panel1-content");
61
- const panel2 = document.querySelector("#panel2-content");
65
+ // 2. Get your panel elements
66
+ const panels = document.querySelectorAll(".panel");
62
67
 
63
68
  // 3. Assign the master container
64
69
  controller.master = appContainer;
65
70
 
66
- // 4. Register your panels with unique IDs
67
- controller.registerPanel("panel1", panel1);
68
- controller.registerPanel("panel2", panel2);
71
+ // 4. Register your panels
72
+ for (const panel of panels) {
73
+ controller.registerPanel(panel.id, panel);
74
+ }
69
75
 
70
76
  // 5. Define the layout structure
71
77
  // A horizontal split between "panel1" and "panel2"
@@ -94,6 +100,31 @@ You can nest these structures to create complex layouts:
94
100
  const complexLayout = ["panelA", ["panelB", "panelC", 1]];
95
101
  ```
96
102
 
103
+ ### CSS Customization
104
+
105
+ ```css
106
+ :root {
107
+ --nya-dock-border: silver;
108
+
109
+ --nya-dock-header: #2c2c2c;
110
+ --nya-dock-header-border: #444;
111
+ --nya-dock-header-color: #ddd;
112
+
113
+ --nya-dock-content-color: #aaa;
114
+ --nya-dock-content-border: #444;
115
+
116
+ --nya-dock-button-background: #444;
117
+ --nya-dock-button-color: white;
118
+ --nya-dock-button-hover-background: #555;
119
+
120
+ --nya-dock-info-box-background: #222;
121
+ --nya-dock-info-box-border: #666;
122
+
123
+ --nya-dock-dock-background: blueviolet;
124
+ --nya-dock-dock-opacity: 0.2;
125
+ }
126
+ ```
127
+
97
128
  ## License
98
129
 
99
130
  MIT [LICENSE](./LICENSE)
package/dist/index.d.ts CHANGED
@@ -1,2 +1,4 @@
1
- import "@wxn0brp/flanker-ui/html";
1
+ import logger from "./logger.js";
2
2
  import "./mouse/index.js";
3
+ import { controller } from "./state.js";
4
+ export { controller, logger };
package/dist/index.js CHANGED
@@ -1,103 +1,4 @@
1
- import "@wxn0brp/flanker-ui/html";
2
1
  import logger from "./logger.js";
3
2
  import "./mouse/index.js";
4
3
  import { controller } from "./state.js";
5
- logger.setLogLevel("DEBUG");
6
- window.logger = logger;
7
- window.controller = controller;
8
- const app = qs("#app");
9
- const panel1 = document.createElement("div");
10
- panel1.innerHTML = `
11
- <div class="panel-header">Panel 1</div>
12
- <div class="panel-content">
13
- <h3>Welcome to Panel 1</h3>
14
- <p>This is the first panel in the layout.</p>
15
- <ul>
16
- <li>Item 1</li>
17
- <li>Item 2</li>
18
- <li>Item 3</li>
19
- </ul>
20
- <div class="button-group">
21
- <button onclick="controller.reset()">Reset Config</button>
22
- </div>
23
- </div>
24
- `;
25
- const panel2 = document.createElement("div");
26
- panel2.innerHTML = `
27
- <div class="panel-header">Panel 2</div>
28
- <div class="panel-content">
29
- <h3>Content for Panel 2</h3>
30
- <p>This is the second panel, split from the main container.</p>
31
- <div class="button-group">
32
- <button>Button 1</button>
33
- <button>Button 2</button>
34
- </div>
35
- </div>
36
- `;
37
- const panel3 = document.createElement("div");
38
- panel3.innerHTML = `
39
- <div class="panel-header">Panel 3</div>
40
- <div class="panel-content">
41
- <h3>Additional Panel</h3>
42
- <p>This is the third panel in the layout.</p>
43
- <div class="info-box">
44
- <p>This panel was created by splitting with Panel 2.</p>
45
- </div>
46
- </div>
47
- `;
48
- const panel4 = document.createElement("div");
49
- panel4.innerHTML = `
50
- <div class="panel-header">Panel 4</div>
51
- <div class="panel-content">
52
- <h3>Form Panel</h3>
53
- <form>
54
- <label for="name">Name:</label>
55
- <input type="text" id="name" name="name"><br><br>
56
- <label for="email">Email:</label>
57
- <input type="email" id="email" name="email"><br><br>
58
- <input type="submit" value="Submit">
59
- </form>
60
- </div>
61
- `;
62
- const panel5 = document.createElement("div");
63
- panel5.innerHTML = `
64
- <div class="panel-header">Panel 5</div>
65
- <div class="panel-content">
66
- <h3>Table Panel</h3>
67
- <table border="1">
68
- <tr>
69
- <th>First name</th>
70
- <th>Last name</th>
71
- <th>Age</th>
72
- </tr>
73
- <tr>
74
- <td>Jill</td>
75
- <td>Smith</td>
76
- <td>50</td>
77
- </tr>
78
- <tr>
79
- <td>Eve</td>
80
- <td>Jackson</td>
81
- <td>94</td>
82
- </tr>
83
- </table>
84
- </div>
85
- `;
86
- controller.master = app;
87
- controller.setDefaultState([
88
- "panel1",
89
- [
90
- "panel2",
91
- [
92
- ["panel3", "panel5", 1],
93
- "panel4",
94
- ],
95
- 1
96
- ]
97
- ]);
98
- controller.registerPanel("panel1", panel1);
99
- controller.registerPanel("panel2", panel2);
100
- controller.registerPanel("panel3", panel3);
101
- controller.registerPanel("panel4", panel4);
102
- controller.registerPanel("panel5", panel5);
103
- controller.init();
4
+ export { controller, logger };
@@ -1,8 +1,17 @@
1
1
  import { DRAG } from "../const.js";
2
- import { controller } from "../state.js";
3
2
  import logger from "../logger.js";
4
- import { detectDockZone, getRelativePosition } from "../utils/detect.js";
3
+ import { controller } from "../state.js";
5
4
  import { saveNyaState } from "../storage.js";
5
+ import { detectDockZone, getRelativePosition } from "../utils/detect.js";
6
+ function removePreviewClass(zone) {
7
+ document.querySelectorAll(`.dock-${zone}`).forEach(dock => dock.classList.remove("dock-" + zone));
8
+ }
9
+ function removePreviewClasses() {
10
+ removePreviewClass("left");
11
+ removePreviewClass("right");
12
+ removePreviewClass("top");
13
+ removePreviewClass("bottom");
14
+ }
6
15
  let draggingPanel = null;
7
16
  document.addEventListener("mousedown", (e) => {
8
17
  const target = e.target;
@@ -19,56 +28,86 @@ document.addEventListener("mousedown", (e) => {
19
28
  logger.info("Dragging panel started", draggingPanel);
20
29
  document.body.style.cursor = "move";
21
30
  });
22
- document.addEventListener("mouseup", (e) => {
31
+ function locatePanel(e, log = false) {
23
32
  if (!draggingPanel) {
24
- logger.debug("Mouseup event ignored: no panel is being dragged");
33
+ if (log)
34
+ logger.debug("Mouse event ignored: no panel is being dragged");
25
35
  return;
26
36
  }
27
- document.body.style.cursor = "";
28
- function end() {
29
- logger.info("Dragging finished");
30
- draggingPanel = null;
31
- }
32
37
  const allPanels = [...controller._panels.values()].filter(p => p !== draggingPanel);
33
- logger.debug("All panels", allPanels);
38
+ if (log)
39
+ logger.debug("All panels", allPanels);
34
40
  const elemUnder = document.elementFromPoint(e.clientX, e.clientY);
35
41
  if (!elemUnder) {
36
- logger.debug("Mouseup event ignored: no element under cursor");
37
- return end();
42
+ if (log)
43
+ logger.debug("Mouse event ignored: no element under cursor");
44
+ return null;
38
45
  }
39
46
  const targetPanel = elemUnder.closest(".panel");
40
47
  if (!targetPanel) {
41
- logger.debug("Mouseup event ignored: no target panel under cursor");
42
- return end();
48
+ if (log)
49
+ logger.debug("Mouse event ignored: no target panel under cursor");
50
+ return null;
43
51
  }
44
- logger.debug("Target panel", targetPanel);
52
+ if (log)
53
+ logger.debug("Target panel", targetPanel);
45
54
  if (!allPanels.includes(targetPanel)) {
46
- logger.debug("Mouseup event ignored: target panel is not a valid drop target");
47
- return end();
55
+ if (log)
56
+ logger.debug("Mouse event ignored: target panel is not a valid drop target");
57
+ return null;
48
58
  }
49
59
  const zone = detectDockZone(e, targetPanel);
50
- logger.info(`Docking to ${zone}`);
60
+ if (log)
61
+ logger.info(`Docking to ${zone}`);
51
62
  if (zone === "center") {
52
- logger.debug("Docking to center, no action taken");
53
- return end();
63
+ if (log)
64
+ logger.debug("Docking to center, no action taken");
65
+ return null;
54
66
  }
55
67
  let sourceId = draggingPanel.dataset.nya_id;
56
68
  const targetId = targetPanel.dataset.nya_id;
57
69
  if (!sourceId)
58
- sourceId = draggingPanel.qs(".panel[data-nya_id]")?.dataset.nya_id;
70
+ sourceId = draggingPanel.querySelector(".panel[data-nya_id]")?.dataset.nya_id;
59
71
  if (!sourceId || !targetId) {
60
- logger.error("Panel ID not found");
61
- logger.error("Source ID:", sourceId);
62
- logger.error("Target ID:", targetId);
63
- return end();
72
+ if (log)
73
+ logger.error("Panel ID not found");
74
+ if (log)
75
+ logger.error("Source ID:", sourceId);
76
+ if (log)
77
+ logger.error("Target ID:", targetId);
78
+ return null;
64
79
  }
65
80
  if (sourceId === targetId) {
66
- logger.debug("Mouseup event ignored: source and target are the same");
67
- return end();
81
+ if (log)
82
+ logger.debug("Mouse event ignored: source and target are the same");
83
+ return null;
68
84
  }
85
+ return { sourceId, targetId, zone, targetPanel, draggingPanel };
86
+ }
87
+ document.addEventListener("mouseup", (e) => {
88
+ function end() {
89
+ logger.info("Dragging finished");
90
+ draggingPanel = null;
91
+ }
92
+ const result = locatePanel(e, true);
93
+ document.body.style.cursor = "";
94
+ if (!result) {
95
+ end();
96
+ return;
97
+ }
98
+ const { sourceId, targetId, zone } = result;
69
99
  controller.movePanel(sourceId, targetId, zone);
70
100
  controller._render();
71
101
  controller._setDefaultSize();
72
102
  saveNyaState();
103
+ removePreviewClasses();
73
104
  end();
74
105
  });
106
+ document.addEventListener("mousemove", (e) => {
107
+ const result = locatePanel(e);
108
+ if (!result)
109
+ return;
110
+ const { zone, targetPanel } = result;
111
+ removePreviewClasses();
112
+ targetPanel.querySelector(".panel-content").classList.add(`dock-${zone}`);
113
+ });
package/dist/style.css CHANGED
@@ -1,22 +1,3 @@
1
- * {
2
- margin: 0;
3
- padding: 0;
4
- box-sizing: border-box;
5
- }
6
-
7
- :root {
8
- --txt: #fff;
9
- --back: #111;
10
- }
11
-
12
- body {
13
- background: var(--back);
14
- color: var(--txt);
15
- font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
16
- width: 100vw;
17
- height: 100vh;
18
- }
19
-
20
1
  .master {
21
2
  height: 100%;
22
3
  width: 100%;
@@ -48,7 +29,7 @@ body {
48
29
  width: 100%;
49
30
  }
50
31
  .split.column > :first-child {
51
- border-bottom: 1px solid silver;
32
+ border-bottom: 1px solid var(--nya-dock-border, silver);
52
33
  height: var(--size) !important;
53
34
  }
54
35
  .split.column > :first-child::before {
@@ -68,7 +49,7 @@ body {
68
49
  height: 100%;
69
50
  }
70
51
  .split.row > :first-child {
71
- border-right: 1px solid silver;
52
+ border-right: 1px solid var(--nya-dock-border, silver);
72
53
  width: var(--size) !important;
73
54
  }
74
55
  .split.row > :first-child::before {
@@ -90,21 +71,22 @@ body {
90
71
  flex-direction: column;
91
72
  }
92
73
  .split .panel .panel-header {
93
- background-color: #2c2c2c;
74
+ background-color: var(--nya-dock-header, #2c2c2c);
94
75
  padding: 10px;
95
- border-bottom: 1px solid #444;
76
+ border-bottom: 1px solid var(--nya-dock-header-border, #444);
96
77
  font-weight: bold;
97
- color: #ddd;
78
+ color: var(--nya-dock-header-color, #ddd);
98
79
  }
99
80
  .split .panel .panel-content {
100
81
  padding: 15px;
101
82
  flex: 1;
102
83
  overflow-y: auto;
84
+ position: relative;
103
85
  }
104
86
  .split .panel .panel-content h3 {
105
87
  margin-top: 0;
106
- color: #aaa;
107
- border-bottom: 1px solid #444;
88
+ color: var(--nya-dock-content-color, #aaa);
89
+ border-bottom: 1px solid var(--nya-dock-content-border, #444);
108
90
  padding-bottom: 5px;
109
91
  }
110
92
  .split .panel .panel-content p {
@@ -121,8 +103,8 @@ body {
121
103
  margin-top: 15px;
122
104
  }
123
105
  .split .panel .panel-content .button-group button {
124
- background: #444;
125
- color: white;
106
+ background: var(--nya-dock-button-background, #444);
107
+ color: var(--nya-dock-button-color, white);
126
108
  border: none;
127
109
  padding: 8px 15px;
128
110
  margin-right: 10px;
@@ -130,13 +112,43 @@ body {
130
112
  cursor: pointer;
131
113
  }
132
114
  .split .panel .panel-content .button-group button:hover {
133
- background: #555;
115
+ background: var(--nya-dock-button-hover-background, #555);
134
116
  }
135
117
  .split .panel .panel-content .info-box {
136
- background: #222;
118
+ background: var(--nya-dock-info-box-background, #222);
137
119
  padding: 10px;
138
120
  border-radius: 4px;
139
- border-left: 3px solid #666;
121
+ border-left: 3px solid var(--nya-dock-info-box-border, #666);
122
+ }
123
+ .split .panel .panel-content::before {
124
+ content: "";
125
+ position: absolute;
126
+ background-color: var(--nya-dock-dock-background, blueviolet);
127
+ opacity: var(--nya-dock-dock-opacity, 0.2);
128
+ }
129
+ .split .panel .panel-content.dock-left::before {
130
+ left: 0;
131
+ top: 0;
132
+ width: 40%;
133
+ height: 100%;
134
+ }
135
+ .split .panel .panel-content.dock-right::before {
136
+ right: 0;
137
+ top: 0;
138
+ width: 40%;
139
+ height: 100%;
140
+ }
141
+ .split .panel .panel-content.dock-top::before {
142
+ left: 0;
143
+ top: 0;
144
+ width: 100%;
145
+ height: 40%;
146
+ }
147
+ .split .panel .panel-content.dock-bottom::before {
148
+ left: 0;
149
+ bottom: 0;
150
+ width: 100%;
151
+ height: 40%;
140
152
  }
141
153
 
142
154
  /*# sourceMappingURL=style.css.map */
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../src/style.scss"],"names":[],"mappings":"AAAA;EACI;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;AAEA;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAKZ;EACI;;AAEA;EACI;;AAGJ;EACI;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAKZ;EACI;;;AAIR;EACI;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;;AAIR;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAKZ;EACI;EACA;EACA;EACA","file":"style.css"}
1
+ {"version":3,"sourceRoot":"","sources":["../src/style.scss"],"names":[],"mappings":"AAAA;EACI;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;AAEA;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAKZ;EACI;;AAEA;EACI;;AAGJ;EACI;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAKZ;EACI;;;AAIR;EACI;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;;AAIR;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAKZ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA","file":"style.css"}
package/package.json CHANGED
@@ -1,41 +1,38 @@
1
1
  {
2
- "name": "@wxn0brp/nya-dock",
3
- "version": "0.0.1",
4
- "main": "dist/index.js",
5
- "types": "dist/index.d.ts",
6
- "description": "",
7
- "repository": {
8
- "type": "git",
9
- "url": "https://github.com/wxn0brP/Nyadock.git"
10
- },
11
- "homepage": "https://github.com/wxn0brP/Nyadock",
12
- "author": "wxn0brP",
13
- "license": "MIT",
14
- "type": "module",
15
- "scripts": {
16
- "build": "tsc && tsc-alias && sass src:dist"
17
- },
18
- "devDependencies": {
19
- "sass": "*",
20
- "tsc-alias": "*",
21
- "typescript": "*"
22
- },
23
- "files": [
24
- "dist"
25
- ],
26
- "exports": {
27
- ".": {
28
- "types": "./dist/index.d.ts",
29
- "import": "./dist/index.js",
30
- "default": "./dist/index.js"
31
- },
32
- "./*": {
33
- "types": "./dist/*.d.ts",
34
- "import": "./dist/*.js",
35
- "default": "./dist/*.js"
36
- }
37
- },
38
- "dependencies": {
39
- "@wxn0brp/flanker-ui": "^0.4.3"
40
- }
2
+ "name": "@wxn0brp/nya-dock",
3
+ "version": "0.0.3",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "description": "",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/wxn0brP/NyaDock.git"
10
+ },
11
+ "homepage": "https://github.com/wxn0brP/NyaDock",
12
+ "author": "wxn0brP",
13
+ "license": "MIT",
14
+ "type": "module",
15
+ "devDependencies": {
16
+ "sass": "*",
17
+ "tsc-alias": "*",
18
+ "typescript": "*"
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "import": "./dist/index.js",
27
+ "default": "./dist/index.js"
28
+ },
29
+ "./*": {
30
+ "types": "./dist/*.d.ts",
31
+ "import": "./dist/*.js",
32
+ "default": "./dist/*.js"
33
+ }
34
+ },
35
+ "dependencies": {
36
+ "@wxn0brp/flanker-ui": "^0.4.3"
37
+ }
41
38
  }