@konomi-app/ui 5.1.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.js CHANGED
@@ -266,6 +266,7 @@ updateItemStatus_fn = function(key, itemKey, status) {
266
266
  // src/overlay-dialog.ts
267
267
  import { LitElement, html, nothing } from "lit";
268
268
  import { customElement, property, state } from "lit/decorators.js";
269
+ import { keyed } from "lit/directives/keyed.js";
269
270
  import { unsafeHTML } from "lit/directives/unsafe-html.js";
270
271
 
271
272
  // src/styles.ts
@@ -282,7 +283,7 @@ var overlayStyles = css`
282
283
  --dialog-z-index: 1000;
283
284
  --dialog-backdrop-color: rgb(255 255 255 / 0.73);
284
285
  --dialog-backdrop-blur: 4px;
285
- --dialog-transition-duration: 250ms;
286
+ --dialog-transition-duration: 280ms;
286
287
 
287
288
  /* Card */
288
289
  --dialog-card-bg: #fff;
@@ -372,7 +373,6 @@ var overlayStyles = css`
372
373
  min-height: var(--dialog-card-min-height);
373
374
  position: relative;
374
375
  overflow: hidden;
375
- transition: all var(--dialog-transition-duration) ease;
376
376
  }
377
377
 
378
378
  @media (min-width: 640px) {
@@ -384,22 +384,101 @@ var overlayStyles = css`
384
384
  }
385
385
  }
386
386
 
387
+ /* ─── Card Open / Close Animations ─── */
388
+
389
+ @keyframes card-enter {
390
+ from {
391
+ opacity: 0;
392
+ transform: translateY(28px) scale(0.96);
393
+ filter: blur(6px);
394
+ }
395
+ to {
396
+ opacity: 1;
397
+ transform: translateY(0) scale(1);
398
+ filter: blur(0);
399
+ }
400
+ }
401
+
402
+ @keyframes card-exit {
403
+ from {
404
+ opacity: 1;
405
+ transform: translateY(0) scale(1);
406
+ filter: blur(0);
407
+ }
408
+ to {
409
+ opacity: 0;
410
+ transform: translateY(14px) scale(0.97);
411
+ filter: blur(4px);
412
+ }
413
+ }
414
+
415
+ .backdrop[data-open] .card {
416
+ animation: card-enter 420ms cubic-bezier(0.16, 1, 0.3, 1) both;
417
+ }
418
+
419
+ .card[data-closing] {
420
+ animation: card-exit 300ms cubic-bezier(0.4, 0, 1, 1) both;
421
+ pointer-events: none;
422
+ }
423
+
387
424
  /* ─── Card Body ─── */
388
425
 
389
426
  .card-body {
390
427
  flex: 1;
391
428
  display: flex;
392
429
  flex-direction: column;
393
- align-items: center;
430
+ align-items: stretch;
394
431
  justify-content: center;
432
+ width: 100%;
433
+ }
434
+
435
+ /* ─── Body Inner (animated content wrapper) ─── */
436
+
437
+ @keyframes body-enter {
438
+ from {
439
+ opacity: 0;
440
+ transform: translateY(10px);
441
+ filter: blur(3px);
442
+ }
443
+ to {
444
+ opacity: 1;
445
+ transform: translateY(0);
446
+ filter: blur(0);
447
+ }
448
+ }
449
+
450
+ .body-inner {
451
+ display: flex;
452
+ flex-direction: column;
453
+ align-items: center;
395
454
  gap: 16px;
396
455
  width: 100%;
456
+ animation: body-enter 380ms 60ms cubic-bezier(0.16, 1, 0.3, 1) both;
397
457
  }
398
458
 
399
459
  /* ─── Spinner ─── */
400
460
 
401
- .spinner {
461
+ @keyframes spinner-enter {
462
+ from {
463
+ opacity: 0;
464
+ transform: scale(0.5);
465
+ }
466
+ to {
467
+ opacity: 1;
468
+ transform: scale(1);
469
+ }
470
+ }
471
+
472
+ /* spin と spinner-enter は同じ transform を書き換えるため衝突する。
473
+ ラッパーでスケール/フェードを担い、.spinner は回転専用にする。 */
474
+ .spinner-wrap {
402
475
  font-size: var(--dialog-spinner-size);
476
+ width: 1em;
477
+ height: 1em;
478
+ animation: spinner-enter 450ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
479
+ }
480
+
481
+ .spinner {
403
482
  width: 1em;
404
483
  height: 1em;
405
484
  border-radius: 50%;
@@ -440,6 +519,19 @@ var overlayStyles = css`
440
519
 
441
520
  /* ─── Icon ─── */
442
521
 
522
+ @keyframes icon-enter {
523
+ from {
524
+ opacity: 0;
525
+ transform: scale(0.4) rotate(-12deg);
526
+ filter: blur(4px);
527
+ }
528
+ to {
529
+ opacity: 1;
530
+ transform: scale(1) rotate(0deg);
531
+ filter: blur(0);
532
+ }
533
+ }
534
+
443
535
  .icon-container {
444
536
  width: 64px;
445
537
  height: 64px;
@@ -448,6 +540,7 @@ var overlayStyles = css`
448
540
  align-items: center;
449
541
  justify-content: center;
450
542
  flex-shrink: 0;
543
+ animation: icon-enter 500ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
451
544
  }
452
545
 
453
546
  .icon-container svg {
@@ -573,6 +666,7 @@ var overlayStyles = css`
573
666
  gap: 8px;
574
667
  width: 100%;
575
668
  margin-top: 8px;
669
+ animation: body-enter 320ms 160ms cubic-bezier(0.16, 1, 0.3, 1) both;
576
670
  }
577
671
 
578
672
  @media (min-width: 640px) {
@@ -592,7 +686,8 @@ var overlayStyles = css`
592
686
  font-weight: 500;
593
687
  transition:
594
688
  background-color 150ms ease,
595
- transform 80ms ease;
689
+ transform 80ms ease,
690
+ box-shadow 150ms ease;
596
691
  min-width: 100px;
597
692
  text-align: center;
598
693
  }
@@ -608,6 +703,7 @@ var overlayStyles = css`
608
703
 
609
704
  .btn-confirm:hover {
610
705
  background-color: var(--dialog-primary-hover);
706
+ box-shadow: 0 4px 12px rgb(59 130 246 / 0.35);
611
707
  }
612
708
 
613
709
  .btn-cancel {
@@ -631,11 +727,48 @@ var overlayStyles = css`
631
727
  list-style: none;
632
728
  }
633
729
 
730
+ @keyframes task-item-enter {
731
+ from {
732
+ opacity: 0;
733
+ transform: translateX(-8px);
734
+ }
735
+ to {
736
+ opacity: 1;
737
+ transform: translateX(0);
738
+ }
739
+ }
740
+
634
741
  .task-item {
635
742
  display: flex;
636
743
  align-items: center;
637
744
  gap: 12px;
638
745
  font-size: 14px;
746
+ animation: task-item-enter 300ms cubic-bezier(0.16, 1, 0.3, 1) both;
747
+ }
748
+
749
+ .task-item:nth-child(1) {
750
+ animation-delay: 40ms;
751
+ }
752
+ .task-item:nth-child(2) {
753
+ animation-delay: 80ms;
754
+ }
755
+ .task-item:nth-child(3) {
756
+ animation-delay: 120ms;
757
+ }
758
+ .task-item:nth-child(4) {
759
+ animation-delay: 160ms;
760
+ }
761
+ .task-item:nth-child(5) {
762
+ animation-delay: 200ms;
763
+ }
764
+ .task-item:nth-child(6) {
765
+ animation-delay: 240ms;
766
+ }
767
+ .task-item:nth-child(7) {
768
+ animation-delay: 280ms;
769
+ }
770
+ .task-item:nth-child(8) {
771
+ animation-delay: 320ms;
639
772
  }
640
773
 
641
774
  .task-icon {
@@ -685,6 +818,7 @@ var overlayStyles = css`
685
818
 
686
819
  .task-label {
687
820
  color: #6b7280;
821
+ transition: color 250ms ease;
688
822
  }
689
823
 
690
824
  .task-label[data-status='active'] {
@@ -692,8 +826,21 @@ var overlayStyles = css`
692
826
  font-weight: 500;
693
827
  }
694
828
 
829
+ @keyframes task-done-flash {
830
+ 0% {
831
+ transform: translateX(0);
832
+ }
833
+ 30% {
834
+ transform: translateX(4px);
835
+ }
836
+ 100% {
837
+ transform: translateX(0);
838
+ }
839
+ }
840
+
695
841
  .task-label[data-status='done'] {
696
842
  color: var(--dialog-success);
843
+ animation: task-done-flash 350ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
697
844
  }
698
845
 
699
846
  .task-label[data-status='error'] {
@@ -702,7 +849,6 @@ var overlayStyles = css`
702
849
 
703
850
  .task-label[data-status='skipped'] {
704
851
  color: #9ca3af;
705
- text-decoration: line-through;
706
852
  }
707
853
 
708
854
  /* ─── Queue ellipsis ─── */
@@ -738,17 +884,54 @@ var overlayStyles = css`
738
884
  margin-bottom: 8px;
739
885
  }
740
886
 
887
+ @keyframes step-dot-enter {
888
+ from {
889
+ opacity: 0;
890
+ transform: scale(0.4);
891
+ }
892
+ to {
893
+ opacity: 1;
894
+ transform: scale(1);
895
+ }
896
+ }
897
+
898
+ @keyframes step-pulse {
899
+ 0% {
900
+ box-shadow:
901
+ 0 0 0 0 rgb(59 130 246 / 0.5),
902
+ 0 0 0 3px rgb(59 130 246 / 0.2);
903
+ }
904
+ 70% {
905
+ box-shadow:
906
+ 0 0 0 7px rgb(59 130 246 / 0),
907
+ 0 0 0 3px rgb(59 130 246 / 0.2);
908
+ }
909
+ 100% {
910
+ box-shadow:
911
+ 0 0 0 0 rgb(59 130 246 / 0),
912
+ 0 0 0 3px rgb(59 130 246 / 0.2);
913
+ }
914
+ }
915
+
741
916
  .step-dot {
742
917
  width: 8px;
743
918
  height: 8px;
744
919
  border-radius: 50%;
745
920
  background-color: #d1d5db;
746
- transition: background-color 200ms ease;
921
+ transition:
922
+ background-color 250ms ease,
923
+ transform 250ms cubic-bezier(0.34, 1.56, 0.64, 1),
924
+ width 250ms cubic-bezier(0.34, 1.56, 0.64, 1);
925
+ animation: step-dot-enter 400ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
747
926
  }
748
927
 
749
928
  .step-dot[data-status='active'] {
750
929
  background-color: var(--dialog-primary);
751
- box-shadow: 0 0 0 3px rgb(59 130 246 / 0.2);
930
+ width: 20px;
931
+ border-radius: 4px;
932
+ animation:
933
+ step-dot-enter 400ms cubic-bezier(0.34, 1.56, 0.64, 1) both,
934
+ step-pulse 2s 400ms infinite;
752
935
  }
753
936
 
754
937
  .step-dot[data-status='done'] {
@@ -768,6 +951,7 @@ var overlayStyles = css`
768
951
  max-width: 24px;
769
952
  height: 2px;
770
953
  background-color: #e5e7eb;
954
+ transition: background-color 400ms ease;
771
955
  }
772
956
  `;
773
957
 
@@ -776,6 +960,8 @@ var OverlayDialog = class extends LitElement {
776
960
  constructor() {
777
961
  super(...arguments);
778
962
  this._state = createInitialState();
963
+ this._bodyKey = 0;
964
+ this._isClosing = false;
779
965
  this._beforeUnloadHandler = (e) => e.preventDefault();
780
966
  this._onKeyDown = (e) => {
781
967
  if (e.key === "Escape" && this._state.open) {
@@ -789,13 +975,24 @@ var OverlayDialog = class extends LitElement {
789
975
  this._state = { ...this.controller.state };
790
976
  this._unsubscribe = this.controller.subscribe((s) => {
791
977
  const wasOpen = this._state.open;
792
- this._state = s;
793
- this._syncBodyScroll(s.open);
978
+ const prevDialogType = this._state.dialogType;
794
979
  if (s.open && !wasOpen) {
980
+ this._isClosing = false;
981
+ clearTimeout(this._closeTimer);
795
982
  window.addEventListener("beforeunload", this._beforeUnloadHandler);
796
983
  } else if (!s.open && wasOpen) {
984
+ this._isClosing = true;
985
+ clearTimeout(this._closeTimer);
986
+ this._closeTimer = setTimeout(() => {
987
+ this._isClosing = false;
988
+ }, 320);
797
989
  window.removeEventListener("beforeunload", this._beforeUnloadHandler);
798
990
  }
991
+ if (s.open && s.dialogType !== prevDialogType) {
992
+ this._bodyKey++;
993
+ }
994
+ this._state = s;
995
+ this._syncBodyScroll(s.open);
799
996
  });
800
997
  }
801
998
  window.addEventListener("keydown", this._onKeyDown);
@@ -804,6 +1001,7 @@ var OverlayDialog = class extends LitElement {
804
1001
  super.disconnectedCallback();
805
1002
  this._unsubscribe?.();
806
1003
  this._syncBodyScroll(false);
1004
+ clearTimeout(this._closeTimer);
807
1005
  window.removeEventListener("beforeunload", this._beforeUnloadHandler);
808
1006
  window.removeEventListener("keydown", this._onKeyDown);
809
1007
  }
@@ -879,9 +1077,11 @@ var OverlayDialog = class extends LitElement {
879
1077
  }
880
1078
  _renderSpinner() {
881
1079
  return html`
882
- <div class="spinner">
883
- <div class="spinner-half">
884
- <div class="spinner-inner"></div>
1080
+ <div class="spinner-wrap">
1081
+ <div class="spinner">
1082
+ <div class="spinner-half">
1083
+ <div class="spinner-inner"></div>
1084
+ </div>
885
1085
  </div>
886
1086
  </div>
887
1087
  `;
@@ -1068,9 +1268,11 @@ var OverlayDialog = class extends LitElement {
1068
1268
  const showHeaderTitle = s.title && s.dialogType !== "alert" && s.dialogType !== "confirm";
1069
1269
  return html`
1070
1270
  <div class="backdrop" ?data-open=${s.open} @click=${this._onBackdropClick}>
1071
- <div class="card">
1271
+ <div class="card" ?data-closing=${this._isClosing}>
1072
1272
  ${showHeaderTitle ? html`<p class="dialog-title">${s.title}</p>` : nothing}
1073
- <div class="card-body">${this._renderBody()}</div>
1273
+ <div class="card-body">
1274
+ ${keyed(this._bodyKey, html`<div class="body-inner">${this._renderBody()}</div>`)}
1275
+ </div>
1074
1276
  <div
1075
1277
  class="progress-bar"
1076
1278
  style="width:${s.progress ?? 0}%;opacity:${s.progress !== null ? 1 : 0}"
@@ -1087,6 +1289,12 @@ __decorateClass([
1087
1289
  __decorateClass([
1088
1290
  state()
1089
1291
  ], OverlayDialog.prototype, "_state", 2);
1292
+ __decorateClass([
1293
+ state()
1294
+ ], OverlayDialog.prototype, "_bodyKey", 2);
1295
+ __decorateClass([
1296
+ state()
1297
+ ], OverlayDialog.prototype, "_isClosing", 2);
1090
1298
  OverlayDialog = __decorateClass([
1091
1299
  customElement("overlay-dialog")
1092
1300
  ], OverlayDialog);