center-center 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.mjs +46 -58
- package/package.json +9 -3
- package/test/index.spec.mjs +316 -0
package/index.mjs
CHANGED
|
@@ -16,76 +16,48 @@ export function getScrollingElement (document) {
|
|
|
16
16
|
|
|
17
17
|
export function getViewportRect () {
|
|
18
18
|
const {
|
|
19
|
-
innerWidth:
|
|
20
|
-
innerHeight:
|
|
19
|
+
innerWidth: width,
|
|
20
|
+
innerHeight: height
|
|
21
21
|
} = window
|
|
22
22
|
|
|
23
23
|
const {
|
|
24
|
-
scrollLeft:
|
|
25
|
-
scrollTop:
|
|
24
|
+
scrollLeft: left,
|
|
25
|
+
scrollTop: top
|
|
26
26
|
} = getScrollingElement(document)
|
|
27
27
|
|
|
28
|
-
const viewportR = (viewportL + viewportW)
|
|
29
|
-
const viewportB = (viewportT + viewportH)
|
|
30
|
-
|
|
31
|
-
return {
|
|
32
|
-
top: viewportT,
|
|
33
|
-
right: viewportR,
|
|
34
|
-
bottom: viewportB,
|
|
35
|
-
left: viewportL,
|
|
36
|
-
width: viewportW,
|
|
37
|
-
height: viewportH
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function getContainerRect (container) {
|
|
42
|
-
const {
|
|
43
|
-
offsetLeft: containerL,
|
|
44
|
-
offsetTop: containerT
|
|
45
|
-
} = container
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* x/top is relative to the viewport
|
|
49
|
-
*/
|
|
50
|
-
const {
|
|
51
|
-
x: containerX,
|
|
52
|
-
y: containerY,
|
|
53
|
-
width: containerW,
|
|
54
|
-
height: containerH
|
|
55
|
-
} = container.getBoundingClientRect()
|
|
56
|
-
|
|
57
|
-
const containerR = (containerL + containerW)
|
|
58
|
-
const containerB = (containerT + containerH)
|
|
59
|
-
|
|
60
28
|
return {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
width: containerW,
|
|
68
|
-
height: containerH
|
|
29
|
+
width,
|
|
30
|
+
height,
|
|
31
|
+
left,
|
|
32
|
+
top,
|
|
33
|
+
right: (left + width),
|
|
34
|
+
bottom: (top + height)
|
|
69
35
|
}
|
|
70
36
|
}
|
|
71
37
|
|
|
72
|
-
export function
|
|
38
|
+
export function getElementRect (element) {
|
|
73
39
|
const {
|
|
74
|
-
offsetWidth:
|
|
75
|
-
offsetHeight:
|
|
76
|
-
|
|
40
|
+
offsetWidth: width,
|
|
41
|
+
offsetHeight: height,
|
|
42
|
+
offsetLeft: left,
|
|
43
|
+
offsetTop: top
|
|
44
|
+
} = element
|
|
77
45
|
|
|
78
46
|
return {
|
|
79
|
-
width
|
|
80
|
-
height
|
|
47
|
+
width,
|
|
48
|
+
height,
|
|
49
|
+
left,
|
|
50
|
+
top,
|
|
51
|
+
right: (left + width),
|
|
52
|
+
bottom: (top + height)
|
|
81
53
|
}
|
|
82
54
|
}
|
|
83
55
|
|
|
84
56
|
export function getRects (container, target) {
|
|
85
57
|
return {
|
|
86
58
|
viewport: getViewportRect(),
|
|
87
|
-
container:
|
|
88
|
-
target:
|
|
59
|
+
container: getElementRect(container),
|
|
60
|
+
target: getElementRect(target)
|
|
89
61
|
}
|
|
90
62
|
}
|
|
91
63
|
|
|
@@ -162,11 +134,19 @@ export function calculateLeft ({
|
|
|
162
134
|
}
|
|
163
135
|
|
|
164
136
|
if (viewportR > containerL) {
|
|
165
|
-
|
|
137
|
+
if (viewportR > containerR) {
|
|
138
|
+
log('calculate containerL to containerR')
|
|
166
139
|
|
|
167
|
-
|
|
140
|
+
const availableW = Math.max(targetW, (containerR - containerL))
|
|
168
141
|
|
|
169
|
-
|
|
142
|
+
return ((availableW / 2) - (targetW / 2))
|
|
143
|
+
} else {
|
|
144
|
+
log('calculate containerL to viewportR')
|
|
145
|
+
|
|
146
|
+
const availableW = Math.max(targetW, (viewportR - containerL))
|
|
147
|
+
|
|
148
|
+
return ((availableW / 2) - (targetW / 2))
|
|
149
|
+
}
|
|
170
150
|
}
|
|
171
151
|
}
|
|
172
152
|
}
|
|
@@ -244,11 +224,19 @@ export function calculateTop ({
|
|
|
244
224
|
}
|
|
245
225
|
|
|
246
226
|
if (viewportB > containerT) {
|
|
247
|
-
|
|
227
|
+
if (viewportB > containerB) {
|
|
228
|
+
log('calculate containerT to containerB')
|
|
248
229
|
|
|
249
|
-
|
|
230
|
+
const availableH = Math.max(targetH, (containerB - containerT))
|
|
250
231
|
|
|
251
|
-
|
|
232
|
+
return ((availableH / 2) - (targetH / 2))
|
|
233
|
+
} else {
|
|
234
|
+
log('calculate containerT to viewportB')
|
|
235
|
+
|
|
236
|
+
const availableH = Math.max(targetH, (viewportB - containerT))
|
|
237
|
+
|
|
238
|
+
return ((availableH / 2) - (targetH / 2))
|
|
239
|
+
}
|
|
252
240
|
}
|
|
253
241
|
}
|
|
254
242
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "center-center",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Position an element at the center center of a container",
|
|
5
5
|
"main": "./index.mjs",
|
|
6
6
|
"type": "module",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
13
|
"lint": "cross-env NODE_ENV=production eslint . --ext .mjs,.cjs",
|
|
14
|
-
"lint:fix": "npm run lint -- --fix"
|
|
14
|
+
"lint:fix": "npm run lint -- --fix",
|
|
15
|
+
"test": "cross-env NODE_ENV=test mocha test --recursive"
|
|
15
16
|
},
|
|
16
17
|
"dependencies": {
|
|
17
18
|
"debug": "^4.3.4"
|
|
@@ -21,9 +22,14 @@
|
|
|
21
22
|
"@babel/core": "^7.22.17",
|
|
22
23
|
"@babel/eslint-parser": "^7.22.15",
|
|
23
24
|
"@babel/preset-env": "^7.22.15",
|
|
25
|
+
"chai": "^5.0.0",
|
|
24
26
|
"core-js": "^3.32.2",
|
|
25
27
|
"cross-env": "^7.0.3",
|
|
26
28
|
"eslint": "^8.49.0",
|
|
27
|
-
"eslint-config-standard": "^17.1.0"
|
|
29
|
+
"eslint-config-standard": "^17.1.0",
|
|
30
|
+
"mocha": "^10.2.0"
|
|
31
|
+
},
|
|
32
|
+
"imports": {
|
|
33
|
+
"#center-center": "./index.mjs"
|
|
28
34
|
}
|
|
29
35
|
}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import {
|
|
2
|
+
expect
|
|
3
|
+
} from 'chai'
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
getScrollingElement,
|
|
7
|
+
getViewportRect,
|
|
8
|
+
getElementRect,
|
|
9
|
+
getRects,
|
|
10
|
+
calculateLeft,
|
|
11
|
+
calculateTop
|
|
12
|
+
} from '#center-center'
|
|
13
|
+
|
|
14
|
+
describe('`center-center`', () => {
|
|
15
|
+
it('exports `getScrollingElement`', () => expect(getScrollingElement).to.be.a('function'))
|
|
16
|
+
|
|
17
|
+
it('exports `getViewportRect`', () => expect(getViewportRect).to.be.a('function'))
|
|
18
|
+
|
|
19
|
+
it('exports `getElementRect`', () => expect(getElementRect).to.be.a('function'))
|
|
20
|
+
|
|
21
|
+
it('exports `getRects`', () => expect(getRects).to.be.a('function'))
|
|
22
|
+
|
|
23
|
+
it('exports `calculateLeft`', () => expect(calculateLeft).to.be.a('function'))
|
|
24
|
+
|
|
25
|
+
it('exports `calculateTop`', () => expect(calculateTop).to.be.a('function'))
|
|
26
|
+
|
|
27
|
+
describe('`getScrollingElement()`', () => {
|
|
28
|
+
describe('`scrollingElement` is defined', () => {
|
|
29
|
+
describe('`scrollingElement` is null', () => {
|
|
30
|
+
it('returns an object', () => {
|
|
31
|
+
return (
|
|
32
|
+
expect(getScrollingElement({ scrollingElement: null }))
|
|
33
|
+
.to.eql({
|
|
34
|
+
scrollLeft: 0,
|
|
35
|
+
scrollTop: 0
|
|
36
|
+
})
|
|
37
|
+
)
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
describe('`scrollingElement` is an object', () => {
|
|
42
|
+
it('returns an object', () => {
|
|
43
|
+
return (
|
|
44
|
+
expect(getScrollingElement({ scrollingElement: { scrollLeft: 'MOCK SCROLL LEFT', scrollTop: 'MOCK SCROLL TOP' } }))
|
|
45
|
+
.to.eql({
|
|
46
|
+
scrollLeft: 'MOCK SCROLL LEFT',
|
|
47
|
+
scrollTop: 'MOCK SCROLL TOP'
|
|
48
|
+
})
|
|
49
|
+
)
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
describe('`scrollingElement` is not defined', () => {
|
|
55
|
+
it('returns an object', () => {
|
|
56
|
+
return (
|
|
57
|
+
expect(getScrollingElement({}))
|
|
58
|
+
.to.eql({
|
|
59
|
+
scrollLeft: 0,
|
|
60
|
+
scrollTop: 0
|
|
61
|
+
})
|
|
62
|
+
)
|
|
63
|
+
})
|
|
64
|
+
})
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
describe('`getViewportRect()`', () => {
|
|
68
|
+
beforeEach(() => {
|
|
69
|
+
global.window = {
|
|
70
|
+
innerWidth: 'MOCK INNER WIDTH',
|
|
71
|
+
innerHeight: 'MOCK INNER HEIGHT'
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
global.document = {
|
|
75
|
+
scrollingElement: {
|
|
76
|
+
scrollLeft: 'MOCK SCROLL LEFT',
|
|
77
|
+
scrollTop: 'MOCK SCROLL TOP'
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
afterEach(() => {
|
|
83
|
+
delete global.window
|
|
84
|
+
delete global.document
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
it('returns an object', () => expect(getViewportRect()).to.eql({
|
|
88
|
+
top: 'MOCK SCROLL TOP',
|
|
89
|
+
right: 'MOCK SCROLL LEFTMOCK INNER WIDTH',
|
|
90
|
+
bottom: 'MOCK SCROLL TOPMOCK INNER HEIGHT',
|
|
91
|
+
left: 'MOCK SCROLL LEFT',
|
|
92
|
+
width: 'MOCK INNER WIDTH',
|
|
93
|
+
height: 'MOCK INNER HEIGHT'
|
|
94
|
+
}))
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
describe('`getElementRect()`', () => {
|
|
98
|
+
const mockElement = {
|
|
99
|
+
offsetLeft: 'MOCK OFFSET LEFT',
|
|
100
|
+
offsetTop: 'MOCK OFFSET TOP',
|
|
101
|
+
offsetWidth: 'MOCK OFFSET WIDTH',
|
|
102
|
+
offsetHeight: 'MOCK OFFSET HEIGHT'
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
it('returns an object', () => {
|
|
106
|
+
return (
|
|
107
|
+
expect(getElementRect(mockElement))
|
|
108
|
+
.to.eql({
|
|
109
|
+
left: 'MOCK OFFSET LEFT',
|
|
110
|
+
top: 'MOCK OFFSET TOP',
|
|
111
|
+
width: 'MOCK OFFSET WIDTH',
|
|
112
|
+
height: 'MOCK OFFSET HEIGHT',
|
|
113
|
+
right: 'MOCK OFFSET LEFTMOCK OFFSET WIDTH',
|
|
114
|
+
bottom: 'MOCK OFFSET TOPMOCK OFFSET HEIGHT'
|
|
115
|
+
})
|
|
116
|
+
)
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
describe('`getRects()`', () => {
|
|
121
|
+
const mockContainer = {
|
|
122
|
+
offsetLeft: 'MOCK OFFSET LEFT',
|
|
123
|
+
offsetTop: 'MOCK OFFSET TOP',
|
|
124
|
+
offsetWidth: 'MOCK OFFSET WIDTH',
|
|
125
|
+
offsetHeight: 'MOCK OFFSET HEIGHT'
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const mockTarget = {
|
|
129
|
+
offsetLeft: 'MOCK OFFSET LEFT',
|
|
130
|
+
offsetTop: 'MOCK OFFSET TOP',
|
|
131
|
+
offsetWidth: 'MOCK OFFSET WIDTH',
|
|
132
|
+
offsetHeight: 'MOCK OFFSET HEIGHT'
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
beforeEach(() => {
|
|
136
|
+
global.window = {
|
|
137
|
+
innerWidth: 'MOCK INNER WIDTH',
|
|
138
|
+
innerHeight: 'MOCK INNER HEIGHT'
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
global.document = {
|
|
142
|
+
scrollingElement: {
|
|
143
|
+
scrollLeft: 'MOCK SCROLL LEFT',
|
|
144
|
+
scrollTop: 'MOCK SCROLL TOP'
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
afterEach(() => {
|
|
150
|
+
delete global.window
|
|
151
|
+
delete global.document
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
it('returns an object', () => {
|
|
155
|
+
return (
|
|
156
|
+
expect(getRects(mockContainer, mockTarget))
|
|
157
|
+
.to.eql({
|
|
158
|
+
viewport: {
|
|
159
|
+
top: 'MOCK SCROLL TOP',
|
|
160
|
+
right: 'MOCK SCROLL LEFTMOCK INNER WIDTH',
|
|
161
|
+
bottom: 'MOCK SCROLL TOPMOCK INNER HEIGHT',
|
|
162
|
+
left: 'MOCK SCROLL LEFT',
|
|
163
|
+
width: 'MOCK INNER WIDTH',
|
|
164
|
+
height: 'MOCK INNER HEIGHT'
|
|
165
|
+
},
|
|
166
|
+
container: {
|
|
167
|
+
left: 'MOCK OFFSET LEFT',
|
|
168
|
+
top: 'MOCK OFFSET TOP',
|
|
169
|
+
width: 'MOCK OFFSET WIDTH',
|
|
170
|
+
height: 'MOCK OFFSET HEIGHT',
|
|
171
|
+
right: 'MOCK OFFSET LEFTMOCK OFFSET WIDTH',
|
|
172
|
+
bottom: 'MOCK OFFSET TOPMOCK OFFSET HEIGHT'
|
|
173
|
+
},
|
|
174
|
+
target: {
|
|
175
|
+
left: 'MOCK OFFSET LEFT',
|
|
176
|
+
top: 'MOCK OFFSET TOP',
|
|
177
|
+
width: 'MOCK OFFSET WIDTH',
|
|
178
|
+
height: 'MOCK OFFSET HEIGHT',
|
|
179
|
+
right: 'MOCK OFFSET LEFTMOCK OFFSET WIDTH',
|
|
180
|
+
bottom: 'MOCK OFFSET TOPMOCK OFFSET HEIGHT'
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
)
|
|
184
|
+
})
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
describe('Container is shorter than the Window', () => {
|
|
188
|
+
const rects = {
|
|
189
|
+
viewport: {
|
|
190
|
+
top: 0,
|
|
191
|
+
right: 1440,
|
|
192
|
+
bottom: 900,
|
|
193
|
+
left: 0,
|
|
194
|
+
width: 1440,
|
|
195
|
+
height: 900
|
|
196
|
+
},
|
|
197
|
+
container: {
|
|
198
|
+
x: 0,
|
|
199
|
+
y: 90,
|
|
200
|
+
top: 90,
|
|
201
|
+
right: 1440,
|
|
202
|
+
bottom: 810,
|
|
203
|
+
left: 0,
|
|
204
|
+
width: 1440,
|
|
205
|
+
height: 720
|
|
206
|
+
},
|
|
207
|
+
target: {
|
|
208
|
+
width: 50,
|
|
209
|
+
height: 50
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
describe('`calculateLeft()`', () => {
|
|
214
|
+
/**
|
|
215
|
+
* Window is 1440 x 900
|
|
216
|
+
* Header is 1440 x 90
|
|
217
|
+
* Container is 1440 x 720
|
|
218
|
+
* Footer is 1440 x 90
|
|
219
|
+
* Target is 50 x 50
|
|
220
|
+
*/
|
|
221
|
+
it('returns an object', () => {
|
|
222
|
+
/**
|
|
223
|
+
* (1440 / 2) - (50 / 2)
|
|
224
|
+
*/
|
|
225
|
+
return (
|
|
226
|
+
expect(calculateLeft(rects))
|
|
227
|
+
.to.equal(695)
|
|
228
|
+
)
|
|
229
|
+
})
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
describe('`calculateTop()`', () => {
|
|
233
|
+
/**
|
|
234
|
+
* Window is 1440 x 900
|
|
235
|
+
* Header is 1440 x 90
|
|
236
|
+
* Container is 1440 x 720
|
|
237
|
+
* Footer is 1440 x 90
|
|
238
|
+
* Target is 50 x 50
|
|
239
|
+
*/
|
|
240
|
+
it('returns an object', () => {
|
|
241
|
+
/**
|
|
242
|
+
* (720 / 2) - (50 / 2)
|
|
243
|
+
*/
|
|
244
|
+
return (
|
|
245
|
+
expect(calculateTop(rects))
|
|
246
|
+
.to.equal(335)
|
|
247
|
+
)
|
|
248
|
+
})
|
|
249
|
+
})
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
describe('Container is taller than the Window', () => {
|
|
253
|
+
const rects = {
|
|
254
|
+
viewport: {
|
|
255
|
+
top: 0,
|
|
256
|
+
right: 1440,
|
|
257
|
+
bottom: 900,
|
|
258
|
+
left: 0,
|
|
259
|
+
width: 1440,
|
|
260
|
+
height: 900
|
|
261
|
+
},
|
|
262
|
+
container: {
|
|
263
|
+
x: 0,
|
|
264
|
+
y: 90,
|
|
265
|
+
top: 90,
|
|
266
|
+
right: 1440,
|
|
267
|
+
bottom: 1080,
|
|
268
|
+
left: 0,
|
|
269
|
+
width: 1440,
|
|
270
|
+
height: 990
|
|
271
|
+
},
|
|
272
|
+
target: {
|
|
273
|
+
width: 50,
|
|
274
|
+
height: 50
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
describe('`calculateLeft()`', () => {
|
|
279
|
+
/**
|
|
280
|
+
* Window is 1440 x 900
|
|
281
|
+
* Header is 1440 x 90
|
|
282
|
+
* Container is 1440 x 990
|
|
283
|
+
* Footer is 1440 x 90
|
|
284
|
+
* Target is 50 x 50
|
|
285
|
+
*/
|
|
286
|
+
it('returns an object', () => {
|
|
287
|
+
/**
|
|
288
|
+
* (1440 / 2) - (50 / 2)
|
|
289
|
+
*/
|
|
290
|
+
return (
|
|
291
|
+
expect(calculateLeft(rects))
|
|
292
|
+
.to.equal(695)
|
|
293
|
+
)
|
|
294
|
+
})
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
describe('`calculateTop()`', () => {
|
|
298
|
+
/**
|
|
299
|
+
* Window is 1440 x 900
|
|
300
|
+
* Header is 1440 x 90
|
|
301
|
+
* Container is 1440 x 990
|
|
302
|
+
* Footer is 1440 x 90
|
|
303
|
+
* Target is 50 x 50
|
|
304
|
+
*/
|
|
305
|
+
it('returns an object', () => {
|
|
306
|
+
/**
|
|
307
|
+
* (810 / 2) - (50 / 2)
|
|
308
|
+
*/
|
|
309
|
+
return (
|
|
310
|
+
expect(calculateTop(rects))
|
|
311
|
+
.to.equal(380)
|
|
312
|
+
)
|
|
313
|
+
})
|
|
314
|
+
})
|
|
315
|
+
})
|
|
316
|
+
})
|