@zuzjs/ui 0.2.4 → 0.2.6

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 (67) hide show
  1. package/README.md +1 -0
  2. package/dist/index.js +214 -15
  3. package/package.json +4 -2
  4. package/src/actions/addForm.tsx +0 -0
  5. package/src/actions/index.tsx +29 -0
  6. package/src/actions/redo.tsx +1 -0
  7. package/src/actions/reset.tsx +1 -0
  8. package/src/actions/undo.tsx +1 -0
  9. package/src/comps/app.tsx +34 -0
  10. package/src/comps/box.tsx +23 -0
  11. package/src/comps/button.tsx +45 -0
  12. package/src/comps/checkbox.tsx +74 -0
  13. package/src/comps/component.tsx +32 -0
  14. package/src/comps/contextmenu.tsx +43 -0
  15. package/src/comps/cover.tsx +34 -0
  16. package/src/comps/form.tsx +89 -0
  17. package/src/comps/heading.tsx +31 -0
  18. package/src/comps/icon.tsx +36 -0
  19. package/src/comps/image.tsx +26 -0
  20. package/src/comps/input.tsx +80 -0
  21. package/src/comps/masonry.tsx +192 -0
  22. package/src/comps/placeholder.tsx +58 -0
  23. package/src/comps/root.tsx +32 -0
  24. package/src/comps/select.tsx +63 -0
  25. package/src/comps/spacer.tsx +20 -0
  26. package/src/comps/spinner.tsx +36 -0
  27. package/src/comps/text.tsx +27 -0
  28. package/src/comps/toaster.tsx +115 -0
  29. package/src/comps/tweet.tsx +48 -0
  30. package/src/context/AppContext.tsx +3 -0
  31. package/src/context/AppProvider.tsx +101 -0
  32. package/src/context/_AppProvider.tsx +116 -0
  33. package/src/context/combineReducers.tsx +47 -0
  34. package/src/context/combineState.tsx +14 -0
  35. package/src/context/createSlice.tsx +40 -0
  36. package/src/context/index.tsx +6 -0
  37. package/src/context/reduceReducers.tsx +6 -0
  38. package/src/context/store/appbase.tsx +19 -0
  39. package/src/context/store/theme.tsx +53 -0
  40. package/src/core/defaultTheme.ts +89 -0
  41. package/src/core/extractCurrentDesignState.tsx +0 -0
  42. package/src/core/index.ts +285 -0
  43. package/src/core/router.ts +86 -0
  44. package/src/core/styles.ts +361 -0
  45. package/src/hooks/index.tsx +8 -0
  46. package/src/hooks/useAppReducer.tsx +40 -0
  47. package/src/hooks/useChooseEffect.tsx +6 -0
  48. package/src/hooks/useDevice.tsx +164 -0
  49. package/src/hooks/useDispatch.tsx +37 -0
  50. package/src/hooks/useImage.tsx +58 -0
  51. package/src/hooks/useResizeObserver.tsx +84 -0
  52. package/src/hooks/useRouter.tsx +45 -0
  53. package/src/hooks/useSelector.tsx +9 -0
  54. package/src/hooks/useStore.tsx +27 -0
  55. package/src/hooks/useTheme.tsx +9 -0
  56. package/src/hooks/useToast.tsx +11 -0
  57. package/src/index.tsx +33 -0
  58. package/src/kit/Builder.tsx +18 -0
  59. package/src/kit/Component.tsx +32 -0
  60. package/src/kit/Header.tsx +21 -0
  61. package/src/redux/slices/app.js +26 -0
  62. package/src/redux/slices/form.js +46 -0
  63. package/src/redux/store.js +33 -0
  64. package/src/scss/constants.scss +4 -0
  65. package/src/scss/mixins.scss +3 -0
  66. package/src/scss/props.scss +60 -0
  67. package/src/scss/style.scss +106 -0
@@ -0,0 +1,361 @@
1
+ const cssProps : { [key: string] : any } = {
2
+ "ac": "align-content",
3
+ "alignContent": "align-content",
4
+
5
+ "aic": "aic",
6
+ "ai": "align-items",
7
+ "alignItems": "align-items",
8
+
9
+ "ass": "ass",
10
+ "asc": "asc",
11
+ "ase": "ase",
12
+ "alignSelf": "align-self",
13
+ "all": "all",
14
+ "animation": "animation",
15
+ "animationDelay": "animation-delay",
16
+ "animationDirection": "animation-direction",
17
+ "animationDuration": "animation-duration",
18
+ "animationFillMode": "animation-fill-mode",
19
+ "animationIterationCount": "animation-iteration-count",
20
+ "animationName": "animation-name",
21
+ "animationPlayState": "animation-play-state",
22
+ "animationTimingFunction": "animation-timing-function",
23
+ "backfaceVisibility": "backface-visibility",
24
+ "backgroundAttachment": "background-attachment",
25
+ "backgroundBlendMode": "background-blend-mode",
26
+ "backgroundClip": "background-clip",
27
+
28
+ "bg": "background",
29
+ "background": "background",
30
+ "bgc": "background-color",
31
+ "bgColor": "background-color",
32
+ "backgroundColor": "background-color",
33
+
34
+ "backgroundImage": "background-image",
35
+ "backgroundOrigin": "background-origin",
36
+ "backgroundPosition": "background-position",
37
+ "backgroundRepeat": "background-repeat",
38
+ "backgroundSize": "background-size",
39
+ "border": "border",
40
+ "borderBottom": "border-bottom",
41
+ "borderBottomColor": "border-bottom-color",
42
+ "borderBottomStyle": "border-bottom-style",
43
+ "borderBottomWidth": "border-bottom-width",
44
+ "borderCollapse": "border-collapse",
45
+ "borderColor": "border-color",
46
+ "borderImage": "border-image",
47
+ "borderImageOutset": "border-image-outset",
48
+ "borderImageRepeat": "border-image-repeat",
49
+ "borderImageSlice": "border-image-slice",
50
+ "borderImageSource": "border-image-source",
51
+ "borderImageWidth": "border-image-width",
52
+ "borderLeft": "border-left",
53
+ "borderLeftColor": "border-left-color",
54
+ "borderLeftStyle": "border-left-style",
55
+ "borderLeftWidth": "border-left-width",
56
+
57
+ //Radius
58
+ "r": "border-radius",
59
+ "br": "border-radius",
60
+ "borderRadius": "border-radius",
61
+ "brtl": "border-top-left-radius",
62
+ "borderTopLeftRadius": "border-top-left-radius",
63
+ "brtr": "border-top-right-radius",
64
+ "borderTopRightRadius": "border-top-right-radius",
65
+ "brbl": "border-bottom-left-radius",
66
+ "borderBottomLeftRadius": "border-bottom-left-radius",
67
+ "brbr": "border-bottom-right-radius",
68
+ "borderBottomRightRadius": "border-bottom-right-radius",
69
+
70
+ "borderRight": "border-right",
71
+ "borderRightColor": "border-right-color",
72
+ "borderRightStyle": "border-right-style",
73
+ "borderRightWidth": "border-right-width",
74
+ "borderSpacing": "border-spacing",
75
+ "borderStyle": "border-style",
76
+ "borderTop": "border-top",
77
+ "borderTopColor": "border-top-color",
78
+
79
+ "borderTopStyle": "border-top-style",
80
+ "borderTopWidth": "border-top-width",
81
+ "borderWidth": "border-width",
82
+ "bottom": "bottom",
83
+ "boxDecorationBreak": "box-decoration-break",
84
+ "boxShadow": "box-shadow",
85
+ "boxSizing": "box-sizing",
86
+ "captionSide": "caption-side",
87
+ "caretColor": "caret-color",
88
+ "@charset": "@charset",
89
+ "clear": "clear",
90
+ "clip": "clip",
91
+ "clipPath": "clip-path",
92
+ "color": "color",
93
+ "columnCount": "column-count",
94
+ "columnFill": "column-fill",
95
+ "columnGap": "column-gap",
96
+ "colGap": "column-gap",
97
+ "columnRule": "column-rule",
98
+ "columnRuleColor": "column-rule-color",
99
+ "columnRuleStyle": "column-rule-style",
100
+ "columnRuleWidth": "column-rule-width",
101
+ "columnSpan": "column-span",
102
+ "columnWidth": "column-width",
103
+ "colW": "column-width",
104
+ "columns": "columns",
105
+ "content": "content",
106
+ "counterIncrement": "counter-increment",
107
+ "counterReset": "counter-reset",
108
+ "cursor": "cursor",
109
+ "pointer": "pointer",
110
+ "direction": "direction",
111
+ "display": "display",
112
+ "emptyCells": "empty-cells",
113
+ "filter": "filter",
114
+ "flex": "flex",
115
+ "flexBasis": "flex-basis",
116
+ "dir": "flex-direction",
117
+ "flexDirection": "flex-direction",
118
+ "flexFlow": "flex-flow",
119
+ "flexGrow": "flex-grow",
120
+ "flexShrink": "flex-shrink",
121
+ "flexWrap": "flex-wrap",
122
+ "float": "float",
123
+ "font": "font",
124
+ "fontFamily": "font-family",
125
+ "fontKerning": "font-kerning",
126
+ "size": "font-size",
127
+ "fontSize": "font-size",
128
+ "fontSizeAdjust": "font-size-adjust",
129
+ "fontStretch": "font-stretch",
130
+ "fontStyle": "font-style",
131
+ "fontVariant": "font-variant",
132
+ "bold": "bold",
133
+ "fontWeight": "font-weight",
134
+ "gap" : "gap",
135
+ "grid": "grid",
136
+ "gridArea": "grid-area",
137
+ "gridAutoColumns": "grid-auto-columns",
138
+ "gridAutoFlow": "grid-auto-flow",
139
+ "gridAutoRows": "grid-auto-rows",
140
+ "gridColumn": "grid-column",
141
+ "gridColumnEnd": "grid-column-end",
142
+ "gridColumnGap": "grid-column-gap",
143
+ "gridColumnStart": "grid-column-start",
144
+ "gridGap": "grid-gap",
145
+ "gridRow": "grid-row",
146
+ "gridRowEnd": "grid-row-end",
147
+ "gridRowGap": "grid-row-gap",
148
+ "gridRowStart": "grid-row-start",
149
+ "gridTemplate": "grid-template",
150
+ "gridTemplateAreas": "grid-template-areas",
151
+ "gridTemplateColumns": "grid-template-columns",
152
+ "gridTemplateRows": "grid-template-rows",
153
+ "hangingPunctuation": "hanging-punctuation",
154
+ "hyphens": "hyphens",
155
+ "isolation": "isolation",
156
+ "jcc": "jcc",
157
+ "jcs": "jcs",
158
+ "jce": "jce",
159
+ "jc": "justify-content",
160
+ "justifyContent": "justify-content",
161
+ "left": "left",
162
+ "letterSpacing": "letter-spacing",
163
+ "lineHeight": "line-height",
164
+ "listStyle": "list-style",
165
+ "listStyleImage": "list-style-image",
166
+ "listStylePosition": "list-style-position",
167
+ "listStyleType": "list-style-type",
168
+
169
+ //Margin
170
+ "m": "margin",
171
+ "margin": "margin",
172
+ "mb": "margin-bottom",
173
+ "marginBottom": "margin-bottom",
174
+ "ml": "margin-left",
175
+ "marginLeft": "margin-left",
176
+ "mr": "margin-right",
177
+ "marginRight": "margin-right",
178
+ "mt": "margin-top",
179
+ "marginTop": "margin-top",
180
+
181
+
182
+ //Height
183
+ "h": "height",
184
+ "height": "height",
185
+ "minH": "min-height",
186
+ "minHeight": "min-height",
187
+ "maxH": "max-height",
188
+ "maxHeight": "max-height",
189
+
190
+ //Width
191
+ "w": "width",
192
+ "width": "width",
193
+ "minW": "min-width",
194
+ "minWidth": "min-width",
195
+ "maxW": "max-width",
196
+ "maxWidth": "max-width",
197
+
198
+ "mixBlendMode": "mix-blend-mode",
199
+ "objectFit": "object-fit",
200
+ "objectPosition": "object-position",
201
+ "opacity": "opacity",
202
+ "order": "order",
203
+ "outline": "outline",
204
+ "outlineColor": "outline-color",
205
+ "outlineOffset": "outline-offset",
206
+ "outlineStyle": "outline-style",
207
+ "outlineWidth": "outline-width",
208
+ "overflow": "overflow",
209
+ "overflowX": "overflow-x",
210
+ "overflowY": "overflow-y",
211
+
212
+
213
+ "p": "padding",
214
+ "padding": "padding",
215
+ "pb": "padding-bottom",
216
+ "paddingBottom": "padding-bottom",
217
+ "pl": "padding-left",
218
+ "paddingLeft": "padding-left",
219
+ "pr": "padding-right",
220
+ "paddingRight": "padding-right",
221
+ "pt": "padding-top",
222
+ "paddingTop": "padding-top",
223
+
224
+ "pageBreakAfter": "page-break-after",
225
+ "pageBreakBefore": "page-break-before",
226
+ "pageBreakInside": "page-break-inside",
227
+ "perspective": "perspective",
228
+ "perspectiveOrigin": "perspective-origin",
229
+ "pointerEvents": "pointer-events",
230
+
231
+ "rel":"rel",
232
+ "abs":"abs",
233
+ "fixed":"fixed",
234
+ "sticky":"sticky",
235
+ "pos": "position",
236
+ "position": "position",
237
+
238
+ "quotes": "quotes",
239
+ "resize": "resize",
240
+ "right": "right",
241
+ "scrollBehavior": "scroll-behavior",
242
+ "tabSize": "tab-size",
243
+ "tableLayout": "table-layout",
244
+
245
+ "align" : "text-align",
246
+ "textAlign": "text-align",
247
+ "textAlignLast": "text-align-last",
248
+
249
+ "tdh": "tdh", //text-decoration: underline on hover
250
+ "td": "text-decoration",
251
+ "textDecoration": "text-decoration",
252
+ "textDecorationColor": "text-decoration-color",
253
+ "textDecorationLine": "text-decoration-line",
254
+ "textDecorationStyle": "text-decoration-style",
255
+ "textIndent": "text-indent",
256
+ "textJustify": "text-justify",
257
+ "textOverflow": "text-overflow",
258
+ "textShadow": "text-shadow",
259
+ "textTransform": "text-transform",
260
+ "top": "top",
261
+
262
+ "transform": "transform",
263
+ "transform(2D)": "transform(2D)",
264
+ "transformOrigin(twoValue syntax)": "transform-origin(two-value syntax)",
265
+ "transformStyle": "transform-style",
266
+ "transition": "transition",
267
+ "transitionDelay": "transition-delay",
268
+ "transitionDuration": "transition-duration",
269
+ "transitionProperty": "transition-property",
270
+ "transitionTimingFunction": "transition-timing-function",
271
+ "unicodeBidi": "unicode-bidi",
272
+ "userSelect": "user-select",
273
+ "verticalAlign": "vertical-align",
274
+ "visibility": "visibility",
275
+ "weight" : "flex",
276
+ "whiteSpace": "white-space",
277
+ "ws": "white-space",
278
+ "wordBreak": "word-break",
279
+ "wordSpacing": "word-spacing",
280
+ "wrap": "wrap",
281
+ "wordWrap": "word-wrap",
282
+ "writingMode": "writing-mode",
283
+ "zIndex": "z-index",
284
+ "backdropFilter": "backdrop-filter",
285
+ "bgFilter": "backdrop-filter",
286
+
287
+ //Custom
288
+ "anim" : "anim",
289
+ "fill" : "fill",
290
+ "abc" : "abc",
291
+ "fb" : "fb",
292
+ "ph" : "ph",
293
+ "pv" : "pv",
294
+ "mv" : "mv",
295
+ "mh" : "mh"
296
+ }
297
+
298
+ const cssPropsVals : { [key: string] : any } = {
299
+ //Colors
300
+ "primary" : 'var(--primary-color)',
301
+ "c" : "center",
302
+ //Flex Directions
303
+ "cols" : "column",
304
+ "colsr" : "column-reverse",
305
+ "rows" : "row",
306
+ "rowsr" : "row-reverse",
307
+ //Positions
308
+ "rel" : "relative",
309
+ "abs" : "absolute",
310
+ }
311
+
312
+ const cssPropsDirect : { [key : string] : any } = {
313
+ 'rel' : 'position: relative;',
314
+ 'fixed' : 'position: fixed;',
315
+ 'abs' : 'position: absolute;',
316
+ 'sticky' : 'position: sticky;',
317
+ 'flex' : 'display: flex;',
318
+ 'fwrap' : 'flex-wrap: wrap;',
319
+ 'aic' : 'align-items: center;',
320
+ 'ass' : 'align-self: flex-start;',
321
+ 'asc' : 'align-self: center;',
322
+ 'ase' : 'align-self: flex-end;',
323
+ 'jcc' : 'justify-content: center;',
324
+ 'jcs' : 'justify-content: flex-start;',
325
+ 'jce' : 'justify-content: flex-end;',
326
+ 'grid' : 'display: grid;',
327
+ 'fill' : 'top: 0px;left: 0px;right: 0px;bottom: 0px;',
328
+ 'abc' : 'top: 50%;left: 50%;transform: translate(-50%, -50%);',
329
+ 'block' : 'display: block;',
330
+ 'bold' : "font-weight: bold;",
331
+ 'wrap' : "word-wrap: break-word;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width: 99%;",
332
+ 'pointer' : "cursor: pointer;",
333
+ 'fb' : 'font-family: var(--primary-font-bold);',
334
+ 'ph' : 'padding-left: __VALUE__;padding-right: __VALUE__;',
335
+ 'pv' : 'padding-bottom: __VALUE__;padding-top: __VALUE__;',
336
+ 'mv' : 'margin-bottom: __VALUE__;margin-top: __VALUE__;',
337
+ 'mh' : 'margin-left: __VALUE__;margin-right: __VALUE__;',
338
+ 'anim' : 'transition:all __VALUE__s linear 0s;'
339
+ }
340
+
341
+ const cssPropsIgnore : string[] = [
342
+ 'weight', `opacity`
343
+ ]
344
+
345
+ const _cssColors : string[] = [ `white`, `black`, `gray`, `red`, `orange`, `yellow`, `green`, `teal`, `blue`, `cyan`, `purple`, `pink`, `linkedin`, `facebook`, `messenger`, `whatsapp`, `twitter`, `telegram` ]
346
+ const _cssColorsRange : string[] = [ `50`, `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900` ]
347
+ let cssColors : string[] = []
348
+
349
+ if(cssColors.length == 0){
350
+ _cssColors.map(c => {
351
+ _cssColorsRange.map(r => cssColors.push(`${c}.${r}`));
352
+ });
353
+ }
354
+
355
+ export {
356
+ cssPropsDirect,
357
+ cssProps,
358
+ cssPropsVals,
359
+ cssPropsIgnore,
360
+ cssColors
361
+ }
@@ -0,0 +1,8 @@
1
+ export { default as useTheme } from './useTheme'
2
+ export { default as useImage } from './useImage'
3
+ export { default as useStore } from './useStore'
4
+ export { default as useDispatch } from './useDispatch'
5
+ export { default as useResizeObserver } from './useResizeObserver'
6
+ export { default as useDevice } from './useDevice'
7
+ export { default as useToast } from './useToast'
8
+ // export { default as useRouter } from './useRouter'
@@ -0,0 +1,40 @@
1
+ import { useReducer } from 'react'
2
+ import { UNDO, REDO, RESET } from '../actions'
3
+
4
+ const useAppReducer = (reducer, inititalState : Object, passedConfig = {}) => {
5
+
6
+ const initialStateWithUndoRedo = {
7
+ ...inititalState,
8
+ pastDesignStates: [],
9
+ futureDesignStates: [],
10
+ hasRedo: false,
11
+ hasUndo: false,
12
+ }
13
+
14
+ const undoRedoResetReducer = (state, action) => {
15
+
16
+ const newPresetState = reducer(state, action) || initialStateWithUndoRedo
17
+
18
+ if([UNDO,REDO,RESET].includes(action.type)){
19
+ return newPresetState;
20
+ }
21
+
22
+ if(newPresetState.isDesignState){
23
+
24
+ const newState = {
25
+
26
+ }
27
+
28
+ return newState;
29
+
30
+ }
31
+
32
+ return newPresetState;
33
+
34
+ }
35
+
36
+ return useReducer(undoRedoResetReducer, initialStateWithUndoRedo)
37
+
38
+ }
39
+
40
+ export default useAppReducer;
@@ -0,0 +1,6 @@
1
+ import { useEffect, useLayoutEffect } from 'react'
2
+
3
+ const useChooseEffect =
4
+ typeof window === 'undefined' ? useEffect : useLayoutEffect
5
+
6
+ export default useChooseEffect
@@ -0,0 +1,164 @@
1
+ import { useMemo, useState, useCallback, useDebugValue } from 'react'
2
+ import useChooseEffect from './useChooseEffect'
3
+
4
+ export type Config = {
5
+ readonly [key: string]: number
6
+ }
7
+
8
+ export type MediaQuery<C extends Config> = {
9
+ breakpoint: keyof C
10
+ maxWidth: number | null
11
+ minWidth: C[keyof C]
12
+ query: string
13
+ }
14
+
15
+ export type Breakpoint<C extends Config> = {
16
+ breakpoint: keyof C
17
+ maxWidth?: number | null
18
+ minWidth: C[keyof C]
19
+ }
20
+
21
+ const EMPTY_BREAKPOINT = {
22
+ breakpoint: undefined,
23
+ minWidth: undefined,
24
+ maxWidth: undefined,
25
+ } as const
26
+
27
+ type Return<C extends Config, D> = D extends undefined
28
+ ? Breakpoint<C> | typeof EMPTY_BREAKPOINT
29
+ : D extends keyof C
30
+ ? Breakpoint<C>
31
+ : never
32
+
33
+ const useDevice = <C extends Config, D extends keyof C | undefined>(
34
+ config: C,
35
+ defaultBreakpoint?: D,
36
+ hydrateInitial = true
37
+ ) : Return<C, D> => {
38
+
39
+ const buildQueries = (breakpoints: Config) : MediaQuery<Config>[] => {
40
+ const sorted = Object.keys(breakpoints).sort(
41
+ (a, b) => breakpoints[b] - breakpoints[a]
42
+ )
43
+
44
+ return sorted.map((breakpoint, index) => {
45
+ let query = ''
46
+ const minWidth = breakpoints[breakpoint]
47
+ const nextBreakpoint = sorted[index - 1] as string | undefined
48
+ const maxWidth = nextBreakpoint ? breakpoints[nextBreakpoint] : null
49
+
50
+ if (minWidth >= 0) {
51
+ query = `(min-width: ${minWidth}px)`
52
+ }
53
+
54
+ if (maxWidth !== null) {
55
+ if (query) {
56
+ query += ' and '
57
+ }
58
+ query += `(max-width: ${maxWidth - 1}px)`
59
+ }
60
+
61
+ const mediaQuery: MediaQuery<Config> = {
62
+ breakpoint,
63
+ maxWidth: maxWidth ? maxWidth - 1 : null,
64
+ minWidth,
65
+ query,
66
+ }
67
+
68
+ return mediaQuery
69
+
70
+ })
71
+
72
+ }
73
+
74
+ /** Memoize list of calculated media queries from config */
75
+ const mediaQueries = useMemo(() => buildQueries(config), [config])
76
+
77
+ /** Get initial breakpoint value */
78
+ const [currentBreakpoint, setCurrentBreakpoint] = useState<
79
+ Breakpoint<C> | typeof EMPTY_BREAKPOINT
80
+ >(() => {
81
+ /** Loop through all media queries */
82
+ for (const { query, ...breakpoint } of mediaQueries) {
83
+ /**
84
+ * If we're in the browser and there's no default value,
85
+ * try to match actual breakpoint. If the default value
86
+ * should not be hydrated, use the actual breakpoint.
87
+ */
88
+ if (
89
+ typeof window !== 'undefined' &&
90
+ !(defaultBreakpoint && hydrateInitial)
91
+ ) {
92
+ const mediaQuery = window.matchMedia(query)
93
+ if (mediaQuery.matches) {
94
+ return breakpoint as Breakpoint<C>
95
+ }
96
+ } else if (breakpoint.breakpoint === defaultBreakpoint) {
97
+ /** Otherwise, try to match default value */
98
+ return breakpoint as Breakpoint<C>
99
+ }
100
+ }
101
+
102
+ return EMPTY_BREAKPOINT
103
+ })
104
+
105
+ /** If there's a match, update the current breakpoint */
106
+ const updateBreakpoint = useCallback(
107
+ (
108
+ { matches }: MediaQueryList | MediaQueryListEvent,
109
+ breakpoint: Breakpoint<C>
110
+ ) => {
111
+ if (matches) {
112
+ setCurrentBreakpoint(breakpoint)
113
+ }
114
+ },
115
+ []
116
+ )
117
+
118
+ /** On changes to mediaQueries, subscribe to changes using window.matchMedia */
119
+ useChooseEffect(() => {
120
+ const unsubscribers = mediaQueries.map(({ query, ...breakpoint }) => {
121
+ const list = window.matchMedia(query)
122
+ updateBreakpoint(list, breakpoint as Breakpoint<C>)
123
+
124
+ const handleChange = (event: MediaQueryListEvent) => {
125
+ updateBreakpoint(event, breakpoint as Breakpoint<C>)
126
+ }
127
+
128
+ const supportsNewEventListeners =
129
+ 'addEventListener' in list && 'removeEventListener' in list
130
+
131
+ if (supportsNewEventListeners) {
132
+ list.addEventListener('change', handleChange)
133
+ } else {
134
+ ;(list as MediaQueryList).addListener(handleChange)
135
+ }
136
+
137
+ /** Map the unsubscribers array to a list of unsubscriber methods */
138
+ return () => {
139
+ if (supportsNewEventListeners) {
140
+ list.removeEventListener('change', handleChange)
141
+ } else {
142
+ ;(list as MediaQueryList).removeListener(handleChange)
143
+ }
144
+ }
145
+ })
146
+
147
+ /** Return a function that when called, will call all unsubscribers */
148
+ return () => unsubscribers.forEach((unsubscriber) => unsubscriber())
149
+ }, [mediaQueries, updateBreakpoint])
150
+
151
+ /** Print a nice debug value for React Devtools */
152
+ useDebugValue(currentBreakpoint, (c) =>
153
+ typeof c.breakpoint === 'string'
154
+ ? `${c.breakpoint} (${c.minWidth} ≤ x${
155
+ c.maxWidth ? ` < ${c.maxWidth + 1}` : ''
156
+ })`
157
+ : ''
158
+ )
159
+
160
+ return currentBreakpoint as Return<C, D>
161
+
162
+ }
163
+
164
+ export default useDevice;
@@ -0,0 +1,37 @@
1
+ import { useContext } from 'react'
2
+ import AppContext from '../context'
3
+
4
+ const useDispatch = (key? : string) => {
5
+
6
+ const state = useContext(AppContext)
7
+ const dispatch = state['dispatch'];
8
+
9
+ const prepareState = (prevState, nextState) => {
10
+ const nextKeys = Object.keys(nextState)
11
+ nextKeys.map(k => {
12
+ if(prevState[k] !== nextState[k]){
13
+ prevState[k] = nextState[k]
14
+ }
15
+ });
16
+ return {
17
+ ...prevState,
18
+ ...nextState
19
+ }
20
+ }
21
+
22
+ if(key){
23
+ return (payload = {}) => {
24
+
25
+ dispatch({
26
+ action: key,
27
+ payload: {
28
+ [key] : prepareState(state[key], payload)
29
+ }
30
+ });
31
+ }
32
+ }
33
+
34
+ return dispatch;
35
+ }
36
+
37
+ export default useDispatch
@@ -0,0 +1,58 @@
1
+ import React, { useRef, useLayoutEffect, useState } from 'react'
2
+
3
+ const useImage = (url, crossOrigin, referrerpolicy) => {
4
+
5
+ const statusRef = useRef('loading')
6
+ const imageRef = useRef<HTMLImageElement>();
7
+
8
+ const [_, setStateToken] = useState(0);
9
+
10
+ const oldUrl = useRef();
11
+ const oldCrossOrigin = useRef();
12
+ const oldReferrerPolicy = useRef();
13
+
14
+ if(oldUrl.current !== url || oldCrossOrigin.current !== crossOrigin || oldReferrerPolicy.current !== referrerpolicy){
15
+ statusRef.current = 'loading';
16
+ imageRef.current = undefined;
17
+ oldUrl.current = url;
18
+ oldCrossOrigin.current = crossOrigin;
19
+ oldReferrerPolicy.current = referrerpolicy;
20
+ }
21
+
22
+ useLayoutEffect(
23
+ function(){
24
+
25
+ if(!url) return;
26
+ var img = document.createElement('img');
27
+
28
+ function onload(){
29
+ statusRef.current = 'loaded';
30
+ imageRef.current = img;
31
+ setStateToken(Math.random());
32
+ }
33
+
34
+ function onerror(){
35
+ statusRef.current = 'failed';
36
+ imageRef.current = undefined;
37
+ setStateToken(Math.random());
38
+ }
39
+
40
+ img.addEventListener('load', onload);
41
+ img.addEventListener('error', onerror);
42
+ crossOrigin && (img.crossOrigin = crossOrigin);
43
+ referrerpolicy && (img.referrerPolicy = referrerpolicy);
44
+ img.src = url;
45
+
46
+ return function cleanup() {
47
+ img.removeEventListener('load', onload);
48
+ img.removeEventListener('error', onerror);
49
+ };
50
+
51
+ },
52
+ [url, crossOrigin, referrerpolicy]
53
+ );
54
+
55
+ return [imageRef.current, statusRef.current];
56
+ }
57
+
58
+ export default useImage;