-
Notifications
You must be signed in to change notification settings - Fork 308
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(content-explorer): Migrate renameDialog
- Loading branch information
1 parent
c76176e
commit d685f6e
Showing
5 changed files
with
255 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
import * as React from 'react'; | ||
import Modal from 'react-modal'; | ||
import { FormattedMessage, useIntl } from 'react-intl'; | ||
import { Modal as BlueprintModal, Text } from '@box/blueprint-web'; | ||
|
||
import { | ||
CLASS_MODAL_CONTENT, | ||
CLASS_MODAL_OVERLAY, | ||
CLASS_MODAL, | ||
ERROR_CODE_ITEM_NAME_TOO_LONG, | ||
ERROR_CODE_ITEM_NAME_IN_USE, | ||
} from '../../constants'; | ||
import type { BoxItem } from '../../common/types/core'; | ||
|
||
import messages from '../common/messages'; | ||
|
||
export interface RenameDialogProps { | ||
appElement: HTMLElement; | ||
errorCode: string; | ||
isLoading: boolean; | ||
isOpen: boolean; | ||
item: BoxItem; | ||
onCancel: () => void; | ||
onRename: (value: string, extension: string) => void; | ||
parentElement: HTMLElement; | ||
} | ||
|
||
const RenameDialog = ({ | ||
appElement, | ||
errorCode, | ||
isOpen, | ||
isLoading, | ||
item, | ||
onCancel, | ||
onRename, | ||
parentElement, | ||
}: RenameDialogProps) => { | ||
const { formatMessage } = useIntl(); | ||
let textInput = null; | ||
let error; | ||
|
||
const { name = '', extension } = item; | ||
const ext = extension ? `.${extension}` : ''; | ||
const nameWithoutExt = extension ? name.replace(ext, '') : name; | ||
|
||
/** | ||
* Appends the extension and calls rename function | ||
*/ | ||
const handleRename = () => { | ||
if (textInput && textInput.value) { | ||
if (textInput.value === nameWithoutExt) { | ||
onCancel(); | ||
} else { | ||
onRename(textInput.value, ext); | ||
} | ||
} | ||
}; | ||
|
||
/** | ||
* Grabs reference to the input element | ||
*/ | ||
const ref = input => { | ||
textInput = input; | ||
if (textInput instanceof HTMLInputElement) { | ||
textInput.focus(); | ||
textInput.select(); | ||
} | ||
}; | ||
|
||
/** | ||
* Handles enter key down | ||
*/ | ||
const onKeyDown = ({ key }) => { | ||
switch (key) { | ||
case 'Enter': | ||
handleRename(); | ||
break; | ||
default: | ||
break; | ||
} | ||
}; | ||
|
||
switch (errorCode) { | ||
case ERROR_CODE_ITEM_NAME_IN_USE: | ||
error = messages.renameDialogErrorInUse; | ||
break; | ||
case ERROR_CODE_ITEM_NAME_TOO_LONG: | ||
error = messages.renameDialogErrorTooLong; | ||
break; | ||
default: | ||
error = errorCode ? messages.renameDialogErrorInvalid : null; | ||
break; | ||
} | ||
|
||
return ( | ||
<Modal | ||
appElement={appElement} | ||
className={CLASS_MODAL_CONTENT} | ||
contentLabel={formatMessage(messages.renameDialogLabel)} | ||
isOpen={isOpen} | ||
onRequestClose={onCancel} | ||
overlayClassName={CLASS_MODAL_OVERLAY} | ||
parentSelector={() => parentElement} | ||
portalClassName={`${CLASS_MODAL} be-modal-rename`} | ||
> | ||
<BlueprintModal.Body> | ||
<Text as="label"> | ||
{error && ( | ||
<div className="be-modal-error"> | ||
<FormattedMessage {...error} values={{ name: nameWithoutExt }} /> | ||
</div> | ||
)} | ||
</Text> | ||
<Text as="label"> | ||
<FormattedMessage {...messages.renameDialogText} values={{ name: nameWithoutExt }} /> | ||
</Text> | ||
<input ref={ref} defaultValue={nameWithoutExt} onKeyDown={onKeyDown} required type="text" /> | ||
</BlueprintModal.Body> | ||
<BlueprintModal.Footer> | ||
<BlueprintModal.Footer.SecondaryButton disabled={isLoading} onClick={onCancel} size="large"> | ||
{formatMessage(messages.cancel)} | ||
</BlueprintModal.Footer.SecondaryButton> | ||
<BlueprintModal.Footer.PrimaryButton | ||
loading={isLoading} | ||
loadingAriaLabel={formatMessage(messages.loading)} | ||
onClick={handleRename} | ||
size="large" | ||
> | ||
{formatMessage(messages.rename)} | ||
</BlueprintModal.Footer.PrimaryButton> | ||
</BlueprintModal.Footer> | ||
</Modal> | ||
); | ||
}; | ||
|
||
export default RenameDialog; |
49 changes: 49 additions & 0 deletions
49
src/elements/content-explorer/stories/RenameDialog.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import * as React from 'react'; | ||
import { useArgs } from '@storybook/preview-api'; | ||
import { Button } from '@box/blueprint-web'; | ||
|
||
import { addRootElement } from '../../../utils/storybook'; | ||
|
||
import RenameDialog, { RenameDialogProps } from '../RenameDialog'; | ||
|
||
export const renameDialog = { | ||
render: (args: RenameDialogProps) => { | ||
// eslint-disable-next-line react-hooks/rules-of-hooks | ||
const [, setArgs] = useArgs(); | ||
|
||
const handleOpenModal = () => setArgs({ isOpen: true }); | ||
|
||
const handleCloseModal = () => { | ||
setArgs({ isOpen: false }); | ||
}; | ||
|
||
const { appElement, rootElement } = addRootElement(); | ||
|
||
return ( | ||
<div> | ||
<RenameDialog | ||
appElement={appElement} | ||
item={{ | ||
id: '123456', | ||
name: 'mockItem', | ||
}} | ||
onCancel={handleCloseModal} | ||
parentElement={rootElement} | ||
{...args} | ||
/> | ||
<Button onClick={handleOpenModal} variant="primary"> | ||
Launch RenameDialog | ||
</Button> | ||
</div> | ||
); | ||
}, | ||
}; | ||
|
||
export default { | ||
title: 'Elements/ContentExplorer', | ||
component: RenameDialog, | ||
args: { | ||
isLoading: false, | ||
isOpen: false, | ||
}, | ||
}; |
Oops, something went wrong.