generated from corrad-software/corrad-af-2024
800 lines
29 KiB
Vue
800 lines
29 KiB
Vue
<script setup>
|
|
import { ref, onMounted } from 'vue';
|
|
import { useDesignSystem } from '~/composables/useDesignSystem';
|
|
import { useNotifications } from '~/composables/useNotifications';
|
|
import { useTouchInteractions } from '~/composables/useTouchInteractions';
|
|
|
|
// Page meta
|
|
definePageMeta({
|
|
title: "Design System Demo",
|
|
layout: "default"
|
|
});
|
|
|
|
// Components
|
|
import ResponsiveContainer from '~/components/base/ResponsiveContainer.vue';
|
|
import BaseModal from '~/components/base/BaseModal.vue';
|
|
import LoadingStates from '~/components/base/LoadingStates.vue';
|
|
import AdvancedDataTable from '~/components/base/AdvancedDataTable.vue';
|
|
import WindowsExplorerTree from '~/components/dms/explorer/WindowsExplorerTree.vue';
|
|
import NotificationDisplay from '~/components/base/NotificationDisplay.vue';
|
|
import RsButton from '~/components/RsButton.vue';
|
|
|
|
// Design system and utilities - wrapped in try-catch to handle SSR
|
|
let designSystem, notifications;
|
|
try {
|
|
designSystem = useDesignSystem();
|
|
notifications = useNotifications();
|
|
} catch (error) {
|
|
console.warn('Design system initialization error:', error);
|
|
}
|
|
|
|
const { tokens, utils, dmsPatterns, statusColors } = designSystem || {};
|
|
const { success, error, warning, info, confirm, loading, dms } = notifications || {};
|
|
|
|
// Demo state
|
|
const showModal = ref(false);
|
|
const currentDemo = ref('overview');
|
|
const loadingDemo = ref(false);
|
|
const tableLoading = ref(false);
|
|
const treeLoading = ref(false);
|
|
const isClient = ref(false);
|
|
|
|
// Sample data for demos
|
|
const sampleTreeData = ref([
|
|
{
|
|
id: '1',
|
|
name: 'Documents',
|
|
type: 'folder',
|
|
parentId: null,
|
|
size: null,
|
|
modifiedAt: '2024-01-15T10:30:00Z'
|
|
},
|
|
{
|
|
id: '2',
|
|
name: 'Projects',
|
|
type: 'folder',
|
|
parentId: '1',
|
|
size: null,
|
|
modifiedAt: '2024-01-14T15:45:00Z'
|
|
},
|
|
{
|
|
id: '3',
|
|
name: 'Project_Plan.pdf',
|
|
type: 'file',
|
|
parentId: '2',
|
|
size: 2048576,
|
|
modifiedAt: '2024-01-13T09:15:00Z'
|
|
},
|
|
{
|
|
id: '4',
|
|
name: 'Budget.xlsx',
|
|
type: 'file',
|
|
parentId: '2',
|
|
size: 1024000,
|
|
modifiedAt: '2024-01-12T14:20:00Z'
|
|
},
|
|
{
|
|
id: '5',
|
|
name: 'Archive',
|
|
type: 'folder',
|
|
parentId: null,
|
|
size: null,
|
|
modifiedAt: '2024-01-10T11:00:00Z'
|
|
}
|
|
]);
|
|
|
|
const sampleTableData = ref([
|
|
{
|
|
id: 1,
|
|
name: 'Annual_Report_2024.pdf',
|
|
type: 'PDF Document',
|
|
size: 2048576,
|
|
owner: 'John Doe',
|
|
modified: '2024-01-15T10:30:00Z',
|
|
status: 'active',
|
|
version: '2.1'
|
|
},
|
|
{
|
|
id: 2,
|
|
name: 'Q4_Budget_Analysis.xlsx',
|
|
type: 'Spreadsheet',
|
|
size: 1536000,
|
|
owner: 'Jane Smith',
|
|
modified: '2024-01-14T15:45:00Z',
|
|
status: 'active',
|
|
version: '1.3'
|
|
},
|
|
{
|
|
id: 3,
|
|
name: 'Meeting_Notes_Draft.docx',
|
|
type: 'Word Document',
|
|
size: 512000,
|
|
owner: 'Mike Johnson',
|
|
modified: '2024-01-13T09:15:00Z',
|
|
status: 'inactive',
|
|
version: '1.0'
|
|
},
|
|
{
|
|
id: 4,
|
|
name: 'Project_Presentation.pptx',
|
|
type: 'Presentation',
|
|
size: 3072000,
|
|
owner: 'Sarah Wilson',
|
|
modified: '2024-01-12T14:20:00Z',
|
|
status: 'active',
|
|
version: '1.7'
|
|
}
|
|
]);
|
|
|
|
const tableColumns = ref([
|
|
{
|
|
key: 'name',
|
|
title: 'Document Name',
|
|
sortable: true,
|
|
filterable: true
|
|
},
|
|
{
|
|
key: 'type',
|
|
title: 'Type',
|
|
sortable: true,
|
|
filterable: true
|
|
},
|
|
{
|
|
key: 'size',
|
|
title: 'Size',
|
|
type: 'filesize',
|
|
sortable: true,
|
|
align: 'right'
|
|
},
|
|
{
|
|
key: 'owner',
|
|
title: 'Owner',
|
|
sortable: true,
|
|
filterable: true
|
|
},
|
|
{
|
|
key: 'modified',
|
|
title: 'Modified',
|
|
type: 'date',
|
|
sortable: true
|
|
},
|
|
{
|
|
key: 'status',
|
|
title: 'Status',
|
|
type: 'status',
|
|
sortable: true,
|
|
filterable: true
|
|
},
|
|
{
|
|
key: 'version',
|
|
title: 'Version',
|
|
sortable: true,
|
|
align: 'center'
|
|
}
|
|
]);
|
|
|
|
const tableActions = ref([
|
|
{
|
|
key: 'view',
|
|
icon: 'mdi:eye',
|
|
title: 'View Document',
|
|
variant: 'secondary-outline'
|
|
},
|
|
{
|
|
key: 'edit',
|
|
icon: 'mdi:pencil',
|
|
title: 'Edit Document',
|
|
variant: 'primary'
|
|
},
|
|
{
|
|
key: 'delete',
|
|
icon: 'mdi:delete',
|
|
title: 'Delete Document',
|
|
variant: 'danger'
|
|
}
|
|
]);
|
|
|
|
// Demo sections
|
|
const demoSections = ref([
|
|
{ id: 'overview', title: 'Design System Overview', icon: 'mdi:palette' },
|
|
{ id: 'components', title: 'Base Components', icon: 'mdi:view-grid' },
|
|
{ id: 'loading', title: 'Loading States', icon: 'mdi:loading' },
|
|
{ id: 'notifications', title: 'Notifications', icon: 'mdi:bell' },
|
|
{ id: 'table', title: 'Data Tables', icon: 'mdi:table' },
|
|
{ id: 'tree', title: 'File Explorer', icon: 'mdi:file-tree' },
|
|
{ id: 'responsive', title: 'Responsive Design', icon: 'mdi:responsive' },
|
|
{ id: 'touch', title: 'Touch Interactions', icon: 'mdi:gesture-tap' }
|
|
]);
|
|
|
|
// Demo functions
|
|
const showNotificationDemo = (type) => {
|
|
switch (type) {
|
|
case 'success':
|
|
success('Document uploaded successfully!');
|
|
break;
|
|
case 'error':
|
|
error('Failed to save document. Please try again.');
|
|
break;
|
|
case 'warning':
|
|
warning('Document will be auto-saved in 30 seconds.');
|
|
break;
|
|
case 'info':
|
|
info('New version of the document is available.');
|
|
break;
|
|
case 'loading':
|
|
loading(
|
|
new Promise(resolve => setTimeout(resolve, 3000)),
|
|
{
|
|
title: 'Processing Document',
|
|
message: 'Please wait while we process your document...'
|
|
}
|
|
);
|
|
break;
|
|
case 'confirm':
|
|
confirm({
|
|
title: 'Delete Document',
|
|
message: 'Are you sure you want to permanently delete this document?',
|
|
dangerous: true
|
|
});
|
|
break;
|
|
}
|
|
};
|
|
|
|
const showDMSNotificationDemo = (type) => {
|
|
switch (type) {
|
|
case 'upload':
|
|
dms.documentUploaded('Annual_Report_2024.pdf');
|
|
break;
|
|
case 'share':
|
|
dms.documentShared('Budget_Analysis.xlsx', ['john.doe', 'jane.smith']);
|
|
break;
|
|
case 'sync':
|
|
dms.syncStarted();
|
|
setTimeout(() => dms.syncCompleted(42), 2000);
|
|
break;
|
|
case 'version':
|
|
dms.newVersionCreated('Project_Plan.pdf', '2.1');
|
|
break;
|
|
case 'access':
|
|
dms.accessGranted('Financial Reports folder');
|
|
break;
|
|
}
|
|
};
|
|
|
|
const toggleTableLoading = () => {
|
|
tableLoading.value = true;
|
|
setTimeout(() => {
|
|
tableLoading.value = false;
|
|
}, 2000);
|
|
};
|
|
|
|
const toggleTreeLoading = () => {
|
|
treeLoading.value = true;
|
|
setTimeout(() => {
|
|
treeLoading.value = false;
|
|
}, 1500);
|
|
};
|
|
|
|
// Touch interaction demo
|
|
const setupTouchDemo = () => {
|
|
const { setupTouchInteractions, onSwipeLeft, onSwipeRight, onTap, onLongPress } = useTouchInteractions();
|
|
|
|
const touchArea = document.getElementById('touch-demo-area');
|
|
if (touchArea) {
|
|
setupTouchInteractions(touchArea);
|
|
|
|
onSwipeLeft(() => {
|
|
info('Swiped left! In DMS, this could delete a file.');
|
|
});
|
|
|
|
onSwipeRight(() => {
|
|
info('Swiped right! In DMS, this could open file details.');
|
|
});
|
|
|
|
onTap(() => {
|
|
info('Tapped! This would select a file.');
|
|
});
|
|
|
|
onLongPress(() => {
|
|
info('Long pressed! This would show the context menu.');
|
|
});
|
|
}
|
|
};
|
|
|
|
// File size formatter
|
|
const formatFileSize = (bytes) => {
|
|
if (!bytes) return '0 B';
|
|
const k = 1024;
|
|
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
|
|
};
|
|
|
|
// Date formatter
|
|
const formatDate = (dateString) => {
|
|
return new Date(dateString).toLocaleDateString();
|
|
};
|
|
|
|
// Lifecycle
|
|
onMounted(() => {
|
|
setupTouchDemo();
|
|
isClient.value = true;
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<!-- Loading state for SSR -->
|
|
<div v-if="!isClient" class="flex items-center justify-center min-h-screen">
|
|
<div class="text-center">
|
|
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto mb-4"></div>
|
|
<p class="text-gray-600">Loading Design System Demo...</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Client-only content -->
|
|
<ClientOnly>
|
|
<ResponsiveContainer v-if="isClient" layout="sidebar" class="design-system-demo">
|
|
<!-- Sidebar Navigation -->
|
|
<template #sidebar>
|
|
<div class="h-full flex flex-col">
|
|
<div class="p-6 border-b border-gray-200 dark:border-gray-600">
|
|
<h2 class="text-xl font-bold text-gray-900 dark:text-gray-100">
|
|
DMS Design System
|
|
</h2>
|
|
<p class="text-sm text-gray-600 dark:text-gray-400 mt-1">
|
|
Interactive component demonstrations
|
|
</p>
|
|
</div>
|
|
|
|
<nav class="flex-1 p-4 space-y-2">
|
|
<button
|
|
v-for="section in demoSections"
|
|
:key="section.id"
|
|
@click="currentDemo = section.id"
|
|
:class="[
|
|
'w-full flex items-center space-x-3 px-3 py-2 rounded-md text-left transition-colors',
|
|
currentDemo === section.id
|
|
? 'bg-blue-600 text-white'
|
|
: 'text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700'
|
|
]"
|
|
>
|
|
<Icon :name="section.icon" class="w-5 h-5" />
|
|
<span>{{ section.title }}</span>
|
|
</button>
|
|
</nav>
|
|
</div>
|
|
</template>
|
|
|
|
<!-- Main Content -->
|
|
<div class="space-y-8">
|
|
<!-- Design System Overview -->
|
|
<section v-if="currentDemo === 'overview'" class="space-y-6">
|
|
<div>
|
|
<h1 class="text-3xl font-bold text-gray-900 dark:text-gray-100 mb-4">
|
|
Design System Overview
|
|
</h1>
|
|
<p class="text-lg text-gray-600 dark:text-gray-400">
|
|
A comprehensive design system for the Document Management System featuring consistent components, responsive design, and enhanced user experience.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Color Palette -->
|
|
<div v-if="statusColors" class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-600 p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
|
Status Colors
|
|
</h3>
|
|
<div class="grid grid-cols-2 md:grid-cols-5 gap-4">
|
|
<div v-for="(color, status) in statusColors" :key="status" class="text-center">
|
|
<div
|
|
:class="[color.bg, color.border, 'w-16 h-16 rounded-lg border-2 mx-auto mb-2']"
|
|
></div>
|
|
<p class="text-sm font-medium capitalize">{{ status }}</p>
|
|
<p :class="[color.text, 'text-xs']">{{ status }} state</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Typography Scale -->
|
|
<div v-if="tokens?.typography" class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-600 p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
|
Typography Scale
|
|
</h3>
|
|
<div class="space-y-3">
|
|
<div v-for="(size, key) in tokens.typography.sizes" :key="key" class="flex items-center space-x-4">
|
|
<span class="w-12 text-xs text-gray-500 dark:text-gray-400">{{ key }}</span>
|
|
<span :style="{ fontSize: size }" class="text-gray-900 dark:text-gray-100">
|
|
The quick brown fox jumps over the lazy dog
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Spacing System -->
|
|
<div v-if="tokens?.spacing" class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-600 p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
|
Spacing System
|
|
</h3>
|
|
<div class="space-y-2">
|
|
<div v-for="(space, key) in tokens.spacing" :key="key" class="flex items-center space-x-4">
|
|
<span class="w-12 text-xs text-gray-500 dark:text-gray-400">{{ key }}</span>
|
|
<div
|
|
class="bg-blue-200 dark:bg-blue-300 rounded"
|
|
:style="{ width: space, height: '20px' }"
|
|
></div>
|
|
<span class="text-sm text-gray-600 dark:text-gray-400">{{ space }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Base Components -->
|
|
<section v-if="currentDemo === 'components'" class="space-y-6">
|
|
<h1 class="text-3xl font-bold text-gray-900 dark:text-gray-100">
|
|
Base Components
|
|
</h1>
|
|
|
|
<!-- Buttons -->
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-600 p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
|
Button Variants
|
|
</h3>
|
|
<div class="flex flex-wrap gap-4">
|
|
<RsButton variant="primary">Primary</RsButton>
|
|
<RsButton variant="secondary">Secondary</RsButton>
|
|
<RsButton variant="secondary-outline">Secondary Outline</RsButton>
|
|
<RsButton variant="danger">Danger</RsButton>
|
|
<RsButton variant="success">Success</RsButton>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal Demo -->
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-600 p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
|
Enhanced Modal
|
|
</h3>
|
|
<RsButton @click="showModal = true">Show Modal</RsButton>
|
|
|
|
<BaseModal
|
|
v-model:visible="showModal"
|
|
title="Enhanced Modal Dialog"
|
|
size="lg"
|
|
@confirm="success && success('Modal confirmed!')"
|
|
@cancel="info && info('Modal cancelled')"
|
|
>
|
|
<div class="space-y-4">
|
|
<p class="text-gray-600 dark:text-gray-400">
|
|
This is an enhanced modal with consistent styling, animations, and responsive behavior.
|
|
</p>
|
|
<div class="bg-gray-50 dark:bg-gray-700 rounded-lg p-4">
|
|
<h4 class="font-medium text-gray-900 dark:text-gray-100 mb-2">Features:</h4>
|
|
<ul class="list-disc list-inside space-y-1 text-sm text-gray-600 dark:text-gray-400">
|
|
<li>Responsive sizing and positioning</li>
|
|
<li>Keyboard navigation and focus management</li>
|
|
<li>Smooth entrance and exit animations</li>
|
|
<li>Dark mode support</li>
|
|
<li>Accessibility features</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</BaseModal>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Loading States -->
|
|
<section v-if="currentDemo === 'loading'" class="space-y-6">
|
|
<h1 class="text-3xl font-bold text-gray-900 dark:text-gray-100">
|
|
Loading States
|
|
</h1>
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
<!-- Spinners -->
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-600 p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
|
Spinner Variants
|
|
</h3>
|
|
<div class="space-y-4">
|
|
<LoadingStates type="spinner" size="sm" message="Small spinner" />
|
|
<LoadingStates type="spinner" size="md" message="Medium spinner" />
|
|
<LoadingStates type="spinner" size="lg" message="Large spinner" />
|
|
<LoadingStates type="pulse" message="Pulse animation" />
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Skeleton Loaders -->
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-600 p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
|
Skeleton Loaders
|
|
</h3>
|
|
<LoadingStates type="skeleton-list" :count="3" />
|
|
</div>
|
|
|
|
<!-- Table Skeleton -->
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-600 p-6 lg:col-span-2">
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
|
Table Skeleton
|
|
</h3>
|
|
<LoadingStates type="skeleton-table" :count="4" />
|
|
</div>
|
|
|
|
<!-- Card Skeleton -->
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-600 p-6 lg:col-span-2">
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
|
Card Skeletons
|
|
</h3>
|
|
<LoadingStates type="skeleton-card" :count="3" />
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Notifications -->
|
|
<section v-if="currentDemo === 'notifications'" class="space-y-6">
|
|
<h1 class="text-3xl font-bold text-gray-900 dark:text-gray-100">
|
|
Notification System
|
|
</h1>
|
|
|
|
<!-- Basic Notifications -->
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-600 p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
|
Basic Notifications
|
|
</h3>
|
|
<div class="flex flex-wrap gap-4">
|
|
<RsButton @click="showNotificationDemo('success')" variant="success">
|
|
Success Toast
|
|
</RsButton>
|
|
<RsButton @click="showNotificationDemo('error')" variant="danger">
|
|
Error Toast
|
|
</RsButton>
|
|
<RsButton @click="showNotificationDemo('warning')" variant="secondary">
|
|
Warning Toast
|
|
</RsButton>
|
|
<RsButton @click="showNotificationDemo('info')" variant="primary">
|
|
Info Toast
|
|
</RsButton>
|
|
<RsButton @click="showNotificationDemo('loading')" variant="secondary-outline">
|
|
Loading Toast
|
|
</RsButton>
|
|
<RsButton @click="showNotificationDemo('confirm')" variant="secondary-outline">
|
|
Confirmation Dialog
|
|
</RsButton>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- DMS-Specific Notifications -->
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-600 p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
|
DMS-Specific Notifications
|
|
</h3>
|
|
<div class="flex flex-wrap gap-4">
|
|
<RsButton @click="showDMSNotificationDemo('upload')" variant="success">
|
|
Document Uploaded
|
|
</RsButton>
|
|
<RsButton @click="showDMSNotificationDemo('share')" variant="primary">
|
|
Document Shared
|
|
</RsButton>
|
|
<RsButton @click="showDMSNotificationDemo('sync')" variant="secondary">
|
|
Sync Operation
|
|
</RsButton>
|
|
<RsButton @click="showDMSNotificationDemo('version')" variant="secondary-outline">
|
|
New Version
|
|
</RsButton>
|
|
<RsButton @click="showDMSNotificationDemo('access')" variant="success">
|
|
Access Granted
|
|
</RsButton>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Data Table -->
|
|
<section v-if="currentDemo === 'table'" class="space-y-6">
|
|
<div class="flex items-center justify-between">
|
|
<h1 class="text-3xl font-bold text-gray-900 dark:text-gray-100">
|
|
Advanced Data Table
|
|
</h1>
|
|
<RsButton @click="toggleTableLoading" :disabled="tableLoading">
|
|
{{ tableLoading ? 'Loading...' : 'Demo Loading' }}
|
|
</RsButton>
|
|
</div>
|
|
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-600 p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
|
Advanced Data Table
|
|
</h3>
|
|
<div class="h-96 overflow-hidden">
|
|
<AdvancedDataTable
|
|
:data="sampleTableData"
|
|
:columns="tableColumns"
|
|
:actions="tableActions"
|
|
:loading="tableLoading"
|
|
:pagination="{ page: 1, pageSize: 10, total: 4, showSizeChanger: true }"
|
|
selectable
|
|
@action-click="(action, row) => info && info(`Action '${action}' clicked for ${row.name}`)"
|
|
@row-click="(row) => info && info(`Clicked on ${row.name}`)"
|
|
@selection-change="(selected) => info && info(`Selected ${selected.length} items`)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- File Explorer Tree -->
|
|
<section v-if="currentDemo === 'tree'" class="space-y-6">
|
|
<div class="flex items-center justify-between">
|
|
<h1 class="text-3xl font-bold text-gray-900 dark:text-gray-100">
|
|
Windows Explorer Tree
|
|
</h1>
|
|
<RsButton @click="toggleTreeLoading" :disabled="treeLoading">
|
|
{{ treeLoading ? 'Loading...' : 'Demo Loading' }}
|
|
</RsButton>
|
|
</div>
|
|
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-600 overflow-hidden">
|
|
<div class="h-96">
|
|
<WindowsExplorerTree
|
|
:data="sampleTreeData"
|
|
:loading="treeLoading"
|
|
@node-click="(node) => info && info(`Clicked on ${node.name}`)"
|
|
@node-rename="(data) => success && success(`Renamed to ${data.newName}`)"
|
|
@folder-create="(data) => success && success(`Created folder: ${data.name}`)"
|
|
@file-upload="() => dms && dms.documentUploaded('NewDocument.pdf')"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Responsive Design -->
|
|
<section v-if="currentDemo === 'responsive'" class="space-y-6">
|
|
<h1 class="text-3xl font-bold text-gray-900 dark:text-gray-100">
|
|
Responsive Design
|
|
</h1>
|
|
|
|
<div v-if="utils?.responsive" class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-600 p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
|
Breakpoint System
|
|
</h3>
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
<div v-for="(width, breakpoint) in utils.responsive" :key="breakpoint" class="p-4 bg-gray-50 dark:bg-gray-700 rounded-lg">
|
|
<h4 class="font-medium text-gray-900 dark:text-gray-100">{{ breakpoint }}</h4>
|
|
<p class="text-sm text-gray-600 dark:text-gray-400">{{ width }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-600 p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
|
Layout Patterns
|
|
</h3>
|
|
<div class="space-y-4">
|
|
<div class="p-4 bg-gray-50 dark:bg-gray-700 rounded-lg">
|
|
<h4 class="font-medium text-gray-900 dark:text-gray-100 mb-2">Stack Layout</h4>
|
|
<div class="flex flex-col space-y-2">
|
|
<div class="bg-blue-200 dark:bg-blue-300 p-2 rounded">Item 1</div>
|
|
<div class="bg-blue-200 dark:bg-blue-300 p-2 rounded">Item 2</div>
|
|
<div class="bg-blue-200 dark:bg-blue-300 p-2 rounded">Item 3</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="p-4 bg-gray-50 dark:bg-gray-700 rounded-lg">
|
|
<h4 class="font-medium text-gray-900 dark:text-gray-100 mb-2">Grid Layout</h4>
|
|
<div class="grid grid-cols-3 gap-2">
|
|
<div class="bg-blue-200 dark:bg-blue-300 p-2 rounded">Grid 1</div>
|
|
<div class="bg-blue-200 dark:bg-blue-300 p-2 rounded">Grid 2</div>
|
|
<div class="bg-blue-200 dark:bg-blue-300 p-2 rounded">Grid 3</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Touch Interactions -->
|
|
<section v-if="currentDemo === 'touch'" class="space-y-6">
|
|
<h1 class="text-3xl font-bold text-gray-900 dark:text-gray-100">
|
|
Touch Interactions
|
|
</h1>
|
|
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-600 p-6">
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
|
Interactive Touch Area
|
|
</h3>
|
|
<p class="text-gray-600 dark:text-gray-400 mb-4">
|
|
Try different touch gestures on the area below (works on mobile devices):
|
|
</p>
|
|
|
|
<div
|
|
id="touch-demo-area"
|
|
class="bg-gradient-to-br from-blue-100 to-blue-200 dark:from-blue-200 dark:to-blue-300
|
|
border-2 border-dashed border-blue-500 rounded-lg p-8 text-center"
|
|
>
|
|
<Icon name="mdi:gesture-tap" class="w-16 h-16 mx-auto mb-4 text-blue-600" />
|
|
<h4 class="text-lg font-medium text-gray-900 dark:text-gray-100 mb-2">
|
|
Touch Gesture Area
|
|
</h4>
|
|
<p class="text-gray-600 dark:text-gray-400 text-sm">
|
|
Tap, long press, swipe left/right to test interactions
|
|
</p>
|
|
</div>
|
|
|
|
<div class="mt-6 grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
|
|
<div class="text-center p-3 bg-gray-50 dark:bg-gray-700 rounded-lg">
|
|
<Icon name="mdi:gesture-tap" class="w-6 h-6 mx-auto mb-1 text-blue-500" />
|
|
<p class="font-medium">Tap</p>
|
|
<p class="text-gray-500 dark:text-gray-400">Select file</p>
|
|
</div>
|
|
<div class="text-center p-3 bg-gray-50 dark:bg-gray-700 rounded-lg">
|
|
<Icon name="mdi:gesture-tap-hold" class="w-6 h-6 mx-auto mb-1 text-green-500" />
|
|
<p class="font-medium">Long Press</p>
|
|
<p class="text-gray-500 dark:text-gray-400">Context menu</p>
|
|
</div>
|
|
<div class="text-center p-3 bg-gray-50 dark:bg-gray-700 rounded-lg">
|
|
<Icon name="mdi:gesture-swipe-left" class="w-6 h-6 mx-auto mb-1 text-red-500" />
|
|
<p class="font-medium">Swipe Left</p>
|
|
<p class="text-gray-500 dark:text-gray-400">Delete action</p>
|
|
</div>
|
|
<div class="text-center p-3 bg-gray-50 dark:bg-gray-700 rounded-lg">
|
|
<Icon name="mdi:gesture-swipe-right" class="w-6 h-6 mx-auto mb-1 text-purple-500" />
|
|
<p class="font-medium">Swipe Right</p>
|
|
<p class="text-gray-500 dark:text-gray-400">File details</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
|
|
<!-- Notification Display Component -->
|
|
<NotificationDisplay />
|
|
</ResponsiveContainer>
|
|
|
|
<template #fallback>
|
|
<div class="flex items-center justify-center min-h-screen">
|
|
<div class="text-center">
|
|
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto mb-4"></div>
|
|
<p class="text-gray-600">Loading components...</p>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</ClientOnly>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.design-system-demo {
|
|
min-height: 100vh;
|
|
}
|
|
|
|
/* Touch demo area enhancements */
|
|
#touch-demo-area {
|
|
user-select: none;
|
|
touch-action: manipulation;
|
|
min-height: 200px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
/* Demo section transitions */
|
|
.demo-section {
|
|
animation: fadeInUp 0.5s ease-out;
|
|
}
|
|
|
|
@keyframes fadeInUp {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(20px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
/* Responsive adjustments */
|
|
@media (max-width: 768px) {
|
|
.grid.grid-cols-2.md\\:grid-cols-4 {
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
}
|
|
|
|
.grid.grid-cols-1.lg\\:grid-cols-2 {
|
|
grid-template-columns: repeat(1, minmax(0, 1fr));
|
|
}
|
|
}
|
|
</style> |