导航菜单

MacWindow

简介

MacWindow 组件模拟 macOS 风格的应用窗口,包含标题栏、工具栏按钮、标签页和状态栏。适用于创建模拟桌面应用界面或代码编辑器等场景。

组件特性:

  • 完整的 macOS 风格窗口外观,包含关闭、最小化、最大化按钮
  • 支持标签页功能,可切换不同内容区域
  • 提供工具栏和状态栏插槽,支持自定义内容
  • 支持侧边栏布局,适合文件浏览器等应用
  • 可自定义窗口高度和阴影效果
  • 支持窗口操作事件回调
  • 支持多种预设背景色主题,包括默认、主要、次要、强调、中性、信息、成功、警告、错误

案例

最简单的窗口展示:

代码编辑器-Astro版本
窗口内容区域

代码编辑器-Vue版本
窗口内容区域
---



/**
 * @component MacWindow.Basic
 *
 * @description
 * 基础MacWindow组件示例,展示最简单的窗口用法。
 */
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";
---

<MacWindow title="代码编辑器-Astro版本">
  <PlaceHolder width="full" height="lg" padding="md">
    窗口内容区域
  </PlaceHolder>
</MacWindow>
<script setup>
import { MacWindow } from "@coffic/cosy-ui/vue";
</script>

<template>
  <MacWindow title="代码编辑器-Vue版本">
    <div class="cosy:p-4">窗口内容区域</div>
  </MacWindow>
</template>

Props

bgType

背景色主题类型,支持多种预设颜色。

默认背景窗口

这是使用默认背景色的 MacWindow 组件。

背景色:浅色主题,适合大多数场景。

主要背景窗口

这是使用主要背景的 MacWindow 组件。

背景色:主要主题背景,适合重要内容。

次要背景窗口

这是使用次要背景的 MacWindow 组件。

背景色:次要主题背景,适合辅助内容。

强调背景窗口

这是使用强调背景的 MacWindow 组件。

背景色:强调主题背景,适合突出显示。

中性背景窗口

这是使用中性背景的 MacWindow 组件。

背景色:中性主题背景,适合中性内容。

信息背景窗口

这是使用信息背景的 MacWindow 组件。

背景色:信息主题背景,适合提示信息。

成功背景窗口

这是使用成功背景的 MacWindow 组件。

背景色:成功主题背景,适合成功状态。

警告背景窗口

这是使用警告背景的 MacWindow 组件。

背景色:警告主题背景,适合警告状态。

错误背景窗口

这是使用错误背景的 MacWindow 组件。

背景色:错误主题背景,适合错误状态。

默认背景窗口

这是使用默认背景的 MacWindow 组件。

主要背景窗口

这是使用主要背景的 MacWindow 组件。

次要背景窗口

这是使用次要背景的 MacWindow 组件。

强调背景窗口

这是使用强调背景的 MacWindow 组件。

中性背景窗口

这是使用中性背景的 MacWindow 组件。

信息背景窗口

这是使用信息背景的 MacWindow 组件。

成功背景窗口

这是使用成功背景的 MacWindow 组件。

警告背景窗口

这是使用警告背景的 MacWindow 组件。

错误背景窗口

这是使用错误背景的 MacWindow 组件。

---



/**
 * @component MacWindow Default Background Example
 * @description 展示 MacWindow 组件的默认背景色
 */

import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";
---

<MacWindow title="默认背景窗口" height="h-48">
  <PlaceHolder width="full" height="lg" padding="md">
    <p>这是使用默认背景色的 MacWindow 组件。</p>
    <p>背景色浅色主题适合大多数场景。</p>
  </PlaceHolder>
</MacWindow>
---



/**
 * @component MacWindow Primary Background Example
 * @description 展示 MacWindow 组件的主要背景色
 */

import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";
---

<MacWindow title="主要背景窗口" height="h-48" bgType="primary">
  <PlaceHolder width="full" height="lg" padding="md">
    <p>这是使用主要背景的 MacWindow 组件。</p>
    <p>背景色主要主题背景适合重要内容。</p>
  </PlaceHolder>
</MacWindow>
---



/**
 * @component MacWindow Secondary Background Example
 * @description 展示 MacWindow 组件的次要背景色
 */

import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";
---

<MacWindow title="次要背景窗口" height="h-48" bgType="secondary">
  <PlaceHolder width="full" height="lg" padding="md">
    <p>这是使用次要背景的 MacWindow 组件。</p>
    <p>背景色次要主题背景适合辅助内容。</p>
  </PlaceHolder>
</MacWindow>
---



/**
 * @component MacWindow Accent Background Example
 * @description 展示 MacWindow 组件的强调背景色
 */

import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";
---

<MacWindow title="强调背景窗口" height="h-48" bgType="accent">
  <PlaceHolder width="full" height="lg" padding="md">
    <p>这是使用强调背景的 MacWindow 组件。</p>
    <p>背景色强调主题背景适合突出显示。</p>
  </PlaceHolder>
</MacWindow>
---



/**
 * @component MacWindow Neutral Background Example
 * @description 展示 MacWindow 组件的中性背景色
 */

import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";
---

<MacWindow title="中性背景窗口" height="h-48" bgType="neutral">
  <PlaceHolder width="full" height="lg" padding="md">
    <p>这是使用中性背景的 MacWindow 组件。</p>
    <p>背景色中性主题背景适合中性内容。</p>
  </PlaceHolder>
</MacWindow>
---



/**
 * @component MacWindow Info Background Example
 * @description 展示 MacWindow 组件的信息背景色
 */

import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";
---

<MacWindow title="信息背景窗口" height="h-48" bgType="info">
  <PlaceHolder width="full" height="lg" padding="md">
    <p>这是使用信息背景的 MacWindow 组件。</p>
    <p>背景色信息主题背景适合提示信息。</p>
  </PlaceHolder>
</MacWindow>
---



/**
 * @component MacWindow Success Background Example
 * @description 展示 MacWindow 组件的成功背景色
 */

import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";
---

<MacWindow title="成功背景窗口" height="h-48" bgType="success">
  <PlaceHolder width="full" height="lg" padding="md">
    <p>这是使用成功背景的 MacWindow 组件。</p>
    <p>背景色成功主题背景适合成功状态。</p>
  </PlaceHolder>
</MacWindow>
---



/**
 * @component MacWindow Warning Background Example
 * @description 展示 MacWindow 组件的警告背景色
 */

import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";
---

<MacWindow title="警告背景窗口" height="h-48" bgType="warning">
  <PlaceHolder width="full" height="lg" padding="md">
    <p>这是使用警告背景的 MacWindow 组件。</p>
    <p>背景色警告主题背景适合警告状态。</p>
  </PlaceHolder>
</MacWindow>
---



/**
 * @component MacWindow Error Background Example
 * @description 展示 MacWindow 组件的错误背景色
 */

import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";
---

<MacWindow title="错误背景窗口" height="h-48" bgType="error">
  <PlaceHolder width="full" height="lg" padding="md">
    <p>这是使用错误背景的 MacWindow 组件。</p>
    <p>背景色错误主题背景适合错误状态。</p>
  </PlaceHolder>
</MacWindow>
<script setup lang="ts">
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui/vue";
</script>

<template>
    <MacWindow title="默认背景窗口" height="h-48" bgType="base-100">
        <PlaceHolder width="full" height="lg" padding="md">
            <p>这是使用默认背景的 MacWindow 组件。</p>
        </PlaceHolder>
    </MacWindow>
</template>
<script setup lang="ts">
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui/vue";
</script>

<template>
    <MacWindow title="主要背景窗口" height="h-48" bgType="primary">
        <PlaceHolder width="full" height="lg" padding="md">
            <p>这是使用主要背景的 MacWindow 组件。</p>
        </PlaceHolder>
    </MacWindow>
</template>
<script setup lang="ts">
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui/vue";
</script>

<template>
    <MacWindow title="次要背景窗口" height="h-48" bgType="secondary">
        <PlaceHolder width="full" height="lg" padding="md">
            <p>这是使用次要背景的 MacWindow 组件。</p>
        </PlaceHolder>
    </MacWindow>
</template>
<script setup lang="ts">
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui/vue";
</script>

<template>
    <MacWindow title="强调背景窗口" height="h-48" bgType="accent">
        <PlaceHolder width="full" height="lg" padding="md">
            <p>这是使用强调背景的 MacWindow 组件。</p>
        </PlaceHolder>
    </MacWindow>
</template>
<script setup lang="ts">
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui/vue";
</script>

<template>
    <MacWindow title="中性背景窗口" height="h-48" bgType="neutral">
        <PlaceHolder width="full" height="lg" padding="md">
            <p>这是使用中性背景的 MacWindow 组件。</p>
        </PlaceHolder>
    </MacWindow>
</template>
<script setup lang="ts">
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui/vue";
</script>

<template>
    <MacWindow title="信息背景窗口" height="h-48" bgType="info">
        <PlaceHolder width="full" height="lg" padding="md">
            <p>这是使用信息背景的 MacWindow 组件。</p>
        </PlaceHolder>
    </MacWindow>
</template>
<script setup lang="ts">
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui/vue";
</script>

<template>
    <MacWindow title="成功背景窗口" height="h-48" bgType="success">
        <PlaceHolder width="full" height="lg" padding="md">
            <p>这是使用成功背景的 MacWindow 组件。</p>
        </PlaceHolder>
    </MacWindow>
</template>
<script setup lang="ts">
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui/vue";
</script>

<template>
    <MacWindow title="警告背景窗口" height="h-48" bgType="warning">
        <PlaceHolder width="full" height="lg" padding="md">
            <p>这是使用警告背景的 MacWindow 组件。</p>
        </PlaceHolder>
    </MacWindow>
</template>
<script setup lang="ts">
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui/vue";
</script>

<template>
    <MacWindow title="错误背景窗口" height="h-48" bgType="error">
        <PlaceHolder width="full" height="lg" padding="md">
            <p>这是使用错误背景的 MacWindow 组件。</p>
        </PlaceHolder>
    </MacWindow>
</template>

height

自定义窗口高度,支持像素值或百分比。

终端-Astro版本
$ echo "Hello, World!"
Hello, World!
$ _

自定义高度窗口

自定义高度示例

这个窗口使用了自定义高度 `h-32`,比默认的 `h-96` 要矮一些。

你可以通过 `height` 属性来调整窗口的高度。

---



/**
 * @component MacWindow.CustomHeight
 *
 * @description
 * 自定义高度的MacWindow组件示例,展示终端风格的窗口。
 */
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";
---

<MacWindow title="终端-Astro版本" height="cosy:h-64">
  <PlaceHolder width="full" height="lg" padding="md">
    <div style="color: #10b981; font-family: monospace;">
      $ echo "Hello, World!"<br />
      Hello, World!<br />
      $ _
    </div>
  </PlaceHolder>
</MacWindow>
<script setup lang="ts">
import { MacWindow } from "@coffic/cosy-ui/vue";
</script>

<template>
    <MacWindow title="自定义高度窗口" height="h-32" bgType="accent">
        <div style="padding: 1rem;">
            <h3 style="margin-bottom: 1rem; font-weight: 600;">自定义高度示例</h3>
            <p>这个窗口使用了自定义高度 `h-32`比默认的 `h-96` 要矮一些。</p>
            <p>你可以通过 `height` 属性来调整窗口的高度。</p>
        </div>
    </MacWindow>
</template>

onClose

窗口关闭事件回调函数。

应用窗口-Astro版本
窗口内容区域
最近事件:

应用窗口-Vue版本
窗口内容区域
---



/**
 * @component MacWindow.WithEvents
 *
 * @description
 * 带事件处理的MacWindow组件示例,展示窗口操作事件。
 * 使用客户端JavaScript来处理事件和显示事件信息。
 */
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";

const windowId = "with-events-window";
---

<MacWindow
  title="应用窗口-Astro版本"
  tabs={['信息', '设置', '帮助']}
  id={windowId}>
  <div id="tab-信息">
    <PlaceHolder width="full" height="lg" padding="md" background="base-200">
      <div style="display: flex; flex-direction: column; gap: 0.5rem;">
        <div style="font-weight: 500;">窗口内容区域</div>
        <div
          id="event-log"
          style="display: flex; flex-direction: column; gap: 0.25rem;">
          <div style="font-size: 0.875rem; opacity: 0.7;">最近事件:</div>
          <!-- 事件日志将通过 JavaScript 动态添加 -->
        </div>
      </div>
    </PlaceHolder>
  </div>
  <div id="tab-设置" style="display: none;">
    <PlaceHolder width="full" height="lg" padding="md" background="base-200">
      设置内容
    </PlaceHolder>
  </div>
  <div id="tab-帮助" style="display: none;">
    <PlaceHolder width="full" height="lg" padding="md" background="base-200">
      帮助内容
    </PlaceHolder>
  </div>
</MacWindow>

<script>
  // 事件日志管理
  let eventLog: string[] = [];

  // 添加事件到日志
  function addEvent(event: string) {
    const timestamp = new Date().toLocaleTimeString();
    eventLog.unshift(`${timestamp} - ${event}`);
    // 只保留最近5个事件
    if (eventLog.length > 5) {
      eventLog = eventLog.slice(0, 5);
    }
    updateEventLog();
  }

  // 更新事件日志显示
  function updateEventLog() {
    const eventLogElement = document.getElementById('event-log');
    if (eventLogElement) {
      // 直接使用 eventLogElement 作为容器,因为它已经有正确的类名
      const logContainer = eventLogElement;
      if (logContainer) {
        // 清除现有事件
        const existingEvents = logContainer.querySelectorAll('.event-item');
        existingEvents.forEach((event) => event.remove());

        // 添加新事件
        eventLog.forEach((event) => {
          const eventDiv = document.createElement('div');
          eventDiv.className = 'event-item';
          eventDiv.style.cssText =
            'font-size: 0.75rem; background-color: #e5e7eb; padding: 0.25rem 0.5rem; border-radius: 0.25rem;';
          eventDiv.textContent = event;
          logContainer.appendChild(eventDiv);
        });
      }
    }
  }

  // 窗口事件处理
  document.addEventListener('DOMContentLoaded', () => {
    const windowElement = document.querySelector(
      '[data-window-id="with-events-window"]'
    );
    if (windowElement) {
      // 监听窗口控制按钮点击 - 使用更通用的选择器
      const controlButtons = windowElement.querySelectorAll(
        'div[class*="bg-error"], div[class*="bg-warning"], div[class*="bg-success"]'
      );

      controlButtons.forEach((button) => {
        button.addEventListener('click', () => {
          const buttonClasses = button.className;
          if (buttonClasses.includes('bg-error')) {
            console.log('关闭窗口');
            addEvent('关闭窗口');
          } else if (buttonClasses.includes('bg-warning')) {
            console.log('最小化窗口');
            addEvent('最小化窗口');
          } else if (buttonClasses.includes('bg-success')) {
            console.log('最大化窗口');
            addEvent('最大化窗口');
          }
        });
      });

      // 监听标签切换
      const tabButtons = windowElement.querySelectorAll('[data-tab]');
      tabButtons.forEach((button) => {
        button.addEventListener('click', (e) => {
          const clickedTab = (e.target as HTMLElement).getAttribute('data-tab');
          if (clickedTab) {
            console.log('切换到标签:', clickedTab);
            addEvent(`切换到标签: ${clickedTab}`);
          }
        });
      });
    }
  });
</script>
<!--
@component MacWindow.WithEvents

@description
带事件处理的MacWindow组件示例展示窗口操作事件
使用Vue的响应式特性来显示事件信息而不是使用alert
-->
<template>
  <MacWindow
    title="应用窗口-Vue版本"
    :tabs="['信息', '设置', '帮助']"
    :onTabClick="handleTabClick"
    :onCloseWindow="handleCloseWindow"
    :onMinimizeWindow="handleMinimizeWindow"
    :onMaximizeWindow="handleMaximizeWindow"
  >
    <div class="cosy:p-4">
      <div class="cosy:space-y-2">
        <div class="cosy:font-medium">窗口内容区域</div>
        <div v-if="eventLog.length > 0" class="cosy:space-y-1">
          <div class="cosy:text-sm cosy:text-base-content/70">最近事件:</div>
          <div
            v-for="(event, index) in eventLog"
            :key="index"
            class="cosy:text-xs cosy:bg-base-200 cosy:px-2 cosy:py-1 cosy:rounded"
          >
            {{ event }}
          </div>
        </div>
      </div>
    </div>
  </MacWindow>
</template>

<script setup lang="ts">
import { MacWindow } from "@coffic/cosy-ui/vue";
import { ref } from "vue";

// 响应式状态 - 事件日志
const eventLog = ref<string[]>([]);

// 添加事件到日志
const addEvent = (event: string) => {
	const timestamp = new Date().toLocaleTimeString();
	eventLog.value.unshift(`${timestamp} - ${event}`);
	// 只保留最近5个事件
	if (eventLog.value.length > 5) {
		eventLog.value = eventLog.value.slice(0, 5);
	}
};

// 处理标签点击事件
const handleTabClick = (tab: string) => {
	console.log("切换到标签:", tab);
	addEvent(`切换到标签: ${tab}`);
};

// 处理关闭窗口事件
const handleCloseWindow = () => {
	console.log("关闭窗口");
	addEvent("关闭窗口");
};

// 处理最小化窗口事件
const handleMinimizeWindow = () => {
	console.log("最小化窗口");
	addEvent("最小化窗口");
};

// 处理最大化窗口事件
const handleMaximizeWindow = () => {
	console.log("最大化窗口");
	addEvent("最大化窗口");
};
</script>

onMinimize

窗口最小化事件回调函数。

应用窗口-Astro版本
窗口内容区域
最近事件:

应用窗口-Vue版本
窗口内容区域
---



/**
 * @component MacWindow.WithEvents
 *
 * @description
 * 带事件处理的MacWindow组件示例,展示窗口操作事件。
 * 使用客户端JavaScript来处理事件和显示事件信息。
 */
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";

const windowId = "with-events-window";
---

<MacWindow
  title="应用窗口-Astro版本"
  tabs={['信息', '设置', '帮助']}
  id={windowId}>
  <div id="tab-信息">
    <PlaceHolder width="full" height="lg" padding="md" background="base-200">
      <div style="display: flex; flex-direction: column; gap: 0.5rem;">
        <div style="font-weight: 500;">窗口内容区域</div>
        <div
          id="event-log"
          style="display: flex; flex-direction: column; gap: 0.25rem;">
          <div style="font-size: 0.875rem; opacity: 0.7;">最近事件:</div>
          <!-- 事件日志将通过 JavaScript 动态添加 -->
        </div>
      </div>
    </PlaceHolder>
  </div>
  <div id="tab-设置" style="display: none;">
    <PlaceHolder width="full" height="lg" padding="md" background="base-200">
      设置内容
    </PlaceHolder>
  </div>
  <div id="tab-帮助" style="display: none;">
    <PlaceHolder width="full" height="lg" padding="md" background="base-200">
      帮助内容
    </PlaceHolder>
  </div>
</MacWindow>

<script>
  // 事件日志管理
  let eventLog: string[] = [];

  // 添加事件到日志
  function addEvent(event: string) {
    const timestamp = new Date().toLocaleTimeString();
    eventLog.unshift(`${timestamp} - ${event}`);
    // 只保留最近5个事件
    if (eventLog.length > 5) {
      eventLog = eventLog.slice(0, 5);
    }
    updateEventLog();
  }

  // 更新事件日志显示
  function updateEventLog() {
    const eventLogElement = document.getElementById('event-log');
    if (eventLogElement) {
      // 直接使用 eventLogElement 作为容器,因为它已经有正确的类名
      const logContainer = eventLogElement;
      if (logContainer) {
        // 清除现有事件
        const existingEvents = logContainer.querySelectorAll('.event-item');
        existingEvents.forEach((event) => event.remove());

        // 添加新事件
        eventLog.forEach((event) => {
          const eventDiv = document.createElement('div');
          eventDiv.className = 'event-item';
          eventDiv.style.cssText =
            'font-size: 0.75rem; background-color: #e5e7eb; padding: 0.25rem 0.5rem; border-radius: 0.25rem;';
          eventDiv.textContent = event;
          logContainer.appendChild(eventDiv);
        });
      }
    }
  }

  // 窗口事件处理
  document.addEventListener('DOMContentLoaded', () => {
    const windowElement = document.querySelector(
      '[data-window-id="with-events-window"]'
    );
    if (windowElement) {
      // 监听窗口控制按钮点击 - 使用更通用的选择器
      const controlButtons = windowElement.querySelectorAll(
        'div[class*="bg-error"], div[class*="bg-warning"], div[class*="bg-success"]'
      );

      controlButtons.forEach((button) => {
        button.addEventListener('click', () => {
          const buttonClasses = button.className;
          if (buttonClasses.includes('bg-error')) {
            console.log('关闭窗口');
            addEvent('关闭窗口');
          } else if (buttonClasses.includes('bg-warning')) {
            console.log('最小化窗口');
            addEvent('最小化窗口');
          } else if (buttonClasses.includes('bg-success')) {
            console.log('最大化窗口');
            addEvent('最大化窗口');
          }
        });
      });

      // 监听标签切换
      const tabButtons = windowElement.querySelectorAll('[data-tab]');
      tabButtons.forEach((button) => {
        button.addEventListener('click', (e) => {
          const clickedTab = (e.target as HTMLElement).getAttribute('data-tab');
          if (clickedTab) {
            console.log('切换到标签:', clickedTab);
            addEvent(`切换到标签: ${clickedTab}`);
          }
        });
      });
    }
  });
</script>
<!--
@component MacWindow.WithEvents

@description
带事件处理的MacWindow组件示例展示窗口操作事件
使用Vue的响应式特性来显示事件信息而不是使用alert
-->
<template>
  <MacWindow
    title="应用窗口-Vue版本"
    :tabs="['信息', '设置', '帮助']"
    :onTabClick="handleTabClick"
    :onCloseWindow="handleCloseWindow"
    :onMinimizeWindow="handleMinimizeWindow"
    :onMaximizeWindow="handleMaximizeWindow"
  >
    <div class="cosy:p-4">
      <div class="cosy:space-y-2">
        <div class="cosy:font-medium">窗口内容区域</div>
        <div v-if="eventLog.length > 0" class="cosy:space-y-1">
          <div class="cosy:text-sm cosy:text-base-content/70">最近事件:</div>
          <div
            v-for="(event, index) in eventLog"
            :key="index"
            class="cosy:text-xs cosy:bg-base-200 cosy:px-2 cosy:py-1 cosy:rounded"
          >
            {{ event }}
          </div>
        </div>
      </div>
    </div>
  </MacWindow>
</template>

<script setup lang="ts">
import { MacWindow } from "@coffic/cosy-ui/vue";
import { ref } from "vue";

// 响应式状态 - 事件日志
const eventLog = ref<string[]>([]);

// 添加事件到日志
const addEvent = (event: string) => {
	const timestamp = new Date().toLocaleTimeString();
	eventLog.value.unshift(`${timestamp} - ${event}`);
	// 只保留最近5个事件
	if (eventLog.value.length > 5) {
		eventLog.value = eventLog.value.slice(0, 5);
	}
};

// 处理标签点击事件
const handleTabClick = (tab: string) => {
	console.log("切换到标签:", tab);
	addEvent(`切换到标签: ${tab}`);
};

// 处理关闭窗口事件
const handleCloseWindow = () => {
	console.log("关闭窗口");
	addEvent("关闭窗口");
};

// 处理最小化窗口事件
const handleMinimizeWindow = () => {
	console.log("最小化窗口");
	addEvent("最小化窗口");
};

// 处理最大化窗口事件
const handleMaximizeWindow = () => {
	console.log("最大化窗口");
	addEvent("最大化窗口");
};
</script>

onMaximize

窗口最大化事件回调函数。

应用窗口-Astro版本
窗口内容区域
最近事件:

应用窗口-Vue版本
窗口内容区域
---



/**
 * @component MacWindow.WithEvents
 *
 * @description
 * 带事件处理的MacWindow组件示例,展示窗口操作事件。
 * 使用客户端JavaScript来处理事件和显示事件信息。
 */
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";

const windowId = "with-events-window";
---

<MacWindow
  title="应用窗口-Astro版本"
  tabs={['信息', '设置', '帮助']}
  id={windowId}>
  <div id="tab-信息">
    <PlaceHolder width="full" height="lg" padding="md" background="base-200">
      <div style="display: flex; flex-direction: column; gap: 0.5rem;">
        <div style="font-weight: 500;">窗口内容区域</div>
        <div
          id="event-log"
          style="display: flex; flex-direction: column; gap: 0.25rem;">
          <div style="font-size: 0.875rem; opacity: 0.7;">最近事件:</div>
          <!-- 事件日志将通过 JavaScript 动态添加 -->
        </div>
      </div>
    </PlaceHolder>
  </div>
  <div id="tab-设置" style="display: none;">
    <PlaceHolder width="full" height="lg" padding="md" background="base-200">
      设置内容
    </PlaceHolder>
  </div>
  <div id="tab-帮助" style="display: none;">
    <PlaceHolder width="full" height="lg" padding="md" background="base-200">
      帮助内容
    </PlaceHolder>
  </div>
</MacWindow>

<script>
  // 事件日志管理
  let eventLog: string[] = [];

  // 添加事件到日志
  function addEvent(event: string) {
    const timestamp = new Date().toLocaleTimeString();
    eventLog.unshift(`${timestamp} - ${event}`);
    // 只保留最近5个事件
    if (eventLog.length > 5) {
      eventLog = eventLog.slice(0, 5);
    }
    updateEventLog();
  }

  // 更新事件日志显示
  function updateEventLog() {
    const eventLogElement = document.getElementById('event-log');
    if (eventLogElement) {
      // 直接使用 eventLogElement 作为容器,因为它已经有正确的类名
      const logContainer = eventLogElement;
      if (logContainer) {
        // 清除现有事件
        const existingEvents = logContainer.querySelectorAll('.event-item');
        existingEvents.forEach((event) => event.remove());

        // 添加新事件
        eventLog.forEach((event) => {
          const eventDiv = document.createElement('div');
          eventDiv.className = 'event-item';
          eventDiv.style.cssText =
            'font-size: 0.75rem; background-color: #e5e7eb; padding: 0.25rem 0.5rem; border-radius: 0.25rem;';
          eventDiv.textContent = event;
          logContainer.appendChild(eventDiv);
        });
      }
    }
  }

  // 窗口事件处理
  document.addEventListener('DOMContentLoaded', () => {
    const windowElement = document.querySelector(
      '[data-window-id="with-events-window"]'
    );
    if (windowElement) {
      // 监听窗口控制按钮点击 - 使用更通用的选择器
      const controlButtons = windowElement.querySelectorAll(
        'div[class*="bg-error"], div[class*="bg-warning"], div[class*="bg-success"]'
      );

      controlButtons.forEach((button) => {
        button.addEventListener('click', () => {
          const buttonClasses = button.className;
          if (buttonClasses.includes('bg-error')) {
            console.log('关闭窗口');
            addEvent('关闭窗口');
          } else if (buttonClasses.includes('bg-warning')) {
            console.log('最小化窗口');
            addEvent('最小化窗口');
          } else if (buttonClasses.includes('bg-success')) {
            console.log('最大化窗口');
            addEvent('最大化窗口');
          }
        });
      });

      // 监听标签切换
      const tabButtons = windowElement.querySelectorAll('[data-tab]');
      tabButtons.forEach((button) => {
        button.addEventListener('click', (e) => {
          const clickedTab = (e.target as HTMLElement).getAttribute('data-tab');
          if (clickedTab) {
            console.log('切换到标签:', clickedTab);
            addEvent(`切换到标签: ${clickedTab}`);
          }
        });
      });
    }
  });
</script>
<!--
@component MacWindow.WithEvents

@description
带事件处理的MacWindow组件示例展示窗口操作事件
使用Vue的响应式特性来显示事件信息而不是使用alert
-->
<template>
  <MacWindow
    title="应用窗口-Vue版本"
    :tabs="['信息', '设置', '帮助']"
    :onTabClick="handleTabClick"
    :onCloseWindow="handleCloseWindow"
    :onMinimizeWindow="handleMinimizeWindow"
    :onMaximizeWindow="handleMaximizeWindow"
  >
    <div class="cosy:p-4">
      <div class="cosy:space-y-2">
        <div class="cosy:font-medium">窗口内容区域</div>
        <div v-if="eventLog.length > 0" class="cosy:space-y-1">
          <div class="cosy:text-sm cosy:text-base-content/70">最近事件:</div>
          <div
            v-for="(event, index) in eventLog"
            :key="index"
            class="cosy:text-xs cosy:bg-base-200 cosy:px-2 cosy:py-1 cosy:rounded"
          >
            {{ event }}
          </div>
        </div>
      </div>
    </div>
  </MacWindow>
</template>

<script setup lang="ts">
import { MacWindow } from "@coffic/cosy-ui/vue";
import { ref } from "vue";

// 响应式状态 - 事件日志
const eventLog = ref<string[]>([]);

// 添加事件到日志
const addEvent = (event: string) => {
	const timestamp = new Date().toLocaleTimeString();
	eventLog.value.unshift(`${timestamp} - ${event}`);
	// 只保留最近5个事件
	if (eventLog.value.length > 5) {
		eventLog.value = eventLog.value.slice(0, 5);
	}
};

// 处理标签点击事件
const handleTabClick = (tab: string) => {
	console.log("切换到标签:", tab);
	addEvent(`切换到标签: ${tab}`);
};

// 处理关闭窗口事件
const handleCloseWindow = () => {
	console.log("关闭窗口");
	addEvent("关闭窗口");
};

// 处理最小化窗口事件
const handleMinimizeWindow = () => {
	console.log("最小化窗口");
	addEvent("最小化窗口");
};

// 处理最大化窗口事件
const handleMaximizeWindow = () => {
	console.log("最大化窗口");
	addEvent("最大化窗口");
};
</script>

tabs

标签页配置,支持多个标签页切换。

设置-Astro版本
外观设置内容
当前选择的标签: 外观

设置-Vue版本
当前选择的标签: 外观
---



/**
 * @component MacWindow.WithTabs
 *
 * @description
 * 带标签页的MacWindow组件示例,展示标签页功能。
 * 使用客户端JavaScript来处理标签切换。
 */
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";

const windowId = "with-tabs-window";
---

<MacWindow
  title="设置-Astro版本"
  tabs={['通用', '外观', '高级']}
  defaultTab="外观"
  id={windowId}>
  <div id="tab-通用" style="display: none;">
    <PlaceHolder width="full" height="lg" padding="md" background="base-200">
      <div>通用设置内容</div>
      <div style="margin-top: 0.5rem;">当前选择的标签: 通用</div>
    </PlaceHolder>
  </div>
  <div id="tab-外观">
    <PlaceHolder width="full" height="lg" padding="md" background="base-200">
      <div>外观设置内容</div>
      <div style="margin-top: 0.5rem;">当前选择的标签: 外观</div>
    </PlaceHolder>
  </div>
  <div id="tab-高级" style="display: none;">
    <PlaceHolder width="full" height="lg" padding="md" background="base-200">
      <div>高级设置内容</div>
      <div style="margin-top: 0.5rem;">当前选择的标签: 高级</div>
    </PlaceHolder>
  </div>
</MacWindow>

<script>
  // 标签切换逻辑
  document.addEventListener('DOMContentLoaded', () => {
    const windowElement = document.querySelector(
      '[data-window-id="with-tabs-window"]'
    );
    if (windowElement) {
      const tabButtons = windowElement.querySelectorAll('[data-tab]');
      tabButtons.forEach((button) => {
        button.addEventListener('click', (e) => {
          const clickedTab = (e.target as HTMLElement).getAttribute('data-tab');
          if (clickedTab) {
            console.log('切换到标签:', clickedTab);

            // 更新内容显示
            const tabContents = windowElement.querySelectorAll('[id^="tab-"]');
            tabContents.forEach((content) => {
              (content as HTMLElement).style.display = 'none';
            });

            const selectedContent = windowElement.querySelector(
              `#tab-${clickedTab}`
            );
            if (selectedContent) {
              (selectedContent as HTMLElement).style.display = 'block';
            }
          }
        });
      });
    }
  });
</script>
<!--
@component MacWindow.WithTabs

@description
带标签页的MacWindow组件示例展示标签页功能
使用Vue的响应式特性来处理标签切换无需手动DOM操作
-->
<template>
  <MacWindow
    title="设置-Vue版本"
    :tabs="['通用', '外观', '高级']"
    :defaultTab="activeTab"
    :onTabClick="handleTabClick"
  >
    <div class="cosy:p-4">
      <div>当前选择的标签: {{ activeTab }}</div>
    </div>
  </MacWindow>
</template>

<script setup lang="ts">
import { MacWindow } from "@coffic/cosy-ui/vue";
import { ref } from "vue";

// 响应式状态
const activeTab = ref("外观");

// 处理标签点击事件
const handleTabClick = (tab: string) => {
	console.log("切换到标签:", tab);
	activeTab.value = tab;
};
</script>

width

窗口宽度,支持 Container 组件的 width 属性值:none、xs、sm、md、lg、xl、full。

小窗口
小宽度窗口内容

中等窗口
中等宽度窗口内容

大窗口
大宽度窗口内容

全宽窗口
全宽窗口内容

小窗口
小宽度窗口内容
中等窗口
中等宽度窗口内容
大窗口
大宽度窗口内容
全宽窗口
全宽窗口内容
---



import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";
---

<MacWindow title="小窗口" width="sm" height="h-48">
  <PlaceHolder width="full" height="lg" padding="md">
    小宽度窗口内容
  </PlaceHolder>
</MacWindow>
---



import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";
---

<MacWindow title="中等窗口" width="md" height="h-48">
  <PlaceHolder width="full" height="lg" padding="md">
    中等宽度窗口内容
  </PlaceHolder>
</MacWindow>
---



import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";
---

<MacWindow title="大窗口" width="lg" height="h-48">
  <PlaceHolder width="full" height="lg" padding="md">
    大宽度窗口内容
  </PlaceHolder>
</MacWindow>
---



import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";
---

<MacWindow title="全宽窗口" width="full" height="h-48">
  <PlaceHolder width="full" height="lg" padding="md">
    全宽窗口内容
  </PlaceHolder>
</MacWindow>
<template>
  <MacWindow title="小窗口" width="sm" height="h-48">
    <PlaceHolder width="full" height="lg" padding="md">
      小宽度窗口内容
    </PlaceHolder>
  </MacWindow>
</template>

<script setup lang="ts">
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui/vue";
</script>
<template>
  <MacWindow title="中等窗口" width="md" height="h-48">
    <PlaceHolder width="full" height="lg" padding="md">
      中等宽度窗口内容
    </PlaceHolder>
  </MacWindow>
</template>

<script setup lang="ts">
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui/vue";
</script>
<template>
  <MacWindow title="大窗口" width="lg" height="h-48">
    <PlaceHolder width="full" height="lg" padding="md">
      大宽度窗口内容
    </PlaceHolder>
  </MacWindow>
</template>

<script setup lang="ts">
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui/vue";
</script>
<template>
  <MacWindow title="全宽窗口" width="full" height="h-48">
    <PlaceHolder width="full" height="lg" padding="md">
      全宽窗口内容
    </PlaceHolder>
  </MacWindow>
</template>

<script setup lang="ts">
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui/vue";
</script>

Slots

default

默认插槽,用于放置窗口的主要内容。

侧边栏插槽,用于创建文件浏览器风格的布局。

文件浏览器-Astro版本
主内容区域

文件浏览器-Vue版本
文件夹
📁 文档
📁 图片
📁 音乐
📁 视频
文件列表
📄document.pdf
📄report.docx
📄presentation.pptx
---



/**
 * @component MacWindow.WithSidebar
 *
 * @description
 * 带侧边栏的MacWindow组件示例,展示文件浏览器风格的布局。
 */
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";
---

<MacWindow title="文件浏览器-Astro版本">
  <template #sidebar>
    <div
      style="width: 12rem; border-right: 1px solid #d1d5db; padding: 0.5rem;">
      <div style="font-weight: 500; margin-bottom: 0.5rem;">文件夹</div>
      <ul>
        <li
          style="padding: 0.25rem 0.5rem; border-radius: 0.25rem; cursor: pointer; margin-bottom: 0.25rem;">
          文档
        </li>
        <li
          style="padding: 0.25rem 0.5rem; border-radius: 0.25rem; cursor: pointer; margin-bottom: 0.25rem;">
          下载
        </li>
        <li
          style="padding: 0.25rem 0.5rem; border-radius: 0.25rem; cursor: pointer; margin-bottom: 0.25rem;">
          图片
        </li>
      </ul>
    </div>
  </template>
  <PlaceHolder width="full" height="lg" padding="md"> 主内容区域 </PlaceHolder>
</MacWindow>
<!--
@component MacWindow.WithSidebar

@description
带侧边栏的MacWindow组件示例展示侧边栏插槽的使用
-->
<template>
  <MacWindow title="文件浏览器-Vue版本">
    <div
      slot="sidebar"
      class="cosy:w-64 cosy:bg-base-200 cosy:border-r cosy:border-base-300"
    >
      <div class="cosy:p-4">
        <div class="cosy:font-medium cosy:mb-2">文件夹</div>
        <div class="cosy:space-y-1">
          <div
            class="cosy:text-sm cosy:px-2 cosy:py-1 cosy:rounded cosy:bg-base-100"
          >
            📁 文档
          </div>
          <div class="cosy:text-sm cosy:px-2 cosy:py-1 cosy:rounded">
            📁 图片
          </div>
          <div class="cosy:text-sm cosy:px-2 cosy:py-1 cosy:rounded">
            📁 音乐
          </div>
          <div class="cosy:text-sm cosy:px-2 cosy:py-1 cosy:rounded">
            📁 视频
          </div>
        </div>
      </div>
    </div>

    <div class="cosy:p-4">
      <div class="cosy:font-medium cosy:mb-4">文件列表</div>
      <div class="cosy:space-y-2">
        <div class="cosy:flex cosy:items-center cosy:space-x-2">
          <span class="cosy:text-lg">📄</span>
          <span class="cosy:text-sm">document.pdf</span>
        </div>
        <div class="cosy:flex cosy:items-center cosy:space-x-2">
          <span class="cosy:text-lg">📄</span>
          <span class="cosy:text-sm">report.docx</span>
        </div>
        <div class="cosy:flex cosy:items-center cosy:space-x-2">
          <span class="cosy:text-lg">📄</span>
          <span class="cosy:text-sm">presentation.pptx</span>
        </div>
      </div>
    </div>
  </MacWindow>
</template>

<script setup lang="ts">
import { MacWindow } from "@coffic/cosy-ui/vue";
</script>

toolbar

工具栏插槽,用于放置工具栏按钮和功能。

文件浏览器-Astro版本
窗口内容区域

文件浏览器-Vue版本
窗口内容
就绪
---



/**
 * @component MacWindow.WithToolbar
 *
 * @description
 * 带工具栏和状态栏的MacWindow组件示例,展示自定义工具栏功能。
 */
import { MacWindow, PlaceHolder } from "@coffic/cosy-ui";
---

<MacWindow title="文件浏览器-Astro版本">
  <template #toolbar>
    <button
      style="background: transparent; border: none; padding: 0.25rem 0.5rem; cursor: pointer;"
      onclick="console.log('搜索')">
      🔍
    </button>
    <button
      style="background: transparent; border: none; padding: 0.25rem 0.5rem; cursor: pointer;"
      onclick="console.log('设置')">
      ⚙️
    </button>
  </template>

  <PlaceHolder width="full" height="lg" padding="md">
    窗口内容区域
  </PlaceHolder>

  <template #status>
    <div style="font-size: 0.75rem;">就绪</div>
    <button
      style="background: transparent; border: none; padding: 0.125rem 0.25rem; cursor: pointer; font-size: 0.75rem;"
      onclick="console.log('信息')">

    </button>
  </template>
</MacWindow>
<!--
@component MacWindow.WithToolbar

@description
带工具栏的MacWindow组件示例展示工具栏和状态栏插槽的使用
-->
<template>
  <MacWindow title="文件浏览器-Vue版本">
    <div slot="toolbar">
      <button class="cosy:btn cosy:btn-ghost cosy:btn-sm">
        <SearchIcon class="cosy:w-4 cosy:h-4" />
      </button>
      <button class="cosy:btn cosy:btn-ghost cosy:btn-sm">
        <SettingsIcon class="cosy:w-4 cosy:h-4" />
      </button>
    </div>

    <div class="cosy:p-4">窗口内容</div>

    <div slot="status">
      <div class="cosy:text-xs">就绪</div>
      <button class="cosy:btn cosy:btn-ghost cosy:btn-xs">
        <InfoIcon class="cosy:w-4 cosy:h-4" />
      </button>
    </div>
  </MacWindow>
</template>

<script setup lang="ts">
import { InfoIcon, MacWindow, SearchIcon, SettingsIcon } from "@coffic/cosy-ui/vue";
</script>

搜索