perfect-gui 4.12.7 → 4.12.9

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,94 +1,113 @@
1
- # Perfect GUI
2
- A nice, simple and (probably not) perfect GUI for JavaScript.
1
+ <div align="center">
2
+ <h1>Perfect GUI</h1>
3
+ <p>A nice, simple and (probably not so) perfect GUI for JavaScript.</p>
4
+
5
+ <p>
6
+ <a href="https://thibka.github.io/perfect-gui/"><b>Documentation & Live Examples</b></a>
7
+ </p>
8
+ </div>
3
9
 
4
- ## Documentation and examples
5
- Go to the [documentation page](https://thibka.github.io/perfect-gui/) to see all the features and examples.
10
+ ## Features
6
11
 
7
- ## Install
12
+ - **Simplicity first**: Extremely easy to setup and use, inspired by timeless classics like `dat.gui` and `lil.gui`.
13
+ - **Modern UI**: Clean, customizable, and polished design right out of the box.
14
+ - **Rich Inputs**: Support for sliders, buttons, color pickers, vectors, images, lists, and toggles.
15
+ - **Folders**: Easily group and organize your controls in collapsible sections.
16
+ - **Draggable & Auto-positioned**: Snap it to screen edges or let the user drag it anywhere.
17
+ - **Data Binding**: Automatically sync your controls with object properties.
18
+ - **Zero Dependencies**: Lightweight and built with vanilla JavaScript.
8
19
 
9
- ### With NPM
20
+ ## Installation
21
+
22
+ **With NPM:**
10
23
 
11
24
  ```bash
12
25
  npm i perfect-gui
13
26
  ```
14
27
 
15
- ### Import from a CDN
28
+ **From a CDN (ES Modules):**
16
29
 
17
- ```javascript
30
+ For a quick setup without build tools, use an import map:
31
+
32
+ ```html
18
33
  <script type="importmap">
19
- {
20
- "imports": {
21
- "perfect-gui": "https://unpkg.com/perfect-gui@latest/dist/perfect-gui.js",
34
+ {
35
+ "imports": {
36
+ "perfect-gui": "https://unpkg.com/perfect-gui@latest/dist/perfect-gui.js"
37
+ }
22
38
  }
23
- }
39
+ </script>
40
+
41
+ <script type="module">
42
+ import GUI from 'perfect-gui';
43
+
44
+ const gui = new GUI();
45
+ gui.button('Click me!', () => alert('Hello world!'));
24
46
  </script>
25
47
  ```
26
48
 
27
- ## Hello world
49
+ ## Quick Start
50
+
51
+ Creating a control panel is as simple as instantiating the GUI and adding some components:
28
52
 
29
53
  ```javascript
30
54
  import GUI from 'perfect-gui';
31
55
 
32
- const gui = new GUI();
56
+ // 1. Create a new GUI instance
57
+ const gui = new GUI({
58
+ label: 'My Settings',
59
+ position: 'top right',
60
+ });
61
+
62
+ // 2. Add a simple button
63
+ gui.button('Click me', () => {
64
+ console.log('Button clicked!');
65
+ });
66
+
67
+ // 3. Add a slider connected to an object value natively
68
+ const params = { opacity: 0.5 };
69
+ gui.slider({ obj: params, prop: 'opacity', min: 0, max: 1 }, (val) => {
70
+ document.body.style.opacity = val;
71
+ });
33
72
 
34
- gui.button('Click me', callback);
73
+ // 4. Group controls in a folder
74
+ const folder = gui.folder({ label: 'Advanced' });
75
+ folder.color({ label: 'Color', value: '#bada55' }, (color) => {
76
+ document.body.style.backgroundColor = color;
77
+ });
35
78
  ```
36
79
 
37
- ## Options
80
+ ## Configuration Options
81
+
82
+ You can customize the GUI by passing an options object to the constructor:
83
+
38
84
  ```javascript
39
85
  const gui = new GUI({
40
- label: 'My GUI',
41
- // Name of the panel.
42
- // Default is null.
43
-
44
- container: '#container',
45
- // Element containing the GUI
46
- // Default is document.body
47
-
48
- width: 250,
49
- // Width of the panel (in pixels).
50
- // Default is 290.
51
-
52
- maxHeight: 500,
53
- // Maximum height beyond which scrolling is necessary.
54
- // Default is the smallest value between the height of the window and the height of the container.
55
-
56
- closed: false,
57
- // Defines whether the panel should be closed by default.
58
- // Default is false.
59
-
60
- position: 'bottom right',
61
- // Defines where to place the panel on screen.
62
- // Accepted values are 'top', 'bottom', 'left' and 'right' in no particular order ('bottom right' = 'right bottom').
63
- // If multiple instances have the same position, they will be stacked horizontally.
64
- // Default is 'top right'.
65
-
66
- draggable: false,
67
- // Defines if the panel can be manually moved across the screen.
68
- // Default is false.
69
-
70
- autoRepositioning: true,
71
- // If set to true, the panel position will be reset when the screen is resized.
72
- // If a panel has been dragged, it won't be be affected.
73
- // Default is true.
74
-
75
- color: '#bada55',
76
- // Default is #2e2e2e
77
-
86
+ label: 'My GUI', // Name of the panel (default: null)
87
+ container: '#container', // Element containing the GUI (default: document.body)
88
+ width: 250, // Width of the panel in pixels (default: 290)
89
+ maxHeight: 500, // Max height beyond which scrolling is necessary
90
+ closed: false, // Start closed? (default: false)
91
+ position: 'bottom right', // Position ('top', 'bottom', 'left', 'right')
92
+ draggable: false, // Can it be manually moved? (default: false)
93
+ autoRepositioning: true, // Reset position on window resize? (default: true)
94
+ color: '#bada55', // Accent color
78
95
  onUpdate: () => {
79
- // Callback function triggered each time this GUI instance is updated.
80
- }
96
+ // Callback function triggered each time any GUI instance is updated
97
+ },
81
98
  });
82
99
  ```
83
100
 
84
- ## [Methods](https://thibka.github.io/perfect-gui/public/)
85
-
86
- * [button](https://thibka.github.io/perfect-gui/public/#button)
87
- * [slider](https://thibka.github.io/perfect-gui/public/#slider)
88
- * [toggle](https://thibka.github.io/perfect-gui/public/#toggle)
89
- * [list](https://thibka.github.io/perfect-gui/public/#list)
90
- * [image](https://thibka.github.io/perfect-gui/public/#image)
91
- * [color](https://thibka.github.io/perfect-gui/public/#color)
92
- * [vector2](https://thibka.github.io/perfect-gui/public/#vector2)
93
- * [folder](https://thibka.github.io/perfect-gui/public/#folder)
94
- * [toggleClose](https://thibka.github.io/perfect-gui/public)
101
+ ## API / Available Components
102
+
103
+ See the [Documentation](https://thibka.github.io/perfect-gui/) for a comprehensive list of properties and usage.
104
+
105
+ - [`button()`](https://thibka.github.io/perfect-gui/public/#button)
106
+ - [`slider()`](https://thibka.github.io/perfect-gui/public/#slider)
107
+ - [`toggle()`](https://thibka.github.io/perfect-gui/public/#toggle)
108
+ - [`list()`](https://thibka.github.io/perfect-gui/public/#list)
109
+ - [`image()`](https://thibka.github.io/perfect-gui/public/#image)
110
+ - [`color()`](https://thibka.github.io/perfect-gui/public/#color)
111
+ - [`vector2()`](https://thibka.github.io/perfect-gui/public/#vector2)
112
+ - [`folder()`](https://thibka.github.io/perfect-gui/public/#folder)
113
+ - [`toggleClose()`](https://thibka.github.io/perfect-gui/public)
@@ -1,4 +1,4 @@
1
- let H = class {
1
+ let M = class {
2
2
  constructor(t, e = {}, i) {
3
3
  this.parent = t;
4
4
  let s = "";
@@ -30,10 +30,10 @@ class N {
30
30
  (this.prop != null && this.obj == null || this.prop == null && this.obj != null) && console.warn('[GUI] slider() "obj" and "prop" parameters must be used together.'), a = (this.max - this.min) / 2;
31
31
  const o = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? s : null, r = document.createElement("div");
32
32
  r.className = "p-gui__slider", o && r.setAttribute("title", o), this.parent.wrapper.append(r);
33
- const p = document.createElement("div");
34
- p.className = "p-gui__slider-name", p.textContent = s, r.append(p), this.ctrlDiv = document.createElement("div"), this.ctrlDiv.className = "p-gui__slider-ctrl", this.ctrlDiv.setAttribute("type", "range"), this.ctrlDiv.setAttribute("min", this.min), this.ctrlDiv.setAttribute("max", this.max), r.append(this.ctrlDiv);
35
- const u = document.createElement("div");
36
- return u.className = "p-gui__slider-bar", this.ctrlDiv.append(u), this.handle = document.createElement("div"), this.handle.className = "p-gui__slider-handle", this.ctrlDiv.append(this.handle), this.filling = document.createElement("div"), this.filling.className = "p-gui__slider-filling", u.append(this.filling), this.valueInput = document.createElement("input"), this.valueInput.className = "p-gui__slider-value", this.valueInput.value = this.isObject ? this.obj[this.prop] : a, r.append(this.valueInput), setTimeout(() => {
33
+ const d = document.createElement("div");
34
+ d.className = "p-gui__slider-name", d.textContent = s, r.append(d), this.ctrlDiv = document.createElement("div"), this.ctrlDiv.className = "p-gui__slider-ctrl", this.ctrlDiv.setAttribute("type", "range"), this.ctrlDiv.setAttribute("min", this.min), this.ctrlDiv.setAttribute("max", this.max), r.append(this.ctrlDiv);
35
+ const c = document.createElement("div");
36
+ return c.className = "p-gui__slider-bar", this.ctrlDiv.append(c), this.handle = document.createElement("div"), this.handle.className = "p-gui__slider-handle", this.ctrlDiv.append(this.handle), this.filling = document.createElement("div"), this.filling.className = "p-gui__slider-filling", c.append(this.filling), this.valueInput = document.createElement("input"), this.valueInput.className = "p-gui__slider-value", this.valueInput.value = this.isObject ? this.obj[this.prop] : a, r.append(this.valueInput), setTimeout(() => {
37
37
  const n = this.handle.offsetWidth;
38
38
  this.handle.position = this._mapLinear(this.valueInput.value, this.min, this.max, n / 2, 88 - n / 2), this.handle.position = Math.min(this.handle.position, 88 - n / 2), this.handle.position = Math.max(this.handle.position, n / 2), this.handle.style.transform = `translate(-50%, -50%) translateX(${this.handle.position}px)`, this.filling.style.width = `${this.handle.position}px`;
39
39
  }, 0), this.valueInput.addEventListener("change", () => {
@@ -57,8 +57,8 @@ class N {
57
57
  e ? o = t.offsetX : o = this.handle.position + l, o = Math.max(s / 2, Math.min(o, i - s / 2));
58
58
  let r = this.min + (this.max - this.min) * (o - s / 2) / (i - s);
59
59
  r > a ? r = this._quantizeFloor(r, this.step) : r = this._quantizeCeil(r, this.step), r = parseFloat(r.toFixed(9));
60
- const p = parseFloat((a + this.step).toFixed(9)), u = parseFloat((a - this.step).toFixed(9));
61
- (r >= p || r <= u) && (r = r.toFixed(this.decimals), this.valueInput.value = r, this.ctrlDiv.prevPosition = t.clientX, this.handle.style.transform = `translate(-50%, -50%) translateX(${o}px)`, this.handle.position = o, this.filling.style.width = this.handle.position + "px", this._triggerCallbacks());
60
+ const d = parseFloat((a + this.step).toFixed(9)), c = parseFloat((a - this.step).toFixed(9));
61
+ (r >= d || r <= c) && (r = r.toFixed(this.decimals), this.valueInput.value = r, this.ctrlDiv.prevPosition = t.clientX, this.handle.style.transform = `translate(-50%, -50%) translateX(${o}px)`, this.handle.position = o, this.filling.style.width = this.handle.position + "px", this._triggerCallbacks());
62
62
  }
63
63
  _updateHandlePositionFromValue() {
64
64
  const t = this.ctrlDiv.offsetWidth, e = this.handle.offsetWidth;
@@ -81,7 +81,7 @@ class N {
81
81
  return e * Math.floor(t / e);
82
82
  }
83
83
  }
84
- class S {
84
+ class H {
85
85
  constructor(t, e = {}, i) {
86
86
  if (this.parent = t, typeof e != "object")
87
87
  throw Error(`[GUI] image() first parameter must be an object. Received: ${typeof e}.`);
@@ -92,26 +92,26 @@ class S {
92
92
  throw typeof e.path == null ? Error("[GUI] image() path must be provided.") : Error("[GUI] image() path must be a string.");
93
93
  let l = s.replace(/^.*[\\\/]/, ""), a;
94
94
  e.label == null ? a = l : a = typeof e.label == "string" && e.label || " ";
95
- const o = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? a : null, r = e.selected === !0, p = e.selectionBorder !== !1;
96
- let u = "";
97
- e.width && (typeof e.width == "number" && (e.width += "px"), u += `flex: 0 0 calc(${e.width} - 5px); `), e.height && (typeof e.height == "number" && (e.height += "px"), u += `height: ${e.height}; `);
95
+ const o = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? a : null, r = e.selected === !0, d = e.selectionBorder !== !1;
96
+ let c = "";
97
+ e.width && (typeof e.width == "number" && (e.width += "px"), c += `flex: 0 0 calc(${e.width} - 5px); `), e.height && (typeof e.height == "number" && (e.height += "px"), c += `height: ${e.height}; `);
98
98
  const n = document.createElement("div");
99
- n.className = "p-gui__image", n.style = "background-image: url(" + s + "); " + u, o && n.setAttribute("title", o), this.parent.imageContainer.append(n), r && p && n.classList.add("p-gui__image--selected");
100
- const g = document.createElement("div");
101
- return g.className = "p-gui__image-text", g.textContent = a, n.append(g), n.addEventListener("click", () => {
102
- let d = n.parentElement.querySelectorAll(".p-gui__image--selected");
103
- for (let c = 0; c < d.length; c++)
104
- d[c].classList.remove("p-gui__image--selected");
105
- p && n.classList.add("p-gui__image--selected"), typeof i == "function" && i({ path: s, text: a }), this.parent.onUpdate ? this.parent.onUpdate() : this.parent.isFolder && this.parent.firstParent.onUpdate && this.parent.firstParent.onUpdate();
99
+ n.className = "p-gui__image", n.style = "background-image: url(" + s + "); " + c, o && n.setAttribute("title", o), this.parent.imageContainer.append(n), r && d && n.classList.add("p-gui__image--selected");
100
+ const f = document.createElement("div");
101
+ return f.className = "p-gui__image-text", f.textContent = a, n.append(f), n.addEventListener("click", () => {
102
+ let p = n.parentElement.querySelectorAll(".p-gui__image--selected");
103
+ for (let h = 0; h < p.length; h++)
104
+ p[h].classList.remove("p-gui__image--selected");
105
+ d && n.classList.add("p-gui__image--selected"), typeof i == "function" && i({ path: s, text: a }), this.parent.onUpdate ? this.parent.onUpdate() : this.parent.isFolder && this.parent.firstParent.onUpdate && this.parent.firstParent.onUpdate();
106
106
  }), n;
107
107
  }
108
108
  }
109
- class X {
109
+ class S {
110
110
  constructor(t, e = {}, i) {
111
111
  if (this.parent = t, typeof e != "object")
112
112
  throw Error(`[GUI] toggle() first parameter must be an object. Received: ${typeof e}.`);
113
- let s = typeof e.label == "string" && e.label || " ", l = !1, a = null, o = e.obj, r = e.prop, p = typeof e.value == "boolean" ? e.value : null;
114
- if (p !== null)
113
+ let s = typeof e.label == "string" && e.label || " ", l = !1, a = null, o = e.obj, r = e.prop, d = typeof e.value == "boolean" ? e.value : null;
114
+ if (d !== null)
115
115
  (r != null || o != null) && console.warn('[GUI] toggle() "obj" and "prop" parameters are ignored when a "value" parameter is used.');
116
116
  else if (r != null && o != null) {
117
117
  if (typeof r != "string")
@@ -121,34 +121,34 @@ class X {
121
121
  s == " " && (s = r), a = this.parent.propReferences.push(o[r]) - 1, l = !0;
122
122
  } else
123
123
  (r != null && o == null || r == null && o == null) && console.warn('[GUI] toggle() "obj" and "prop" parameters must be used together.');
124
- const u = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? s : null, n = document.createElement("div");
125
- n.textContent = s, n.className = "p-gui__toggle", u && n.setAttribute("title", u), n.addEventListener("click", (c) => {
126
- const h = c.target.childNodes[1];
127
- let f = !0;
128
- h.classList.contains("p-gui__toggle-checkbox--active") && (f = !1), h.classList.toggle("p-gui__toggle-checkbox--active"), l ? o[r] = f : typeof i == "function" && i(f), this.parent.onUpdate ? this.parent.onUpdate() : this.parent.isFolder && this.parent.firstParent.onUpdate && this.parent.firstParent.onUpdate();
124
+ const c = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? s : null, n = document.createElement("div");
125
+ n.textContent = s, n.className = "p-gui__toggle", c && n.setAttribute("title", c), n.addEventListener("click", (h) => {
126
+ const u = h.target.childNodes[1];
127
+ let g = !0;
128
+ u.classList.contains("p-gui__toggle-checkbox--active") && (g = !1), u.classList.toggle("p-gui__toggle-checkbox--active"), l ? o[r] = g : typeof i == "function" && i(g), this.parent.onUpdate ? this.parent.onUpdate() : this.parent.isFolder && this.parent.firstParent.onUpdate && this.parent.firstParent.onUpdate();
129
129
  });
130
- let g = l ? o[r] ? " p-gui__toggle-checkbox--active" : "" : p ? " p-gui__toggle-checkbox--active" : "";
131
- const d = document.createElement("div");
132
- return d.className = "p-gui__toggle-checkbox" + g, n.append(d), l && Object.defineProperty(o, r, {
133
- set: (c) => {
134
- this.parent.propReferences[a] = c, c ? d.classList.add("p-gui__toggle-checkbox--active") : d.classList.remove("p-gui__toggle-checkbox--active"), typeof i == "function" && i(c);
130
+ let f = l ? o[r] ? " p-gui__toggle-checkbox--active" : "" : d ? " p-gui__toggle-checkbox--active" : "";
131
+ const p = document.createElement("div");
132
+ return p.className = "p-gui__toggle-checkbox" + f, n.append(p), l && Object.defineProperty(o, r, {
133
+ set: (h) => {
134
+ this.parent.propReferences[a] = h, h ? p.classList.add("p-gui__toggle-checkbox--active") : p.classList.remove("p-gui__toggle-checkbox--active"), typeof i == "function" && i(h);
135
135
  },
136
136
  get: () => this.parent.propReferences[a]
137
137
  }), n;
138
138
  }
139
139
  }
140
- class W {
140
+ class X {
141
141
  constructor(t, e = {}, i) {
142
142
  if (this.parent = t, typeof e != "object")
143
143
  throw Error(`[GUI] list() first parameter must be an object. Received: ${typeof e}.`);
144
- let s = typeof e.label == "string" ? e.label : " ", l = !1, a = null, o = e.obj, r = e.prop, p = Array.isArray(e.values) ? e.values : null, u, n = typeof p[0] != "string";
145
- const g = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? s : null;
144
+ let s = typeof e.label == "string" ? e.label : " ", l = !1, a = null, o = e.obj, r = e.prop, d = Array.isArray(e.values) ? e.values : null, c, n = typeof d[0] != "string";
145
+ const f = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? s : null;
146
146
  if (i = typeof i == "function" ? i : null, e.value !== void 0 || e.value === void 0 && o === void 0 && r === void 0)
147
- (r != null || o != null) && console.warn('[GUI] list() "obj" and "prop" parameters are ignored when a "value" parameter is used.'), u = (() => {
148
- if (!p)
147
+ (r != null || o != null) && console.warn('[GUI] list() "obj" and "prop" parameters are ignored when a "value" parameter is used.'), c = (() => {
148
+ if (!d)
149
149
  return null;
150
150
  if (typeof e.value == "string")
151
- return p.indexOf(e.value);
151
+ return d.indexOf(e.value);
152
152
  if (typeof e.value == "number")
153
153
  return e.value;
154
154
  })();
@@ -157,43 +157,43 @@ class W {
157
157
  throw Error(`[GUI] list() "prop" parameter must be an string. Received: ${typeof r}.`);
158
158
  if (typeof o != "object")
159
159
  throw Error(`[GUI] list() "obj" parameter must be an object. Received: ${typeof o}.`);
160
- u = (() => {
161
- if (!p)
160
+ c = (() => {
161
+ if (!d)
162
162
  return null;
163
163
  if (typeof o[r] == "string")
164
- return n ? p.find((h) => h.value === o[r]).value : p.indexOf(o[r]);
164
+ return n ? d.find((u) => u.value === o[r]).value : d.indexOf(o[r]);
165
165
  if (typeof o[r] == "number")
166
- return n ? p.find((h) => h.value === o[r]).value : o[r];
166
+ return n ? d.find((u) => u.value === o[r]).value : o[r];
167
167
  })(), a = this.parent.propReferences.push(o[r]) - 1, l = !0;
168
168
  } else
169
169
  (r != null && o == null || r == null && o == null) && console.warn('[GUI] list() "obj" and "prop" parameters must be used together.');
170
- let d = document.createElement("div");
171
- d.className = "p-gui__list", d.textContent = s, g && d.setAttribute("title", g), this.parent.wrapper.append(d);
172
- let c = document.createElement("select");
173
- return d.append(c), c.className = "p-gui__list-dropdown", c.addEventListener("change", (h) => {
174
- l ? o[r] = h.target.value : i && i(h.target.value), this.parent.onUpdate ? this.parent.onUpdate() : this.parent.isFolder && this.parent.firstParent.onUpdate && this.parent.firstParent.onUpdate();
175
- }), p && p.forEach((h, f) => {
176
- const b = n ? h.label : h, v = n ? h.value : h;
177
- let m = document.createElement("option");
178
- m.setAttribute("value", v), m.textContent = b, c.append(m), (!n && u == f || n && u == v) && m.setAttribute("selected", "");
170
+ let p = document.createElement("div");
171
+ p.className = "p-gui__list", p.textContent = s, f && p.setAttribute("title", f), this.parent.wrapper.append(p);
172
+ let h = document.createElement("select");
173
+ return p.append(h), h.className = "p-gui__list-dropdown", h.addEventListener("change", (u) => {
174
+ l ? o[r] = u.target.value : i && i(u.target.value), this.parent.onUpdate ? this.parent.onUpdate() : this.parent.isFolder && this.parent.firstParent.onUpdate && this.parent.firstParent.onUpdate();
175
+ }), d && d.forEach((u, g) => {
176
+ const b = n ? u.label : u, v = n ? u.value : u;
177
+ let x = document.createElement("option");
178
+ x.setAttribute("value", v), x.textContent = b, h.append(x), (!n && c == g || n && c == v) && x.setAttribute("selected", "");
179
179
  }), l && Object.defineProperty(o, r, {
180
- set: (h) => {
181
- let f, b, v;
182
- n ? (v = p.find((w) => w.value == h), b = v?.value || p[0].value, f = p.indexOf(v)) : (typeof h == "string" && (f = p.indexOf(h), b = h), typeof h == "number" && (f = h, b = p[h])), this.parent.propReferences[a] = n ? b : h;
183
- const m = c.querySelector("[selected]");
184
- m && m.removeAttribute("selected"), c.querySelectorAll("option")[f].setAttribute("selected", ""), typeof i == "function" && i(n ? v : b, f);
180
+ set: (u) => {
181
+ let g, b, v;
182
+ n ? (v = d.find((w) => w.value == u), b = v?.value || d[0].value, g = d.indexOf(v)) : (typeof u == "string" && (g = d.indexOf(u), b = u), typeof u == "number" && (g = u, b = d[u])), this.parent.propReferences[a] = n ? b : u;
183
+ const x = h.querySelector("[selected]");
184
+ x && x.removeAttribute("selected"), h.querySelectorAll("option")[g].setAttribute("selected", ""), typeof i == "function" && i(n ? v : b, g);
185
185
  },
186
186
  get: () => this.parent.propReferences[a]
187
- }), d;
187
+ }), p;
188
188
  }
189
189
  }
190
- class G {
190
+ class W {
191
191
  constructor(t, e = {}, i) {
192
192
  if (this.parent = t, typeof e != "object")
193
193
  throw Error(`[GUI] color() first parameter must be an object. Received: ${typeof e}.`);
194
- let s = typeof e.label == "string" && e.label || " ", l = !1, a = null, o = e.obj, r = e.prop, p;
195
- const u = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? s : null;
196
- if (typeof e.value == "string" && (e.value.length != 7 || e.value[0] != "#" ? console.error(`[GUI] color() 'value' parameter must be an hexadecimal string in the format "#ffffff". Received: "${e.value}".`) : p = e.value), p || (p = "#000000"), e.value !== void 0)
194
+ let s = typeof e.label == "string" && e.label || " ", l = !1, a = null, o = e.obj, r = e.prop, d;
195
+ const c = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? s : null;
196
+ if (typeof e.value == "string" && (e.value.length != 7 || e.value[0] != "#" ? console.error(`[GUI] color() 'value' parameter must be an hexadecimal string in the format "#ffffff". Received: "${e.value}".`) : d = e.value), d || (d = "#000000"), e.value !== void 0)
197
197
  (r != null || o != null) && console.warn('[GUI] color() "obj" and "prop" parameters are ignored when a "value" parameter is used.');
198
198
  else if (r != null && o != null) {
199
199
  if (typeof r != "string")
@@ -204,72 +204,72 @@ class G {
204
204
  } else
205
205
  (r != null && o == null || r == null && o == null) && console.warn('[GUI] color() "obj" and "prop" parameters must be used together.');
206
206
  const n = document.createElement("div");
207
- n.className = "p-gui__color", n.textContent = s, u && n.setAttribute("title", u), this.parent.wrapper.append(n);
208
- const g = document.createElement("input");
209
- return g.className = "p-gui__color-picker", g.setAttribute("type", "color"), g.value = p, n.append(g), typeof i == "function" && g.addEventListener("input", () => {
210
- l ? o[r] = g.value : typeof i == "function" && i(g.value), this.parent.onUpdate ? this.parent.onUpdate() : this.parent.isFolder && this.parent.firstParent.onUpdate && this.parent.firstParent.onUpdate();
207
+ n.className = "p-gui__color", n.textContent = s, c && n.setAttribute("title", c), this.parent.wrapper.append(n);
208
+ const f = document.createElement("input");
209
+ return f.className = "p-gui__color-picker", f.setAttribute("type", "color"), f.value = d, n.append(f), typeof i == "function" && f.addEventListener("input", () => {
210
+ l ? o[r] = f.value : typeof i == "function" && i(f.value), this.parent.onUpdate ? this.parent.onUpdate() : this.parent.isFolder && this.parent.firstParent.onUpdate && this.parent.firstParent.onUpdate();
211
211
  }), l && Object.defineProperty(o, r, {
212
- set: (d) => {
213
- this.parent.propReferences[a] = d, g.value = d, typeof i == "function" && i(d);
212
+ set: (p) => {
213
+ this.parent.propReferences[a] = p, f.value = p, typeof i == "function" && i(p);
214
214
  },
215
215
  get: () => this.parent.propReferences[a]
216
216
  }), n;
217
217
  }
218
218
  }
219
- class Y {
219
+ class G {
220
220
  constructor(t, e = {}, i) {
221
221
  if (this.parent = t, typeof e != "object")
222
222
  throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof e}.`);
223
223
  let s = typeof e.label == "string" && e.label || " ";
224
- const l = e.x.min ?? 0, a = e.x.max ?? 1, o = e.y.min ?? 0, r = e.y.max ?? 1, p = e.x.step || (a - l) / 100, u = e.y.step || (r - o) / 100, n = this.parent._countDecimals(p), g = this.parent._countDecimals(u), d = e.x.obj, c = e.x.prop, h = this.parent.propReferences.push(d[c]) - 1, f = e.y.obj, b = e.y.prop, v = this.parent.propReferences.push(f[b]) - 1, m = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? s : null;
224
+ const l = e.x.min ?? 0, a = e.x.max ?? 1, o = e.y.min ?? 0, r = e.y.max ?? 1, d = e.x.step || (a - l) / 100, c = e.y.step || (r - o) / 100, n = this.parent._countDecimals(d), f = this.parent._countDecimals(c), p = e.x.obj, h = e.x.prop, u = this.parent.propReferences.push(p[h]) - 1, g = e.y.obj, b = e.y.prop, v = this.parent.propReferences.push(g[b]) - 1, x = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? s : null;
225
225
  i = typeof i == "function" ? i : null;
226
226
  const w = document.createElement("div");
227
- w.className = "p-gui__vector2", w.textContent = s, m && w.setAttribute("title", m), this.parent.wrapper.append(w);
227
+ w.className = "p-gui__vector2", w.textContent = s, x && w.setAttribute("title", x), this.parent.wrapper.append(w);
228
228
  const A = document.createElement("div");
229
- A.className = "p-gui__vector-value", A.textContent = d[c] + ", " + f[b], w.append(A);
229
+ A.className = "p-gui__vector-value", A.textContent = p[h] + ", " + g[b], w.append(A);
230
230
  const _ = document.createElement("div");
231
- _.className = "p-gui__vector2-area", w.append(_), _.addEventListener("click", (x) => {
232
- const j = parseFloat(this.parent._mapLinear(x.offsetX, 0, _.clientWidth, l, a)), I = parseFloat(this.parent._mapLinear(x.offsetY, 0, _.clientHeight, r, o));
233
- d[c] = j.toFixed(n), f[b] = I.toFixed(g), i && i(d[c], d[b]), this.parent.onUpdate ? this.parent.onUpdate() : this.parent.isFolder && this.parent.firstParent.onUpdate && this.parent.firstParent.onUpdate();
231
+ _.className = "p-gui__vector2-area", w.append(_), _.addEventListener("click", (m) => {
232
+ const U = parseFloat(this.parent._mapLinear(m.offsetX, 0, _.clientWidth, l, a)), I = parseFloat(this.parent._mapLinear(m.offsetY, 0, _.clientHeight, r, o));
233
+ p[h] = U.toFixed(n), g[b] = I.toFixed(f), i && i(p[h], p[b]), this.parent.onUpdate ? this.parent.onUpdate() : this.parent.isFolder && this.parent.firstParent.onUpdate && this.parent.firstParent.onUpdate();
234
234
  });
235
- const U = (x) => {
236
- const j = _.getBoundingClientRect(), I = x.clientX - j.left, $ = x.clientY - j.top, D = this.parent._mapLinear(I, 0, _.clientWidth, l, a), L = this.parent._mapLinear($, 0, _.clientHeight, r, o), F = Math.max(l, Math.min(a, D)), M = Math.max(o, Math.min(r, L));
237
- d[c] = parseFloat(F.toFixed(n)), f[b] = parseFloat(M.toFixed(g)), i && i(d[c], f[b]), this.parent.onUpdate ? this.parent.onUpdate() : this.parent.isFolder && this.parent.firstParent.onUpdate && this.parent.firstParent.onUpdate();
235
+ const j = (m) => {
236
+ const U = _.getBoundingClientRect(), I = m.clientX - U.left, O = m.clientY - U.top, $ = this.parent._mapLinear(I, 0, _.clientWidth, l, a), D = this.parent._mapLinear(O, 0, _.clientHeight, r, o), L = Math.max(l, Math.min(a, $)), F = Math.max(o, Math.min(r, D));
237
+ p[h] = parseFloat(L.toFixed(n)), g[b] = parseFloat(F.toFixed(f)), i && i(p[h], g[b]), this.parent.onUpdate ? this.parent.onUpdate() : this.parent.isFolder && this.parent.firstParent.onUpdate && this.parent.firstParent.onUpdate();
238
238
  };
239
- _.addEventListener("pointerdown", (x) => {
240
- U(x), document.addEventListener("pointermove", U), document.addEventListener("pointerup", () => {
241
- document.removeEventListener("pointermove", U);
239
+ _.addEventListener("pointerdown", (m) => {
240
+ j(m), document.addEventListener("pointermove", j), document.addEventListener("pointerup", () => {
241
+ document.removeEventListener("pointermove", j);
242
242
  }, { once: !0 });
243
243
  });
244
244
  const R = document.createElement("div");
245
245
  R.className = "p-gui__vector2-line p-gui__vector2-line-x", _.append(R);
246
246
  const P = document.createElement("div");
247
247
  P.className = "p-gui__vector2-line p-gui__vector2-line-y", _.append(P);
248
- const k = document.createElement("div");
249
- k.className = "p-gui__vector2-dot", _.append(k);
250
- const E = () => {
251
- k.style.left = this.parent._mapLinear(d[c], l, a, 0, _.clientWidth) + "px", k.style.top = this.parent._mapLinear(f[b], o, r, _.clientHeight, 0) + "px";
248
+ const E = document.createElement("div");
249
+ E.className = "p-gui__vector2-dot", _.append(E);
250
+ const k = () => {
251
+ E.style.left = this.parent._mapLinear(p[h], l, a, 0, _.clientWidth) + "px", E.style.top = this.parent._mapLinear(g[b], o, r, _.clientHeight, 0) + "px";
252
252
  };
253
- return E(), new ResizeObserver(() => {
254
- E();
255
- }).observe(_), Object.defineProperty(d, c, {
256
- set: (x) => {
257
- this.parent.propReferences[h] = x, E(), A.textContent = String(x) + ", " + f[b];
253
+ return k(), new ResizeObserver(() => {
254
+ k();
255
+ }).observe(_), Object.defineProperty(p, h, {
256
+ set: (m) => {
257
+ this.parent.propReferences[u] = m, k(), A.textContent = String(m) + ", " + g[b];
258
258
  },
259
- get: () => this.parent.propReferences[h]
260
- }), Object.defineProperty(f, b, {
261
- set: (x) => {
262
- this.parent.propReferences[v] = x, E(), A.textContent = d[c] + ", " + String(x);
259
+ get: () => this.parent.propReferences[u]
260
+ }), Object.defineProperty(g, b, {
261
+ set: (m) => {
262
+ this.parent.propReferences[v] = m, k(), A.textContent = p[h] + ", " + String(m);
263
263
  },
264
264
  get: () => this.parent.propReferences[v]
265
265
  }), w;
266
266
  }
267
267
  }
268
- const O = ".p-gui__button{background:var(--color-accent);text-align:center;color:var(--color-bg);border:none;border:1px solid transparent;box-sizing:border-box;transition:var(--transition) background,var(--transition) border-color}.p-gui__button:hover{background:var(--color-accent-hover);border-color:#fff3}.p-gui__folder .p-gui__button{margin-inline:0}", z = ".p-gui__slider{position:relative;min-height:14px;display:flex;align-items:center;justify-content:space-between;gap:10px;color:var(--color-text-dark);transition:color var(--transition);padding:3px}.p-gui__slider:hover{color:var(--color-text-light)}.p-gui__slider-name{width:50%;text-overflow:ellipsis;overflow:hidden}.p-gui__slider-ctrl{-webkit-appearance:none;padding:0;font:inherit;outline:none;box-sizing:border-box;cursor:pointer;position:relative;right:0;height:14px;margin:0 0 0 auto;width:37%}.p-gui__slider-bar{position:absolute;top:50%;left:0;height:2px;background:#fff3;width:100%;transform:translateY(-50%)}.p-gui__slider-filling{position:absolute;top:-25%;left:0;height:100%;background:var(--color-accent);width:0}.p-gui__slider:hover .p-gui__slider-filling{background:var(--color-accent-hover)}.p-gui__slider-handle{width:9px;height:9px;position:absolute;top:50%;left:0;border-radius:2px;transform:translate(-50%,-50%);pointer-events:none;background:var(--color-text-dark);box-shadow:0 0 2px #00000080}.p-gui__slider:hover .p-gui__slider-handle{background:var(--color-text-light)}.p-gui__slider-value{display:inline-block;right:7px;width:13%;border:none;color:#fff;border-radius:2px;background:#ffffff1a;padding:2px 4px;color:inherit}.p-gui__slider-value:focus{outline:none}", B = ".p-gui__list{cursor:default;color:var(--color-text-dark);transition:var(--transition) color}.p-gui__list:hover{color:var(--color-text-light)}.p-gui__list-dropdown{background:#ffffff0d;color:#fff;padding:0 12px 0 5px;top:0}.p-gui__list-dropdown{position:absolute;right:5px;top:0;bottom:0;margin:auto;height:calc(100% - 4px);cursor:pointer;border-radius:3px;border:1px solid var(--color-border-2);outline:none}.p-gui__list-dropdown option{background:#fff;color:#000}.p-gui__list-dropdown:hover{background:#ffffff1a}", V = ".p-gui__toggle{color:var(--color-text-dark);transition:var(--transition) background,var(--transition) color}.p-gui__toggle:hover{background:#ffffff1a;color:var(--color-text-light)}.p-gui__folder .p-gui__toggle{margin-inline:0}.p-gui__toggle-checkbox{width:10px;height:10px;background-color:#ffffff1a;position:absolute;top:0;right:10px;bottom:0;margin:auto;border-radius:2px;pointer-events:none;transition:.5s all ease}.p-gui__toggle-checkbox--active{background-color:#ddd;box-shadow:0 0 5px #ddd}", T = ".p-gui__color{cursor:default;color:var(--color-text-dark);transition:var(--transition) color}.p-gui__color:hover{color:var(--color-text-light)}.p-gui__color-picker{position:absolute;right:5px;top:0;bottom:0;margin:auto;height:calc(100% - 4px);cursor:pointer;border-radius:3px;border:1px solid var(--color-border-2);outline:none;-webkit-appearance:none;padding:0;background-color:transparent;border:1px solid #222222;overflow:hidden}.p-gui__color-picker::-webkit-color-swatch-wrapper{padding:0}.p-gui__color-picker::-webkit-color-swatch{border:none}", Q = ".p-gui__vector2{background:transparent;aspect-ratio:1;padding-bottom:0;color:var(--color-text-dark)}.p-gui__vector2:hover{color:var(--color-text-light)}.p-gui__vector2-area{position:relative;background:#0000004d;margin-top:8px;width:100%;height:calc(100% - 28px);touch-action:none}.p-gui__vector2-line{position:absolute;background:#fff;opacity:.3;pointer-events:none}.p-gui__vector2-line-x{width:100%;height:1px;left:0;top:50%;transform:translateY(-50%)}.p-gui__vector2-line-y{width:1px;height:100%;top:0;left:50%;transform:translate(-50%)}.p-gui__vector2-dot{position:absolute;top:0;left:0;width:8px;height:8px;border-radius:50%;background:#d5d5d5;border:2px solid #ff9999;transform:translate(-50%,-50%);pointer-events:none}.p-gui__vector-value{display:inline-block;right:7px;position:absolute}", q = '.p-gui__image-container{width:100%;padding:3px;display:flex;justify-content:flex-start;flex-wrap:wrap;box-sizing:border-box}.p-gui__image{background-size:cover;cursor:pointer;position:relative;margin:1px 2.5px 19px;border-radius:var(--main-border-radius);flex:0 0 calc(33.333% - 5px);height:90px;background-position:center;color:var(--color-text-dark);transition:var(--transition) color}.p-gui__image:hover{color:var(--color-text-light)}.p-gui__image:after{position:absolute;top:0;left:0;width:100%;height:100%;content:"";border:1px solid transparent;box-sizing:border-box;border-radius:var(--main-border-radius);transition:var(--transition) border-color}.p-gui__image--selected:after{border-color:#06ff89}.p-gui__image-text{position:absolute;bottom:-15px;text-shadow:0 -1px 0 #111;white-space:nowrap;width:100%;overflow:hidden;text-overflow:ellipsis}', J = ".p-gui__folder{width:100%;position:relative;background:var(--color-bg);overflow:auto;margin-bottom:2px;display:flex;flex-wrap:wrap;border:1px solid var(--color-border-2);padding:0 2px 0 3px;border-radius:var(--main-border-radius);box-sizing:border-box;border-left:1px solid #bbbbbb}.p-gui__folder--first{margin-top:0}.p-gui__folder--closed{height:25px;overflow:hidden}.p-gui__folder-header{padding:5px 3px;background-color:#00000080;color:#fff;cursor:pointer;width:100%;margin:0 -2px 2px -3px}.p-gui__folder-header:hover{background-color:#000000bf}.p-gui__folder-arrow{width:8px;height:8px;display:inline-block;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAHlBMVEUAAAD///////////////////////////////////8kfJuVAAAACXRSTlMA9Z1fCdMo1yxEJnA0AAAAK0lEQVQI12PABlRgjKkJUMZMYRhjpgqMAZSEMICSaIzpDWiKhdENhEhgAgATSg5jyWnYewAAAABJRU5ErkJggg==);background-size:contain;margin-right:5px;transform:rotate(90deg)}.p-gui__folder--closed .p-gui__folder-arrow{transform:rotate(0)}";
268
+ const Y = ".p-gui__button{background:var(--color-accent);text-align:center;color:var(--color-bg);border:1px solid transparent;box-sizing:border-box;transition:var(--transition) background,var(--transition) border-color}.p-gui__button:hover{background:var(--color-accent-hover);border-color:#fff3}.p-gui__folder .p-gui__button{margin-inline:0}", z = ".p-gui__slider{position:relative;min-height:14px;display:flex;align-items:center;justify-content:space-between;gap:10px;color:var(--color-text-dark);transition:color var(--transition);padding:3px}.p-gui__slider:hover{color:var(--color-text-light)}.p-gui__slider-name{width:50%;text-overflow:ellipsis;overflow:hidden}.p-gui__slider-ctrl{-webkit-appearance:none;padding:0;font:inherit;outline:none;box-sizing:border-box;cursor:pointer;position:relative;right:0;height:14px;margin:0 0 0 auto;width:37%}.p-gui__slider-bar{position:absolute;top:50%;left:0;height:2px;background:#fff3;width:100%;transform:translateY(-50%)}.p-gui__slider-filling{position:absolute;top:-25%;left:0;height:100%;background:var(--color-accent);width:0}.p-gui__slider:hover .p-gui__slider-filling{background:var(--color-accent-hover)}.p-gui__slider-handle{width:9px;height:9px;position:absolute;top:50%;left:0;border-radius:2px;transform:translate(-50%,-50%);pointer-events:none;background:var(--color-text-dark);box-shadow:0 0 2px #00000080}.p-gui__slider:hover .p-gui__slider-handle{background:var(--color-text-light)}.p-gui__slider-value{display:inline-block;right:7px;width:13%;border:none;color:#fff;border-radius:2px;background:#ffffff1a;padding:2px 4px;color:inherit}.p-gui__slider-value:focus{outline:none}", B = ".p-gui__list{cursor:default;color:var(--color-text-dark);transition:var(--transition) color}.p-gui__list:hover{color:var(--color-text-light)}.p-gui__list-dropdown{background:#ffffff0d;color:#fff;padding:0 12px 0 5px;top:0}.p-gui__list-dropdown{position:absolute;right:5px;top:0;bottom:0;margin:auto;height:calc(100% - 4px);cursor:pointer;border-radius:3px;border:1px solid var(--color-border-2);outline:none}.p-gui__list-dropdown option{background:#fff;color:#000}.p-gui__list-dropdown:hover{background:#ffffff1a}", V = ".p-gui__toggle{color:var(--color-text-dark);transition:var(--transition) background,var(--transition) color}.p-gui__toggle:hover{background:#ffffff1a;color:var(--color-text-light)}.p-gui__folder .p-gui__toggle{margin-inline:0}.p-gui__toggle-checkbox{width:10px;height:10px;background-color:#ffffff1a;position:absolute;top:0;right:10px;bottom:0;margin:auto;border-radius:2px;pointer-events:none;transition:.5s all ease}.p-gui__toggle-checkbox--active{background-color:#ddd;box-shadow:0 0 5px #ddd}", T = ".p-gui__color{cursor:default;color:var(--color-text-dark);transition:var(--transition) color}.p-gui__color:hover{color:var(--color-text-light)}.p-gui__color-picker{position:absolute;right:5px;top:0;bottom:0;margin:auto;height:calc(100% - 4px);cursor:pointer;border-radius:3px;border:1px solid var(--color-border-2);outline:none;-webkit-appearance:none;padding:0;background-color:transparent;border:1px solid #222222;overflow:hidden}.p-gui__color-picker::-webkit-color-swatch-wrapper{padding:0}.p-gui__color-picker::-webkit-color-swatch{border:none}", Q = ".p-gui__vector2{background:transparent;aspect-ratio:1;padding-bottom:0;color:var(--color-text-dark)}.p-gui__vector2:hover{color:var(--color-text-light)}.p-gui__vector2-area{position:relative;background:#0000004d;margin-top:8px;width:100%;height:calc(100% - 28px);touch-action:none}.p-gui__vector2-line{position:absolute;background:#fff;opacity:.3;pointer-events:none}.p-gui__vector2-line-x{width:100%;height:1px;left:0;top:50%;transform:translateY(-50%)}.p-gui__vector2-line-y{width:1px;height:100%;top:0;left:50%;transform:translate(-50%)}.p-gui__vector2-dot{position:absolute;top:0;left:0;width:8px;height:8px;border-radius:50%;background:#d5d5d5;border:2px solid #ff9999;transform:translate(-50%,-50%);pointer-events:none}.p-gui__vector-value{display:inline-block;right:7px;position:absolute}", q = '.p-gui__image-container{width:100%;padding:3px;display:flex;justify-content:flex-start;flex-wrap:wrap;box-sizing:border-box}.p-gui__image{background-size:cover;cursor:pointer;position:relative;margin:1px 2.5px 19px;border-radius:var(--main-border-radius);flex:0 0 calc(33.333% - 5px);height:90px;background-position:center;color:var(--color-text-dark);transition:var(--transition) color}.p-gui__image:hover{color:var(--color-text-light)}.p-gui__image:after{position:absolute;top:0;left:0;width:100%;height:100%;content:"";border:1px solid transparent;box-sizing:border-box;border-radius:var(--main-border-radius);transition:var(--transition) border-color}.p-gui__image--selected:after{border-color:#06ff89}.p-gui__image-text{position:absolute;bottom:-15px;text-shadow:0 -1px 0 #111;white-space:nowrap;width:100%;overflow:hidden;text-overflow:ellipsis}', J = ".p-gui__folder{width:100%;position:relative;background:var(--color-bg);margin-bottom:2px;display:flex;flex-wrap:wrap;border:1px solid var(--color-border-2);border-radius:var(--main-border-radius);box-sizing:border-box;border-left:1px solid #bbbbbb}.p-gui__folder--first{margin-top:0}.p-gui__folder-content{display:grid;grid-template-rows:1fr;transition:.25s grid-template-rows ease;width:100%}.p-gui__folder-inner{overflow:hidden;padding-left:3px;padding-right:2px}.p-gui__folder--closed .p-gui__folder-content{grid-template-rows:0fr}.p-gui__folder-header{padding:5px 3px;background-color:#00000080;color:#fff;cursor:pointer;width:100%;box-sizing:border-box;border-top-right-radius:var(--main-border-radius);border-bottom-right-radius:var(--main-border-radius)}.p-gui__folder-header:hover{background-color:#000000bf}.p-gui__folder-arrow{width:8px;height:8px;display:inline-block;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAHlBMVEUAAAD///////////////////////////////////8kfJuVAAAACXRSTlMA9Z1fCdMo1yxEJnA0AAAAK0lEQVQI12PABlRgjKkJUMZMYRhjpgqMAZSEMICSaIzpDWiKhdENhEhgAgATSg5jyWnYewAAAABJRU5ErkJggg==);background-size:contain;margin-right:5px;transform:rotate(90deg)}.p-gui__folder--closed .p-gui__folder-arrow{transform:rotate(0)}";
269
269
  function Z(y) {
270
- return console.log(O), `
270
+ return `
271
271
  .p-gui {
272
- --main-border-radius: 3px;
272
+ --main-border-radius: 6px;
273
273
  --color-bg: #161616;
274
274
  --color-border: #222222;
275
275
  --color-border-2: transparent;
@@ -283,15 +283,11 @@ function Z(y) {
283
283
  top: 0;
284
284
  left: 0;
285
285
  transform: translate3d(0,0,0);
286
- padding-top: 21px;
287
- padding-inline: 3px;
288
286
  background: var(--color-bg);
289
- display: block;
290
- justify-content: center;
291
- flex-wrap: wrap;
287
+ display: flex;
288
+ flex-direction: column;
292
289
  font-family: "Arial Rounded MT Bold", Arial, sans-serif;
293
290
  width: 290px;
294
- overflow: auto;
295
291
  box-shadow: 0 0 2px black;
296
292
  box-sizing: border-box;
297
293
  z-index: 99999;
@@ -303,6 +299,33 @@ function Z(y) {
303
299
  transition: var(--transition) opacity;
304
300
  }
305
301
 
302
+ .p-gui__content {
303
+ display: grid;
304
+ grid-template-rows: 1fr;
305
+ transition: 250ms grid-template-rows ease;
306
+ overflow: hidden;
307
+ }
308
+
309
+ .p-gui__inner {
310
+ padding-top: 1px;
311
+ padding-inline: 3px;
312
+ overflow: hidden;
313
+ min-height: 0;
314
+ }
315
+
316
+ .p-gui:not(.p-gui--collapsed) .p-gui__inner {
317
+ animation: p-gui-reveal-scroll 0s 250ms forwards;
318
+ }
319
+
320
+ @keyframes p-gui-reveal-scroll {
321
+ from { overflow: hidden; }
322
+ to { overflow: auto; }
323
+ }
324
+
325
+ .p-gui--collapsed .p-gui__content {
326
+ grid-template-rows: 0fr;
327
+ }
328
+
306
329
  .p-gui:hover {
307
330
  opacity: 1!important;
308
331
  }
@@ -330,14 +353,8 @@ function Z(y) {
330
353
  border: 1px solid #2f2f2f;
331
354
  }
332
355
 
333
- .p-gui--collapsed {
334
- height: 0;
335
- padding: 21px 10px 0 10px;
336
- overflow: hidden;
337
- }
338
-
339
356
  .p-gui__header {
340
- position: absolute;
357
+ position: relative;
341
358
  top: 0;
342
359
  left: 0;
343
360
  width: 100%;
@@ -395,7 +412,7 @@ function Z(y) {
395
412
  border-color: rgba(255,255,255,.2);
396
413
  }
397
414
 
398
- ${O}
415
+ ${Y}
399
416
 
400
417
  ${q}
401
418
 
@@ -414,7 +431,7 @@ function Z(y) {
414
431
  }
415
432
  class C {
416
433
  constructor(t = {}) {
417
- if (console.log("test"), this.firstParent = this, t.container ? (this.container = typeof t.container == "string" ? document.querySelector(t.container) : t.container, this.position_type = "absolute") : (this.container = document.body, this.position_type = "fixed"), this.propReferences = [], this.folders = [], t.isFolder) {
434
+ if (this.firstParent = this, t.container ? (this.container = typeof t.container == "string" ? document.querySelector(t.container) : t.container, this.position_type = "absolute") : (this.container = document.body, this.position_type = "fixed"), this.propReferences = [], this.folders = [], t.isFolder) {
418
435
  this._folderConstructor(t.folderOptions);
419
436
  return;
420
437
  }
@@ -445,7 +462,7 @@ class C {
445
462
  }`);
446
463
  }
447
464
  _folderConstructor(t) {
448
- this.wrapper = t.wrapper, this.isFolder = !0, this.parent = t.parent, this.firstParent = t.firstParent;
465
+ this.domElement = t.wrapper, this.isFolder = !0, this.parent = t.parent, this.firstParent = t.firstParent, this.wrapper = t.inner;
449
466
  }
450
467
  _parseScreenCorner(t) {
451
468
  let e = { x: "right", y: "top" };
@@ -463,7 +480,7 @@ class C {
463
480
  let t = this._getScrollbarWidth(this.container);
464
481
  if (this.xOffset = this.screenCorner.x == "left" ? 0 : this.container.clientWidth - this.wrapperWidth - t, this.instanceId > 0) {
465
482
  let e = this.container.querySelectorAll(
466
- `.p-gui:not(#${this.wrapper.id}):not([data-dragged])`
483
+ `.p-gui:not(#${this.domElement.id}):not([data-dragged])`
467
484
  );
468
485
  for (let i = 0; i < e.length && !(parseInt(
469
486
  e[i].id.replace("p-gui-", "")
@@ -475,38 +492,40 @@ class C {
475
492
  prevY: this.yOffset,
476
493
  x: this.xOffset,
477
494
  y: this.yOffset
478
- }, this.wrapper.style.transform = `translate3d(${this.position.x}px, ${this.position.y}px, 0)`;
495
+ }, this.domElement.style.transform = `translate3d(${this.position.x}px, ${this.position.y}px, 0)`;
479
496
  }
480
497
  _addStyles(t) {
481
498
  this.stylesheet.innerHTML += t;
482
499
  }
483
500
  _addWrapper() {
484
- this.wrapper = document.createElement("div"), this.wrapper.id = "p-gui-" + this.instanceId, this.wrapper.className = "p-gui", this.wrapper.setAttribute("data-lenis-prevent", ""), this.container.append(this.wrapper), this.header = document.createElement("div"), this.header.className = "p-gui__header", this.header.textContent = this.label, this.header.style = `${this.backgroundColor ? "border-color: " + this.backgroundColor + ";" : ""}`, this.wrapper.append(this.header);
501
+ this.domElement = document.createElement("div"), this.domElement.id = "p-gui-" + this.instanceId, this.domElement.className = "p-gui", this.domElement.setAttribute("data-lenis-prevent", ""), this.container.append(this.domElement), this.header = document.createElement("div"), this.header.className = "p-gui__header", this.header.textContent = this.label, this.header.style = `${this.backgroundColor ? "border-color: " + this.backgroundColor + ";" : ""}`, this.domElement.append(this.header);
485
502
  const t = document.createElement("div");
486
503
  t.className = "p-gui__header-close", t.addEventListener("click", this.toggleClose.bind(this)), this.header.append(t);
504
+ const e = document.createElement("div");
505
+ e.className = "p-gui__content", this.domElement.append(e), this.wrapper = document.createElement("div"), this.wrapper.className = "p-gui__inner", e.append(this.wrapper);
487
506
  }
488
507
  button(t = {}, e) {
489
- return this.imageContainer = null, new H(this, t, e);
508
+ return this.imageContainer = null, new M(this, t, e);
490
509
  }
491
510
  image(t = {}, e) {
492
- return this.imageContainer || (this.imageContainer = document.createElement("div"), this.imageContainer.className = "p-gui__image-container", this.wrapper.append(this.imageContainer)), new S(this, t, e);
511
+ return this.imageContainer || (this.imageContainer = document.createElement("div"), this.imageContainer.className = "p-gui__image-container", this.wrapper.append(this.imageContainer)), new H(this, t, e);
493
512
  }
494
513
  slider(t = {}, e) {
495
514
  return this.imageContainer = null, new N(this, t, e);
496
515
  }
497
516
  toggle(t = {}, e) {
498
517
  this.imageContainer = null;
499
- const i = new X(this, t, e);
518
+ const i = new S(this, t, e);
500
519
  return this.wrapper.append(i), i;
501
520
  }
502
521
  list(t = {}, e) {
503
- return this.imageContainer = null, new W(this, t, e);
522
+ return this.imageContainer = null, new X(this, t, e);
504
523
  }
505
524
  color(t = {}, e) {
506
- return this.imageContainer = null, new G(this, t, e);
525
+ return this.imageContainer = null, new W(this, t, e);
507
526
  }
508
527
  vector2(t = {}, e) {
509
- return this.imageContainer = null, new Y(this, t, e);
528
+ return this.imageContainer = null, new G(this, t, e);
510
529
  }
511
530
  folder(t = {}) {
512
531
  let e = typeof t.closed == "boolean" ? t.closed : !1, i = t.label || "", s = t.color || null, l = t.maxHeight || null;
@@ -517,19 +536,24 @@ class C {
517
536
  o += l ? `max-height: ${l}px;` : "";
518
537
  const r = document.createElement("div");
519
538
  r.className = a, r.style = o, this.wrapper.append(r);
520
- const p = document.createElement("div");
521
- p.innerHTML = `<span class="p-gui__folder-arrow"></span>${i}`, p.className = "p-gui__folder-header", r.append(p), p.addEventListener("click", () => {
539
+ const d = document.createElement("div");
540
+ d.innerHTML = `<span class="p-gui__folder-arrow"></span>${i}`, d.className = "p-gui__folder-header", r.append(d);
541
+ const c = document.createElement("div");
542
+ c.className = "p-gui__folder-content", r.append(c);
543
+ const n = document.createElement("div");
544
+ n.className = "p-gui__folder-inner", c.append(n), d.addEventListener("click", () => {
522
545
  r.classList.toggle("p-gui__folder--closed");
523
546
  });
524
- let u = new C({
547
+ let f = new C({
525
548
  isFolder: !0,
526
549
  folderOptions: {
527
550
  wrapper: r,
551
+ inner: n,
528
552
  parent: this,
529
553
  firstParent: this.firstParent
530
554
  }
531
555
  });
532
- return this.folders.push(u), u;
556
+ return this.folders.push(f), f;
533
557
  }
534
558
  _makeDraggable() {
535
559
  var t = this;
@@ -538,17 +562,17 @@ class C {
538
562
  l.preventDefault(), t.position.initX = t.position.x, t.position.initY = t.position.y, t.position.prevX = l.clientX, t.position.prevY = l.clientY, document.addEventListener("pointermove", i);
539
563
  }
540
564
  function i(l) {
541
- l.preventDefault(), t.hasBeenDragged || (t.hasBeenDragged = !0, t.wrapper.setAttribute("data-dragged", "true")), t.position.x = t.position.initX + l.clientX - t.position.prevX, t.position.y = t.position.initY + l.clientY - t.position.prevY, t.wrapper.style.transform = "translate3d(" + t.position.x + "px," + t.position.y + "px,0)";
565
+ l.preventDefault(), t.hasBeenDragged || (t.hasBeenDragged = !0, t.domElement.setAttribute("data-dragged", "true")), t.position.x = t.position.initX + l.clientX - t.position.prevX, t.position.y = t.position.initY + l.clientY - t.position.prevY, t.domElement.style.transform = "translate3d(" + t.position.x + "px," + t.position.y + "px,0)";
542
566
  }
543
567
  function s(l) {
544
568
  document.removeEventListener("pointermove", i);
545
569
  }
546
570
  }
547
571
  toggleClose() {
548
- this.closed = !this.closed, this.closed ? (this.previousInnerScroll = this.wrapper.scrollTop, this.wrapper.scrollTo(0, 0)) : this.wrapper.scrollTo(0, this.previousInnerScroll), this.wrapper.classList.toggle("p-gui--collapsed");
572
+ this.closed = !this.closed, this.closed ? (this.previousInnerScroll = this.wrapper.scrollTop, this.wrapper.scrollTo(0, 0)) : this.wrapper.scrollTo(0, this.previousInnerScroll), this.domElement.classList.toggle("p-gui--collapsed");
549
573
  }
550
574
  kill() {
551
- this.wrapper.remove();
575
+ this.domElement.remove();
552
576
  }
553
577
  _mapLinear(t, e, i, s, l) {
554
578
  return s + (t - e) * (l - s) / (i - e);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "perfect-gui",
3
3
  "type": "module",
4
- "version": "4.12.7",
4
+ "version": "4.12.9",
5
5
  "description": "GUI for JavaScript",
6
6
  "main": "src/index.js",
7
7
  "scripts": {
package/src/index.js CHANGED
@@ -199,11 +199,11 @@ export default class GUI {
199
199
  this.screenCorner.x == 'left'
200
200
  ? 0
201
201
  : this.container.clientWidth -
202
- this.wrapperWidth -
203
- scrollbar_width;
202
+ this.wrapperWidth -
203
+ scrollbar_width;
204
204
  if (this.instanceId > 0) {
205
205
  let existingDomInstances = this.container.querySelectorAll(
206
- `.p-gui:not(#${this.wrapper.id}):not([data-dragged])`,
206
+ `.p-gui:not(#${this.domElement.id}):not([data-dragged])`,
207
207
  );
208
208
  for (let i = 0; i < existingDomInstances.length; i++) {
209
209
  let instanceId = parseInt(