重命名CubeListPager和CubeListToolbarSearch
Yann authored at 2025-07-28 22:53:20 Yann committed at 2025-07-28 23:04:14
1.66 KiB
cube-front
import { ref, computed, shallowRef, type Component } from 'vue';

/**
 * 布局选项描述
 */
export interface LayoutOption {
  id: string;
  label: string;
  icon: string; // emoji 或 SVG 标识
  description?: string;
  component: Component;
}

const STORAGE_KEY = 'cube-layout';

// 模块级响应式状态(全局单例)
const registeredLayouts = ref<LayoutOption[]>([]);
const currentLayoutId = ref<string>('');

/**
 * 注册一个布局
 * 通常在 main.ts / initApp 回调中调用
 * 第一个注册的布局自动成为默认布局
 */
export function registerLayout(option: LayoutOption): void {
  if (registeredLayouts.value.some((l) => l.id === option.id)) return;

  registeredLayouts.value.push(option);

  // 第一次注册时,从 localStorage 恢复或设为第一个
  if (!currentLayoutId.value) {
    const stored = localStorage.getItem(STORAGE_KEY);
    const valid = stored && registeredLayouts.value.some((l) => l.id === stored);
    currentLayoutId.value = valid ? stored! : option.id;
  }
}

/**
 * 布局组合式函数
 * 在 Topnav / RootLayout 等组件中使用
 */
export function useLayout() {
  const currentLayout = computed<LayoutOption | undefined>(() =>
    registeredLayouts.value.find((l) => l.id === currentLayoutId.value),
  );

  const currentComponent = computed<Component | undefined>(() => currentLayout.value?.component);

  function setLayout(id: string): void {
    if (!registeredLayouts.value.some((l) => l.id === id)) return;
    currentLayoutId.value = id;
    localStorage.setItem(STORAGE_KEY, id);
  }

  return {
    layouts: registeredLayouts,
    currentLayoutId,
    currentLayout,
    currentComponent,
    setLayout,
  };
}