@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.js CHANGED
@@ -86,12 +86,13 @@ var DialogController = class {
86
86
  // ─── Alert ───────────────────────────────────────────────
87
87
  alert(optionsOrLabel) {
88
88
  __privateMethod(this, _DialogController_instances, clearTimer_fn).call(this);
89
- const opts = typeof optionsOrLabel === "string" ? { label: optionsOrLabel } : optionsOrLabel;
89
+ const opts = typeof optionsOrLabel === "string" ? { title: optionsOrLabel } : optionsOrLabel;
90
90
  __privateMethod(this, _DialogController_instances, update_fn).call(this, {
91
91
  open: true,
92
92
  dialogType: "alert",
93
93
  icon: opts.type ?? "info",
94
- label: opts.label ?? "",
94
+ title: opts.title ?? "",
95
+ label: "",
95
96
  description: opts.description ?? "",
96
97
  html: opts.html ?? "",
97
98
  showConfirmButton: true,
@@ -108,12 +109,13 @@ var DialogController = class {
108
109
  // ─── Confirm ─────────────────────────────────────────────
109
110
  confirm(optionsOrLabel) {
110
111
  __privateMethod(this, _DialogController_instances, clearTimer_fn).call(this);
111
- const opts = typeof optionsOrLabel === "string" ? { label: optionsOrLabel } : optionsOrLabel;
112
+ const opts = typeof optionsOrLabel === "string" ? { title: optionsOrLabel } : optionsOrLabel;
112
113
  __privateMethod(this, _DialogController_instances, update_fn).call(this, {
113
114
  open: true,
114
115
  dialogType: "confirm",
115
116
  icon: opts.type ?? "warning",
116
- label: opts.label ?? "",
117
+ title: opts.title ?? "",
118
+ label: "",
117
119
  description: opts.description ?? "",
118
120
  showConfirmButton: true,
119
121
  showCancelButton: true,
@@ -264,6 +266,7 @@ updateItemStatus_fn = function(key, itemKey, status) {
264
266
  // src/overlay-dialog.ts
265
267
  import { LitElement, html, nothing } from "lit";
266
268
  import { customElement, property, state } from "lit/decorators.js";
269
+ import { keyed } from "lit/directives/keyed.js";
267
270
  import { unsafeHTML } from "lit/directives/unsafe-html.js";
268
271
 
269
272
  // src/styles.ts
@@ -280,7 +283,7 @@ var overlayStyles = css`
280
283
  --dialog-z-index: 1000;
281
284
  --dialog-backdrop-color: rgb(255 255 255 / 0.73);
282
285
  --dialog-backdrop-blur: 4px;
283
- --dialog-transition-duration: 250ms;
286
+ --dialog-transition-duration: 280ms;
284
287
 
285
288
  /* Card */
286
289
  --dialog-card-bg: #fff;
@@ -360,8 +363,8 @@ var overlayStyles = css`
360
363
  display: flex;
361
364
  flex-direction: column;
362
365
  align-items: center;
363
- justify-content: center;
364
- gap: 16px;
366
+ justify-content: flex-start;
367
+ gap: 0;
365
368
  padding: var(--dialog-card-padding);
366
369
  background-color: var(--dialog-card-bg);
367
370
  border-radius: 0;
@@ -370,7 +373,6 @@ var overlayStyles = css`
370
373
  min-height: var(--dialog-card-min-height);
371
374
  position: relative;
372
375
  overflow: hidden;
373
- transition: all var(--dialog-transition-duration) ease;
374
376
  }
375
377
 
376
378
  @media (min-width: 640px) {
@@ -382,10 +384,101 @@ var overlayStyles = css`
382
384
  }
383
385
  }
384
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
+
424
+ /* ─── Card Body ─── */
425
+
426
+ .card-body {
427
+ flex: 1;
428
+ display: flex;
429
+ flex-direction: column;
430
+ align-items: stretch;
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;
454
+ gap: 16px;
455
+ width: 100%;
456
+ animation: body-enter 380ms 60ms cubic-bezier(0.16, 1, 0.3, 1) both;
457
+ }
458
+
385
459
  /* ─── Spinner ─── */
386
460
 
387
- .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 {
388
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 {
389
482
  width: 1em;
390
483
  height: 1em;
391
484
  border-radius: 50%;
@@ -426,6 +519,19 @@ var overlayStyles = css`
426
519
 
427
520
  /* ─── Icon ─── */
428
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
+
429
535
  .icon-container {
430
536
  width: 64px;
431
537
  height: 64px;
@@ -434,6 +540,7 @@ var overlayStyles = css`
434
540
  align-items: center;
435
541
  justify-content: center;
436
542
  flex-shrink: 0;
543
+ animation: icon-enter 500ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
437
544
  }
438
545
 
439
546
  .icon-container svg {
@@ -501,11 +608,11 @@ var overlayStyles = css`
501
608
  /* ─── Text ─── */
502
609
 
503
610
  .dialog-title {
504
- font-size: 14px;
611
+ font-size: 18px;
505
612
  font-weight: 600;
506
613
  color: #374151;
507
614
  text-align: center;
508
- margin: 0;
615
+ margin: 0 0 16px;
509
616
  word-break: break-word;
510
617
  width: 100%;
511
618
  padding-bottom: 12px;
@@ -513,8 +620,8 @@ var overlayStyles = css`
513
620
  }
514
621
 
515
622
  .label {
516
- font-size: 18px;
517
- font-weight: 600;
623
+ font-size: 16px;
624
+ font-weight: 400;
518
625
  color: #1f2937;
519
626
  text-align: center;
520
627
  margin: 0;
@@ -559,6 +666,7 @@ var overlayStyles = css`
559
666
  gap: 8px;
560
667
  width: 100%;
561
668
  margin-top: 8px;
669
+ animation: body-enter 320ms 160ms cubic-bezier(0.16, 1, 0.3, 1) both;
562
670
  }
563
671
 
564
672
  @media (min-width: 640px) {
@@ -578,7 +686,8 @@ var overlayStyles = css`
578
686
  font-weight: 500;
579
687
  transition:
580
688
  background-color 150ms ease,
581
- transform 80ms ease;
689
+ transform 80ms ease,
690
+ box-shadow 150ms ease;
582
691
  min-width: 100px;
583
692
  text-align: center;
584
693
  }
@@ -594,6 +703,7 @@ var overlayStyles = css`
594
703
 
595
704
  .btn-confirm:hover {
596
705
  background-color: var(--dialog-primary-hover);
706
+ box-shadow: 0 4px 12px rgb(59 130 246 / 0.35);
597
707
  }
598
708
 
599
709
  .btn-cancel {
@@ -617,11 +727,48 @@ var overlayStyles = css`
617
727
  list-style: none;
618
728
  }
619
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
+
620
741
  .task-item {
621
742
  display: flex;
622
743
  align-items: center;
623
744
  gap: 12px;
624
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;
625
772
  }
626
773
 
627
774
  .task-icon {
@@ -671,6 +818,7 @@ var overlayStyles = css`
671
818
 
672
819
  .task-label {
673
820
  color: #6b7280;
821
+ transition: color 250ms ease;
674
822
  }
675
823
 
676
824
  .task-label[data-status='active'] {
@@ -678,8 +826,21 @@ var overlayStyles = css`
678
826
  font-weight: 500;
679
827
  }
680
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
+
681
841
  .task-label[data-status='done'] {
682
842
  color: var(--dialog-success);
843
+ animation: task-done-flash 350ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
683
844
  }
684
845
 
685
846
  .task-label[data-status='error'] {
@@ -688,7 +849,6 @@ var overlayStyles = css`
688
849
 
689
850
  .task-label[data-status='skipped'] {
690
851
  color: #9ca3af;
691
- text-decoration: line-through;
692
852
  }
693
853
 
694
854
  /* ─── Queue ellipsis ─── */
@@ -724,17 +884,54 @@ var overlayStyles = css`
724
884
  margin-bottom: 8px;
725
885
  }
726
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
+
727
916
  .step-dot {
728
917
  width: 8px;
729
918
  height: 8px;
730
919
  border-radius: 50%;
731
920
  background-color: #d1d5db;
732
- 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;
733
926
  }
734
927
 
735
928
  .step-dot[data-status='active'] {
736
929
  background-color: var(--dialog-primary);
737
- 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;
738
935
  }
739
936
 
740
937
  .step-dot[data-status='done'] {
@@ -754,6 +951,7 @@ var overlayStyles = css`
754
951
  max-width: 24px;
755
952
  height: 2px;
756
953
  background-color: #e5e7eb;
954
+ transition: background-color 400ms ease;
757
955
  }
758
956
  `;
759
957
 
@@ -762,6 +960,8 @@ var OverlayDialog = class extends LitElement {
762
960
  constructor() {
763
961
  super(...arguments);
764
962
  this._state = createInitialState();
963
+ this._bodyKey = 0;
964
+ this._isClosing = false;
765
965
  this._beforeUnloadHandler = (e) => e.preventDefault();
766
966
  this._onKeyDown = (e) => {
767
967
  if (e.key === "Escape" && this._state.open) {
@@ -775,13 +975,24 @@ var OverlayDialog = class extends LitElement {
775
975
  this._state = { ...this.controller.state };
776
976
  this._unsubscribe = this.controller.subscribe((s) => {
777
977
  const wasOpen = this._state.open;
778
- this._state = s;
779
- this._syncBodyScroll(s.open);
978
+ const prevDialogType = this._state.dialogType;
780
979
  if (s.open && !wasOpen) {
980
+ this._isClosing = false;
981
+ clearTimeout(this._closeTimer);
781
982
  window.addEventListener("beforeunload", this._beforeUnloadHandler);
782
983
  } else if (!s.open && wasOpen) {
984
+ this._isClosing = true;
985
+ clearTimeout(this._closeTimer);
986
+ this._closeTimer = setTimeout(() => {
987
+ this._isClosing = false;
988
+ }, 320);
783
989
  window.removeEventListener("beforeunload", this._beforeUnloadHandler);
784
990
  }
991
+ if (s.open && s.dialogType !== prevDialogType) {
992
+ this._bodyKey++;
993
+ }
994
+ this._state = s;
995
+ this._syncBodyScroll(s.open);
785
996
  });
786
997
  }
787
998
  window.addEventListener("keydown", this._onKeyDown);
@@ -790,6 +1001,7 @@ var OverlayDialog = class extends LitElement {
790
1001
  super.disconnectedCallback();
791
1002
  this._unsubscribe?.();
792
1003
  this._syncBodyScroll(false);
1004
+ clearTimeout(this._closeTimer);
793
1005
  window.removeEventListener("beforeunload", this._beforeUnloadHandler);
794
1006
  window.removeEventListener("keydown", this._onKeyDown);
795
1007
  }
@@ -865,9 +1077,11 @@ var OverlayDialog = class extends LitElement {
865
1077
  }
866
1078
  _renderSpinner() {
867
1079
  return html`
868
- <div class="spinner">
869
- <div class="spinner-half">
870
- <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>
871
1085
  </div>
872
1086
  </div>
873
1087
  `;
@@ -1030,7 +1244,7 @@ var OverlayDialog = class extends LitElement {
1030
1244
  case "alert":
1031
1245
  case "confirm":
1032
1246
  return html`
1033
- ${this._renderIcon(s.icon)} ${s.label ? html`<p class="label">${s.label}</p>` : nothing}
1247
+ ${this._renderIcon(s.icon)} ${s.title ? html`<p class="label">${s.title}</p>` : nothing}
1034
1248
  ${s.description ? html`<p class="description">${s.description}</p>` : nothing}
1035
1249
  ${s.html ? html`<div class="html-content">${unsafeHTML(s.html)}</div>` : nothing}
1036
1250
  ${this._renderButtons()}
@@ -1051,10 +1265,14 @@ var OverlayDialog = class extends LitElement {
1051
1265
  }
1052
1266
  render() {
1053
1267
  const s = this._state;
1268
+ const showHeaderTitle = s.title && s.dialogType !== "alert" && s.dialogType !== "confirm";
1054
1269
  return html`
1055
1270
  <div class="backdrop" ?data-open=${s.open} @click=${this._onBackdropClick}>
1056
- <div class="card">
1057
- ${s.title ? html`<p class="dialog-title">${s.title}</p>` : nothing} ${this._renderBody()}
1271
+ <div class="card" ?data-closing=${this._isClosing}>
1272
+ ${showHeaderTitle ? html`<p class="dialog-title">${s.title}</p>` : nothing}
1273
+ <div class="card-body">
1274
+ ${keyed(this._bodyKey, html`<div class="body-inner">${this._renderBody()}</div>`)}
1275
+ </div>
1058
1276
  <div
1059
1277
  class="progress-bar"
1060
1278
  style="width:${s.progress ?? 0}%;opacity:${s.progress !== null ? 1 : 0}"
@@ -1071,6 +1289,12 @@ __decorateClass([
1071
1289
  __decorateClass([
1072
1290
  state()
1073
1291
  ], OverlayDialog.prototype, "_state", 2);
1292
+ __decorateClass([
1293
+ state()
1294
+ ], OverlayDialog.prototype, "_bodyKey", 2);
1295
+ __decorateClass([
1296
+ state()
1297
+ ], OverlayDialog.prototype, "_isClosing", 2);
1074
1298
  OverlayDialog = __decorateClass([
1075
1299
  customElement("overlay-dialog")
1076
1300
  ], OverlayDialog);