@atlaskit/editor-plugin-media
Version:
Media plugin for @atlaskit/editor-core
233 lines (230 loc) • 8.22 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
/**
* @jsxRuntime classic
* @jsx jsx
*/
import React, { Fragment } from 'react';
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports
import { css, jsx } from '@emotion/react';
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
import { container, containerWithProvider, inputWrapper, RecentSearch } from '@atlaskit/editor-common/link';
import { mediaLinkToolbarMessages } from '@atlaskit/editor-common/media';
import { linkToolbarMessages } from '@atlaskit/editor-common/messages';
import { FloatingToolbarButton as Button, ErrorMessage, FloatingToolbarSeparator as Separator,
// Common Translations will live here
PanelTextInput } from '@atlaskit/editor-common/ui';
import { normalizeUrl } from '@atlaskit/editor-common/utils';
import ChevronLeftLargeIcon from '@atlaskit/icon/core/chevron-left';
import EditorUnlinkIcon from '@atlaskit/icon/core/link-broken';
const validationWrapper = css({
// eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
lineHeight: 0,
padding: `${"var(--ds-space-150, 12px)"} ${"var(--ds-space-300, 24px)"} ${"var(--ds-space-150, 12px)"} 0`,
margin: `0 ${"var(--ds-space-050, 4px)"} 0 ${"var(--ds-space-400, 32px)"}`,
borderTop: `${"var(--ds-border-width, 1px)"} solid ${"var(--ds-border-danger, #E2483D)"}`,
alignItems: 'start',
display: 'flex',
flexDirection: 'column'
});
const buttonWrapper = css({
padding: `${"var(--ds-space-050, 4px)"} ${"var(--ds-space-100, 8px)"} ${"var(--ds-space-050, 4px)"} 0px`
});
// eslint-disable-next-line @repo/internal/react/no-class-components
class LinkAddToolbar extends React.PureComponent {
constructor(...args) {
super(...args);
_defineProperty(this, "state", {
validationErrors: []
});
_defineProperty(this, "handleSubmit", ({
url,
inputMethod
}) => {
this.props.onSubmit(url, {
inputMethod
});
});
_defineProperty(this, "handleOnBack", ({
url,
inputMethod
}, setFocus) => {
const {
onBack
} = this.props;
if (onBack) {
onBack(url, {
inputMethod
}, setFocus);
}
});
_defineProperty(this, "handleCancel", () => {
const {
onCancel
} = this.props;
if (onCancel) {
onCancel();
}
});
_defineProperty(this, "handleUnlink", setFocus => {
const {
onUnlink
} = this.props;
if (onUnlink) {
onUnlink(setFocus);
}
});
_defineProperty(this, "handleOnBlur", options => {
this.props.onBlur(options.url);
});
_defineProperty(this, "renderContainer", ({
activityProvider,
inputProps: {
onChange,
onKeyDown,
onSubmit,
value
},
currentInputMethod,
renderRecentList
}) => {
const {
intl: {
formatMessage
},
displayUrl
} = this.props;
const getPlaceholder = hasActivityProvider => formatMessage(hasActivityProvider ? linkToolbarMessages.placeholder : linkToolbarMessages.linkPlaceholder);
const formatLinkAddressText = formatMessage(mediaLinkToolbarMessages.backLink);
const formatUnlinkText = formatMessage(linkToolbarMessages.unlink);
const errorsList = this.state.validationErrors.map(function (error, index) {
// Ignored via go/ees005
// eslint-disable-next-line react/no-array-index-key
return jsx(ErrorMessage, {
key: index
}, error);
});
return (
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
jsx("div", {
className: "recent-list"
}, jsx("div", {
css: [container, !!activityProvider && containerWithProvider]
}, jsx("div", {
css: inputWrapper
}, jsx("span", {
css: buttonWrapper
}, jsx(Button, {
title: formatLinkAddressText,
icon: jsx(ChevronLeftLargeIcon, {
label: formatLinkAddressText,
size: "small"
})
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onClick: () => this.handleOnBack({
url: value,
inputMethod: currentInputMethod
})
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onKeyDown: event => {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
this.handleOnBack({
url: value,
inputMethod: currentInputMethod
}, true);
}
},
areAnyNewToolbarFlagsEnabled: this.props.areAnyNewToolbarFlagsEnabled
})), jsx(PanelTextInput, {
inputId: "media-link-search-input",
testId: "media-link-input",
placeholder: getPlaceholder(!!activityProvider),
autoFocus: true,
onCancel: this.handleCancel,
defaultValue: value
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onSubmit: inputValue => {
const validationErrors = this.getValidationErrors(inputValue, currentInputMethod);
this.setState({
validationErrors
});
if (!validationErrors.length) {
onSubmit();
}
}
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onChange: value => {
this.setState({
validationErrors: []
});
onChange(value);
},
onKeyDown: onKeyDown
}), jsx("label", {
className: "assistive",
htmlFor: "media-link-search-input"
}, formatMessage(linkToolbarMessages.searchInput)), normalizeUrl(displayUrl) && jsx(Fragment, null, jsx(Separator, {
areAnyNewToolbarFlagsEnabled: this.props.areAnyNewToolbarFlagsEnabled
}), jsx(Button, {
title: formatUnlinkText,
icon: jsx(EditorUnlinkIcon, {
label: formatUnlinkText
})
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onClick: () => this.handleUnlink()
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onKeyDown: event => {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
this.handleUnlink(true);
}
},
areAnyNewToolbarFlagsEnabled: this.props.areAnyNewToolbarFlagsEnabled
}))), !!errorsList.length && jsx("section", {
css: validationWrapper
}, errorsList), renderRecentList()))
);
});
}
getValidationErrors(value, inputMethod) {
const {
intl: {
formatMessage
}
} = this.props;
// dont show validation errors if input method is typeahed, which means user selects from search list
if (inputMethod === INPUT_METHOD.TYPEAHEAD) {
return [];
}
if (!value) {
return [formatMessage(linkToolbarMessages.emptyLink)];
}
// if url can be normalized - we consider it is a valid url
// also don't show validaition errors for empty values
if (normalizeUrl(value)) {
return [];
} else {
return [formatMessage(linkToolbarMessages.invalidLink)];
}
}
render() {
const {
providerFactory,
displayUrl
} = this.props;
return jsx(RecentSearch, {
defaultUrl: normalizeUrl(displayUrl),
providerFactory: providerFactory,
onSubmit: this.handleSubmit,
onBlur: this.handleOnBlur,
render: this.renderContainer
});
}
}
export default LinkAddToolbar;