nanosplash 2.2.4 → 2.3.2

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.
Files changed (53) hide show
  1. package/.github/workflows/production.yml +57 -0
  2. package/.github/workflows/release.yml +61 -0
  3. package/README.md +17 -15
  4. package/dist/iife/nanosplash.iife.js +1 -1
  5. package/dist/module/Nanosplash.css +1 -0
  6. package/dist/module/manifest.json +6 -3
  7. package/dist/module/nanosplash.cjs.js +1 -1
  8. package/dist/module/nanosplash.es.js +244 -330
  9. package/docs/index.html +54 -430
  10. package/docs/nanosplash.iife.js +1 -1
  11. package/docs/style.css +1 -1
  12. package/docs/typedoc/assets/highlight.css +1 -50
  13. package/docs/typedoc/assets/main.js +2 -2
  14. package/docs/typedoc/assets/search.js +1 -1
  15. package/docs/typedoc/assets/style.css +32 -2
  16. package/docs/typedoc/classes/Core_Nanosplash.Nanosplash.html +1 -0
  17. package/docs/typedoc/index.html +1 -1
  18. package/docs/typedoc/modules/Core_Nanosplash.html +1 -0
  19. package/docs/typedoc/modules/types.html +1 -1
  20. package/index.html +51 -412
  21. package/jest.config.ts +194 -0
  22. package/package.json +70 -65
  23. package/src/Core/Nanosplash.ts +74 -0
  24. package/src/Core/SplashInstance.ts +154 -0
  25. package/src/Factory/NanosplashFactory.ts +73 -0
  26. package/src/Interfaces/ContextualAPIInterface.ts +8 -0
  27. package/src/Interfaces/IdentityInterface.ts +3 -0
  28. package/src/Interfaces/ImageInterface.ts +5 -0
  29. package/src/Interfaces/InsideInterface.ts +5 -0
  30. package/src/Interfaces/NanosplashInterface.ts +4 -0
  31. package/src/Interfaces/ProgressInterface.ts +5 -0
  32. package/src/Interfaces/ShowInterface.ts +5 -0
  33. package/src/Interfaces/WhileInterface.ts +5 -0
  34. package/src/main.ts +2 -6
  35. package/src/repositories/NanosplashRepository.ts +34 -55
  36. package/src/style.sass +51 -61
  37. package/src/types.d.ts +45 -200
  38. package/src/utilities/dom.spec.ts +70 -0
  39. package/src/utilities/dom.ts +17 -256
  40. package/update-all.sh +3 -0
  41. package/vite.iife.config.js +46 -18
  42. package/vite.mod.config.js +48 -12
  43. package/vite.site.config.js +0 -3
  44. package/dist/module/style.css +0 -1
  45. package/docs/typedoc/classes/Nanosplash.Nanosplash-1.html +0 -56
  46. package/docs/typedoc/classes/types.Nanosplash.html +0 -56
  47. package/docs/typedoc/modules/Nanosplash.html +0 -1
  48. package/src/Exceptions/Exception.ts +0 -12
  49. package/src/Exceptions/IllegalArgumentException.ts +0 -9
  50. package/src/Exceptions/InvalidDestinationException.ts +0 -9
  51. package/src/Exceptions/MissingResourceException.ts +0 -9
  52. package/src/Nanosplash.ts +0 -484
  53. package/update-latest.sh +0 -21
package/src/style.sass CHANGED
@@ -1,68 +1,58 @@
1
- // Keyframe animations:
2
- @keyframes pulse
3
- from
4
- transform: scale(1)
5
- to
6
- transform: scale(1.1)
1
+ $z-index-regular: 1
2
+ $z-index-fullscreen: 2
3
+ $bg-color: rgba(White, 0.8)
7
4
 
8
- @keyframes spin
9
- from
10
- transform: rotate(0deg)
11
- to
12
- transform: rotate(360deg)
5
+ %blur
6
+ overflow: hidden
7
+ filter: blur(5px)
13
8
 
14
- .nanosplash-container
15
- // Base of container
16
- position: absolute
17
- flex-direction: column
18
- justify-content: center
19
- align-items: center
20
- z-index: 1
21
- border-radius: inherit
22
- overflow: inherit
9
+ .ns-wrapper
10
+ position: relative
23
11
 
24
- // When container is hidden
25
- &[hidden="true"]
26
- display: none
27
- // When container is visible
28
- &:not([hidden="true"])
29
- display: flex
12
+ .ns-fs
13
+ top: 0
14
+ left: 0
15
+ position: fixed
16
+ min-width: 100%
17
+ min-height: 100vh
18
+ z-index: $z-index-fullscreen
30
19
 
31
- // Standardized blur modes:
32
- &[data-blur="none"]:not([hidden="true"]) ~ *
33
- filter: blur(0)
34
- &[data-blur="light"]:not([hidden="true"]) ~ *
35
- filter: blur(2px)
36
- &[data-blur="medium"]:not([hidden="true"]) ~ *
37
- filter: blur(4px)
38
- &[data-blur="heavy"]:not([hidden="true"]) ~ *
39
- filter: blur(10px)
20
+ // Fullscreen content blur
21
+ body .ns-fs ~ *, .ns-blur
22
+ @extend %blur
40
23
 
41
- // Loading text
42
- .nanosplash-text
43
- text-rendering: optimizeLegibility
44
- -moz-osx-font-smoothing: grayscale
45
- font-smoothing: antialiased
46
- -webkit-font-smoothing: antialiased
47
- text-shadow: 0 0 2px rgba(0, 0, 0, 0.2)
48
-
49
- // Splash image
50
- img.nanosplash-img
51
- margin-bottom: 40px
24
+ .ns-window
25
+ top: 0
26
+ left: 0
27
+ width: 100%
28
+ height: 100%
29
+ display: flex
30
+ position: absolute
31
+ align-items: center
32
+ justify-content: center
33
+ z-index: $z-index-regular
34
+ background-color: $bg-color
52
35
 
53
- // Standardized splash image animations:
54
- &[data-splash-animation="pulse"] > img
55
- animation-name: pulse
56
- animation-duration: 300ms
57
- animation-direction: alternate
58
- animation-iteration-count: infinite
59
- &[data-splash-animation="spin"] > img
60
- animation-name: spin
61
- animation-duration: 700ms
62
- animation-iteration-count: infinite
63
- animation-timing-function: linear
36
+ .ns-img
37
+ max-width: 9rem
38
+ max-height: 9rem
39
+ margin-bottom: 1rem
64
40
 
65
- // Style exception when container is the direct child of body
66
- body > &:not([hidden="true"])
67
- height: 100vh
68
- width: 100%
41
+ .ns-text
42
+ color: #333
43
+ display: flex
44
+ text-align: center
45
+ &::after
46
+ margin-left: 0.25em
47
+ content: '\00a0\00a0\00a0'
48
+ animation: anim 1s infinite
49
+
50
+ @keyframes anim
51
+ 0%
52
+ content: '\00a0\00a0\00a0'
53
+ 30%
54
+ content: '.\00a0\00a0'
55
+ 60%
56
+ content: '..\00a0'
57
+ 90%
58
+ content: '...'
package/src/types.d.ts CHANGED
@@ -1,205 +1,50 @@
1
- declare module 'nanosplash' {
2
- /**
3
- * Nanosplash
4
- *
5
- * @author Isak K. Hauge
6
- */
7
- class Nanosplash {
8
- /**
9
- * Constructor
10
- *
11
- * @public
12
- * @constructor
13
- * @param {Config | undefined} config The configuration object.
14
- *
15
- * @example
16
- * ```js
17
- * // Instantiatie without config object.
18
- * new Nanosplash()
19
- * ```
20
- *
21
- * @example
22
- * ```js
23
- * // Instantiate with config object.
24
- * new Nanosplash(config)
25
- * ```
26
- */
27
- constructor(config?: Config)
28
-
29
- /**
30
- * Configure
31
- *
32
- * @param {Config} config The config object.
33
- * @return {Nanosplash} The updated instance.
34
- *
35
- * @description Mutates the existing configuration and returns the updated
36
- * instance.
37
- *
38
- * @example
39
- * ```js
40
- * nanosplash.configure(config)
41
- * ```
42
- *
43
- * @example
44
- * ```js
45
- * window.loading.configure(config).show(text)
46
- * ```
47
- */
48
- configure(config: Config): Nanosplash
49
-
50
- /**
51
- * Show
52
- *
53
- * @param {string | undefined} text The text that will be shown in the
54
- * loading screen. If undefined, Nanosplash will use the default text.
55
- * @return {DisplayController} An object with a function that controls the
56
- * visibility and destination of the loading screen.
57
- *
58
- * @description Shows the loading screen. Invoking the inside function will
59
- * display the loading screen within the constraints of the defined
60
- * destination.
61
- *
62
- * Basic usage.
63
- * @example
64
- * ```js
65
- * // Basic usage.
66
- * loading.show(text)
67
- * ```
68
- *
69
- * Display Nanosplash inside other DOM elements.
70
- * @example
71
- * ```js
72
- * // Show loading screen within another element using CSS selector.
73
- * loading.show(text).inside('#my-element')
74
- * // Use DOM element reference.
75
- * loading.show(text).inside(document.getElementById(id))
76
- * // Use function that returns a DOM element reference.
77
- * loading.show(text).inside(() => getDomReference())
78
- * ```
79
- *
80
- * Display Nanosplash while an asynchronous task is resolving.
81
- * @example
82
- * ```js
83
- * // Define an asynchronous task.
84
- * const task = async () => await getDataFromApi()
85
- * // Show loading screen while the task is running.
86
- * loading.show(text).during(task)
87
- * loading.show(text).inside('#my-element').during(task)
88
- * ```
89
- */
90
- show(text?: string): DisplayController
91
-
92
- /**
93
- * Hide
94
- *
95
- * @description Hides the loading screen and moves to its default destination.
96
- * If no custom default destination is defined, it will move to the document
97
- * body.
98
- *
99
- * @example
100
- * ```js
101
- * // Basic usage
102
- * loading.hide()
103
- * // Use with async functions
104
- * loading.show('Loading ...')
105
- * await fetchStuffFromApi()
106
- * loading.hide()
107
- * ```
108
- */
109
- hide(): void
110
-
111
- /**
112
- * Install
113
- *
114
- * @description Assigns itself to the Window object and sets essential event
115
- * listeners that responds to changes in the browser. The instance is
116
- * globally accessible through the property "loading".
117
- *
118
- * @example
119
- * ```js
120
- * // Install
121
- * (new Nanosplash()).install()
122
- *
123
- * // Access the instance globally
124
- * loading.show('Some text')
125
- * ```
126
- */
127
- public install(): void
128
- }
129
-
130
- type SplashAnimation = 'none' | 'pulse' | 'spin'
131
-
132
- type DefaultOptions = {
133
- destination?: Destination
134
- text?: string
135
- }
136
-
137
- type TextOptions = {
138
- family?: string
139
- weight?: string
140
- color?: string
141
- size?: string
142
- }
143
-
144
- type SplashOptions = {
145
- src?: string
146
- width?: string
147
- height?: string
148
- animation?: SplashAnimation
149
- }
150
-
151
- type BlurMode = 'none' | 'light' | 'medium' | 'heavy'
1
+ import {Nanosplash} from "./Core/Nanosplash";
2
+ import {ShowInterface} from "./Interfaces/ShowInterface";
3
+ import {InsideInterface} from "./Interfaces/InsideInterface";
4
+ import {SplashInstance} from "./Core/SplashInstance";
5
+ import {ContextualAPIInterface} from "./Interfaces/ContextualAPIInterface";
152
6
 
153
- type BackgroundOptions = {
154
- color?: string
155
- blur?: BlurMode
156
- }
157
-
158
- type Destination = Node | Element | DestinationCallback | string
159
-
160
- type DestinationCallback = () => Element
161
-
162
- type Config = {
163
- default?: DefaultOptions
164
- text?: TextOptions
165
- splash?: SplashOptions
166
- background?: BackgroundOptions
167
- }
168
-
169
- type TargetNodeController<T> = (target: T, asFirstChild?: boolean) => void
170
- type TargetNodeObject<T> = {
171
- [key: string]: TargetNodeController<T>
172
- }
173
- type TaskController<T> = (task: Promise<T>) => Promise<void>
174
-
175
- type DisplayController = {
176
- during: (task: Promise<any>) => Promise<void>
177
- inside: (destination: Destination) => {
178
- during: (task: Promise<any>) => Promise<void>
179
- }
180
- }
181
-
182
- /**
183
- * @internal
184
- */
185
- type MakeOptions = {
186
- id?: string
187
- className?: string
188
- attributes?: { key: string; value: string | null }[]
189
- eventListeners?: {
190
- event: keyof HTMLElementEventMap
191
- handler: EventListener
192
- }[]
193
- content?: Node | Element | HTMLElement | string
7
+ declare global {
8
+ interface Window {
9
+ ns: Nanosplash
194
10
  }
11
+ }
195
12
 
196
- /**
197
- * @internal
198
- */
199
- type HTMLElementTag = keyof HTMLElementTagNameMap
13
+ type Destination = Node | string
14
+ type SplashJob = [Promise<any>, string]
15
+
16
+ /**
17
+ * @internal
18
+ */
19
+ export type HTMLElementTag = keyof HTMLElementTagNameMap
20
+
21
+ /**
22
+ * @internal
23
+ */
24
+ type CSSProperty = keyof CSSStyleDeclaration
25
+
26
+ type ShowFunction = (text: string) => ContextualAPIInterface
27
+ type ProgressFunction = (...[]: SplashJob[]) => ContextualAPIInterface
28
+ type WhileFunction = (asyncTask: Promise<any>) => ShowInterface
29
+ type StrategyObject = {
30
+ show: ShowFunction,
31
+ progress: ProgressFunction,
32
+ while: WhileFunction
33
+ }
34
+ type ImgFunction = (src: string) => StrategyObject
35
+ type InsideFunction = (selector: string) => ContextualAPIInterface
36
+ type ContextualAPIObject = {
37
+ getId: () => string,
38
+ inside?: InsideFunction,
39
+ remove: () => void
40
+ moveTo: (selector: string) => void,
41
+ getText: () => string,
42
+ setText: (text: string) => SplashInstance,
43
+ getImgSrc: () => string | undefined,
44
+ setImgSrc: (src?: string) => SplashInstance
45
+ }
200
46
 
201
- /**
202
- * @internal
203
- */
204
- type CSSProperty = keyof CSSStyleDeclaration
47
+ declare module 'nanosplash' {
48
+ class Nanosplash {}
49
+ class SplashInstance {}
205
50
  }
@@ -0,0 +1,70 @@
1
+ import {addClass, get, mk, move, setAttr} from "./dom";
2
+
3
+ const resetDOM = () => document.body.innerHTML = ''
4
+
5
+ test('Single DOM get function', () => {
6
+ const element = document.createElement('div')
7
+ element.id = 'a'
8
+ element.classList.add('b')
9
+ element.setAttribute('data-ref', 'c')
10
+ document.body.append(element)
11
+
12
+ const selector = 'div#a.b[data-ref="c"]'
13
+ const refElement = get<HTMLDivElement>(selector)
14
+
15
+ expect(refElement?.outerHTML).toBe(element.outerHTML)
16
+
17
+ resetDOM()
18
+ })
19
+
20
+ test('Move Element from origin to destination', () => {
21
+ const html = `
22
+ <div id="main">
23
+ <div id="a">
24
+ <div id="b">
25
+ <div id="c">
26
+ <div id="first"></div>
27
+ </div>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ `
32
+ document.body.innerHTML = html
33
+
34
+ const main = get('#main') as HTMLDivElement
35
+ const first = get('#first') as HTMLDivElement
36
+ const b = get('#b') as HTMLDivElement
37
+ const c = get('#c') as HTMLDivElement
38
+
39
+ move(b, main)
40
+ move(c, main)
41
+ move(first, main, true)
42
+
43
+ const ids = Array.from(main.children).map((v => v.id))
44
+
45
+ expect(ids.join(',')).toBe('first,a,b,c')
46
+
47
+ resetDOM()
48
+ })
49
+
50
+ test('Make HTML Element', () => {
51
+ document.body.appendChild(mk('span'))
52
+ const span = document.body.children.item(0) as Node
53
+ expect(span instanceof HTMLSpanElement).toBe(true)
54
+ resetDOM()
55
+ })
56
+
57
+ test('Add CSS classes', () => {
58
+ const div = mk('div')
59
+ addClass(div, 'ns-1', 'ns-2', 'ns-3')
60
+ expect(div.classList.toString()).toBe('ns-1 ns-2 ns-3')
61
+ resetDOM()
62
+ })
63
+
64
+ test('Set Node attribute', () => {
65
+ const div = mk('div')
66
+ const attr = {name: 'data-test', value: 'success'}
67
+ setAttr(div, attr.name, attr.value)
68
+ expect(div.getAttribute(attr.name)).toBe(attr.value)
69
+ resetDOM()
70
+ })