diff --git a/packages/component/component/table/components/TableToolbar.tsx b/packages/component/component/table/components/TableToolbar.tsx new file mode 100644 index 0000000000000000000000000000000000000000..74158661b7661842e97ef2af5caaba0cc851d939 --- /dev/null +++ b/packages/component/component/table/components/TableToolbar.tsx @@ -0,0 +1,163 @@ +import type { PropType } from "vue"; +import type { LayTableContextType } from "../constant"; +import type { TableColumn, TableDefaultToolbar } from "../typing"; +import type { TableToolBarType } from "./types"; + +import LayRender from "@layui/component/component/_components/render"; +import LayCheckboxV2 from "@layui/component/component/checkboxV2/index.vue"; +import LayDropdown from "@layui/component/component/dropdown/index.vue"; +import LayIcon from "@layui/component/component/icon"; +import { isValueArray } from "@layui/component/utils"; +import { defineComponent, h, inject } from "vue"; +import { LAY_TABLE_CONTEXT } from "../constant"; +import { useToolBar } from "../hooks/useToolbar"; + +const clsPrefix = (cls: string) => `layui-${cls}`; + +function handleCheckChange(column: TableColumn) { + column.hide = !column.hide; +} + +const ToolbarItem = defineComponent({ + name: "ToolbarItem", + + props: { + resetParams: { + required: true, + type: Object as PropType< + Omit, "showToolbars"> & { + hierarchicalColumns: TableToolBarType["hierarchicalColumns"]; + } + >, + }, + + toolbar: { + required: true, + type: [String, Object] as PropType, + }, + }, + + setup(props) { + return () => { + const { toolbar, resetParams: { t, exportData, toolbarStyle, hierarchicalColumns } } = props; + + // filter + if (toolbar === "filter") { + return h(LayDropdown, { placement: "bottom-end" }, { + default: () => h( + "div", + { + "lay-event": true, + "class": clsPrefix("inline"), + "title": t("table.filter"), + "style": toolbarStyle(toolbar), + }, + h(LayIcon, { type: clsPrefix("icon-slider") }), + ), + + content: () => h( + "div", + { class: clsPrefix("table-tool-checkbox") }, + hierarchicalColumns[0].map((column, columnIndex) => h(LayCheckboxV2, { + skin: "primary", + key: column.key || column.type || columnIndex, + value: columnIndex, + modelValue: !column.hide, + disabled: isValueArray(column.children), + + onChange: () => handleCheckChange(column), + }, () => column.title)), + ), + }); + } + + // export + if (toolbar === "export") { + return h("div", { + "lay-event": true, + "title": t("table.export"), + "style": toolbarStyle(toolbar), + "class": clsPrefix("inline"), + + "onClick": exportData, + }, h(LayIcon, { type: clsPrefix("icon-export") })); + } + + // print + if (toolbar === "print") { + return h("div", { + "lay-event": true, + "title": t("table.print"), + "class": clsPrefix("inline"), + "style": toolbarStyle(toolbar), + + "onClick": print, + }, h(LayIcon, { type: clsPrefix("icon-print") })); + } + + // render + if (toolbar?.render) { + return toolbar.render(h, toolbar); + } + + return h("div", { + "lay-event": true, + "title": toolbar.title, + "style": toolbarStyle(toolbar), + "class": clsPrefix("inline"), + + "onClick": toolbar.onClick, + }, h(LayIcon, { type: toolbar.icon })); + }; + }, +}); + +const TableToolbar = defineComponent({ + name: "TableToolbar", + + props: { + defaultToolbar: { + required: true, + type: Array as PropType, + }, + + hierarchicalColumns: { + required: true, + type: Array as PropType, + }, + }, + + setup(props) { + const { tableSlots } = inject(LAY_TABLE_CONTEXT) as LayTableContextType; + const { showToolbars, ...resetToolBar } = useToolBar(props); + + return () => { + if (!isValueArray(showToolbars.value) && !tableSlots.toolbar) { + return null; + } + + return h("div", { class: clsPrefix("table-tool") }, [ + h("div", { class: clsPrefix("table-tool-temp") }, [ + h(LayRender, { slots: tableSlots, render: "toolbar" }), + ]), + + isValueArray(showToolbars.value) && h( + "div", + { class: "table-tool-self" }, + showToolbars.value.map((toolbar, index) => { + return h(ToolbarItem, { + toolbar, + key: index, + resetParams: { + ...resetToolBar, + hierarchicalColumns: props.hierarchicalColumns, + }, + }); + }), + ), + ]); + }; + }, +}); + +export default TableToolbar; diff --git a/packages/component/component/table/constant.ts b/packages/component/component/table/constant.ts index 0cf5c6dabfa128c1c0ef669251a5826814c2859b..1feb894dcda66f5747d7ae95964175bf709d5190 100644 --- a/packages/component/component/table/constant.ts +++ b/packages/component/component/table/constant.ts @@ -8,7 +8,7 @@ import type { RequiredTableProps, TableEmit, TableProps } from "./typing"; export const columnsTypeList = ["radio", "checkbox", "number"]; -interface LayTableContextType { +export interface LayTableContextType { tableEmits: TableEmit; tableProps: RequiredTableProps; tableSlots: Slots; diff --git a/packages/component/component/table/index.vue b/packages/component/component/table/index.vue index b0697e32b9052010cce224a2a36839cb787095e1..117e1377107043f8ded5dc4f847b1db921fff573 100644 --- a/packages/component/component/table/index.vue +++ b/packages/component/component/table/index.vue @@ -19,7 +19,7 @@ import LayEmpty from "../empty/index.vue"; import TableHeader from "./components/TableHeader.vue"; import TableMain from "./components/TableMain"; import TablePage from "./components/TablePage.vue"; -import TableToolbar from "./components/TableToolbar.vue"; +import TableToolbar from "./components/TableToolbar.tsx"; import TableTotal from "./components/TableTotal.vue"; import { LAY_TABLE_CONTEXT } from "./constant"; diff --git a/packages/component/component/table/typing.ts b/packages/component/component/table/typing.ts index 888b95560f03a03ee6c8b3449cf9f489235fe27b..a1e2d2621f670cd010b0fa768ef709edb107086a 100644 --- a/packages/component/component/table/typing.ts +++ b/packages/component/component/table/typing.ts @@ -2,6 +2,7 @@ import type { RenderProps } from "@layui/component/component/_components/render" import type { PageProps } from "@layui/component/component/page/interface"; // import type { TooltipProps } from "@layui/component/component/tooltip/types"; import type { CommonAlign, Recordable } from "@layui/component/types"; +import type { h, VNode } from "vue"; export interface TableProps { id?: string; @@ -121,4 +122,5 @@ export interface TableDefaultToolbarComplex { title: string; icon: string; onClick?: () => void; + render?: (_h: typeof h, params: Record) => VNode; } diff --git a/play/main.ts b/play/main.ts index c1868e7847b1b03924fe22d83541937656f83ea3..a5789235d89ceb7ec91c54420e342b0bc975e6c3 100644 --- a/play/main.ts +++ b/play/main.ts @@ -1,12 +1,11 @@ import { createApp } from "vue"; import layui from "../packages/component/index"; -import layer from "../packages/layer/src/index"; // import LayJsonSchemaForm from "../packages/json-schema-form/src/index"; // import LayJsonSchemaForm from "../packages/json-schema-form/lib/json-schema-form.es.js"; // import "../packages/component/lib/index.css"; (async () => { - const apps = import.meta.glob("./src/*.vue"); + const apps = import.meta.glob(["./src/*.vue", "./src/*.tsx"]); const name = location.pathname.replace(/^\//, "") || "App"; const file = apps[`./src/${name}.vue`]; if (!file) {