lexgui 0.6.5 → 0.6.7

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.
@@ -0,0 +1,354 @@
1
+ @import url('https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap');
2
+ @font-face {
3
+ font-family: "GeistSans";
4
+ src: url("https://raw.githubusercontent.com/jxarco/lexgui.js/master/data/GeistSans.ttf");
5
+ }
6
+
7
+ :root {
8
+ color-scheme: light dark;
9
+
10
+ --border-style: 1px solid #444;
11
+ --panel-width: 300px;
12
+ --page-padding: 24px;
13
+ --max-width: 960px;
14
+ --icon-size: 20px;
15
+ --stylish-color: light-dark(#fd18a5, #e2c886);
16
+ }
17
+
18
+ #content {
19
+ font-family: "GeistSans", sans-serif;
20
+ tab-size: 4;
21
+ max-width: var(--max-width);
22
+ width: 100%;
23
+ height: auto;
24
+ margin: 0 auto;
25
+ padding: var(--page-padding);
26
+ word-break: break-word;
27
+ text-align: justify;
28
+ text-justify: inter-word;
29
+ border-radius: 12px;
30
+ }
31
+
32
+ #content .lexarea.docs {
33
+ margin-block: 1.5em;
34
+ width: 80% !important;
35
+ justify-self: center;
36
+ }
37
+
38
+ #content::-webkit-scrollbar {
39
+ display: none;
40
+ }
41
+
42
+ .code-container {
43
+ position: relative;
44
+ margin: 16px calc(-1 * var(--page-padding));
45
+ }
46
+
47
+ .code-container button {
48
+ border: none;
49
+ outline: none;
50
+ background: none;
51
+ position: absolute;
52
+ top: 12px;
53
+ right: 12px;
54
+ font-size: 18px;
55
+ padding: 6px;
56
+ color: #bbb;
57
+ transition: color 0.25s;
58
+ z-index: 1;
59
+ }
60
+
61
+ .code-container button:hover {
62
+ color: #ccc;
63
+ cursor: pointer;
64
+ }
65
+
66
+ .code-container button.copied svg {
67
+ color: #42d065;
68
+ }
69
+
70
+ #content a {
71
+ color: var(--global-color-accent-light);
72
+ cursor: pointer;
73
+ text-decoration: none;
74
+ }
75
+
76
+ #content .lexpanel a, #content .lexarea a {
77
+ color: unset;
78
+ }
79
+
80
+ #content h1 {
81
+ font-size: 32px;
82
+ line-height: 48px;
83
+ margin-left: -2px;
84
+ margin-top: 0.67em;
85
+ margin-bottom: 0.67em;
86
+ font-optical-sizing: auto;
87
+ font-weight: 600;
88
+ font-style: normal;
89
+ font-variation-settings: "wdth" 100;
90
+ }
91
+
92
+ #content h2 {
93
+ font-size: 28px;
94
+ line-height: 36px;
95
+ font-weight: normal;
96
+ margin-left: -1px;
97
+ margin-top: 0.83em;
98
+ margin-bottom: 0.83em;
99
+ }
100
+
101
+ #content h3 {
102
+ font-size: 20px;
103
+ line-height: 28px;
104
+ font-weight: normal;
105
+ margin-top: 0.95em;
106
+ margin-bottom: 0.95em;
107
+ }
108
+
109
+ code {
110
+ font-family: "Roboto Mono", monospace;
111
+ font-size: 14px;
112
+ line-height: calc(var(--line-height) - 1px);
113
+ /* margin: 16px calc(-1 * var(--page-padding)); */
114
+ background-color: #282828;
115
+ text-align: unset !important;
116
+ text-justify: unset !important;
117
+ }
118
+
119
+ code.inline {
120
+ display: inline-block;
121
+ vertical-align: middle;
122
+ border-radius: 4px;
123
+ padding: 3px 6px;
124
+ margin: 0;
125
+ }
126
+
127
+ code.inline:not(.ref) {
128
+ color: var(--stylish-color);
129
+ font-weight: 500;
130
+ }
131
+
132
+ code:not(.inline) {
133
+ display: block;
134
+ padding: calc(var(--page-padding) - 6px) var(--page-padding);
135
+ /* white-space: pre-wrap; */
136
+ overflow: auto;
137
+ box-sizing: border-box;
138
+ position: relative;
139
+ border-radius: 6px;
140
+ }
141
+
142
+ code.inline.table {
143
+ padding: 0px 2px;
144
+ line-height: unset;
145
+ font-size: 13px;
146
+ }
147
+
148
+ code.inline.desc {
149
+ background-color: var(--global-color-tertiary);
150
+ color: var(--global-text-tertiary);
151
+ }
152
+
153
+ #content strong {
154
+ font-weight:700;
155
+ }
156
+
157
+ #content a.permalink {
158
+ float: right;
159
+ margin-left: 5px;
160
+ display: none;
161
+ }
162
+
163
+ #content > img {
164
+ width: 100%;
165
+ /* margin: 16px calc(-1 * var(--page-padding)) ; */
166
+ border-radius: 4px;
167
+ }
168
+
169
+ @media all and ( min-width: 1700px ) {
170
+
171
+ :root {
172
+ --panel-width: 360px;
173
+ --line-height: 28px;
174
+ --page-padding: 28px;
175
+ --icon-size: 24px;
176
+ }
177
+
178
+ #content h1 {
179
+ font-size: 42px;
180
+ line-height: 50px;
181
+ }
182
+
183
+ #content h2 {
184
+ font-size: 32px;
185
+ line-height: 40px;
186
+ }
187
+
188
+ #content h3 {
189
+ font-size: 24px;
190
+ line-height: 32px;
191
+ }
192
+
193
+ }
194
+
195
+ /* mobile */
196
+
197
+ @media all and ( max-width: 640px ) {
198
+
199
+ :root {
200
+ --page-padding: 16px;
201
+ --icon-size: 20px;
202
+ }
203
+
204
+ #content {
205
+ padding: var(--page-padding);
206
+ }
207
+
208
+ #content h1 {
209
+ font-size: 28px;
210
+ line-height: 36px;
211
+ padding-right: 20px;
212
+ margin-top: 0;
213
+ }
214
+
215
+ #content h2 {
216
+ font-size: 24px;
217
+ line-height: 32px;
218
+ margin-top: 24px;
219
+ }
220
+
221
+ #content h3 {
222
+ font-size: 20px;
223
+ line-height: 28px;
224
+ }
225
+
226
+ }
227
+
228
+ pre .str, code .str { color: #c79369; } /* string */
229
+ pre .kwd, code .kwd { color: #2194ce; } /* keyword */
230
+ pre .com, code .com { color: #999999; } /* comment */
231
+ pre .cls, code .cls { color: #4fccbd; } /* class */
232
+ pre .stc, code .stc { color: #0b6b60; } /* static member */
233
+ pre .stf, code .stf { color: #6d8cf5; } /* static function */
234
+ pre .lit, code .lit { color: #ce57b4; } /* literal */
235
+
236
+ pre .pre, code .pre { color: #8f8c8c; } /* preprocessor */
237
+ pre .pln, code .pln { color: #444444; } /* plaintext */
238
+ pre .dec, code .dec { color: #a5dba0; } /* decimal */
239
+ pre .mtd, code .mtd { color: #e6e2b8; } /* method */
240
+ pre .var, code .var { color: #d8d5d5; } /* variable */
241
+ pre .enu, code .enu { color: #c0dec2; } /* enum */
242
+
243
+ pre .tag, code .tag { color: #2194ce; } /* HTML tag */
244
+ pre .atn, code .atn { color: #81cdf8; } /* HTML attribute name */
245
+ pre .com, code .com { color: #4e994d; } /* comment */
246
+ pre .pln, code .pln { color: #aaaaaa; } /* plaintext */
247
+
248
+ .desc {
249
+ color: var(--global-text-tertiary);
250
+ }
251
+
252
+ a .desc {
253
+ color: var(--global-color-accent);
254
+ }
255
+
256
+ .param {
257
+ color: var(--stylish-color);
258
+ }
259
+
260
+ .prop, .method {
261
+ color: var(--stylish-color);
262
+ font-size: 16px;
263
+ }
264
+
265
+ code:has(.constructor) {
266
+ background: none;
267
+ }
268
+
269
+ .constructor {
270
+ color: var(--stylish-color);
271
+ font-size: 21px;
272
+ }
273
+
274
+ #content span.solid {
275
+ border-radius: 8px;
276
+ padding: 2px;
277
+ padding-inline: 8px;
278
+ }
279
+
280
+ #content span.outline {
281
+ border-radius: 8px;
282
+ padding: 2px;
283
+ padding-inline: 8px;
284
+ }
285
+
286
+ :root[data-theme="light"] #content {
287
+ color: #202124;
288
+ }
289
+
290
+ :root[data-theme="light"] code {
291
+ background-color: #ededed;
292
+ }
293
+
294
+ :root[data-theme="light"] code button {
295
+ color: #434e53;
296
+ }
297
+
298
+ :root[data-theme="light"] code button:hover {
299
+ color: #879094;
300
+ }
301
+
302
+ :root[data-theme="light"] pre .str, :root[data-theme="light"] code .str { color: #188038; }
303
+ :root[data-theme="light"] pre .kwd, :root[data-theme="light"] code .kwd { color: #1967d2; }
304
+ :root[data-theme="light"] pre .com, :root[data-theme="light"] code .com { color: #b80672; }
305
+ :root[data-theme="light"] pre .cls, :root[data-theme="light"] code .cls { color: #0b9484; }
306
+ :root[data-theme="light"] pre .dec, :root[data-theme="light"] code .dec { color: #c5221f; }
307
+ :root[data-theme="light"] pre .mtd, :root[data-theme="light"] code .mtd { color: #636362; }
308
+ :root[data-theme="light"] pre .lit, :root[data-theme="light"] code .lit { color: #1967d2; }
309
+ :root[data-theme="light"] pre .var, :root[data-theme="light"] code .var { color: #222222; }
310
+ :root[data-theme="light"] pre .enu, :root[data-theme="light"] code .enu { color: #505fe2; }
311
+ :root[data-theme="light"] pre .tag, :root[data-theme="light"] code .tag { color: #2183b4; }
312
+ :root[data-theme="light"] pre .atn, :root[data-theme="light"] code .atn { color: #a753c0; }
313
+
314
+ :root[data-theme="light"] .desc {
315
+ color: #70777a;
316
+ }
317
+
318
+ :root[data-theme="light"] a .desc {
319
+ color: var(--global-color-accent);
320
+ }
321
+
322
+ :root[data-theme="light"] .param {
323
+ color: #37474f;
324
+ }
325
+
326
+ :root[data-theme="light"] .prop, :root[data-theme="light"] .method {
327
+ color: #37474f;
328
+ }
329
+
330
+ :root[data-theme="light"] #goUpButton {
331
+ color: #37474f;
332
+ }
333
+
334
+ :root[data-theme="light"] #goUpButton:hover {
335
+ color: #879094;
336
+ }
337
+
338
+ .lextable {
339
+ overflow-x: scroll
340
+ }
341
+
342
+ .lextable table {
343
+ table-layout: auto;
344
+ }
345
+
346
+ .lextable table th {
347
+ white-space: nowrap;
348
+ }
349
+
350
+ /* Hack to shrink Type and Method columns in reference docs */
351
+ .lextable:has(input) table tbody tr:last-child td:not(:last-child) {
352
+ width: 1px;
353
+ white-space: nowrap;
354
+ }
package/build/lexgui.css CHANGED
@@ -3938,6 +3938,10 @@ meter:-moz-meter-sub-sub-optimum::-moz-meter-bar {
3938
3938
 
3939
3939
  /* Table Widget */
3940
3940
 
3941
+ .lextable {
3942
+ overflow-x: scroll;
3943
+ }
3944
+
3941
3945
  .lextable table {
3942
3946
  width: 100%;
3943
3947
  border: 1px solid;
@@ -3999,6 +4003,7 @@ meter:-moz-meter-sub-sub-optimum::-moz-meter-bar {
3999
4003
  padding-block: 2px;
4000
4004
  cursor: pointer;
4001
4005
  transition: all 0.1s linear;
4006
+ white-space: nowrap;
4002
4007
  background-color: var(--global-color-tertiary);
4003
4008
  -webkit-user-select: none;
4004
4009
  -moz-user-select: none;
@@ -5873,6 +5878,12 @@ ul.lexassetscontent {
5873
5878
  .hover\:fg-error:hover { color: var(--global-color-error) !important }
5874
5879
  .hover\:fg-warning:hover { color: var(--global-color-warning) !important }
5875
5880
 
5881
+ .hover\:scale-xs:hover { transform: scale(1.01); transition: transform 0.3s cubic-bezier(.42,.97,.52,1.19); }
5882
+ .hover\:scale-sm:hover { transform: scale(1.025); transition: transform 0.3s cubic-bezier(.42,.97,.52,1.19); }
5883
+ .hover\:scale-md:hover { transform: scale(1.05); transition: transform 0.3s cubic-bezier(.42,.97,.52,1.19); }
5884
+ .hover\:scale-bg:hover { transform: scale(1.1); transition: transform 0.3s cubic-bezier(.42,.97,.52,1.19); }
5885
+ .hover\:scale-xl:hover { transform: scale(1.25); transition: transform 0.3s cubic-bezier(.42,.97,.52,1.19); }
5886
+
5876
5887
  .stroke-none { stroke: none }
5877
5888
 
5878
5889
  /* Layout */
package/build/lexgui.js CHANGED
@@ -14,7 +14,7 @@ console.warn( 'Script _build/lexgui.js_ is depracated and will be removed soon.
14
14
  */
15
15
 
16
16
  const LX = {
17
- version: "0.6.5",
17
+ version: "0.6.7",
18
18
  ready: false,
19
19
  components: [], // Specific pre-build components
20
20
  signals: {}, // Events and triggers
@@ -877,7 +877,7 @@ class Sheet {
877
877
  this.root.dataset["side"] = this.side;
878
878
  this.root.tabIndex = "1";
879
879
  this.root.role = "dialog";
880
- this.root.className = "lexsheet fixed z-100 bg-primary";
880
+ this.root.className = "lexsheet fixed z-1000 bg-primary";
881
881
  LX.root.appendChild( this.root );
882
882
 
883
883
  this.root.addEventListener( "keydown", (e) => {
@@ -1151,6 +1151,7 @@ class DropdownMenu {
1151
1151
  {
1152
1152
  const checkbox = new LX.Checkbox( pKey + "_entryChecked", item.checked, (v) => {
1153
1153
  const f = item[ 'callback' ];
1154
+ item.checked = v;
1154
1155
  if( f )
1155
1156
  {
1156
1157
  f.call( this, key, v, menuItem );
@@ -2211,6 +2212,11 @@ class Tabs {
2211
2212
 
2212
2213
  delete( name ) {
2213
2214
 
2215
+ if( this.selected == name )
2216
+ {
2217
+ this.selected = null;
2218
+ }
2219
+
2214
2220
  const tabEl = this.tabDOMs[ name ];
2215
2221
 
2216
2222
  if( !tabEl || tabEl.fixed )
@@ -7408,11 +7414,6 @@ function ADD_CUSTOM_WIDGET( customWidgetName, options = {} )
7408
7414
 
7409
7415
  const refresh_widget = () => {
7410
7416
 
7411
- if( instance )
7412
- {
7413
- widget.instance = instance = Object.assign( LX.deepCopy(defaultInstance), instance );
7414
- }
7415
-
7416
7417
  if( container ) container.remove();
7417
7418
  if( customWidgetsDom ) customWidgetsDom.remove();
7418
7419
 
@@ -7477,13 +7478,36 @@ function ADD_CUSTOM_WIDGET( customWidgetName, options = {} )
7477
7478
  this.queue( customWidgetsDom );
7478
7479
 
7479
7480
  const on_instance_changed = ( key, value, event ) => {
7480
- instance[ key ] = value;
7481
+ const setter = options[ `_set_${ key }` ];
7482
+ if( setter )
7483
+ {
7484
+ setter.call( instance, value );
7485
+ }
7486
+ else
7487
+ {
7488
+ instance[ key ] = value;
7489
+ }
7481
7490
  widget._trigger( new LX.IEvent( name, instance, event ), callback );
7482
7491
  };
7483
7492
 
7484
7493
  for( let key in defaultInstance )
7485
7494
  {
7486
- const value = instance[ key ] ?? defaultInstance[ key ];
7495
+ let value = null;
7496
+
7497
+ const getter = options[ `_get_${ key }` ];
7498
+ if( getter )
7499
+ {
7500
+ value = instance[ key ] ? getter.call( instance ) : getter.call( defaultInstance );
7501
+ }
7502
+ else
7503
+ {
7504
+ value = instance[ key ] ?? defaultInstance[ key ];
7505
+ }
7506
+
7507
+ if( !value )
7508
+ {
7509
+ continue;
7510
+ }
7487
7511
 
7488
7512
  switch( value.constructor )
7489
7513
  {
@@ -7513,6 +7537,9 @@ function ADD_CUSTOM_WIDGET( customWidgetName, options = {} )
7513
7537
  this._addVector( value.length, key, value, on_instance_changed.bind( this, key ) );
7514
7538
  }
7515
7539
  break;
7540
+ default:
7541
+ console.warn( `Unsupported property type: ${ value.constructor.name }` );
7542
+ break;
7516
7543
  }
7517
7544
  }
7518
7545
 
@@ -8450,6 +8477,27 @@ class Button extends Widget {
8450
8477
  wValue.innerHTML = `<span>${ ( value || "" ) }</span>`;
8451
8478
  }
8452
8479
 
8480
+ if( options.fileInput )
8481
+ {
8482
+ const fileInput = document.createElement( "input" );
8483
+ fileInput.type = "file";
8484
+ fileInput.className = "file-input";
8485
+ fileInput.style.display = "none";
8486
+ wValue.appendChild( fileInput );
8487
+
8488
+ fileInput.addEventListener( 'change', function( e ) {
8489
+ const files = e.target.files;
8490
+ if( !files.length ) return;
8491
+
8492
+ const reader = new FileReader();
8493
+ if( options.fileInputType === 'text' ) reader.readAsText( files[ 0 ] );
8494
+ else if( options.fileInputType === 'buffer' ) reader.readAsArrayBuffer( files[ 0 ] );
8495
+ else if( options.fileInputType === 'bin' ) reader.readAsBinaryString( files[ 0 ] );
8496
+ else if( options.fileInputType === 'url' ) reader.readAsDataURL( files[ 0 ] );
8497
+ reader.onload = e => { callback.call( this, e.target.result, files[ 0 ] ); } ;
8498
+ });
8499
+ }
8500
+
8453
8501
  if( options.disabled )
8454
8502
  {
8455
8503
  this.disabled = true;
@@ -8502,8 +8550,15 @@ class Button extends Widget {
8502
8550
  wValue.classList.toggle('selected');
8503
8551
  }
8504
8552
 
8505
- const swapInput = wValue.querySelector( "input" );
8506
- this._trigger( new LX.IEvent( name, swapInput?.checked ?? value, e ), callback );
8553
+ if( options.fileInput )
8554
+ {
8555
+ wValue.querySelector( ".file-input" ).click();
8556
+ }
8557
+ else
8558
+ {
8559
+ const swapInput = wValue.querySelector( "input" );
8560
+ this._trigger( new LX.IEvent( name, swapInput?.checked ?? value, e ), callback );
8561
+ }
8507
8562
  });
8508
8563
 
8509
8564
  if( options.tooltip )
@@ -12839,6 +12894,8 @@ class Panel {
12839
12894
  * hideName: Don't use name as label [false]
12840
12895
  * disabled: Make the widget disabled [false]
12841
12896
  * icon: Icon class to show as button value
12897
+ * fileInput: Button click requests a file
12898
+ * fileInputType: Type of the requested file
12842
12899
  * img: Path to image to show as button value
12843
12900
  * title: Text to show in native Element title
12844
12901
  * buttonClass: Class to add to the native button element
@@ -14179,6 +14236,13 @@ class Sidebar {
14179
14236
  info.appendChild( infoSubtext );
14180
14237
  }
14181
14238
 
14239
+ // Add icon if onHeaderPressed is defined and not collapsable (it uses the toggler icon)
14240
+ if( options.onHeaderPressed && !this.collapsable )
14241
+ {
14242
+ const icon = LX.makeIcon( "MenuArrows" );
14243
+ header.appendChild( icon );
14244
+ }
14245
+
14182
14246
  return header;
14183
14247
  }
14184
14248
 
@@ -14224,8 +14288,13 @@ class Sidebar {
14224
14288
  info.appendChild( infoSubtext );
14225
14289
  }
14226
14290
 
14227
- const icon = LX.makeIcon( "MenuArrows" );
14228
- footer.appendChild( icon );
14291
+ // Add icon if onFooterPressed is defined
14292
+ // Useful to indicate that the footer is clickable
14293
+ if( options.onFooterPressed )
14294
+ {
14295
+ const icon = LX.makeIcon( "MenuArrows" );
14296
+ footer.appendChild( icon );
14297
+ }
14229
14298
 
14230
14299
  return footer;
14231
14300
  }
@@ -14526,20 +14595,17 @@ class Sidebar {
14526
14595
  return;
14527
14596
  }
14528
14597
 
14598
+ const f = options.callback;
14599
+ if( f ) f.call( this, key, item.value, e );
14600
+
14529
14601
  if( isCollapsable )
14530
14602
  {
14531
14603
  itemDom.querySelector( ".collapser" ).click();
14532
14604
  }
14533
- else
14605
+ else if( item.checkbox )
14534
14606
  {
14535
- const f = options.callback;
14536
- if( f ) f.call( this, key, item.value, e );
14537
-
14538
- if( item.checkbox )
14539
- {
14540
- item.value = !item.value;
14541
- item.checkbox.set( item.value, true );
14542
- }
14607
+ item.value = !item.value;
14608
+ item.checkbox.set( item.value, true );
14543
14609
  }
14544
14610
 
14545
14611
  // Manage selected