Skip to content

Commit

Permalink
feat(bigscreen): support bigscreen
Browse files Browse the repository at this point in the history
  • Loading branch information
qianmoQ committed Nov 18, 2024
1 parent 16d3458 commit 17acd5f
Show file tree
Hide file tree
Showing 8 changed files with 341 additions and 21 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ All notable changes to this project will be documented in this file. See [standa
### 🐛 Bug Fixes

- **input:** fixed textarea border ([588b8dd](https://github.com/devlive-community/shadcn-ui-vue-admin/commit/588b8dd889d8846068c262c984c1e8dc5608043c))
- **tree:** fix the abnormal hover and selected styles in lazy
loading ([b6610f1](https://github.com/devlive-community/shadcn-ui-vue-admin/commit/b6610f18ecbcc4b9f91581d04fc45064bfeac334))
- **tree:** fix the abnormal hover and selected styles in lazy loading ([b6610f1](https://github.com/devlive-community/shadcn-ui-vue-admin/commit/b6610f18ecbcc4b9f91581d04fc45064bfeac334))

### ✨ Features

Expand All @@ -31,6 +30,7 @@ All notable changes to this project will be documented in this file. See [standa
- **toggle:** support group multiple mode ([ae09b8c](https://github.com/devlive-community/shadcn-ui-vue-admin/commit/ae09b8c560d474e7cd2b06de965a91b8f8e80750))
- **toggle:** support size ([0efec03](https://github.com/devlive-community/shadcn-ui-vue-admin/commit/0efec03439273445b928c22a3efdcf6e66890cc9))
- **toggle:** support toggle ([f732b08](https://github.com/devlive-community/shadcn-ui-vue-admin/commit/f732b08f27a183ff843f076988d5b2dac6bb0f65))
- **switch**: support true-value and false-value([036b7b3](https://github.com/devlive-community/view-shadcn-ui/commit/036b7b32a2186b87d5c53b9d458c86792a28109c))

## 2024.3.0 (2024-11-10)

Expand Down
4 changes: 2 additions & 2 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ title: "Release Notes"
### 🐛 Bug Fixes

- **input:** fixed textarea border ([588b8dd](https://github.com/devlive-community/shadcn-ui-vue-admin/commit/588b8dd889d8846068c262c984c1e8dc5608043c))
- **tree:** fix the abnormal hover and selected styles in lazy
loading ([b6610f1](https://github.com/devlive-community/shadcn-ui-vue-admin/commit/b6610f18ecbcc4b9f91581d04fc45064bfeac334))
- **tree:** fix the abnormal hover and selected styles in lazy loading ([b6610f1](https://github.com/devlive-community/shadcn-ui-vue-admin/commit/b6610f18ecbcc4b9f91581d04fc45064bfeac334))

### ✨ Features

Expand All @@ -33,6 +32,7 @@ title: "Release Notes"
- **toggle:** support group multiple mode ([ae09b8c](https://github.com/devlive-community/shadcn-ui-vue-admin/commit/ae09b8c560d474e7cd2b06de965a91b8f8e80750))
- **toggle:** support size ([0efec03](https://github.com/devlive-community/shadcn-ui-vue-admin/commit/0efec03439273445b928c22a3efdcf6e66890cc9))
- **toggle:** support toggle ([f732b08](https://github.com/devlive-community/shadcn-ui-vue-admin/commit/f732b08f27a183ff843f076988d5b2dac6bb0f65))
- **switch**: support true-value and false-value([036b7b3](https://github.com/devlive-community/view-shadcn-ui/commit/036b7b32a2186b87d5c53b9d458c86792a28109c))

## 2024.3.0 (2024-11-10)

Expand Down
32 changes: 31 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"author": "devlive-community",
"homepage": "https://view-shadcn-ui.devlive.org",
"private": false,
"version": "2024.4.0",
"version": "2024.5.0",
"license": "MIT",
"main": "./dist/view-shadcn.umd.ts",
"module": "./dist/view-shadcn.es.ts",
Expand Down Expand Up @@ -51,6 +51,36 @@
"type": "docs",
"section": "📚 Documentation",
"hidden": false
},
{
"type": "style",
"section": "🎨 Style",
"hidden": false
},
{
"type": "refactor",
"section": "⚡️ Refactor",
"hidden": false
},
{
"type": "improvement",
"section": "⚡️ Improvements",
"hidden": false
},
{
"type": "test",
"section": "✅ Tests",
"hidden": false
},
{
"type": "build",
"section": "🚀 Build",
"hidden": false
},
{
"type": "revert",
"section": "⏪ Revert",
"hidden": false
}
]
},
Expand Down
68 changes: 52 additions & 16 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,58 @@
<template>
<div class="p-32 space-y-2">
<div>Default Value: {{ checked }}</div>
<ShadcnSwitch v-model="checked">
<template #open>ON</template>
<template #close>OFF</template>
</ShadcnSwitch>

<div>Null Value: {{ checked2 }}</div>
<ShadcnSwitch v-model="checked2" true-value="ON" false-value="OFF">
<template #open>OFF</template>
<template #close>ON</template>
</ShadcnSwitch>
<div class="flex h-screen bg-gray-100">
<slot name="panel">
<BigScreenPanel :items="panels"/>
</slot>

<!-- 中间编辑区域 -->
<BigScreenEditor ref="editorRef"
:grid-size="20"
:selected-id="selectedId"
@select="handleSelect"
@update:components="handleComponentsUpdate"/>

<!-- 右侧配置面板 -->
<BigScreenConfigure :selected-component="selectedComponent" @update="handleConfigUpdate"/>
</div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
<script setup>
import { computed, ref } from 'vue'
import BigScreenPanel from "@/ui/bigscreen/BigScreenPanel.vue";
import BigScreenEditor from "@/ui/bigscreen/BigScreenEditor.vue";
import BigScreenConfigure from "@/ui/bigscreen/BigScreenConfigure.vue";
const panels = ref([
{
group: 'Basic Components',
children: [
{type: 'text', label: '文本'},
{type: 'image', label: '图片'},
{type: 'chart', label: '图表'},
]
}
])
const editorRef = ref(null)
const components = ref([])
const selectedId = ref(null)
// 计算选中的组件
const selectedComponent = computed(() =>
components.value.find(item => item.id === selectedId.value)
)
// 选择组件
const handleSelect = (component) => {
selectedId.value = component.id
}
// 更新组件列表
const handleComponentsUpdate = (newComponents) => {
components.value = newComponents
}
const checked = ref(false)
const checked2 = ref(null)
// 更新组件配置
const handleConfigUpdate = (updatedComponent) => {
editorRef.value?.updateComponent(updatedComponent)
}
</script>
104 changes: 104 additions & 0 deletions src/ui/bigscreen/BigScreenConfigure.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# BigScreenConfigure.vue
<template>
<div class="w-64 bg-white border-l border-gray-200 p-4">
<div class="text-lg font-medium mb-4">配置面板</div>
<template v-if="selectedComponent">
<div class="space-y-4">
<!-- 位置配置 -->
<div class="space-y-2">
<div class="text-sm font-medium text-gray-600">位置</div>
<div class="grid grid-cols-2 gap-2">
<div>
<div class="text-xs text-gray-500 mb-1">X 坐标</div>
<input
type="number"
v-model="componentConfig.x"
@input="handleUpdate"
class="w-full px-2 py-1 border border-gray-200 rounded text-sm focus:outline-none focus:border-blue-500"
>
</div>
<div>
<div class="text-xs text-gray-500 mb-1">Y 坐标</div>
<input
type="number"
v-model="componentConfig.y"
@input="handleUpdate"
class="w-full px-2 py-1 border border-gray-200 rounded text-sm focus:outline-none focus:border-blue-500"
>
</div>
</div>
</div>

<!-- 大小配置 -->
<div class="space-y-2">
<div class="text-sm font-medium text-gray-600">大小</div>
<div class="grid grid-cols-2 gap-2">
<div>
<div class="text-xs text-gray-500 mb-1">宽度</div>
<input
type="number"
v-model="componentConfig.width"
@input="handleUpdate"
class="w-full px-2 py-1 border border-gray-200 rounded text-sm focus:outline-none focus:border-blue-500"
>
</div>
<div>
<div class="text-xs text-gray-500 mb-1">高度</div>
<input
type="number"
v-model="componentConfig.height"
@input="handleUpdate"
class="w-full px-2 py-1 border border-gray-200 rounded text-sm focus:outline-none focus:border-blue-500"
>
</div>
</div>
</div>
</div>
</template>
<div v-else class="text-gray-400 text-center py-4">
请选择组件进行配置
</div>
</div>
</template>

<script setup>
import { ref, watch } from 'vue'
const props = defineProps({
selectedComponent: {
type: Object,
default: null
}
})
const emit = defineEmits(['update'])
// 组件配置
const componentConfig = ref({
x: 0,
y: 0,
width: 0,
height: 0
})
// 监听选中组件变化
watch(() => props.selectedComponent, (newVal) => {
if (newVal) {
componentConfig.value = {
x: newVal.x,
y: newVal.y,
width: newVal.width,
height: newVal.height
}
}
}, { deep: true })
// 更新组件
const handleUpdate = () => {
if (!props.selectedComponent) return
emit('update', {
...props.selectedComponent,
...componentConfig.value
})
}
</script>
104 changes: 104 additions & 0 deletions src/ui/bigscreen/BigScreenEditor.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<template>
<div class="flex-1 relative overflow-auto"
@dragover.prevent
@drop="handleDrop"
:style="gridStyle">
<!-- 已添加的组件 -->
<div v-for="item in components"
:key="item.id"
class="absolute bg-white border-2 flex items-center justify-center cursor-move transition-all"
:class="[
selectedId === item.id
? 'border-blue-500 shadow-lg'
: 'border-gray-200 hover:border-gray-300'
]"
:style="getPosition(item)"
@click.stop="handleSelect(item)"
>
{{ item.label }}
</div>
</div>
</template>

<script setup>
import { defineEmits, ref } from 'vue'
const props = defineProps({
gridSize: {
type: Number,
default: 20
},
selectedId: {
type: [Number, null],
default: null
}
})
const emit = defineEmits(['update:components', 'select'])
// 编辑区网格配置
const gridStyle = {
backgroundSize: `${props.gridSize}px ${props.gridSize}px`,
backgroundImage: 'linear-gradient(#f0f0f0 1px, transparent 1px), linear-gradient(90deg, #f0f0f0 1px, transparent 1px)'
}
// 画布中的组件
const components = ref([])
// 处理放置
const handleDrop = (e) => {
const type = e.dataTransfer.getData('componentType')
const label = e.dataTransfer.getData('componentLabel')
// 获取放置位置
const rect = e.target.getBoundingClientRect()
const x = e.clientX - rect.left
const y = e.clientY - rect.top
// 对齐到网格
const alignedX = Math.round(x / props.gridSize) * props.gridSize
const alignedY = Math.round(y / props.gridSize) * props.gridSize
// 添加新组件
const newComponents = [...components.value, {
id: Date.now(),
type,
label,
x: alignedX,
y: alignedY,
width: props.gridSize * 5,
height: props.gridSize * 3
}]
components.value = newComponents
emit('update:components', newComponents)
}
// 选择组件
const handleSelect = (component) => {
emit('select', component)
}
// 获取组件位置样式
const getPosition = (component) => {
return {
left: component.x + 'px',
top: component.y + 'px',
width: component.width + 'px',
height: component.height + 'px'
}
}
// 暴露方法给父组件
defineExpose({
updateComponent: (updatedComponent) => {
const index = components.value.findIndex(item => item.id === updatedComponent.id)
if (index > -1) {
const newComponents = [...components.value]
newComponents[index] = updatedComponent
components.value = newComponents
emit('update:components', newComponents)
}
}
})
</script>
30 changes: 30 additions & 0 deletions src/ui/bigscreen/BigScreenPanel.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<template>
<div class="w-64 bg-white border-r border-gray-200 p-4">
<div v-for="item in items" class="text-lg font-medium mb-4">
<ShadcnCard :title="item.group">
<div class="space-y-2 p-1">
<div v-for="item in item.children"
draggable="true"
class="p-3 bg-gray-50 border border-gray-200 rounded cursor-move text-center hover:bg-gray-100 transition-colors"
:key="item.type"
@dragstart="onDragStart($event, item)">
{{ item.label }}
</div>
</div>
</ShadcnCard>
</div>
</div>
</template>

<script setup lang="ts">
import { BigScreenPanelItemProps, BigScreenPanelProps } from '@/ui/bigscreen/types.ts'
withDefaults(defineProps<BigScreenPanelProps>(), {
items: () => Array<BigScreenPanelItemProps>
})
const onDragStart = (e, component) => {
e.dataTransfer.setData('componentType', component.type)
e.dataTransfer.setData('componentLabel', component.label)
}
</script>
Loading

0 comments on commit 17acd5f

Please sign in to comment.