fluent-styles 1.62.13 → 1.62.15
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/lib/commonjs/button/index.js +12 -4
- package/lib/commonjs/button/index.js.map +1 -1
- package/lib/commonjs/datePicker/index.js +7 -2
- package/lib/commonjs/datePicker/index.js.map +1 -1
- package/lib/commonjs/dropdown/index.js +49 -16
- package/lib/commonjs/dropdown/index.js.map +1 -1
- package/lib/commonjs/input/index.js +87 -44
- package/lib/commonjs/input/index.js.map +1 -1
- package/lib/commonjs/page/index.js +24 -3
- package/lib/commonjs/page/index.js.map +1 -1
- package/lib/commonjs/pressable/index.js +6 -0
- package/lib/commonjs/pressable/index.js.map +1 -1
- package/lib/commonjs/safeAreaView/index.js +10 -0
- package/lib/commonjs/safeAreaView/index.js.map +1 -1
- package/lib/commonjs/utiles/styled.js +12 -2
- package/lib/commonjs/utiles/styled.js.map +1 -1
- package/lib/module/button/index.js +12 -4
- package/lib/module/button/index.js.map +1 -1
- package/lib/module/datePicker/index.js +7 -2
- package/lib/module/datePicker/index.js.map +1 -1
- package/lib/module/dropdown/index.js +49 -16
- package/lib/module/dropdown/index.js.map +1 -1
- package/lib/module/input/index.js +87 -44
- package/lib/module/input/index.js.map +1 -1
- package/lib/module/page/index.js +25 -4
- package/lib/module/page/index.js.map +1 -1
- package/lib/module/pressable/index.js +7 -1
- package/lib/module/pressable/index.js.map +1 -1
- package/lib/module/safeAreaView/index.js +11 -1
- package/lib/module/safeAreaView/index.js.map +1 -1
- package/lib/module/utiles/styled.js +12 -2
- package/lib/module/utiles/styled.js.map +1 -1
- package/lib/typescript/badge/index.d.ts +1 -6
- package/lib/typescript/badge/index.d.ts.map +1 -1
- package/lib/typescript/button/index.d.ts +3 -8
- package/lib/typescript/button/index.d.ts.map +1 -1
- package/lib/typescript/card/index.d.ts +1 -6
- package/lib/typescript/card/index.d.ts.map +1 -1
- package/lib/typescript/checkBox/index.d.ts +1 -6
- package/lib/typescript/checkBox/index.d.ts.map +1 -1
- package/lib/typescript/datePicker/index.d.ts.map +1 -1
- package/lib/typescript/dialog/index.d.ts +1 -6
- package/lib/typescript/dialog/index.d.ts.map +1 -1
- package/lib/typescript/divider/index.d.ts +1 -6
- package/lib/typescript/divider/index.d.ts.map +1 -1
- package/lib/typescript/dropdown/index.d.ts +27 -2
- package/lib/typescript/dropdown/index.d.ts.map +1 -1
- package/lib/typescript/image/index.d.ts +1 -6
- package/lib/typescript/image/index.d.ts.map +1 -1
- package/lib/typescript/input/index.d.ts +21 -8
- package/lib/typescript/input/index.d.ts.map +1 -1
- package/lib/typescript/page/index.d.ts.map +1 -1
- package/lib/typescript/pressable/index.d.ts +1 -6
- package/lib/typescript/pressable/index.d.ts.map +1 -1
- package/lib/typescript/safeAreaProvider/index.d.ts +1 -6
- package/lib/typescript/safeAreaProvider/index.d.ts.map +1 -1
- package/lib/typescript/safeAreaView/index.d.ts +1 -6
- package/lib/typescript/safeAreaView/index.d.ts.map +1 -1
- package/lib/typescript/scrollView/index.d.ts +1 -6
- package/lib/typescript/scrollView/index.d.ts.map +1 -1
- package/lib/typescript/shape/cycle.d.ts +1 -6
- package/lib/typescript/shape/cycle.d.ts.map +1 -1
- package/lib/typescript/shape/index.d.ts +1 -6
- package/lib/typescript/shape/index.d.ts.map +1 -1
- package/lib/typescript/spacer/index.d.ts +1 -6
- package/lib/typescript/spacer/index.d.ts.map +1 -1
- package/lib/typescript/stack/index.d.ts +3 -18
- package/lib/typescript/stack/index.d.ts.map +1 -1
- package/lib/typescript/text/index.d.ts +1 -6
- package/lib/typescript/text/index.d.ts.map +1 -1
- package/lib/typescript/utiles/styled.d.ts +1 -6
- package/lib/typescript/utiles/styled.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/button/index.tsx +14 -2
- package/src/datePicker/index.tsx +5 -1
- package/src/dropdown/index.tsx +72 -11
- package/src/input/index.tsx +111 -48
- package/src/page/index.tsx +36 -3
- package/src/pressable/index.tsx +8 -2
- package/src/safeAreaView/index.tsx +11 -1
- package/src/utiles/styled.tsx +12 -3
- package/lib/commonjs/portal/portal.test.js +0 -154
- package/lib/commonjs/portal/portal.test.js.map +0 -1
- package/lib/module/portal/portal.test.js +0 -155
- package/lib/module/portal/portal.test.js.map +0 -1
- package/lib/typescript/portal/portal.test.d.ts +0 -11
- package/lib/typescript/portal/portal.test.d.ts.map +0 -1
- package/src/portal/portal.test.ts +0 -157
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _PortalInstance = require("./PortalInstance.js");
|
|
4
|
-
var _position = require("../utiles/position.js");
|
|
5
|
-
/**
|
|
6
|
-
* Unit tests for the portal module.
|
|
7
|
-
*
|
|
8
|
-
* Run with: jest --testPathPattern=portal
|
|
9
|
-
*
|
|
10
|
-
* These tests cover the two independently-testable units:
|
|
11
|
-
* 1. `PortalInstance` — the imperative singleton logic
|
|
12
|
-
* 2. `getPositionStyles` — the position-to-style mapping utility
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
// ─── PortalInstance ───────────────────────────────────────────────────────────
|
|
16
|
-
|
|
17
|
-
describe('PortalInstance', () => {
|
|
18
|
-
let instance;
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
instance = new _PortalInstance.PortalInstance();
|
|
21
|
-
});
|
|
22
|
-
it('starts with no portals', () => {
|
|
23
|
-
expect(instance.getPortals()).toHaveLength(0);
|
|
24
|
-
});
|
|
25
|
-
it('show() adds a portal and returns a unique id', () => {
|
|
26
|
-
const id1 = instance.show(null);
|
|
27
|
-
const id2 = instance.show(null);
|
|
28
|
-
expect(id1).not.toBe(id2);
|
|
29
|
-
expect(instance.getPortals()).toHaveLength(2);
|
|
30
|
-
});
|
|
31
|
-
it('show() stores the supplied options', () => {
|
|
32
|
-
const id = instance.show(null, {
|
|
33
|
-
position: 'top',
|
|
34
|
-
backdrop: true
|
|
35
|
-
});
|
|
36
|
-
const portal = instance.getPortals().find(p => p.id === id);
|
|
37
|
-
expect(portal?.options.position).toBe('top');
|
|
38
|
-
expect(portal?.options.backdrop).toBe(true);
|
|
39
|
-
});
|
|
40
|
-
it('update() replaces children and options', () => {
|
|
41
|
-
const id = instance.show(null, {
|
|
42
|
-
position: 'top'
|
|
43
|
-
});
|
|
44
|
-
instance.update(id, null, {
|
|
45
|
-
position: 'bottom'
|
|
46
|
-
});
|
|
47
|
-
const portal = instance.getPortals().find(p => p.id === id);
|
|
48
|
-
expect(portal?.options.position).toBe('bottom');
|
|
49
|
-
});
|
|
50
|
-
it('update() preserves options when none supplied', () => {
|
|
51
|
-
const id = instance.show(null, {
|
|
52
|
-
position: 'top'
|
|
53
|
-
});
|
|
54
|
-
instance.update(id, null);
|
|
55
|
-
const portal = instance.getPortals().find(p => p.id === id);
|
|
56
|
-
expect(portal?.options.position).toBe('top');
|
|
57
|
-
});
|
|
58
|
-
it('update() is a no-op for unknown ids', () => {
|
|
59
|
-
instance.update(99999, null);
|
|
60
|
-
expect(instance.getPortals()).toHaveLength(0);
|
|
61
|
-
});
|
|
62
|
-
it('hide() removes the portal', () => {
|
|
63
|
-
const id = instance.show(null);
|
|
64
|
-
instance.hide(id);
|
|
65
|
-
expect(instance.getPortals()).toHaveLength(0);
|
|
66
|
-
});
|
|
67
|
-
it('hide() is safe to call twice', () => {
|
|
68
|
-
const id = instance.show(null);
|
|
69
|
-
instance.hide(id);
|
|
70
|
-
expect(() => instance.hide(id)).not.toThrow();
|
|
71
|
-
});
|
|
72
|
-
it('hideAll() clears every portal', () => {
|
|
73
|
-
instance.show(null);
|
|
74
|
-
instance.show(null);
|
|
75
|
-
instance.show(null);
|
|
76
|
-
instance.hideAll();
|
|
77
|
-
expect(instance.getPortals()).toHaveLength(0);
|
|
78
|
-
});
|
|
79
|
-
it('notifies subscribers on show', () => {
|
|
80
|
-
const listener = jest.fn();
|
|
81
|
-
instance.subscribe(listener);
|
|
82
|
-
instance.show(null);
|
|
83
|
-
expect(listener).toHaveBeenCalledTimes(1);
|
|
84
|
-
});
|
|
85
|
-
it('notifies subscribers on hide', () => {
|
|
86
|
-
const listener = jest.fn();
|
|
87
|
-
const id = instance.show(null);
|
|
88
|
-
instance.subscribe(listener);
|
|
89
|
-
instance.hide(id);
|
|
90
|
-
expect(listener).toHaveBeenCalledTimes(1);
|
|
91
|
-
});
|
|
92
|
-
it('unsubscribe stops notifications', () => {
|
|
93
|
-
const listener = jest.fn();
|
|
94
|
-
const unsubscribe = instance.subscribe(listener);
|
|
95
|
-
unsubscribe();
|
|
96
|
-
instance.show(null);
|
|
97
|
-
expect(listener).not.toHaveBeenCalled();
|
|
98
|
-
});
|
|
99
|
-
it('hideAll() does not notify when already empty', () => {
|
|
100
|
-
const listener = jest.fn();
|
|
101
|
-
instance.subscribe(listener);
|
|
102
|
-
instance.hideAll();
|
|
103
|
-
expect(listener).not.toHaveBeenCalled();
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
// ─── getPositionStyles ────────────────────────────────────────────────────────
|
|
108
|
-
|
|
109
|
-
describe('getPositionStyles', () => {
|
|
110
|
-
it('returns position:absolute for all variants', () => {
|
|
111
|
-
const positions = ['top', 'bottom', 'center', 'top-left', 'top-right', 'bottom-left', 'bottom-right'];
|
|
112
|
-
positions.forEach(pos => {
|
|
113
|
-
expect((0, _position.getPositionStyles)(pos).position).toBe('absolute');
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
it('top spans full width', () => {
|
|
117
|
-
const styles = (0, _position.getPositionStyles)('top');
|
|
118
|
-
expect(styles.left).toBe(0);
|
|
119
|
-
expect(styles.right).toBe(0);
|
|
120
|
-
expect(styles.top).toBe(0);
|
|
121
|
-
});
|
|
122
|
-
it('bottom spans full width', () => {
|
|
123
|
-
const styles = (0, _position.getPositionStyles)('bottom');
|
|
124
|
-
expect(styles.left).toBe(0);
|
|
125
|
-
expect(styles.right).toBe(0);
|
|
126
|
-
expect(styles.bottom).toBe(0);
|
|
127
|
-
});
|
|
128
|
-
it('top-right uses right/top anchors', () => {
|
|
129
|
-
const styles = (0, _position.getPositionStyles)('top-right');
|
|
130
|
-
expect(styles.right).toBeDefined();
|
|
131
|
-
expect(styles.top).toBeDefined();
|
|
132
|
-
expect(styles.left).toBeUndefined();
|
|
133
|
-
});
|
|
134
|
-
it('applies x offset to top-left', () => {
|
|
135
|
-
const styles = (0, _position.getPositionStyles)('top-left', {
|
|
136
|
-
x: 16,
|
|
137
|
-
y: 0
|
|
138
|
-
});
|
|
139
|
-
expect(styles.left).toBe(16);
|
|
140
|
-
});
|
|
141
|
-
it('applies y offset to bottom', () => {
|
|
142
|
-
const styles = (0, _position.getPositionStyles)('bottom', {
|
|
143
|
-
x: 0,
|
|
144
|
-
y: 24
|
|
145
|
-
});
|
|
146
|
-
expect(styles.bottom).toBe(24);
|
|
147
|
-
});
|
|
148
|
-
it('defaults to center when no position given', () => {
|
|
149
|
-
const styles = (0, _position.getPositionStyles)();
|
|
150
|
-
expect(styles.top).toBe('50%');
|
|
151
|
-
expect(styles.left).toBe('50%');
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
//# sourceMappingURL=portal.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["_PortalInstance","require","_position","describe","instance","beforeEach","PortalInstance","it","expect","getPortals","toHaveLength","id1","show","id2","not","toBe","id","position","backdrop","portal","find","p","options","update","hide","toThrow","hideAll","listener","jest","fn","subscribe","toHaveBeenCalledTimes","unsubscribe","toHaveBeenCalled","positions","forEach","pos","getPositionStyles","styles","left","right","top","bottom","toBeDefined","toBeUndefined","x","y"],"sourceRoot":"../../../src","sources":["portal/portal.test.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Unit tests for the portal module.
|
|
5
|
-
*
|
|
6
|
-
* Run with: jest --testPathPattern=portal
|
|
7
|
-
*
|
|
8
|
-
* These tests cover the two independently-testable units:
|
|
9
|
-
* 1. `PortalInstance` — the imperative singleton logic
|
|
10
|
-
* 2. `getPositionStyles` — the position-to-style mapping utility
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { PortalInstance } from "./PortalInstance.js";
|
|
14
|
-
import { getPositionStyles } from "../utiles/position.js";
|
|
15
|
-
|
|
16
|
-
// ─── PortalInstance ───────────────────────────────────────────────────────────
|
|
17
|
-
|
|
18
|
-
describe('PortalInstance', () => {
|
|
19
|
-
let instance;
|
|
20
|
-
beforeEach(() => {
|
|
21
|
-
instance = new PortalInstance();
|
|
22
|
-
});
|
|
23
|
-
it('starts with no portals', () => {
|
|
24
|
-
expect(instance.getPortals()).toHaveLength(0);
|
|
25
|
-
});
|
|
26
|
-
it('show() adds a portal and returns a unique id', () => {
|
|
27
|
-
const id1 = instance.show(null);
|
|
28
|
-
const id2 = instance.show(null);
|
|
29
|
-
expect(id1).not.toBe(id2);
|
|
30
|
-
expect(instance.getPortals()).toHaveLength(2);
|
|
31
|
-
});
|
|
32
|
-
it('show() stores the supplied options', () => {
|
|
33
|
-
const id = instance.show(null, {
|
|
34
|
-
position: 'top',
|
|
35
|
-
backdrop: true
|
|
36
|
-
});
|
|
37
|
-
const portal = instance.getPortals().find(p => p.id === id);
|
|
38
|
-
expect(portal?.options.position).toBe('top');
|
|
39
|
-
expect(portal?.options.backdrop).toBe(true);
|
|
40
|
-
});
|
|
41
|
-
it('update() replaces children and options', () => {
|
|
42
|
-
const id = instance.show(null, {
|
|
43
|
-
position: 'top'
|
|
44
|
-
});
|
|
45
|
-
instance.update(id, null, {
|
|
46
|
-
position: 'bottom'
|
|
47
|
-
});
|
|
48
|
-
const portal = instance.getPortals().find(p => p.id === id);
|
|
49
|
-
expect(portal?.options.position).toBe('bottom');
|
|
50
|
-
});
|
|
51
|
-
it('update() preserves options when none supplied', () => {
|
|
52
|
-
const id = instance.show(null, {
|
|
53
|
-
position: 'top'
|
|
54
|
-
});
|
|
55
|
-
instance.update(id, null);
|
|
56
|
-
const portal = instance.getPortals().find(p => p.id === id);
|
|
57
|
-
expect(portal?.options.position).toBe('top');
|
|
58
|
-
});
|
|
59
|
-
it('update() is a no-op for unknown ids', () => {
|
|
60
|
-
instance.update(99999, null);
|
|
61
|
-
expect(instance.getPortals()).toHaveLength(0);
|
|
62
|
-
});
|
|
63
|
-
it('hide() removes the portal', () => {
|
|
64
|
-
const id = instance.show(null);
|
|
65
|
-
instance.hide(id);
|
|
66
|
-
expect(instance.getPortals()).toHaveLength(0);
|
|
67
|
-
});
|
|
68
|
-
it('hide() is safe to call twice', () => {
|
|
69
|
-
const id = instance.show(null);
|
|
70
|
-
instance.hide(id);
|
|
71
|
-
expect(() => instance.hide(id)).not.toThrow();
|
|
72
|
-
});
|
|
73
|
-
it('hideAll() clears every portal', () => {
|
|
74
|
-
instance.show(null);
|
|
75
|
-
instance.show(null);
|
|
76
|
-
instance.show(null);
|
|
77
|
-
instance.hideAll();
|
|
78
|
-
expect(instance.getPortals()).toHaveLength(0);
|
|
79
|
-
});
|
|
80
|
-
it('notifies subscribers on show', () => {
|
|
81
|
-
const listener = jest.fn();
|
|
82
|
-
instance.subscribe(listener);
|
|
83
|
-
instance.show(null);
|
|
84
|
-
expect(listener).toHaveBeenCalledTimes(1);
|
|
85
|
-
});
|
|
86
|
-
it('notifies subscribers on hide', () => {
|
|
87
|
-
const listener = jest.fn();
|
|
88
|
-
const id = instance.show(null);
|
|
89
|
-
instance.subscribe(listener);
|
|
90
|
-
instance.hide(id);
|
|
91
|
-
expect(listener).toHaveBeenCalledTimes(1);
|
|
92
|
-
});
|
|
93
|
-
it('unsubscribe stops notifications', () => {
|
|
94
|
-
const listener = jest.fn();
|
|
95
|
-
const unsubscribe = instance.subscribe(listener);
|
|
96
|
-
unsubscribe();
|
|
97
|
-
instance.show(null);
|
|
98
|
-
expect(listener).not.toHaveBeenCalled();
|
|
99
|
-
});
|
|
100
|
-
it('hideAll() does not notify when already empty', () => {
|
|
101
|
-
const listener = jest.fn();
|
|
102
|
-
instance.subscribe(listener);
|
|
103
|
-
instance.hideAll();
|
|
104
|
-
expect(listener).not.toHaveBeenCalled();
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
// ─── getPositionStyles ────────────────────────────────────────────────────────
|
|
109
|
-
|
|
110
|
-
describe('getPositionStyles', () => {
|
|
111
|
-
it('returns position:absolute for all variants', () => {
|
|
112
|
-
const positions = ['top', 'bottom', 'center', 'top-left', 'top-right', 'bottom-left', 'bottom-right'];
|
|
113
|
-
positions.forEach(pos => {
|
|
114
|
-
expect(getPositionStyles(pos).position).toBe('absolute');
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
it('top spans full width', () => {
|
|
118
|
-
const styles = getPositionStyles('top');
|
|
119
|
-
expect(styles.left).toBe(0);
|
|
120
|
-
expect(styles.right).toBe(0);
|
|
121
|
-
expect(styles.top).toBe(0);
|
|
122
|
-
});
|
|
123
|
-
it('bottom spans full width', () => {
|
|
124
|
-
const styles = getPositionStyles('bottom');
|
|
125
|
-
expect(styles.left).toBe(0);
|
|
126
|
-
expect(styles.right).toBe(0);
|
|
127
|
-
expect(styles.bottom).toBe(0);
|
|
128
|
-
});
|
|
129
|
-
it('top-right uses right/top anchors', () => {
|
|
130
|
-
const styles = getPositionStyles('top-right');
|
|
131
|
-
expect(styles.right).toBeDefined();
|
|
132
|
-
expect(styles.top).toBeDefined();
|
|
133
|
-
expect(styles.left).toBeUndefined();
|
|
134
|
-
});
|
|
135
|
-
it('applies x offset to top-left', () => {
|
|
136
|
-
const styles = getPositionStyles('top-left', {
|
|
137
|
-
x: 16,
|
|
138
|
-
y: 0
|
|
139
|
-
});
|
|
140
|
-
expect(styles.left).toBe(16);
|
|
141
|
-
});
|
|
142
|
-
it('applies y offset to bottom', () => {
|
|
143
|
-
const styles = getPositionStyles('bottom', {
|
|
144
|
-
x: 0,
|
|
145
|
-
y: 24
|
|
146
|
-
});
|
|
147
|
-
expect(styles.bottom).toBe(24);
|
|
148
|
-
});
|
|
149
|
-
it('defaults to center when no position given', () => {
|
|
150
|
-
const styles = getPositionStyles();
|
|
151
|
-
expect(styles.top).toBe('50%');
|
|
152
|
-
expect(styles.left).toBe('50%');
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
//# sourceMappingURL=portal.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["PortalInstance","getPositionStyles","describe","instance","beforeEach","it","expect","getPortals","toHaveLength","id1","show","id2","not","toBe","id","position","backdrop","portal","find","p","options","update","hide","toThrow","hideAll","listener","jest","fn","subscribe","toHaveBeenCalledTimes","unsubscribe","toHaveBeenCalled","positions","forEach","pos","styles","left","right","top","bottom","toBeDefined","toBeUndefined","x","y"],"sourceRoot":"../../../src","sources":["portal/portal.test.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit tests for the portal module.
|
|
3
|
-
*
|
|
4
|
-
* Run with: jest --testPathPattern=portal
|
|
5
|
-
*
|
|
6
|
-
* These tests cover the two independently-testable units:
|
|
7
|
-
* 1. `PortalInstance` — the imperative singleton logic
|
|
8
|
-
* 2. `getPositionStyles` — the position-to-style mapping utility
|
|
9
|
-
*/
|
|
10
|
-
export {};
|
|
11
|
-
//# sourceMappingURL=portal.test.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"portal.test.d.ts","sourceRoot":"","sources":["../../../src/portal/portal.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit tests for the portal module.
|
|
3
|
-
*
|
|
4
|
-
* Run with: jest --testPathPattern=portal
|
|
5
|
-
*
|
|
6
|
-
* These tests cover the two independently-testable units:
|
|
7
|
-
* 1. `PortalInstance` — the imperative singleton logic
|
|
8
|
-
* 2. `getPositionStyles` — the position-to-style mapping utility
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { PortalInstance } from './PortalInstance'
|
|
12
|
-
import { getPositionStyles } from '../utiles/position'
|
|
13
|
-
|
|
14
|
-
// ─── PortalInstance ───────────────────────────────────────────────────────────
|
|
15
|
-
|
|
16
|
-
describe('PortalInstance', () => {
|
|
17
|
-
let instance: PortalInstance
|
|
18
|
-
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
instance = new PortalInstance()
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
it('starts with no portals', () => {
|
|
24
|
-
expect(instance.getPortals()).toHaveLength(0)
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('show() adds a portal and returns a unique id', () => {
|
|
28
|
-
const id1 = instance.show(null)
|
|
29
|
-
const id2 = instance.show(null)
|
|
30
|
-
expect(id1).not.toBe(id2)
|
|
31
|
-
expect(instance.getPortals()).toHaveLength(2)
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
it('show() stores the supplied options', () => {
|
|
35
|
-
const id = instance.show(null, { position: 'top', backdrop: true })
|
|
36
|
-
const portal = instance.getPortals().find(p => p.id === id)
|
|
37
|
-
expect(portal?.options.position).toBe('top')
|
|
38
|
-
expect(portal?.options.backdrop).toBe(true)
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
it('update() replaces children and options', () => {
|
|
42
|
-
const id = instance.show(null, { position: 'top' })
|
|
43
|
-
instance.update(id, null, { position: 'bottom' })
|
|
44
|
-
const portal = instance.getPortals().find(p => p.id === id)
|
|
45
|
-
expect(portal?.options.position).toBe('bottom')
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
it('update() preserves options when none supplied', () => {
|
|
49
|
-
const id = instance.show(null, { position: 'top' })
|
|
50
|
-
instance.update(id, null)
|
|
51
|
-
const portal = instance.getPortals().find(p => p.id === id)
|
|
52
|
-
expect(portal?.options.position).toBe('top')
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('update() is a no-op for unknown ids', () => {
|
|
56
|
-
instance.update(99999, null)
|
|
57
|
-
expect(instance.getPortals()).toHaveLength(0)
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
it('hide() removes the portal', () => {
|
|
61
|
-
const id = instance.show(null)
|
|
62
|
-
instance.hide(id)
|
|
63
|
-
expect(instance.getPortals()).toHaveLength(0)
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
it('hide() is safe to call twice', () => {
|
|
67
|
-
const id = instance.show(null)
|
|
68
|
-
instance.hide(id)
|
|
69
|
-
expect(() => instance.hide(id)).not.toThrow()
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it('hideAll() clears every portal', () => {
|
|
73
|
-
instance.show(null)
|
|
74
|
-
instance.show(null)
|
|
75
|
-
instance.show(null)
|
|
76
|
-
instance.hideAll()
|
|
77
|
-
expect(instance.getPortals()).toHaveLength(0)
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
it('notifies subscribers on show', () => {
|
|
81
|
-
const listener = jest.fn()
|
|
82
|
-
instance.subscribe(listener)
|
|
83
|
-
instance.show(null)
|
|
84
|
-
expect(listener).toHaveBeenCalledTimes(1)
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
it('notifies subscribers on hide', () => {
|
|
88
|
-
const listener = jest.fn()
|
|
89
|
-
const id = instance.show(null)
|
|
90
|
-
instance.subscribe(listener)
|
|
91
|
-
instance.hide(id)
|
|
92
|
-
expect(listener).toHaveBeenCalledTimes(1)
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
it('unsubscribe stops notifications', () => {
|
|
96
|
-
const listener = jest.fn()
|
|
97
|
-
const unsubscribe = instance.subscribe(listener)
|
|
98
|
-
unsubscribe()
|
|
99
|
-
instance.show(null)
|
|
100
|
-
expect(listener).not.toHaveBeenCalled()
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
it('hideAll() does not notify when already empty', () => {
|
|
104
|
-
const listener = jest.fn()
|
|
105
|
-
instance.subscribe(listener)
|
|
106
|
-
instance.hideAll()
|
|
107
|
-
expect(listener).not.toHaveBeenCalled()
|
|
108
|
-
})
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
// ─── getPositionStyles ────────────────────────────────────────────────────────
|
|
112
|
-
|
|
113
|
-
describe('getPositionStyles', () => {
|
|
114
|
-
it('returns position:absolute for all variants', () => {
|
|
115
|
-
const positions = ['top', 'bottom', 'center', 'top-left', 'top-right', 'bottom-left', 'bottom-right'] as const
|
|
116
|
-
positions.forEach(pos => {
|
|
117
|
-
expect(getPositionStyles(pos).position).toBe('absolute')
|
|
118
|
-
})
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
it('top spans full width', () => {
|
|
122
|
-
const styles = getPositionStyles('top')
|
|
123
|
-
expect(styles.left).toBe(0)
|
|
124
|
-
expect(styles.right).toBe(0)
|
|
125
|
-
expect(styles.top).toBe(0)
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
it('bottom spans full width', () => {
|
|
129
|
-
const styles = getPositionStyles('bottom')
|
|
130
|
-
expect(styles.left).toBe(0)
|
|
131
|
-
expect(styles.right).toBe(0)
|
|
132
|
-
expect(styles.bottom).toBe(0)
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
it('top-right uses right/top anchors', () => {
|
|
136
|
-
const styles = getPositionStyles('top-right')
|
|
137
|
-
expect(styles.right).toBeDefined()
|
|
138
|
-
expect(styles.top).toBeDefined()
|
|
139
|
-
expect((styles as any).left).toBeUndefined()
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
it('applies x offset to top-left', () => {
|
|
143
|
-
const styles = getPositionStyles('top-left', { x: 16, y: 0 })
|
|
144
|
-
expect(styles.left).toBe(16)
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
it('applies y offset to bottom', () => {
|
|
148
|
-
const styles = getPositionStyles('bottom', { x: 0, y: 24 })
|
|
149
|
-
expect(styles.bottom).toBe(24)
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
it('defaults to center when no position given', () => {
|
|
153
|
-
const styles = getPositionStyles()
|
|
154
|
-
expect(styles.top).toBe('50%')
|
|
155
|
-
expect(styles.left).toBe('50%')
|
|
156
|
-
})
|
|
157
|
-
})
|