diff --git a/src/control/caption-bar/caption-bar.scss b/src/control/caption-bar/caption-bar.scss index 5aa2aeadc47552076d9fe1591111a98f98f73740..973c0ad486a64de0dcd93ce7abd63e7bcbcb9ea2 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 38aad47ca83f4efa035d18e8d40ac0681687999e..6693db63c50184e8db6f2f584f85ad64b04b71f9 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 4858d4a6522db8519210052c4633181b1c675340..877fce301462edd8fafbc329e741cfceca88c7f0 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 e51b2ff4604ee5e34bc5e95dd83afca4bba3344c..7096ba16a5bbd469de2c03ad62795bfc6ccafbc7 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 10c4adf74bf37c7ff8d3bd0cc289c2f9497865c1..60d237657010c44ae4b1d22d40183fbe7b78a2ab 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 ddb14eac5cb99c8c1c09262c8144d51b8a175759..edec0c5f768269e434aee3d7eedd4c33bff010e3 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 e4c2619354e5b3deafcfb1eae57b3fb571445e72..c92632d8cda53ec6c33406653e478b192c8b4338 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 0000000000000000000000000000000000000000..136cf4300f46fa1cc299048d6669c78114d2c0e5 --- /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 0000000000000000000000000000000000000000..686cf7ff6ad96d5bb596cd00ba955480f6d603c2 --- /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 0000000000000000000000000000000000000000..9bd8ffbc8ee7397528b110f9e7d61c86b06c905c --- /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 0000000000000000000000000000000000000000..18dd5b7c05b9be304df316e7252c1b06f39f7d11 --- /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 0000000000000000000000000000000000000000..76502920bd55aaa6560c1bc877ea9da58638004e --- /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 0000000000000000000000000000000000000000..b497b92482ce116f788f494626625c6aff24b14c --- /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}
+
+ ); + }, +});