@instructure/ui-editable 11.7.2-snapshot-23 → 11.7.2-snapshot-25

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.
@@ -56,7 +56,7 @@ const Example = (props) => {
56
56
  }
57
57
 
58
58
  const renderViewer = () => {
59
- return <span>{value}</span>
59
+ return <Text>{value}</Text>
60
60
  }
61
61
 
62
62
  const handleValueChange = (event) => {
@@ -69,8 +69,10 @@ const Example = (props) => {
69
69
 
70
70
  const renderEditor = ({ onBlur, editorRef }) => {
71
71
  return (
72
- <input
73
- ref={editorRef}
72
+ <TextInput
73
+ renderLabel=""
74
+ width="10rem"
75
+ inputRef={editorRef}
74
76
  onBlur={onBlur}
75
77
  value={value}
76
78
  onChange={handleValueChange}
@@ -0,0 +1,338 @@
1
+ ---
2
+ describes: InPlaceEdit
3
+ ---
4
+
5
+ `InPlaceEdit` provides the DOM structure to organize the components that participate
6
+ in in-place editing by calling the `renderViewer` and `renderEditor` _render props_
7
+ in the context of the containing DOM sub-tree. It also takes care of wiring up the
8
+ event handlers required by [`Editable`](Editable) to make the user interactions work.
9
+
10
+ As a controlled component, it is the responsibility of the consumer to maintain some data to make this work.
11
+ Each time `InPlaceEdit` is rendered, you must provide as props:
12
+
13
+ - the current `mode` prop, which defaults to `'view'`. The app will be notified of
14
+ changes in mode via the `onChangeMode` function property.
15
+ - the current `value` prop, which primarily serves to trigger a re-render when the value changes
16
+
17
+ The view component, as returned by the `renderViewer` property can be anything you wish, but
18
+ will typically render some formatted text. It is up to the consumer to provide this component with
19
+ the current value.
20
+
21
+ The edit component, as returned by the `renderEditor` property is used to collect the user's
22
+ input. It is up to the consumer to provide the necessary properties to get the user provided value
23
+ (typically `onChange`), and to provide the current value.
24
+
25
+ Some components, like [Heading](Heading) and [Text](Text) can be made editable by setting their `as` property
26
+ to `input` (and optionally the `type` property). The value of this approach is that the editable version
27
+ will render in the same style as the view, making for a nice user experience. Other transitions,
28
+ `Text` to `Select` or `DateTimeInput` for example, result in a wholesale change in the component's UI, and will alter
29
+ the space it consumes in the app.
30
+
31
+ Use `InPlaceEdit` to edit `Text` using `Text as="input"`. Also demonstrates how you might wish to handle
32
+ the case when the text is empty. Use the checkbox to switch between inline and block layout.
33
+
34
+ ```js
35
+ ---
36
+ type: example
37
+ ---
38
+ const Example = (props) => {
39
+ const [mode, setMode] = useState(props.mode || 'view')
40
+ const [value, setValue] = useState('This is some text')
41
+ const [inline, setInline] = useState(true)
42
+
43
+ // You must provide this to Editable to be
44
+ // notified of mode changes
45
+ const handleChangeMode = (mode) => {
46
+ setMode(mode)
47
+ }
48
+
49
+ // You attach an event handler to your edit component
50
+ // to be notified of value changes from user interactions
51
+ const handleChange = (event) => {
52
+ setValue(event.target.value)
53
+ }
54
+
55
+ // Renders the view component
56
+ // Be sure to give it the current value
57
+ const renderView = () => (
58
+ <Text
59
+ color={value ? 'primary' : 'secondary'}
60
+ weight={value ? 'normal' : 'light'}
61
+ size="large"
62
+ >
63
+ {value || 'Enter some text'}
64
+ </Text>
65
+ )
66
+
67
+ // Renders the edit component.
68
+ // You have to forward the props on, which
69
+ // includes an onBlur property to help manage
70
+ // the mode changes.
71
+ // Be sure to give it the current value
72
+ const renderEdit = ({ onBlur, editorRef }) => (
73
+ <Text
74
+ color="primary"
75
+ size="large"
76
+ as="input"
77
+ type="text"
78
+ value={value}
79
+ onChange={handleChange}
80
+ aria-label="The title"
81
+ onBlur={onBlur}
82
+ elementRef={editorRef}
83
+ />
84
+ )
85
+
86
+ // Renders the edit button.
87
+ // Leverage the default implementation provided by InPlaceEdit
88
+ const renderEditButton = (props) => {
89
+ props.label = `Edit title "${value}"`
90
+ return InPlaceEdit.renderDefaultEditButton(props)
91
+ }
92
+
93
+ const onChangeLayout = (event) => {
94
+ setInline(event.target.checked)
95
+ }
96
+
97
+ return (
98
+ <View as="div">
99
+ <InPlaceEdit
100
+ renderViewer={renderView}
101
+ renderEditor={renderEdit}
102
+ renderEditButton={renderEditButton}
103
+ onChangeMode={handleChangeMode}
104
+ mode={mode}
105
+ value={value}
106
+ inline={inline}
107
+ />
108
+ <View as="div" margin="small 0">
109
+ <Checkbox label="inline" checked={inline} onChange={onChangeLayout} />
110
+ </View>
111
+ </View>
112
+ )
113
+ }
114
+
115
+ render(<Example />)
116
+ ```
117
+
118
+ A readOnly `InPlaceEdit`
119
+
120
+ ```js
121
+ ---
122
+ type: example
123
+ ---
124
+ const Example = (props) => {
125
+ const [mode, setMode] = useState(props.mode || 'view')
126
+ const [value, setValue] = useState('This is some text')
127
+
128
+ // You must provide this to Editable to be
129
+ // notified of mode changes
130
+ const handleChangeMode = (mode) => {
131
+ setMode(mode)
132
+ }
133
+
134
+ // You attach an event handler to your edit component
135
+ // to be notified of value changes from user interactions
136
+ const handleChange = (event) => {
137
+ setValue(event.target.value)
138
+ }
139
+
140
+ // Renders the view component
141
+ // Be sure to give it the current value
142
+ const renderView = () => <Text size="large">{value}</Text>
143
+
144
+ // Renders the edit component.
145
+ // You have to forward the props on, which
146
+ // includes an onBlur property to help manage
147
+ // the mode changes.
148
+ // Be sure to give it the current value
149
+ const renderEdit = ({ onBlur, editorRef }) => (
150
+ <Text
151
+ size="large"
152
+ as="input"
153
+ type="text"
154
+ value={value}
155
+ onChange={handleChange}
156
+ aria-label="The title"
157
+ onBlur={onBlur}
158
+ elementRef={editorRef}
159
+ />
160
+ )
161
+
162
+ // Renders the edit button.
163
+ // Leverage the default implementation provided by InPlaceEdit
164
+ const renderEditButton = (props) => {
165
+ props.label = `Edit title "${value}"`
166
+ return InPlaceEdit.renderDefaultEditButton(props)
167
+ }
168
+
169
+ return (
170
+ <InPlaceEdit
171
+ readOnly
172
+ renderViewer={renderView}
173
+ renderEditor={renderEdit}
174
+ renderEditButton={renderEditButton}
175
+ onChangeMode={handleChangeMode}
176
+ mode={mode}
177
+ value={value}
178
+ />
179
+ )
180
+ }
181
+
182
+ render(<Example />)
183
+ ```
184
+
185
+ To edit end-justified text, wrap `<InPlaceEdit />` in a
186
+ `<View>` component, as follows:
187
+
188
+ ```js
189
+ ---
190
+ type: example
191
+ ---
192
+ const Example = (props) => {
193
+ const [mode, setMode] = useState(props.mode || 'view')
194
+ const [value, setValue] = useState('This is some text')
195
+
196
+ // You must provide this to Editable to be
197
+ // notified of mode changes
198
+ const handleChangeMode = (mode) => {
199
+ setMode(mode)
200
+ }
201
+
202
+ // You attach an event handler to your edit component
203
+ // to be notified of value changes from user interactions
204
+ const handleChange = (event) => {
205
+ setValue(event.target.value)
206
+ }
207
+
208
+ // Renders the view component
209
+ // Be sure to give it the current value
210
+ const renderView = () => <Text size="large">{value}</Text>
211
+
212
+ // Renders the edit component.
213
+ // You have to forward the props on, which
214
+ // includes an onBlur property to help manage
215
+ // the mode changes.
216
+ // Be sure to give it the current value
217
+ const renderEdit = ({ onBlur, editorRef }) => (
218
+ <Text
219
+ size="large"
220
+ as="input"
221
+ type="text"
222
+ value={value}
223
+ onChange={handleChange}
224
+ aria-label="The title"
225
+ onBlur={onBlur}
226
+ elementRef={editorRef}
227
+ />
228
+ )
229
+
230
+ // Renders the edit button.
231
+ // Leverage the default implementation provided by InPlaceEdit
232
+ const renderEditButton = (props) => {
233
+ props.label = `Edit title "${value}"`
234
+ return InPlaceEdit.renderDefaultEditButton(props)
235
+ }
236
+
237
+ return (
238
+ <View as="div" textAlign="end">
239
+ <InPlaceEdit
240
+ renderViewer={renderView}
241
+ renderEditor={renderEdit}
242
+ renderEditButton={renderEditButton}
243
+ onChangeMode={handleChangeMode}
244
+ mode={mode}
245
+ value={value}
246
+ editButtonPlacement="start"
247
+ />
248
+ </View>
249
+ )
250
+ }
251
+
252
+ render(<Example />)
253
+ ```
254
+
255
+ Same as the first example, but notifies `Editable`'s `onChange`
256
+ when the user has finished editing and the value has changed.
257
+
258
+ ```js
259
+ ---
260
+ type: example
261
+ ---
262
+ const Example = (props) => {
263
+ const [mode, setMode] = useState(props.mode || 'view')
264
+ const [value, setValue] = useState('Edit me')
265
+ const [onChangeValue, setOnChangeValue] = useState(undefined)
266
+
267
+ // typically provided by the application so it can
268
+ // be notified of value changes when the user is
269
+ // finished editing
270
+ const onChange = (newValue) => {
271
+ setOnChangeValue(newValue)
272
+ }
273
+
274
+ // You must provide this to Editable to be
275
+ // notified of mode changes
276
+ const handleChangeMode = (mode) => {
277
+ setMode(mode)
278
+ }
279
+
280
+ // You attach an event handler to your edit component
281
+ // to be notified of value changes from user interactions
282
+ const handleChange = (event) => {
283
+ setValue(event.target.value)
284
+ }
285
+
286
+ // Renders the view component
287
+ // Be sure to give it the current value
288
+ const renderView = () => <Text size="large">{value}</Text>
289
+
290
+ // Renders the edit component.
291
+ // You have to forward the props on, which
292
+ // includes an onBlur property to help manage
293
+ // the mode changes.
294
+ // Be sure to give it the current value
295
+ const renderEdit = ({ onBlur, editorRef }) => (
296
+ <Text
297
+ size="large"
298
+ as="input"
299
+ type="text"
300
+ value={value}
301
+ onChange={handleChange}
302
+ aria-label="The title"
303
+ onBlur={onBlur}
304
+ elementRef={editorRef}
305
+ />
306
+ )
307
+
308
+ // Renders the edit button.
309
+ // Leverage the default implementation provided by InPlaceEdit
310
+ const renderEditButton = (props) => {
311
+ props.label = `Edit title "${value}"`
312
+ return InPlaceEdit.renderDefaultEditButton(props)
313
+ }
314
+
315
+ return (
316
+ <View as="div" background="primary">
317
+ <InPlaceEdit
318
+ renderViewer={renderView}
319
+ renderEditor={renderEdit}
320
+ renderEditButton={renderEditButton}
321
+ onChangeMode={handleChangeMode}
322
+ mode={mode}
323
+ value={value}
324
+ onChange={onChange}
325
+ />
326
+ <div>
327
+ <Text fontStyle="italic">
328
+ {onChangeValue !== undefined
329
+ ? `onChange said: ${onChangeValue}`
330
+ : `You haven't edited me yet!`}
331
+ </Text>
332
+ </div>
333
+ </View>
334
+ )
335
+ }
336
+
337
+ render(<Example />)
338
+ ```
@@ -0,0 +1,205 @@
1
+ /*
2
+ * The MIT License (MIT)
3
+ *
4
+ * Copyright (c) 2018 - present Instructure, Inc.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+
25
+ import { Component } from 'react'
26
+
27
+ import { Flex } from '@instructure/ui-flex/latest'
28
+ import { IconButton } from '@instructure/ui-buttons/latest'
29
+ import type { IconButtonProps } from '@instructure/ui-buttons/latest'
30
+ import { PencilInstUIIcon } from '@instructure/ui-icons'
31
+ import { logWarn as warn } from '@instructure/console'
32
+ import { createChainedFunction } from '@instructure/ui-utils'
33
+ import { withStyle } from '@instructure/emotion'
34
+ import { View } from '@instructure/ui-view/latest'
35
+
36
+ import { Editable } from '../../Editable/v1'
37
+ import generateStyle from './styles'
38
+
39
+ import { allowedProps } from './props'
40
+ import type { InPlaceEditProps } from './props'
41
+ import type { EditableRenderProps } from '../../Editable/v1/props'
42
+
43
+ /**
44
+ ---
45
+ category: components
46
+ ---
47
+ **/
48
+ @withStyle(generateStyle)
49
+ class InPlaceEdit extends Component<InPlaceEditProps> {
50
+ static readonly componentId = 'InPlaceEdit'
51
+ static allowedProps = allowedProps
52
+ static defaultProps = {
53
+ readOnly: false,
54
+ showFocusRing: true,
55
+ inline: true,
56
+ editButtonPlacement: 'end'
57
+ }
58
+
59
+ ref: Element | null = null
60
+ _editButtonRef: HTMLButtonElement | null = null
61
+
62
+ handleRef = (el: Element | null) => {
63
+ this.ref = el
64
+ }
65
+
66
+ constructor(props: InPlaceEditProps) {
67
+ super(props)
68
+
69
+ warn(
70
+ props.readOnly ? props.mode === 'view' : true,
71
+ '[InPlaceEdit] When readOnly is true, mode is forced to "view"'
72
+ )
73
+ }
74
+
75
+ componentDidMount() {
76
+ this.props.makeStyles?.()
77
+ }
78
+
79
+ componentDidUpdate() {
80
+ this.props.makeStyles?.()
81
+ }
82
+
83
+ handleEditButtonRef = (el: HTMLButtonElement) => {
84
+ this._editButtonRef = el
85
+ }
86
+
87
+ renderEditor({
88
+ mode,
89
+ onBlur,
90
+ editorRef,
91
+ readOnly
92
+ }: ReturnType<EditableRenderProps['getEditorProps']>) {
93
+ const { showFocusRing, renderEditor } = this.props
94
+ const isEditMode = !readOnly && mode === 'edit'
95
+
96
+ return isEditMode ? (
97
+ <View
98
+ as="span"
99
+ display="block"
100
+ withFocusOutline={showFocusRing}
101
+ position="relative"
102
+ css={this.props.styles?.inPlaceEdit}
103
+ borderRadius="medium"
104
+ margin="auto"
105
+ >
106
+ {renderEditor({ onBlur, editorRef })}
107
+ </View>
108
+ ) : null
109
+ }
110
+
111
+ renderViewer({
112
+ readOnly,
113
+ mode
114
+ }: ReturnType<EditableRenderProps['getViewerProps']>) {
115
+ return readOnly || mode === 'view' ? this.props.renderViewer() : null
116
+ }
117
+
118
+ renderEditButton({
119
+ buttonRef,
120
+ ...rest
121
+ }: ReturnType<EditableRenderProps['getEditButtonProps']>) {
122
+ return this.props.renderEditButton({
123
+ elementRef: createChainedFunction(this.handleEditButtonRef, buttonRef),
124
+ ...rest
125
+ })
126
+ }
127
+
128
+ // Render a default edit button, an icon button with the edit icon
129
+ // the margin makes room for the focus ring
130
+ static renderDefaultEditButton = ({
131
+ isVisible,
132
+ readOnly,
133
+ label,
134
+ ...buttonProps
135
+ }: {
136
+ isVisible: boolean
137
+ readOnly?: boolean
138
+ label: string
139
+ } & Partial<IconButtonProps>) => {
140
+ if (readOnly) {
141
+ return null
142
+ }
143
+ return (
144
+ <IconButton
145
+ size="small"
146
+ screenReaderLabel={label}
147
+ withBackground={false}
148
+ withBorder={false}
149
+ {...buttonProps}
150
+ >
151
+ {isVisible ? PencilInstUIIcon : null}
152
+ </IconButton>
153
+ )
154
+ }
155
+
156
+ renderAll = ({
157
+ getContainerProps,
158
+ getViewerProps,
159
+ getEditorProps,
160
+ getEditButtonProps
161
+ }: EditableRenderProps) => {
162
+ const flexDir =
163
+ this.props.editButtonPlacement === 'start' ? 'row-reverse' : 'row'
164
+ const justifyItems = flexDir === 'row-reverse' ? 'end' : 'start'
165
+ const buttonMargin =
166
+ this.props.editButtonPlacement === 'start'
167
+ ? '0 xx-small 0 0'
168
+ : '0 0 0 xx-small'
169
+ return (
170
+ <Flex
171
+ display={this.props.inline ? 'inline-flex' : 'flex'}
172
+ direction={flexDir}
173
+ justifyItems={justifyItems}
174
+ {...getContainerProps()}
175
+ >
176
+ <Flex.Item shouldGrow shouldShrink>
177
+ {this.renderEditor(getEditorProps())}
178
+ {this.renderViewer(getViewerProps())}
179
+ </Flex.Item>
180
+ <Flex.Item margin={buttonMargin}>
181
+ {this.renderEditButton(getEditButtonProps())}
182
+ </Flex.Item>
183
+ </Flex>
184
+ )
185
+ }
186
+
187
+ render() {
188
+ const { mode, value, onChange, onChangeMode, readOnly } = this.props
189
+
190
+ return (
191
+ <Editable
192
+ mode={mode}
193
+ onChangeMode={onChangeMode}
194
+ render={this.renderAll}
195
+ value={value}
196
+ onChange={onChange}
197
+ readOnly={readOnly}
198
+ elementRef={this.handleRef}
199
+ />
200
+ )
201
+ }
202
+ }
203
+
204
+ export default InPlaceEdit
205
+ export { InPlaceEdit }
@@ -0,0 +1,146 @@
1
+ /*
2
+ * The MIT License (MIT)
3
+ *
4
+ * Copyright (c) 2015 - present Instructure, Inc.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+
25
+ import type { WithStyleProps, ComponentStyle } from '@instructure/emotion'
26
+ import type { EditableProps } from '../../Editable/v1/props'
27
+ import React from 'react'
28
+
29
+ type ExtendedRenderEditButton = {
30
+ elementRef?: (el: HTMLButtonElement) => void
31
+ onClick: () => void
32
+ onFocus: () => void
33
+ onBlur: () => void
34
+ isVisible: boolean
35
+ readOnly?: boolean
36
+ }
37
+
38
+ type InPlaceEditOwnProps = {
39
+ /**
40
+ * Function to render the view mode component.
41
+ * It is the consumer's responsibility to provide the
42
+ * current value or children.
43
+ *
44
+ * Return value:
45
+ * - element: the viewer DOM sub-tree.
46
+ */
47
+ renderViewer: () => React.ReactNode
48
+ /**
49
+ * Function to render the edit mode component
50
+ * It is the consumer's responsibility to provide the
51
+ * current value, and to attach the appropriate onChange
52
+ * event handler needed to capture the updated value. This
53
+ * new value must then be forwarded to the view mode component.
54
+ *
55
+ * Return value:
56
+ * - element: the editor DOM sub-tree.
57
+ */
58
+ renderEditor: (data: {
59
+ onBlur: () => void
60
+ editorRef: (el: HTMLElement | null) => void
61
+ }) => React.ReactNode
62
+ /**
63
+ * Function to render the edit button.
64
+ *
65
+ * Parameters:
66
+ * - object: { isVisible, onClick, onFocus, onBlur, buttonRef }
67
+ *
68
+ * Return value:
69
+ *
70
+ * - element: the edit button DOM sub-tree
71
+ *
72
+ * If you choose to use the default edit button, add `label` to the
73
+ * incoming `props` parameter and call `InPlaceEdit.renderDefaultEditButton(props)`
74
+ *
75
+ * If you choose to render a custom button, attach the on* event handlers
76
+ * and set `buttonRef` as a `ref` type property on the `button` element.
77
+ *
78
+ * `isVisible` is a hint as to whether the button is _typically_ shown,
79
+ * but you're free to ignore it for your use-case.
80
+ */
81
+ renderEditButton: (props: ExtendedRenderEditButton) => React.ReactNode | null
82
+ /**
83
+ * If `'view'`: the view component is rendered,
84
+ * if `'edit'`: the edit component is rendered
85
+ */
86
+ mode: 'view' | 'edit'
87
+ /**
88
+ * Called when the component's mode changes
89
+ * Parameter:
90
+ * - newMode: string
91
+ */
92
+ onChangeMode: EditableProps['onChangeMode']
93
+ /**
94
+ * The current value.
95
+ * The value is managed by the consuming app, but we need to tell InPlaceEdit
96
+ * it's changed or it won't re-render
97
+ */
98
+ value?: any
99
+ /**
100
+ * Called when Editable switches from edit to view mode and the value has changed.
101
+ * Parameter:
102
+ * - value: any
103
+ */
104
+ onChange?: EditableProps['onChange']
105
+ /**
106
+ * The mode is fixed as 'view'
107
+ */
108
+ readOnly?: boolean
109
+ /**
110
+ * Show a focus outline when the input is focused
111
+ */
112
+ showFocusRing?: boolean
113
+ /**
114
+ * Put the edit button before or after the view
115
+ */
116
+ editButtonPlacement?: 'start' | 'end'
117
+ /**
118
+ * Render outermost element inline v. block
119
+ */
120
+ inline?: boolean
121
+ }
122
+
123
+ type PropKeys = keyof InPlaceEditOwnProps
124
+
125
+ type AllowedPropKeys = Readonly<Array<PropKeys>>
126
+
127
+ type InPlaceEditProps = InPlaceEditOwnProps &
128
+ WithStyleProps<null, InPlaceEditStyle>
129
+
130
+ type InPlaceEditStyle = ComponentStyle<'inPlaceEdit'>
131
+ const allowedProps: AllowedPropKeys = [
132
+ 'renderViewer',
133
+ 'renderEditor',
134
+ 'renderEditButton',
135
+ 'mode',
136
+ 'onChangeMode',
137
+ 'value',
138
+ 'onChange',
139
+ 'readOnly',
140
+ 'showFocusRing',
141
+ 'editButtonPlacement',
142
+ 'inline'
143
+ ]
144
+
145
+ export type { InPlaceEditProps, InPlaceEditStyle }
146
+ export { allowedProps }