@instructure/ui-editable 8.25.1-snapshot.0 → 8.26.0
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 +4 -0
- package/es/Editable/index.js +13 -14
- 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 -14
- package/lib/Editable/props.js +0 -40
- package/lib/InPlaceEdit/index.js +18 -12
- package/lib/InPlaceEdit/props.js +0 -70
- package/package.json +14 -15
- package/src/Editable/index.tsx +33 -43
- 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 -50
- 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/LICENSE.md +0 -27
package/src/Editable/index.tsx
CHANGED
|
@@ -21,20 +21,26 @@
|
|
|
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
|
-
experimental: true
|
|
37
42
|
---
|
|
43
|
+
@tsProps
|
|
38
44
|
**/
|
|
39
45
|
class Editable extends Component<EditableProps> {
|
|
40
46
|
static propTypes = propTypes
|
|
@@ -44,16 +50,15 @@ class Editable extends Component<EditableProps> {
|
|
|
44
50
|
children: null
|
|
45
51
|
}
|
|
46
52
|
|
|
47
|
-
state = {
|
|
53
|
+
state: EditableState = {
|
|
48
54
|
showModeToggle: false,
|
|
49
55
|
valueOnEdit: null // the value when mode flips from view -> edit
|
|
50
56
|
}
|
|
51
57
|
|
|
52
|
-
_editorRef = null
|
|
53
|
-
_editButtonRef = null
|
|
58
|
+
_editorRef: HTMLInputElement | null = null
|
|
59
|
+
_editButtonRef: HTMLButtonElement | null = null
|
|
54
60
|
|
|
55
|
-
|
|
56
|
-
constructor(props) {
|
|
61
|
+
constructor(props: EditableProps) {
|
|
57
62
|
super(props)
|
|
58
63
|
|
|
59
64
|
warn(
|
|
@@ -67,10 +72,8 @@ class Editable extends Component<EditableProps> {
|
|
|
67
72
|
this.focusEditor()
|
|
68
73
|
}
|
|
69
74
|
}
|
|
70
|
-
componentWillUnmount() {}
|
|
71
75
|
|
|
72
|
-
|
|
73
|
-
componentDidUpdate(prevProps) {
|
|
76
|
+
componentDidUpdate(prevProps: EditableProps) {
|
|
74
77
|
const { mode, value, onChange } = this.props
|
|
75
78
|
|
|
76
79
|
// on the switch from view -> edit
|
|
@@ -81,7 +84,6 @@ class Editable extends Component<EditableProps> {
|
|
|
81
84
|
|
|
82
85
|
// on the switch from edit to view
|
|
83
86
|
if (prevProps.mode === 'edit' && mode !== 'edit') {
|
|
84
|
-
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
|
|
85
87
|
this._editButtonRef && this._editButtonRef.focus()
|
|
86
88
|
if (onChange && !deepEqual(this.state.valueOnEdit, value)) {
|
|
87
89
|
onChange(value)
|
|
@@ -95,7 +97,6 @@ class Editable extends Component<EditableProps> {
|
|
|
95
97
|
'[Editable] Did you forget to connect editorRef to your editor component?'
|
|
96
98
|
)
|
|
97
99
|
if (this._editorRef) {
|
|
98
|
-
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
|
|
99
100
|
this._editorRef.focus()
|
|
100
101
|
}
|
|
101
102
|
}
|
|
@@ -116,15 +117,13 @@ class Editable extends Component<EditableProps> {
|
|
|
116
117
|
}
|
|
117
118
|
}
|
|
118
119
|
|
|
119
|
-
|
|
120
|
-
handleEditESC = (event) => {
|
|
120
|
+
handleEditESC = (event: React.KeyboardEvent) => {
|
|
121
121
|
if (event.key === 'Escape') {
|
|
122
122
|
this.enterView()
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
|
|
127
|
-
handleViewMouseOver = (event) => {
|
|
126
|
+
handleViewMouseOver = (event: React.MouseEvent) => {
|
|
128
127
|
if (this.props.mode === 'view') {
|
|
129
128
|
// because the mouse event handlers are on the container, not the view
|
|
130
129
|
event.stopPropagation()
|
|
@@ -132,8 +131,7 @@ class Editable extends Component<EditableProps> {
|
|
|
132
131
|
}
|
|
133
132
|
}
|
|
134
133
|
|
|
135
|
-
|
|
136
|
-
handleViewMouseOut = (event) => {
|
|
134
|
+
handleViewMouseOut = (event: React.MouseEvent) => {
|
|
137
135
|
if (this.props.mode === 'view') {
|
|
138
136
|
event.stopPropagation()
|
|
139
137
|
this.setState({
|
|
@@ -142,8 +140,7 @@ class Editable extends Component<EditableProps> {
|
|
|
142
140
|
}
|
|
143
141
|
}
|
|
144
142
|
|
|
145
|
-
|
|
146
|
-
handleViewClick = (event) => {
|
|
143
|
+
handleViewClick = (event: React.MouseEvent) => {
|
|
147
144
|
if (event.buttons === 1) {
|
|
148
145
|
requestAnimationFrame(() => {
|
|
149
146
|
this.enterEdit()
|
|
@@ -151,23 +148,19 @@ class Editable extends Component<EditableProps> {
|
|
|
151
148
|
}
|
|
152
149
|
}
|
|
153
150
|
|
|
154
|
-
|
|
155
|
-
handleEditBlur = (event) => {
|
|
151
|
+
handleEditBlur = () => {
|
|
156
152
|
this.enterView()
|
|
157
153
|
}
|
|
158
154
|
|
|
159
|
-
|
|
160
|
-
handleEditButtonFocus = (event) => {
|
|
155
|
+
handleEditButtonFocus = () => {
|
|
161
156
|
this.setState({ showModeToggle: true })
|
|
162
157
|
}
|
|
163
158
|
|
|
164
|
-
|
|
165
|
-
handleEditButtonBlur = (event) => {
|
|
159
|
+
handleEditButtonBlur = () => {
|
|
166
160
|
this.setState({ showModeToggle: false })
|
|
167
161
|
}
|
|
168
162
|
|
|
169
|
-
|
|
170
|
-
handleEditButtonClick = (event) => {
|
|
163
|
+
handleEditButtonClick = () => {
|
|
171
164
|
this.enterEdit()
|
|
172
165
|
}
|
|
173
166
|
|
|
@@ -184,20 +177,20 @@ class Editable extends Component<EditableProps> {
|
|
|
184
177
|
}
|
|
185
178
|
|
|
186
179
|
// ------- prop getters ------
|
|
187
|
-
getContainerProps = (props = {}) => {
|
|
180
|
+
getContainerProps: GetContainerProps = (props = {}) => {
|
|
188
181
|
const { mode, readOnly } = this.props
|
|
189
182
|
return {
|
|
190
183
|
onMouseOver: this.handleViewMouseOver,
|
|
191
184
|
onMouseOut: this.handleViewMouseOut,
|
|
192
|
-
onMouseDown: mode !== 'edit' ? this.handleViewClick :
|
|
193
|
-
onKeyUp: mode === 'edit' ? this.handleEditESC :
|
|
185
|
+
onMouseDown: mode !== 'edit' ? this.handleViewClick : undefined,
|
|
186
|
+
onKeyUp: mode === 'edit' ? this.handleEditESC : undefined,
|
|
194
187
|
readOnly,
|
|
195
188
|
...props,
|
|
196
189
|
ref: this.handleContainerRef
|
|
197
190
|
}
|
|
198
191
|
}
|
|
199
192
|
|
|
200
|
-
getViewerProps = (props = {}) => {
|
|
193
|
+
getViewerProps: GetViewerProps = (props = {}) => {
|
|
201
194
|
return {
|
|
202
195
|
mode: this.props.mode,
|
|
203
196
|
readOnly: this.props.readOnly,
|
|
@@ -205,29 +198,26 @@ class Editable extends Component<EditableProps> {
|
|
|
205
198
|
}
|
|
206
199
|
}
|
|
207
200
|
|
|
208
|
-
|
|
209
|
-
getEditorProps = (props) => {
|
|
201
|
+
getEditorProps: GetEditorProps = (props = {}) => {
|
|
210
202
|
return {
|
|
211
203
|
mode: this.props.mode,
|
|
212
204
|
onBlur: this.handleEditBlur,
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
this._editorRef = el
|
|
205
|
+
editorRef: (el: HTMLElement | null) => {
|
|
206
|
+
this._editorRef = el as HTMLInputElement
|
|
216
207
|
},
|
|
217
208
|
readOnly: this.props.readOnly,
|
|
218
209
|
...props
|
|
219
210
|
}
|
|
220
211
|
}
|
|
221
212
|
|
|
222
|
-
getEditButtonProps = (props = {}) => {
|
|
213
|
+
getEditButtonProps: GetEditButtonProps = (props = {}) => {
|
|
223
214
|
return {
|
|
224
215
|
onClick: this.handleEditButtonClick,
|
|
225
216
|
onFocus: this.handleEditButtonFocus,
|
|
226
217
|
onBlur: this.handleEditButtonBlur,
|
|
227
218
|
isVisible: this.state.showModeToggle,
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
this._editButtonRef = el
|
|
219
|
+
buttonRef: (el: Element) => {
|
|
220
|
+
this._editButtonRef = el as HTMLButtonElement
|
|
231
221
|
},
|
|
232
222
|
readOnly: this.props.readOnly,
|
|
233
223
|
...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
|
|