uiconfig-blueprint 0.0.3 → 0.1.0-dev.11

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 (260) hide show
  1. package/README.md +41 -3
  2. package/dist/ConfigObject.d.ts +7 -4
  3. package/dist/UiConfigRendererBlueprint.d.ts +6 -4
  4. package/dist/allPaths-Dhco1c7a.js +23 -0
  5. package/dist/{allPaths-3YKfhB8Q.js.map → allPaths-Dhco1c7a.js.map} +1 -1
  6. package/dist/{allPathsLoader-lWFPuUtu.js → allPathsLoader-BNvrKJa2.js} +5 -5
  7. package/dist/{allPathsLoader-lWFPuUtu.js.map → allPathsLoader-BNvrKJa2.js.map} +1 -1
  8. package/dist/bpComponents/BPButtonComponent.d.ts +2 -1
  9. package/dist/bpComponents/BPColorInputComponent.d.ts +2 -2
  10. package/dist/bpComponents/BPComponent.d.ts +10 -4
  11. package/dist/bpComponents/BPContainerComponent.d.ts +1 -1
  12. package/dist/bpComponents/BPDropdownInputComponent.d.ts +1 -2
  13. package/dist/bpComponents/BPFileComponent.d.ts +9 -7
  14. package/dist/bpComponents/BPFolderComponent.d.ts +10 -2
  15. package/dist/bpComponents/BPInputComponent.d.ts +4 -3
  16. package/dist/bpComponents/BPNumberInputComponent.d.ts +4 -3
  17. package/dist/bpComponents/BPPanelComponent.d.ts +1 -2
  18. package/dist/bpComponents/BPSliderInputComponent.d.ts +2 -2
  19. package/dist/bpComponents/BPTextInputComponent.d.ts +1 -2
  20. package/dist/bpComponents/BPToggleInputComponent.d.ts +2 -3
  21. package/dist/bpComponents/BPTreeComponent.d.ts +26 -12
  22. package/dist/bpComponents/BPTreeFolderComponent.d.ts +2 -2
  23. package/dist/bpComponents/BPValueComponent.d.ts +4 -1
  24. package/dist/bpComponents/BPVectorInputComponent.d.ts +2 -2
  25. package/dist/bpComponents/GetNumberTransformFunctions.d.ts +4 -0
  26. package/dist/bpComponents/NumberUnits.d.ts +7 -0
  27. package/dist/components/AppToaster.d.ts +6 -0
  28. package/dist/components/ConfigurationPanelComponent.d.ts +4 -0
  29. package/dist/components/DialogContext.d.ts +60 -0
  30. package/dist/components/DraggableIcon.d.ts +2 -1
  31. package/dist/components/ExtendedNumericInput.d.ts +14 -4
  32. package/dist/components/FileComponent.d.ts +3 -1
  33. package/dist/components/FormGroupComponent.d.ts +2 -2
  34. package/dist/components/InspectorStackComponent.d.ts +3 -3
  35. package/dist/components/NumericInput.d.ts +79 -0
  36. package/dist/components/Tree2.d.ts +52 -0
  37. package/dist/components/TreeNode2.d.ts +43 -0
  38. package/dist/components/VisualStyleContext.d.ts +10 -1
  39. package/dist/components/axesIcons.d.ts +7 -0
  40. package/dist/components/bpIconWrapper.d.ts +2 -2
  41. package/dist/components/iconMapping.d.ts +198 -0
  42. package/dist/components/loadingState.d.ts +8 -0
  43. package/dist/components/shapesIcons.d.ts +100 -0
  44. package/dist/components/treeTypes.d.ts +18 -0
  45. package/dist/components/variableIcons.d.ts +40 -41
  46. package/dist/index-B1k4Miq7.js +671 -0
  47. package/dist/index-B1k4Miq7.js.map +1 -0
  48. package/dist/index-BvGAMcRo.js +671 -0
  49. package/dist/index-BvGAMcRo.js.map +1 -0
  50. package/dist/index-GANXo7JZ.js +13560 -0
  51. package/dist/index-GANXo7JZ.js.map +1 -0
  52. package/dist/index.js +71 -36
  53. package/dist/index.js.map +1 -1
  54. package/dist/index.mjs +3 -3
  55. package/dist/lib.d.ts +36 -0
  56. package/dist/{splitPathsBySizeLoader-97pYQiA7.js → splitPathsBySizeLoader-DGIXBgyZ.js} +6 -6
  57. package/dist/{splitPathsBySizeLoader-97pYQiA7.js.map → splitPathsBySizeLoader-DGIXBgyZ.js.map} +1 -1
  58. package/docs/assets/highlight.css +45 -17
  59. package/docs/assets/main.js +4 -3
  60. package/docs/assets/navigation.js +1 -0
  61. package/docs/assets/search.js +1 -1
  62. package/docs/assets/style.css +484 -369
  63. package/docs/classes/UI.html +27 -403
  64. package/docs/classes/UiConfigRendererBlueprint.html +27 -404
  65. package/docs/index.html +41 -107
  66. package/docs/modules.html +3 -50
  67. package/lib/css/renderer.css +13276 -0
  68. package/lib/css/renderer.css.map +1 -0
  69. package/lib/esm/ConfigObject.d.ts +19 -0
  70. package/lib/esm/ConfigObject.js +84 -0
  71. package/lib/esm/ConfigObject.js.map +1 -0
  72. package/lib/esm/UiConfigRendererBlueprint.d.ts +15 -0
  73. package/lib/esm/UiConfigRendererBlueprint.js +65 -0
  74. package/lib/esm/UiConfigRendererBlueprint.js.map +1 -0
  75. package/lib/esm/bpComponents/BPButtonComponent.d.ts +9 -0
  76. package/lib/esm/bpComponents/BPButtonComponent.js +17 -0
  77. package/lib/esm/bpComponents/BPButtonComponent.js.map +1 -0
  78. package/lib/esm/bpComponents/BPColorInputComponent.d.ts +25 -0
  79. package/lib/esm/bpComponents/BPColorInputComponent.js +125 -0
  80. package/lib/esm/bpComponents/BPColorInputComponent.js.map +1 -0
  81. package/lib/esm/bpComponents/BPComponent.d.ts +31 -0
  82. package/lib/esm/bpComponents/BPComponent.js +68 -0
  83. package/lib/esm/bpComponents/BPComponent.js.map +1 -0
  84. package/lib/esm/bpComponents/BPContainerComponent.d.ts +21 -0
  85. package/lib/esm/bpComponents/BPContainerComponent.js +60 -0
  86. package/lib/esm/bpComponents/BPContainerComponent.js.map +1 -0
  87. package/lib/esm/bpComponents/BPDropdownInputComponent.d.ts +15 -0
  88. package/lib/esm/bpComponents/BPDropdownInputComponent.js +43 -0
  89. package/lib/esm/bpComponents/BPDropdownInputComponent.js.map +1 -0
  90. package/lib/esm/bpComponents/BPFileComponent.d.ts +28 -0
  91. package/lib/esm/bpComponents/BPFileComponent.js +59 -0
  92. package/lib/esm/bpComponents/BPFileComponent.js.map +1 -0
  93. package/lib/esm/bpComponents/BPFolderComponent.d.ts +24 -0
  94. package/lib/esm/bpComponents/BPFolderComponent.js +77 -0
  95. package/lib/esm/bpComponents/BPFolderComponent.js.map +1 -0
  96. package/lib/esm/bpComponents/BPInputComponent.d.ts +12 -0
  97. package/lib/esm/bpComponents/BPInputComponent.js +31 -0
  98. package/lib/esm/bpComponents/BPInputComponent.js.map +1 -0
  99. package/lib/esm/bpComponents/BPLabelledComponent.d.ts +8 -0
  100. package/lib/esm/bpComponents/BPLabelledComponent.js +10 -0
  101. package/lib/esm/bpComponents/BPLabelledComponent.js.map +1 -0
  102. package/lib/esm/bpComponents/BPNumberInputComponent.d.ts +12 -0
  103. package/lib/esm/bpComponents/BPNumberInputComponent.js +41 -0
  104. package/lib/esm/bpComponents/BPNumberInputComponent.js.map +1 -0
  105. package/lib/esm/bpComponents/BPPanelComponent.d.ts +16 -0
  106. package/lib/esm/bpComponents/BPPanelComponent.js +31 -0
  107. package/lib/esm/bpComponents/BPPanelComponent.js.map +1 -0
  108. package/lib/esm/bpComponents/BPSliderInputComponent.d.ts +15 -0
  109. package/lib/esm/bpComponents/BPSliderInputComponent.js +49 -0
  110. package/lib/esm/bpComponents/BPSliderInputComponent.js.map +1 -0
  111. package/lib/esm/bpComponents/BPTextInputComponent.d.ts +7 -0
  112. package/lib/esm/bpComponents/BPTextInputComponent.js +15 -0
  113. package/lib/esm/bpComponents/BPTextInputComponent.js.map +1 -0
  114. package/lib/esm/bpComponents/BPToggleInputComponent.d.ts +8 -0
  115. package/lib/esm/bpComponents/BPToggleInputComponent.js +19 -0
  116. package/lib/esm/bpComponents/BPToggleInputComponent.js.map +1 -0
  117. package/lib/esm/bpComponents/BPTreeComponent.d.ts +46 -0
  118. package/lib/esm/bpComponents/BPTreeComponent.js +221 -0
  119. package/lib/esm/bpComponents/BPTreeComponent.js.map +1 -0
  120. package/lib/esm/bpComponents/BPTreeFolderComponent.d.ts +10 -0
  121. package/lib/esm/bpComponents/BPTreeFolderComponent.js +37 -0
  122. package/lib/esm/bpComponents/BPTreeFolderComponent.js.map +1 -0
  123. package/lib/esm/bpComponents/BPValueComponent.d.ts +19 -0
  124. package/lib/esm/bpComponents/BPValueComponent.js +58 -0
  125. package/lib/esm/bpComponents/BPValueComponent.js.map +1 -0
  126. package/lib/esm/bpComponents/BPVectorInputComponent.d.ts +20 -0
  127. package/lib/esm/bpComponents/BPVectorInputComponent.js +112 -0
  128. package/lib/esm/bpComponents/BPVectorInputComponent.js.map +1 -0
  129. package/lib/esm/bpComponents/GetNumberTransformFunctions.d.ts +4 -0
  130. package/lib/esm/bpComponents/GetNumberTransformFunctions.js +14 -0
  131. package/lib/esm/bpComponents/GetNumberTransformFunctions.js.map +1 -0
  132. package/lib/esm/bpComponents/NumberUnits.d.ts +7 -0
  133. package/lib/esm/bpComponents/NumberUnits.js +101 -0
  134. package/lib/esm/bpComponents/NumberUnits.js.map +1 -0
  135. package/lib/esm/components/AppToaster.d.ts +6 -0
  136. package/lib/esm/components/AppToaster.js +8 -0
  137. package/lib/esm/components/AppToaster.js.map +1 -0
  138. package/lib/esm/components/ConfigurationPanelComponent.d.ts +4 -0
  139. package/lib/esm/components/ConfigurationPanelComponent.js +31 -0
  140. package/lib/esm/components/ConfigurationPanelComponent.js.map +1 -0
  141. package/lib/esm/components/DialogContext.d.ts +60 -0
  142. package/lib/esm/components/DialogContext.js +108 -0
  143. package/lib/esm/components/DialogContext.js.map +1 -0
  144. package/lib/esm/components/DraggableIcon.d.ts +20 -0
  145. package/lib/esm/components/DraggableIcon.js +69 -0
  146. package/lib/esm/components/DraggableIcon.js.map +1 -0
  147. package/lib/esm/components/ExtendedNumericInput.d.ts +35 -0
  148. package/lib/esm/components/ExtendedNumericInput.js +215 -0
  149. package/lib/esm/components/ExtendedNumericInput.js.map +1 -0
  150. package/lib/esm/components/FileComponent.d.ts +9 -0
  151. package/lib/esm/components/FileComponent.js +45 -0
  152. package/lib/esm/components/FileComponent.js.map +1 -0
  153. package/lib/esm/components/FormGroupComponent.d.ts +6 -0
  154. package/lib/esm/components/FormGroupComponent.js +12 -0
  155. package/lib/esm/components/FormGroupComponent.js.map +1 -0
  156. package/lib/esm/components/InspectorStackComponent.d.ts +5 -0
  157. package/lib/esm/components/InspectorStackComponent.js +23 -0
  158. package/lib/esm/components/InspectorStackComponent.js.map +1 -0
  159. package/lib/esm/components/NumericInput.d.ts +79 -0
  160. package/lib/esm/components/NumericInput.js +311 -0
  161. package/lib/esm/components/NumericInput.js.map +1 -0
  162. package/lib/esm/components/Tree2.d.ts +52 -0
  163. package/lib/esm/components/Tree2.js +177 -0
  164. package/lib/esm/components/Tree2.js.map +1 -0
  165. package/lib/esm/components/TreeNode2.d.ts +43 -0
  166. package/lib/esm/components/TreeNode2.js +111 -0
  167. package/lib/esm/components/TreeNode2.js.map +1 -0
  168. package/lib/esm/components/VisualStyleContext.d.ts +119 -0
  169. package/lib/esm/components/VisualStyleContext.js +59 -0
  170. package/lib/esm/components/VisualStyleContext.js.map +1 -0
  171. package/lib/esm/components/axesIcons.d.ts +7 -0
  172. package/lib/esm/components/axesIcons.js +10 -0
  173. package/lib/esm/components/axesIcons.js.map +1 -0
  174. package/lib/esm/components/bpIconWrapper.d.ts +2 -0
  175. package/lib/esm/components/bpIconWrapper.js +5 -0
  176. package/lib/esm/components/bpIconWrapper.js.map +1 -0
  177. package/lib/esm/components/iconMapping.d.ts +198 -0
  178. package/lib/esm/components/iconMapping.js +202 -0
  179. package/lib/esm/components/iconMapping.js.map +1 -0
  180. package/lib/esm/components/loadingState.d.ts +8 -0
  181. package/lib/esm/components/loadingState.js +31 -0
  182. package/lib/esm/components/loadingState.js.map +1 -0
  183. package/lib/esm/components/shapesIcons.d.ts +100 -0
  184. package/lib/esm/components/shapesIcons.js +102 -0
  185. package/lib/esm/components/shapesIcons.js.map +1 -0
  186. package/lib/esm/components/treeTypes.d.ts +18 -0
  187. package/lib/esm/components/treeTypes.js +2 -0
  188. package/lib/esm/components/treeTypes.js.map +1 -0
  189. package/lib/esm/components/variableIcons.d.ts +40 -0
  190. package/lib/esm/components/variableIcons.js +43 -0
  191. package/lib/esm/components/variableIcons.js.map +1 -0
  192. package/lib/esm/contexts.d.ts +1 -0
  193. package/lib/esm/contexts.js +2 -0
  194. package/lib/esm/contexts.js.map +1 -0
  195. package/lib/esm/index.d.ts +4 -0
  196. package/lib/esm/index.js +5 -0
  197. package/lib/esm/index.js.map +1 -0
  198. package/lib/esm/lib.d.ts +36 -0
  199. package/lib/esm/lib.js +37 -0
  200. package/lib/esm/lib.js.map +1 -0
  201. package/lib/esm/renderer.css.js +1 -0
  202. package/lib/esm/threejs.d.ts +2 -0
  203. package/lib/esm/threejs.js +2 -0
  204. package/lib/esm/threejs.js.map +1 -0
  205. package/package.json +64 -11
  206. package/src/ConfigObject.tsx +29 -15
  207. package/src/UiConfigRendererBlueprint.tsx +33 -35
  208. package/src/bpComponents/BPButtonComponent.scss +6 -1
  209. package/src/bpComponents/BPButtonComponent.tsx +9 -2
  210. package/src/bpComponents/BPColorInputComponent.tsx +9 -3
  211. package/src/bpComponents/BPComponent.tsx +26 -7
  212. package/src/bpComponents/BPContainerComponent.tsx +13 -1
  213. package/src/bpComponents/BPDropdownInputComponent.tsx +8 -3
  214. package/src/bpComponents/BPFileComponent.tsx +56 -29
  215. package/src/bpComponents/BPFolderComponent.scss +22 -8
  216. package/src/bpComponents/BPFolderComponent.tsx +105 -16
  217. package/src/bpComponents/BPInputComponent.tsx +7 -3
  218. package/src/bpComponents/BPNumberInputComponent.tsx +14 -2
  219. package/src/bpComponents/BPPanelComponent.tsx +1 -2
  220. package/src/bpComponents/BPSliderInputComponent.tsx +40 -21
  221. package/src/bpComponents/BPTextInputComponent.tsx +2 -1
  222. package/src/bpComponents/BPToggleInputComponent.tsx +7 -4
  223. package/src/bpComponents/BPTreeComponent.tsx +153 -36
  224. package/src/bpComponents/BPTreeFolderComponent.tsx +5 -5
  225. package/src/bpComponents/BPValueComponent.tsx +31 -4
  226. package/src/bpComponents/BPVectorInputComponent.tsx +23 -20
  227. package/src/bpComponents/GetNumberTransformFunctions.tsx +14 -0
  228. package/src/bpComponents/NumberUnits.tsx +123 -0
  229. package/src/components/AppToaster.tsx +38 -0
  230. package/src/components/ConfigurationPanelComponent.tsx +74 -0
  231. package/src/components/DialogContext.tsx +210 -0
  232. package/src/components/DraggableIcon.tsx +7 -5
  233. package/src/components/ExtendedNumericInput.tsx +70 -18
  234. package/src/components/FileComponent.tsx +48 -25
  235. package/src/components/FormGroupComponent.tsx +1 -1
  236. package/src/components/InspectorStackComponent.tsx +4 -34
  237. package/src/components/NumericInput.tsx +679 -0
  238. package/src/components/Tree2.tsx +344 -0
  239. package/src/components/TreeNode2.tsx +192 -0
  240. package/src/components/VisualStyleContext.tsx +41 -1
  241. package/src/components/axesIcons.tsx +116 -0
  242. package/src/components/bpIconWrapper.tsx +5 -4
  243. package/src/components/common.scss +23 -0
  244. package/src/components/iconMapping.ts +354 -0
  245. package/src/components/loadingState.tsx +20 -0
  246. package/src/components/shapesIcons.tsx +980 -0
  247. package/src/components/tree2.scss +69 -0
  248. package/src/components/treeTypes.ts +97 -0
  249. package/src/components/variableIcons.tsx +0 -1
  250. package/src/lib.ts +36 -0
  251. package/src/renderer.scss +136 -65
  252. package/src/tsconfig.json +6 -0
  253. package/tsconfig.json +2 -1
  254. package/dist/allPaths-3YKfhB8Q.js +0 -23
  255. package/dist/index-RJDPvlPL.js +0 -604
  256. package/dist/index-RJDPvlPL.js.map +0 -1
  257. package/dist/index-sUDdkVfJ.js +0 -604
  258. package/dist/index-sUDdkVfJ.js.map +0 -1
  259. package/dist/index-zXngzS2o.js +0 -12752
  260. package/dist/index-zXngzS2o.js.map +0 -1
@@ -0,0 +1,74 @@
1
+ import React from "react";
2
+ import {Button, Card, Panel, PanelStack2, Popover} from "@blueprintjs/core";
3
+ import {ConfigObject, ConfigProps} from "../ConfigObject";
4
+ import {UiObjectConfig} from 'uiconfig.js'
5
+ import {UiConfigRendererContext} from '../bpComponents/BPComponent'
6
+ import {Classes} from '@blueprintjs/core/src/common'
7
+ import {
8
+ defaultVisualStyle,
9
+ setupVisualStyle,
10
+ ThemeSettingsMenuComponent,
11
+ VisualStyleContext
12
+ } from './VisualStyleContext'
13
+
14
+ // import {ViewerAppContext} from "./ViewerAppComponent";
15
+
16
+ export function ConfigurationPanelComponent({config}: { config: UiObjectConfig<any, 'panel'> }) {
17
+ const renderer = React.useContext(UiConfigRendererContext)
18
+ const stackItem = React.useCallback(() => {
19
+ return {
20
+ props: {config: config},
21
+ renderPanel(props: ConfigProps) {
22
+ // console.log(props.config === config)
23
+ return (
24
+ <ul style={{listStyleType: "none", paddingLeft: "0", margin: "0"}}>
25
+ {/*{v && (<ConfigObject {...props}/>)}*/}
26
+ {config && (<ConfigObject {...props} isPanel={true}/>)}
27
+ </ul>
28
+ )
29
+ },
30
+ title: renderer.methods.getLabel(config)
31
+ } as Panel<{ config: UiObjectConfig }>
32
+ }, [config])
33
+ const [currentPanelStack, setCurrentPanelStack] = React.useState<Array<Panel<{ config: UiObjectConfig }>>>([stackItem()]);
34
+ const [isMinimized, setIsMinimized] = React.useState(false);
35
+
36
+ React.useEffect(() => {
37
+ setCurrentPanelStack([stackItem()])
38
+ }, [stackItem, setCurrentPanelStack])
39
+
40
+ const style = setupVisualStyle()
41
+
42
+ return (
43
+ <VisualStyleContext.Provider value={{...defaultVisualStyle, ...style}}>
44
+ <Card className={`bpInspectorCard ${style.darkMode?Classes.DARK:""}`} style={{display: isMinimized ? 'none' : 'block'}}>
45
+ <PanelStack2 className="inspectorPanelStack"
46
+ showPanelHeader={true}
47
+ renderActivePanelOnly={true}
48
+ onOpen={(p) => setCurrentPanelStack([...currentPanelStack, p] as any)}
49
+ onClose={() => setCurrentPanelStack(currentPanelStack.slice(0, -1))}
50
+ stack={currentPanelStack}/>
51
+ <div className={"bpPanelStackHeaderOverlay " + Classes.PANEL_STACK2_HEADER}>
52
+ <Popover targetProps={{style: {position: "absolute", right: "30px"}}}
53
+ minimal={true}
54
+ targetTagName={"div"}
55
+ content={
56
+ <ThemeSettingsMenuComponent/>
57
+ } placement="bottom">
58
+ <Button icon="more" small minimal text="" />
59
+ </Popover>
60
+ <Button icon="minus" small minimal text="" style={{position: "absolute", right: "5px"}}
61
+ onClick={() => {
62
+ setIsMinimized(!isMinimized);
63
+ }}
64
+ />
65
+ </div>
66
+ </Card>
67
+ {isMinimized && <Button icon="cog" small text="Configuration" style={{position: "absolute", right: "5px"}}
68
+ onClick={() => {
69
+ setIsMinimized(!isMinimized);
70
+ }}
71
+ />}
72
+ </VisualStyleContext.Provider>
73
+ )
74
+ }
@@ -0,0 +1,210 @@
1
+ import {createContext, Dispatch, ReactNode, SetStateAction, useCallback, useContext, useState} from 'react'
2
+ import {Button, Dialog, DialogBody, DialogFooter, FormGroup, InputGroup} from '@blueprintjs/core'
3
+ import {useLoadingState} from './loadingState'
4
+ import {Intent} from '@blueprintjs/core/src/common/intent'
5
+
6
+ export type DialogStateType = {
7
+ isOpen: boolean,
8
+ title: string,
9
+ content: ReactNode,
10
+ actions: ReactNode,
11
+ state: any,
12
+ canClose: boolean // if true, dialog can be closed by clicking outside of it
13
+ }
14
+ export const defaultDialogContext = {
15
+ isOpen: false, title: '',
16
+ content: null as ReactNode,
17
+ actions: null as ReactNode,
18
+ state: {} as any, canClose: true,
19
+ }
20
+ export function setupDialog(){
21
+ const [dialog, setDialog] = useState<DialogStateType>(defaultDialogContext)
22
+ const open = useCallback((d: Partial<DialogStateType>)=>{
23
+ setDialog({...dialog, isOpen: true, ...d})
24
+ }, [dialog, setDialog])
25
+ const close = useCallback(()=>setDialog({...dialog, isOpen: false}), [dialog, setDialog])
26
+ const setDialogState = useCallback((state: any)=>{
27
+ setDialog({...dialog, state})
28
+ }, [dialog, setDialog])
29
+ return {dialog, open, close, setDialog, state: dialog.state, setState: setDialogState}
30
+ }
31
+ export const DialogContext = createContext<{
32
+ dialog: DialogStateType,
33
+ open: (d: Partial<DialogStateType>)=>void,
34
+ close: ()=>void,
35
+ setDialog: Dispatch<SetStateAction<DialogStateType>>,
36
+ setState: Dispatch<SetStateAction<any>>,
37
+ state: any
38
+ }>(
39
+ {dialog: defaultDialogContext, open: ()=>{}, close: ()=>{}, setDialog: ()=>{}, setState: ()=>{}, state: {}}
40
+ )
41
+ export const useDialog = () => useContext(DialogContext)
42
+
43
+ export function DialogProvider({children}: {children: ReactNode}){
44
+ const dialog = setupDialog()
45
+ return <DialogContext.Provider value={{...dialog}}>
46
+ {children}
47
+ </DialogContext.Provider>
48
+ }
49
+
50
+ export function DialogComponent(){
51
+ const {dialog, close} = useDialog()
52
+ return (
53
+ <Dialog title={dialog.title} isOpen={dialog.isOpen} isCloseButtonShown={dialog.canClose} onClose={() => {dialog.canClose && close()}}>
54
+ <DialogBody>
55
+ {dialog.content}
56
+ </DialogBody>
57
+ <DialogFooter actions={dialog.actions}/>
58
+ </Dialog>)
59
+ }
60
+
61
+ interface DialogPromptState {
62
+ value: string,
63
+ intent: Intent,
64
+ helperText: string,
65
+ }
66
+ interface DialogPromptProps extends Partial<DialogStateType>{
67
+ closeButtonText?: string,
68
+ submitButtonText?: string,
69
+ message?: string,
70
+ placeholder?: string,
71
+ value?: string,
72
+ showInput?: boolean,
73
+ onClose?: (value: string)=>boolean|undefined|Promise<boolean|undefined>, // does not close if false
74
+ onSubmit?: (value: string)=>boolean|undefined|any|Promise<boolean|undefined|any>, // does not close if false
75
+ }
76
+ /**
77
+ * Usage:
78
+ * ```tsx
79
+ * const {prompt, close} = useDialogPrompt()
80
+ * const text = await prompt({
81
+ * title: 'Enter some text',
82
+ * message: 'Enter some text: ',
83
+ * placeholder: 'Enter some text',
84
+ * value: 'Default Value',
85
+ * onClose: ()=>{console.log('close'); return true},
86
+ * onSubmit: ()=>{console.log('submit'); return true},
87
+ * closeButtonText: 'Close',
88
+ * submitButtonText: 'Okay',
89
+ * })
90
+ * ```
91
+ */
92
+ export function useDialogPrompt(){
93
+ const {open, close} = useDialog()
94
+ const prompt = useCallback(({
95
+ closeButtonText = 'Close',
96
+ submitButtonText = 'Okay',
97
+ message = 'Enter some text: ',
98
+ placeholder = '',
99
+ value = '',
100
+ showInput = true,
101
+ onClose, onSubmit,
102
+ ...props}: DialogPromptProps) => {
103
+ return new Promise<string|null>((resolve)=>{
104
+ open({
105
+ canClose: false,
106
+ ...props,
107
+ state: {
108
+ value,
109
+ intent: Intent.NONE,
110
+ helperText: '',
111
+ } as DialogPromptState,
112
+ content: (
113
+ <DialogPromptContent message={message} showInput={showInput} placeholder={placeholder}/>
114
+ ),
115
+ actions: (
116
+ <DialogPromptButtons closeButtonText={closeButtonText} submitButtonText={submitButtonText} onClose={onClose} onSubmit={onSubmit} resolve={resolve}/>
117
+ ),
118
+ })
119
+ })
120
+ }, [open, close])
121
+ return {prompt, close}
122
+ }
123
+
124
+ function DialogPromptButtons({
125
+ closeButtonText = 'Close',
126
+ submitButtonText = 'Okay',
127
+ onClose, onSubmit, resolve
128
+ }:{
129
+ closeButtonText?: string,
130
+ submitButtonText?: string,
131
+ onClose?: (value: string)=>boolean|undefined|Promise<boolean|undefined>, // does not close if false
132
+ onSubmit?: (value: string)=>boolean|undefined|{error: string}|Promise<boolean|undefined|{error: string}>, // does not close if false
133
+ resolve: (value: string|null)=>void,
134
+ }){
135
+ const {loadingState, updateLoading} = useLoadingState()
136
+ const {state, setState, close} = useDialog() as {state: DialogPromptState, setState: Dispatch<SetStateAction<DialogPromptState>>, close: ()=>void}
137
+ const doClose = async()=> {
138
+ if (onClose && (await onClose(state.value)) !== true) return
139
+ close()
140
+ resolve(null)
141
+ }
142
+ const doSubmit = async()=> {
143
+ if (onSubmit) {
144
+ const res = await onSubmit(state.value)
145
+ if(res && (res as any).error){
146
+ setState({...state, intent: Intent.DANGER, helperText: (res as any).error})
147
+ }
148
+ if(res !== true) return
149
+ }
150
+ close()
151
+ resolve(state.value)
152
+ }
153
+ return <>
154
+ <Button text={closeButtonText}
155
+ loading={loadingState['popup-close']}
156
+ onClick={() => updateLoading('popup-close', doClose())}/>
157
+ <Button text={submitButtonText}
158
+ intent="primary"
159
+ data-dialog-submit="true"
160
+ loading={loadingState['popup-submit']}
161
+ onClick={() => updateLoading('popup-submit', doSubmit())}/>
162
+ </>
163
+
164
+ }
165
+
166
+ function DialogPromptContent({
167
+ message = 'Enter some text: ',
168
+ placeholder = '',
169
+ showInput = true,
170
+ }: {
171
+ message?: string,
172
+ placeholder?: string,
173
+ showInput?: boolean,
174
+ }){
175
+ const {state, setState} = useDialog() as {state: DialogPromptState, setState: Dispatch<SetStateAction<DialogPromptState>>}
176
+ const {loadingState} = useLoadingState()
177
+
178
+ const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
179
+ if (e.key === 'Enter') {
180
+ // Get the submit button using the data attribute and simulate a click
181
+ const submitButton = document.querySelector('[data-dialog-submit="true"]') as HTMLButtonElement;
182
+ if (submitButton && !loadingState['popup-submit']) {
183
+ submitButton.click();
184
+ }
185
+ }
186
+ }
187
+
188
+ return <FormGroup
189
+ helperText={state.helperText||undefined}
190
+ intent={state.intent}
191
+ label={message}
192
+ labelFor="dialog-prompt-text-input"
193
+ >
194
+ <InputGroup
195
+ intent={state.intent}
196
+ id="dialog-prompt-text-input"
197
+ placeholder={placeholder}
198
+ defaultValue={state.value}
199
+ style={{display: showInput ? 'block' : 'none'}}
200
+ autoFocus={true}
201
+ onChange={(e: any) => {
202
+ state.value = e.target.value
203
+ state.helperText = ''
204
+ state.intent = Intent.NONE
205
+ setState({...state})
206
+ }}
207
+ onKeyDown={handleKeyDown}
208
+ />
209
+ </FormGroup>
210
+ }
@@ -1,13 +1,14 @@
1
1
  import * as React from "react";
2
2
  import {Icon, IconName, MaybeElement} from "@blueprintjs/core";
3
3
 
4
- export class DraggableIcon extends React.Component<{ icon: IconName | MaybeElement, size?: number, value: number, stepSize?: number, small?: boolean, onChange: (v: number, last?: boolean) => void }> {
4
+ // todo: bounds and stepsize
5
+ export class DraggableIcon extends React.Component<{ icon: IconName | MaybeElement, size?: number, value: number, stepSize?: number, small?: boolean, disabled?: boolean, onChange: (v: number, last?: boolean) => void }> {
5
6
  private cursor = 'auto'
6
7
  private dragStartOffset = -Infinity
7
8
  private dragStartValue = -Infinity
8
9
  private lastValue = -Infinity
9
10
  private removeEvents = () => {
10
- if (isFinite(this.lastValue)) this.props.onChange(this.lastValue)
11
+ if (isFinite(this.lastValue) && !this.props.disabled) this.props.onChange(this.lastValue)
11
12
  this.lastValue = -Infinity
12
13
  this.dragStartOffset = -Infinity
13
14
  this.dragStartValue = -Infinity
@@ -41,7 +42,7 @@ export class DraggableIcon extends React.Component<{ icon: IconName | MaybeEleme
41
42
  let val = this.dragStartValue - off;
42
43
  // val = Math.min(props.max, Math.max(props.min, val)); // todo
43
44
  val = Number(val.toFixed(Math.max(1, -Math.log10(stepSize / 10)))); // clip decimal places depending on step size
44
- this.props.onChange(val, false)
45
+ if(!this.props.disabled) this.props.onChange(val, false)
45
46
  this.lastValue = val;
46
47
  }
47
48
  } else {
@@ -54,9 +55,10 @@ export class DraggableIcon extends React.Component<{ icon: IconName | MaybeEleme
54
55
  // const [dragging, setDragging] = React.useState(false)
55
56
 
56
57
  return (
57
- <div style={{cursor: 'ew-resize', marginLeft: "6px", marginRight: "6px", marginTop: this.props.small ? "3px" : "6px", marginBottom: this.props.small ? "3px" : "6px"}}
58
+ <div style={{cursor: !this.props.disabled ? 'ew-resize': 'auto', marginLeft: "6px", marginRight: "6px", marginTop: this.props.small ? "3px" : "6px", marginBottom: this.props.small ? "3px" : "6px"}}
58
59
  onMouseDown={(ev) => {
59
60
  // if(dragging) return
61
+ if(this.props.disabled) return
60
62
  this.dragStartOffset = ev.clientX
61
63
  this.dragStartValue = this.props.value
62
64
  ev.stopPropagation()
@@ -68,7 +70,7 @@ export class DraggableIcon extends React.Component<{ icon: IconName | MaybeEleme
68
70
  // setDragging(true)
69
71
  }}
70
72
  >
71
- <Icon icon={this.props.icon} size={this.props.size}/>
73
+ <Icon icon={this.props.icon} size={this.props.size} aria-disabled={this.props.disabled} />
72
74
  </div>
73
75
  )
74
76
  }
@@ -20,7 +20,7 @@
20
20
  import React from "react";
21
21
 
22
22
  import type {HTMLInputProps, NumericInputProps} from "@blueprintjs/core";
23
- import {NumericInput} from "@blueprintjs/core";
23
+ import {NumericInput} from "./NumericInput";
24
24
  import {DraggableIcon} from "./DraggableIcon";
25
25
 
26
26
  export interface IExtendedNumericInputState {
@@ -35,39 +35,87 @@ const NumberAbbreviation = {
35
35
 
36
36
  const NUMBER_ABBREVIATION_REGEX = /((\.\d+)|(\d+(\.\d+)?))(k|m|b)\b/gi;
37
37
  const SCIENTIFIC_NOTATION_REGEX = /((\.\d+)|(\d+(\.\d+)?))(e\d+)\b/gi;
38
+ type Props = HTMLInputProps & NumericInputProps & {
39
+ onChange2?: (v: number, last?: boolean) => void,
40
+ transformValue?: (v: number) => number,
41
+ invTransformValue?: (v: number) => number,
42
+ draggableIcon?: boolean
43
+ value?: number | undefined
44
+ defaultValue?: number | undefined
45
+ }
46
+ // todo: bounds and stepsize
47
+ export class ExtendedNumericInput extends React.PureComponent<Props, IExtendedNumericInputState> {
48
+ invTransformValue = (v: number|undefined) => {
49
+ v = v || 0
50
+ const v1 = this.props.invTransformValue ? this.props.invTransformValue(v) : v;
51
+ return v1
52
+ }
53
+ transformValue = (v: number|undefined) => {
54
+ v = v || 0
55
+ const v1 = this.props.transformValue ? this.props.transformValue(v) : v;
56
+ return v1
57
+ }
38
58
 
39
- export class ExtendedNumericInput extends React.PureComponent<HTMLInputProps & NumericInputProps & { onChange2: (v: number, last?: boolean) => void }, IExtendedNumericInputState> {
40
59
  public state: IExtendedNumericInputState = {
41
- value: (this.props.value ?? this.props.defaultValue ?? '').toString(),
60
+ value: this.invTransformValue(this.props.value ?? this.props.defaultValue).toString(),
42
61
  };
43
62
 
44
63
  async setValue(val?: number) {
45
64
  return new Promise<void>((resolve) => {
46
- this.setState({value: (val ?? this.props.value ?? this.props.defaultValue ?? '').toString()}, resolve)
65
+ this.setState({value: this.invTransformValue(val ?? this.props.value ?? this.props.defaultValue).toString()}, resolve)
47
66
  })
48
67
  }
49
68
 
69
+ componentDidUpdate(prevProps: Props) {
70
+ if (prevProps.value !== this.props.value && this.props.value !== undefined) {
71
+ this.setState({ value: this.invTransformValue(this.props.value).toString() });
72
+ }
73
+ }
50
74
  public render() {
51
75
  const {value} = this.state;
52
- const props2: HTMLInputProps & NumericInputProps & { onChange2?: (v: number, last?: boolean) => void } = {...this.props}
53
- if (props2.onChange2) delete props2.onChange2
76
+ const {
77
+ invTransformValue,
78
+ transformValue,
79
+ draggableIcon,
80
+ onChange2,
81
+ value: _value,
82
+ leftIcon,
83
+ defaultValue,
84
+ ...props2
85
+ } = this.props;
86
+
87
+ if(transformValue && !invTransformValue ||
88
+ !transformValue && invTransformValue) {
89
+ console.error('ExtendedNumericInput: Both transformValue and invTransformValue must be provided or neither. This is to ensure that the value can be transformed back and forth correctly.');
90
+ }
91
+
92
+ if(transformValue){
93
+ if(props2.min !== undefined) props2.min = this.invTransformValue(props2.min);
94
+ if(props2.max !== undefined) props2.max = this.invTransformValue(props2.max);
95
+ if(props2.stepSize !== undefined) props2.stepSize = this.invTransformValue(props2.stepSize);
96
+ if(props2.minorStepSize /*!== undefined*/) props2.minorStepSize = this.invTransformValue(props2.minorStepSize);
97
+ if(props2.majorStepSize /*!== undefined*/) props2.majorStepSize = this.invTransformValue(props2.majorStepSize);
98
+ }
54
99
 
55
100
  return (
56
101
  <NumericInput
57
102
  {...props2}
58
- leftElement={(
59
- <DraggableIcon icon={this.props.leftIcon ?? "variable"}
103
+ leftElement={( // props2.leftElement could be null
104
+ props2.leftElement !== undefined ? props2.leftElement :
105
+ draggableIcon !== false ? <DraggableIcon icon={leftIcon ?? "variable"}
60
106
  size={16}
61
- small={this.props.small}
107
+ disabled={props2.readOnly}
108
+ small={props2.small}
62
109
  value={parseFloat(value ?? '0')}
63
- stepSize={this.props.stepSize}
110
+ stepSize={props2.stepSize}
64
111
  onChange={(v, last) => {
65
112
  this.handleValueChange(v, v.toString(), null, last, true)
66
- }}/>
113
+ }}/> : undefined
67
114
  )}
68
115
  // leftIcon={"variable"}
69
- buttonPosition={this.props.buttonPosition ?? (this.props.disabled ? "none" : "right")}
116
+ buttonPosition={props2.buttonPosition ?? (props2.disabled ? "none" : "right")}
70
117
  allowNumericCharactersOnly={false}
118
+ clampValueOnBlur={true}
71
119
  onBlur={this.handleBlur}
72
120
  onKeyDown={this.handleKeyDown}
73
121
  onButtonClick={this.handleButtonClick}
@@ -107,9 +155,11 @@ export class ExtendedNumericInput extends React.PureComponent<HTMLInputProps & N
107
155
  private handleValueChange = (_valueAsNumber: number, valueAsString: string, inputElement: HTMLInputElement | null, last?: boolean, dispatchOnChange2 = false) => {
108
156
  this._lastChangedValue = [_valueAsNumber, valueAsString]
109
157
  this.setState({value: valueAsString}, () => {
110
- this.props.onValueChange?.(_valueAsNumber, valueAsString, inputElement)
111
- if(dispatchOnChange2)
112
- this.props.onChange2?.(_valueAsNumber, last)
158
+ const transformed = this.transformValue(_valueAsNumber)
159
+ this.props.onValueChange?.(transformed, valueAsString, inputElement)
160
+ if(dispatchOnChange2) {
161
+ this.props.onChange2?.(transformed, last)
162
+ }
113
163
  });
114
164
  };
115
165
 
@@ -124,8 +174,10 @@ export class ExtendedNumericInput extends React.PureComponent<HTMLInputProps & N
124
174
  result = this.evaluateSimpleMathExpression(result);
125
175
  result = this.nanStringToEmptyString(result);
126
176
  this.setState({value: result}, () => {
127
- this.props.onValueChange?.(parseFloat(result) || 0, result, null)
128
- this.props.onChange2?.(parseFloat(result) || 0)
177
+ const _valueAsNumber = parseFloat(result) || 0;
178
+ const transformed = this.transformValue(_valueAsNumber)
179
+ this.props.onValueChange?.(transformed, result, null)
180
+ this.props.onChange2?.(transformed, true)
129
181
  });
130
182
 
131
183
  // the user could have typed a different expression that evaluates to
@@ -151,7 +203,7 @@ export class ExtendedNumericInput extends React.PureComponent<HTMLInputProps & N
151
203
  };
152
204
 
153
205
  // Adapted from http://stackoverflow.com/questions/2276021/evaluating-a-string-as-a-mathematical-expression-in-javascript
154
- // maybe try a better solution from above, right now it only works left to right
206
+ // todo - use a proper parser and evaluator, right now it only works left to right
155
207
  private evaluateSimpleMathExpression = (value: string) => {
156
208
  // leave empty strings empty
157
209
  if (!value) {
@@ -1,12 +1,15 @@
1
1
  import React, {useEffect, useRef} from "react";
2
2
  import {Button, ControlGroup, FileInput, HTMLSelect, InputGroup} from "@blueprintjs/core";
3
3
  import {BPFileComponentState} from "../bpComponents/BPFileComponent";
4
+ import {useLoadingStateKey} from './loadingState'
4
5
 
5
6
  export interface FileComponentProps {
6
7
  state: BPFileComponentState
7
- onChange: (state: Partial<BPFileComponentState>)=>void
8
+ onChange: (state: Partial<BPFileComponentState>)=>Promise<void>
9
+ previewSlot?: React.ReactNode,
10
+ uuid?: string
8
11
  }
9
- export const FileComponent: React.FC<FileComponentProps> = ({state, onChange})=>{
12
+ export const FileComponent: React.FC<FileComponentProps> = ({state, onChange, previewSlot})=>{
10
13
  const fileInputRef = useRef<HTMLInputElement>()
11
14
  const textInputRef = useRef<HTMLInputElement>()
12
15
  // console.log('render file component', state)
@@ -33,47 +36,67 @@ export const FileComponent: React.FC<FileComponentProps> = ({state, onChange})=>
33
36
  // fileInputRef.current && (fileInputRef.current.placeholder = 'https://example.com/file.png')
34
37
  // }, []);
35
38
 
39
+ // const hasValue = !!state.value || !!state.preview
40
+
41
+ const {loadingState, updateLoading} = useLoadingStateKey()
42
+
36
43
  return (
37
- <div style={{flexGrow: "1", display: "flex", height: "100%"}}>
38
- <ControlGroup fill={false} vertical={false} style={{width: "100%"}}>
39
- {!state.readOnly ? (<HTMLSelect options={['url', 'file']} minimal={true} fill={false}
44
+ <div style={{position: "relative", flexGrow: "1", display: "flex", height: "100%", flexDirection: "column"}}>
45
+ {!!state.preview && (
46
+ <>
47
+ {previewSlot}
48
+ <Button icon="small-cross"
49
+ minimal={false}
50
+ small={true}
40
51
  disabled={state.disabled}
41
- value={state.mode} onChange={(e)=>{
42
- onChange({mode: e.target.value as 'url'|'file'})
43
- }} /> ) : null}
52
+ intent={"danger"}
53
+ style={{position: "absolute", top: 0, right: 0, opacity: 0.7}}
54
+ loading={loadingState}
55
+ onClick={() => updateLoading(onChange({value: null}))}></Button>
56
+ </>
57
+ )}
58
+ {(!state.preview || !previewSlot) && <ControlGroup fill={false} vertical={false} style={{width: "100%"}}>
59
+ {!state.readOnly && !state.value ? (<HTMLSelect options={['url', 'file']} minimal={true} fill={false}
60
+ disabled={state.disabled}
61
+ className={"file-component-select"}
62
+ value={state.mode} onChange={(e) => {
63
+ onChange({mode: e.target.value as 'url' | 'file'})
64
+ }}/>) : null}
44
65
  {state.mode === 'url' ? (
45
- <InputGroup style={{flexGrow: "1", flexShrink: "1"}} inputRef={textInputRef as any} type="url" defaultValue={typeof state.value === 'string' ? state.value : ''}
66
+ <InputGroup style={{flexGrow: "1", flexShrink: "1"}} inputRef={textInputRef as any} type="url"
67
+ defaultValue={typeof state.value === 'string' ? state.value : ''}
46
68
  rightElement={(
47
- <Button disabled={state.readOnly} minimal={true} icon="arrow-right" onClick={()=>{
48
- onChange({mode:'url', value: textInputRef.current?.value??''})
49
- }} ></Button>
69
+ <Button disabled={state.readOnly} minimal={true} icon="arrow-right" onClick={() => {
70
+ onChange({mode: 'url', value: textInputRef.current?.value ?? ''})
71
+ }}></Button>
50
72
  )}
51
73
  disabled={state.disabled} readOnly={state.readOnly}
52
- onChange={(_)=>{
74
+ onChange={(_) => {
53
75
  }} placeholder="https://example.com/file.png"/>
54
76
  ) : (
55
- <FileInput inputProps={{ref: fileInputRef as any}} style={{flexGrow: "1", flexShrink: "1", minWidth: "50px"}}
77
+ <FileInput inputProps={{ref: fileInputRef as any}}
78
+ style={{flexGrow: "1", flexShrink: "1", minWidth: "50px"}}
56
79
  text={(state.value as File)?.name || 'No file'}
57
80
  disabled={state.disabled}
58
- onClick={(e)=>{
59
- if(state.readOnly) {
81
+ onClick={(e) => {
82
+ if (state.readOnly) {
60
83
  e.preventDefault()
61
84
  e.stopPropagation()
62
85
  }
63
86
  }}
64
87
  buttonText={state.readOnly ? '-' : state.value ? 'Change' : 'Choose'}
65
- onChange={()=>{
66
- onChange({mode: 'file', value: fileInputRef.current?.files?.[0]??null})
67
- }} className="inputGroupFile" />
88
+ onChange={() => {
89
+ onChange({mode: 'file', value: fileInputRef.current?.files?.[0] ?? null})
90
+ }} className="inputGroupFile"/>
68
91
  )}
69
92
  {!state.readOnly && state.value && (
70
- <Button minimal={true} icon="small-cross"
71
- disabled={state.disabled}
72
- onClick={()=>{
73
- onChange({value: null})
74
- }}></Button>
93
+ <Button minimal={true} icon="small-cross"
94
+ disabled={state.disabled}
95
+ loading={loadingState}
96
+ onClick={() => updateLoading(onChange({value: null}))
97
+ }></Button>
75
98
  )}
76
- </ControlGroup>
99
+ </ControlGroup>}
77
100
  </div>
78
101
  )
79
102
  }
@@ -1,5 +1,5 @@
1
1
  import {FormGroup} from "@blueprintjs/core";
2
- import React, {PropsWithChildren} from "react";
2
+ import {PropsWithChildren} from "react";
3
3
 
4
4
  export function FormGroupComponent(props: PropsWithChildren<{ label: string, flexBasis?: string, disabled?: boolean }>) {
5
5
  return (
@@ -1,14 +1,12 @@
1
1
  import React from "react";
2
- import {Button, Card, Panel, PanelStack2, Popover} from "@blueprintjs/core";
2
+ import {Card, Panel, PanelStack2} from "@blueprintjs/core";
3
3
  import {ConfigObject, ConfigProps} from "../ConfigObject";
4
4
  import {UiObjectConfig} from 'uiconfig.js'
5
5
  import {UiConfigRendererContext} from '../bpComponents/BPComponent'
6
- import {Classes} from '@blueprintjs/core/src/common'
7
- import {defaultVisualStyle, ThemeSettingsMenuComponent, VisualStyleContext} from './VisualStyleContext'
8
6
 
9
7
  // import {ViewerAppContext} from "./ViewerAppComponent";
10
8
 
11
- export function InspectorStackComponent({config}: { config: UiObjectConfig<any, 'panel'> }) {
9
+ export function InspectorStackComponent({config, className}: { config: UiObjectConfig<any, 'panel'>, className?: string }) {
12
10
  const renderer = React.useContext(UiConfigRendererContext)
13
11
  const stackItem = React.useCallback(() => {
14
12
  return {
@@ -29,44 +27,16 @@ export function InspectorStackComponent({config}: { config: UiObjectConfig<any,
29
27
  React.useEffect(() => {
30
28
  // console.warn('change', config)
31
29
  setCurrentPanelStack([stackItem()])
32
- }, [config])
33
-
34
- const localStoragePrefix = 'bpUi'
35
- const localStorageIds = {
36
- 'darkMode': localStoragePrefix + 'DarkMode',
37
- 'theme': localStoragePrefix + 'Theme',
38
- }
39
- const [darkMode, setDarkMode] = React.useState(localStorage.getItem(localStorageIds.darkMode) !== (defaultVisualStyle.darkMode ? 'false' : 'true'))
40
- React.useEffect(() => {
41
- localStorage.setItem('bpUiDarkMode', darkMode ? 'true' : 'false')
42
- }, [darkMode])
43
- const [theme, setTheme] = React.useState(localStorage.getItem(localStorageIds.theme) || defaultVisualStyle.theme)
44
- React.useEffect(() => {
45
- localStorage.setItem('bpUiTheme', theme)
46
- document.documentElement.classList.remove(...Object.keys(defaultVisualStyle.themes).map(k => k))
47
- document.documentElement.classList.add(theme)
48
- }, [theme])
30
+ }, [setCurrentPanelStack, stackItem])
49
31
 
50
32
  return (
51
- <VisualStyleContext.Provider value={{...defaultVisualStyle, darkMode, setDarkMode, theme, setTheme}}>
52
- <Card id="bpInspectorCard" className={darkMode?Classes.DARK:""} style={{height: "100%", flexGrow: "1", position: "relative"}}>
33
+ <Card className={"bpInspectorCard " + className||''} style={{borderRadius: 0}}>
53
34
  <PanelStack2 className="inspectorPanelStack"
54
35
  showPanelHeader={true}
55
36
  renderActivePanelOnly={true}
56
37
  onOpen={(p) => setCurrentPanelStack([...currentPanelStack, p] as any)}
57
38
  onClose={() => setCurrentPanelStack(currentPanelStack.slice(0, -1))}
58
39
  stack={currentPanelStack}/>
59
- <div className={"bpPanelStackHeaderOverlay " + Classes.PANEL_STACK2_HEADER}>
60
- <Popover targetProps={{style: {position: "absolute", right: "5px"}}}
61
- minimal={true}
62
- targetTagName={"div"}
63
- content={
64
- <ThemeSettingsMenuComponent/>
65
- } placement="bottom">
66
- <Button icon="cog" small minimal text="" />
67
- </Popover>
68
- </div>
69
40
  </Card>
70
- </VisualStyleContext.Provider>
71
41
  )
72
42
  }