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 = (
+
+ );
+ }
+ return (
+
+ );
+ },
+});