From 8d91d15fb9485596a09ac2a0ab5cff7c918c00f0 Mon Sep 17 00:00:00 2001 From: zhujiamin <1147570162@qq.com> Date: Mon, 17 Jul 2023 14:45:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A7=86=E5=9B=BE=E5=A4=B4=E9=83=A8?= =?UTF-8?q?=E4=BB=A5=E5=8F=8A=E5=86=85=E9=83=A8=E9=83=A8=E4=BB=B6=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/control/caption-bar/caption-bar.scss | 20 +++++ .../form-item-container.scss | 25 ++++-- src/control/search-bar/search-bar.scss | 9 ++ src/control/search-bar/search-bar.tsx | 11 ++- src/control/toolbar/toolbar.scss | 15 ++++ src/panel-component/index.ts | 2 + src/panel-component/nav-tabs/nav-tabs.scss | 10 +-- .../panel-view-header/index.ts | 26 ++++++ .../panel-view-header.controller.ts | 18 ++++ .../panel-view-header.provider.ts | 27 ++++++ .../panel-view-header/panel-view-header.scss | 11 +++ .../panel-view-header.state.ts | 12 +++ .../panel-view-header/panel-view-header.tsx | 89 +++++++++++++++++++ 13 files changed, 263 insertions(+), 12 deletions(-) create mode 100644 src/panel-component/panel-view-header/index.ts create mode 100644 src/panel-component/panel-view-header/panel-view-header.controller.ts create mode 100644 src/panel-component/panel-view-header/panel-view-header.provider.ts create mode 100644 src/panel-component/panel-view-header/panel-view-header.scss create mode 100644 src/panel-component/panel-view-header/panel-view-header.state.ts create mode 100644 src/panel-component/panel-view-header/panel-view-header.tsx diff --git a/src/control/caption-bar/caption-bar.scss b/src/control/caption-bar/caption-bar.scss index 5aa2aead..973c0ad4 100644 --- a/src/control/caption-bar/caption-bar.scss +++ b/src/control/caption-bar/caption-bar.scss @@ -1,5 +1,25 @@ @include b(control-captionbar) { + position: relative; + height: 100%; @include b(control-captionbar-caption) { @include utils-ellipsis; + + position: relative; + padding-left: 16px; + font-size: 20px; + font-weight: bold; + color: #3f4254; + + &::before { + position: absolute; + top: 50%; + left: 0; + width: 4px; + height: 20px; + content: ''; + background: #557da5; + border-radius: 2px; + transform: translateY(-50%); + } } } diff --git a/src/control/form/form-detail/form-item/form-item-container/form-item-container.scss b/src/control/form/form-detail/form-item/form-item-container/form-item-container.scss index 38aad47c..6693db63 100644 --- a/src/control/form/form-detail/form-item/form-item-container/form-item-container.scss +++ b/src/control/form/form-detail/form-item/form-item-container/form-item-container.scss @@ -1,3 +1,4 @@ +/* stylelint-disable scss/operator-no-newline-after */ $form-item-container: ( 'label-width': 130px, 'line-height': 32px, @@ -17,15 +18,15 @@ $form-item-container: ( padding-top: calc( ( - getCssVar('form-item-container', 'line-height') - - getCssVar('form-item', 'font-size') - ) / 2 + getCssVar('form-item-container', 'line-height') - + getCssVar('form-item', 'font-size') + ) / 2 ); padding-bottom: calc( ( - getCssVar('form-item-container', 'line-height') - - getCssVar('form-item', 'font-size') - ) / 2 + getCssVar('form-item-container', 'line-height') - + getCssVar('form-item', 'font-size') + ) / 2 ); line-height: getCssVar('form-item', 'font-size'); } @@ -73,6 +74,18 @@ $form-item-container: ( } } } + + @include e(editor) { + position: relative; + flex-grow: 1; + height: 100%; + } +} + +@include b(form-item-container-content) { + @include flex; + + height: 100%; } .#{bem('form-item-container', '', 'left')}, diff --git a/src/control/search-bar/search-bar.scss b/src/control/search-bar/search-bar.scss index 4858d4a6..877fce30 100644 --- a/src/control/search-bar/search-bar.scss +++ b/src/control/search-bar/search-bar.scss @@ -9,5 +9,14 @@ $control-searchbar: ( @include set-component-css-var('control-searchbar', $control-searchbar); @include b(control-searchbar-quick-search) { width: getCssVar('control-searchbar', 'quick-search-width'); + font-size: 14px; + color: #bcbcbc; + background: #fff; + border: 1px solid #dcdee2; + border-radius: 4px; + + .el-input__wrapper { + padding: 0 20px; + } } } diff --git a/src/control/search-bar/search-bar.tsx b/src/control/search-bar/search-bar.tsx index e51b2ff4..7096ba16 100644 --- a/src/control/search-bar/search-bar.tsx +++ b/src/control/search-bar/search-bar.tsx @@ -58,8 +58,17 @@ export const SearchBarControl = defineComponent({ + > + {{ + prefix: () => { + return ( + + ); + }, + }} + )} ); diff --git a/src/control/toolbar/toolbar.scss b/src/control/toolbar/toolbar.scss index 10c4adf7..60d23765 100644 --- a/src/control/toolbar/toolbar.scss +++ b/src/control/toolbar/toolbar.scss @@ -1,6 +1,9 @@ /* control-toolbar 工具栏部件 start */ $control-toolbar: ( 'item-margin': 0 4px, + 'item-padding': 7px 16px, + 'item-hover-color': #fff, + 'item-hover-bg-color': #557da5, 'icon-margin': 0 5px 0 0, 'icon-max-width': 16px, 'icon-max-height': 16px, @@ -26,9 +29,14 @@ $control-toolbar-embed: ( .el-button { @include flex(row, center, center); + padding: getCssVar('control-toolbar', 'item-padding'); + border: 1px solid #d9d9d9; + border-radius: 4px; + > span { @include flex(row, center, center); + font-size: 14px; pointer-events: none; // 禁用点击事件,保证event.target是button元素 } @@ -39,6 +47,13 @@ $control-toolbar-embed: ( max-height: getCssVar('control-toolbar', 'icon-max-height'); margin: getCssVar('control-toolbar', 'icon-margin'); } + + &:hover { + &:not(.is-disabled) { + color: getCssVar('control-toolbar', 'item-hover-color'); + background: getCssVar('control-toolbar', 'item-hover-bg-color'); + } + } } } diff --git a/src/panel-component/index.ts b/src/panel-component/index.ts index ddb14eac..edec0c5f 100644 --- a/src/panel-component/index.ts +++ b/src/panel-component/index.ts @@ -11,6 +11,7 @@ import IBizPanelAppTitle from './panel-app-title'; import IBizSingleDataContainer from './single-data-container'; import IBizPanelField from './panel-field'; import IBizPanelAppHeader from './panel-app-header'; +import IBizPanelViewHeader from './panel-view-header'; export * from './panel-container'; export * from './panel-ctrl-pos'; @@ -37,6 +38,7 @@ export const IBizPanelComponents = { v.use(IBizSingleDataContainer); v.use(IBizPanelField); v.use(IBizPanelAppHeader); + v.use(IBizPanelViewHeader); }, }; diff --git a/src/panel-component/nav-tabs/nav-tabs.scss b/src/panel-component/nav-tabs/nav-tabs.scss index e4c26193..c92632d8 100644 --- a/src/panel-component/nav-tabs/nav-tabs.scss +++ b/src/panel-component/nav-tabs/nav-tabs.scss @@ -1,12 +1,12 @@ $nav-tabs: ( - 'padding': 0 16px, + 'padding': 12px 20px, 'left-width': 100%, 'right-width': 60px, ); $nav-tabs-item: ( 'height': 40px, - 'padding': 9px 28px, + 'padding': 0 20px, 'margin': 0 16px 0 0, 'item-font-size': 14px, 'border-radius': 8px, @@ -90,14 +90,14 @@ $nav-tabs-item: ( } &:nth-child(2):not(.is-active).is-closable:hover { - padding-left: 28px; + padding-left: 20px; } &:last-child { - padding-right: 28px; + padding-right: 20px; &:not(.is-active).is-closable:hover { - padding-right: 28px; + padding-right: 20px; } } diff --git a/src/panel-component/panel-view-header/index.ts b/src/panel-component/panel-view-header/index.ts new file mode 100644 index 00000000..136cf430 --- /dev/null +++ b/src/panel-component/panel-view-header/index.ts @@ -0,0 +1,26 @@ +import { App } from 'vue'; +import { withInstall } from '@ibiz-template/vue3-util'; +import { registerPanelItemProvider } from '@ibiz-template/runtime'; +import { PanelViewHeader } from './panel-view-header'; +import { PanelViewHeaderProvider } from './panel-view-header.provider'; +import { PanelViewHeaderController } from './panel-view-header.controller'; +import { PanelViewHeaderState } from './panel-view-header.state'; + +export { + PanelViewHeaderProvider, + PanelViewHeaderState, + PanelViewHeaderController, +}; + +export const IBizPanelViewHeader = withInstall( + PanelViewHeader, + function (v: App) { + v.component(PanelViewHeader.name, PanelViewHeader); + registerPanelItemProvider( + 'CONTAINER_ViewHeader', + () => new PanelViewHeaderProvider(), + ); + }, +); + +export default IBizPanelViewHeader; diff --git a/src/panel-component/panel-view-header/panel-view-header.controller.ts b/src/panel-component/panel-view-header/panel-view-header.controller.ts new file mode 100644 index 00000000..686cf7ff --- /dev/null +++ b/src/panel-component/panel-view-header/panel-view-header.controller.ts @@ -0,0 +1,18 @@ +import { IPanelContainer } from '@ibiz/model-core'; +import { PanelItemController } from '../../control'; +import { PanelViewHeaderState } from './panel-view-header.state'; + +/** + * 面板视图头部控制器 + * + * @export + * @class PanelViewHeaderController + * @extends {PanelItemController} + */ +export class PanelViewHeaderController extends PanelItemController { + declare state: PanelViewHeaderState; + + protected createState(): PanelViewHeaderState { + return new PanelViewHeaderState(this.parent?.state); + } +} diff --git a/src/panel-component/panel-view-header/panel-view-header.provider.ts b/src/panel-component/panel-view-header/panel-view-header.provider.ts new file mode 100644 index 00000000..9bd8ffbc --- /dev/null +++ b/src/panel-component/panel-view-header/panel-view-header.provider.ts @@ -0,0 +1,27 @@ +import { IPanelItemProvider } from '@ibiz-template/runtime'; +import { IPanelContainer } from '@ibiz/model-core'; +import { PanelController, PanelItemController } from '../../control'; +import { PanelViewHeaderController } from './panel-view-header.controller'; + +/** + * 面板容器适配器 + * + * @author lxm + * @date 2022-09-19 22:09:03 + * @export + * @class PanelViewHeaderProvider + * @implements {EditorProvider} + */ +export class PanelViewHeaderProvider implements IPanelItemProvider { + component: string = 'IBizPanelViewHeader'; + + async createController( + panelItem: IPanelContainer, + panel: PanelController, + parent: PanelItemController | undefined, + ): Promise { + const c = new PanelViewHeaderController(panelItem, panel, parent); + await c.init(); + return c; + } +} diff --git a/src/panel-component/panel-view-header/panel-view-header.scss b/src/panel-component/panel-view-header/panel-view-header.scss new file mode 100644 index 00000000..18dd5b7c --- /dev/null +++ b/src/panel-component/panel-view-header/panel-view-header.scss @@ -0,0 +1,11 @@ +@include b(panel-view-header) { + height: 100%; + padding: 12px 0; + margin: 0 20px; + border-bottom: 1px solid #f6f6f6; + + @include b(panel-view-header-content) { + width: 100%; + height: 100%; + } +} diff --git a/src/panel-component/panel-view-header/panel-view-header.state.ts b/src/panel-component/panel-view-header/panel-view-header.state.ts new file mode 100644 index 00000000..76502920 --- /dev/null +++ b/src/panel-component/panel-view-header/panel-view-header.state.ts @@ -0,0 +1,12 @@ +import { PanelItemState } from '../../control/panel/panel/panel-item.state'; + +/** + * 面板容器状态 + * + * @author lxm + * @date 2023-02-07 06:04:27 + * @export + * @class PanelViewHeaderState + * @extends {PanelItemState} + */ +export class PanelViewHeaderState extends PanelItemState {} diff --git a/src/panel-component/panel-view-header/panel-view-header.tsx b/src/panel-component/panel-view-header/panel-view-header.tsx new file mode 100644 index 00000000..b497b924 --- /dev/null +++ b/src/panel-component/panel-view-header/panel-view-header.tsx @@ -0,0 +1,89 @@ +import { useNamespace } from '@ibiz-template/vue3-util'; +import { IPanelContainer } from '@ibiz/model-core'; +import { computed, defineComponent, PropType, ref, VNode } from 'vue'; +import { PanelViewHeaderController } from './panel-view-header.controller'; +import './panel-view-header.scss'; + +export const PanelViewHeader = defineComponent({ + name: 'IBizPanelViewHeader', + props: { + modelData: { + type: Object as PropType, + required: true, + }, + controller: { + type: PanelViewHeaderController, + required: true, + }, + }, + setup(props) { + const ns = useNamespace('panel-view-header'); + const { showCaption, titleBarCloseMode, id } = props.modelData; + const collapsible = titleBarCloseMode !== 0; + const isCollapse = ref(titleBarCloseMode === 2); + const changeCollapse = () => { + if (collapsible) { + isCollapse.value = !isCollapse.value; + } + }; + + // 类名控制 + const classArr = computed(() => { + let result: Array = [ns.b(), ns.m(id)]; + if (showCaption === true) { + result = [ + ...result, + showCaption && ns.m('show-header'), + collapsible && ns.m('collapsible'), + ns.is('collapse', collapsible && isCollapse.value), + ns.is('hidden', !props.controller.state.visible), + ]; + } + return result; + }); + + return { ns, isCollapse, classArr, changeCollapse }; + }, + render() { + // 内容区默认插槽处理,封装app-col + const defaultSlots: VNode[] = this.$slots.default?.() || []; + const content = ( + + {defaultSlots.map(slot => { + const props = slot.props as IData; + if (!props || !props.controller) { + return slot; + } + + return ( + + {slot} + + ); + })} + + ); + + // 头部绘制 + let header: unknown = null; + if (this.modelData.showCaption) { + header = ( +
+
+
{this.modelData.caption}
+
+
+
+ ); + } + return ( +
+ {header} +
{content}
+
+ ); + }, +}); -- Gitee