mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-16 14:16:16 -08:00
feat(groups-view): add search functionality to filter grouped channels
feat(recent-view): implement search term filtering for recent items fix(dashboard-data): update return type for navigation state methods chore(jest): add jest configuration for workspace shell feature refactor(global-favorites): migrate global favorites list to shared UI refactor(global-favorites): remove global favorites page component and its styles refactor(global-favorites): update unified favorite channel interface to use shared util test(workspace-shell): setup test environment for workspace shell feature Entire-Checkpoint: 0e4488af6c76
This commit is contained in:
1 parent
aa5e4097f1
commit
8874e4a17e
80 files changed
+2396
-4316
No files matched your search
@@ -52,6 +52,24 @@ nav.flex .portal-rail-link {
|
||||
justify-content: center;
|
||||
color: var(--rail-link-color);
|
||||
app-region: no-drag;
|
||||
animation: rail-link-enter 0.2s ease-out both;
|
||||
}
|
||||
|
||||
@for $i from 1 through 8 {
|
||||
nav.flex .portal-rail-link:nth-child(#{$i}) {
|
||||
animation-delay: #{($i - 1) * 30}ms;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rail-link-enter {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-6px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
nav.flex .portal-rail-link.is-active,
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
// ─── Shared skeleton / shimmer primitives ────────────────────────────────────
|
||||
// Used by grid-list (poster cards) and unified-collection (channel list rows).
|
||||
|
||||
// ─── Grid skeleton (poster cards) ────────────────────────────────────────────
|
||||
|
||||
.grid-skeleton-card {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.grid-skeleton-thumb {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
aspect-ratio: 2 / 3;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
background: color-mix(
|
||||
in srgb,
|
||||
var(--app-widget-header-bg, var(--mat-sys-surface-container-high)) 84%,
|
||||
var(--app-widget-bg, var(--mat-sys-surface-container)) 16%
|
||||
);
|
||||
border: 1px solid
|
||||
color-mix(
|
||||
in srgb,
|
||||
var(--app-widget-header-border, var(--mat-sys-outline-variant)) 94%,
|
||||
transparent
|
||||
);
|
||||
}
|
||||
|
||||
.grid-skeleton-badge {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
width: 34px;
|
||||
height: 14px;
|
||||
border-radius: 999px;
|
||||
background: color-mix(
|
||||
in srgb,
|
||||
var(--app-widget-header-bg, var(--mat-sys-surface-container-high)) 56%,
|
||||
var(--app-body-color, var(--mat-sys-on-surface-variant)) 44%
|
||||
);
|
||||
}
|
||||
|
||||
.grid-skeleton-title {
|
||||
margin-top: 10px;
|
||||
padding: 0 3px;
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.grid-skeleton-line {
|
||||
height: 9px;
|
||||
border-radius: 999px;
|
||||
background: color-mix(
|
||||
in srgb,
|
||||
var(--app-widget-header-bg, var(--mat-sys-surface-container-high)) 52%,
|
||||
var(--app-body-color, var(--mat-sys-on-surface-variant)) 48%
|
||||
);
|
||||
|
||||
&--primary {
|
||||
width: 92%;
|
||||
}
|
||||
|
||||
&--secondary {
|
||||
width: 68%;
|
||||
}
|
||||
}
|
||||
|
||||
// ─── List skeleton (channel rows) ────────────────────────────────────────────
|
||||
|
||||
.list-skeleton-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 10px 16px;
|
||||
border-bottom: 1px solid
|
||||
color-mix(
|
||||
in srgb,
|
||||
var(--mat-sys-outline-variant) 40%,
|
||||
transparent
|
||||
);
|
||||
}
|
||||
|
||||
.list-skeleton-handle {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 4px;
|
||||
flex-shrink: 0;
|
||||
background: color-mix(
|
||||
in srgb,
|
||||
var(--app-widget-header-bg, var(--mat-sys-surface-container-high)) 60%,
|
||||
var(--app-body-color, var(--mat-sys-on-surface-variant)) 40%
|
||||
);
|
||||
}
|
||||
|
||||
.list-skeleton-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 6px;
|
||||
flex-shrink: 0;
|
||||
background: color-mix(
|
||||
in srgb,
|
||||
var(--app-widget-header-bg, var(--mat-sys-surface-container-high)) 84%,
|
||||
var(--app-widget-bg, var(--mat-sys-surface-container)) 16%
|
||||
);
|
||||
}
|
||||
|
||||
.list-skeleton-text {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.list-skeleton-star {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 4px;
|
||||
flex-shrink: 0;
|
||||
background: color-mix(
|
||||
in srgb,
|
||||
var(--app-widget-header-bg, var(--mat-sys-surface-container-high)) 60%,
|
||||
var(--app-body-color, var(--mat-sys-on-surface-variant)) 40%
|
||||
);
|
||||
}
|
||||
|
||||
// ─── Shimmer animation (shared) ──────────────────────────────────────────────
|
||||
|
||||
.grid-skeleton-thumb,
|
||||
.grid-skeleton-badge,
|
||||
.grid-skeleton-line,
|
||||
.list-skeleton-handle,
|
||||
.list-skeleton-avatar,
|
||||
.list-skeleton-star,
|
||||
.list-skeleton-text .grid-skeleton-line {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(
|
||||
100deg,
|
||||
transparent 10%,
|
||||
color-mix(
|
||||
in srgb,
|
||||
var(--app-heading-color, var(--mat-sys-on-surface)) 20%,
|
||||
transparent
|
||||
)
|
||||
46%,
|
||||
transparent 76%
|
||||
);
|
||||
transform: translateX(-120%);
|
||||
animation: skeleton-shimmer 1.2s ease-in-out infinite;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes skeleton-shimmer {
|
||||
100% {
|
||||
transform: translateX(120%);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user