@xoong/ui 0.0.39 → 0.0.42

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xoong/ui",
3
- "version": "0.0.39",
3
+ "version": "0.0.42",
4
4
  "description": "xoong admin set: xoong.css tokens, <xo-table>, <xo-form>, <xo-dialog>, toast, confirm and a declarative History-API router. Depends on @xoong/core, @xoong/data and @xoong/forms.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -20,9 +20,9 @@
20
20
  "sideEffects": true,
21
21
  "license": "MIT",
22
22
  "dependencies": {
23
- "@xoong/core": "0.0.39",
24
- "@xoong/data": "0.0.39",
25
- "@xoong/forms": "0.0.39"
23
+ "@xoong/core": "0.0.42",
24
+ "@xoong/data": "0.0.42",
25
+ "@xoong/forms": "0.0.42"
26
26
  },
27
27
  "files": [
28
28
  "src"
@@ -42,7 +42,7 @@
42
42
  "bugs": {
43
43
  "url": "https://github.com/fpt-duongtx/xoong/issues"
44
44
  },
45
- "homepage": "https://github.com/fpt-duongtx/xoong#readme",
45
+ "homepage": "https://fpt-duongtx.github.io/xoong/",
46
46
  "types": "./src/index.d.ts",
47
47
  "publishConfig": {
48
48
  "access": "public"
package/src/mist.css CHANGED
@@ -313,6 +313,18 @@
313
313
  --ic-list-number: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 7h10M10 12h10M10 17h10M4 6l1.6-1v5M3.8 14.8c.6-1 2.6-1 2.6.4 0 1.4-2.6 1.8-2.7 3.3h2.9'/%3E%3C/svg%3E");
314
314
  --ic-quote: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 8C6 8.5 4.5 11 4.5 14v2h4.5v-4.5H6.5M19 8c-3 .5-4.5 3-4.5 6v2H19v-4.5h-2.5'/%3E%3C/svg%3E");
315
315
  --ic-code: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m8 8-4 4 4 4m8-8 4 4-4 4m-2.5-10.5-3 13'/%3E%3C/svg%3E");
316
+ --ic-bell: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 17V11a6 6 0 0 1 12 0v6l1.5 2h-15zM10 21h4'/%3E%3C/svg%3E");
317
+ --ic-settings: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3Cpath d='M12 3v2.5M12 18.5V21M3 12h2.5M18.5 12H21M5.6 5.6l1.8 1.8M16.6 16.6l1.8 1.8M18.4 5.6l-1.8 1.8M7.4 16.6l-1.8 1.8'/%3E%3C/svg%3E");
318
+ --ic-home: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 11 8-7 8 7M6 10v10h12V10'/%3E%3C/svg%3E");
319
+ --ic-chart: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 20V10m7 10V4m7 16v-7'/%3E%3C/svg%3E");
320
+ --ic-mail: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3.5' y='5.5' width='17' height='13' rx='2'/%3E%3Cpath d='m4 7 8 6 8-6'/%3E%3C/svg%3E");
321
+ --ic-star: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m12 4 2.4 5 5.4.7-4 3.8 1 5.4-4.8-2.6-4.8 2.6 1-5.4-4-3.8 5.4-.7z'/%3E%3C/svg%3E");
322
+ --ic-shield: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3.5 5 6v5.5c0 4.2 2.8 7.4 7 9 4.2-1.6 7-4.8 7-9V6z'/%3E%3Cpath d='m9 12 2.2 2.2L15 10'/%3E%3C/svg%3E");
323
+ --ic-zap: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M13 3 5 13.5h6L10 21l8-10.5h-6z'/%3E%3C/svg%3E");
324
+ --ic-globe: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M3 12h18M12 3c3 3 3 15 0 18M12 3c-3 3-3 15 0 18'/%3E%3C/svg%3E");
325
+ --ic-upload: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 16V5m-5 5 5-5 5 5M5 20h14'/%3E%3C/svg%3E");
326
+ --ic-users: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='8.5' r='3'/%3E%3Cpath d='M3.5 19c0-3.2 2.4-5 5.5-5s5.5 1.8 5.5 5M16 6a3 3 0 0 1 0 5.8M17.5 14.3c2 .6 3 2.2 3 4.7'/%3E%3C/svg%3E");
327
+ --ic-lock: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='5' y='11' width='14' height='9' rx='2'/%3E%3Cpath d='M8 11V8a4 4 0 0 1 8 0v3'/%3E%3C/svg%3E");
316
328
  --ic-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4' y='5' width='16' height='14' rx='2'/%3E%3Ccircle cx='9' cy='10' r='1.5'/%3E%3Cpath d='m4 17 5-5 4 4 3-3 4 4'/%3E%3C/svg%3E");
317
329
  --ic-calendar: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4' y='5' width='16' height='15' rx='2'/%3E%3Cpath d='M4 10h16M8 3v4m8-4v4'/%3E%3C/svg%3E");
318
330
  --ic-user: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8' r='3.5'/%3E%3Cpath d='M5 20c0-3.9 3.1-6 7-6s7 2.1 7 6'/%3E%3C/svg%3E");
@@ -377,6 +389,18 @@
377
389
  .ic[data-ic="palette"] { --ic: var(--ic-palette); }
378
390
  .ic[data-ic="sun"] { --ic: var(--ic-sun); }
379
391
  .ic[data-ic="moon"] { --ic: var(--ic-moon); }
392
+ .ic[data-ic="bell"] { --ic: var(--ic-bell); }
393
+ .ic[data-ic="settings"] { --ic: var(--ic-settings); }
394
+ .ic[data-ic="home"] { --ic: var(--ic-home); }
395
+ .ic[data-ic="chart"] { --ic: var(--ic-chart); }
396
+ .ic[data-ic="mail"] { --ic: var(--ic-mail); }
397
+ .ic[data-ic="star"] { --ic: var(--ic-star); }
398
+ .ic[data-ic="shield"] { --ic: var(--ic-shield); }
399
+ .ic[data-ic="zap"] { --ic: var(--ic-zap); }
400
+ .ic[data-ic="globe"] { --ic: var(--ic-globe); }
401
+ .ic[data-ic="upload"] { --ic: var(--ic-upload); }
402
+ .ic[data-ic="users"] { --ic: var(--ic-users); }
403
+ .ic[data-ic="lock"] { --ic: var(--ic-lock); }
380
404
 
381
405
  /* ---- components ---- */
382
406
  xo-tabs > [role="tablist"] { gap: .25rem; padding: 0; }
@@ -613,6 +637,7 @@
613
637
  align-items: center;
614
638
  width: 44px;
615
639
  height: 24px;
640
+ min-height: 0;
616
641
  padding: 0;
617
642
  cursor: pointer;
618
643
  background: var(--xo-color-control-border);
@@ -678,8 +703,27 @@
678
703
  .xo-switch--sm {
679
704
  width: 36px;
680
705
  height: 20px;
706
+ min-height: 0;
681
707
  border-radius: 10px;
682
708
  }
709
+ .xo-switch-row {
710
+ display: inline-flex;
711
+ gap: 12px;
712
+ align-items: center;
713
+ cursor: pointer;
714
+ }
715
+ .xo-switch-text {
716
+ font-size: 14px;
717
+ font-weight: 500;
718
+ line-height: 1.4;
719
+ color: var(--xo-color-text);
720
+ }
721
+ .xo-switch-row:has(.xo-switch:disabled) {
722
+ cursor: not-allowed;
723
+ }
724
+ .xo-switch-row:has(.xo-switch:disabled) .xo-switch-text {
725
+ color: var(--xo-color-text-2);
726
+ }
683
727
  .xo-switch--sm::after {
684
728
  width: 16px;
685
729
  height: 16px;
@@ -1274,7 +1318,7 @@
1274
1318
  .xo-date-open:hover { color: var(--xo-color-text); background: var(--xo-color-subtle); }
1275
1319
  .xo-date-open[aria-expanded="true"] { color: var(--xo-color-accent-strong); background: var(--xo-color-accent-soft); }
1276
1320
  .xo-date-open .ic { --xo-icon: 18px; }
1277
- .xo-date-panel { position: absolute; z-index: 20; box-sizing: border-box; width: calc(7 * 36px + 6 * 2px + 32px + 2px); max-width: calc(100vw - 16px); padding: 16px; }
1321
+ .xo-date-panel { overflow: auto; position: absolute; z-index: 20; box-sizing: border-box; width: calc(7 * 36px + 6 * 2px + 32px + 2px); max-width: calc(100vw - 16px); padding: 16px; }
1278
1322
  .xo-date-panel[hidden] { display: none; }
1279
1323
  .xo-date-head { display: grid; grid-template-columns: 32px 1fr 32px; align-items: center; gap: 8px; margin-bottom: 8px; }
1280
1324
  .xo-date-head > b { text-align: center; font: 600 14px/1.3 var(--xo-font); }
@@ -1363,6 +1407,67 @@
1363
1407
  font-size: 13px;
1364
1408
  color: var(--xo-color-text-2);
1365
1409
  }
1410
+ .xo-chart { margin: 0; }
1411
+ .xo-chart svg { width: 100%; height: auto; display: block; overflow: visible; }
1412
+ .xo-chart .grid { stroke: var(--xo-color-border); stroke-width: 1; }
1413
+ .xo-chart .axis { fill: var(--xo-color-text-2); font-size: 11px; font-family: inherit; }
1414
+ .xo-chart .bar { fill: var(--xo-color-accent); }
1415
+ .xo-chart .bar:hover, .xo-chart .bar:focus-visible { fill: var(--xo-color-accent-strong); }
1416
+ .xo-chart .line { fill: none; stroke: var(--xo-color-accent); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
1417
+ .xo-chart .area { fill: var(--xo-color-accent-soft); stroke: none; }
1418
+ .xo-chart .dot { fill: var(--xo-color-surface); stroke: var(--xo-color-accent); stroke-width: 2; }
1419
+ .xo-chart__legend { display: flex; gap: 16px; margin: 12px 0 0; padding: 0; list-style: none; font-size: 13px; color: var(--xo-color-text-2); }
1420
+ .xo-chart__legend i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; background: var(--xo-color-accent); margin-right: 6px; }
1421
+ .xo-chart__legend li + li i { background: var(--xo-color-border-strong, var(--xo-color-control-border)); }
1422
+ .xo-feed { list-style: none; margin: 0; padding: 0; display: grid; }
1423
+ .xo-feed li { display: grid; grid-template-columns: auto 1fr auto; gap: 12px; align-items: center; padding: 12px 0; border-top: 1px solid var(--xo-color-border); }
1424
+ .xo-feed li:first-child { border-top: 0; padding-top: 0; }
1425
+ .xo-feed__text { min-width: 0; font-size: 14px; color: var(--xo-color-text); }
1426
+ .xo-feed__text span { display: block; font-size: 13px; color: var(--xo-color-text-2); }
1427
+ .xo-feed time { font-size: 13px; color: var(--xo-color-text-2); white-space: nowrap; }
1428
+ .xo-dropzone { display: grid; place-items: center; gap: 6px; text-align: center; padding: 28px 16px; border: 1.5px dashed var(--xo-color-control-border); border-radius: calc(var(--xo-radius) + 2px); color: var(--xo-color-text-2); background: var(--xo-color-subtle); cursor: pointer; }
1429
+ .xo-dropzone:hover, .xo-dropzone[data-over] { border-color: var(--xo-color-accent); background: var(--xo-color-accent-soft); color: var(--xo-color-text); }
1430
+ .xo-dropzone:focus-within { outline: var(--xo-focus); outline-offset: 2px; }
1431
+ .xo-dropzone .icon { --xo-icon: 24px; }
1432
+ .xo-dropzone input { position: absolute; inline-size: 1px; block-size: 1px; opacity: 0; }
1433
+ .xo-dropzone { position: relative; }
1434
+ .xo-notify { position: relative; }
1435
+ .xo-notify__dot { position: absolute; top: 8px; right: 9px; width: 8px; height: 8px; border-radius: 50%; background: var(--xo-color-danger); box-shadow: 0 0 0 2px var(--xo-color-surface); }
1436
+ .xo-notify__dot[hidden] { display: none; }
1437
+ .xo-popover { position: absolute; z-index: 30; top: calc(100% + 8px); right: 0; width: min(340px, calc(100vw - 32px)); padding: 8px; background: var(--xo-color-surface); border: 1px solid var(--xo-color-border); border-radius: calc(var(--xo-radius) + 2px); box-shadow: var(--xo-shadow-pop); }
1438
+ .xo-popover[hidden] { display: none; }
1439
+ .xo-popover__head { display: flex; justify-content: space-between; align-items: center; padding: 8px 8px 10px; font-weight: 600; font-size: 14px; }
1440
+ .xo-popover .xo-feed li { padding: 10px 8px; border-radius: var(--xo-radius); }
1441
+ .xo-popover .xo-feed li:first-child { padding-top: 10px; }
1442
+ .xo-popover .xo-feed li:hover { background: var(--xo-color-subtle); }
1443
+ .xo-consent { position: fixed; z-index: 50; inset-inline: 16px; inset-block-end: 16px; max-width: 560px; margin-inline: auto 0; padding: 18px; background: var(--xo-color-surface); border: 1px solid var(--xo-color-border); border-radius: 16px; box-shadow: var(--xo-shadow-pop); display: grid; gap: 12px; }
1444
+ .xo-consent[hidden] { display: none; }
1445
+ .xo-consent p { margin: 0; font-size: 14px; line-height: 1.5; color: var(--xo-color-text-2); }
1446
+ .xo-consent p b { color: var(--xo-color-text); }
1447
+ .xo-consent .row-inline { justify-content: flex-end; }
1448
+ xo-theme-toggle { display: inline-flex; }
1449
+ xo-theme-toggle > button.icon-only[aria-pressed] { background: transparent; border-color: transparent; color: var(--xo-color-text-2); }
1450
+ xo-theme-toggle > button.icon-only[aria-pressed]:hover { background: var(--xo-color-subtle); color: var(--xo-color-text); }
1451
+ dialog.xo-command-dialog { padding: 0; border: 0; background: transparent; width: min(560px, calc(100vw - 32px)); max-width: none; margin: 12vh auto auto; overflow: visible; color: var(--xo-color-text); }
1452
+ dialog.xo-command-dialog:focus, dialog.xo-command-dialog:focus-visible { outline: none; }
1453
+ dialog.xo-command-dialog::backdrop { background: rgb(10 20 28 / .45); }
1454
+ dialog.xo-command-dialog .xo-command { width: 100%; }
1455
+ dialog.xo-command-dialog .xo-listbox { max-height: min(50vh, 360px); overflow: auto; }
1456
+ button.xo-option { width: 100%; border: 0; background: transparent; color: var(--xo-color-text); font: inherit; text-align: left; justify-content: flex-start; box-shadow: none; }
1457
+ button.xo-option:hover, button.xo-option.xo-option--active { background: var(--xo-color-accent-soft); color: var(--xo-color-accent-strong); }
1458
+ button.xo-option[aria-selected="true"] { background: var(--xo-color-accent-soft); color: var(--xo-color-accent-strong); }
1459
+ .xo-command .xo-command__input .ic { color: var(--xo-color-text-2); }
1460
+ xo-file { display: grid; gap: 8px; }
1461
+ xo-file .xo-dropzone .ic { width: 24px; height: 24px; }
1462
+ xo-file .error { display: flex; align-items: center; gap: 6px; margin: 0; font-size: 13px; color: var(--xo-color-danger); }
1463
+ xo-file progress { width: 100%; height: 6px; border: 0; border-radius: 999px; overflow: hidden; background: var(--xo-color-subtle); accent-color: var(--xo-color-accent); }
1464
+ xo-file progress::-webkit-progress-bar { background: var(--xo-color-subtle); }
1465
+ xo-file progress::-webkit-progress-value { background: var(--xo-color-accent); border-radius: 999px; }
1466
+ xo-file progress::-moz-progress-bar { background: var(--xo-color-accent); }
1467
+ .xo-file-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
1468
+ .xo-file-list li { display: flex; align-items: center; gap: 12px; padding: 8px 12px; border: 1px solid var(--xo-color-border); border-radius: var(--xo-radius); background: var(--xo-color-surface); font-size: 14px; }
1469
+ .xo-file-list li img { width: 40px; height: 40px; border-radius: 6px; object-fit: cover; flex: none; }
1470
+ .xo-file-list li span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1366
1471
 
1367
1472
  /* ---- skin ---- */
1368
1473
  :root { --shadow-sm: 0 1px 2px color-mix(in srgb, var(--xo-color-text) 6%, transparent); --shadow-float: 0 12px 32px color-mix(in srgb, var(--xo-color-text) 14%, transparent), 0 2px 6px color-mix(in srgb, var(--xo-color-text) 8%, transparent); --xo-shadow-pop: var(--shadow-float); --xo-shadow-raised: none; --xo-focus: 2px solid var(--xo-color-accent); --xo-focus-thin: 2px solid var(--xo-color-accent); }
package/src/router.js CHANGED
@@ -143,7 +143,9 @@ class XoRouter extends XoElement {
143
143
  const own = dirty.map((f) => f.getAttribute('xo-guard')).find((m) => m && m !== 'off');
144
144
  return ask(own ?? text('xoong.guard.leave', 'You have unsaved changes. Leave this page?'), { kind: 'leave', forms: dirty });
145
145
  });
146
- // url-params of a view: write the query string through the router, without rendering the route again
146
+ // url-params of a view: write the query string through the router, without rendering the route again.
147
+ // Nothing to subscribe to: Back/Forward is the router's (vetoes, guards): it sees the new query, renders the route again and the
148
+ // new view reads the URL. A view listening to popstate itself would change before a vetoed Back is undone.
147
149
  setUrlSync({ read: () => new URLSearchParams(window.location.search), write: (params, mode) => this.#writeQuery(params, mode), subscribe: () => () => {} });
148
150
  this.#go(this.#read(), 'replace', 'start').catch((e) => this.#report(e));
149
151
  }