@instructure/ui-editable 8.25.1-snapshot-13 → 8.25.1-snapshot-14
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/CHANGELOG.md +1 -1
- package/es/Editable/index.js +13 -13
- package/es/Editable/props.js +0 -40
- package/es/InPlaceEdit/index.js +18 -12
- package/es/InPlaceEdit/props.js +0 -70
- package/lib/Editable/index.js +13 -13
- package/lib/Editable/props.js +0 -40
- package/lib/InPlaceEdit/index.js +18 -12
- package/lib/InPlaceEdit/props.js +0 -70
- package/package.json +13 -13
- package/src/Editable/index.tsx +33 -42
- package/src/Editable/props.ts +78 -31
- package/src/InPlaceEdit/index.tsx +29 -26
- package/src/InPlaceEdit/props.ts +62 -37
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/Editable/index.d.ts +30 -49
- package/types/Editable/index.d.ts.map +1 -1
- package/types/Editable/props.d.ts +75 -5
- package/types/Editable/props.d.ts.map +1 -1
- package/types/InPlaceEdit/index.d.ts +45 -38
- package/types/InPlaceEdit/index.d.ts.map +1 -1
- package/types/InPlaceEdit/props.d.ts +86 -5
- package/types/InPlaceEdit/props.d.ts.map +1 -1
package/src/Editable/index.tsx
CHANGED
|
@@ -21,20 +21,27 @@
|
|
|
21
21
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
|
-
import { Component } from 'react'
|
|
24
|
+
import React, { Component } from 'react'
|
|
25
25
|
|
|
26
26
|
import { deepEqual } from '@instructure/ui-utils'
|
|
27
27
|
import { logWarn as warn } from '@instructure/console'
|
|
28
28
|
import { requestAnimationFrame } from '@instructure/ui-dom-utils'
|
|
29
29
|
|
|
30
|
-
import { propTypes, allowedProps } from './props'
|
|
31
|
-
import type {
|
|
30
|
+
import { propTypes, allowedProps, EditableState } from './props'
|
|
31
|
+
import type {
|
|
32
|
+
EditableProps,
|
|
33
|
+
GetContainerProps,
|
|
34
|
+
GetEditButtonProps,
|
|
35
|
+
GetEditorProps,
|
|
36
|
+
GetViewerProps
|
|
37
|
+
} from './props'
|
|
32
38
|
|
|
33
39
|
/**
|
|
34
40
|
---
|
|
35
41
|
category: components
|
|
36
42
|
experimental: true
|
|
37
43
|
---
|
|
44
|
+
@tsProps
|
|
38
45
|
**/
|
|
39
46
|
class Editable extends Component<EditableProps> {
|
|
40
47
|
static propTypes = propTypes
|
|
@@ -44,16 +51,15 @@ class Editable extends Component<EditableProps> {
|
|
|
44
51
|
children: null
|
|
45
52
|
}
|
|
46
53
|
|
|
47
|
-
state = {
|
|
54
|
+
state: EditableState = {
|
|
48
55
|
showModeToggle: false,
|
|
49
56
|
valueOnEdit: null // the value when mode flips from view -> edit
|
|
50
57
|
}
|
|
51
58
|
|
|
52
|
-
_editorRef = null
|
|
53
|
-
_editButtonRef = null
|
|
59
|
+
_editorRef: HTMLInputElement | null = null
|
|
60
|
+
_editButtonRef: HTMLButtonElement | null = null
|
|
54
61
|
|
|
55
|
-
|
|
56
|
-
constructor(props) {
|
|
62
|
+
constructor(props: EditableProps) {
|
|
57
63
|
super(props)
|
|
58
64
|
|
|
59
65
|
warn(
|
|
@@ -67,10 +73,8 @@ class Editable extends Component<EditableProps> {
|
|
|
67
73
|
this.focusEditor()
|
|
68
74
|
}
|
|
69
75
|
}
|
|
70
|
-
componentWillUnmount() {}
|
|
71
76
|
|
|
72
|
-
|
|
73
|
-
componentDidUpdate(prevProps) {
|
|
77
|
+
componentDidUpdate(prevProps: EditableProps) {
|
|
74
78
|
const { mode, value, onChange } = this.props
|
|
75
79
|
|
|
76
80
|
// on the switch from view -> edit
|
|
@@ -81,7 +85,6 @@ class Editable extends Component<EditableProps> {
|
|
|
81
85
|
|
|
82
86
|
// on the switch from edit to view
|
|
83
87
|
if (prevProps.mode === 'edit' && mode !== 'edit') {
|
|
84
|
-
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
|
|
85
88
|
this._editButtonRef && this._editButtonRef.focus()
|
|
86
89
|
if (onChange && !deepEqual(this.state.valueOnEdit, value)) {
|
|
87
90
|
onChange(value)
|
|
@@ -95,7 +98,6 @@ class Editable extends Component<EditableProps> {
|
|
|
95
98
|
'[Editable] Did you forget to connect editorRef to your editor component?'
|
|
96
99
|
)
|
|
97
100
|
if (this._editorRef) {
|
|
98
|
-
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
|
|
99
101
|
this._editorRef.focus()
|
|
100
102
|
}
|
|
101
103
|
}
|
|
@@ -116,15 +118,13 @@ class Editable extends Component<EditableProps> {
|
|
|
116
118
|
}
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
|
|
120
|
-
handleEditESC = (event) => {
|
|
121
|
+
handleEditESC = (event: React.KeyboardEvent) => {
|
|
121
122
|
if (event.key === 'Escape') {
|
|
122
123
|
this.enterView()
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
126
|
|
|
126
|
-
|
|
127
|
-
handleViewMouseOver = (event) => {
|
|
127
|
+
handleViewMouseOver = (event: React.MouseEvent) => {
|
|
128
128
|
if (this.props.mode === 'view') {
|
|
129
129
|
// because the mouse event handlers are on the container, not the view
|
|
130
130
|
event.stopPropagation()
|
|
@@ -132,8 +132,7 @@ class Editable extends Component<EditableProps> {
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
|
|
136
|
-
handleViewMouseOut = (event) => {
|
|
135
|
+
handleViewMouseOut = (event: React.MouseEvent) => {
|
|
137
136
|
if (this.props.mode === 'view') {
|
|
138
137
|
event.stopPropagation()
|
|
139
138
|
this.setState({
|
|
@@ -142,8 +141,7 @@ class Editable extends Component<EditableProps> {
|
|
|
142
141
|
}
|
|
143
142
|
}
|
|
144
143
|
|
|
145
|
-
|
|
146
|
-
handleViewClick = (event) => {
|
|
144
|
+
handleViewClick = (event: React.MouseEvent) => {
|
|
147
145
|
if (event.buttons === 1) {
|
|
148
146
|
requestAnimationFrame(() => {
|
|
149
147
|
this.enterEdit()
|
|
@@ -151,23 +149,19 @@ class Editable extends Component<EditableProps> {
|
|
|
151
149
|
}
|
|
152
150
|
}
|
|
153
151
|
|
|
154
|
-
|
|
155
|
-
handleEditBlur = (event) => {
|
|
152
|
+
handleEditBlur = () => {
|
|
156
153
|
this.enterView()
|
|
157
154
|
}
|
|
158
155
|
|
|
159
|
-
|
|
160
|
-
handleEditButtonFocus = (event) => {
|
|
156
|
+
handleEditButtonFocus = () => {
|
|
161
157
|
this.setState({ showModeToggle: true })
|
|
162
158
|
}
|
|
163
159
|
|
|
164
|
-
|
|
165
|
-
handleEditButtonBlur = (event) => {
|
|
160
|
+
handleEditButtonBlur = () => {
|
|
166
161
|
this.setState({ showModeToggle: false })
|
|
167
162
|
}
|
|
168
163
|
|
|
169
|
-
|
|
170
|
-
handleEditButtonClick = (event) => {
|
|
164
|
+
handleEditButtonClick = () => {
|
|
171
165
|
this.enterEdit()
|
|
172
166
|
}
|
|
173
167
|
|
|
@@ -184,20 +178,20 @@ class Editable extends Component<EditableProps> {
|
|
|
184
178
|
}
|
|
185
179
|
|
|
186
180
|
// ------- prop getters ------
|
|
187
|
-
getContainerProps = (props = {}) => {
|
|
181
|
+
getContainerProps: GetContainerProps = (props = {}) => {
|
|
188
182
|
const { mode, readOnly } = this.props
|
|
189
183
|
return {
|
|
190
184
|
onMouseOver: this.handleViewMouseOver,
|
|
191
185
|
onMouseOut: this.handleViewMouseOut,
|
|
192
|
-
onMouseDown: mode !== 'edit' ? this.handleViewClick :
|
|
193
|
-
onKeyUp: mode === 'edit' ? this.handleEditESC :
|
|
186
|
+
onMouseDown: mode !== 'edit' ? this.handleViewClick : undefined,
|
|
187
|
+
onKeyUp: mode === 'edit' ? this.handleEditESC : undefined,
|
|
194
188
|
readOnly,
|
|
195
189
|
...props,
|
|
196
190
|
ref: this.handleContainerRef
|
|
197
191
|
}
|
|
198
192
|
}
|
|
199
193
|
|
|
200
|
-
getViewerProps = (props = {}) => {
|
|
194
|
+
getViewerProps: GetViewerProps = (props = {}) => {
|
|
201
195
|
return {
|
|
202
196
|
mode: this.props.mode,
|
|
203
197
|
readOnly: this.props.readOnly,
|
|
@@ -205,29 +199,26 @@ class Editable extends Component<EditableProps> {
|
|
|
205
199
|
}
|
|
206
200
|
}
|
|
207
201
|
|
|
208
|
-
|
|
209
|
-
getEditorProps = (props) => {
|
|
202
|
+
getEditorProps: GetEditorProps = (props = {}) => {
|
|
210
203
|
return {
|
|
211
204
|
mode: this.props.mode,
|
|
212
205
|
onBlur: this.handleEditBlur,
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
this._editorRef = el
|
|
206
|
+
editorRef: (el: HTMLElement | null) => {
|
|
207
|
+
this._editorRef = el as HTMLInputElement
|
|
216
208
|
},
|
|
217
209
|
readOnly: this.props.readOnly,
|
|
218
210
|
...props
|
|
219
211
|
}
|
|
220
212
|
}
|
|
221
213
|
|
|
222
|
-
getEditButtonProps = (props = {}) => {
|
|
214
|
+
getEditButtonProps: GetEditButtonProps = (props = {}) => {
|
|
223
215
|
return {
|
|
224
216
|
onClick: this.handleEditButtonClick,
|
|
225
217
|
onFocus: this.handleEditButtonFocus,
|
|
226
218
|
onBlur: this.handleEditButtonBlur,
|
|
227
219
|
isVisible: this.state.showModeToggle,
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
this._editButtonRef = el
|
|
220
|
+
buttonRef: (el: Element) => {
|
|
221
|
+
this._editButtonRef = el as HTMLButtonElement
|
|
231
222
|
},
|
|
232
223
|
readOnly: this.props.readOnly,
|
|
233
224
|
...props
|
package/src/Editable/props.ts
CHANGED
|
@@ -21,71 +21,106 @@
|
|
|
21
21
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
|
-
|
|
24
|
+
import React from 'react'
|
|
25
25
|
import PropTypes from 'prop-types'
|
|
26
26
|
|
|
27
27
|
import type { PropValidators } from '@instructure/shared-types'
|
|
28
28
|
|
|
29
|
-
type
|
|
29
|
+
type GetContainerProps = (props?: Record<string, any>) => {
|
|
30
|
+
ref: React.RefCallback<any>
|
|
31
|
+
onMouseOver: (event: React.MouseEvent) => void
|
|
32
|
+
onMouseOut: (event: React.MouseEvent) => void
|
|
33
|
+
onMouseDown?: (event: React.MouseEvent) => void
|
|
34
|
+
onKeyUp?: (event: React.KeyboardEvent) => void
|
|
35
|
+
readOnly?: boolean
|
|
36
|
+
} & Record<string, any>
|
|
37
|
+
|
|
38
|
+
type GetViewerProps = (props?: Record<string, any>) => {
|
|
30
39
|
mode: 'view' | 'edit'
|
|
31
|
-
onChangeMode: (...args: any[]) => any
|
|
32
|
-
children?: (...args: any[]) => any
|
|
33
|
-
render?: (...args: any[]) => any
|
|
34
|
-
value?: any
|
|
35
|
-
onChange?: (...args: any[]) => any
|
|
36
40
|
readOnly?: boolean
|
|
37
|
-
|
|
38
|
-
}
|
|
41
|
+
} & Record<string, any>
|
|
39
42
|
|
|
40
|
-
type
|
|
43
|
+
type GetEditorProps = (props?: Record<string, any>) => {
|
|
44
|
+
mode: 'view' | 'edit'
|
|
45
|
+
onBlur: () => void
|
|
46
|
+
editorRef: (el: HTMLElement | null) => void
|
|
47
|
+
readOnly?: boolean
|
|
48
|
+
} & Record<string, any>
|
|
41
49
|
|
|
42
|
-
type
|
|
50
|
+
type GetEditButtonProps = (props?: Record<string, any>) => {
|
|
51
|
+
onClick: () => void
|
|
52
|
+
onFocus: () => void
|
|
53
|
+
onBlur: () => void
|
|
54
|
+
isVisible: boolean
|
|
55
|
+
buttonRef: (el: Element) => void
|
|
56
|
+
readOnly?: boolean
|
|
57
|
+
} & Record<string, any>
|
|
43
58
|
|
|
44
|
-
type
|
|
59
|
+
type EditableRenderProps = {
|
|
60
|
+
mode: string
|
|
61
|
+
getContainerProps: GetContainerProps
|
|
62
|
+
getViewerProps: GetViewerProps
|
|
63
|
+
getEditorProps: GetEditorProps
|
|
64
|
+
getEditButtonProps: GetEditButtonProps
|
|
65
|
+
}
|
|
45
66
|
|
|
46
|
-
|
|
67
|
+
type EditableOwnProps = {
|
|
47
68
|
/**
|
|
48
69
|
* If `'view'`: the view component is rendered,
|
|
49
70
|
* if `'edit'`: the edit component is rendered
|
|
50
71
|
*/
|
|
51
|
-
mode:
|
|
72
|
+
mode: 'view' | 'edit'
|
|
52
73
|
/**
|
|
53
|
-
* Called when the component's mode changes
|
|
54
|
-
* @param {string} new_mode
|
|
74
|
+
* Called when the component's mode changes.
|
|
55
75
|
*/
|
|
56
|
-
onChangeMode:
|
|
57
|
-
|
|
76
|
+
onChangeMode: (newMode: string) => void
|
|
58
77
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
78
|
+
* Function that you can supply that will return the children of this component.
|
|
79
|
+
* It has one parameter has the following fields:
|
|
80
|
+
* - mode: `view` or `edit`, depending on whether the view or the editor should be rendered.
|
|
81
|
+
* - getContainerProps(props) - Props to be spread onto the container element
|
|
82
|
+
* - getEditorProps(props) - Props to be spread onto the editor element
|
|
83
|
+
* - getEditButtonProps(props) - Props to be spread onto the edit button element
|
|
64
84
|
*/
|
|
65
|
-
children:
|
|
85
|
+
children?: (props: EditableRenderProps) => React.ReactNode
|
|
66
86
|
/**
|
|
67
87
|
* Identical to children
|
|
68
88
|
*/
|
|
69
|
-
render:
|
|
70
|
-
|
|
89
|
+
render?: (props: EditableRenderProps) => React.ReactNode
|
|
71
90
|
/**
|
|
72
91
|
* The current value.
|
|
73
92
|
* The value is managed by the consuming app, but we need to tell Editable
|
|
74
93
|
* it's changed or it won't re-render
|
|
75
94
|
*/
|
|
76
|
-
value
|
|
95
|
+
value?: any
|
|
77
96
|
/**
|
|
78
97
|
* Called when Editable switches from edit to view mode and the value has changed.
|
|
79
|
-
* @param {any} value
|
|
80
98
|
*/
|
|
81
|
-
onChange:
|
|
99
|
+
onChange?: (value: any) => void
|
|
82
100
|
/**
|
|
83
101
|
* The mode is fixed as 'view'
|
|
84
102
|
*/
|
|
85
|
-
readOnly
|
|
103
|
+
readOnly?: boolean
|
|
86
104
|
/**
|
|
87
105
|
* provides a reference to the underlying html root element (container)
|
|
88
106
|
*/
|
|
107
|
+
elementRef?: (element: Element | null) => void
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
type PropKeys = keyof EditableOwnProps
|
|
111
|
+
|
|
112
|
+
type AllowedPropKeys = Readonly<Array<PropKeys>>
|
|
113
|
+
|
|
114
|
+
type EditableProps = EditableOwnProps
|
|
115
|
+
|
|
116
|
+
const propTypes: PropValidators<PropKeys> = {
|
|
117
|
+
mode: PropTypes.oneOf(['view', 'edit']).isRequired,
|
|
118
|
+
onChangeMode: PropTypes.func.isRequired,
|
|
119
|
+
children: PropTypes.func,
|
|
120
|
+
render: PropTypes.func,
|
|
121
|
+
value: PropTypes.any,
|
|
122
|
+
onChange: PropTypes.func,
|
|
123
|
+
readOnly: PropTypes.bool,
|
|
89
124
|
elementRef: PropTypes.func
|
|
90
125
|
}
|
|
91
126
|
|
|
@@ -100,5 +135,17 @@ const allowedProps: AllowedPropKeys = [
|
|
|
100
135
|
'elementRef'
|
|
101
136
|
]
|
|
102
137
|
|
|
103
|
-
|
|
138
|
+
type EditableState = {
|
|
139
|
+
showModeToggle: boolean
|
|
140
|
+
valueOnEdit: any
|
|
141
|
+
}
|
|
142
|
+
export type {
|
|
143
|
+
EditableProps,
|
|
144
|
+
EditableRenderProps,
|
|
145
|
+
EditableState,
|
|
146
|
+
GetContainerProps,
|
|
147
|
+
GetEditButtonProps,
|
|
148
|
+
GetEditorProps,
|
|
149
|
+
GetViewerProps
|
|
150
|
+
}
|
|
104
151
|
export { propTypes, allowedProps }
|
|
@@ -27,6 +27,7 @@ import { Component } from 'react'
|
|
|
27
27
|
|
|
28
28
|
import { Flex } from '@instructure/ui-flex'
|
|
29
29
|
import { IconButton } from '@instructure/ui-buttons'
|
|
30
|
+
import type { IconButtonProps } from '@instructure/ui-buttons'
|
|
30
31
|
import { IconEditLine } from '@instructure/ui-icons'
|
|
31
32
|
import { logWarn as warn } from '@instructure/console'
|
|
32
33
|
import { createChainedFunction } from '@instructure/ui-utils'
|
|
@@ -38,11 +39,13 @@ import generateStyle from './styles'
|
|
|
38
39
|
|
|
39
40
|
import { propTypes, allowedProps } from './props'
|
|
40
41
|
import type { InPlaceEditProps } from './props'
|
|
42
|
+
import type { EditableRenderProps } from '../Editable/props'
|
|
41
43
|
|
|
42
44
|
/**
|
|
43
45
|
---
|
|
44
46
|
category: components
|
|
45
47
|
---
|
|
48
|
+
@tsProps
|
|
46
49
|
**/
|
|
47
50
|
@withStyle(generateStyle, null)
|
|
48
51
|
class InPlaceEdit extends Component<InPlaceEditProps> {
|
|
@@ -57,13 +60,13 @@ class InPlaceEdit extends Component<InPlaceEditProps> {
|
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
ref: Element | null = null
|
|
63
|
+
_editButtonRef: HTMLButtonElement | null = null
|
|
60
64
|
|
|
61
65
|
handleRef = (el: Element | null) => {
|
|
62
66
|
this.ref = el
|
|
63
67
|
}
|
|
64
68
|
|
|
65
|
-
|
|
66
|
-
constructor(props) {
|
|
69
|
+
constructor(props: InPlaceEditProps) {
|
|
67
70
|
super(props)
|
|
68
71
|
|
|
69
72
|
warn(
|
|
@@ -73,24 +76,23 @@ class InPlaceEdit extends Component<InPlaceEditProps> {
|
|
|
73
76
|
}
|
|
74
77
|
|
|
75
78
|
componentDidMount() {
|
|
76
|
-
|
|
77
|
-
this.props.makeStyles()
|
|
79
|
+
this.props.makeStyles?.()
|
|
78
80
|
}
|
|
79
81
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// @ts-expect-error ts-migrate(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message
|
|
83
|
-
this.props.makeStyles()
|
|
82
|
+
componentDidUpdate() {
|
|
83
|
+
this.props.makeStyles?.()
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
handleEditButtonRef = (el) => {
|
|
88
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_editButtonRef' does not exist on type '... Remove this comment to see the full error message
|
|
86
|
+
handleEditButtonRef = (el: HTMLButtonElement) => {
|
|
89
87
|
this._editButtonRef = el
|
|
90
88
|
}
|
|
91
89
|
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
renderEditor({
|
|
91
|
+
mode,
|
|
92
|
+
onBlur,
|
|
93
|
+
editorRef,
|
|
94
|
+
readOnly
|
|
95
|
+
}: ReturnType<EditableRenderProps['getEditorProps']>) {
|
|
94
96
|
const { showFocusRing, renderEditor } = this.props
|
|
95
97
|
const isEditMode = !readOnly && mode === 'edit'
|
|
96
98
|
|
|
@@ -109,13 +111,17 @@ class InPlaceEdit extends Component<InPlaceEditProps> {
|
|
|
109
111
|
) : null
|
|
110
112
|
}
|
|
111
113
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
+
renderViewer({
|
|
115
|
+
readOnly,
|
|
116
|
+
mode
|
|
117
|
+
}: ReturnType<EditableRenderProps['getViewerProps']>) {
|
|
114
118
|
return readOnly || mode === 'view' ? this.props.renderViewer() : null
|
|
115
119
|
}
|
|
116
120
|
|
|
117
|
-
|
|
118
|
-
|
|
121
|
+
renderEditButton({
|
|
122
|
+
buttonRef,
|
|
123
|
+
...rest
|
|
124
|
+
}: ReturnType<EditableRenderProps['getEditButtonProps']>) {
|
|
119
125
|
return this.props.renderEditButton({
|
|
120
126
|
elementRef: createChainedFunction(this.handleEditButtonRef, buttonRef),
|
|
121
127
|
...rest
|
|
@@ -125,14 +131,15 @@ class InPlaceEdit extends Component<InPlaceEditProps> {
|
|
|
125
131
|
// Render a default edit button, an icon button with the edit icon
|
|
126
132
|
// the margin makes room for the focus ring
|
|
127
133
|
static renderDefaultEditButton = ({
|
|
128
|
-
// @ts-expect-error ts-migrate(7031) FIXME: Binding element 'isVisible' implicitly has an 'any... Remove this comment to see the full error message
|
|
129
134
|
isVisible,
|
|
130
|
-
// @ts-expect-error ts-migrate(7031) FIXME: Binding element 'readOnly' implicitly has an 'any'... Remove this comment to see the full error message
|
|
131
135
|
readOnly,
|
|
132
|
-
// @ts-expect-error ts-migrate(7031) FIXME: Binding element 'label' implicitly has an 'any' ty... Remove this comment to see the full error message
|
|
133
136
|
label,
|
|
134
137
|
...buttonProps
|
|
135
|
-
}
|
|
138
|
+
}: {
|
|
139
|
+
isVisible: boolean
|
|
140
|
+
readOnly?: boolean
|
|
141
|
+
label: string
|
|
142
|
+
} & Partial<IconButtonProps>) => {
|
|
136
143
|
if (readOnly) {
|
|
137
144
|
return null
|
|
138
145
|
}
|
|
@@ -150,15 +157,11 @@ class InPlaceEdit extends Component<InPlaceEditProps> {
|
|
|
150
157
|
}
|
|
151
158
|
|
|
152
159
|
renderAll = ({
|
|
153
|
-
// @ts-expect-error ts-migrate(7031) FIXME: Binding element 'getContainerProps' implicitly has... Remove this comment to see the full error message
|
|
154
160
|
getContainerProps,
|
|
155
|
-
// @ts-expect-error ts-migrate(7031) FIXME: Binding element 'getViewerProps' implicitly has an... Remove this comment to see the full error message
|
|
156
161
|
getViewerProps,
|
|
157
|
-
// @ts-expect-error ts-migrate(7031) FIXME: Binding element 'getEditorProps' implicitly has an... Remove this comment to see the full error message
|
|
158
162
|
getEditorProps,
|
|
159
|
-
// @ts-expect-error ts-migrate(7031) FIXME: Binding element 'getEditButtonProps' implicitly ha... Remove this comment to see the full error message
|
|
160
163
|
getEditButtonProps
|
|
161
|
-
}) => {
|
|
164
|
+
}: EditableRenderProps) => {
|
|
162
165
|
const flexDir =
|
|
163
166
|
this.props.editButtonPlacement === 'start' ? 'row-reverse' : 'row'
|
|
164
167
|
const justifyItems = flexDir === 'row-reverse' ? 'end' : 'start'
|
package/src/InPlaceEdit/props.ts
CHANGED
|
@@ -26,39 +26,28 @@ import PropTypes from 'prop-types'
|
|
|
26
26
|
|
|
27
27
|
import type { PropValidators } from '@instructure/shared-types'
|
|
28
28
|
import type { WithStyleProps, ComponentStyle } from '@instructure/emotion'
|
|
29
|
+
import type { EditableProps } from '../Editable/props'
|
|
30
|
+
import React from 'react'
|
|
29
31
|
|
|
30
|
-
type
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
value?: any
|
|
37
|
-
onChange?: (...args: any[]) => any
|
|
32
|
+
type ExtendedRenderEditButton = {
|
|
33
|
+
elementRef?: (el: HTMLButtonElement) => void
|
|
34
|
+
onClick: () => void
|
|
35
|
+
onFocus: () => void
|
|
36
|
+
onBlur: () => void
|
|
37
|
+
isVisible: boolean
|
|
38
38
|
readOnly?: boolean
|
|
39
|
-
showFocusRing?: boolean
|
|
40
|
-
editButtonPlacement?: 'start' | 'end'
|
|
41
|
-
inline?: boolean
|
|
42
39
|
}
|
|
43
40
|
|
|
44
|
-
type
|
|
45
|
-
|
|
46
|
-
type AllowedPropKeys = Readonly<Array<PropKeys>>
|
|
47
|
-
|
|
48
|
-
type InPlaceEditProps = InPlaceEditOwnProps &
|
|
49
|
-
WithStyleProps<null, InPlaceEditStyle>
|
|
50
|
-
|
|
51
|
-
type InPlaceEditStyle = ComponentStyle<'inPlaceEdit'>
|
|
52
|
-
|
|
53
|
-
const propTypes: PropValidators<PropKeys> = {
|
|
41
|
+
type InPlaceEditOwnProps = {
|
|
54
42
|
/**
|
|
55
43
|
* Function to render the view mode component.
|
|
56
44
|
* It is the consumer's responsibility to provide the
|
|
57
45
|
* current value or children.
|
|
58
46
|
*
|
|
59
|
-
*
|
|
47
|
+
* Return value:
|
|
48
|
+
* - element: the viewer DOM sub-tree.
|
|
60
49
|
*/
|
|
61
|
-
renderViewer:
|
|
50
|
+
renderViewer: () => React.ReactNode
|
|
62
51
|
/**
|
|
63
52
|
* Function to render the edit mode component
|
|
64
53
|
* It is the consumer's responsibility to provide the
|
|
@@ -66,14 +55,25 @@ const propTypes: PropValidators<PropKeys> = {
|
|
|
66
55
|
* event handler needed to capture the updated value. This
|
|
67
56
|
* new value must then be forwarded to the view mode component.
|
|
68
57
|
*
|
|
69
|
-
*
|
|
58
|
+
* Return value:
|
|
59
|
+
* - element: the editor DOM sub-tree.
|
|
70
60
|
*/
|
|
71
|
-
renderEditor:
|
|
61
|
+
renderEditor: ({
|
|
62
|
+
onBlur,
|
|
63
|
+
editorRef
|
|
64
|
+
}: {
|
|
65
|
+
onBlur: () => void
|
|
66
|
+
editorRef: (el: HTMLElement | null) => void
|
|
67
|
+
}) => React.ReactNode
|
|
72
68
|
/**
|
|
73
69
|
* Function to render the edit button.
|
|
74
70
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
71
|
+
* Parameters:
|
|
72
|
+
* - object: { isVisible, onClick, onFocus, onBlur, buttonRef }
|
|
73
|
+
*
|
|
74
|
+
* Return value:
|
|
75
|
+
*
|
|
76
|
+
* - element: the edit button DOM sub-tree
|
|
77
77
|
*
|
|
78
78
|
* If you choose to use the default edit button, add `label` to the
|
|
79
79
|
* incoming `props` parameter and call `InPlaceEdit.renderDefaultEditButton(props)`
|
|
@@ -84,43 +84,68 @@ const propTypes: PropValidators<PropKeys> = {
|
|
|
84
84
|
* `isVisible` is a hint as to whether the button is _typically_ shown,
|
|
85
85
|
* but you're free to ignore it for your use-case.
|
|
86
86
|
*/
|
|
87
|
-
renderEditButton:
|
|
87
|
+
renderEditButton: (props: ExtendedRenderEditButton) => React.ReactNode | null
|
|
88
88
|
/**
|
|
89
89
|
* If `'view'`: the view component is rendered,
|
|
90
90
|
* if `'edit'`: the edit component is rendered
|
|
91
91
|
*/
|
|
92
|
-
mode:
|
|
92
|
+
mode: 'view' | 'edit'
|
|
93
93
|
/**
|
|
94
94
|
* Called when the component's mode changes
|
|
95
|
-
*
|
|
95
|
+
* Parameter:
|
|
96
|
+
* - newMode: string
|
|
96
97
|
*/
|
|
97
|
-
onChangeMode:
|
|
98
|
+
onChangeMode: EditableProps['onChangeMode']
|
|
98
99
|
/**
|
|
99
100
|
* The current value.
|
|
100
101
|
* The value is managed by the consuming app, but we need to tell InPlaceEdit
|
|
101
102
|
* it's changed or it won't re-render
|
|
102
103
|
*/
|
|
103
|
-
value
|
|
104
|
+
value?: any
|
|
104
105
|
/**
|
|
105
106
|
* Called when Editable switches from edit to view mode and the value has changed.
|
|
106
|
-
*
|
|
107
|
+
* Parameter:
|
|
108
|
+
* - value: any
|
|
107
109
|
*/
|
|
108
|
-
onChange
|
|
110
|
+
onChange?: EditableProps['onChange']
|
|
109
111
|
/**
|
|
110
112
|
* The mode is fixed as 'view'
|
|
111
113
|
*/
|
|
112
|
-
readOnly
|
|
114
|
+
readOnly?: boolean
|
|
113
115
|
/**
|
|
114
116
|
* Show a focus outline when the input is focused
|
|
115
117
|
*/
|
|
116
|
-
showFocusRing
|
|
118
|
+
showFocusRing?: boolean
|
|
117
119
|
/**
|
|
118
120
|
* Put the edit button before or after the view
|
|
119
121
|
*/
|
|
120
|
-
editButtonPlacement
|
|
122
|
+
editButtonPlacement?: 'start' | 'end'
|
|
121
123
|
/**
|
|
122
124
|
* Render outermost element inline v. block
|
|
123
125
|
*/
|
|
126
|
+
inline?: boolean
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
type PropKeys = keyof InPlaceEditOwnProps
|
|
130
|
+
|
|
131
|
+
type AllowedPropKeys = Readonly<Array<PropKeys>>
|
|
132
|
+
|
|
133
|
+
type InPlaceEditProps = InPlaceEditOwnProps &
|
|
134
|
+
WithStyleProps<null, InPlaceEditStyle>
|
|
135
|
+
|
|
136
|
+
type InPlaceEditStyle = ComponentStyle<'inPlaceEdit'>
|
|
137
|
+
|
|
138
|
+
const propTypes: PropValidators<PropKeys> = {
|
|
139
|
+
renderViewer: PropTypes.func.isRequired,
|
|
140
|
+
renderEditor: PropTypes.func.isRequired,
|
|
141
|
+
renderEditButton: PropTypes.func.isRequired,
|
|
142
|
+
mode: PropTypes.oneOf(['view', 'edit']).isRequired,
|
|
143
|
+
onChangeMode: PropTypes.func.isRequired,
|
|
144
|
+
value: PropTypes.any,
|
|
145
|
+
onChange: PropTypes.func,
|
|
146
|
+
readOnly: PropTypes.bool,
|
|
147
|
+
showFocusRing: PropTypes.bool,
|
|
148
|
+
editButtonPlacement: PropTypes.oneOf(['start', 'end']),
|
|
124
149
|
inline: PropTypes.bool
|
|
125
150
|
}
|
|
126
151
|
|