-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[TreeView] Clean label editing code #14264
Changes from 1 commit
cdab9e0
33ae500
5070e7d
1082418
d528bda
1aeb92f
3cb705c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,12 @@ | ||
export interface TreeItem2LabelInputProps extends React.InputHTMLAttributes<HTMLInputElement> { | ||
import * as React from 'react'; | ||
import { MuiCancellableEventHandler } from '../internals/models/MuiCancellableEvent'; | ||
|
||
export interface TreeItem2LabelInputProps { | ||
value?: string; | ||
onChange?: React.ChangeEventHandler<HTMLInputElement>; | ||
/** | ||
* Used to determine if the target of keydown or blur events is the input and prevent the event from propagating to the root. | ||
*/ | ||
flaviendelangle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
'data-element'?: 'labelInput'; | ||
onChange?: React.ChangeEventHandler<HTMLInputElement>; | ||
onKeyDown?: MuiCancellableEventHandler<React.KeyboardEvent<HTMLInputElement>>; | ||
onBlur?: MuiCancellableEventHandler<React.FocusEvent<HTMLInputElement>>; | ||
autoFocus?: true; | ||
type?: 'text'; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,12 @@ | ||
import * as React from 'react'; | ||
import { useTreeViewContext } from '../../TreeViewProvider'; | ||
import { TreeViewItemPlugin } from '../../models'; | ||
import { MuiCancellableEvent, TreeViewItemPlugin } from '../../models'; | ||
import { UseTreeViewItemsSignature } from '../useTreeViewItems'; | ||
import { | ||
UseTreeItem2LabelInputSlotPropsFromItemsReordering, | ||
UseTreeItem2LabelInputSlotPropsFromLabelEditing, | ||
UseTreeViewLabelSignature, | ||
} from './useTreeViewLabel.types'; | ||
|
||
export const isAndroid = () => navigator.userAgent.toLowerCase().includes('android'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Never used |
||
|
||
export const useTreeViewLabelItemPlugin: TreeViewItemPlugin<any> = ({ props }) => { | ||
const { instance } = useTreeViewContext<[UseTreeViewItemsSignature, UseTreeViewLabelSignature]>(); | ||
const { label, itemId } = props; | ||
|
@@ -27,13 +25,41 @@ export const useTreeViewLabelItemPlugin: TreeViewItemPlugin<any> = ({ props }) = | |
propsEnhancers: { | ||
labelInput: ({ | ||
externalEventHandlers, | ||
}): UseTreeItem2LabelInputSlotPropsFromItemsReordering => { | ||
interactions, | ||
}): UseTreeItem2LabelInputSlotPropsFromLabelEditing => { | ||
const editable = instance.isItemEditable(itemId); | ||
|
||
if (!editable) { | ||
return {}; | ||
} | ||
|
||
const handleKeydown = ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move those two callbacks here, that way |
||
event: React.KeyboardEvent<HTMLInputElement> & MuiCancellableEvent, | ||
) => { | ||
externalEventHandlers.onKeyDown?.(event); | ||
if (event.defaultMuiPrevented) { | ||
return; | ||
} | ||
const target = event.target as HTMLInputElement; | ||
|
||
if (event.key === 'Enter' && target.value) { | ||
interactions.handleSaveItemLabel(event, target.value); | ||
} else if (event.key === 'Escape') { | ||
interactions.handleCancelItemLabelEditing(event); | ||
} | ||
}; | ||
|
||
const handleBlur = (event: React.FocusEvent<HTMLInputElement> & MuiCancellableEvent) => { | ||
externalEventHandlers.onBlur?.(event); | ||
if (event.defaultMuiPrevented) { | ||
return; | ||
} | ||
|
||
if (event.target.value) { | ||
interactions.handleSaveItemLabel(event, event.target.value); | ||
} | ||
}; | ||
|
||
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => { | ||
externalEventHandlers.onChange?.(event); | ||
setLabelInputValue(event.target.value); | ||
|
@@ -43,6 +69,8 @@ export const useTreeViewLabelItemPlugin: TreeViewItemPlugin<any> = ({ props }) = | |
value: labelInputValue ?? '', | ||
'data-element': 'labelInput', | ||
onChange: handleInputChange, | ||
onKeyDown: handleKeydown, | ||
onBlur: handleBlur, | ||
autoFocus: true, | ||
type: 'text', | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -76,5 +76,10 @@ export type UseTreeViewLabelSignature = TreeViewPluginSignature<{ | |
experimentalFeatures: 'labelEditing'; | ||
dependencies: [UseTreeViewItemsSignature]; | ||
}>; | ||
export interface UseTreeItem2LabelInputSlotPropsFromItemsReordering | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo in the name and the props were never added to the typing of |
||
extends TreeItem2LabelInputProps {} | ||
|
||
export interface UseTreeItem2LabelInputSlotPropsFromLabelEditing extends TreeItem2LabelInputProps {} | ||
|
||
declare module '@mui/x-tree-view/useTreeItem2' { | ||
interface UseTreeItem2LabelInputSlotOwnProps | ||
extends UseTreeItem2LabelInputSlotPropsFromLabelEditing {} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should avoid to add props we don't actually use to the typing of our slots.
That way people implementing custom slots only need to support the props we actually need and not all the props we could theoretically use on our default slot component.