Skip to content

Commit

Permalink
✨ [collapse] add collapse component
Browse files Browse the repository at this point in the history
  • Loading branch information
higuaifan committed Feb 17, 2025
1 parent a4dd0e7 commit b2941b6
Show file tree
Hide file tree
Showing 26 changed files with 536 additions and 2 deletions.
18 changes: 18 additions & 0 deletions core/components/base/collapse/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* @description collapse api
* @author 阿怪
* @date 2025/02/17 20:52
* @version v1.0.0
*
* 江湖的业务千篇一律,复杂的代码好几百行。
*/

import { MCOPO } from '../../types/props';
import { CollapseProps } from './props';

export const props: MCOPO<CollapseProps> = {
modelValue: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
renderContext: { type: Boolean, default: false },
line: { type: Boolean, default: true }
};
43 changes: 43 additions & 0 deletions core/components/base/collapse/collapse.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
.m-collapse {
display: flex;
flex-direction: column;
width: 100%;
}

.m-collapse-disabled {
cursor: var(--m-cursor-disabled);
--m-cursor-auto: var(--m-cursor-disabled);

.m-collapse-header{
cursor: var(--m-cursor-disabled);
--m-cursor-auto: var(--m-cursor-disabled);
opacity: 0.3;
}

}

.m-collapse-header {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;

cursor: var(--m-cursor-pointer);
--m-cursor-auto: var(--m-cursor-pointer);

.m-divider {
margin-left: 0.5rem;
flex:1;
}

.m-collapse-arrow{
margin:0 0.5rem;
transition: transform 0.3s ease-in-out;
}

}


.m-collapse-content-hidden {
display: none;
}
17 changes: 17 additions & 0 deletions core/components/base/collapse/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* @description collapse index
* @author 阿怪
* @date 2025/02/17 20:52
* @version v1.0.0
*
* 江湖的业务千篇一律,复杂的代码好几百行。
*/

import { props } from './api';
import { useCollapse, collapseOptions } from './useCollapse.tsx';

export const CollapseCore = {
props,
useCollapse,
collapseOptions
};
40 changes: 40 additions & 0 deletions core/components/base/collapse/props.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* @description collapse api type
* @author 阿怪
* @date 2025/02/17 20:52
* @version v1.0.0
*
* @name m-collapse
* @docDescription Collapse component with shuimo-ui style.
* 水墨组件的折叠组件。
* @docUrl https://shuimo.design/collapse
*
* 江湖的业务千篇一律,复杂的代码好几百行。
*/

export declare type CollapseProps = {
/**
* @description collapse modelValue. 折叠展开状态
* @type boolean
* @default false
*/
modelValue?: boolean;
/**
* @description collapse disabled. 是否禁用
* @type boolean
* @default false
*/
disabled?: boolean;
/**
* @description collapse renderContext. 是否渲染上下文
* @type boolean
* @default false
*/
renderContext?: boolean;
/**
* @description collapse line. 是否显示分割线
* @type boolean
* @default true
*/
line?: boolean;
};
65 changes: 65 additions & 0 deletions core/components/base/collapse/useCollapse.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* @description collapse hook
* @author 阿怪
* @date 2025/02/17 20:52
* @version v1.0.0
*
* 江湖的业务千篇一律,复杂的代码好几百行。
*/

import { defineHook } from '../../../runtime/defineHook';
import { props } from './api';
import { CollapseProps } from './props';
import { ref, watch } from 'vue';

export const collapseOptions = {
name: 'MCollapse',
props,
emits: ['update:modelValue', 'change']
};

export const useCollapse = defineHook((props: Required<CollapseProps>, ctx) => {
const innerValue = ref(props.modelValue);

watch(() => props.modelValue, (val) => {
innerValue.value = val;
});

const toggle = () => {
if (props.disabled) return;
const newValue = !innerValue.value;
innerValue.value = newValue;
ctx.emit('update:modelValue', newValue);
ctx.emit('change', newValue);
};

const renderInit = () => {
const collapseClass = [
'm-collapse',
{
'm-collapse-disabled': props.disabled,
'm-collapse-arrow-expanded': innerValue.value
}
]

const context = props.renderContext ? (
<div class={['m-collapse-content', { 'm-collapse-content-hidden': !innerValue.value }]}>
{ctx.slots.content?.()}
</div>
) : innerValue.value ? (
<div class="m-collapse-content">
{ctx.slots.content?.()}
</div>
) : null;

return {
collapseClass,
context,
}
}

return {
toggle,
renderInit
};
}, collapseOptions);
1 change: 1 addition & 0 deletions core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export * from './components/base/button';
export * from './components/base/checkbox';
export * from './components/base/switch';
export * from './components/base/li';
export * from './components/base/collapse';

export * from './components/other/loading';
export * from './components/other/divider';
Expand Down
1 change: 1 addition & 0 deletions doc/config/menu.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const menu: MenuTypeArr = [
{ label: '标签', route: 'tag', isActive: false },
{ label: '滑动条', route: 'slider', isActive: false },
{ label: '进度条', route: 'progress', isActive: false },
{ label: '折叠', route: 'collapse', isActive: false },
],
},
{
Expand Down
8 changes: 8 additions & 0 deletions doc/demos/base/collapse/default.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<template>
<m-collapse>
欲卷珠帘春恨长
<template #content>
却下水晶帘,玲珑望秋月
</template>
</m-collapse>
</template>
8 changes: 8 additions & 0 deletions doc/demos/base/collapse/disabled.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<template>
<m-collapse disabled>
众里寻他千百度
<template #content>
蓦然回首,那人却在灯火阑珊处
</template>
</m-collapse>
</template>
18 changes: 18 additions & 0 deletions doc/demos/base/collapse/event.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<template>
<m-collapse v-model="isOpen" @change="handleChange">
庭院深深深几许
<template #content>
乱红飞过秋千去
</template>
</m-collapse>
</template>

<script setup lang="ts">
import { ref } from 'vue';
const isOpen = ref(false);
const handleChange = (value: boolean) => {
console.log('折叠面板状态改变:', value);
};
</script>
8 changes: 8 additions & 0 deletions doc/demos/base/collapse/line.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<template>
<m-collapse :line="false">
初极狭,才通人
<template #content>
复行数十步,豁然开朗
</template>
</m-collapse>
</template>
10 changes: 10 additions & 0 deletions doc/demos/base/collapse/render.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<template>
<m-collapse render-context>
山重水复疑无路
<template #content>
<div class="content-box">
柳暗花明又一村
</div>
</template>
</m-collapse>
</template>
10 changes: 10 additions & 0 deletions doc/i18n/components/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ export const base = {
'滚动效果': 'Scroll effect',
'修改尺寸': 'Change Size',
'隐藏叶子': 'Hide Leaf',
'折叠': 'Collapse',
'基础用法': 'Basic Usage',
'禁用状态': 'Disabled State',
'隐藏分割线': 'Hide Line',
'是否渲染': 'Render Slot',
},
zh: {
'普通按钮': '普通按钮',
Expand Down Expand Up @@ -79,5 +84,10 @@ export const base = {
'滚动效果': '滚动效果',
'修改尺寸': '修改尺寸',
'隐藏叶子': '隐藏叶子',
'折叠': '折叠',
'基础用法': '基础用法',
'禁用状态': '禁用状态',
'隐藏分割线': '隐藏分割线',
'是否渲染': '是否渲染',
},
};
25 changes: 25 additions & 0 deletions doc/pages/docs/components/base/collapse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# {{$t(\'折叠\')}}

### {{$t(\'基础用法\')}}

::: demo base/collapse/default

### {{$t(\'禁用状态\')}}

::: demo base/collapse/disabled

### {{$t(\'隐藏分割线\')}}

::: demo base/collapse/line

### {{$t(\'事件\')}}

::: demo base/collapse/event

### {{$t(\'是否渲染\')}}

::: demo base/collapse/render

## API

::: api base/collapse
37 changes: 37 additions & 0 deletions headless/components/base/collapse/MCollapse.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* @description collapse component
* @author 阿怪
* @date 2025/02/17 20:52
* @version v1.0.0
*
* 江湖的业务千篇一律,复杂的代码好几百行。
*/

import { defineComponent } from 'vue';
import { CollapseCore } from '@shuimo-design/ui-core';
import { CollapseProps } from '@shuimo-design/ui-core/components/base/collapse/props';
import './collapse.css';
import MDivider from '../../other/divider/MDivider';

const { useCollapse, collapseOptions } = CollapseCore;

export default defineComponent((_props: CollapseProps, ctx) => {
const props = _props as Required<CollapseProps>;
const { toggle, renderInit } = useCollapse(props, ctx);

return () => {
const { collapseClass, context } = renderInit();
const line = props.line ? (<MDivider />) : null;

return (
<div class={collapseClass}>
<div class="m-collapse-header" onClick={toggle}>
{ctx.slots.default?.() }
{line}
<div class="m-collapse-arrow">&lt;</div>
</div>
{context}
</div>
);
};
}, collapseOptions);
7 changes: 7 additions & 0 deletions headless/components/base/collapse/collapse.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@import '@shuimo-design/ui-core/components/base/collapse/collapse.css';

.m-collapse-arrow-expanded {
.m-collapse-arrow{
transform: rotate(-90deg);
}
}
3 changes: 3 additions & 0 deletions headless/utils/install/importComponents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import MLi from '../../components/base/li/MLi.tsx';
// import MSelect from '../../components/base/select/MSelect.tsx';
import MCheckbox from '../../components/base/checkbox/MCheckbox.tsx';
import MSwitch from '../../components/base/switch/MSwitch.tsx';
import MCollapse from '../../components/base/collapse/MCollapse.tsx';
// [other]
import MDivider from '../../components/other/divider/MDivider.tsx';
import MLoading from '../../components/other/loading/MLoading.tsx';
Expand All @@ -33,6 +34,7 @@ export const components: Record<string, Component> = {
MCheckbox,
MSwitch,
MLi,
MCollapse,

MLoading,
MDivider,
Expand All @@ -48,6 +50,7 @@ export {
MCheckbox,
MSwitch,
MLi,
MCollapse,

MLoading,
MDivider,
Expand Down
Loading

0 comments on commit b2941b6

Please sign in to comment.