Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

panel-shift-dropdown.blade.php 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. @php
  2. $items = filament()->getUserMenuItems();
  3. $logoutItem = $items['logout'] ?? null;
  4. $currentTenant = filament()->getTenant();
  5. $currentTenantName = $currentTenant ? filament()->getTenantName($currentTenant) : null;
  6. $navigation = $component->getNavigation();
  7. $hasDisplayAndAccessibility = $component->hasDisplayAndAccessibility();
  8. $hasCompanySettings = $component->hasCompanySettings();
  9. $hasLogoutItem = $component->hasLogoutItem();
  10. $panels = $component->getNavigationAsHierarchyArray();
  11. @endphp
  12. <div x-data="panelShiftDropdown">
  13. <div x-on:click="toggleDropdown()" class="flex cursor-pointer">
  14. <button
  15. type="button"
  16. class="fi-tenant-menu-trigger group flex w-full items-center justify-center gap-x-3 rounded-lg p-2 text-sm font-medium outline-none transition duration-75 hover:bg-gray-100 focus-visible:bg-gray-100 dark:hover:bg-white/5 dark:focus-visible:bg-white/5"
  17. >
  18. <x-filament-panels::avatar.tenant
  19. :tenant="$currentTenant"
  20. class="shrink-0"
  21. />
  22. <span class="grid justify-items-start text-start">
  23. @if ($currentTenant instanceof \Filament\Models\Contracts\HasCurrentTenantLabel)
  24. <span class="text-xs text-gray-500 dark:text-gray-400">
  25. {{ $currentTenant->getCurrentTenantLabel() }}
  26. </span>
  27. @endif
  28. <span class="text-gray-950 dark:text-white">
  29. {{ $currentTenantName }}
  30. </span>
  31. </span>
  32. <x-filament::icon
  33. icon="heroicon-m-chevron-down"
  34. class="h-5 w-5 transition duration-75 text-gray-400 group-hover:text-gray-500 group-focus-visible:text-gray-500 dark:text-gray-500 dark:group-hover:text-gray-400 dark:group-focus-visible:text-gray-400"
  35. x-bind:class="{ 'rotate-180': open }"
  36. />
  37. </button>
  38. </div>
  39. <div x-show="open" class="flex flex-col transition duration-200 ease-in-out grow shrink mt-4 absolute z-10 w-screen max-w-[360px] end-8 rounded-lg bg-white shadow-lg ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10 overflow-hidden">
  40. @foreach($panels as $panelId => $panel)
  41. <x-panel-shift-dropdown.panel :panel-id="$panelId">
  42. @if($panelId !== 'main' && isset($panel['label']))
  43. <x-panel-shift-dropdown.subpanel-header :label="$panel['label']" :panel-id="$panelId" />
  44. @endif
  45. @if($panel['renderItems'])
  46. @foreach($panel['items'] as $item)
  47. <x-panel-shift-dropdown.content-handler :item="$item" />
  48. @endforeach
  49. @endif
  50. @if($panelId === 'company-settings')
  51. <x-panel-shift-dropdown.company-settings :current-tenant="$currentTenant" icon="heroicon-m-building-office-2" />
  52. @endif
  53. @if($panelId === 'company-switcher')
  54. <x-panel-shift-dropdown.company-switcher :current-tenant="$currentTenant" icon="heroicon-m-adjustments-horizontal" />
  55. @endif
  56. @if($panelId === 'display-and-accessibility')
  57. <x-panel-shift-dropdown.display-accessibility icon="heroicon-s-moon"/>
  58. @endif
  59. @if($panelId === 'main' && $hasLogoutItem)
  60. <x-panel-shift-dropdown.item
  61. tag="form"
  62. method="post"
  63. :action="$logoutItem?->getUrl() ?? filament()->getLogoutUrl()"
  64. :label="$logoutItem?->getLabel() ?? __('filament-panels::layout.actions.logout.label')"
  65. :icon="$logoutItem?->getIcon() ?? \Filament\Support\Facades\FilamentIcon::resolve('panels::user-menu.logout-button') ?? 'heroicon-m-arrow-left-on-rectangle'"
  66. />
  67. @endif
  68. </x-panel-shift-dropdown.panel>
  69. @endforeach
  70. </div>
  71. </div>
  72. <script>
  73. document.addEventListener('alpine:init', () => {
  74. Alpine.data('panelShiftDropdown', () => ({
  75. open: false,
  76. navigationStack: ['main'],
  77. theme: localStorage.getItem('theme') || '{{ filament()->getDefaultThemeMode()->value }}',
  78. themeLabels: {
  79. light: 'Off',
  80. dark: 'On',
  81. system: 'System',
  82. },
  83. toggleDropdown() {
  84. this.open = !this.open;
  85. },
  86. setActiveMenu(menu) {
  87. if (this.open) {
  88. this.transitionPanel(menu, 'forward');
  89. }
  90. },
  91. focusMenuItem(menuItemRef) {
  92. this.$nextTick(() => {
  93. setTimeout(() => {
  94. this.$refs[menuItemRef]?.focus();
  95. }, 200);
  96. });
  97. },
  98. focusBackButton(backButtonRef) {
  99. this.$nextTick(() => {
  100. setTimeout(() => {
  101. this.$refs[backButtonRef]?.focus();
  102. }, 200);
  103. });
  104. },
  105. goBack() {
  106. if (this.open && this.navigationStack.length > 1) {
  107. this.transitionPanel(this.navigationStack.at(-2), 'back');
  108. }
  109. },
  110. currentActiveMenu() {
  111. return this.navigationStack.at(-1);
  112. },
  113. transitionPanel(target, direction) {
  114. const currentPanel = this.$refs[this.currentActiveMenu()];
  115. const targetPanel = this.$refs[target];
  116. const translateX = direction === 'forward' ? '-100%' : '100%';
  117. currentPanel.style.transform = `translateX(${translateX})`;
  118. setTimeout(() => {
  119. currentPanel.classList.add('hide');
  120. targetPanel.classList.remove('hide');
  121. targetPanel.style.transform = 'translateX(0)';
  122. if (direction === 'forward') {
  123. this.navigationStack.push(target);
  124. } else {
  125. this.navigationStack.pop();
  126. }
  127. }, 200);
  128. },
  129. setTheme(newTheme) {
  130. this.theme = newTheme;
  131. },
  132. init() {
  133. this.$watch('theme', (value) => {
  134. this.$dispatch('theme-changed', value);
  135. });
  136. this.$watch('open', (value) => {
  137. if (value) {
  138. if (this.navigationStack.length === 1) {
  139. const mainPanel = this.$refs.main;
  140. mainPanel.classList.remove('hide');
  141. mainPanel.style.transform = 'translateX(0)';
  142. }
  143. } else {
  144. this.navigationStack = ['main'];
  145. }
  146. });
  147. },
  148. getThemeLabel(value) {
  149. return this.themeLabels[value] || value;
  150. },
  151. }));
  152. });
  153. </script>