Skip to content

Commit bb96da8

Browse files
committed
feat: basic accordion
1 parent 0f2e5aa commit bb96da8

File tree

7 files changed

+318
-21
lines changed

7 files changed

+318
-21
lines changed

devui/accordion/accordion.vue

Lines changed: 286 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,32 @@
11
<template>
2-
<div>accordion</div>
2+
<ul class="devui-accordion-list" v-if="!innerListTemplate || deepth === 0">
3+
<li class="devui-accordion-item" v-for="category in data" :key="category.title">
4+
<div
5+
class="devui-accordion-item-title devui-over-flow-ellipsis"
6+
:class="{
7+
open: open,
8+
active: childActived,
9+
disabled: disabled
10+
}"
11+
:title="category.title"
12+
@click="!disabled && toggle($event)"
13+
>
14+
<div
15+
class="devui-accordion-splitter"
16+
:class="{
17+
'devui-parent-list': deepth === 0
18+
}"
19+
:style="{ left: deepth * 20 + 10 + 'px' }"
20+
></div>
21+
{{ category.title }}
22+
</div>
23+
<ul class="devui-accordion-submenu">
24+
<li class="devui-accordion-item" v-for="component in category.children" :key="component.title">
25+
<router-link :to="component.link">{{ component.title }}</router-link>
26+
</li>
27+
</ul>
28+
</li>
29+
</ul>
330
</template>
431

532
<script lang="ts">
@@ -18,4 +45,261 @@ export default defineComponent({
1845
console.log('linkType:', linkType);
1946
}
2047
})
21-
</script>
48+
</script>
49+
50+
<style lang="scss">
51+
@import '../style/mixins/index';
52+
@import '../style/theme/color';
53+
@import '../style/theme/shadow';
54+
@import '../style/theme/corner';
55+
56+
:host {
57+
display: block;
58+
}
59+
60+
d-accordion-menu,
61+
d-accordion-item,
62+
d-accordion-item-hreflink,
63+
d-accordion-item-routerlink,
64+
d-accordion-list {
65+
display: block;
66+
}
67+
68+
/* 菜单底色 */
69+
.devui-accordion-menu {
70+
display: block;
71+
background: $devui-base-bg;
72+
width: 100%;
73+
overflow-y: auto;
74+
border-radius: $devui-border-radius;
75+
height: 100%;
76+
77+
&.devui-accordion-menu-normal {
78+
box-shadow: $devui-shadow-length-base $devui-shadow;
79+
}
80+
81+
& > .devui-accordion-list {
82+
padding: 10px 0;
83+
}
84+
85+
.devui-over-flow-ellipsis {
86+
overflow: hidden;
87+
white-space: nowrap;
88+
text-overflow: ellipsis;
89+
}
90+
}
91+
92+
.devui-accordion-submenu {
93+
background: $devui-base-bg;
94+
width: 100%;
95+
}
96+
97+
/* 单行菜单 */
98+
.devui-accordion-item-title {
99+
display: block;
100+
height: 40px;
101+
width: 100%;
102+
padding: 0 10px 0 20px;
103+
font-weight: 400;
104+
line-height: 40px;
105+
color: $devui-text-weak;
106+
background: transparent;
107+
cursor: pointer;
108+
109+
&.disabled {
110+
color: $devui-disabled-text;
111+
cursor: not-allowed;
112+
113+
& > a {
114+
color: $devui-disabled-text;
115+
}
116+
}
117+
118+
&:not(.disabled) {
119+
&:hover {
120+
background: $devui-list-item-hover-bg;
121+
color: $devui-list-item-hover-text;
122+
}
123+
124+
&.devui-router-active,
125+
&.active:not(.open) {
126+
color: $devui-brand-active;
127+
font-weight: bold;
128+
129+
& > a {
130+
color: $devui-brand-active;
131+
}
132+
}
133+
}
134+
135+
& > a {
136+
text-decoration: none;
137+
display: block;
138+
width: 100%;
139+
color: $devui-text-weak;
140+
141+
&:hover {
142+
color: inherit;
143+
text-decoration: none;
144+
}
145+
}
146+
}
147+
148+
/* 解决链接可点击区域大小不是100%宽度问题 */
149+
d-accordion-item-hreflink,
150+
d-accordion-item-routerlink {
151+
&.devui-accordion-item-title {
152+
padding: 0;
153+
154+
& > a {
155+
padding: 0 10px 0 20px;
156+
}
157+
}
158+
}
159+
160+
/* 展开图标相关 */
161+
.devui-accordion-menu-item > .devui-accordion-item-title {
162+
position: relative;
163+
164+
& > .devui-accordion-open-icon {
165+
display: inline-block;
166+
text-indent: 0;
167+
pointer-events: none; /* 让鼠标穿透 */
168+
position: absolute;
169+
right: 10px;
170+
top: 12px;
171+
width: 16px;
172+
height: 16px;
173+
line-height: 16px;
174+
transition: transform ease-out 0.3s;
175+
176+
& > svg {
177+
width: 16px;
178+
height: 16px;
179+
180+
polygon {
181+
fill: $devui-text-weak;
182+
}
183+
}
184+
}
185+
186+
&:not(.open) {
187+
&.active {
188+
svg polygon {
189+
fill: $devui-icon-fill-active;
190+
}
191+
}
192+
193+
& > .devui-accordion-open-icon {
194+
transform: rotate(-180deg);
195+
transform-origin: center;
196+
}
197+
}
198+
199+
&.disabled > .devui-accordion-open-icon {
200+
color: $devui-disabled-text;
201+
202+
svg polygon {
203+
fill: $devui-disabled-text;
204+
}
205+
}
206+
}
207+
208+
/* 可展开的菜单 */
209+
.devui-accordion-menu-item > .devui-accordion-item-title {
210+
padding-right: 30px;
211+
212+
&.active:not(.open) {
213+
color: $devui-brand-active;
214+
background: transparent;
215+
}
216+
}
217+
218+
d-accordion-list.devui-accordion-menu-hidden {
219+
display: none;
220+
}
221+
222+
/* 视觉融合灰线 */
223+
.devui-accordion-item-title {
224+
position: relative;
225+
226+
.devui-accordion-splitter {
227+
position: absolute;
228+
display: inline-block;
229+
left: 10px;
230+
width: 2px;
231+
height: 40px;
232+
background: $devui-dividing-line;
233+
vertical-align: middle;
234+
235+
&.devui-parent-list {
236+
background-color: transparent;
237+
}
238+
}
239+
240+
&.devui-router-active,
241+
&.active {
242+
&:not(.open) .devui-accordion-splitter::before {
243+
content: '';
244+
display: block;
245+
width: 2px;
246+
height: 18px;
247+
background: $devui-form-control-line-active;
248+
position: absolute;
249+
top: 11px;
250+
left: 0;
251+
}
252+
}
253+
}
254+
255+
.devui-accordion-list > .devui-accordion-item:first-child {
256+
& > .devui-accordion-item-title,
257+
& > .devui-accordion-menu-item > .devui-accordion-item-title {
258+
& > a > .devui-accordion-splitter,
259+
& > .devui-accordion-splitter {
260+
height: 28px;
261+
top: 12px;
262+
263+
&::before {
264+
top: 0;
265+
}
266+
}
267+
}
268+
}
269+
270+
.devui-accordion-list > .devui-accordion-item:last-child {
271+
& > .devui-accordion-item-title,
272+
& > .devui-accordion-menu-item > .devui-accordion-item-title {
273+
& > a > .devui-accordion-splitter,
274+
& > .devui-accordion-splitter {
275+
height: 28px;
276+
top: 0;
277+
278+
&::before {
279+
top: initial;
280+
bottom: 0;
281+
}
282+
}
283+
}
284+
}
285+
286+
.devui-accordion-list > .devui-accordion-item:last-child:first-child {
287+
& > .devui-accordion-item-title,
288+
& > .devui-accordion-menu-item > .devui-accordion-item-title {
289+
& > a > .devui-accordion-splitter,
290+
& > .devui-accordion-splitter {
291+
height: 18px;
292+
top: 11px;
293+
}
294+
}
295+
}
296+
297+
.devui-accordion-item > a {
298+
padding: 0 10px 0 20px;
299+
color: var(--devui-text-weak,#575d6c);
300+
display: block;
301+
text-decoration: none;
302+
width: 100%;
303+
}
304+
305+
</style>

devui/style/theme/_color.scss

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ $devui-list-item-strip-bg: var(--devui-list-item-strip-bg, #f2f5fc);
5858
$devui-disabled-bg: var(--devui-disabled-bg, #f5f5f6); // disabled背景颜色
5959
$devui-disabled-line: var(--devui-disabled-line, #dfe1e6); // disabled边框颜色
6060
$devui-disabled-text: var(--devui-disabled-text, #adb0b8); // disabled文字颜色
61-
61+
$devui-primary-disabled: var(--devui-primary-disabled, #beccfa); //主要按钮disabled状态文字颜色
62+
$devui-icon-fill-active-disabled: var(--devui-icon-fill-active-disabled, #beccfa); // svg图标激活状态禁用色
63+
$devui-icon-fill-active-disabled: var(--devui-icon-fill-active-disabled, #beccfa); // svg图标激活状态禁用色
6264
// 特殊背景色
6365
$devui-label-bg: var(--devui-label-bg, #eef0f5); // 默认标签化选项背景色
6466
$devui-connected-overlay-bg: var(--devui-connected-overlay-bg, #ffffff); // 有连接点的弹出菜单层背景色

devui/style/theme/_corner.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
//圆角变量
2+
3+
$devui-border-radius: var(--devui-border-radius, 2px); //一般圆角
4+
$devui-border-radius-feedback: var(--devui-border-radius-feedback, 4px); //反馈类圆角
5+
$devui-border-radius-card: var(--devui-border-radius-card, 6px); //卡片圆角

devui/style/theme/_font.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,11 @@ $devui-font-size-icon: var(--devui-font-size-icon, 16px); //图标大小
1111
$devui-font-size-sm: var(--devui-font-size-sm, 12px); //当组件size为'sm'时使用此字号大小
1212
$devui-font-size-md: var(--devui-font-size-md, 12px); //当组件size为''时使用此字号大小
1313
$devui-font-size-lg: var(--devui-font-size-lg, 14px); //当组件size为'lg'时使用此字号大小
14+
15+
$devui-font-title-weight: bold; //标题文字粗细
16+
$devui-font-content-weight: normal; //内容文字粗细
17+
$devui-line-height-base: 1.5; //规范行高
18+
19+
$font-title-weight: bold;
20+
$font-content-weight: normal;
21+
$line-height-base: 1.5;

devui/style/theme/_shadow.scss

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
// 用于阴影
2-
$hwc-shadow-1: var(--hwc-shadow-1, 0 1px 3px 0 rbga(0, 0, 0, 0.1));
3-
$hwc-shadow-2: var(--hwc-shadow-2, 0 2px 5px 0 rgba(0, 0, 0, 0.2));
4-
$hwc-shadow-3: var(--hwc-shadow-3, 0 4px 8px 0 rgba(0, 0, 0, 0.2));
5-
$hwc-shadow-4: var(--hwc-shadow-4, 0 2px 8px 0 rgba(94, 124, 224, 0.3));
6-
$hwc-shadow-5: var(--hwc-shadow-5, 0 0 6px 0 rgba(0, 0, 0, 0.1));
7-
$hwc-shadow-6: var(--hwc-shadow-6, 0 8px 6px -4px rgba(199, 54, 54, 0.4));
8-
$hwc-shadow-7: var(--hwc-shadow-7, 0 10px 40px 0 rgba(0, 0, 0, 0.1));
9-
$hwc-shadow-8: var(--hwc-shadow-8, 0 1px 2px 0 rgba(57, 71, 166, 0.5));
10-
$hwc-shadow-error: var(--hwc-shadow-error, 0 1px 3px 0 rgba(199, 54, 54, 0.25));
11-
$hwc-shadow-warn: var(--hwc-shadow-warn, 0 1px 3px 0 rgba(204, 100, 20, 0.25));
12-
$hwc-shadow-prompt: var(--hwc-shadow-prompt, 0 1px 3px 0 rgba(70, 94, 184, 0.25));
13-
$hwc-shadow-success: var(--hwc-shadow-success, 0 1px 3px 0 rgba(39, 176, 128, 0.25));
14-
$hwc-shadow-dark: var(--hwc-shadow-dark, 0 5px 8px 0 rgba(70, 77, 110, 0.25));
1+
//阴影变量
2+
3+
$devui-shadow-length-base: var(--devui-shadow-length-base, 0 1px 4px 0); //直接铺陈在页面上方的元素 (card等)
4+
5+
$devui-shadow-length-slide-left: var(--devui-shadow-length-slide-left, -2px 0 8px 0); //向左滑动时出现在右侧边缘的阴影 (dataTable固定右侧列向左滑动)
6+
$devui-shadow-length-slide-right: var(--devui-shadow-length-slide-right, 2px 0 8px 0); //向右滑动时出现在左侧边缘的阴影 (dataTable固定左侧列向右滑动)
7+
$devui-shadow-length-connected-overlay : var(--devui-shadow-connected-overlay, 0 2px 8px 0); //有连接点的弹出(覆盖)层 (DatePicker Cascader Select TagsInput Pagination的下拉菜单等)
8+
9+
$devui-shadow-length-hover : var(--devui-shadow-length-hover, 0 4px 16px 0); //涉及到hover的地方
10+
$devui-shadow-length-feedback-overlay : var(--devui-shadow-length-feedback-overlay, 0 4px 16px 0); //信息提示反馈类 (PopOver Tooltip Toast StepsGuide等)
11+
12+
$devui-shadow-length-fullscreen-overlay: var(--devui-shadow-fullscreen-overlay, 0 8px 40px 0); //无连接点的弹出(覆盖)层 (Drawer Modal ImagePreview等)

devui/style/theme/_variables.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
@import './color';
22
@import '../core/font';
3+
@import '../theme/font';
34

45
$text-color: $devui-text;
5-
$font-family: 'Helvetica Neue', helvetica, arial, 'PingFang SC', 'Hiragino Sans GB', 'Heiti SC', 'Microsoft YaHei', 'WenQuanYi Micro Hei',
6-
sans-serif;
6+
$font-family: 'HuaweiFont', helvetica, arial, 'PingFang', 'Microsoft YaHei', 'Hiragino Sans GB', 'Microsoft JhengHei', sans-serif;
77
$font-variant-base: tabular-nums;
88
$body-background: $devui-base-bg;
99
$devui-font-size: $devui-font-size; // 12px

src/components/app-content.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@
2323
</ul>
2424
<nav class="side-nav">
2525
<!-- TODO: 左侧组件导航 d-accordion -->
26-
<div v-for="category in componentsData" v-bind:key="category">
26+
<!-- <div v-for="category in componentsData" v-bind:key="category">
2727
{{ category.title }}
2828
<div v-for="component in category.children" v-bind:key="component">
2929
<router-link :to="component.link">{{ component.title }}</router-link>
3030
</div>
31-
</div>
31+
</div> -->
3232
<d-accordion :data="componentsData" :linkType="'routerLink'"></d-accordion>
3333
</nav>
3434
</div>

0 commit comments

Comments
 (0)