-
-
-
![]()
-
{{ initialText(child) }}
-
-
-
- {{ child.type === 'icon' ? child.icon?.name : child.widget?.component || 'Widget' }}
-
-
{{ child.icon.url }}
-
-
-
-
+
@@ -104,96 +148,119 @@ const initialText = (child: FolderChild) => {
.folder-dialog-overlay {
position: fixed;
inset: 0;
- background: rgba(0, 0, 0, 0.35);
- backdrop-filter: blur(6px);
+ background: rgba(10, 12, 20, 0.32);
+ backdrop-filter: blur(18px) saturate(140%);
+ -webkit-backdrop-filter: blur(18px) saturate(140%);
display: flex;
align-items: center;
justify-content: center;
z-index: $z-index-menu;
+ opacity: 0;
+ pointer-events: none;
+}
+
+.folder-dialog-overlay.is-open {
+ opacity: 1;
+ pointer-events: auto;
+}
+
+.folder-dialog-wrap {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 16px;
+}
+
+.folder-title {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.folder-title-pill {
+ min-width: 180px;
+ height: 36px;
+ padding: 0 16px;
+ border-radius: 10px;
+ border: none;
+ background: transparent;
+ color: #fff;
+ font-size: 16px;
+ font-weight: 600;
+ letter-spacing: 0.5px;
+ box-shadow: none;
+ cursor: pointer;
+ box-sizing: border-box;
+}
+
+.folder-title-input {
+ min-width: 180px;
+ height: 36px;
+ padding: 0 16px;
+ border-radius: 10px;
+ border: 1px solid rgba(255, 255, 255, 0.35);
+ background: rgba(255, 255, 255, 0.38);
+ backdrop-filter: blur(22px) saturate(160%);
+ -webkit-backdrop-filter: blur(22px) saturate(160%);
+ color: rgba(0, 0, 0, 0.85);
+ font-size: 16px;
+ font-weight: 600;
+ outline: none;
+ text-align: center;
+ box-shadow: 0 30px 80px rgba(0, 0, 0, 0.2);
+ box-sizing: border-box;
}
.folder-dialog {
- width: min(520px, 90vw);
- max-height: 80vh;
- background: #fff;
- border-radius: 16px;
- box-shadow: 0 20px 80px rgba(0, 0, 0, 0.18);
- overflow: hidden;
+ width: min(720px, 90vw);
+ min-height: 200px;
+ padding: 22px 26px 26px;
+ border-radius: 22px;
+ border: 1px solid rgba(255, 255, 255, 0.35);
+ background: rgba(255, 255, 255, 0.38);
+ backdrop-filter: blur(22px) saturate(160%);
+ box-shadow: 0 30px 80px rgba(0, 0, 0, 0.2);
+}
+
+.folder-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
+ gap: 16px;
+}
+
+.folder-item {
+ position: relative;
display: flex;
flex-direction: column;
-}
-
-.folder-dialog__header {
- display: flex;
align-items: center;
- gap: 10px;
- padding: 14px 18px;
- border-bottom: 1px solid rgba(0, 0, 0, 0.06);
-}
+ gap: 6px;
+ padding: 6px 4px 10px;
+ border-radius: 14px;
+ cursor: pointer;
+ transition: transform $motion-duration-sm $motion-easing-standard, background $motion-duration-sm $motion-easing-standard;
-.folder-name-input {
- flex: 1;
- border: 1px solid rgba(0, 0, 0, 0.08);
- border-radius: 10px;
- padding: 8px 10px;
- font-size: 15px;
- outline: none;
- transition: border-color $motion-duration-sm $motion-easing-standard, box-shadow $motion-duration-sm $motion-easing-standard;
+ &:hover {
+ transform: translateY(-2px);
+ background: rgba(255, 255, 255, 0.2);
+ }
- &:focus {
- border-color: #007aff;
- box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.15);
+ &:hover .folder-item-remove {
+ opacity: 1;
+ transform: translateY(0);
}
}
-.folder-badge {
- background: rgba(0, 122, 255, 0.12);
- color: #0a63d1;
- border-radius: 999px;
- padding: 6px 12px;
- font-weight: 600;
- font-size: 13px;
-}
-
-.close-btn {
- background: transparent;
- border: none;
- font-size: 20px;
- color: #666;
- cursor: pointer;
- line-height: 1;
-}
-
-.folder-dialog__body {
- padding: 12px 18px 18px;
- overflow: auto;
- max-height: 60vh;
- display: flex;
- flex-direction: column;
- gap: 10px;
-}
-
-.folder-row {
- display: grid;
- grid-template-columns: 54px 1fr auto;
- align-items: center;
- gap: 12px;
- padding: 10px 12px;
- border: 1px solid rgba(0, 0, 0, 0.06);
- border-radius: 12px;
- background: rgba(0, 0, 0, 0.02);
-}
-
-.row-thumb {
- width: 54px;
- height: 54px;
- border-radius: 12px;
- background: rgba(0, 0, 0, 0.06);
+.folder-item-icon {
+ width: 56px;
+ height: 56px;
+ border-radius: 16px;
+ background: rgba(255, 255, 255, 0.8);
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
- font-size: 18px;
+ color: #222;
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);
overflow: hidden;
img {
@@ -207,62 +274,56 @@ const initialText = (child: FolderChild) => {
}
}
-.row-title {
- min-width: 0;
-}
-
-.row-name {
- font-weight: 600;
- color: #1f1f1f;
- font-size: 15px;
- line-height: 1.3;
-}
-
-.row-sub {
+.folder-item-label {
font-size: 12px;
- color: #666;
- margin-top: 4px;
+ color: rgba(0, 0, 0, 0.7);
+ text-align: center;
+ max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
-.row-actions {
- display: flex;
- align-items: center;
- gap: 8px;
-}
-
-.link-btn {
- background: rgba(0, 0, 0, 0.05);
+.folder-item-remove {
+ position: absolute;
+ top: 2px;
+ right: 6px;
border: none;
- border-radius: 8px;
- padding: 6px 10px;
+ background: rgba(255, 255, 255, 0.85);
+ color: #c0392b;
+ border-radius: 999px;
+ padding: 2px 8px;
+ font-size: 11px;
cursor: pointer;
- font-size: 13px;
- color: #222;
- transition: background $motion-duration-sm $motion-easing-standard, transform $motion-duration-sm $motion-easing-standard;
-
- &:hover {
- background: rgba(0, 122, 255, 0.12);
- transform: translateY(-1px);
- }
-
- &.danger {
- color: #c0392b;
- background: rgba(192, 57, 43, 0.08);
-
- &:hover {
- background: rgba(192, 57, 43, 0.15);
- }
- }
+ opacity: 0;
+ transform: translateY(-4px);
+ transition: opacity $motion-duration-sm $motion-easing-standard, transform $motion-duration-sm $motion-easing-standard;
}
.folder-empty {
- text-align: center;
- padding: 26px 12px;
- color: #666;
- border: 1px dashed rgba(0, 0, 0, 0.08);
- border-radius: 12px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ min-height: 160px;
+ color: rgba(255, 255, 255, 0.85);
+ font-weight: 600;
+}
+
+.folder-dialog-enter-active {
+ transition: transform 220ms $motion-easing-standard;
+}
+
+.folder-dialog-enter-from {
+ transform: translateY(14px) scale(0.98);
+}
+
+.folder-title-enter-active,
+.folder-title-leave-active {
+ transition: opacity 90ms $motion-easing-standard;
+}
+
+.folder-title-enter-from,
+.folder-title-leave-to {
+ opacity: 0;
}
diff --git a/app/src/components/GridCanvas/index.vue b/app/src/components/GridCanvas/index.vue
index 3419d65..24d6eac 100644
--- a/app/src/components/GridCanvas/index.vue
+++ b/app/src/components/GridCanvas/index.vue
@@ -1,6 +1,6 @@
-