Skip to content

Commit 6dabb19

Browse files
committed
refactor(CDropdown): improve syntax
1 parent 52f5fd5 commit 6dabb19

File tree

4 files changed

+88
-80
lines changed

4 files changed

+88
-80
lines changed

packages/coreui-vue/src/components/dropdown/CDropdown.ts

Lines changed: 3 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -2,73 +2,11 @@ import { defineComponent, h, ref, provide, watch, PropType } from 'vue'
22
import type { Placement } from '@popperjs/core'
33

44
import { usePopper } from '../../composables'
5-
import type { Placements, Triggers } from '../../types'
5+
import type { Triggers } from '../../types'
66
import { isRTL } from '../../utils'
77

8-
export type Directions = 'start' | 'end'
9-
10-
export type Breakpoints =
11-
| { xs: Directions }
12-
| { sm: Directions }
13-
| { md: Directions }
14-
| { lg: Directions }
15-
| { xl: Directions }
16-
| { xxl: Directions }
17-
18-
export type Alignments = Directions | Breakpoints
19-
20-
export const getNextActiveElement = (
21-
list: HTMLElement[],
22-
activeElement: HTMLElement,
23-
shouldGetNext: boolean,
24-
isCycleAllowed: boolean,
25-
) => {
26-
const listLength = list.length
27-
let index = list.indexOf(activeElement)
28-
29-
if (index === -1) {
30-
return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0]
31-
}
32-
33-
index += shouldGetNext ? 1 : -1
34-
35-
if (isCycleAllowed) {
36-
index = (index + listLength) % listLength
37-
}
38-
39-
return list[Math.max(0, Math.min(index, listLength - 1))]
40-
}
41-
42-
const getPlacement = (
43-
placement: Placement,
44-
direction: string | undefined,
45-
alignment: Alignments | string | undefined,
46-
isRTL: boolean,
47-
): Placements => {
48-
let _placement = placement
49-
50-
if (direction === 'dropup') {
51-
_placement = isRTL ? 'top-end' : 'top-start'
52-
}
53-
54-
if (direction === 'dropup-center') {
55-
_placement = 'top'
56-
}
57-
58-
if (direction === 'dropend') {
59-
_placement = isRTL ? 'left-start' : 'right-start'
60-
}
61-
62-
if (direction === 'dropstart') {
63-
_placement = isRTL ? 'right-start' : 'left-start'
64-
}
65-
66-
if (alignment === 'end') {
67-
_placement = isRTL ? 'bottom-start' : 'bottom-end'
68-
}
69-
70-
return _placement
71-
}
8+
import type { Alignments } from './types'
9+
import { getNextActiveElement, getPlacement } from './utils'
7210

7311
const CDropdown = defineComponent({
7412
name: 'CDropdown',

packages/coreui-vue/src/components/dropdown/CDropdownMenu.ts

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { defineComponent, h, inject, Ref } from 'vue'
22

3+
import { getAlignmentClassNames } from './utils'
4+
35
const CDropdownMenu = defineComponent({
46
name: 'CDropdownMenu',
57
props: {
@@ -20,28 +22,14 @@ const CDropdownMenu = defineComponent({
2022

2123
const { alignment, dark, popper } = config
2224

23-
// eslint-disable-next-line @typescript-eslint/ban-types, unicorn/consistent-function-scoping
24-
const alignmentClassNames = (alignment: object | string) => {
25-
const classNames: string[] = []
26-
if (typeof alignment === 'object') {
27-
Object.keys(alignment).map((key) => {
28-
classNames.push(`dropdown-menu${key === 'xs' ? '' : `-${key}`}-${alignment[key]}`)
29-
})
30-
}
31-
if (typeof alignment === 'string') {
32-
classNames.push(`dropdown-menu-${alignment}`)
33-
}
34-
return classNames
35-
}
36-
3725
return () =>
3826
h(
3927
props.component,
4028
{
4129
class: [
4230
'dropdown-menu',
4331
{ 'dropdown-menu-dark': dark, show: visible.value },
44-
alignmentClassNames(alignment),
32+
getAlignmentClassNames(alignment),
4533
],
4634
...((typeof alignment === 'object' || !popper) && {
4735
'data-coreui-popper': 'static',
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export type Directions = 'start' | 'end'
2+
3+
export type Breakpoints =
4+
| { xs: Directions }
5+
| { sm: Directions }
6+
| { md: Directions }
7+
| { lg: Directions }
8+
| { xl: Directions }
9+
| { xxl: Directions }
10+
11+
export type Alignments = Directions | Breakpoints
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import type { Placement } from '@popperjs/core'
2+
import type { Placements } from '../../types'
3+
import type { Alignments } from './types'
4+
5+
export const getAlignmentClassNames = (alignment: object | string) => {
6+
const classNames: string[] = []
7+
if (typeof alignment === 'object') {
8+
Object.keys(alignment).map((key) => {
9+
classNames.push(`dropdown-menu${key === 'xs' ? '' : `-${key}`}-${alignment[key]}`)
10+
})
11+
}
12+
13+
if (typeof alignment === 'string') {
14+
classNames.push(`dropdown-menu-${alignment}`)
15+
}
16+
17+
return classNames
18+
}
19+
20+
export const getNextActiveElement = (
21+
list: HTMLElement[],
22+
activeElement: HTMLElement,
23+
shouldGetNext: boolean,
24+
isCycleAllowed: boolean,
25+
) => {
26+
const listLength = list.length
27+
let index = list.indexOf(activeElement)
28+
29+
if (index === -1) {
30+
return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0]
31+
}
32+
33+
index += shouldGetNext ? 1 : -1
34+
35+
if (isCycleAllowed) {
36+
index = (index + listLength) % listLength
37+
}
38+
39+
return list[Math.max(0, Math.min(index, listLength - 1))]
40+
}
41+
42+
export const getPlacement = (
43+
placement: Placement,
44+
direction: string | undefined,
45+
alignment: Alignments | string | undefined,
46+
isRTL: boolean,
47+
): Placements => {
48+
let _placement = placement
49+
50+
if (direction === 'dropup') {
51+
_placement = isRTL ? 'top-end' : 'top-start'
52+
}
53+
54+
if (direction === 'dropup-center') {
55+
_placement = 'top'
56+
}
57+
58+
if (direction === 'dropend') {
59+
_placement = isRTL ? 'left-start' : 'right-start'
60+
}
61+
62+
if (direction === 'dropstart') {
63+
_placement = isRTL ? 'right-start' : 'left-start'
64+
}
65+
66+
if (alignment === 'end') {
67+
_placement = isRTL ? 'bottom-start' : 'bottom-end'
68+
}
69+
70+
return _placement
71+
}

0 commit comments

Comments
 (0)