@xyo-network/react-app-settings 2.26.37 → 2.26.38

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/dist/docs.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "fileName": "index.ts",
11
11
  "line": 1,
12
12
  "character": 0,
13
- "url": "https://github.com/XYOracleNetwork/sdk-xyo-react-js/blob/eeec410/packages/appsettings/src/index.ts#L1"
13
+ "url": "https://github.com/XYOracleNetwork/sdk-xyo-react-js/blob/c31a96d/packages/appsettings/src/index.ts#L1"
14
14
  }
15
15
  ]
16
16
  }
package/package.json CHANGED
@@ -16,7 +16,7 @@
16
16
  "@mui/material": "^5.9.2",
17
17
  "@xylabs/react-shared": "^2.14.10",
18
18
  "@xylabs/sdk-js": "^2.6.2",
19
- "@xyo-network/react-shared": "^2.26.37",
19
+ "@xyo-network/react-shared": "^2.26.38",
20
20
  "react": "^18.2.0",
21
21
  "tslib": "^2.4.0"
22
22
  },
@@ -75,5 +75,5 @@
75
75
  },
76
76
  "sideEffects": false,
77
77
  "types": "dist/esm/index.d.ts",
78
- "version": "2.26.37"
78
+ "version": "2.26.38"
79
79
  }
@@ -0,0 +1 @@
1
+ export type WebAppNavigationType = 'menu' | 'sidebar'
@@ -0,0 +1,19 @@
1
+ import DarkModeRoundedIcon from '@mui/icons-material/DarkModeRounded'
2
+ import LightModeRoundedIcon from '@mui/icons-material/LightModeRounded'
3
+ import { IconButton, IconButtonProps } from '@mui/material'
4
+
5
+ import { useAppSettings } from '../contexts'
6
+
7
+ export const DarkModeIconButton: React.FC<IconButtonProps> = (props) => {
8
+ const { darkMode, enableDarkMode } = useAppSettings()
9
+
10
+ const handleDarkModeChange = () => {
11
+ enableDarkMode?.(!darkMode)
12
+ }
13
+
14
+ return (
15
+ <IconButton onClick={handleDarkModeChange} {...props}>
16
+ {darkMode ? <DarkModeRoundedIcon /> : <LightModeRoundedIcon />}
17
+ </IconButton>
18
+ )
19
+ }
@@ -0,0 +1 @@
1
+ export * from './DarkModeIconButton'
@@ -0,0 +1,15 @@
1
+ import { createContext } from 'react'
2
+
3
+ import { WebAppNavigationType } from '../../WebAppNavigationType'
4
+ import { appSettingDefault } from './appSettingDefault'
5
+
6
+ export interface AppSettingsContextProps {
7
+ darkMode?: boolean
8
+ developerMode?: boolean
9
+ enableDarkMode?: (value: boolean) => void
10
+ enableDeveloperMode?: (value: boolean) => void
11
+ changeNavigationType?: (value: WebAppNavigationType) => void
12
+ navigationType?: WebAppNavigationType
13
+ }
14
+
15
+ export const AppSettingsContext = createContext<AppSettingsContextProps>(appSettingDefault())
@@ -0,0 +1,49 @@
1
+ import { WithChildren } from '@xylabs/react-shared'
2
+ import { ProviderProps, useState } from 'react'
3
+
4
+ import { WebAppNavigationType } from '../../WebAppNavigationType'
5
+ import { AppSettingsContext, AppSettingsContextProps } from './Context'
6
+ import { AppSettingsStorage } from './Storage'
7
+
8
+ export interface AppSettingsProviderProps<T extends AppSettingsContextProps = AppSettingsContextProps> extends ProviderProps<T> {
9
+ storage?: AppSettingsStorage
10
+ }
11
+
12
+ export const AppSettingsProvider: React.FC<WithChildren<AppSettingsProviderProps>> = ({ storage = new AppSettingsStorage(), value, children, ...props }) => {
13
+ const [developerMode, setDeveloperMode] = useState(storage.developerMode)
14
+ const [darkMode, setDarkMode] = useState(storage.darkMode)
15
+ const [navigationType, setNaviagtionType] = useState(storage.navigationType)
16
+
17
+ const enableDeveloperMode = (value: boolean) => {
18
+ storage.developerMode = value
19
+ setDeveloperMode(storage.developerMode)
20
+ }
21
+
22
+ const enableDarkMode = (value: boolean) => {
23
+ storage.darkMode = value
24
+ setDarkMode(storage.darkMode)
25
+ }
26
+
27
+ const changeNavigationType = (value: WebAppNavigationType) => {
28
+ storage.navigationType = value
29
+ setNaviagtionType(value)
30
+ }
31
+
32
+ return (
33
+ <AppSettingsContext.Provider
34
+ value={{
35
+ changeNavigationType,
36
+ darkMode,
37
+ developerMode,
38
+ enableDarkMode,
39
+ enableDeveloperMode,
40
+ navigationType,
41
+
42
+ ...value,
43
+ }}
44
+ {...props}
45
+ >
46
+ {children}
47
+ </AppSettingsContext.Provider>
48
+ )
49
+ }
@@ -0,0 +1,5 @@
1
+ export enum AppSettingSlug {
2
+ DarkMode = 'darkmode',
3
+ Developer = 'developer',
4
+ NavigationType = 'navgiationType',
5
+ }
@@ -0,0 +1,34 @@
1
+ import { WebAppNavigationType } from '../../WebAppNavigationType'
2
+ import { appSettingDefault } from './appSettingDefault'
3
+ import { AppSettingSlug } from './Slug'
4
+ import { AppSettingsStorageBase } from './StorageBase'
5
+
6
+ export class AppSettingsStorage extends AppSettingsStorageBase {
7
+ constructor(prefix = 'AppSettings', defaults?: Record<string, unknown>) {
8
+ super(prefix, { ...appSettingDefault(), ...defaults })
9
+ }
10
+
11
+ get darkMode() {
12
+ return this.getBoolean(AppSettingSlug.DarkMode)
13
+ }
14
+
15
+ set darkMode(value: boolean) {
16
+ this.setBoolean(AppSettingSlug.DarkMode, value)
17
+ }
18
+
19
+ get developerMode() {
20
+ return this.getBoolean(AppSettingSlug.Developer)
21
+ }
22
+
23
+ set developerMode(value: boolean) {
24
+ this.setBoolean(AppSettingSlug.Developer, value)
25
+ }
26
+
27
+ get navigationType() {
28
+ return this.getString(AppSettingSlug.NavigationType) as WebAppNavigationType
29
+ }
30
+
31
+ set navigationType(value: WebAppNavigationType) {
32
+ this.setString(AppSettingSlug.NavigationType, value)
33
+ }
34
+ }
@@ -0,0 +1,85 @@
1
+ import { assertEx } from '@xylabs/sdk-js'
2
+ import { assertDefinedEx } from '@xyo-network/react-shared'
3
+
4
+ export class AppSettingsStorageBase {
5
+ private prefix: string
6
+ private defaults: Record<string, unknown>
7
+ constructor(prefix = 'AppSettings', defaults?: Record<string, unknown>) {
8
+ this.prefix = prefix
9
+ this.defaults = defaults ?? {}
10
+ }
11
+
12
+ public getBoolean(name: string): boolean {
13
+ const storedValue = localStorage.getItem(`${this.prefix}|${name}`)
14
+ if (!storedValue) {
15
+ assertEx(typeof this.defaults[name] === 'boolean', 'Default value is not boolean')
16
+ const defaultValue = this.defaults[name] as boolean
17
+ assertEx(defaultValue !== undefined, `Missing Default for ${name}`)
18
+ return defaultValue
19
+ }
20
+ return storedValue !== 'false'
21
+ }
22
+
23
+ public setBoolean(name: string, value: boolean) {
24
+ localStorage.setItem(`${this.prefix}|${name}`, JSON.stringify(value))
25
+ }
26
+
27
+ public setNumber(name: string, value: number) {
28
+ localStorage.setItem(`${this.prefix}|${name}`, JSON.stringify(value))
29
+ }
30
+
31
+ public getNumber(name: string): number {
32
+ const storedValue = localStorage.getItem(`${this.prefix}|${name}`)
33
+ if (!storedValue) {
34
+ assertEx(typeof this.defaults[name] === 'boolean', 'Default value is not boolean')
35
+ const defaultValue = this.defaults[name] as number
36
+ assertEx(defaultValue !== undefined, `Missing Default for ${name}`)
37
+ return defaultValue
38
+ }
39
+ return parseFloat(storedValue)
40
+ }
41
+
42
+ public getString(name: string) {
43
+ const storedValue = localStorage.getItem(`${this.prefix}|${name}`)
44
+ if (!storedValue) {
45
+ assertDefinedEx(typeof this.defaults[name] === 'string', 'Default value is not string')
46
+ const defaultValue = this.defaults[name] as string
47
+ assertEx(defaultValue !== undefined, `Missing Default for ${name}`)
48
+ return defaultValue
49
+ }
50
+ return storedValue
51
+ }
52
+
53
+ public setString(name: string, value: string) {
54
+ localStorage.setItem(`${this.prefix}|${name}`, value)
55
+ }
56
+
57
+ public getStringArray(name: string) {
58
+ const storedValue = localStorage.getItem(`${this.prefix}|${name}`)?.split(',')
59
+ if (!storedValue) {
60
+ assertDefinedEx(Array.isArray(this.defaults[name]), 'Default value is not array')
61
+ const defaultValue = this.defaults[name] as string[]
62
+ assertEx(defaultValue !== undefined, `Missing Default for ${name}`)
63
+ return defaultValue
64
+ }
65
+ return storedValue
66
+ }
67
+
68
+ public setStringArray(name: string, value: string[]) {
69
+ localStorage.setItem(`${this.prefix}|${name}`, value.join(','))
70
+ }
71
+
72
+ public getObject<T>(name: string): T {
73
+ const storedValue = localStorage.getItem(`${this.prefix}|${name}`)
74
+ const parsedStoredValue = storedValue ? JSON.parse(storedValue) : null
75
+ if (!parsedStoredValue) {
76
+ assertEx(typeof this.defaults[name] === 'object', 'Default value is not object')
77
+ return assertEx(this.defaults[name] as T, `Missing Default for ${name}`)
78
+ }
79
+ return parsedStoredValue as T
80
+ }
81
+
82
+ public setObject<T>(name: string, value: T) {
83
+ localStorage.setItem(`${this.prefix}|${name}`, JSON.stringify(value))
84
+ }
85
+ }
@@ -0,0 +1,9 @@
1
+ import { AppSettingSlug } from './Slug'
2
+
3
+ export const appSettingDefault = (): Record<string, unknown> => {
4
+ return {
5
+ [AppSettingSlug.DarkMode]: false,
6
+ [AppSettingSlug.Developer]: false,
7
+ [AppSettingSlug.NavigationType]: 'menu',
8
+ }
9
+ }
@@ -0,0 +1,6 @@
1
+ export * from './Context'
2
+ export * from './Provider'
3
+ export * from './Slug'
4
+ export * from './Storage'
5
+ export * from './StorageBase'
6
+ export * from './useAppSettings'
@@ -0,0 +1,7 @@
1
+ import { useContext } from 'react'
2
+
3
+ import { AppSettingsContext } from './Context'
4
+
5
+ export const useAppSettings = () => {
6
+ return useContext(AppSettingsContext)
7
+ }
@@ -0,0 +1 @@
1
+ export * from './AppSettings'
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './components'
2
+ export * from './contexts'
3
+ export * from './WebAppNavigationType'