update: toolbar popup

This commit is contained in:
yanmao 2022-01-07 00:13:10 +08:00
parent 679bb4116f
commit 614131e810
28 changed files with 272 additions and 162 deletions

View File

@ -311,84 +311,82 @@ export const lineHeightOptions: LineHeightOptions = {
}; };
export const toolbarOptions: ToolbarOptions = { export const toolbarOptions: ToolbarOptions = {
// popup: { popup: {
// items: [ items: [
// ['undo', 'redo'], ['undo', 'redo'],
// { {
// icon: 'text', icon: 'text',
// items: [ items: [
// 'bold', 'bold',
// 'italic', 'italic',
// 'strikethrough', 'strikethrough',
// 'underline', 'underline',
// 'fontsize', 'backcolor',
// 'fontcolor', 'moremark',
// 'backcolor', ],
// 'moremark', },
// ], [
// }, {
// [ type: 'button',
// { name: 'image-uploader',
// type: 'button', icon: 'image',
// name: 'image-uploader', },
// icon: 'image', 'link',
// }, 'tasklist',
// 'link', 'heading',
// 'tasklist', ],
// 'heading', {
// ], icon: 'more',
// { items: [
// icon: 'more', {
// items: [ type: 'button',
// { name: 'video-uploader',
// type: 'button', icon: 'video',
// name: 'video-uploader', },
// icon: 'video', {
// }, type: 'button',
// { name: 'file-uploader',
// type: 'button', icon: 'attachment',
// name: 'file-uploader', },
// icon: 'attachment', {
// }, type: 'button',
// { name: 'table',
// type: 'button', icon: 'table',
// name: 'table', },
// icon: 'table', {
// }, type: 'button',
// { name: 'math',
// type: 'button', icon: 'math',
// name: 'math', },
// icon: 'math', {
// }, type: 'button',
// { name: 'codeblock',
// type: 'button', icon: 'codeblock',
// name: 'codeblock', },
// icon: 'codeblock', {
// }, type: 'button',
// { name: 'orderedlist',
// type: 'button', icon: 'ordered-list',
// name: 'orderedlist', },
// icon: 'ordered-list', {
// }, type: 'button',
// { name: 'unordered-list',
// type: 'button', icon: 'unordered-list',
// name: 'unordered-list', },
// icon: 'unordered-list', {
// }, type: 'button',
// { name: 'hr',
// type: 'button', icon: 'hr',
// name: 'hr', },
// icon: 'hr', {
// }, type: 'button',
// { name: 'quote',
// type: 'button', icon: 'quote',
// name: 'quote', },
// icon: 'quote', ],
// }, },
// ], ],
// }, },
// ]
// }
}; };
export const pluginConfig: Record<string, PluginOptions> = { export const pluginConfig: Record<string, PluginOptions> = {

View File

@ -111,6 +111,84 @@ export const cards: Array<CardEntry> = [
]; ];
export const pluginConfig: { [key: string]: PluginOptions } = { export const pluginConfig: { [key: string]: PluginOptions } = {
[ToolbarPlugin.pluginName]: {
popup: {
items: [
['undo', 'redo'],
{
icon: 'text',
items: [
'bold',
'italic',
'strikethrough',
'underline',
'backcolor',
'moremark',
],
},
[
{
type: 'button',
name: 'image-uploader',
icon: 'image',
},
'link',
'tasklist',
'heading',
],
{
icon: 'more',
items: [
{
type: 'button',
name: 'video-uploader',
icon: 'video',
},
{
type: 'button',
name: 'file-uploader',
icon: 'attachment',
},
{
type: 'button',
name: 'table',
icon: 'table',
},
{
type: 'button',
name: 'math',
icon: 'math',
},
{
type: 'button',
name: 'codeblock',
icon: 'codeblock',
},
{
type: 'button',
name: 'orderedlist',
icon: 'ordered-list',
},
{
type: 'button',
name: 'unordered-list',
icon: 'unordered-list',
},
{
type: 'button',
name: 'hr',
icon: 'hr',
},
{
type: 'button',
name: 'quote',
icon: 'quote',
},
],
},
],
},
},
[Italic.pluginName]: { [Italic.pluginName]: {
// 默认为 _ 下划线,这里修改为单个 * 号 // 默认为 _ 下划线,这里修改为单个 * 号
markdown: '*', markdown: '*',

View File

@ -99,7 +99,7 @@ export default defineComponent({
</script> </script>
<style css> <style css>
.editor-toolbar .toolbar-button { .editor-toolbar .toolbar-button {
display: inline-flex; display: inline-block;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: auto; width: auto;
@ -116,12 +116,13 @@ export default defineComponent({
outline: none; outline: none;
line-height: 32px; line-height: 32px;
} }
.editor-toolbar.editor-toolbar-popup .toolbar-button { .editor-toolbar.editor-toolbar-popup .toolbar-button {
min-width: 24px; min-width: 24px;
line-height: 24px; line-height: 24px;
border-radius: 4px; border-radius: 4px;
margin: 0 4px;
} }
.editor-toolbar:not(.editor-toolbar-mobile) .toolbar-button { .editor-toolbar:not(.editor-toolbar-mobile) .toolbar-button {
padding: 0 4px; padding: 0 4px;
} }

View File

@ -11,6 +11,7 @@
:title="buttonTitle" :title="buttonTitle"
:on-click="triggerClick" :on-click="triggerClick"
:disabled="disabled" :disabled="disabled"
:placement="placement"
> >
<span v-html="buttonContent"></span> <span v-html="buttonContent"></span>
</am-button> </am-button>
@ -20,6 +21,7 @@
:title="dropdownTitle" :title="dropdownTitle"
:on-click="toggleDropdown" :on-click="toggleDropdown"
:disabled="disabled" :disabled="disabled"
:placement="placement"
> >
<template #icon> <template #icon>
<span class="colorpicker-button-dropdown-empty" /> <span class="colorpicker-button-dropdown-empty" />
@ -151,24 +153,36 @@ export default defineComponent({
} }
.colorpicker-button-group .colorpicker-button-text { .colorpicker-button-group .colorpicker-button-text {
height: 32px;
margin-right: 0; margin-right: 0;
min-width: 26px; min-width: 26px;
border-radius: 3px 0 0 3px; border-radius: 3px 0 0 3px;
} }
.editor-toolbar.editor-toolbar-popup .colorpicker-button-group .colorpicker-button-text {
margin: 0;
border-radius: 3px 0 0 3px;
}
.colorpicker-button-group .colorpicker-button-text:active { .colorpicker-button-group .colorpicker-button-text:active {
background-color: #e8e8e8; background-color: #e8e8e8;
} }
.colorpicker-button-group .colorpicker-button-dropdown { .colorpicker-button-group .colorpicker-button-dropdown {
height: 32px;
margin-left: -1px; margin-left: -1px;
min-width: 17px; min-width: 17px;
text-align: center; text-align: center;
padding: 0 0; padding: 0 0;
border-radius: 0 3px 3px 0; border-radius: 0 3px 3px 0;
} }
.editor-toolbar.editor-toolbar-popup .colorpicker-button-group .colorpicker-button-dropdown {
line-height: 24px;
min-width: 17px;
padding: 0 4px;
margin: 0;
margin-left: -1px;
border-radius: 0 3px 3px 0;
}
.colorpicker-button-group .colorpicker-button-dropdown:hover, .colorpicker-button-group .colorpicker-button-dropdown:hover,
.colorpicker-button-group .colorpicker-button-dropdown:active { .colorpicker-button-group .colorpicker-button-dropdown:active {

View File

@ -16,6 +16,7 @@
:title="title" :title="title"
:active="visible" :active="visible"
:disabled="disabled" :disabled="disabled"
:placement="placement"
> >
<template #default> <template #default>
<slot :item="content"> <slot :item="content">
@ -144,11 +145,9 @@ export default defineComponent({
<style> <style>
.toolbar-dropdown { .toolbar-dropdown {
position: relative; position: relative;
display: inline-flex;
} }
.toolbar-dropdown .toolbar-dropdown-trigger { .toolbar-dropdown .toolbar-dropdown-trigger {
display: inline-flex;
align-items: center; align-items: center;
} }
@ -158,6 +157,7 @@ export default defineComponent({
.toolbar-dropdown .toolbar-dropdown-trigger-arrow .toolbar-button{ .toolbar-dropdown .toolbar-dropdown-trigger-arrow .toolbar-button{
padding-right: 20px; padding-right: 20px;
margin: 0;
} }
.toolbar-dropdown .toolbar-dropdown-trigger-arrow .data-icon-arrow { .toolbar-dropdown .toolbar-dropdown-trigger-arrow .data-icon-arrow {

View File

@ -11,9 +11,9 @@
<div :class="['editor-toolbar', {'editor-toolbar-mobile': isMobile && !popup, <div :class="['editor-toolbar', {'editor-toolbar-mobile': isMobile && !popup,
'editor-toolbar-popup': popup,}]" data-element="ui"> 'editor-toolbar-popup': popup,}]" data-element="ui">
<template v-for="(item , index) in items" :key="index"> <template v-for="(item , index) in items" :key="index">
<am-button v-if="item.type === 'button'" :key="index" v-bind="item" :engine="engine" /> <am-button v-if="item.type === 'button'" :key="index" v-bind="item" placement="top" :engine="engine" />
<am-dropdown v-if="item.type === 'dropdown'" :key="index" v-bind="item" :engine="engine" /> <am-dropdown v-if="item.type === 'dropdown'" :key="index" v-bind="item" placement="top" :engine="engine" />
<am-color v-if="item.type === 'color'" :key="index" v-bind="item" :engine="engine" /> <am-color v-if="item.type === 'color'" :key="index" v-bind="item" placement="top" :engine="engine" />
<am-collapse v-if="item.type === 'collapse'" :key="index" v-bind="item" :engine="engine" /> <am-collapse v-if="item.type === 'collapse'" :key="index" v-bind="item" :engine="engine" />
</template> </template>
</div> </div>
@ -67,6 +67,8 @@ export default defineComponent({
padding: 4px 8px; padding: 4px 8px;
width: auto; width: auto;
border-left: 1px solid #e8e8e8; border-left: 1px solid #e8e8e8;
display: flex;
align-items: center;
} }
.editor-toolbar .editor-toolbar-group:nth-child(1) { .editor-toolbar .editor-toolbar-group:nth-child(1) {

View File

@ -298,6 +298,7 @@ export {
border: 0 none; border: 0 none;
left: 0; left: 0;
top: 0; top: 0;
display: flex;
} }
.editor-toolbar-popover { .editor-toolbar-popover {

View File

@ -33,7 +33,6 @@
overflow: auto; overflow: auto;
} }
/** ------------------- popup ---------------------- **/ /** ------------------- popup ---------------------- **/
/** ------------------- popup ---------------------- **/
.data-toolbar-popup-wrapper { .data-toolbar-popup-wrapper {
position: absolute; position: absolute;
z-index: 9999; z-index: 9999;
@ -49,7 +48,7 @@
} }
.data-toolbar-popup-wrapper .editor-toolbar-popover .ant-popover-inner-content { .data-toolbar-popup-wrapper .editor-toolbar-popover .ant-popover-inner-content {
padding: 4px 0; padding: 4px;
background-color: #fff; background-color: #fff;
border-radius: 4px; border-radius: 4px;
border: 1px solid #dee0e3; border: 1px solid #dee0e3;

View File

@ -1,4 +1,4 @@
import { EngineInterface } from '@aomao/engine'; import type { EngineInterface, Placement } from '@aomao/engine';
import { ExtractPropTypes, PropType, VNode } from 'vue'; import { ExtractPropTypes, PropType, VNode } from 'vue';
import { omit } from 'lodash'; import { omit } from 'lodash';
@ -7,20 +7,6 @@ export type Command =
| { name: string; args: Array<any> } | { name: string; args: Array<any> }
| Array<any> | Array<any>
| undefined; | undefined;
//tooltip 位置
export type Placement =
| 'top'
| 'left'
| 'right'
| 'bottom'
| 'topLeft'
| 'topRight'
| 'bottomLeft'
| 'bottomRight'
| 'leftTop'
| 'leftBottom'
| 'rightTop'
| 'rightBottom';
//按钮 //按钮
export const buttonProps = { export const buttonProps = {
engine: Object as PropType<EngineInterface | undefined>, engine: Object as PropType<EngineInterface | undefined>,
@ -116,6 +102,7 @@ export const dropdownProps = {
default: [], default: [],
} as const, } as const,
icon: String, icon: String,
placement: String as PropType<Placement>,
content: [String, Function] as PropType<string | (() => string)>, content: [String, Function] as PropType<string | (() => string)>,
title: String, title: String,
disabled: { disabled: {
@ -195,6 +182,7 @@ export const colorPickerProps = {
} as const, } as const,
setStroke: colorPickerGroupProps.setStroke, setStroke: colorPickerGroupProps.setStroke,
onSelect: colorPickerItemProps.onSelect, onSelect: colorPickerItemProps.onSelect,
placement: String as PropType<Placement>,
}; };
export type ColorPickerProps = ExtractPropTypes<typeof colorPickerProps>; export type ColorPickerProps = ExtractPropTypes<typeof colorPickerProps>;
//color //color

View File

@ -1,5 +1,5 @@
.editor-toolbar .toolbar-button { .editor-toolbar .toolbar-button {
display: inline-flex; display: inline-block;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: auto; width: auto;
@ -21,7 +21,6 @@
min-width: 24px; min-width: 24px;
line-height: 24px; line-height: 24px;
border-radius: 4px; border-radius: 4px;
margin: 0 4px;
} }
.editor-toolbar:not(.editor-toolbar-mobile) .toolbar-button { .editor-toolbar:not(.editor-toolbar-mobile) .toolbar-button {

View File

@ -1,7 +1,8 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import Tooltip from 'antd/es/tooltip'; import Tooltip from 'antd/es/tooltip';
import classnames from 'classnames-es-ts'; import classnames from 'classnames-es-ts';
import { EngineInterface, formatHotkey, isMobile } from '@aomao/engine'; import { formatHotkey, isMobile } from '@aomao/engine';
import type { EngineInterface, Placement } from '@aomao/engine';
import { autoGetHotkey } from '../utils'; import { autoGetHotkey } from '../utils';
import 'antd/es/tooltip/style'; import 'antd/es/tooltip/style';
import './index.css'; import './index.css';
@ -12,19 +13,7 @@ export type ButtonProps = {
icon?: React.ReactNode; icon?: React.ReactNode;
content?: React.ReactNode | (() => React.ReactNode); content?: React.ReactNode | (() => React.ReactNode);
title?: string; title?: string;
placement?: placement?: Placement;
| 'right'
| 'top'
| 'left'
| 'bottom'
| 'topLeft'
| 'topRight'
| 'bottomLeft'
| 'bottomRight'
| 'leftTop'
| 'leftBottom'
| 'rightTop'
| 'rightBottom';
hotkey?: boolean | string; hotkey?: boolean | string;
command?: { name: string; args: Array<any> } | Array<any>; command?: { name: string; args: Array<any> } | Array<any>;
autoExecute?: boolean; autoExecute?: boolean;

View File

@ -9,7 +9,11 @@
.colorpicker-button-group .colorpicker-button-text { .colorpicker-button-group .colorpicker-button-text {
margin-right: 0; margin-right: 0;
min-width: 26px; min-width: 26px;
height: 32px; border-radius: 3px 0 0 3px;
}
.editor-toolbar.editor-toolbar-popup .colorpicker-button-group .colorpicker-button-text {
margin: 0;
border-radius: 3px 0 0 3px; border-radius: 3px 0 0 3px;
} }
@ -20,11 +24,19 @@
.colorpicker-button-group .colorpicker-button-dropdown { .colorpicker-button-group .colorpicker-button-dropdown {
margin-left: -1px; margin-left: -1px;
min-width: 17px; min-width: 17px;
height: 32px;
text-align: center; text-align: center;
padding: 0 0; padding: 0 0;
border-radius: 0 3px 3px 0; border-radius: 0 3px 3px 0;
} }
.editor-toolbar.editor-toolbar-popup .colorpicker-button-group .colorpicker-button-dropdown {
line-height: 24px;
min-width: 17px;
padding: 0 4px;
margin: 0;
margin-left: -1px;
border-radius: 0 3px 3px 0;
}
.colorpicker-button-group .colorpicker-button-dropdown:hover, .colorpicker-button-group .colorpicker-button-dropdown:hover,
.colorpicker-button-group .colorpicker-button-dropdown:active { .colorpicker-button-group .colorpicker-button-dropdown:active {

View File

@ -1,6 +1,6 @@
import React, { useEffect, useState, useRef } from 'react'; import React, { useEffect, useState, useRef } from 'react';
import classNames from 'classnames-es-ts'; import classNames from 'classnames-es-ts';
import { EngineInterface } from '@aomao/engine'; import type { EngineInterface, Placement } from '@aomao/engine';
import { useRight } from '../hooks'; import { useRight } from '../hooks';
import Button from '../button'; import Button from '../button';
import ColorPicker, { ColorPickerProps, Palette } from './picker'; import ColorPicker, { ColorPickerProps, Palette } from './picker';
@ -21,6 +21,7 @@ export type ColorButtonProps = {
autoExecute?: boolean; autoExecute?: boolean;
engine?: EngineInterface; engine?: EngineInterface;
disabled?: boolean; disabled?: boolean;
placement?: Placement;
} & ColorPickerProps; } & ColorPickerProps;
const ColorButton: React.FC<ColorButtonProps> = ({ const ColorButton: React.FC<ColorButtonProps> = ({
@ -37,6 +38,7 @@ const ColorButton: React.FC<ColorButtonProps> = ({
defaultColor, defaultColor,
onSelect, onSelect,
setStroke, setStroke,
placement,
}) => { }) => {
const [pickerVisible, setPickerVisible] = useState(false); const [pickerVisible, setPickerVisible] = useState(false);
const [buttonContent, setButtonContent] = useState( const [buttonContent, setButtonContent] = useState(
@ -137,6 +139,7 @@ const ColorButton: React.FC<ColorButtonProps> = ({
content={buttonContent} content={buttonContent}
disabled={disabled} disabled={disabled}
onClick={(event) => triggerSelect(currentColor, event)} onClick={(event) => triggerSelect(currentColor, event)}
placement={placement}
/> />
<Button <Button
className="colorpicker-button-dropdown toolbar-dropdown-trigger-arrow" className="colorpicker-button-dropdown toolbar-dropdown-trigger-arrow"
@ -148,6 +151,7 @@ const ColorButton: React.FC<ColorButtonProps> = ({
} }
content={<span className="data-icon data-icon-arrow" />} content={<span className="data-icon data-icon-arrow" />}
onClick={toggleDropdown} onClick={toggleDropdown}
placement={placement}
/> />
</div> </div>
{pickerVisible && ( {pickerVisible && (

View File

@ -1,10 +1,8 @@
.toolbar-dropdown { .toolbar-dropdown {
position: relative; position: relative;
display: inline-flex;
} }
.toolbar-dropdown .toolbar-dropdown-trigger { .toolbar-dropdown .toolbar-dropdown-trigger {
display: inline-flex;
align-items: center; align-items: center;
} }
@ -14,6 +12,7 @@
.toolbar-dropdown .toolbar-dropdown-trigger-arrow .toolbar-button{ .toolbar-dropdown .toolbar-dropdown-trigger-arrow .toolbar-button{
padding-right: 20px; padding-right: 20px;
margin: 0;
} }
.toolbar-dropdown .toolbar-dropdown-trigger-arrow .data-icon-arrow { .toolbar-dropdown .toolbar-dropdown-trigger-arrow .data-icon-arrow {
@ -64,7 +63,7 @@
color: #595959; color: #595959;
text-align: left; text-align: left;
position: relative; position: relative;
display: block; display: flex;
white-space: nowrap; white-space: nowrap;
} }

View File

@ -1,6 +1,6 @@
import React, { useState, useRef } from 'react'; import React, { useState, useRef } from 'react';
import classnames from 'classnames-es-ts'; import classnames from 'classnames-es-ts';
import { EngineInterface } from '@aomao/engine'; import type { EngineInterface, Placement } from '@aomao/engine';
import Button from '../button'; import Button from '../button';
import DropdownList, { DropdownListItem } from './list'; import DropdownList, { DropdownListItem } from './list';
import { useRight } from '../hooks'; import { useRight } from '../hooks';
@ -11,6 +11,7 @@ export type DropdownProps = {
items: Array<DropdownListItem>; items: Array<DropdownListItem>;
values?: string | Array<string>; values?: string | Array<string>;
engine?: EngineInterface; engine?: EngineInterface;
placement?: Placement;
icon?: React.ReactNode; icon?: React.ReactNode;
content?: React.ReactNode | (() => React.ReactNode); content?: React.ReactNode | (() => React.ReactNode);
title?: string; title?: string;
@ -40,6 +41,7 @@ const Dropdown: React.FC<DropdownProps> = ({
hasArrow, hasArrow,
renderContent, renderContent,
hasDot, hasDot,
placement,
}) => { }) => {
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
@ -144,6 +146,7 @@ const Dropdown: React.FC<DropdownProps> = ({
title={title} title={title}
active={visible} active={visible}
disabled={disabled} disabled={disabled}
placement={placement}
/> />
</div> </div>
{visible && ( {visible && (

View File

@ -2,6 +2,8 @@
padding: 4px 8px; padding: 4px 8px;
width: auto; width: auto;
border-left: 1px solid #e8e8e8; border-left: 1px solid #e8e8e8;
display: flex;
align-items: center;
} }
.editor-toolbar .editor-toolbar-group:nth-child(1) { .editor-toolbar .editor-toolbar-group:nth-child(1) {

View File

@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import classNames from 'classnames-es-ts'; import classNames from 'classnames-es-ts';
import { EngineInterface, isMobile } from '@aomao/engine'; import { isMobile } from '@aomao/engine';
import type { Placement, EngineInterface } from '@aomao/engine';
import Popover from 'antd/es/popover'; import Popover from 'antd/es/popover';
import Button, { ButtonProps } from '../button'; import Button, { ButtonProps } from '../button';
import Dropdown, { DropdownProps } from '../dropdown'; import Dropdown, { DropdownProps } from '../dropdown';
@ -42,14 +43,26 @@ const ToolbarGroup: React.FC<GroupProps> = ({
content, content,
popup, popup,
}) => { }) => {
const renderItems = () => { const renderItems = (placement?: Placement) => {
return items.map((item, index) => { return items.map((item, index) => {
switch (item.type) { switch (item.type) {
case 'button': case 'button':
return <Button engine={engine} key={item.name} {...item} />; return (
<Button
engine={engine}
key={item.name}
{...item}
placement={placement}
/>
);
case 'dropdown': case 'dropdown':
return ( return (
<Dropdown engine={engine} key={item.name} {...item} /> <Dropdown
engine={engine}
key={item.name}
{...item}
placement={placement}
/>
); );
case 'color': case 'color':
return ( return (
@ -57,6 +70,7 @@ const ToolbarGroup: React.FC<GroupProps> = ({
engine={engine} engine={engine}
key={item.name} key={item.name}
{...item} {...item}
placement={placement}
/> />
); );
case 'collapse': case 'collapse':
@ -83,7 +97,7 @@ const ToolbarGroup: React.FC<GroupProps> = ({
})} })}
data-element="ui" data-element="ui"
> >
{renderItems()} {renderItems('top')}
</div> </div>
} }
arrowPointAtCenter arrowPointAtCenter

View File

@ -65,6 +65,7 @@
border: 0 none; border: 0 none;
left: 0; left: 0;
top: 0; top: 0;
display: flex;
} }
.editor-toolbar-popover { .editor-toolbar-popover {

View File

@ -48,7 +48,7 @@
} }
.data-toolbar-popup-wrapper .editor-toolbar-popover .ant-popover-inner-content { .data-toolbar-popup-wrapper .editor-toolbar-popover .ant-popover-inner-content {
padding: 4px 0; padding: 4px;
background-color: #fff; background-color: #fff;
border-radius: 4px; border-radius: 4px;
border: 1px solid #dee0e3; border: 1px solid #dee0e3;

View File

@ -1,3 +1,4 @@
import type { FileOptions } from '../types';
import { import {
$, $,
Card, Card,
@ -71,8 +72,6 @@ export default class FileCard<V extends FileValue = FileValue> extends Card<V> {
private container?: NodeInterface; private container?: NodeInterface;
private maxWidth: number = 752;
getLocales() { getLocales() {
return this.editor.language.get<{ [key: string]: string }>('file'); return this.editor.language.get<{ [key: string]: string }>('file');
} }
@ -83,20 +82,20 @@ export default class FileCard<V extends FileValue = FileValue> extends Card<V> {
}; };
onWindowResize = () => { onWindowResize = () => {
this.maxWidth = this.getMaxWidth();
this.updateMaxWidth(); this.updateMaxWidth();
}; };
updateMaxWidth = () => { updateMaxWidth = () => {
const maxWidth = this.getMaxWidth();
this.root this.root
.find('.data-file-title') .find('.data-file-title')
.css('max-width', this.maxWidth - 100 + 'px'); .css('max-width', maxWidth - 100 + 'px');
}; };
onBeforeRender = (action: 'preview' | 'download', url: string) => { onBeforeRender = (action: 'preview' | 'download', url: string) => {
const filePlugin = this.editor.plugin.components['file']; const filePlugin = this.editor.plugin.findPlugin<FileOptions>('file');
if (filePlugin) { if (filePlugin) {
const { onBeforeRender } = (filePlugin['options'] || {}) as any; const { onBeforeRender } = filePlugin.options || {};
if (onBeforeRender) return onBeforeRender(action, url); if (onBeforeRender) return onBeforeRender(action, url);
} }
return url; return url;
@ -259,7 +258,6 @@ export default class FileCard<V extends FileValue = FileValue> extends Card<V> {
this.bindErrorEvent(this.root); this.bindErrorEvent(this.root);
} }
this.container?.find('.percent').html(`${value.percent}%`); this.container?.find('.percent').html(`${value.percent}%`);
this.maxWidth = this.getMaxWidth();
this.updateMaxWidth(); this.updateMaxWidth();
window.addEventListener('resize', this.onWindowResize); window.addEventListener('resize', this.onWindowResize);
} }

View File

@ -19,8 +19,7 @@ import type { FileValue } from './component';
import FileUploader from './uploader'; import FileUploader from './uploader';
import type { FileUploaderOptions } from './uploader'; import type { FileUploaderOptions } from './uploader';
import locales from './locales'; import locales from './locales';
import { FileOptions } from './types';
export interface FileOptions extends PluginOptions {}
export default class<T extends FileOptions = FileOptions> extends Plugin<T> { export default class<T extends FileOptions = FileOptions> extends Plugin<T> {
static get pluginName() { static get pluginName() {

View File

@ -0,0 +1,5 @@
import { PluginOptions } from '@aomao/engine';
export interface FileOptions extends PluginOptions {
onBeforeRender?: (action: 'preview' | 'download', url: string) => string;
}

View File

@ -1,3 +1,4 @@
import type { ImageOptions } from '@/types';
import { import {
Card, Card,
CardToolbarItemOptions, CardToolbarItemOptions,
@ -262,10 +263,10 @@ class ImageComponent<T extends ImageValue = ImageValue> extends Card<T> {
percent: value.percent, percent: value.percent,
message: value.message, message: value.message,
onBeforeRender: (status, src) => { onBeforeRender: (status, src) => {
const imagePlugin = this.editor.plugin.components['image']; const imagePlugin =
this.editor.plugin.findPlugin<ImageOptions>('image');
if (imagePlugin) { if (imagePlugin) {
const { onBeforeRender } = (imagePlugin['options'] || const { onBeforeRender } = imagePlugin.options || {};
{}) as any;
if (onBeforeRender) return onBeforeRender(status, src); if (onBeforeRender) return onBeforeRender(status, src);
} }
return src; return src;

View File

@ -1,6 +1,5 @@
import { import {
$, $,
CardEntry,
CardInterface, CardInterface,
CardType, CardType,
CARD_KEY, CARD_KEY,
@ -10,17 +9,13 @@ import {
NodeInterface, NodeInterface,
Plugin, Plugin,
PluginEntry, PluginEntry,
PluginOptions,
READY_CARD_KEY, READY_CARD_KEY,
} from '@aomao/engine'; } from '@aomao/engine';
import ImageComponent, { ImageValue } from './component'; import ImageComponent, { ImageValue } from './component';
import ImageUploader from './uploader'; import ImageUploader from './uploader';
import { ImageUploaderOptions } from './uploader'; import { ImageUploaderOptions } from './uploader';
import locales from './locales'; import locales from './locales';
import { ImageOptions } from './types';
export interface ImageOptions extends PluginOptions {
onBeforeRender?: (status: 'uploading' | 'done', src: string) => string;
}
export default class<T extends ImageOptions = ImageOptions> extends Plugin<T> { export default class<T extends ImageOptions = ImageOptions> extends Plugin<T> {
static get pluginName() { static get pluginName() {

View File

@ -1,4 +1,4 @@
import { NodeInterface } from '@aomao/engine'; import { NodeInterface, PluginOptions } from '@aomao/engine';
import { EventEmitter2 } from 'eventemitter2'; import { EventEmitter2 } from 'eventemitter2';
export interface PswpInterface extends EventEmitter2 { export interface PswpInterface extends EventEmitter2 {
@ -27,3 +27,7 @@ export interface PswpInterface extends EventEmitter2 {
close(): void; close(): void;
destroy(): void; destroy(): void;
} }
export interface ImageOptions extends PluginOptions {
onBeforeRender?: (status: 'uploading' | 'done', src: string) => string;
}

View File

@ -1,3 +1,4 @@
import { VideoOptions } from '@/types';
import type { import type {
CardToolbarItemOptions, CardToolbarItemOptions,
ToolbarItemOptions, ToolbarItemOptions,
@ -190,9 +191,10 @@ class VideoComponent<T extends VideoValue = VideoValue> extends Card<T> {
} }
onBeforeRender = (action: 'query' | 'download' | 'cover', url: string) => { onBeforeRender = (action: 'query' | 'download' | 'cover', url: string) => {
const videoPlugin = this.editor.plugin.components['video']; const videoPlugin =
this.editor.plugin.findPlugin<VideoOptions>('video');
if (videoPlugin) { if (videoPlugin) {
const { onBeforeRender } = (videoPlugin['options'] || {}) as any; const { onBeforeRender } = videoPlugin.options || {};
if (onBeforeRender) return onBeforeRender(action, url); if (onBeforeRender) return onBeforeRender(action, url);
} }
return url; return url;

View File

@ -20,14 +20,7 @@ import type { VideoValue, VideoStatus } from './component';
import VideoUploader from './uploader'; import VideoUploader from './uploader';
import type { VideoUploaderOptions } from './uploader'; import type { VideoUploaderOptions } from './uploader';
import locales from './locales'; import locales from './locales';
import { VideoOptions } from './types';
export interface VideoOptions extends PluginOptions {
onBeforeRender?: (
action: 'download' | 'query' | 'cover',
url: string,
) => string;
showTitle?: boolean;
}
export default class VideoPlugin< export default class VideoPlugin<
T extends VideoOptions = VideoOptions, T extends VideoOptions = VideoOptions,

View File

@ -0,0 +1,9 @@
import { PluginOptions } from '@aomao/engine';
export interface VideoOptions extends PluginOptions {
onBeforeRender?: (
action: 'download' | 'query' | 'cover',
url: string,
) => string;
showTitle?: boolean;
}