From e62ab4f2c5b40725c409fdcedad2f03520900823 Mon Sep 17 00:00:00 2001 From: devin Date: Tue, 31 Jan 2023 20:23:22 +0800 Subject: [PATCH 01/16] init table --- packages/docs/table.md | 48 ++++++++ .../src/components/table/OTable.vue | 113 ++++++++++++++++++ .../components/table/__demo__/IndexTable.vue | 15 +++ .../components/table/__demo__/TableBasic.vue | 84 +++++++++++++ .../table/__demo__/TableDiyHead.vue | 86 +++++++++++++ .../components/table/__demo__/TableSpan.vue | 97 +++++++++++++++ .../opendesign/src/components/table/index.ts | 10 ++ .../src/components/table/style/index.scss | 96 +++++++++++++++ .../src/components/table/style/index.ts | 1 + .../src/components/table/style/var.scss | 17 +++ .../opendesign/src/components/table/table.ts | 89 ++++++++++++++ .../opendesign/src/components/table/types.ts | 18 +++ packages/portal/src/components/TheHeader.vue | 1 - packages/portal/src/router.ts | 6 + packages/portal/src/style.scss | 2 +- 15 files changed, 681 insertions(+), 2 deletions(-) create mode 100644 packages/docs/table.md create mode 100644 packages/opendesign/src/components/table/OTable.vue create mode 100644 packages/opendesign/src/components/table/__demo__/IndexTable.vue create mode 100644 packages/opendesign/src/components/table/__demo__/TableBasic.vue create mode 100644 packages/opendesign/src/components/table/__demo__/TableDiyHead.vue create mode 100644 packages/opendesign/src/components/table/__demo__/TableSpan.vue create mode 100644 packages/opendesign/src/components/table/index.ts create mode 100644 packages/opendesign/src/components/table/style/index.scss create mode 100644 packages/opendesign/src/components/table/style/index.ts create mode 100644 packages/opendesign/src/components/table/style/var.scss create mode 100644 packages/opendesign/src/components/table/table.ts create mode 100644 packages/opendesign/src/components/table/types.ts diff --git a/packages/docs/table.md b/packages/docs/table.md new file mode 100644 index 00000000..3706aa49 --- /dev/null +++ b/packages/docs/table.md @@ -0,0 +1,48 @@ +# Table 表格 + +## props + +### OTabs + +| name | type | 默认值 | 说明 | +| :--------- | :-------------------------- | :----- | ------------------------------------ | +| modelValue | string \| number(v-model) | '' | 可选,开关状态 | +| lazy | boolean | false | 可选,是否在首次激活标签时再挂载内容 | +| addable | boolean | false | 可选,是否可以添加页签 | + +### OTabPane + +| name | type | 默认值 | 说明 | +| :------------ | :--------------- | :-------------- | ------------------------------------ | +| value | string \| number | instance.uid | 可选,tab id | +| label | string | undefined | 可选,页签文本 | +| transition | string | o-fade-up-enter | 可选,页签切换时过渡动画 | +| lazy | boolean | false | 可选,是否在首次激活标签时再挂载内容 | +| unmountOnHide | boolean | false | 可选,是否在未激活时卸载页签内容 | +| disabled | boolean | false | 可选,是否禁用选中 | +| closable | boolean | false | 可选,是否可以删除 | + +## event + +### OTabs + +| name | 参数 | 说明 | +| :----- | :---------------------------------------------------- | :------------- | +| change | (value: string \| number, oldValue: string \| number) | 页签切换后触发 | +| delete | (value: string \| number ) | 页签删除后触发 | + +## expose + +## slot + +### OTabs + +| name | 说明 | +| :--- | :------------------- | +| act | 页签右侧额外内容插槽 | + +### OTabPane + +| name | 说明 | +| :--- | :------- | +| nav | 页签插槽 | diff --git a/packages/opendesign/src/components/table/OTable.vue b/packages/opendesign/src/components/table/OTable.vue new file mode 100644 index 00000000..811a4ee8 --- /dev/null +++ b/packages/opendesign/src/components/table/OTable.vue @@ -0,0 +1,113 @@ + + diff --git a/packages/opendesign/src/components/table/__demo__/IndexTable.vue b/packages/opendesign/src/components/table/__demo__/IndexTable.vue new file mode 100644 index 00000000..ae99bd6a --- /dev/null +++ b/packages/opendesign/src/components/table/__demo__/IndexTable.vue @@ -0,0 +1,15 @@ + + + diff --git a/packages/opendesign/src/components/table/__demo__/TableBasic.vue b/packages/opendesign/src/components/table/__demo__/TableBasic.vue new file mode 100644 index 00000000..8ed2de5f --- /dev/null +++ b/packages/opendesign/src/components/table/__demo__/TableBasic.vue @@ -0,0 +1,84 @@ + + + diff --git a/packages/opendesign/src/components/table/__demo__/TableDiyHead.vue b/packages/opendesign/src/components/table/__demo__/TableDiyHead.vue new file mode 100644 index 00000000..44ee002b --- /dev/null +++ b/packages/opendesign/src/components/table/__demo__/TableDiyHead.vue @@ -0,0 +1,86 @@ + + + diff --git a/packages/opendesign/src/components/table/__demo__/TableSpan.vue b/packages/opendesign/src/components/table/__demo__/TableSpan.vue new file mode 100644 index 00000000..3e3a5750 --- /dev/null +++ b/packages/opendesign/src/components/table/__demo__/TableSpan.vue @@ -0,0 +1,97 @@ + + + diff --git a/packages/opendesign/src/components/table/index.ts b/packages/opendesign/src/components/table/index.ts new file mode 100644 index 00000000..ed9356c9 --- /dev/null +++ b/packages/opendesign/src/components/table/index.ts @@ -0,0 +1,10 @@ +import _OTable from './OTable.vue'; +import type { App } from 'vue'; + +const OTable = Object.assign(_OTable, { + install(app: App) { + app.component(_OTable.name, _OTable); + }, +}); + +export { OTable }; diff --git a/packages/opendesign/src/components/table/style/index.scss b/packages/opendesign/src/components/table/style/index.scss new file mode 100644 index 00000000..e4ac7544 --- /dev/null +++ b/packages/opendesign/src/components/table/style/index.scss @@ -0,0 +1,96 @@ +@import './var.scss'; + +.o-table { + table { + width: 100%; + border-collapse: collapse; + border-spacing: 0; + } + th { + text-align: left; + font-weight: normal; + } + + th, + td { + padding: 13px 16px; + font-size: var(--table-text-size); + line-height: var(--table-text-height); + } + + th { + background-color: var(--table-head-bg); + } + + tbody tr:hover { + background-color: var(--table-row-hover); + } + + &.is-small { + th, + td { + padding: 7px 8px; + font-size: var(--table-text-size_small); + line-height: var(--table-text-height_small); + } + &.is-border { + th, + td { + padding-bottom: 4px; + } + } + } +} + +// border +.o-table-border-all, +.o-table-border-frame { + border: var(--table-border); + tr:last-child { + td { + border-bottom: none; + } + } +} +.o-table-border-all, +.o-table-border-row { + th, + td { + border-bottom: var(--table-border); + padding: 13px 16px 12px; + + &.is-small { + & { + padding: 7px 8px 6px; + } + } + } +} + +.o-table-border-all, +.o-table-border-column { + th, + td { + border-right: var(--table-border); + + &.last { + border-right: none; + } + } +} + +// tip +.o-table-tip-wrap { + display: flex; + justify-content: center; + align-items: center; + padding: 32px; + border-bottom: var(--table-border); + font-size: var(--table-tip-text-size); + line-height: var(--table-tip-text-height); + color: var(--table-tip-color); +} + +.o-table-loading-label { + margin-left: 8px; +} diff --git a/packages/opendesign/src/components/table/style/index.ts b/packages/opendesign/src/components/table/style/index.ts new file mode 100644 index 00000000..67aac616 --- /dev/null +++ b/packages/opendesign/src/components/table/style/index.ts @@ -0,0 +1 @@ +import './index.scss'; diff --git a/packages/opendesign/src/components/table/style/var.scss b/packages/opendesign/src/components/table/style/var.scss new file mode 100644 index 00000000..9e3afe92 --- /dev/null +++ b/packages/opendesign/src/components/table/style/var.scss @@ -0,0 +1,17 @@ +.o-table { + --table-head-bg: var(--o-color-bg3); + --table-row-hover: var(--o-color-bg3); + --table-text-size: var(--o-font_size-text); + --table-text-height: var(--o-line_height-text); + + --table-text-size_small: var(--o-font_size-tip1); + --table-text-height_small: var(--o-line_height-tip1); + + --table-tip-text-size: var(--o-font_size-tip1); + --table-tip-text-height: var(--o-line_height-tip1); + + --table-tip-color: var(--o-color-text3); + + --table-border: 1px solid var(--o-color-border2); + // --table-border: 1px solid var(--o-color-border1); +} diff --git a/packages/opendesign/src/components/table/table.ts b/packages/opendesign/src/components/table/table.ts new file mode 100644 index 00000000..ceeaba0a --- /dev/null +++ b/packages/opendesign/src/components/table/table.ts @@ -0,0 +1,89 @@ +import { Ref } from 'vue'; +import { isFunction, isString } from '../_shared/utils'; +import { TableColumnT, TableRowT, CellSpanT } from './types'; + +export function getColumnData(columns?: string[] | TableColumnT[]): TableColumnT[] { + if (!Array.isArray(columns)) { + return []; + } + + return columns.map(item => { + if (isString(item)) { + return { + key: item + }; + } + + return item; + }); +} +function getSkipCell(rowIndex: number, columnIndex: number, span: { rowspan?: number; colspan?: number }) { + const skip: Record = {}; + const { colspan = 1, rowspan = 1 } = span; + for (let i = 0; i < rowspan; i++) { + for (let j = 0; j < colspan; j++) { + if (i !== 0 || j !== 0) { + skip[`${rowIndex + i}-${columnIndex + j}`] = true; + } + } + } + return skip; +} +interface CellT { + value: any, + key: string | number, + colspan?: number, + rowspan?: number, + last?: boolean +} + +export function getBodyData(columnData: Ref, bodyData?: TableRowT[], cellSpan?: CellSpanT) { + if (!bodyData) { + return []; + } + + const rowLength = bodyData.length; + const colLenght = columnData.value.length; + + const rlt = []; + let span = null; + const skipCell: Record = {}; + + for (let r = 0; r < rowLength; r += 1) { + const row = bodyData[r]; + let cols = []; + for (let c = 0; c < colLenght; c += 1) { + const col = columnData.value[c]; + if (isFunction(cellSpan)) { + span = cellSpan(r, c); + } + const cell: CellT = { + value: row[col.key], + key: col.key + }; + + if (span) { + const { colspan = 1, rowspan = 1 } = span; + Object.assign(skipCell, getSkipCell(r, c, span)); + + if (colspan > 1) { + cell.colspan = colspan; + } + if (rowspan > 1) { + cell.rowspan = rowspan; + } + } + + + if (!skipCell[`${r}-${c}`]) { + if (c === colLenght - 1) { + cell.last = true; + } + cols.push(cell); + } + } + rlt.push({ key: row.key, data: cols }); + } + + return rlt; +} \ No newline at end of file diff --git a/packages/opendesign/src/components/table/types.ts b/packages/opendesign/src/components/table/types.ts new file mode 100644 index 00000000..5a98997d --- /dev/null +++ b/packages/opendesign/src/components/table/types.ts @@ -0,0 +1,18 @@ +import { StyleValue } from 'vue'; + +export interface TableColumnT { + key: string, + label?: string, + style?: StyleValue +} + +export interface TableRowT { + key?: string | number; + [key: string]: any; +} + +export type ColumnKeysT = Array; + +export type CellSpanT = (rowIndex: number, columnIndex: number) => { rowspan?: number; colspan?: number } | undefined; + +export type TableBorderT = 'all' | 'row' | 'column' | 'frame' | 'row-column' | 'row-frame' | 'column-frame' | 'none'; \ No newline at end of file diff --git a/packages/portal/src/components/TheHeader.vue b/packages/portal/src/components/TheHeader.vue index 4aedd9c2..15178d66 100644 --- a/packages/portal/src/components/TheHeader.vue +++ b/packages/portal/src/components/TheHeader.vue @@ -25,7 +25,6 @@ const globalSetting = () => { justify-content: center; background-color: #f6f6f6; box-shadow: 0px 2px 8px rgba($color: #000000, $alpha: 0.1); - position: relative; } .tools { position: absolute; diff --git a/packages/portal/src/router.ts b/packages/portal/src/router.ts index d7fea009..f7db10d5 100644 --- a/packages/portal/src/router.ts +++ b/packages/portal/src/router.ts @@ -75,6 +75,12 @@ export const routes = [ label: '标签页', component: () => import('@demo/tabs/__demo__/IndexTabs.vue'), }, + { + path: '/table', + name: 'Table', + label: '表格', + component: () => import('@demo/table/__demo__/IndexTable.vue'), + }, ]; export const router = createRouter({ diff --git a/packages/portal/src/style.scss b/packages/portal/src/style.scss index a712c786..3b5b7159 100644 --- a/packages/portal/src/style.scss +++ b/packages/portal/src/style.scss @@ -32,7 +32,7 @@ body { } */ .page-demo { - padding: 24px 24px; + padding: 8px 24px; } section { border: 1px solid #eee; -- Gitee From 7d895459ab66f64d4297e9af046ea1a2c0edb9c6 Mon Sep 17 00:00:00 2001 From: devin Date: Tue, 31 Jan 2023 21:53:01 +0800 Subject: [PATCH 02/16] up table --- packages/opendesign/src/components/table/OTable.vue | 4 ++-- packages/opendesign/src/components/table/index.ts | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/opendesign/src/components/table/OTable.vue b/packages/opendesign/src/components/table/OTable.vue index 811a4ee8..28f6e896 100644 --- a/packages/opendesign/src/components/table/OTable.vue +++ b/packages/opendesign/src/components/table/OTable.vue @@ -5,7 +5,7 @@ import { computed } from 'vue'; import { IconLoading } from '../_shared/icons'; import { isString } from '../_shared/utils'; -interface SelectPropT { +interface TablePropT { /** * 表头内容 */ @@ -44,7 +44,7 @@ interface SelectPropT { loadingLabel?: string; } -const props = withDefaults(defineProps(), { +const props = withDefaults(defineProps(), { small: false, cellSpan: undefined, columns: undefined, diff --git a/packages/opendesign/src/components/table/index.ts b/packages/opendesign/src/components/table/index.ts index ed9356c9..3a0d0b31 100644 --- a/packages/opendesign/src/components/table/index.ts +++ b/packages/opendesign/src/components/table/index.ts @@ -7,4 +7,6 @@ const OTable = Object.assign(_OTable, { }, }); +export * from './types'; + export { OTable }; -- Gitee From 2733010651afe958821e65f51ebf5423cef45d2b Mon Sep 17 00:00:00 2001 From: devin Date: Thu, 2 Feb 2023 10:24:00 +0800 Subject: [PATCH 03/16] init pagination --- .../src/components/pagination/OPagination.vue | 80 ++++++++++++++++++ .../pagination/__demo__/IndexPagination.vue | 11 +++ .../pagination/__demo__/PaginationBasic.vue | 22 +++++ .../src/components/pagination/index.ts | 10 +++ .../src/components/pagination/pagination.ts | 83 +++++++++++++++++++ .../components/pagination/style/index.scss | 46 ++++++++++ .../src/components/pagination/style/index.ts | 1 + .../src/components/pagination/style/var.scss | 3 + .../src/components/pagination/types.ts | 0 packages/portal/src/router.ts | 6 ++ 10 files changed, 262 insertions(+) create mode 100644 packages/opendesign/src/components/pagination/OPagination.vue create mode 100644 packages/opendesign/src/components/pagination/__demo__/IndexPagination.vue create mode 100644 packages/opendesign/src/components/pagination/__demo__/PaginationBasic.vue create mode 100644 packages/opendesign/src/components/pagination/index.ts create mode 100644 packages/opendesign/src/components/pagination/pagination.ts create mode 100644 packages/opendesign/src/components/pagination/style/index.scss create mode 100644 packages/opendesign/src/components/pagination/style/index.ts create mode 100644 packages/opendesign/src/components/pagination/style/var.scss create mode 100644 packages/opendesign/src/components/pagination/types.ts diff --git a/packages/opendesign/src/components/pagination/OPagination.vue b/packages/opendesign/src/components/pagination/OPagination.vue new file mode 100644 index 00000000..301d23fb --- /dev/null +++ b/packages/opendesign/src/components/pagination/OPagination.vue @@ -0,0 +1,80 @@ + + diff --git a/packages/opendesign/src/components/pagination/__demo__/IndexPagination.vue b/packages/opendesign/src/components/pagination/__demo__/IndexPagination.vue new file mode 100644 index 00000000..60792c90 --- /dev/null +++ b/packages/opendesign/src/components/pagination/__demo__/IndexPagination.vue @@ -0,0 +1,11 @@ + + + diff --git a/packages/opendesign/src/components/pagination/__demo__/PaginationBasic.vue b/packages/opendesign/src/components/pagination/__demo__/PaginationBasic.vue new file mode 100644 index 00000000..34358e03 --- /dev/null +++ b/packages/opendesign/src/components/pagination/__demo__/PaginationBasic.vue @@ -0,0 +1,22 @@ + + + diff --git a/packages/opendesign/src/components/pagination/index.ts b/packages/opendesign/src/components/pagination/index.ts new file mode 100644 index 00000000..09fbd47d --- /dev/null +++ b/packages/opendesign/src/components/pagination/index.ts @@ -0,0 +1,10 @@ +import _OPagination from './OPagination.vue'; +import type { App } from 'vue'; + +const OPagination = Object.assign(_OPagination, { + install(app: App) { + app.component(_OPagination.name, _OPagination); + }, +}); + +export { OPagination }; diff --git a/packages/opendesign/src/components/pagination/pagination.ts b/packages/opendesign/src/components/pagination/pagination.ts new file mode 100644 index 00000000..b2bb9353 --- /dev/null +++ b/packages/opendesign/src/components/pagination/pagination.ts @@ -0,0 +1,83 @@ +function getNumbers(min: number, max: number) { + const arr = []; + for (let i = min; i <= max; i++) { + arr.push(i); + } + return arr; +} +export function getPagerItem(totalPage: number, currentPage = 1, showPageCount = 9) { + const maxCount = showPageCount > 3 ? showPageCount : 3; + let pages: Array<{ value: number | string, isMore?: boolean, list?: number[] }> = []; + + /** + * 如果页码小于最大显示页码数,直接显示全部 + */ + if (totalPage <= maxCount) { + for (let i = 1; i <= totalPage; i++) { + pages.push({ value: i }); + } + return pages; + } + + /** + * 如果页码大于最大显示页码数,需要处理页码隐藏 + */ + // 先设置首尾页码 + pages[0] = { value: 1 }; + pages[maxCount - 1] = { value: totalPage }; + + if (maxCount === 3) { + // 如果只显示3个,则中间全部隐藏 + pages[1] = { + isMore: true, + value: 'left', + list: getNumbers(2, totalPage - 1) + }; + } else { + const d = (maxCount - 3) / 2; + + let min = currentPage - Math.floor(d); + let max = currentPage + Math.ceil(d); + + // 处理边缘问题 + if (max > totalPage - 1) { + min -= (max - totalPage + 1); + max = totalPage - 1; + } + if (min < 2) { + max += (2 - min); + min = 2; + } + + // 判断第二个页码是否隐藏 + if (min < 3) { + pages[1] = { value: 2 }; + min = 2; + } else { + pages[1] = { + isMore: true, + value: 'left', + list: getNumbers(2, min) + }; + } + + // 判断倒数第二个页码是否隐藏 + if (max > totalPage - 2) { + pages[maxCount - 2] = { value: totalPage - 1 }; + max = totalPage - 1; + } else { + pages[maxCount - 2] = { + isMore: true, + value: 'right', + list: getNumbers(max, totalPage - 1) + }; + } + + // 处理中间显示的页码 + getNumbers(min + 1, max - 1).forEach((item, idx) => { + pages[2 + idx] = ({ value: item }); + }); + } + + return pages; +} \ No newline at end of file diff --git a/packages/opendesign/src/components/pagination/style/index.scss b/packages/opendesign/src/components/pagination/style/index.scss new file mode 100644 index 00000000..0024746d --- /dev/null +++ b/packages/opendesign/src/components/pagination/style/index.scss @@ -0,0 +1,46 @@ +@import './var.scss'; + +.o-pagination-wrap { + display: flex; + align-items: center; +} + +.o-pagination-prev, +.o-pagination-next { + width: var(--pagination-item-size); + height: var(--pagination-item-size); + display: inline-flex; + justify-content: center; + align-items: center; + border: 1px solid var(--o-color-border2); + cursor: pointer; + + &.disabled { + color: var(--o-color-border2); + border: 1px solid var(--o-color-border2); + } +} +.o-pagination-pages { + margin-left: 8px; + margin-right: 8px; + display: flex; + align-items: center; +} +.o-pagination-item { + width: var(--pagination-item-size); + height: var(--pagination-item-size); + display: inline-flex; + justify-content: center; + align-items: center; + cursor: pointer; + + .o-pagination-item { + margin-left: 8px; + } + &:hover { + color: var(--o-color-primary2); + } + &.active { + color: var(--o-color-primary1); + border: 1px solid var(--o-color-primary1); + } +} diff --git a/packages/opendesign/src/components/pagination/style/index.ts b/packages/opendesign/src/components/pagination/style/index.ts new file mode 100644 index 00000000..67aac616 --- /dev/null +++ b/packages/opendesign/src/components/pagination/style/index.ts @@ -0,0 +1 @@ +import './index.scss'; diff --git a/packages/opendesign/src/components/pagination/style/var.scss b/packages/opendesign/src/components/pagination/style/var.scss new file mode 100644 index 00000000..69d106cb --- /dev/null +++ b/packages/opendesign/src/components/pagination/style/var.scss @@ -0,0 +1,3 @@ +.o-pagination { + --pagination-item-size: 32px; +} diff --git a/packages/opendesign/src/components/pagination/types.ts b/packages/opendesign/src/components/pagination/types.ts new file mode 100644 index 00000000..e69de29b diff --git a/packages/portal/src/router.ts b/packages/portal/src/router.ts index f7db10d5..aed0a6c6 100644 --- a/packages/portal/src/router.ts +++ b/packages/portal/src/router.ts @@ -81,6 +81,12 @@ export const routes = [ label: '表格', component: () => import('@demo/table/__demo__/IndexTable.vue'), }, + { + path: '/pagination', + name: 'Pagination', + label: '分页', + component: () => import('@demo/pagination/__demo__/IndexPagination.vue'), + }, ]; export const router = createRouter({ -- Gitee From 7c777d5b2926879a2ac0322b0b56a25c2db879a8 Mon Sep 17 00:00:00 2001 From: devin Date: Thu, 2 Feb 2023 15:49:40 +0800 Subject: [PATCH 04/16] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8F=AA=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E4=B8=80=E4=B8=AA=E5=AD=90=E5=85=83=E7=B4=A0=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/_shared/vue-utils.ts | 125 +++++++++++++++--- .../src/components/directves/index.ts | 4 +- .../only-child/__demo__/IndexChildOnly.vue | 33 +++++ .../only-child/__demo__/SlotChild.vue | 5 + .../src/components/only-child/index.ts | 1 + .../src/components/only-child/only-child.ts | 15 +++ packages/portal/src/router.ts | 6 + 7 files changed, 172 insertions(+), 17 deletions(-) create mode 100644 packages/opendesign/src/components/only-child/__demo__/IndexChildOnly.vue create mode 100644 packages/opendesign/src/components/only-child/__demo__/SlotChild.vue create mode 100644 packages/opendesign/src/components/only-child/index.ts create mode 100644 packages/opendesign/src/components/only-child/only-child.ts diff --git a/packages/opendesign/src/components/_shared/vue-utils.ts b/packages/opendesign/src/components/_shared/vue-utils.ts index 8a5dbc94..21bdb616 100644 --- a/packages/opendesign/src/components/_shared/vue-utils.ts +++ b/packages/opendesign/src/components/_shared/vue-utils.ts @@ -1,19 +1,20 @@ -import { Component, onMounted, Slots, VNode, VNodeTypes } from 'vue'; +import { Component, onMounted, ref, Slots, VNode, VNodeTypes } from 'vue'; +import { isArray } from './utils'; // 来着vuejs/core // https://github.com/vuejs/core/blob/main/packages/shared/src/shapeFlags.ts export const enum ShapeFlags { - ELEMENT = 1, - FUNCTIONAL_COMPONENT = 1 << 1, - STATEFUL_COMPONENT = 1 << 2, - TEXT_CHILDREN = 1 << 3, - ARRAY_CHILDREN = 1 << 4, - SLOTS_CHILDREN = 1 << 5, - TELEPORT = 1 << 6, - SUSPENSE = 1 << 7, - COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8, - COMPONENT_KEPT_ALIVE = 1 << 9, - COMPONENT = ShapeFlags.STATEFUL_COMPONENT | ShapeFlags.FUNCTIONAL_COMPONENT + ELEMENT = 1, // 普通HTML元素 + FUNCTIONAL_COMPONENT = 1 << 1, //函数式组件 + STATEFUL_COMPONENT = 1 << 2, //有状态组件 + TEXT_CHILDREN = 1 << 3, //文本节点 + ARRAY_CHILDREN = 1 << 4, //数组子节点 + SLOTS_CHILDREN = 1 << 5, //插槽子节点 + TELEPORT = 1 << 6, // teleport组件 + SUSPENSE = 1 << 7, //suspense组件 + COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8, //需要被keep-live的有状态组件 + COMPONENT_KEPT_ALIVE = 1 << 9, //已经被keep-alive的有状态组件 + COMPONENT = ShapeFlags.STATEFUL_COMPONENT | ShapeFlags.FUNCTIONAL_COMPONENT//有状态或函数式组件 } /** * 判断vnode是不是element @@ -33,15 +34,22 @@ export function isComponent(vnode: VNode, type?: VNodeTypes): type is Component /** * 判断vnode是不是vue组件 */ -export const isSlotsChildren = (vnode: VNode, children: VNode['children']): children is Slots => { +export const isSlotsChildren = (vnode: VNode, children?: VNode['children']): children is Slots => { return Boolean(vnode && vnode.shapeFlag & ShapeFlags.SLOTS_CHILDREN); }; +/** + * 判断vnode是不是slot的子元素 + */ +export const isArrayChildren = (vn: VNode, children?: VNode['children']): children is VNode[] => { + return Boolean(vn && vn.shapeFlag & ShapeFlags.ARRAY_CHILDREN); +}; + // TODO export function useSlotElement(componentName?: string) { let children: VNode[] | null = null; const components = []; - // const + onMounted(() => { children?.forEach(child => { console.log(child, isComponent(child)); @@ -53,8 +61,93 @@ export function useSlotElement(componentName?: string) { }); }); return { - setSlotChildren(nodes: VNode[]) { - children = nodes; + setSlotChildren(nodes: VNode[] | undefined) { + if (nodes) { + children = nodes; + } + } + }; +} +export function getFirstComponent(vn: VNode | VNode[]): VNode | null { + if (isArray(vn)) { + for (const child of vn) { + const result = getFirstComponent(child); + if (result) { + return result; + } + } + } else if (isElement(vn) || isComponent(vn)) { + return vn; + } else if (isArrayChildren(vn, vn.children)) { + for (const child of vn.children) { + const result = getFirstComponent(child); + if (result) { + return result; + } + } + } else if (isSlotsChildren(vn, vn.children)) { + const children = vn.children.default?.(); + if (children) { + const result = getFirstComponent(children); + if (result) { + return result; + } + } + } + return null; +} + + +export const getFirstElement = (vn: VNode | VNode[]): HTMLElement | null => { + if (isArray(vn)) { + for (const child of vn) { + const result = getFirstElement(child); + if (result) { + return result; + } + } + } else if (isElement(vn)) { + return vn.el as HTMLElement; + } else if (isComponent(vn)) { + if ((vn.el as Node).nodeType === 1) { + return vn.el as HTMLElement; } + if (vn.component) { + const result = getFirstElement(vn.component.subTree); + if (result) { + return result; + }; + } + } else if (isArrayChildren(vn, vn.children)) { + for (const child of vn.children) { + const result = getFirstElement(child); + if (result) { + return result; + } + } + } + return null; +}; + +export function useSlotFirstElement() { + let children: VNode[] | null = null; + const fistElement = ref(null); + + onMounted(() => { + if (children) { + fistElement.value = getFirstElement(children); + console.log(fistElement.value); + + } + }); + return { + setSlot(nodes: VNode[] | undefined) { + if (nodes) { + children = nodes; + console.log(children); + + } + }, + fistElement }; } \ No newline at end of file diff --git a/packages/opendesign/src/components/directves/index.ts b/packages/opendesign/src/components/directves/index.ts index c6ac1fa8..aab73ab4 100644 --- a/packages/opendesign/src/components/directves/index.ts +++ b/packages/opendesign/src/components/directves/index.ts @@ -1,2 +1,4 @@ export * from './click-outside'; -export * from './focus'; \ No newline at end of file +export * from './focus'; +export * from './on-intersection'; +export * from './on-resize'; \ No newline at end of file diff --git a/packages/opendesign/src/components/only-child/__demo__/IndexChildOnly.vue b/packages/opendesign/src/components/only-child/__demo__/IndexChildOnly.vue new file mode 100644 index 00000000..9bb417fd --- /dev/null +++ b/packages/opendesign/src/components/only-child/__demo__/IndexChildOnly.vue @@ -0,0 +1,33 @@ + + + diff --git a/packages/opendesign/src/components/only-child/__demo__/SlotChild.vue b/packages/opendesign/src/components/only-child/__demo__/SlotChild.vue new file mode 100644 index 00000000..5894a4b1 --- /dev/null +++ b/packages/opendesign/src/components/only-child/__demo__/SlotChild.vue @@ -0,0 +1,5 @@ + diff --git a/packages/opendesign/src/components/only-child/index.ts b/packages/opendesign/src/components/only-child/index.ts new file mode 100644 index 00000000..9492e853 --- /dev/null +++ b/packages/opendesign/src/components/only-child/index.ts @@ -0,0 +1 @@ +export { default as OChildOnly } from './only-child'; \ No newline at end of file diff --git a/packages/opendesign/src/components/only-child/only-child.ts b/packages/opendesign/src/components/only-child/only-child.ts new file mode 100644 index 00000000..ba95c8c8 --- /dev/null +++ b/packages/opendesign/src/components/only-child/only-child.ts @@ -0,0 +1,15 @@ +import { defineComponent } from 'vue'; +import { getFirstComponent } from '../_shared/vue-utils'; + +/** + * 只渲染一个子元素 + */ +export default defineComponent({ + name: 'OChildOnly', + setup(props, { slots }) { + return () => { + const children = slots.default?.(); + return children ? getFirstComponent(children) : null; + }; + }, +}); diff --git a/packages/portal/src/router.ts b/packages/portal/src/router.ts index aed0a6c6..a27ce218 100644 --- a/packages/portal/src/router.ts +++ b/packages/portal/src/router.ts @@ -39,6 +39,12 @@ export const routes = [ label: 'Intersection监听', component: () => import('@demo/intersection-observer/__demo__/IndexIntersection.vue'), }, + { + path: '/child-only', + name: 'ChildOnly', + label: '只渲染一个子元素', + component: () => import('@demo/only-child/__demo__/IndexChildOnly.vue'), + }, { path: '/popup', name: 'Popup', -- Gitee From ced85fbe5aacbbebb5185847761f88016e60cf8e Mon Sep 17 00:00:00 2001 From: devin Date: Thu, 2 Feb 2023 15:54:00 +0800 Subject: [PATCH 05/16] =?UTF-8?q?ResizeObserver=E5=A2=9E=E5=8A=A0=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E5=89=8D=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/opendesign/src/components/popup/OPopup.vue | 7 ++++--- .../resize-observer/__demo__/IndexResize.vue | 4 ++-- .../components/resize-observer/__demo__/ResizeDemo.vue | 10 +++++----- .../opendesign/src/components/resize-observer/index.ts | 2 +- .../src/components/resize-observer/resize-observer.ts | 2 +- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/opendesign/src/components/popup/OPopup.vue b/packages/opendesign/src/components/popup/OPopup.vue index 7ef18ecc..c23de11f 100644 --- a/packages/opendesign/src/components/popup/OPopup.vue +++ b/packages/opendesign/src/components/popup/OPopup.vue @@ -10,7 +10,7 @@ import { isElement, getScrollParents } from '../_shared/dom'; import { isArray, throttleRAF } from '../_shared/utils'; import { calcPopupStyle, bindTrigger, getTransformOrigin } from './popup'; import { useResizeObserver } from '../hooks/use-resize-observer'; -import { ResizeObserver } from '../resize-observer'; +import { OResizeObserver } from '../resize-observer'; import { useIntersectionObserver } from '../hooks'; import type { IntersectionListenerT } from '../hooks'; @@ -431,7 +431,7 @@ onUnmounted(() => { diff --git a/packages/opendesign/src/components/resize-observer/__demo__/IndexResize.vue b/packages/opendesign/src/components/resize-observer/__demo__/IndexResize.vue index 75df8370..4ea04af1 100644 --- a/packages/opendesign/src/components/resize-observer/__demo__/IndexResize.vue +++ b/packages/opendesign/src/components/resize-observer/__demo__/IndexResize.vue @@ -1,9 +1,9 @@ diff --git a/packages/opendesign/src/components/resize-observer/__demo__/ResizeDemo.vue b/packages/opendesign/src/components/resize-observer/__demo__/ResizeDemo.vue index c550dc15..0c98f96e 100644 --- a/packages/opendesign/src/components/resize-observer/__demo__/ResizeDemo.vue +++ b/packages/opendesign/src/components/resize-observer/__demo__/ResizeDemo.vue @@ -1,6 +1,6 @@ - diff --git a/packages/opendesign/src/components/child-only/__demo__/SlotChild.vue b/packages/opendesign/src/components/child-only/__demo__/SlotChild.vue new file mode 100644 index 00000000..bffab631 --- /dev/null +++ b/packages/opendesign/src/components/child-only/__demo__/SlotChild.vue @@ -0,0 +1,15 @@ + + diff --git a/packages/opendesign/src/components/only-child/only-child.ts b/packages/opendesign/src/components/child-only/child-only.ts similarity index 91% rename from packages/opendesign/src/components/only-child/only-child.ts rename to packages/opendesign/src/components/child-only/child-only.ts index ba95c8c8..3c4c5ea1 100644 --- a/packages/opendesign/src/components/only-child/only-child.ts +++ b/packages/opendesign/src/components/child-only/child-only.ts @@ -9,6 +9,8 @@ export default defineComponent({ setup(props, { slots }) { return () => { const children = slots.default?.(); + // console.log(children); + return children ? getFirstComponent(children) : null; }; }, diff --git a/packages/opendesign/src/components/child-only/index.ts b/packages/opendesign/src/components/child-only/index.ts new file mode 100644 index 00000000..d833b6d4 --- /dev/null +++ b/packages/opendesign/src/components/child-only/index.ts @@ -0,0 +1 @@ +export { default as OChildOnly } from './child-only'; \ No newline at end of file diff --git a/packages/opendesign/src/components/only-child/__demo__/SlotChild.vue b/packages/opendesign/src/components/only-child/__demo__/SlotChild.vue deleted file mode 100644 index 5894a4b1..00000000 --- a/packages/opendesign/src/components/only-child/__demo__/SlotChild.vue +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/packages/opendesign/src/components/only-child/index.ts b/packages/opendesign/src/components/only-child/index.ts deleted file mode 100644 index 9492e853..00000000 --- a/packages/opendesign/src/components/only-child/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as OChildOnly } from './only-child'; \ No newline at end of file diff --git a/packages/opendesign/src/components/popup/OPopup.vue b/packages/opendesign/src/components/popup/OPopup.vue index c23de11f..10b6c549 100644 --- a/packages/opendesign/src/components/popup/OPopup.vue +++ b/packages/opendesign/src/components/popup/OPopup.vue @@ -13,6 +13,7 @@ import { useResizeObserver } from '../hooks/use-resize-observer'; import { OResizeObserver } from '../resize-observer'; import { useIntersectionObserver } from '../hooks'; import type { IntersectionListenerT } from '../hooks'; +import { OChildOnly } from '../child-only'; // TODO 处理嵌套 @@ -130,6 +131,7 @@ const emits = defineEmits<{ (e: 'update:visible', val: boolean): void; (e: 'chan const triggers = isArray(props.trigger) ? props.trigger : [props.trigger]; const visible = ref(false); +const targetElRef = ref(null); let targetEl: HTMLElement | null = null; // 默认为true,避免props.visible为初始值为true时,无法计算popup位置 const isTargetInViewport = ref(true); @@ -289,15 +291,22 @@ const bindTargetEvent = (el: HTMLElement | null) => { } }; -// 触发元素为组件ref,处理事件触发 +// 触发元素为组件ref,因生命周期问题,延后绑定处理事件触发 watch( () => props.target, (ele) => { - if (ele) { + if (isElement((ele as ComponentPublicInstance)?.$el)) { bindTargetEvent((ele as ComponentPublicInstance).$el); } } ); + +watch(targetElRef, (elRef) => { + if (isElement(elRef?.$el)) { + bindTargetEvent(elRef?.$el); + } +}); + const onResize = (en: ResizeObserverEntry, isFirst: boolean) => { if (visible.value && !isFirst) { updatePopupStyle(); @@ -387,6 +396,7 @@ const onPopupHoverOut = () => { updateVisible(false, props.hoverDelay); } }; + onMounted(() => { // 在mounted事件后再显示,避免找不到wrapper visible.value = props.visible; @@ -430,6 +440,9 @@ onUnmounted(() => { }); diff --git a/packages/opendesign/src/components/popup/__demo__/IndexPopup.vue b/packages/opendesign/src/components/popup/__demo__/IndexPopup.vue index 29a44a15..d873b04c 100644 --- a/packages/opendesign/src/components/popup/__demo__/IndexPopup.vue +++ b/packages/opendesign/src/components/popup/__demo__/IndexPopup.vue @@ -4,9 +4,11 @@ import '../style'; import PopupPosition from './PopupPosition.vue'; import PopupVisible from './PopupVisible.vue'; import PopupContainer from './PopupContainer.vue'; +import PopupTarget from './PopupTarget.vue'; diff --git a/packages/opendesign/src/components/input/__demo__/InputBasic.vue b/packages/opendesign/src/components/input/__demo__/InputBasic.vue new file mode 100644 index 00000000..42a50e2d --- /dev/null +++ b/packages/opendesign/src/components/input/__demo__/InputBasic.vue @@ -0,0 +1,20 @@ + + + diff --git a/packages/opendesign/src/components/input/__demo__/InputDisabled.vue b/packages/opendesign/src/components/input/__demo__/InputDisabled.vue new file mode 100644 index 00000000..e1cbaaff --- /dev/null +++ b/packages/opendesign/src/components/input/__demo__/InputDisabled.vue @@ -0,0 +1,8 @@ + + + diff --git a/packages/opendesign/src/components/input/index.ts b/packages/opendesign/src/components/input/index.ts new file mode 100644 index 00000000..ab9ff675 --- /dev/null +++ b/packages/opendesign/src/components/input/index.ts @@ -0,0 +1,9 @@ +import _OInput from './OInput.vue'; +import type { App } from 'vue'; + +const OInput = Object.assign(_OInput, { + install(app: App) { + app.component(_OInput.name, _OInput); + }, +}); +export { OInput }; diff --git a/packages/opendesign/src/components/input/style/index.scss b/packages/opendesign/src/components/input/style/index.scss new file mode 100644 index 00000000..d483f12a --- /dev/null +++ b/packages/opendesign/src/components/input/style/index.scss @@ -0,0 +1,63 @@ +@import './var.scss'; +@import '../../popup/style/index.scss'; + +.o-input { + border: 1px solid var(--input-border); + border-radius: 4px; + padding: 0 12px; + cursor: pointer; + color: var(--input-color); + display: inline-flex; + height: var(--input-height-m); + + &:hover { + border-color: var(--input-border_hover); + background-color: var(--input-bg_hover); + } + &.is-inputing { + border-color: var(--input-border_hover); + background-color: var(--input-bg_hover); + } + &.is-disabled { + cursor: not-allowed; + border-color: var(--input-border_disabled); + background-color: var(--input-bg_disabled); + color: var(--input-color_disabled); + } +} +.o-input-size-small { + padding: 0 6px 0 12px; + height: var(--input-height-s); + border-radius: var(--input-radius-s); +} + +.o-input-size-normal { + padding: 4px 8px 4px 12px; + height: var(--input-height-m); + border-radius: var(--input-radius-m); +} + +.o-input-size-large { + padding: 4px 12px 4px 16px; + height: var(--input-height-l); + border-radius: var(--input-radius-l); +} + +.o-input-shape-round { + border-radius: 100px; +} + +.o-input-input { + outline: none; + border: none; + padding: 0; + color: inherit; + cursor: inherit; + background-color: transparent; + display: inline-flex; + width: 100%; + caret-color: red; + // &.password { + // -webkit-text-security: disc; + // } +} diff --git a/packages/opendesign/src/components/input/style/index.ts b/packages/opendesign/src/components/input/style/index.ts new file mode 100644 index 00000000..67aac616 --- /dev/null +++ b/packages/opendesign/src/components/input/style/index.ts @@ -0,0 +1 @@ +import './index.scss'; diff --git a/packages/opendesign/src/components/input/style/var.scss b/packages/opendesign/src/components/input/style/var.scss new file mode 100644 index 00000000..3f8bda81 --- /dev/null +++ b/packages/opendesign/src/components/input/style/var.scss @@ -0,0 +1,26 @@ +.o-input { + --input-text-size: var(--o-font_size-text); + --input-text-height: var(--o-line_height-text); + + --input-height-s: var(--o-size-s); + --input-height-m: var(--o-size-m); + --input-height-l: var(--o-size-l); + + --input-radius-s: var(--o-radius-s); + --input-radius-m: var(--o-radius-s); + --input-radius-l: var(--o-radius-s); + + --input-border: var(--o-color-info1); + --input-border_hover: var(--o-color-primary2); + --input-border_active: var(--o-color-primary3); + --input-border_disabled: var(--o-color-info1); + + --input-bg: var(--o-color-bg1); + --input-bg_hover: var(--o-color-bg2); + --input-bg_disabled: var(--o-color-info4); + + --input-color: var(--o-color-text2); + --input-color_disabled: var(--o-color-text4); + + --input-icon-color: var(--o-color-text3); +} diff --git a/packages/portal/src/router.ts b/packages/portal/src/router.ts index 4f26eda2..f3072634 100644 --- a/packages/portal/src/router.ts +++ b/packages/portal/src/router.ts @@ -57,6 +57,12 @@ export const routes = [ label: '弹出框', component: () => import('@demo/popover/__demo__/IndexPopover.vue'), }, + { + path: '/input', + name: 'Input', + label: '输入框', + component: () => import('@demo/input/__demo__/IndexInput.vue'), + }, { path: '/select', name: 'Select', -- Gitee From 02a0fa8568190a5a6967f0a114767d002fd53cef Mon Sep 17 00:00:00 2001 From: devin Date: Fri, 3 Feb 2023 13:02:05 +0800 Subject: [PATCH 10/16] =?UTF-8?q?=E5=A2=9E=E5=8A=A0is=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../opendesign/src/components/_shared/dom.ts | 2 +- .../opendesign/src/components/_shared/is.ts | 42 +++++++++++++++++++ .../src/components/_shared/utils.ts | 25 ----------- .../src/components/_shared/vue-utils.ts | 2 +- .../components/directves/on-intersection.ts | 2 +- .../src/components/directves/on-resize.ts | 2 +- .../hooks/use-element-intersection.ts | 2 +- .../components/hooks/use-element-resize.ts | 2 +- .../hooks/use-intersection-observer.ts | 2 +- .../components/hooks/use-resize-observer.ts | 2 +- .../src/components/popup/OPopup.vue | 3 +- .../src/components/switch/OSwitch.vue | 2 +- .../src/components/table/OTable.vue | 2 +- .../opendesign/src/components/table/table.ts | 4 +- 14 files changed, 56 insertions(+), 38 deletions(-) create mode 100644 packages/opendesign/src/components/_shared/is.ts diff --git a/packages/opendesign/src/components/_shared/dom.ts b/packages/opendesign/src/components/_shared/dom.ts index e904b2b1..8563d9f0 100644 --- a/packages/opendesign/src/components/_shared/dom.ts +++ b/packages/opendesign/src/components/_shared/dom.ts @@ -1,4 +1,4 @@ -import { isArray } from './utils'; +import { isArray } from './is'; export type DirectionT = 'left' | 'right' | 'top' | 'bottom'; diff --git a/packages/opendesign/src/components/_shared/is.ts b/packages/opendesign/src/components/_shared/is.ts new file mode 100644 index 00000000..68b97455 --- /dev/null +++ b/packages/opendesign/src/components/_shared/is.ts @@ -0,0 +1,42 @@ + +const opt = Object.prototype.toString; + +export function isUndefined(val: unknown): val is undefined { + return val === undefined; +} + +export function isNull(val: unknown): val is null { + return opt.call(val) === '[object Null]'; +} + +export function isBoolean(val: unknown): val is boolean { + return opt.call(val) === '[object Boolean]'; +} + +export function isString(val: unknown): val is string { + return opt.call(val) === '[object String]'; +} + +export function isNumber(val: unknown): val is number { + return opt.call(val) === '[object Number]' && val === val; // eslint-disable-line +} + +export function isFunction(val: unknown): val is Function { + return typeof val === 'function'; +} + +export function isArray(val: unknown): val is Array { + return Array.isArray(val); +} + +export function isObject(val: unknown): val is Record { + return val !== null && typeof val === 'object'; +} + +export function isPlainObject(val: unknown): val is object { + return opt.call(val) === '[object Object]'; +} + +export const isPromise = (val: unknown): val is Promise => { + return opt.call(val) === '[object Promise]'; +}; \ No newline at end of file diff --git a/packages/opendesign/src/components/_shared/utils.ts b/packages/opendesign/src/components/_shared/utils.ts index e4b00010..c600242b 100644 --- a/packages/opendesign/src/components/_shared/utils.ts +++ b/packages/opendesign/src/components/_shared/utils.ts @@ -1,31 +1,6 @@ import { throttle as _throttle, debounce as _debounce } from 'lodash-es'; import type { ThrottleSettings, DebounceSettings } from 'lodash-es'; -export function isBoolean(val: unknown): val is boolean { - return typeof val === 'boolean'; -} -export function isString(val: unknown): val is string { - return typeof val === 'string'; -} -export function isNumber(val: unknown): val is number { - return typeof val === 'string'; -} -export function isFunction(val: unknown): val is Function { - return typeof val === 'function'; -} -export function isArray(val: unknown): val is Array { - return Array.isArray(val); -} -export function isObject(val: unknown): val is Record { - return val !== null && typeof val === 'object'; -} -export function isPlainObject(val: unknown): val is object { - return Object.prototype.toString.call(val) === '[object Object]'; -} -export function isPromise(val: unknown): val is Promise { - return isObject(val) && isFunction(val.then) && isFunction(val.catch); -} - // 防抖 export function debounce) => unknown>(fn: T, wait?: number, ctx?: unknown | null, opts?: ThrottleSettings) { return _debounce.apply(ctx, [fn, wait, opts]); diff --git a/packages/opendesign/src/components/_shared/vue-utils.ts b/packages/opendesign/src/components/_shared/vue-utils.ts index e42af3b6..73e401ac 100644 --- a/packages/opendesign/src/components/_shared/vue-utils.ts +++ b/packages/opendesign/src/components/_shared/vue-utils.ts @@ -1,5 +1,5 @@ import { Component, onMounted, ref, Slots, VNode, VNodeTypes, Comment } from 'vue'; -import { isArray } from './utils'; +import { isArray } from './is'; // 来着vuejs/core // https://github.com/vuejs/core/blob/main/packages/shared/src/shapeFlags.ts diff --git a/packages/opendesign/src/components/directves/on-intersection.ts b/packages/opendesign/src/components/directves/on-intersection.ts index 9a3d76bb..73468b4a 100644 --- a/packages/opendesign/src/components/directves/on-intersection.ts +++ b/packages/opendesign/src/components/directves/on-intersection.ts @@ -1,6 +1,6 @@ import { DirectiveBinding, ObjectDirective } from 'vue'; import { useIntersectionObserver, IntersectionListenerT } from '../hooks'; -import { isFunction } from '../_shared/utils'; +import { isFunction } from '../_shared/is'; const io = useIntersectionObserver(); let listener: IntersectionListenerT = () => null; diff --git a/packages/opendesign/src/components/directves/on-resize.ts b/packages/opendesign/src/components/directves/on-resize.ts index 86606666..6348ad47 100644 --- a/packages/opendesign/src/components/directves/on-resize.ts +++ b/packages/opendesign/src/components/directves/on-resize.ts @@ -1,6 +1,6 @@ import { DirectiveBinding, ObjectDirective } from 'vue'; import { useResizeObserver, ResizeListenerT } from '../hooks'; -import { isFunction } from '../_shared/utils'; +import { isFunction } from '../_shared/is'; const ob = useResizeObserver(); let listener: ResizeListenerT = () => null; diff --git a/packages/opendesign/src/components/hooks/use-element-intersection.ts b/packages/opendesign/src/components/hooks/use-element-intersection.ts index 01a3e4c2..37943dba 100644 --- a/packages/opendesign/src/components/hooks/use-element-intersection.ts +++ b/packages/opendesign/src/components/hooks/use-element-intersection.ts @@ -1,7 +1,7 @@ import { ObjectDirective } from 'vue'; import { useIntersectionObserver } from './use-intersection-observer'; import type { IntersectionListenerT } from './use-intersection-observer'; -import { isFunction } from '../_shared/utils'; +import { isFunction } from '../_shared/is'; const io = useIntersectionObserver(); export function useIntersectionObserverDirective({ listener, removeOnUnmounted }: { diff --git a/packages/opendesign/src/components/hooks/use-element-resize.ts b/packages/opendesign/src/components/hooks/use-element-resize.ts index 4ea41216..72c60f48 100644 --- a/packages/opendesign/src/components/hooks/use-element-resize.ts +++ b/packages/opendesign/src/components/hooks/use-element-resize.ts @@ -1,7 +1,7 @@ import { ObjectDirective } from 'vue'; import { useResizeObserver } from './use-resize-observer'; import type { ResizeListenerT } from './use-resize-observer'; -import { isFunction } from '../_shared/utils'; +import { isFunction } from '../_shared/is'; const ob = useResizeObserver(); export function useReiszeObserverDirective(onResize: ResizeListenerT): { vResizeObserver: ObjectDirective } { diff --git a/packages/opendesign/src/components/hooks/use-intersection-observer.ts b/packages/opendesign/src/components/hooks/use-intersection-observer.ts index 6f171276..2a62f8c8 100644 --- a/packages/opendesign/src/components/hooks/use-intersection-observer.ts +++ b/packages/opendesign/src/components/hooks/use-intersection-observer.ts @@ -1,5 +1,5 @@ import IntersectionObserver from 'intersection-observer-polyfill'; -import { isFunction } from '../_shared/utils'; +import { isFunction } from '../_shared/is'; export type IntersectionListenerT = (entry: IntersectionObserverEntry) => void; /** diff --git a/packages/opendesign/src/components/hooks/use-resize-observer.ts b/packages/opendesign/src/components/hooks/use-resize-observer.ts index cb1e7db9..ebacf706 100644 --- a/packages/opendesign/src/components/hooks/use-resize-observer.ts +++ b/packages/opendesign/src/components/hooks/use-resize-observer.ts @@ -1,5 +1,5 @@ import ResizeObserver from 'resize-observer-polyfill'; -import { isFunction } from '../_shared/utils'; +import { isFunction } from '../_shared/is'; export type ResizeListenerT = (entry: ResizeObserverEntry, isFirst: boolean) => void; /** diff --git a/packages/opendesign/src/components/popup/OPopup.vue b/packages/opendesign/src/components/popup/OPopup.vue index eea526f4..fdee19f2 100644 --- a/packages/opendesign/src/components/popup/OPopup.vue +++ b/packages/opendesign/src/components/popup/OPopup.vue @@ -7,7 +7,8 @@ export default { import { onMounted, reactive, ref, Ref, watch, nextTick, onUnmounted, PropType, ComponentPublicInstance, computed } from 'vue'; import { PopupPositionT, PopupTriggerT } from './types'; import { isElement, getScrollParents } from '../_shared/dom'; -import { isArray, throttleRAF } from '../_shared/utils'; +import { throttleRAF } from '../_shared/utils'; +import { isArray } from '../_shared/is'; import { calcPopupStyle, bindTrigger, getTransformOrigin } from './popup'; import { useResizeObserver } from '../hooks/use-resize-observer'; import { OResizeObserver } from '../resize-observer'; diff --git a/packages/opendesign/src/components/switch/OSwitch.vue b/packages/opendesign/src/components/switch/OSwitch.vue index 3fe06ef1..e137d77b 100644 --- a/packages/opendesign/src/components/switch/OSwitch.vue +++ b/packages/opendesign/src/components/switch/OSwitch.vue @@ -1,5 +1,5 @@ @@ -118,7 +115,7 @@ const onKeyDown = (e: KeyboardEvent) => { :class="[`o-input-size-${props.size || defaultSize}`, `o-input-shape-${props.shape || defaultShape}`, { 'is-disabled': props.disabled }]" > { + val2.value += '---'; +}, 2000); + +const printEvent = (event: string, val?: string) => { + console.log(event, val); +}; diff --git a/packages/opendesign/src/components/button/style/index.scss b/packages/opendesign/src/components/button/style/index.scss index 6c71fd9d..6fd6e64f 100644 --- a/packages/opendesign/src/components/button/style/index.scss +++ b/packages/opendesign/src/components/button/style/index.scss @@ -56,7 +56,7 @@ } .o-btn-primary { - color: var(--btn-color_inverse); + color: var(--btn-color-inverse); background-color: var(--btn-primary); &:not(:disabled) { diff --git a/packages/opendesign/src/components/button/style/var.scss b/packages/opendesign/src/components/button/style/var.scss index ca8adcf1..91ef3503 100644 --- a/packages/opendesign/src/components/button/style/var.scss +++ b/packages/opendesign/src/components/button/style/var.scss @@ -9,7 +9,7 @@ --btn-bg_disabled: var(--o-color-info4); --btn-color: var(--o-color-text2); - --btn-color_inverse: var(--o-color-text2_inverse); + --btn-color-inverse: var(--o-color-text2-inverse); --btn-color_disabled: var(--o-color-text4); --btn-text-size: var(--o-font_size-text); diff --git a/packages/opendesign/src/components/checkbox/style/index.scss b/packages/opendesign/src/components/checkbox/style/index.scss index 188b4f51..32dca6a1 100644 --- a/packages/opendesign/src/components/checkbox/style/index.scss +++ b/packages/opendesign/src/components/checkbox/style/index.scss @@ -56,7 +56,7 @@ display: inline-flex; justify-content: center; align-items: center; - color: var(--o-color-text1_inverse); + color: var(--o-color-text1-inverse); } .o-checkbox-label { diff --git a/packages/opendesign/src/components/input/OInput.vue b/packages/opendesign/src/components/input/OInput.vue index f0445b68..aaa14909 100644 --- a/packages/opendesign/src/components/input/OInput.vue +++ b/packages/opendesign/src/components/input/OInput.vue @@ -1,8 +1,8 @@ diff --git a/packages/opendesign/src/components/input/__demo__/IndexInput.vue b/packages/opendesign/src/components/input/__demo__/IndexInput.vue index 8433f4c3..67407ab3 100644 --- a/packages/opendesign/src/components/input/__demo__/IndexInput.vue +++ b/packages/opendesign/src/components/input/__demo__/IndexInput.vue @@ -3,12 +3,12 @@ import '../style'; import '../../option/style'; import InputBasic from './InputBasic.vue'; -import InputDisabled from './InputDisabled.vue'; +import InputSlot from './InputSlot.vue'; diff --git a/packages/opendesign/src/components/input/__demo__/InputBasic.vue b/packages/opendesign/src/components/input/__demo__/InputBasic.vue index 074b969a..088893d7 100644 --- a/packages/opendesign/src/components/input/__demo__/InputBasic.vue +++ b/packages/opendesign/src/components/input/__demo__/InputBasic.vue @@ -1,15 +1,17 @@ @@ -17,18 +19,51 @@ const printEvent = (event: string, val?: string) => {

Basic

val1:{{ val1 }}
- + - - - + + + +
+

Size

+
+
val1:{{ val1 }}
+ + + +
+

Disabled

+
+
val1:{{ val1 }}
+ + + + + + + + + +
diff --git a/packages/opendesign/src/components/input/__demo__/InputDisabled.vue b/packages/opendesign/src/components/input/__demo__/InputDisabled.vue deleted file mode 100644 index e1cbaaff..00000000 --- a/packages/opendesign/src/components/input/__demo__/InputDisabled.vue +++ /dev/null @@ -1,8 +0,0 @@ - - - diff --git a/packages/opendesign/src/components/input/__demo__/InputSlot.vue b/packages/opendesign/src/components/input/__demo__/InputSlot.vue new file mode 100644 index 00000000..846b883a --- /dev/null +++ b/packages/opendesign/src/components/input/__demo__/InputSlot.vue @@ -0,0 +1,39 @@ + + + diff --git a/packages/opendesign/src/components/input/style/index.scss b/packages/opendesign/src/components/input/style/index.scss index d483f12a..e362c3a9 100644 --- a/packages/opendesign/src/components/input/style/index.scss +++ b/packages/opendesign/src/components/input/style/index.scss @@ -2,62 +2,164 @@ @import '../../popup/style/index.scss'; .o-input { - border: 1px solid var(--input-border); - border-radius: 4px; - padding: 0 12px; cursor: pointer; color: var(--input-color); display: inline-flex; - height: var(--input-height-m); - - &:hover { - border-color: var(--input-border_hover); - background-color: var(--input-bg_hover); - } - &.is-inputing { - border-color: var(--input-border_hover); - background-color: var(--input-bg_hover); - } - &.is-disabled { - cursor: not-allowed; - border-color: var(--input-border_disabled); - background-color: var(--input-bg_disabled); - color: var(--input-color_disabled); - } } .o-input-size-small { - padding: 0 6px 0 12px; height: var(--input-height-s); - border-radius: var(--input-radius-s); + font-size: var(--input-text-size-s); + line-height: var(--input-text-height-s); + .o-input-wrap { + padding-left: 6px; + padding-right: 6px; + border-radius: var(--input-radius-s); + } } .o-input-size-normal { - padding: 4px 8px 4px 12px; height: var(--input-height-m); - border-radius: var(--input-radius-m); + font-size: var(--input-text-size-m); + line-height: var(--input-text-height-m); + .o-input-wrap { + padding-left: 12px; + padding-right: 12px; + border-radius: var(--input-radius-m); + } + .o-input-append { + border-top-right-radius: var(--input-radius-m); + border-bottom-right-radius: var(--input-radius-m); + } + + .o-input-prepend { + border-top-left-radius: var(--input-radius-m); + border-bottom-left-radius: var(--input-radius-m); + } } .o-input-size-large { - padding: 4px 12px 4px 16px; height: var(--input-height-l); - border-radius: var(--input-radius-l); + font-size: var(--input-text-size-l); + line-height: var(--input-text-height-l); + .o-input-wrap { + padding-left: 16px; + padding-right: 16px; + border-radius: var(--input-radius-l); + } } .o-input-shape-round { border-radius: 100px; } +.o-input-wrap { + display: flex; + padding: 0 12px; + border: 1px solid var(--input-border); + + &:hover { + border-color: var(--input-border-hover); + background-color: var(--input-bg-hover); + } + .o-input.is-focus & { + border-color: var(--input-border-active); + background-color: var(--input-bg-active); + } + .o-input.is-disabled & { + color: var(--input-color-disabled); + cursor: not-allowed; + border-color: var(--input-border-disabled); + background-color: var(--input-bg-disabled); + } + + .o-input:not(.is-disabled) & { + &.clearable { + &.has-suffix { + .o-input-clear { + position: absolute; + right: 0; + height: 100%; + } + + &:hover { + .o-input-suffix-wrap { + visibility: hidden; + opacity: 0; + } + } + } + &:hover { + .o-input-clear { + visibility: visible; + opacity: 1; + transform: scale(1); + } + } + } + } + &.has-prepend { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + &.has-append { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +} + .o-input-input { outline: none; border: none; - padding: 0; color: inherit; cursor: inherit; background-color: transparent; display: inline-flex; width: 100%; - caret-color: red; - // &.password { - // -webkit-text-security: disc; - // } + caret-color: var(--o-color-primary1); + padding: 4px 0; +} + +.o-input-clear { + visibility: hidden; + opacity: 0; + transform: scale(0.1); + transition: all var(--o-duration-m1) var(--o-easing-standard-in); + display: flex; + align-items: center; + justify-content: center; +} +.o-input-suffix-wrap { + transition: all var(var(--o-duration-m1)) var(--o-easing-standard-out); +} +.o-input-suffix { + display: flex; + align-items: center; + position: relative; + margin-left: 4px; +} +.o-input-prefix { + display: flex; + align-items: center; + + margin-right: 4px; +} +.o-input-clear-icon { + stroke-width: 0.5px; +} + +.o-input-append, +.o-input-prepend { + display: flex; + align-items: center; + padding: 0 8px; +} + +.o-input-append { + border: 1px solid var(--o-color-border2); + border-left: 0; +} + +.o-input-prepend { + border: 1px solid var(--o-color-border2); + border-right: 0; } diff --git a/packages/opendesign/src/components/input/style/var.scss b/packages/opendesign/src/components/input/style/var.scss index 3f8bda81..8be559a6 100644 --- a/packages/opendesign/src/components/input/style/var.scss +++ b/packages/opendesign/src/components/input/style/var.scss @@ -1,6 +1,10 @@ .o-input { - --input-text-size: var(--o-font_size-text); - --input-text-height: var(--o-line_height-text); + --input-text-size-s: var(--o-font_size-tip1); + --input-text-height-s: var(--o-line_height-tip1); + --input-text-size-m: var(--o-font_size-text); + --input-text-height-m: var(--o-line_height-text); + --input-text-size-l: var(--o-font_size-h4); + --input-text-height-l: var(--o-line_height-h4); --input-height-s: var(--o-size-s); --input-height-m: var(--o-size-m); @@ -11,16 +15,16 @@ --input-radius-l: var(--o-radius-s); --input-border: var(--o-color-info1); - --input-border_hover: var(--o-color-primary2); - --input-border_active: var(--o-color-primary3); - --input-border_disabled: var(--o-color-info1); + --input-border-hover: var(--o-color-primary2); + --input-border-active: var(--o-color-primary3); + --input-border-disabled: var(--o-color-info1); --input-bg: var(--o-color-bg1); - --input-bg_hover: var(--o-color-bg2); - --input-bg_disabled: var(--o-color-info4); + --input-bg-hover: var(--o-color-bg2); + --input-bg-disabled: var(--o-color-info4); --input-color: var(--o-color-text2); - --input-color_disabled: var(--o-color-text4); + --input-color-disabled: var(--o-color-text4); --input-icon-color: var(--o-color-text3); } diff --git a/packages/opendesign/src/components/option/style/var.scss b/packages/opendesign/src/components/option/style/var.scss index 71db472a..ed3568f9 100644 --- a/packages/opendesign/src/components/option/style/var.scss +++ b/packages/opendesign/src/components/option/style/var.scss @@ -1,7 +1,7 @@ .o-option { --option-color: var(--o-color-text2); - --option-color_hover: var(--o-color-text2_inverse); - --option-color_active: var(--o-color-text2_inverse); + --option-color_hover: var(--o-color-text2-inverse); + --option-color_active: var(--o-color-text2-inverse); --option-color_disabled: var(--o-color-text4); --option-bg: transparent; diff --git a/packages/opendesign/src/components/pagination/OPagination.vue b/packages/opendesign/src/components/pagination/OPagination.vue index 8e6ddb80..b52bf6a2 100644 --- a/packages/opendesign/src/components/pagination/OPagination.vue +++ b/packages/opendesign/src/components/pagination/OPagination.vue @@ -63,7 +63,17 @@ const totalPage = computed(() => Math.ceil(props.total / currentPageSize.value)) const pages = ref(getPagerItem(totalPage.value, currentPage.value, props.showPageCount)); const updateCurrentPage = (page: number) => { - currentPage.value = page; + if (isNaN(page)) { + return; + } + + if (page < 1) { + currentPage.value = 1; + } else if (page > totalPage.value) { + currentPage.value = totalPage.value; + } else { + currentPage.value = page; + } emits('update:currentPage', currentPage.value); emits('change', { @@ -91,7 +101,7 @@ const moreClick = (more: PagerItemT[0]) => { }; const goToChange = (val: string) => { - console.log(val); + updateCurrentPage(Number(val)); };