Адаптивное изменение размера wellPanel в R Shiny с помощью JavaScript

Проблема с автоматическим изменением размера плавающей панели

Пытаюсь создать в приложении Shiny плавающую панель wellPanel, которая должна автоматически изменять размер при сворачивании боковой панели shinydashboard. Написал рабочий пример:

Код приложения (main.R):

library(shiny)
library(shinydashboard)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(
    sidebarMenu(
      id = "navigation",
      menuItem(
        "Главная",
        tabName = "main",
        icon = icon("home")
      )
    )
  ),
  dashboardBody(
    tags$head(tags$script(src = "panel_resize.js")),
    div(
      id = "floatingContainer",
      style = "left:0px; right:0px; bottom:0px; position:fixed; cursor:inherit; z-index: 10000;",
      wellPanel(
        id = "dynamicPanel",
        style = "padding: 8px; border-bottom: 1px solid #CCC; background: #F0F8FF;",
        HTML("Сохранить изменения?"),
        actionButton("confirm", "Подтвердить"),
        actionButton("decline", "Отменить")
      )
    )
  )
)

server <- function(input, output) {
  # Пустая серверная функция
}

shinyApp(ui, server)

JavaScript файл (www/panel_resize.js):

function adjustPanelSize(isCollapsed) {
    console.log('Изменение размера панели');
    var menuWidth = $('#navigation').width();
    var totalWidth = $(window).innerWidth();
    var remainingSpace = totalWidth - menuWidth;
    console.log('menuWidth: ' + menuWidth + '; totalWidth: ' + totalWidth + '; remainingSpace: ' + remainingSpace);
    
    var panel = $('#dynamicPanel');
    
    if (isCollapsed == "true") {
        console.log("панель свернута: " + isCollapsed);
        $('#dynamicPanel').css('margin-left', 5 + 'px');
        panel.innerWidth(totalWidth - 5);
    } else if (isCollapsed === false) {
        console.log("панель развернута: " + isCollapsed);
        panel.innerWidth(remainingSpace);
        $('#dynamicPanel').css('margin-left', 5 + menuWidth + 'px');
    } else {
        throw new Error('Действие не выполнено');
    }
}

$(document).ready(function() {
    var sidebarState = $('.main-sidebar.shiny-bound-input').attr("data-collapsed");
    console.log("sidebarState: ", + sidebarState);
    adjustPanelSize(sidebarState);

    $('.main-sidebar.shiny-bound-input').change(function() {
        sidebarState = $(this).attr("data-collapsed");
        setTimeout(function(sidebarState) {
            adjustPanelSize(sidebarState);
        }, 500);
    });
});

Возникшие проблемы:

  1. Переменная sidebarState получает значение NaN - не могу понять почему. Команда $('.main-sidebar.shiny-bound-input').attr("data-collapsed") должна возвращать true/false.

  2. Функция $('.main-sidebar.shiny-bound-input').change() не срабатывает при сворачивании боковой панели. Странно, потому что в консоли браузера этот же код работает нормально.

Помогите разобраться с этими проблемами. Заранее спасибо!

Скорее всего DOM еще не загрузился когда твой скрипт запускается. Оберни код в $(document).ready(function() { и добавь setTimeout с небольшой задержкой. У меня такое же было - помог setInterval каждые 100мс с проверкой data-collapsed. Проверь в девтулзах правильный селектор элемента - может отличается от твоего. И убери console.log с плюсом - он ломает логику.

У тебя опечатка в коде - в console.log("sidebarState: ", sidebarState); лишний плюс перед переменной, отсюда и NaN. Убери его. Вместо change лучше используй $(document).on('click', '[data-toggle="offcanvas"]', function() {...}) для отслеживания клика - работает надежнее. И проверь, что элемент с классом main-sidebar вообще существует когда скрипт выполняется.

Попробуй MutationObserver вместо обработчика событий - он точно поймает изменения data-collapsed. В setTimeout переменную нужно передать через замыкание, иначе она не доходит. Какая версия shinydashboard? Может селектор другой нужен?