nanosplash 2.2.2 → 2.3.0

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 (51) hide show
  1. package/.github/workflows/production.yml +57 -0
  2. package/.github/workflows/release.yml +61 -0
  3. package/README.md +33 -9
  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 +249 -285
  9. package/docs/index.html +54 -415
  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/types.html +1 -1
  19. package/index.html +51 -397
  20. package/jest.config.ts +194 -0
  21. package/package.json +71 -66
  22. package/src/Core/Nanosplash.ts +74 -0
  23. package/src/Core/SplashInstance.ts +154 -0
  24. package/src/Factory/NanosplashFactory.ts +73 -0
  25. package/src/Interfaces/ContextualAPIInterface.ts +8 -0
  26. package/src/Interfaces/IdentityInterface.ts +3 -0
  27. package/src/Interfaces/ImageInterface.ts +5 -0
  28. package/src/Interfaces/InsideInterface.ts +5 -0
  29. package/src/Interfaces/NanosplashInterface.ts +4 -0
  30. package/src/Interfaces/ProgressInterface.ts +5 -0
  31. package/src/Interfaces/ShowInterface.ts +5 -0
  32. package/src/Interfaces/WhileInterface.ts +5 -0
  33. package/src/main.ts +2 -6
  34. package/src/repositories/NanosplashRepository.ts +34 -57
  35. package/src/style.sass +36 -61
  36. package/src/types.d.ts +45 -197
  37. package/src/utilities/dom.spec.ts +70 -0
  38. package/src/utilities/dom.ts +17 -246
  39. package/update-all.sh +3 -0
  40. package/vite.iife.config.js +46 -18
  41. package/vite.mod.config.js +48 -12
  42. package/vite.site.config.js +0 -3
  43. package/dist/module/style.css +0 -1
  44. package/docs/typedoc/classes/Nanosplash.Nanosplash-1.html +0 -56
  45. package/docs/typedoc/classes/types.Nanosplash.html +0 -56
  46. package/docs/typedoc/modules/Nanosplash.html +0 -1
  47. package/src/Nanosplash.ts +0 -421
  48. package/src/exceptions/Exception.ts +0 -11
  49. package/src/exceptions/IllegalArgumentException.ts +0 -9
  50. package/src/exceptions/InvalidDestinationException.ts +0 -9
  51. package/update-latest.sh +0 -21
package/src/style.sass CHANGED
@@ -1,68 +1,43 @@
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
+ filter: blur(5px)
7
+ overflow: hidden
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
+ text-align: center
package/src/types.d.ts CHANGED
@@ -1,202 +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
- * // Access the instance globally
121
- * loading.show('Some text')
122
- * ```
123
- */
124
- public install(): void
125
- }
126
-
127
- type SplashAnimation = 'none' | 'pulse' | 'spin'
128
-
129
- type DefaultOptions = {
130
- destination?: Destination
131
- text?: string
132
- }
133
-
134
- type TextOptions = {
135
- family?: string
136
- weight?: string
137
- color?: string
138
- size?: string
139
- }
140
-
141
- type SplashOptions = {
142
- src?: string
143
- width?: string
144
- height?: string
145
- animation?: SplashAnimation
146
- }
147
-
148
- 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";
149
6
 
150
- type BackgroundOptions = {
151
- color?: string
152
- blur?: BlurMode
153
- }
154
-
155
- type Destination = Node | Element | DestinationCallback | string
156
-
157
- type DestinationCallback = () => Element
158
-
159
- type Config = {
160
- default?: DefaultOptions
161
- text?: TextOptions
162
- splash?: SplashOptions
163
- background?: BackgroundOptions
164
- }
165
-
166
- type TargetNodeController<T> = (target: T, asFirstChild?: boolean) => void
167
- type TargetNodeObject<T> = {
168
- [key: string]: TargetNodeController<T>
169
- }
170
- type TaskController<T> = (task: Promise<T>) => Promise<void>
171
-
172
- type DisplayController = {
173
- during: (task: Promise<any>) => Promise<void>
174
- inside: (destination: Destination) => {
175
- during: (task: Promise<any>) => Promise<void>
176
- }
177
- }
178
-
179
- /**
180
- * @internal
181
- */
182
- type MakeOptions = {
183
- id?: string
184
- className?: string
185
- attributes?: { key: string; value: string | null }[]
186
- eventListeners?: {
187
- event: keyof HTMLElementEventMap
188
- handler: EventListener
189
- }[]
190
- content?: Node | Element | HTMLElement | string
7
+ declare global {
8
+ interface Window {
9
+ ns: Nanosplash
191
10
  }
11
+ }
192
12
 
193
- /**
194
- * @internal
195
- */
196
- 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
+ }
197
46
 
198
- /**
199
- * @internal
200
- */
201
- type CSSProperty = keyof CSSStyleDeclaration
47
+ declare module 'nanosplash' {
48
+ class Nanosplash {}
49
+ class SplashInstance {}
202
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
+ })
@@ -1,255 +1,26 @@
1
- import {
2
- CSSProperty,
3
- HTMLElementTag,
4
- MakeOptions,
5
- TargetNodeObject,
6
- } from 'nanosplash'
1
+ import {HTMLElementTag} from "../types";
7
2
 
8
- /**
9
- * Ref (reference)
10
- *
11
- * @param {string} cssSelector
12
- * @return {Element | null}
13
- *
14
- * @description Returns the instance reference of whatever element in the DOM
15
- * that matches the CSS selector string.
16
- */
17
- export const ref = (cssSelector: string): Element | null =>
18
- document.querySelector(cssSelector)
19
-
20
- /**
21
- * Create
22
- *
23
- * @param {HTMLElementTag} tag Valid HTML element tag name
24
- * @param {MakeOptions} options Make options
25
- * @returns {HTMLElement}
26
- *
27
- * @description Creates any HTML element that corresponds with the given tag.
28
- * Additionally, if options are defined, it can mutate the element by adding
29
- * class names, attributes, and content.
30
- */
31
- export const create = (
32
- tag: HTMLElementTag,
33
- options?: MakeOptions
34
- ): HTMLElement => {
35
- const element = document.createElement(tag)
36
- if (options) {
37
- // Element ID
38
- element.id ||= options.id + ''
39
-
40
- // Element class names
41
- element.className ||= options.className + ''
42
-
43
- // Element attributes
44
- options.attributes
45
- ?.filter(v => v.value)
46
- .forEach(({ key, value }) => setAttribute(element, key, value as string))
47
-
48
- // Element content
49
- if (options.content) {
50
- if (typeof options.content === 'string') {
51
- element.innerText = options.content
52
- } else {
53
- element.append(options.content)
54
- }
55
- }
56
- }
57
- return element
58
- }
59
-
60
- /**
61
- * Display
62
- *
63
- * @param {HTMLElement} node The HTML element.
64
- * @param {boolean} show A boolean value that decides the node's visibility.
65
- */
66
- export const display = (node: HTMLElement, show: boolean): void => {
67
- node.hidden = !show
68
- if (show) {
69
- removeAttribute(node, 'hidden')
70
- } else {
71
- setAttribute(node, 'hidden', 'true')
72
- }
73
- }
74
-
75
- /**
76
- * Move
77
- *
78
- * @param {Node} node The node to append to another, as its child.
79
- * @returns An object with a target node controller function. Said function
80
- * will append the given node to a yet to be defined target node.
81
- *
82
- * @description This function will in turn append the node to another node.
83
- * If the child node already is a reference to another node in the
84
- * DOM, it will be moved to its new position by removing the current reference
85
- * before creating the new one.
86
- *
87
- * @example move(node).to(targetNode) // Regular append
88
- * @example mode(child).to(parent, true) // Append as first child
89
- */
90
- export const move = (node: Node): TargetNodeObject<Node> => ({
91
- /**
92
- * @param {Node} targetNode The node in which the new node shall reside.
93
- * @param {boolean} asFirstChild Whether or not the new node shall be the
94
- * first child of the target node.
95
- */
96
- to: (targetNode: Node, asFirstChild?: boolean): void => {
97
- const children = Array.from(targetNode.childNodes)
98
- const noChildren = children.length < 1
99
- if (noChildren || !asFirstChild) {
100
- targetNode.appendChild<Node>(node)
101
- return
102
- }
103
- const firstChild = children[0]
104
- targetNode.insertBefore(node, firstChild)
105
- },
106
- })
107
-
108
- /**
109
- * Fit Parent Dimensions
110
- *
111
- * @param {HTMLElement} node The HTML element of which style to change.
112
- *
113
- * @description Transforms the node's dimensions and document position in order
114
- * to match its parent node.
115
- */
116
- export const fitToParent = (node: HTMLElement): void => {
117
- const parent = node.parentNode as HTMLElement
118
- if (parent) {
119
- ;((domRect: DOMRect) => {
120
- parent.style.position = 'relative' // Set parent as relative
121
- const unit = 'px'
122
- const parentIsBody = parent === document.body
123
- let left, top, width, height
124
-
125
- // Set distance from left
126
- if (parentIsBody) {
127
- left = scrollX + unit
128
- } else {
129
- left = 0 + unit
130
- }
131
-
132
- // Set distance from top
133
- if (parentIsBody) {
134
- top = scrollY + unit
135
- } else {
136
- top = 0 + unit
137
- }
138
-
139
- // Set width from parent
140
- if (parentIsBody) {
141
- width = '100%'
142
- } else {
143
- width = domRect.width + unit
144
- }
145
-
146
- // Set height from parent
147
- if (parentIsBody) {
148
- height = '100vh'
149
- } else {
150
- height = domRect.height + unit
151
- }
152
-
153
- setStyle(parent, 'position', 'relative')
154
- setStyle(node, 'left', left)
155
- setStyle(node, 'top', top)
156
- setStyle(node, 'width', width)
157
- setStyle(node, 'height', height)
158
- })(parent.getBoundingClientRect())
159
- }
160
- }
161
-
162
- declare global {
163
- interface Window {
164
- attachEvent: Function
165
- }
166
- interface Node {
167
- attachEvent: Function
168
- }
3
+ export function get<T>(selector: string): HTMLElement | T | null {
4
+ return document.querySelector(selector) as HTMLElement | T | null
169
5
  }
170
6
 
171
- /**
172
- * Invoke On
173
- *
174
- * @param {Window | Node} dispatcher The node in which the given events
175
- * are captured.
176
- * @param {() => void} handler A function to be invoked when one of the given
177
- * events are captured.
178
- * @param {keyof WindowEventMap} events An array of event names.
179
- *
180
- * @example invokeOn(window, () => alert('Scroll'), ['scroll'])
181
- */
182
- export const invokeOn = (
183
- dispatcher: Window | Node,
184
- handler: () => void,
185
- events: Array<keyof WindowEventMap>
186
- ): void =>
187
- (([addEventListenerLegacy, addEventListener]) => {
188
- events.forEach(event => {
189
- if (addEventListenerLegacy) {
190
- addEventListenerLegacy(`on${event}`, handler)
191
- } else {
192
- addEventListener(event, handler, true)
193
- }
194
- })
195
- })([dispatcher.attachEvent, dispatcher.addEventListener])
196
-
197
- /**
198
- * Is Element or Node
199
- *
200
- * @param {any} value A value of any type.
201
- * @returns {boolean}
202
- */
203
- export const isElementOrNode = (value: any): boolean => {
204
- return value instanceof Element || value instanceof Node
7
+ export function move(source: Node, destination: Node, asFirstChild: boolean = false): void
8
+ {
9
+ if (source && destination) {
10
+ (destination.hasChildNodes() && asFirstChild)
11
+ ? destination.insertBefore(source, destination.firstChild)
12
+ : destination.appendChild(source)
13
+ }
205
14
  }
206
15
 
207
- /**
208
- * Is Function
209
- *
210
- * @param {any} value A value of any type.
211
- * @returns {boolean}
212
- */
213
- export const isFunction = (value: any): boolean => {
214
- return value && {}.toString.call(value) === '[object Function]'
215
- }
216
-
217
- /**
218
- * Set Style
219
- *
220
- * @param {HTMLElement} node An HTML element.
221
- * @param {CSSProperty} prop A CSS property.
222
- * @param {string} value A CSS value.
223
- *
224
- * @description Sets a CSS declaration on an HTML element.
225
- *
226
- * @example setStyle(divElement, 'color', '#FF0000')
227
- */
228
- export const setStyle = (
229
- node: HTMLElement,
230
- prop: CSSProperty,
231
- value: any
232
- ): void => {
233
- node.style[prop as any] = value
234
- }
16
+ export const mk = (tag: HTMLElementTag) => document.createElement(tag)
235
17
 
236
- /**
237
- * Set Attribute
238
- *
239
- * @param {Element} node An element.
240
- * @param {string} key The attribute name.
241
- * @param {string} value The attribute value.
242
- */
243
- export const setAttribute = (node: Element, key: string, value: string) => {
244
- node.setAttribute(key, value)
18
+ export function addClass(node: HTMLElement, ...classes: string[]): void
19
+ {
20
+ node.classList.add(...classes)
245
21
  }
246
22
 
247
- /**
248
- * Remove Attribute
249
- *
250
- * @param {Element} node An element.
251
- * @param {string} key The attribute name.
252
- */
253
- export const removeAttribute = (node: Element, key: string) => {
254
- node.removeAttribute(key)
23
+ export function setAttr(node: HTMLElement, attribute: string, value: string): void
24
+ {
25
+ node.setAttribute(attribute, value)
255
26
  }
package/update-all.sh ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bash
2
+ yarn remove @types/jest @types/jsdom autoprefixer cssnano jest jsdom jest-environment-jsdom postcss sass ts-jest ts-node typedoc typescript vite
3
+ yarn add -D @types/jest @types/jsdom autoprefixer cssnano jest jsdom jest-environment-jsdom postcss sass ts-jest ts-node typedoc typescript vite