-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathelement.ts
148 lines (124 loc) · 3.77 KB
/
element.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import { theme, hideScrollbar } from './style'
import { directions, Instance, Options, Direction, Inline } from './types'
import { registerClickListener } from './feature/click'
import { wrapTable } from './feature/table'
import { move } from './feature/move-styles'
import {
isTable,
isInline,
hideScrollbarWithWebkitPseudoClass,
wrapElementIn,
arrowIcon,
} from './helper'
// <element>{contents}</element> => <element><wrapper>{contents}<wrapper/></element>
const wrapContentsWith = (element: HTMLElement, wrapper: HTMLElement) => {
wrapper.innerHTML = element.innerHTML
element.innerHTML = ''
element.appendChild(wrapper)
}
const wrap = ({
element,
options,
table,
inline,
}: {
element: HTMLElement
options: Options
table: boolean
inline: Inline
}) => {
if (table) {
return wrapTable({ element, options })
}
// Wrapper arount the element to position the indicators.
const outerWrapper = options.outerWrapper ?? document.createElement('div')
theme(outerWrapper, 'outerWrapper', options, table, inline)
if (!options.outerWrapper) {
wrapElementIn(element, outerWrapper)
}
// Wrapper around the content of the element.
// Allows to position observers absolutely inside (due to inline-block).
const innerWrapper = options.innerWrapper ?? document.createElement('div')
theme(innerWrapper, 'innerWrapper', options, table, inline)
if (!options.innerWrapper) {
wrapContentsWith(element, innerWrapper)
}
return { outerWrapper, innerWrapper }
}
export const createInstance = (element: HTMLElement, options: Options): Instance => {
const table = isTable(element)
const inline = isInline(element)
const getSpansByDirection = () => {
const result = {}
directions.forEach((direction) => {
result[direction] = document.createElement('span')
})
return result
}
const { outerWrapper, innerWrapper } = wrap({
element,
options,
table,
inline,
})
move(element, outerWrapper, options)
theme(element, 'element', options, table, inline)
if (options.hideScrollbar) {
const scrollableElement = table ? innerWrapper : element
hideScrollbar(scrollableElement)
hideScrollbarWithWebkitPseudoClass(scrollableElement)
}
return {
outerWrapper,
innerWrapper,
element,
indicator: getSpansByDirection(),
observer: getSpansByDirection(),
options,
table,
inline,
} as Instance
}
const addArrow = (instance: Instance, indicator: HTMLSpanElement, direction: Direction) => {
const options = instance.options.arrow
if (!options) {
return
}
let arrow = null
if (options.image) {
arrow = document.createElement('img')
arrow.src = options.image
arrow.alt = `indicate arrow ${direction}`
} else if (options.markup && options.markup !== '') {
if (typeof options.markup === 'string') {
arrow = document.createElement('span')
arrow.innerHTML = options.markup
} else {
arrow = options.markup
}
} else {
arrow = arrowIcon(options.icon, options.color)
}
theme(arrow, 'arrow', instance.options, direction)
indicator.append(arrow)
}
export const addIndicators = (instance: Instance) => {
directions.forEach((direction) => {
const indicator = instance.indicator[direction]
theme(indicator, 'indicator', instance.options, direction)
instance.outerWrapper.append(indicator)
registerClickListener(direction, indicator, instance)
addArrow(instance, indicator, direction)
})
}
export const addObservers = (instance: Instance) => {
directions.forEach((direction) => {
const observer = instance.observer[direction]
theme(observer, 'observer', instance.options, direction)
if (instance.table) {
instance.element.append(observer)
} else {
instance.innerWrapper.append(observer)
}
})
}