@konomi-app/ui 5.0.0 → 5.2.1

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/dist/index.cjs CHANGED
@@ -111,12 +111,13 @@ var DialogController = class {
111
111
  // ─── Alert ───────────────────────────────────────────────
112
112
  alert(optionsOrLabel) {
113
113
  __privateMethod(this, _DialogController_instances, clearTimer_fn).call(this);
114
- const opts = typeof optionsOrLabel === "string" ? { label: optionsOrLabel } : optionsOrLabel;
114
+ const opts = typeof optionsOrLabel === "string" ? { title: optionsOrLabel } : optionsOrLabel;
115
115
  __privateMethod(this, _DialogController_instances, update_fn).call(this, {
116
116
  open: true,
117
117
  dialogType: "alert",
118
118
  icon: opts.type ?? "info",
119
- label: opts.label ?? "",
119
+ title: opts.title ?? "",
120
+ label: "",
120
121
  description: opts.description ?? "",
121
122
  html: opts.html ?? "",
122
123
  showConfirmButton: true,
@@ -133,12 +134,13 @@ var DialogController = class {
133
134
  // ─── Confirm ─────────────────────────────────────────────
134
135
  confirm(optionsOrLabel) {
135
136
  __privateMethod(this, _DialogController_instances, clearTimer_fn).call(this);
136
- const opts = typeof optionsOrLabel === "string" ? { label: optionsOrLabel } : optionsOrLabel;
137
+ const opts = typeof optionsOrLabel === "string" ? { title: optionsOrLabel } : optionsOrLabel;
137
138
  __privateMethod(this, _DialogController_instances, update_fn).call(this, {
138
139
  open: true,
139
140
  dialogType: "confirm",
140
141
  icon: opts.type ?? "warning",
141
- label: opts.label ?? "",
142
+ title: opts.title ?? "",
143
+ label: "",
142
144
  description: opts.description ?? "",
143
145
  showConfirmButton: true,
144
146
  showCancelButton: true,
@@ -289,6 +291,7 @@ updateItemStatus_fn = function(key, itemKey, status) {
289
291
  // src/overlay-dialog.ts
290
292
  var import_lit2 = require("lit");
291
293
  var import_decorators = require("lit/decorators.js");
294
+ var import_keyed = require("lit/directives/keyed.js");
292
295
  var import_unsafe_html = require("lit/directives/unsafe-html.js");
293
296
 
294
297
  // src/styles.ts
@@ -305,7 +308,7 @@ var overlayStyles = import_lit.css`
305
308
  --dialog-z-index: 1000;
306
309
  --dialog-backdrop-color: rgb(255 255 255 / 0.73);
307
310
  --dialog-backdrop-blur: 4px;
308
- --dialog-transition-duration: 250ms;
311
+ --dialog-transition-duration: 280ms;
309
312
 
310
313
  /* Card */
311
314
  --dialog-card-bg: #fff;
@@ -385,8 +388,8 @@ var overlayStyles = import_lit.css`
385
388
  display: flex;
386
389
  flex-direction: column;
387
390
  align-items: center;
388
- justify-content: center;
389
- gap: 16px;
391
+ justify-content: flex-start;
392
+ gap: 0;
390
393
  padding: var(--dialog-card-padding);
391
394
  background-color: var(--dialog-card-bg);
392
395
  border-radius: 0;
@@ -395,7 +398,6 @@ var overlayStyles = import_lit.css`
395
398
  min-height: var(--dialog-card-min-height);
396
399
  position: relative;
397
400
  overflow: hidden;
398
- transition: all var(--dialog-transition-duration) ease;
399
401
  }
400
402
 
401
403
  @media (min-width: 640px) {
@@ -407,10 +409,101 @@ var overlayStyles = import_lit.css`
407
409
  }
408
410
  }
409
411
 
412
+ /* ─── Card Open / Close Animations ─── */
413
+
414
+ @keyframes card-enter {
415
+ from {
416
+ opacity: 0;
417
+ transform: translateY(28px) scale(0.96);
418
+ filter: blur(6px);
419
+ }
420
+ to {
421
+ opacity: 1;
422
+ transform: translateY(0) scale(1);
423
+ filter: blur(0);
424
+ }
425
+ }
426
+
427
+ @keyframes card-exit {
428
+ from {
429
+ opacity: 1;
430
+ transform: translateY(0) scale(1);
431
+ filter: blur(0);
432
+ }
433
+ to {
434
+ opacity: 0;
435
+ transform: translateY(14px) scale(0.97);
436
+ filter: blur(4px);
437
+ }
438
+ }
439
+
440
+ .backdrop[data-open] .card {
441
+ animation: card-enter 420ms cubic-bezier(0.16, 1, 0.3, 1) both;
442
+ }
443
+
444
+ .card[data-closing] {
445
+ animation: card-exit 300ms cubic-bezier(0.4, 0, 1, 1) both;
446
+ pointer-events: none;
447
+ }
448
+
449
+ /* ─── Card Body ─── */
450
+
451
+ .card-body {
452
+ flex: 1;
453
+ display: flex;
454
+ flex-direction: column;
455
+ align-items: stretch;
456
+ justify-content: center;
457
+ width: 100%;
458
+ }
459
+
460
+ /* ─── Body Inner (animated content wrapper) ─── */
461
+
462
+ @keyframes body-enter {
463
+ from {
464
+ opacity: 0;
465
+ transform: translateY(10px);
466
+ filter: blur(3px);
467
+ }
468
+ to {
469
+ opacity: 1;
470
+ transform: translateY(0);
471
+ filter: blur(0);
472
+ }
473
+ }
474
+
475
+ .body-inner {
476
+ display: flex;
477
+ flex-direction: column;
478
+ align-items: center;
479
+ gap: 16px;
480
+ width: 100%;
481
+ animation: body-enter 380ms 60ms cubic-bezier(0.16, 1, 0.3, 1) both;
482
+ }
483
+
410
484
  /* ─── Spinner ─── */
411
485
 
412
- .spinner {
486
+ @keyframes spinner-enter {
487
+ from {
488
+ opacity: 0;
489
+ transform: scale(0.5);
490
+ }
491
+ to {
492
+ opacity: 1;
493
+ transform: scale(1);
494
+ }
495
+ }
496
+
497
+ /* spin と spinner-enter は同じ transform を書き換えるため衝突する。
498
+ ラッパーでスケール/フェードを担い、.spinner は回転専用にする。 */
499
+ .spinner-wrap {
413
500
  font-size: var(--dialog-spinner-size);
501
+ width: 1em;
502
+ height: 1em;
503
+ animation: spinner-enter 450ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
504
+ }
505
+
506
+ .spinner {
414
507
  width: 1em;
415
508
  height: 1em;
416
509
  border-radius: 50%;
@@ -451,6 +544,19 @@ var overlayStyles = import_lit.css`
451
544
 
452
545
  /* ─── Icon ─── */
453
546
 
547
+ @keyframes icon-enter {
548
+ from {
549
+ opacity: 0;
550
+ transform: scale(0.4) rotate(-12deg);
551
+ filter: blur(4px);
552
+ }
553
+ to {
554
+ opacity: 1;
555
+ transform: scale(1) rotate(0deg);
556
+ filter: blur(0);
557
+ }
558
+ }
559
+
454
560
  .icon-container {
455
561
  width: 64px;
456
562
  height: 64px;
@@ -459,6 +565,7 @@ var overlayStyles = import_lit.css`
459
565
  align-items: center;
460
566
  justify-content: center;
461
567
  flex-shrink: 0;
568
+ animation: icon-enter 500ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
462
569
  }
463
570
 
464
571
  .icon-container svg {
@@ -526,11 +633,11 @@ var overlayStyles = import_lit.css`
526
633
  /* ─── Text ─── */
527
634
 
528
635
  .dialog-title {
529
- font-size: 14px;
636
+ font-size: 18px;
530
637
  font-weight: 600;
531
638
  color: #374151;
532
639
  text-align: center;
533
- margin: 0;
640
+ margin: 0 0 16px;
534
641
  word-break: break-word;
535
642
  width: 100%;
536
643
  padding-bottom: 12px;
@@ -538,8 +645,8 @@ var overlayStyles = import_lit.css`
538
645
  }
539
646
 
540
647
  .label {
541
- font-size: 18px;
542
- font-weight: 600;
648
+ font-size: 16px;
649
+ font-weight: 400;
543
650
  color: #1f2937;
544
651
  text-align: center;
545
652
  margin: 0;
@@ -584,6 +691,7 @@ var overlayStyles = import_lit.css`
584
691
  gap: 8px;
585
692
  width: 100%;
586
693
  margin-top: 8px;
694
+ animation: body-enter 320ms 160ms cubic-bezier(0.16, 1, 0.3, 1) both;
587
695
  }
588
696
 
589
697
  @media (min-width: 640px) {
@@ -603,7 +711,8 @@ var overlayStyles = import_lit.css`
603
711
  font-weight: 500;
604
712
  transition:
605
713
  background-color 150ms ease,
606
- transform 80ms ease;
714
+ transform 80ms ease,
715
+ box-shadow 150ms ease;
607
716
  min-width: 100px;
608
717
  text-align: center;
609
718
  }
@@ -619,6 +728,7 @@ var overlayStyles = import_lit.css`
619
728
 
620
729
  .btn-confirm:hover {
621
730
  background-color: var(--dialog-primary-hover);
731
+ box-shadow: 0 4px 12px rgb(59 130 246 / 0.35);
622
732
  }
623
733
 
624
734
  .btn-cancel {
@@ -642,11 +752,48 @@ var overlayStyles = import_lit.css`
642
752
  list-style: none;
643
753
  }
644
754
 
755
+ @keyframes task-item-enter {
756
+ from {
757
+ opacity: 0;
758
+ transform: translateX(-8px);
759
+ }
760
+ to {
761
+ opacity: 1;
762
+ transform: translateX(0);
763
+ }
764
+ }
765
+
645
766
  .task-item {
646
767
  display: flex;
647
768
  align-items: center;
648
769
  gap: 12px;
649
770
  font-size: 14px;
771
+ animation: task-item-enter 300ms cubic-bezier(0.16, 1, 0.3, 1) both;
772
+ }
773
+
774
+ .task-item:nth-child(1) {
775
+ animation-delay: 40ms;
776
+ }
777
+ .task-item:nth-child(2) {
778
+ animation-delay: 80ms;
779
+ }
780
+ .task-item:nth-child(3) {
781
+ animation-delay: 120ms;
782
+ }
783
+ .task-item:nth-child(4) {
784
+ animation-delay: 160ms;
785
+ }
786
+ .task-item:nth-child(5) {
787
+ animation-delay: 200ms;
788
+ }
789
+ .task-item:nth-child(6) {
790
+ animation-delay: 240ms;
791
+ }
792
+ .task-item:nth-child(7) {
793
+ animation-delay: 280ms;
794
+ }
795
+ .task-item:nth-child(8) {
796
+ animation-delay: 320ms;
650
797
  }
651
798
 
652
799
  .task-icon {
@@ -696,6 +843,7 @@ var overlayStyles = import_lit.css`
696
843
 
697
844
  .task-label {
698
845
  color: #6b7280;
846
+ transition: color 250ms ease;
699
847
  }
700
848
 
701
849
  .task-label[data-status='active'] {
@@ -703,8 +851,21 @@ var overlayStyles = import_lit.css`
703
851
  font-weight: 500;
704
852
  }
705
853
 
854
+ @keyframes task-done-flash {
855
+ 0% {
856
+ transform: translateX(0);
857
+ }
858
+ 30% {
859
+ transform: translateX(4px);
860
+ }
861
+ 100% {
862
+ transform: translateX(0);
863
+ }
864
+ }
865
+
706
866
  .task-label[data-status='done'] {
707
867
  color: var(--dialog-success);
868
+ animation: task-done-flash 350ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
708
869
  }
709
870
 
710
871
  .task-label[data-status='error'] {
@@ -713,7 +874,6 @@ var overlayStyles = import_lit.css`
713
874
 
714
875
  .task-label[data-status='skipped'] {
715
876
  color: #9ca3af;
716
- text-decoration: line-through;
717
877
  }
718
878
 
719
879
  /* ─── Queue ellipsis ─── */
@@ -749,17 +909,54 @@ var overlayStyles = import_lit.css`
749
909
  margin-bottom: 8px;
750
910
  }
751
911
 
912
+ @keyframes step-dot-enter {
913
+ from {
914
+ opacity: 0;
915
+ transform: scale(0.4);
916
+ }
917
+ to {
918
+ opacity: 1;
919
+ transform: scale(1);
920
+ }
921
+ }
922
+
923
+ @keyframes step-pulse {
924
+ 0% {
925
+ box-shadow:
926
+ 0 0 0 0 rgb(59 130 246 / 0.5),
927
+ 0 0 0 3px rgb(59 130 246 / 0.2);
928
+ }
929
+ 70% {
930
+ box-shadow:
931
+ 0 0 0 7px rgb(59 130 246 / 0),
932
+ 0 0 0 3px rgb(59 130 246 / 0.2);
933
+ }
934
+ 100% {
935
+ box-shadow:
936
+ 0 0 0 0 rgb(59 130 246 / 0),
937
+ 0 0 0 3px rgb(59 130 246 / 0.2);
938
+ }
939
+ }
940
+
752
941
  .step-dot {
753
942
  width: 8px;
754
943
  height: 8px;
755
944
  border-radius: 50%;
756
945
  background-color: #d1d5db;
757
- transition: background-color 200ms ease;
946
+ transition:
947
+ background-color 250ms ease,
948
+ transform 250ms cubic-bezier(0.34, 1.56, 0.64, 1),
949
+ width 250ms cubic-bezier(0.34, 1.56, 0.64, 1);
950
+ animation: step-dot-enter 400ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
758
951
  }
759
952
 
760
953
  .step-dot[data-status='active'] {
761
954
  background-color: var(--dialog-primary);
762
- box-shadow: 0 0 0 3px rgb(59 130 246 / 0.2);
955
+ width: 20px;
956
+ border-radius: 4px;
957
+ animation:
958
+ step-dot-enter 400ms cubic-bezier(0.34, 1.56, 0.64, 1) both,
959
+ step-pulse 2s 400ms infinite;
763
960
  }
764
961
 
765
962
  .step-dot[data-status='done'] {
@@ -779,6 +976,7 @@ var overlayStyles = import_lit.css`
779
976
  max-width: 24px;
780
977
  height: 2px;
781
978
  background-color: #e5e7eb;
979
+ transition: background-color 400ms ease;
782
980
  }
783
981
  `;
784
982
 
@@ -787,6 +985,8 @@ var OverlayDialog = class extends import_lit2.LitElement {
787
985
  constructor() {
788
986
  super(...arguments);
789
987
  this._state = createInitialState();
988
+ this._bodyKey = 0;
989
+ this._isClosing = false;
790
990
  this._beforeUnloadHandler = (e) => e.preventDefault();
791
991
  this._onKeyDown = (e) => {
792
992
  if (e.key === "Escape" && this._state.open) {
@@ -800,13 +1000,24 @@ var OverlayDialog = class extends import_lit2.LitElement {
800
1000
  this._state = { ...this.controller.state };
801
1001
  this._unsubscribe = this.controller.subscribe((s) => {
802
1002
  const wasOpen = this._state.open;
803
- this._state = s;
804
- this._syncBodyScroll(s.open);
1003
+ const prevDialogType = this._state.dialogType;
805
1004
  if (s.open && !wasOpen) {
1005
+ this._isClosing = false;
1006
+ clearTimeout(this._closeTimer);
806
1007
  window.addEventListener("beforeunload", this._beforeUnloadHandler);
807
1008
  } else if (!s.open && wasOpen) {
1009
+ this._isClosing = true;
1010
+ clearTimeout(this._closeTimer);
1011
+ this._closeTimer = setTimeout(() => {
1012
+ this._isClosing = false;
1013
+ }, 320);
808
1014
  window.removeEventListener("beforeunload", this._beforeUnloadHandler);
809
1015
  }
1016
+ if (s.open && s.dialogType !== prevDialogType) {
1017
+ this._bodyKey++;
1018
+ }
1019
+ this._state = s;
1020
+ this._syncBodyScroll(s.open);
810
1021
  });
811
1022
  }
812
1023
  window.addEventListener("keydown", this._onKeyDown);
@@ -815,6 +1026,7 @@ var OverlayDialog = class extends import_lit2.LitElement {
815
1026
  super.disconnectedCallback();
816
1027
  this._unsubscribe?.();
817
1028
  this._syncBodyScroll(false);
1029
+ clearTimeout(this._closeTimer);
818
1030
  window.removeEventListener("beforeunload", this._beforeUnloadHandler);
819
1031
  window.removeEventListener("keydown", this._onKeyDown);
820
1032
  }
@@ -890,9 +1102,11 @@ var OverlayDialog = class extends import_lit2.LitElement {
890
1102
  }
891
1103
  _renderSpinner() {
892
1104
  return import_lit2.html`
893
- <div class="spinner">
894
- <div class="spinner-half">
895
- <div class="spinner-inner"></div>
1105
+ <div class="spinner-wrap">
1106
+ <div class="spinner">
1107
+ <div class="spinner-half">
1108
+ <div class="spinner-inner"></div>
1109
+ </div>
896
1110
  </div>
897
1111
  </div>
898
1112
  `;
@@ -1055,7 +1269,7 @@ var OverlayDialog = class extends import_lit2.LitElement {
1055
1269
  case "alert":
1056
1270
  case "confirm":
1057
1271
  return import_lit2.html`
1058
- ${this._renderIcon(s.icon)} ${s.label ? import_lit2.html`<p class="label">${s.label}</p>` : import_lit2.nothing}
1272
+ ${this._renderIcon(s.icon)} ${s.title ? import_lit2.html`<p class="label">${s.title}</p>` : import_lit2.nothing}
1059
1273
  ${s.description ? import_lit2.html`<p class="description">${s.description}</p>` : import_lit2.nothing}
1060
1274
  ${s.html ? import_lit2.html`<div class="html-content">${(0, import_unsafe_html.unsafeHTML)(s.html)}</div>` : import_lit2.nothing}
1061
1275
  ${this._renderButtons()}
@@ -1076,10 +1290,14 @@ var OverlayDialog = class extends import_lit2.LitElement {
1076
1290
  }
1077
1291
  render() {
1078
1292
  const s = this._state;
1293
+ const showHeaderTitle = s.title && s.dialogType !== "alert" && s.dialogType !== "confirm";
1079
1294
  return import_lit2.html`
1080
1295
  <div class="backdrop" ?data-open=${s.open} @click=${this._onBackdropClick}>
1081
- <div class="card">
1082
- ${s.title ? import_lit2.html`<p class="dialog-title">${s.title}</p>` : import_lit2.nothing} ${this._renderBody()}
1296
+ <div class="card" ?data-closing=${this._isClosing}>
1297
+ ${showHeaderTitle ? import_lit2.html`<p class="dialog-title">${s.title}</p>` : import_lit2.nothing}
1298
+ <div class="card-body">
1299
+ ${(0, import_keyed.keyed)(this._bodyKey, import_lit2.html`<div class="body-inner">${this._renderBody()}</div>`)}
1300
+ </div>
1083
1301
  <div
1084
1302
  class="progress-bar"
1085
1303
  style="width:${s.progress ?? 0}%;opacity:${s.progress !== null ? 1 : 0}"
@@ -1096,6 +1314,12 @@ __decorateClass([
1096
1314
  __decorateClass([
1097
1315
  (0, import_decorators.state)()
1098
1316
  ], OverlayDialog.prototype, "_state", 2);
1317
+ __decorateClass([
1318
+ (0, import_decorators.state)()
1319
+ ], OverlayDialog.prototype, "_bodyKey", 2);
1320
+ __decorateClass([
1321
+ (0, import_decorators.state)()
1322
+ ], OverlayDialog.prototype, "_isClosing", 2);
1099
1323
  OverlayDialog = __decorateClass([
1100
1324
  (0, import_decorators.customElement)("overlay-dialog")
1101
1325
  ], OverlayDialog);