Parcourir la source

Nested Card Expand Icon Not Showing

Aigars Silkalns il y a 1 jour
Parent
commit
8a9add99d5

+ 7 - 0
CHANGELOG.md

@@ -42,6 +42,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - **Release Workflow:** Fixed zip command in release.yml
   - Corrected `-d` flag to `-r` for recursive directory zipping
   - Fixed filename inconsistency in release artifacts
+- **Nested Card Expand Icon:** Fixed issue #5909 where nested collapsed cards didn't show expand icon
+  - Updated CSS selectors to use direct child (>) scoping for card state icons
+  - Collapse/expand icons now correctly display for nested cards independently
+  - Card body/footer display rules now only affect direct children, not nested cards
+- **Card Widget JavaScript:** Fixed nested card collapse/expand affecting child cards
+  - Added `:scope >` selector to only target direct card-body/footer children
+  - Prevents parent card collapse from affecting nested card animations
 
 ### Updated
 

+ 4 - 4
dist/css/adminlte.css

@@ -14248,14 +14248,14 @@ body:not(.app-loaded) .app-footer {
 .card:not(.maximized-card) [data-lte-icon=minimize] {
   display: none;
 }
-.card.collapsed-card [data-lte-icon=collapse] {
+.card.collapsed-card > .card-header [data-lte-icon=collapse] {
   display: none;
 }
-.card.collapsed-card .card-body,
-.card.collapsed-card .card-footer {
+.card.collapsed-card > .card-body,
+.card.collapsed-card > .card-footer {
   display: none;
 }
-.card:not(.collapsed-card) [data-lte-icon=expand] {
+.card:not(.collapsed-card) > .card-header [data-lte-icon=expand] {
   display: none;
 }
 .card .nav.flex-column > li {

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
dist/css/adminlte.css.map


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
dist/css/adminlte.min.css


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
dist/css/adminlte.min.css.map


+ 4 - 4
dist/css/adminlte.rtl.css

@@ -14222,14 +14222,14 @@ body:not(.app-loaded) .app-footer {
 .card:not(.maximized-card) [data-lte-icon=minimize] {
   display: none;
 }
-.card.collapsed-card [data-lte-icon=collapse] {
+.card.collapsed-card > .card-header [data-lte-icon=collapse] {
   display: none;
 }
-.card.collapsed-card .card-body,
-.card.collapsed-card .card-footer {
+.card.collapsed-card > .card-body,
+.card.collapsed-card > .card-footer {
   display: none;
 }
-.card:not(.collapsed-card) [data-lte-icon=expand] {
+.card:not(.collapsed-card) > .card-header [data-lte-icon=expand] {
   display: none;
 }
 .card .nav.flex-column > li {

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
dist/css/adminlte.rtl.css.map


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
dist/css/adminlte.rtl.min.css


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
dist/css/adminlte.rtl.min.css.map


+ 11 - 9
dist/js/adminlte.js

@@ -1,5 +1,5 @@
 /*!
- * AdminLTE v4.0.0-rc5 (https://adminlte.io)
+ * AdminLTE v4.0.0-rc6 (https://adminlte.io)
  * Copyright 2014-2025 Colorlib <https://colorlib.com>
  * Licensed under MIT (https://github.com/ColorlibHQ/AdminLTE/blob/master/LICENSE)
  */
@@ -180,7 +180,8 @@
             const event = new Event(EVENT_COLLAPSED$2);
             if (this._parent) {
                 this._parent.classList.add(CLASS_NAME_COLLAPSING);
-                const elm = this._parent?.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`);
+                // Only target direct children to avoid affecting nested cards
+                const elm = this._parent?.querySelectorAll(`:scope > ${SELECTOR_CARD_BODY}, :scope > ${SELECTOR_CARD_FOOTER}`);
                 elm.forEach(el => {
                     if (el instanceof HTMLElement) {
                         slideUp(el, this._config.animationSpeed);
@@ -199,7 +200,8 @@
             const event = new Event(EVENT_EXPANDED$2);
             if (this._parent) {
                 this._parent.classList.add(CLASS_NAME_EXPANDING);
-                const elm = this._parent?.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`);
+                // Only target direct children to avoid affecting nested cards
+                const elm = this._parent?.querySelectorAll(`:scope > ${SELECTOR_CARD_BODY}, :scope > ${SELECTOR_CARD_FOOTER}`);
                 elm.forEach(el => {
                     if (el instanceof HTMLElement) {
                         slideDown(el, this._config.animationSpeed);
@@ -692,13 +694,13 @@
                 return;
             }
             // Check for SSR environment
-            if (typeof window === 'undefined' || typeof localStorage === 'undefined') {
+            if (globalThis.window === undefined || globalThis.localStorage === undefined) {
                 return;
             }
             try {
-                const state = document.body.classList.contains(CLASS_NAME_SIDEBAR_COLLAPSE)
-                    ? CLASS_NAME_SIDEBAR_COLLAPSE
-                    : CLASS_NAME_SIDEBAR_OPEN;
+                const state = document.body.classList.contains(CLASS_NAME_SIDEBAR_COLLAPSE) ?
+                    CLASS_NAME_SIDEBAR_COLLAPSE :
+                    CLASS_NAME_SIDEBAR_OPEN;
                 localStorage.setItem(STORAGE_KEY_SIDEBAR_STATE, state);
             }
             catch {
@@ -714,11 +716,11 @@
                 return;
             }
             // Check for SSR environment
-            if (typeof window === 'undefined' || typeof localStorage === 'undefined') {
+            if (globalThis.window === undefined || globalThis.localStorage === undefined) {
                 return;
             }
             // Don't restore state on mobile - let responsive behavior handle it
-            if (window.innerWidth <= this._config.sidebarBreakpoint) {
+            if (globalThis.innerWidth <= this._config.sidebarBreakpoint) {
                 return;
             }
             try {

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
dist/js/adminlte.js.map


Fichier diff supprimé car celui-ci est trop grand
+ 1 - 1
dist/js/adminlte.min.js


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
dist/js/adminlte.min.js.map


+ 4 - 4
src/html/public/css/adminlte.css

@@ -14248,14 +14248,14 @@ body:not(.app-loaded) .app-footer {
 .card:not(.maximized-card) [data-lte-icon=minimize] {
   display: none;
 }
-.card.collapsed-card [data-lte-icon=collapse] {
+.card.collapsed-card > .card-header [data-lte-icon=collapse] {
   display: none;
 }
-.card.collapsed-card .card-body,
-.card.collapsed-card .card-footer {
+.card.collapsed-card > .card-body,
+.card.collapsed-card > .card-footer {
   display: none;
 }
-.card:not(.collapsed-card) [data-lte-icon=expand] {
+.card:not(.collapsed-card) > .card-header [data-lte-icon=expand] {
   display: none;
 }
 .card .nav.flex-column > li {

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
src/html/public/css/adminlte.css.map


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
src/html/public/css/adminlte.min.css


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
src/html/public/css/adminlte.min.css.map


+ 4 - 4
src/html/public/css/adminlte.rtl.css

@@ -14222,14 +14222,14 @@ body:not(.app-loaded) .app-footer {
 .card:not(.maximized-card) [data-lte-icon=minimize] {
   display: none;
 }
-.card.collapsed-card [data-lte-icon=collapse] {
+.card.collapsed-card > .card-header [data-lte-icon=collapse] {
   display: none;
 }
-.card.collapsed-card .card-body,
-.card.collapsed-card .card-footer {
+.card.collapsed-card > .card-body,
+.card.collapsed-card > .card-footer {
   display: none;
 }
-.card:not(.collapsed-card) [data-lte-icon=expand] {
+.card:not(.collapsed-card) > .card-header [data-lte-icon=expand] {
   display: none;
 }
 .card .nav.flex-column > li {

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
src/html/public/css/adminlte.rtl.css.map


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
src/html/public/css/adminlte.rtl.min.css


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
src/html/public/css/adminlte.rtl.min.css.map


+ 11 - 9
src/html/public/js/adminlte.js

@@ -1,5 +1,5 @@
 /*!
- * AdminLTE v4.0.0-rc5 (https://adminlte.io)
+ * AdminLTE v4.0.0-rc6 (https://adminlte.io)
  * Copyright 2014-2025 Colorlib <https://colorlib.com>
  * Licensed under MIT (https://github.com/ColorlibHQ/AdminLTE/blob/master/LICENSE)
  */
@@ -180,7 +180,8 @@
             const event = new Event(EVENT_COLLAPSED$2);
             if (this._parent) {
                 this._parent.classList.add(CLASS_NAME_COLLAPSING);
-                const elm = this._parent?.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`);
+                // Only target direct children to avoid affecting nested cards
+                const elm = this._parent?.querySelectorAll(`:scope > ${SELECTOR_CARD_BODY}, :scope > ${SELECTOR_CARD_FOOTER}`);
                 elm.forEach(el => {
                     if (el instanceof HTMLElement) {
                         slideUp(el, this._config.animationSpeed);
@@ -199,7 +200,8 @@
             const event = new Event(EVENT_EXPANDED$2);
             if (this._parent) {
                 this._parent.classList.add(CLASS_NAME_EXPANDING);
-                const elm = this._parent?.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`);
+                // Only target direct children to avoid affecting nested cards
+                const elm = this._parent?.querySelectorAll(`:scope > ${SELECTOR_CARD_BODY}, :scope > ${SELECTOR_CARD_FOOTER}`);
                 elm.forEach(el => {
                     if (el instanceof HTMLElement) {
                         slideDown(el, this._config.animationSpeed);
@@ -692,13 +694,13 @@
                 return;
             }
             // Check for SSR environment
-            if (typeof window === 'undefined' || typeof localStorage === 'undefined') {
+            if (globalThis.window === undefined || globalThis.localStorage === undefined) {
                 return;
             }
             try {
-                const state = document.body.classList.contains(CLASS_NAME_SIDEBAR_COLLAPSE)
-                    ? CLASS_NAME_SIDEBAR_COLLAPSE
-                    : CLASS_NAME_SIDEBAR_OPEN;
+                const state = document.body.classList.contains(CLASS_NAME_SIDEBAR_COLLAPSE) ?
+                    CLASS_NAME_SIDEBAR_COLLAPSE :
+                    CLASS_NAME_SIDEBAR_OPEN;
                 localStorage.setItem(STORAGE_KEY_SIDEBAR_STATE, state);
             }
             catch {
@@ -714,11 +716,11 @@
                 return;
             }
             // Check for SSR environment
-            if (typeof window === 'undefined' || typeof localStorage === 'undefined') {
+            if (globalThis.window === undefined || globalThis.localStorage === undefined) {
                 return;
             }
             // Don't restore state on mobile - let responsive behavior handle it
-            if (window.innerWidth <= this._config.sidebarBreakpoint) {
+            if (globalThis.innerWidth <= this._config.sidebarBreakpoint) {
                 return;
             }
             try {

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
src/html/public/js/adminlte.js.map


Fichier diff supprimé car celui-ci est trop grand
+ 1 - 1
src/html/public/js/adminlte.min.js


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
src/html/public/js/adminlte.min.js.map


+ 6 - 4
src/scss/_cards.scss

@@ -63,18 +63,20 @@
 
   // collapsed mode
   &.collapsed-card {
-    [data-lte-icon="collapse"] {
+    // Use > .card-header to scope to direct card only, not nested cards
+    > .card-header [data-lte-icon="collapse"] {
       display: none;
     }
 
-    .card-body,
-    .card-footer {
+    > .card-body,
+    > .card-footer {
       display: none;
     }
   }
 
   &:not(.collapsed-card) {
-    [data-lte-icon="expand"] {
+    // Use > .card-header to scope to direct card only, not nested cards
+    > .card-header [data-lte-icon="expand"] {
       display: none;
     }
   }

+ 4 - 2
src/ts/card-widget.ts

@@ -76,7 +76,8 @@ class CardWidget {
     if (this._parent) {
       this._parent.classList.add(CLASS_NAME_COLLAPSING)
 
-      const elm = this._parent?.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`)
+      // Only target direct children to avoid affecting nested cards
+      const elm = this._parent?.querySelectorAll(`:scope > ${SELECTOR_CARD_BODY}, :scope > ${SELECTOR_CARD_FOOTER}`)
 
       elm.forEach(el => {
         if (el instanceof HTMLElement) {
@@ -101,7 +102,8 @@ class CardWidget {
     if (this._parent) {
       this._parent.classList.add(CLASS_NAME_EXPANDING)
 
-      const elm = this._parent?.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`)
+      // Only target direct children to avoid affecting nested cards
+      const elm = this._parent?.querySelectorAll(`:scope > ${SELECTOR_CARD_BODY}, :scope > ${SELECTOR_CARD_FOOTER}`)
 
       elm.forEach(el => {
         if (el instanceof HTMLElement) {

+ 6 - 6
src/ts/push-menu.ts

@@ -145,14 +145,14 @@ class PushMenu {
     }
 
     // Check for SSR environment
-    if (typeof window === 'undefined' || typeof localStorage === 'undefined') {
+    if (globalThis.window === undefined || globalThis.localStorage === undefined) {
       return
     }
 
     try {
-      const state = document.body.classList.contains(CLASS_NAME_SIDEBAR_COLLAPSE)
-        ? CLASS_NAME_SIDEBAR_COLLAPSE
-        : CLASS_NAME_SIDEBAR_OPEN
+      const state = document.body.classList.contains(CLASS_NAME_SIDEBAR_COLLAPSE) ?
+        CLASS_NAME_SIDEBAR_COLLAPSE :
+        CLASS_NAME_SIDEBAR_OPEN
       localStorage.setItem(STORAGE_KEY_SIDEBAR_STATE, state)
     } catch {
       // localStorage may be unavailable (private browsing, quota exceeded, etc.)
@@ -169,12 +169,12 @@ class PushMenu {
     }
 
     // Check for SSR environment
-    if (typeof window === 'undefined' || typeof localStorage === 'undefined') {
+    if (globalThis.window === undefined || globalThis.localStorage === undefined) {
       return
     }
 
     // Don't restore state on mobile - let responsive behavior handle it
-    if (window.innerWidth <= this._config.sidebarBreakpoint) {
+    if (globalThis.innerWidth <= this._config.sidebarBreakpoint) {
       return
     }
 

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff