uiconfig-blueprint 0.1.0-dev.13 → 0.1.0-dev.15

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 (167) hide show
  1. package/dist/ConfigObject.d.ts +3 -1
  2. package/dist/{allPaths-Dbwyd6G0.js → allPaths-vhUhWron.js} +5 -5
  3. package/dist/{allPaths-Dbwyd6G0.js.map → allPaths-vhUhWron.js.map} +1 -1
  4. package/dist/{allPathsLoader-B9DtnPQs.js → allPathsLoader-BeDEFia4.js} +4 -4
  5. package/dist/{allPathsLoader-B9DtnPQs.js.map → allPathsLoader-BeDEFia4.js.map} +1 -1
  6. package/dist/bpComponents/BPColorInputComponent.d.ts +1 -0
  7. package/dist/bpComponents/BPComponent.d.ts +2 -0
  8. package/dist/bpComponents/BPContainerComponent.d.ts +10 -2
  9. package/dist/bpComponents/BPDropdownInputComponent.d.ts +1 -0
  10. package/dist/bpComponents/BPFileComponent.d.ts +12 -10
  11. package/dist/bpComponents/BPFolderComponent.d.ts +13 -4
  12. package/dist/bpComponents/BPPanelComponent.d.ts +3 -3
  13. package/dist/bpComponents/BPTextInputComponent.d.ts +4 -0
  14. package/dist/bpComponents/BPValueComponent.d.ts +2 -2
  15. package/dist/bpComponents/BPVectorInputComponent.d.ts +11 -5
  16. package/dist/bpComponents/InputGroup2.d.ts +25 -0
  17. package/dist/components/DialogContext.d.ts +10 -3
  18. package/dist/components/DraggableIcon.d.ts +4 -3
  19. package/dist/components/FileComponent.d.ts +13 -6
  20. package/dist/components/FormGroupComponent.d.ts +3 -2
  21. package/dist/components/InspectorStackComponent.d.ts +11 -2
  22. package/dist/index-BaIbKicL.js +695 -0
  23. package/dist/index-BaIbKicL.js.map +1 -0
  24. package/dist/index-Bh4sHBxX.js +695 -0
  25. package/dist/index-Bh4sHBxX.js.map +1 -0
  26. package/dist/index-C8ABKThN.js +13501 -0
  27. package/dist/index-C8ABKThN.js.map +1 -0
  28. package/dist/index.js +28 -41
  29. package/dist/index.js.map +1 -1
  30. package/dist/index.mjs +2 -2
  31. package/dist/lib.d.ts +2 -3
  32. package/dist/{splitPathsBySizeLoader-Dii-Xb62.js → splitPathsBySizeLoader-CYAuGCeX.js} +5 -5
  33. package/dist/{splitPathsBySizeLoader-Dii-Xb62.js.map → splitPathsBySizeLoader-CYAuGCeX.js.map} +1 -1
  34. package/dist/utils/pointerLock.d.ts +44 -0
  35. package/docs/classes/UI.html +3 -3
  36. package/docs/classes/UiConfigRendererBlueprint.html +3 -3
  37. package/lib/css/renderer.css +35 -103
  38. package/lib/css/renderer.css.map +1 -1
  39. package/lib/esm/ConfigObject.d.ts +3 -1
  40. package/lib/esm/ConfigObject.js +5 -4
  41. package/lib/esm/ConfigObject.js.map +1 -1
  42. package/lib/esm/UiConfigRendererBlueprint.js +2 -1
  43. package/lib/esm/UiConfigRendererBlueprint.js.map +1 -1
  44. package/lib/esm/bpComponents/BPButtonComponent.js +1 -1
  45. package/lib/esm/bpComponents/BPButtonComponent.js.map +1 -1
  46. package/lib/esm/bpComponents/BPColorInputComponent.d.ts +1 -0
  47. package/lib/esm/bpComponents/BPColorInputComponent.js +17 -4
  48. package/lib/esm/bpComponents/BPColorInputComponent.js.map +1 -1
  49. package/lib/esm/bpComponents/BPComponent.d.ts +2 -0
  50. package/lib/esm/bpComponents/BPComponent.js +4 -4
  51. package/lib/esm/bpComponents/BPComponent.js.map +1 -1
  52. package/lib/esm/bpComponents/BPContainerComponent.d.ts +10 -2
  53. package/lib/esm/bpComponents/BPContainerComponent.js +4 -1
  54. package/lib/esm/bpComponents/BPContainerComponent.js.map +1 -1
  55. package/lib/esm/bpComponents/BPDropdownInputComponent.d.ts +1 -0
  56. package/lib/esm/bpComponents/BPDropdownInputComponent.js +5 -4
  57. package/lib/esm/bpComponents/BPDropdownInputComponent.js.map +1 -1
  58. package/lib/esm/bpComponents/BPFileComponent.d.ts +12 -10
  59. package/lib/esm/bpComponents/BPFileComponent.js +10 -8
  60. package/lib/esm/bpComponents/BPFileComponent.js.map +1 -1
  61. package/lib/esm/bpComponents/BPFolderComponent.d.ts +13 -4
  62. package/lib/esm/bpComponents/BPFolderComponent.js +58 -13
  63. package/lib/esm/bpComponents/BPFolderComponent.js.map +1 -1
  64. package/lib/esm/bpComponents/BPInputComponent.js +1 -1
  65. package/lib/esm/bpComponents/BPInputComponent.js.map +1 -1
  66. package/lib/esm/bpComponents/BPPanelComponent.d.ts +3 -3
  67. package/lib/esm/bpComponents/BPPanelComponent.js +1 -1
  68. package/lib/esm/bpComponents/BPPanelComponent.js.map +1 -1
  69. package/lib/esm/bpComponents/BPTextInputComponent.d.ts +4 -0
  70. package/lib/esm/bpComponents/BPTextInputComponent.js +34 -3
  71. package/lib/esm/bpComponents/BPTextInputComponent.js.map +1 -1
  72. package/lib/esm/bpComponents/BPTreeComponent.d.ts +4 -4
  73. package/lib/esm/bpComponents/BPTreeComponent.js +2 -2
  74. package/lib/esm/bpComponents/BPTreeComponent.js.map +1 -1
  75. package/lib/esm/bpComponents/BPValueComponent.d.ts +2 -2
  76. package/lib/esm/bpComponents/BPValueComponent.js +5 -4
  77. package/lib/esm/bpComponents/BPValueComponent.js.map +1 -1
  78. package/lib/esm/bpComponents/BPVectorInputComponent.d.ts +11 -5
  79. package/lib/esm/bpComponents/BPVectorInputComponent.js +47 -6
  80. package/lib/esm/bpComponents/BPVectorInputComponent.js.map +1 -1
  81. package/lib/esm/bpComponents/InputGroup2.d.ts +25 -0
  82. package/lib/esm/bpComponents/InputGroup2.js +93 -0
  83. package/lib/esm/bpComponents/InputGroup2.js.map +1 -0
  84. package/lib/esm/components/ConfigurationPanelComponent.js +1 -1
  85. package/lib/esm/components/ConfigurationPanelComponent.js.map +1 -1
  86. package/lib/esm/components/DialogContext.d.ts +10 -3
  87. package/lib/esm/components/DialogContext.js +14 -13
  88. package/lib/esm/components/DialogContext.js.map +1 -1
  89. package/lib/esm/components/DraggableIcon.d.ts +4 -3
  90. package/lib/esm/components/DraggableIcon.js +41 -39
  91. package/lib/esm/components/DraggableIcon.js.map +1 -1
  92. package/lib/esm/components/ExtendedNumericInput.js +1 -1
  93. package/lib/esm/components/ExtendedNumericInput.js.map +1 -1
  94. package/lib/esm/components/FileComponent.d.ts +13 -6
  95. package/lib/esm/components/FileComponent.js +15 -6
  96. package/lib/esm/components/FileComponent.js.map +1 -1
  97. package/lib/esm/components/FormGroupComponent.d.ts +3 -2
  98. package/lib/esm/components/FormGroupComponent.js +1 -6
  99. package/lib/esm/components/FormGroupComponent.js.map +1 -1
  100. package/lib/esm/components/InspectorStackComponent.d.ts +11 -2
  101. package/lib/esm/components/InspectorStackComponent.js +14 -4
  102. package/lib/esm/components/InspectorStackComponent.js.map +1 -1
  103. package/lib/esm/components/NumericInput.js +3 -2
  104. package/lib/esm/components/NumericInput.js.map +1 -1
  105. package/lib/esm/components/TreeNode2.d.ts +1 -1
  106. package/lib/esm/components/TreeNode2.js +4 -2
  107. package/lib/esm/components/TreeNode2.js.map +1 -1
  108. package/lib/esm/components/treeTypes.d.ts +2 -1
  109. package/lib/esm/lib.d.ts +2 -3
  110. package/lib/esm/lib.js +2 -3
  111. package/lib/esm/lib.js.map +1 -1
  112. package/lib/esm/renderer.css.js +1 -1
  113. package/lib/esm/utils/pointerLock.d.ts +44 -0
  114. package/lib/esm/utils/pointerLock.js +215 -0
  115. package/lib/esm/utils/pointerLock.js.map +1 -0
  116. package/lib/esm/utils.js +6 -1
  117. package/lib/esm/utils.js.map +1 -1
  118. package/package.json +10 -12
  119. package/src/ConfigObject.tsx +11 -5
  120. package/src/UiConfigRendererBlueprint.tsx +1 -1
  121. package/src/bpComponents/BPButtonComponent.tsx +1 -1
  122. package/src/bpComponents/BPColorInputComponent.tsx +13 -4
  123. package/src/bpComponents/BPComponent.tsx +4 -3
  124. package/src/bpComponents/BPContainerComponent.tsx +20 -3
  125. package/src/bpComponents/BPDropdownInputComponent.tsx +6 -4
  126. package/src/bpComponents/BPFileComponent.tsx +29 -20
  127. package/src/bpComponents/BPFolderComponent.scss +11 -6
  128. package/src/bpComponents/BPFolderComponent.tsx +122 -24
  129. package/src/bpComponents/BPInputComponent.tsx +1 -0
  130. package/src/bpComponents/BPPanelComponent.tsx +4 -4
  131. package/src/bpComponents/BPTextInputComponent.tsx +38 -5
  132. package/src/bpComponents/BPValueComponent.tsx +4 -4
  133. package/src/bpComponents/BPVectorInputComponent.tsx +80 -10
  134. package/src/bpComponents/InputGroup2.tsx +175 -0
  135. package/src/bpComponents/index.scss +0 -1
  136. package/src/components/ConfigurationPanelComponent.tsx +2 -2
  137. package/src/components/DialogContext.tsx +20 -12
  138. package/src/components/DraggableIcon.tsx +71 -49
  139. package/src/components/ExtendedNumericInput.tsx +2 -2
  140. package/src/components/FileComponent.tsx +37 -18
  141. package/src/components/FormGroupComponent.tsx +8 -4
  142. package/src/components/InspectorStackComponent.tsx +20 -7
  143. package/src/components/NumericInput.tsx +4 -5
  144. package/src/components/common.scss +1 -1
  145. package/src/lib.ts +2 -3
  146. package/src/renderer.scss +30 -8
  147. package/src/utils/PointerLockManager.md +334 -0
  148. package/src/utils/pointerLock.ts +264 -0
  149. package/src/utils.ts +8 -4
  150. package/dist/bpComponents/BPTreeComponent.d.ts +0 -46
  151. package/dist/bpComponents/BPTreeFolderComponent.d.ts +0 -10
  152. package/dist/components/Tree2.d.ts +0 -52
  153. package/dist/components/TreeNode2.d.ts +0 -43
  154. package/dist/components/treeTypes.d.ts +0 -18
  155. package/dist/index-BFBvfUPU.js +0 -671
  156. package/dist/index-BFBvfUPU.js.map +0 -1
  157. package/dist/index-CHQ1fP9-.js +0 -671
  158. package/dist/index-CHQ1fP9-.js.map +0 -1
  159. package/dist/index-Dbe8gLld.js +0 -13583
  160. package/dist/index-Dbe8gLld.js.map +0 -1
  161. package/src/bpComponents/BPTreeComponent.scss +0 -3
  162. package/src/bpComponents/BPTreeComponent.tsx +0 -244
  163. package/src/bpComponents/BPTreeFolderComponent.tsx +0 -31
  164. package/src/components/Tree2.tsx +0 -344
  165. package/src/components/TreeNode2.tsx +0 -192
  166. package/src/components/tree2.scss +0 -69
  167. package/src/components/treeTypes.ts +0 -97
@@ -1,24 +1,27 @@
1
- import {FileComponent} from "../components/FileComponent";
1
+ import {FileComponent, FileComponentProps} from "../components/FileComponent";
2
2
  import {BPComponentProps, UiConfigRendererContextType} from "./BPComponent";
3
3
  import {BPValueComponent, BPValueComponentState} from "./BPValueComponent";
4
4
  import {FormGroupComponent} from "../components/FormGroupComponent";
5
5
 
6
6
  type StateValue = string | File | null
7
7
  type FileImportType = any
8
- export type BPFileComponentState = BPValueComponentState<StateValue> & {
9
- mode: 'url'|'file',
8
+ export type BPFileComponentState<TSV=never> = BPValueComponentState<TSV|StateValue> & {
9
+ mode: 'url'|'file'|'asset',
10
10
  preview?: string,
11
11
  }
12
12
 
13
- type BPFileComponentExtras = {fileLoader?: {load: (v: string|File|{path: string, file: File|Blob})=>Promise<FileImportType>}}
14
- type BPFileComponentContextType = UiConfigRendererContextType & BPFileComponentExtras
13
+ type BPFileComponentProps<TSV=never> = {
14
+ fileLoader?: {load: (v: string|File|{path: string, file: File|Blob})=>Promise<FileImportType>},
15
+ AssetPicker?: FileComponentProps<TSV>['AssetPicker']
16
+ }
17
+ type BPFileComponentContextType<TSV=never> = UiConfigRendererContextType & BPFileComponentProps<TSV>
15
18
 
16
19
  // todo make this abstract?
17
20
  // @ts-ignore
18
- export class BPFileComponent<T extends FileImportType=FileImportType, TP = {}> extends BPValueComponent<T | null, BPFileComponentState, StateValue> {
19
- declare context: BPFileComponentContextType
20
- declare props: BPComponentProps<T | null> & BPFileComponentExtras & TP
21
- constructor(props: BPComponentProps<T | null> & BPFileComponentExtras & TP, context: BPFileComponentContextType) {
21
+ export class BPFileComponent<T extends FileImportType=FileImportType, TP = {}, TSV = never> extends BPValueComponent<T | null, BPFileComponentState<TSV>, TSV|StateValue> {
22
+ declare context: BPFileComponentContextType<TSV>
23
+ declare props: BPComponentProps<T | null> & BPFileComponentProps<TSV> & TP
24
+ constructor(props: BPComponentProps<T | null> & BPFileComponentProps<TSV> & TP, context: BPFileComponentContextType<TSV>) {
22
25
  super(props, context, {
23
26
  mode: 'url',
24
27
  value: null,
@@ -28,7 +31,7 @@ export class BPFileComponent<T extends FileImportType=FileImportType, TP = {}> e
28
31
  }
29
32
 
30
33
  // reimplemented in subclass
31
- convertValueToState(_val: T | null, _state: BPFileComponentState): BPFileComponentState {
34
+ convertValueToState(_val: T | null, _state: BPFileComponentState<TSV>): BPFileComponentState<TSV> {
32
35
  throw new Error('Not Implemented')
33
36
  // let mode: BPFileComponentState['mode'] = state.mode
34
37
  // let value = state.value
@@ -46,19 +49,19 @@ export class BPFileComponent<T extends FileImportType=FileImportType, TP = {}> e
46
49
  // return {...state, mode, value}
47
50
  }
48
51
 
49
- async convertStateToValue(state: BPFileComponentState): Promise<T|null> {
52
+ async convertStateToValue(state: BPFileComponentState<TSV>): Promise<T|null> {
50
53
  const value = state.value
54
+ if(!value) return null
51
55
  let val: any
52
56
  const last = this.context.methods.getRawValue(this.props.config as any) ?? null
53
57
  const lastState = this.convertValueToState(last as any, {...this.state, value: null})
54
- if (value === null) {
55
- val = null
56
- } else if (typeof value === 'string') {
58
+ if (typeof value === 'string') {
57
59
  val = value === lastState.value ? last : await (this.context.fileLoader ?? this.props.fileLoader)!.load(value);
58
- } else {
60
+ } else if(typeof (value as File).arrayBuffer === 'function'){
61
+ const file = (value as File)
59
62
  // todo handle blob with no name
60
- val = value === lastState.value ? last : await (this.context.fileLoader ?? this.props.fileLoader)!.load({path: value.name || 'file', file: value});
61
- }
63
+ val = file === lastState.value ? last : await (this.context.fileLoader ?? this.props.fileLoader)!.load({path: file.name || 'file', file: file});
64
+ }else val = value
62
65
  // console.log(val)
63
66
  return val;
64
67
  }
@@ -91,9 +94,15 @@ export class BPFileComponent<T extends FileImportType=FileImportType, TP = {}> e
91
94
  disabled={this.state.disabled}
92
95
  flexBasis={this.state.baseWidth ?? this.flexBasis}
93
96
  >
94
- <FileComponent previewSlot={this.renderPreviewSlot()} state={this.state} onChange={(s) =>
95
- this.updateStateValue({...this.state, preview: undefined, ...s}) // todo: set loading while this promise is happening.
96
- } key={this.props.config.uuid}/>
97
+ <FileComponent<TSV>
98
+ previewSlot={this.renderPreviewSlot()}
99
+ state={this.state} // ignore ts f
100
+ onChange={(s) =>
101
+ this.updateStateValue({...this.state, preview: undefined, ...s}) // todo: set loading while this promise is happening.
102
+ }
103
+ key={this.props.config.uuid}
104
+ AssetPicker={this.props.AssetPicker ?? this.context.AssetPicker} // todo which one first?
105
+ />
97
106
  </FormGroupComponent>
98
107
  ) : null
99
108
  }
@@ -47,9 +47,11 @@
47
47
  //}
48
48
 
49
49
 
50
- .folder-trigger-button {
50
+ .folder-trigger-text {
51
51
  font-size: 12px !important;
52
52
  font-weight: 550 !important;
53
+ }
54
+ .folder-trigger-button {
53
55
 
54
56
  margin-top: 1px;
55
57
  display: flex;
@@ -102,8 +104,8 @@
102
104
  //margin-right: $pt-grid-size;
103
105
  margin-right: 6px;
104
106
  //margin-left: $pt-grid-size;
105
- padding-top: 6px;
106
- padding-bottom: 6px;
107
+ padding-top: 8px;
108
+ padding-bottom: 8px;
107
109
  min-height: 36px;
108
110
  }
109
111
  }
@@ -116,6 +118,12 @@
116
118
  //box-shadow: 0 1px $pt-divider-black;
117
119
  //z-index: 1;
118
120
 
121
+ > .folder-trigger-button {
122
+ padding-top: 8px;
123
+ padding-bottom: 8px;
124
+ min-height: 36px;
125
+ }
126
+
119
127
  > button {
120
128
  border-radius: 0;
121
129
  }
@@ -131,7 +139,4 @@
131
139
  font-size: var(--pt-font-size-small);
132
140
  }
133
141
 
134
- .bp5-button{
135
- font-size: var(--pt-font-size-small);
136
- }
137
142
  }
@@ -1,10 +1,19 @@
1
1
  import React, {ChangeEventHandler, DOMAttributes} from "react";
2
2
  import {BPComponentProps, UiConfigRendererContextType} from "./BPComponent";
3
- import {Button, Checkbox, Collapse, Icon, Intent} from "@blueprintjs/core";
3
+ import {
4
+ Button,
5
+ Checkbox,
6
+ Collapse,
7
+ Divider,
8
+ Icon,
9
+ IconName,
10
+ Intent,
11
+ MaybeElement, Menu, MenuItem, Popover
12
+ } from "@blueprintjs/core";
4
13
  import {ConfigObject} from "../ConfigObject";
5
14
  import {PanelActions} from "@blueprintjs/core/lib/esm/components/panel-stack2/panelTypes";
6
- import {safeSetProperty} from 'ts-browser-helpers'
7
- import {BPContainerComponent, BPContainerComponentState} from './BPContainerComponent'
15
+ import {getOrCall, safeSetProperty} from 'ts-browser-helpers'
16
+ import {BPContainerComponent, BPContainerComponentState, BPContainerComponentProps} from './BPContainerComponent'
8
17
  import classNames from "classnames";
9
18
  import {Classes} from "@blueprintjs/core/src/common";
10
19
  import {AnimationStates} from "@blueprintjs/core/lib/esm/components/collapse/collapse";
@@ -12,41 +21,80 @@ import {AnimationStates} from "@blueprintjs/core/lib/esm/components/collapse/col
12
21
  export type BPFolderComponentState = BPContainerComponentState & {
13
22
  }
14
23
 
15
- export class BPFolderComponent extends BPContainerComponent<BPFolderComponentState> {
16
- constructor(props: BPComponentProps<void>&PanelActions, context: UiConfigRendererContextType) {
24
+ export type BPFolderComponentProps = BPContainerComponentProps & {
25
+ icon?: IconName | MaybeElement
26
+ }
27
+
28
+
29
+ export class BPFolderComponent extends BPContainerComponent<BPFolderComponentState, BPFolderComponentProps> {
30
+ constructor(props: BPComponentProps<void>&PanelActions&BPFolderComponentProps, context: UiConfigRendererContextType) {
17
31
  super(props, context, {children: [], expanded: false, label: 'Folder'});
18
32
  }
19
33
 
20
34
  render() {
35
+ const {
36
+ icon,
37
+ config,
38
+ level,
39
+ filter,
40
+ ...props
41
+ } = this.props
42
+
21
43
  const setExpanded = (e: boolean) => {
22
44
  if (e === this.state.expanded) return
23
45
  this.setState({...this.state, expanded: e})
24
- safeSetProperty(this.props.config, "expanded", e, true)
46
+ safeSetProperty(config, "expanded", e, true)
25
47
  // if (e) this.state.children.forEach(c => Array.isArray(c) ? null : c.uiRefresh?.("postFrame", true, 1)) // todo: handle array and functions
26
48
  }
27
- const children = this.state.children
49
+ let children = this.state.children
28
50
  const enabledToggle = children[0] && this.context.methods.getBinding(children[0])[1] === 'enabled' ? children[0] : undefined
29
- enabledToggle && (enabledToggle.hidden = true)
51
+ if(enabledToggle) children = children.slice(1)
52
+
53
+ const ctxMenuBtns = children.filter(c=>{
54
+ return c.type === 'button' && c.tags?.includes('context-menu')
55
+ })
56
+ let endIcon: MaybeElement = undefined
57
+ if(ctxMenuBtns.length > 0){
58
+ children = children.filter(c=>!ctxMenuBtns.includes(c))
59
+ endIcon = (
60
+ <Popover
61
+ content={<ContextMenu buttons={ctxMenuBtns} context={this.context} />}
62
+ placement="bottom-end"
63
+ >
64
+ <Button
65
+ icon="more"
66
+ variant={"minimal"}
67
+ size={"small"}
68
+ />
69
+ </Popover>
70
+ )
71
+ }
72
+
30
73
  return !this.state.hidden ? (
31
74
  <FolderHeadCard
32
- key={this.props.config.uuid}
75
+ key={config.uuid}
33
76
  open={this.state.expanded}
34
77
  disabled={this.state.disabled}
35
- level={this.props.level ?? 0}
36
- minimal={(this.props.level ?? 0) > 0}
78
+ level={level ?? 0}
79
+ minimal={(level ?? 0) > 0}
37
80
  onClick={() => {
38
81
  if(this.state.readOnly) return
39
82
  setExpanded(!this.state.expanded)
40
83
  }}
84
+ icon={icon}
85
+ endIcon={endIcon}
41
86
  label={this.state.label}
42
87
  enabled={enabledToggle ? this.context.methods.getRawValue(enabledToggle) : undefined}
43
88
  onEnabledChange={(e) => enabledToggle && this.context.methods.setValue(enabledToggle, e.target.checked, {}).then(() => this.setState(this.state))}
44
89
  >
45
90
  <Collapse2 isOpen={this.state.expanded} keepChildrenMounted={true} transitionDuration={300}>
46
- <div className="folder-children" style={{listStyleType: "none", paddingLeft: this.props.level??0 > 2 ? "6px" : 0}}> {/*todo use parameter instead of const 6*/}
91
+ <div className="folder-children" style={{
92
+ listStyleType: "none",
93
+ paddingLeft: level??0 > 2 ? "6px" : 0}
94
+ }> {/*todo use parameter instead of const 6*/}
47
95
  {children.map((c, i) =>
48
- <ConfigObject key={'c' + i} {...this.props} config={c}
49
- level={(this.props.level ?? 0) + 1}/>
96
+ <ConfigObject key={'c' + i} {...props} config={c}
97
+ level={(level ?? 0) + 1}/>
50
98
  )}
51
99
  </div>
52
100
  </Collapse2>
@@ -55,7 +103,15 @@ export class BPFolderComponent extends BPContainerComponent<BPFolderComponentSta
55
103
  }
56
104
  }
57
105
 
58
- export const FolderHeadCard: React.FC<React.PropsWithChildren<{ open: boolean, label: string, minimal: boolean, level: number, disabled?: boolean, enabled?: boolean, onEnabledChange?: ChangeEventHandler<HTMLInputElement>, onClick: DOMAttributes<HTMLElement>['onClick'] }>> = (props) => {
106
+ export const FolderHeadCard: React.FC<React.PropsWithChildren<{
107
+ open: boolean, label: string,
108
+ minimal: boolean, level: number,
109
+ disabled?: boolean,
110
+ enabled?: boolean, onEnabledChange?: ChangeEventHandler<HTMLInputElement>,
111
+ onClick: DOMAttributes<HTMLElement>['onClick']
112
+ icon?: IconName | MaybeElement
113
+ endIcon?: IconName | MaybeElement
114
+ }>> = (props) => {
59
115
  const hasEnabled = (props.enabled !== undefined)
60
116
  return (
61
117
  <div
@@ -63,7 +119,13 @@ export const FolderHeadCard: React.FC<React.PropsWithChildren<{ open: boolean, l
63
119
  className="folder-card"
64
120
  // elevation={props.open ? 3 : undefined}
65
121
  >
66
- <div className={props.minimal ? 'folder-head-card-minimal' : 'folder-head-card'}>
122
+ {props.level === 0 &&
123
+ <Divider style={{margin: 0}}/>
124
+ }
125
+ <div className={props.minimal ? 'folder-head-card-minimal' : 'folder-head-card'} style={{
126
+ paddingTop: props.level > 0 ? "unset" : undefined,
127
+ paddingBottom: props.level > 0 ? "unset" : undefined,
128
+ }}>
67
129
  {/*<H6 className="folder-head-label"*/}
68
130
  {/* onClick={props.onClick}>{props.label}</H6>*/}
69
131
  {/*<Icon icon="chevron-right" style={{*/}
@@ -71,9 +133,9 @@ export const FolderHeadCard: React.FC<React.PropsWithChildren<{ open: boolean, l
71
133
  {/* transition: "rotate 0.25s ease-in-out"*/}
72
134
  {/*}} className="folder-head-label-icon"/>*/}
73
135
 
74
- {/*<Button className="folder-trigger-button" onClick={props.onClick}*/}
75
- {/* fill={true} minimal={true}*/}
76
- {/* rightIcon={(*/}
136
+ {/*<Button className="folder-trigger-button folder-trigger-text" onClick={props.onClick}*/}
137
+ {/* fill={true} variant={"minimal"}*/}
138
+ {/* endIcon={(*/}
77
139
  {/* <Icon icon="chevron-right" style={{*/}
78
140
  {/* rotate: props.open ? "90deg" : "0deg",*/}
79
141
  {/* transition: "rotate 0.25s ease-in-out"*/}
@@ -82,18 +144,18 @@ export const FolderHeadCard: React.FC<React.PropsWithChildren<{ open: boolean, l
82
144
  {/*</Button>*/}
83
145
 
84
146
  <Button
85
- className={"folder-trigger-button " + (props.open ? "folder-trigger-button-expanded" : "")}
147
+ className={"folder-trigger-button folder-trigger-text " + (props.open ? "folder-trigger-button-expanded" : "")}
86
148
  // fill={!props.minimal}
87
149
  fill={true}
88
150
  onClick={props.onClick}
89
- minimal={true}
151
+ variant={"minimal"}
90
152
  disabled={props.disabled}
91
- small={props.minimal}
153
+ size={props.minimal?"small":"medium"}
92
154
  style={props.level ? {marginLeft: "6px"} : {fontSize: "0.95rem", paddingTop: "8px", paddingBottom: "8px"}}
93
155
  // intent={props.open ? Intent.PRIMARY : Intent.NONE}
94
156
  intent={Intent.NONE}
95
157
  // icon={props.enabled !== undefined && <span style={{minWidth: '20px'}}></span>} // adding a span here will center the text in the button
96
- icon={(
158
+ icon={props.icon ?? (
97
159
  <>
98
160
  <Icon icon="caret-right" style={{
99
161
  rotate: props.open ? "90deg" : "0deg",
@@ -105,12 +167,15 @@ export const FolderHeadCard: React.FC<React.PropsWithChildren<{ open: boolean, l
105
167
  </Button>
106
168
  {hasEnabled && <Checkbox
107
169
  style={{margin: 0, position: 'absolute', left: '10px'}}
108
- large inline
170
+ inline size={"large"}
109
171
  defaultChecked={props.enabled}
110
172
  onChange={props.onEnabledChange}
111
173
  disabled={props.disabled}
112
174
  onClick={(e) => e.stopPropagation()}
113
175
  />}
176
+ {props.endIcon && <div style={{position: 'absolute', right: '10px'}}>
177
+ {props.endIcon}
178
+ </div>}
114
179
  </div>
115
180
  {props.children}
116
181
  </div>
@@ -180,3 +245,36 @@ export class Collapse2 extends Collapse{
180
245
  }
181
246
 
182
247
  }
248
+
249
+ export const ContextMenu: React.FC<{
250
+ buttons: any[];
251
+ context: UiConfigRendererContextType;
252
+ }> = ({ buttons, context }) => {
253
+ return (
254
+ <Menu>
255
+ {buttons.map((btn, i) => {
256
+ const getProps = ()=>{ // todo use UiConfigMethods.getBaseProps
257
+ const hidden = getOrCall(btn.hidden) ?? false
258
+ const disabled = getOrCall(btn.disabled) ?? false
259
+ const readOnly = getOrCall(btn.readOnly) ?? false
260
+ return { hidden, disabled, readOnly }
261
+ }
262
+ const props = getProps()
263
+ return props.hidden ? null : (
264
+ <MenuItem
265
+ key={'ctx' + i}
266
+ disabled={props.disabled || props.readOnly}
267
+ text={context.methods.getLabel(btn)}
268
+ onClick={(e) => {
269
+ e.stopPropagation();
270
+ const {hidden, disabled, readOnly} = getProps()
271
+ if (hidden || disabled || readOnly) return;
272
+ // todo loading state for promise
273
+ context.methods.clickButton(btn, { args: [e] });
274
+ }}
275
+ />
276
+ );
277
+ })}
278
+ </Menu>
279
+ );
280
+ };
@@ -29,6 +29,7 @@ export abstract class BPInputComponent<
29
29
  <FormGroupComponent disabled={this.state.disabled}
30
30
  label={this.state.label}
31
31
  flexBasis={this.state.baseWidth ?? this.flexBasis}
32
+ key={this.props.config.uuid}
32
33
  >
33
34
  {this.renderInput()}
34
35
  </FormGroupComponent>
@@ -4,15 +4,15 @@ import {BPLabelledComponentState} from "./BPLabelledComponent";
4
4
  import {PanelActions} from "@blueprintjs/core/lib/esm/components/panel-stack2/panelTypes";
5
5
  import {UiObjectConfig} from 'uiconfig.js'
6
6
  import {safeSetProperty} from 'ts-browser-helpers'
7
- import {BPContainerComponent} from './BPContainerComponent'
7
+ import {BPContainerComponent, BPContainerComponentProps} from './BPContainerComponent'
8
8
 
9
9
  export type BPPanelComponentState = BPLabelledComponentState & {
10
10
  children: UiObjectConfig[]
11
11
  expanded: boolean
12
12
  }
13
13
 
14
- export class BPPanelComponent extends BPContainerComponent<BPPanelComponentState> {
15
- constructor(props: BPComponentProps<void>&PanelActions, context: UiConfigRendererContextType) {
14
+ export class BPPanelComponent extends BPContainerComponent<BPPanelComponentState, BPContainerComponentProps> {
15
+ constructor(props: BPComponentProps<void>&PanelActions&BPContainerComponentProps, context: UiConfigRendererContextType) {
16
16
  super(props, context, {
17
17
  children: [],
18
18
  expanded: false,
@@ -41,7 +41,7 @@ export class BPPanelComponent extends BPContainerComponent<BPPanelComponentState
41
41
  return !this.state.hidden ? (
42
42
  <div
43
43
  key={this.props.config.uuid}
44
- className="folder-children" style={{listStyleType: "none", paddingLeft: "0"}}>
44
+ className="folder-children" style={{listStyleType: "none", paddingLeft: "0", overflowAnchor: 'none', paddingBottom: '400px'}}>
45
45
  {this.state.children.map((c, i) => c ? <ConfigObject key={'c' + i} {...this.props} config={c}/> : null)}
46
46
  </div>
47
47
  ) : null
@@ -1,22 +1,55 @@
1
- import {ChangeEventHandler} from "react";
1
+ import React, {ChangeEventHandler} from "react";
2
2
  import {BPComponentProps, UiConfigRendererContextType} from "./BPComponent";
3
- import {InputGroup} from "@blueprintjs/core";
3
+ import {InputGroup, TextArea} from "@blueprintjs/core";
4
4
  import {BPInputComponent} from "./BPInputComponent";
5
+ import {BPValueComponentState} from "./BPValueComponent";
5
6
 
6
7
  export class BPTextInputComponent extends BPInputComponent<string> {
7
8
  constructor(props: BPComponentProps<string>, context: UiConfigRendererContextType) {
8
9
  super(props, context, {value: '', label: 'Input'});
9
10
  }
10
11
 
12
+ private _inputRef = React.createRef<HTMLInputElement|HTMLTextAreaElement>()
13
+
14
+ private _iv = 0
15
+ async refreshConfigState(state?: BPValueComponentState<string>): Promise<void> {
16
+ const iv = this._iv
17
+ await super.refreshConfigState(state);
18
+ if(iv === this._iv) {
19
+ if (this._inputRef.current && this._inputRef.current.value !== this.state.value)
20
+ this._inputRef.current.value = this.state.value
21
+ }
22
+ }
23
+
11
24
  private _onChange: ChangeEventHandler<HTMLInputElement> = (e) => {
12
- this.setValue(e.target.value); // todo: set loading while this promise is happening.
25
+ this._iv+=1
26
+ this.setValue(e.target.value, false); // todo: set loading while this promise is happening.
13
27
  }
14
28
 
15
29
  renderInput() {
30
+ const config = this.props.config as any;
31
+ const isMultiline = config.multiline === true;
32
+
33
+ if (isMultiline) {
34
+ return (
35
+ <TextArea
36
+ defaultValue={this.state.value}
37
+ inputRef={this._inputRef as any}
38
+ disabled={this.state.disabled}
39
+ readOnly={this.state.readOnly}
40
+ key={this.props.config.uuid}
41
+ fill={true}
42
+ rows={config.rows}
43
+ cols={config.cols}
44
+ autoResize={config.autoResize}
45
+ onChange={this._onChange as any}/>
46
+ )
47
+ }
48
+
16
49
  return (
17
50
  <InputGroup
18
- // defaultValue={this.state.value} // for uncontrolled usage, we will also need ref and set ref.value on change: https://reactjs.org/docs/uncontrolled-components.html
19
- value={this.state.value}
51
+ defaultValue={this.state.value}
52
+ inputRef={this._inputRef as any}
20
53
  disabled={this.state.disabled}
21
54
  readOnly={this.state.readOnly}
22
55
  key={this.props.config.uuid}
@@ -49,13 +49,13 @@ export abstract class BPValueComponent<TValue extends PrimitiveVal, TState exten
49
49
  super.setState(state, callback);
50
50
  }
51
51
 
52
- async setValue(value: TStateValue, last?: boolean) {
53
- return this.updateStateValue({...this.state, value}, last)
52
+ async setValue(value: TStateValue, last?: boolean, refreshState = true) {
53
+ return this.updateStateValue({...this.state, value}, last, refreshState)
54
54
  }
55
55
 
56
56
  forceOnChange: boolean = false
57
57
 
58
- async updateStateValue(state: TState, last?: boolean) {
58
+ async updateStateValue(state: TState, last?: boolean, refreshState = true) {
59
59
  if (!this.doesNeedRefresh(state, last)) {
60
60
  await this.setStatePromise(state)
61
61
  return
@@ -63,7 +63,7 @@ export abstract class BPValueComponent<TValue extends PrimitiveVal, TState exten
63
63
  let val = await this.convertStateToValue(state)
64
64
  this._lastValRef = val
65
65
  await this.context.methods.setValue(this.props.config, val, {last}, this.forceOnChange)
66
- await this.refreshConfigState(state)
66
+ if(refreshState) await this.refreshConfigState(state)
67
67
  }
68
68
 
69
69
  }