From 5687a81719b997fbf99c1019ab587045a142e3b4 Mon Sep 17 00:00:00 2001 From: "jlj05024111@163.com" Date: Wed, 6 Aug 2025 15:55:38 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0drtab=E6=B5=81?= =?UTF-8?q?=E5=B8=83=E5=B1=80=E9=94=9A=E7=82=B9=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + src/control/drtab/flow-drtab.scss | 56 +++++++++++++-- src/control/drtab/flow-drtab.tsx | 114 +++++++++++++++++++++++++----- 3 files changed, 148 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4cc9d5a..c8d50e23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ ### Changed +- 更新drtab流布局锚点样式 - 优化重复器表单样式 ## [0.7.41-alpha.16] - 2025-07-30 diff --git a/src/control/drtab/flow-drtab.scss b/src/control/drtab/flow-drtab.scss index 98453323..4b723927 100644 --- a/src/control/drtab/flow-drtab.scss +++ b/src/control/drtab/flow-drtab.scss @@ -3,7 +3,7 @@ height: 100%; overflow: hidden; background-color: getCssVar(color,bg,0);; - @include e('container'){ + @include e('container'){ height: 100%; overflow: auto; } @@ -39,6 +39,7 @@ display: flex; min-width: 200px; padding: getCssVar(spacing,base) 0; + font-size: getCssVar(font-size,regular); background-color: white; @include when('topleft'){ align-items: start; @@ -71,24 +72,67 @@ width: 100%; height: 32px; padding: 0 getCssVar(spacing,base); - font-family: '微软雅黑 Bold'; line-height: 32px; cursor: pointer; &:hover{ - color: getCssVar('color','primary-hover-text'); - background-color: getCssVar('color','primary'); + color: getCssVar('color','primary'); } @include when('active'){ - color: getCssVar('color','primary-hover-text'); - background-color: getCssVar('color','primary'); + position: relative; + color: getCssVar('color','primary'); + + &::before{ + position: absolute; + top: 0; + left: 0; + width:4px; + height: 100%; + content:''; + background-color: getCssVar('color','primary'); + border-radius: 2px; + } } } @include when('left'){ flex-direction:row; + overflow: auto; + @include e('container'){ + --navbarwidth:200; + + flex: 1 0; + width: calc(100% - var(--navbarwidth) - (2 * getCssVar(spacing,base))); + overflow: unset; + } + @include e('anchor-bar') { + position: sticky; + top: 0; + } + @include e('anchor-items'){ + &::-webkit-scrollbar{ + display: none; + } + } } @include when(right){ flex-direction: row-reverse; + overflow: auto; + @include e('container'){ + --navbarwidth:200; + + flex: 1 0; + width: calc(100% - var(--navbarwidth) - (2 * getCssVar(spacing,base))); + overflow: unset; + } + @include e('anchor-bar') { + position: sticky; + top: 0; + } + @include e('anchor-items'){ + &::-webkit-scrollbar{ + display: none; + } + } } } } \ No newline at end of file diff --git a/src/control/drtab/flow-drtab.tsx b/src/control/drtab/flow-drtab.tsx index 7c17769c..cb78f3ac 100644 --- a/src/control/drtab/flow-drtab.tsx +++ b/src/control/drtab/flow-drtab.tsx @@ -63,14 +63,32 @@ export const FlowDrtab = defineComponent({ // 导航栏位置 const navbarpos = ref(); // 导航栏宽度 - const navBarWidth = ref(200); + const navBarWidth: Ref = ref(200); // 观察滚动项元素id数组 - const observerIds: string[] = []; + const visibleViews: string[] = []; // 滚动高度 const scrollTop = ref(0); + // 导航栏 + const navbarRef = ref(); + // 已加载完成视图数量 + const completedViews: Ref = ref(0); + // 定时器引用 + const tempTimer = ref(); + // 点击时候最终激活的锚点 + const tempTarget = ref(); navbarpos.value = c.navbarpos; navBarWidth.value = c.navbarwidth; + // 所有可视视图 + const allVisibleViews = computed(() => { + return props.pagesstate.filter(item => { + const target = props.drtabpages.find(page => { + return page.id === item.tag; + }); + return target && !item.hidden; + }).length; + }); + // 所有导航项元素id const allNavTags = computed(() => { if (props.pagesstate) { @@ -94,41 +112,85 @@ export const FlowDrtab = defineComponent({ } }; + // 是否完全可见 + const isFullyVisible = (element: HTMLElement, container: HTMLElement) => { + // 获取容器和元素的位置信息 + const containerRect = container.getBoundingClientRect(); + const elementRect = element.getBoundingClientRect(); + + // 完全可见的四个条件 + return ( + // 元素顶部不超出容器顶部 + elementRect.top >= containerRect.top && + // 元素底部不超出容器底部 + elementRect.bottom <= containerRect.bottom && + // 元素左侧不超出容器左侧 + elementRect.left >= containerRect.left && + // 元素右侧不超出容器右侧 + elementRect.right <= containerRect.right + ); + }; + + // 滚动到目标锚点 + const scrollToTargetNavItem = () => { + const anchor = document.getElementById(`navbar_${navtag.value}`); + if ( + anchor && + navbarRef.value && + !isFullyVisible(anchor, navbarRef.value) + ) { + anchor.scrollIntoView({ behavior: 'smooth' }); + } + }; + // 计算当前选中激活项 const computeSelectItem = () => { - if (observerIds.length > 0) { - navtag.value = observerIds[0]; + if (visibleViews.length > 0) { + navtag.value = visibleViews[0]; + } + if (tempTarget.value) { + clearTimeout(tempTimer.value); + tempTimer.value = setTimeout(() => { + navtag.value = tempTarget.value; + scrollToTargetNavItem(); + tempTarget.value = ''; + }, 200); + } else { + scrollToTargetNavItem(); } }; // 创建 Intersection Observer 对象,用来观察滚动元素 const observer = new IntersectionObserver( (entries: IntersectionObserverEntry[]) => { + if (allVisibleViews.value !== completedViews.value) { + return; + } entries.forEach(entry => { if (entry.isIntersecting) { // 当元素进入视口时执行的操作 if (entry.target && entry.target.id) { - if (observerIds.length > 0) { + if (visibleViews.length > 0) { const curIndex = allNavTags.value?.findIndex( tag => tag === entry.target.id, ); const index = allNavTags.value?.findIndex( - tag => tag === observerIds[0], + tag => tag === visibleViews[0], ); if (curIndex < index) { - observerIds.unshift(entry.target.id); + visibleViews.unshift(entry.target.id); } else { - observerIds.push(entry.target.id); + visibleViews.push(entry.target.id); } } else { - observerIds.push(entry.target.id); + visibleViews.push(entry.target.id); } } } else if (entry.target && entry.target.id) { // 当元素离开视口时执行的操作 - const index = observerIds.indexOf(entry.target.id); + const index = visibleViews.indexOf(entry.target.id); if (index >= 0) { - observerIds.splice(index, 1); + visibleViews.splice(index, 1); } } }); @@ -141,6 +203,10 @@ export const FlowDrtab = defineComponent({ const target = props.drtabpages.find(page => { return page.id === item.tag; }); + completedViews.value += 1; + if (completedViews.value === allVisibleViews.value && !navtag.value) { + navtag.value = `${target?.appViewId}_${props.pagesstate[0].tag}`; + } const el = document.getElementById(`${target?.appViewId}_${item.tag}`); if (el) { observer.observe(el); @@ -212,11 +278,13 @@ export const FlowDrtab = defineComponent({ const target = props.drtabpages.find(page => { return page.id === item.tag; }); + tempTarget.value = `${target?.appViewId}_${item.tag}`; const el = document.getElementById(`${target?.appViewId}_${item.tag}`); if (el) { - el.scrollIntoView({ - behavior: 'smooth', - }); + el.scrollIntoView({ behavior: 'smooth' }); + if (visibleViews.includes(tempTarget.value)) { + navtag.value = tempTarget.value; + } } }; @@ -229,11 +297,19 @@ export const FlowDrtab = defineComponent({ class={[ns.e('anchor-bar'), ns.is(navbarpos.value, true)]} style={{ width: `${navBarWidth.value}px` }} > -
+
{ + navbarRef.value = el; + }} + > {props.pagesstate.map(item => { const target = props.drtabpages.find(page => { return page.id === item.tag; }); + if (!target || item.hidden) { + return null; + } return (
onClickBar(item)} > {item.caption} @@ -255,6 +332,7 @@ export const FlowDrtab = defineComponent({ } }; + // 处理滚动事件,记录滚动距离 const handleScroll = () => { const el = document.getElementById(`${uuid}`); if (el) { @@ -268,6 +346,7 @@ export const FlowDrtab = defineComponent({ uuid, navbarpos, onViewMounted, + navBarWidth, calcStyle, renderAnchorBar, handleScroll, @@ -331,12 +410,13 @@ export const FlowDrtab = defineComponent({ this.ns.is('right', this.navbarpos?.includes('right')), this.ns.is('enable-anchor', this.c.enableAnchor), ]} + onScroll={this.handleScroll} + id={this.uuid} > {this.renderAnchorBar()}
{tabs}
-- Gitee From 5b1c387d2f290b1dc7a30ed357c26e84b3721eba Mon Sep 17 00:00:00 2001 From: "jlj05024111@163.com" Date: Wed, 6 Aug 2025 15:57:34 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/control/drtab/flow-drtab.scss | 137 ++++++++++++++++++------------ 1 file changed, 83 insertions(+), 54 deletions(-) diff --git a/src/control/drtab/flow-drtab.scss b/src/control/drtab/flow-drtab.scss index 4b723927..55e4c35e 100644 --- a/src/control/drtab/flow-drtab.scss +++ b/src/control/drtab/flow-drtab.scss @@ -1,135 +1,164 @@ -@include b('flow-drtab'){ +@include b('flow-drtab') { width: 100%; height: 100%; overflow: hidden; - background-color: getCssVar(color,bg,0);; - @include e('container'){ + background-color: getCssVar(color, bg, 0); + ; + + @include e('container') { height: 100%; overflow: auto; } - @include e('tab-item'){ - background-color: getCssVar(color,bg,1); - border-radius: getCssVar(border-radius,medium); - @include m('label'){ - padding: getCssVar(spacing,base); - font-size: getCssVar(font-size,header-5); - border-bottom: 1px solid getCssVar(color,fill,1); + + @include e('tab-item') { + background-color: getCssVar(color, bg, 1); + border-radius: getCssVar(border-radius, medium); + + @include m('label') { + padding: getCssVar(spacing, base); + font-size: getCssVar(font-size, header-5); + border-bottom: 1px solid getCssVar(color, fill, 1); } - @include m('tab-view'){ - padding:getCssVar(spacing,tight) 0; + + @include m('tab-view') { + padding: getCssVar(spacing, tight) 0; } - & + .#{bem(flow-drtab,tab-item)}{ - margin-top: getCssVar(spacing,base);; + + &+.#{bem(flow-drtab,tab-item)} { + margin-top: getCssVar(spacing, base); + ; } } - @include e('counter'){ - font-size: getCssVar(font-size,regular); + + @include e('counter') { + font-size: getCssVar(font-size, regular); text-align: center; } - .#{bem('flow-drtab')}{ + + .#{bem('flow-drtab')} { background-color: inherit; } - @include when('enable-anchor'){ - display:flex; - gap: getCssVar(spacing,base); - @include e('container'){ + + @include when('enable-anchor') { + display: flex; + gap: getCssVar(spacing, base); + + @include e('container') { flex: 1; } - @include e('anchor-bar'){ + + @include e('anchor-bar') { display: flex; min-width: 200px; - padding: getCssVar(spacing,base) 0; - font-size: getCssVar(font-size,regular); + padding: getCssVar(spacing, base) 0; + font-size: getCssVar(font-size, regular); background-color: white; - @include when('topleft'){ + + @include when('topleft') { align-items: start; } - @include when('bottomleft'){ + + @include when('bottomleft') { align-items: end; } - @include when('topright'){ + + @include when('topright') { flex-direction: row-reverse; align-items: start; } - @include when('bottomright'){ + + @include when('bottomright') { flex-direction: row-reverse; align-items: end; } - @include when('middleleft'){ + + @include when('middleleft') { align-items: center; } - @include when(middleright){ + + @include when(middleright) { flex-direction: row-reverse; align-items: center; } } - @include e('anchor-items'){ + + @include e('anchor-items') { width: 100%; max-height: 100%; overflow: auto; } - @include e('anchor-item'){ + + @include e('anchor-item') { width: 100%; height: 32px; - padding: 0 getCssVar(spacing,base); + padding: 0 getCssVar(spacing, base); line-height: 32px; cursor: pointer; - &:hover{ - color: getCssVar('color','primary'); + &:hover { + color: getCssVar('color', 'primary'); } - @include when('active'){ + + @include when('active') { position: relative; - color: getCssVar('color','primary'); + color: getCssVar('color', 'primary'); - &::before{ + &::before { position: absolute; top: 0; left: 0; - width:4px; + width: 4px; height: 100%; - content:''; - background-color: getCssVar('color','primary'); + content: ''; + background-color: getCssVar('color', 'primary'); border-radius: 2px; } } } - @include when('left'){ - flex-direction:row; + + @include when('left') { + flex-direction: row; overflow: auto; - @include e('container'){ - --navbarwidth:200; + + @include e('container') { + --navbarwidth: 200; flex: 1 0; - width: calc(100% - var(--navbarwidth) - (2 * getCssVar(spacing,base))); + width: calc(100% - var(--navbarwidth) - (2 * getCssVar(spacing, base))); overflow: unset; } + @include e('anchor-bar') { position: sticky; top: 0; } - @include e('anchor-items'){ - &::-webkit-scrollbar{ + + @include e('anchor-items') { + &::-webkit-scrollbar { display: none; } } } - @include when(right){ + + @include when(right) { flex-direction: row-reverse; overflow: auto; - @include e('container'){ - --navbarwidth:200; + + @include e('container') { + --navbarwidth: 200; flex: 1 0; - width: calc(100% - var(--navbarwidth) - (2 * getCssVar(spacing,base))); + width: calc(100% - var(--navbarwidth) - (2 * getCssVar(spacing, base))); overflow: unset; } + @include e('anchor-bar') { position: sticky; top: 0; } - @include e('anchor-items'){ - &::-webkit-scrollbar{ + + @include e('anchor-items') { + &::-webkit-scrollbar { display: none; } } -- Gitee From 36888bdb898b9dc37fad640aa7a6979bfb127e5f Mon Sep 17 00:00:00 2001 From: "jlj05024111@163.com" Date: Wed, 6 Aug 2025 17:28:54 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E6=97=A5?= =?UTF-8?q?=E5=8E=86=E7=94=A8=E6=88=B7=E8=87=AA=E5=AE=9A=E4=B9=89=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E5=9B=BD=E9=99=85=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../calendar/components/custom-calendar/custom-calendar.tsx | 4 ++-- src/locale/en/index.ts | 1 + src/locale/zh-CN/index.ts | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8d50e23..99a60d2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ ### Changed +- 更新日历用户自定义模式国际化 - 更新drtab流布局锚点样式 - 优化重复器表单样式 diff --git a/src/control/calendar/components/custom-calendar/custom-calendar.tsx b/src/control/calendar/components/custom-calendar/custom-calendar.tsx index 683731da..fd5deae4 100644 --- a/src/control/calendar/components/custom-calendar/custom-calendar.tsx +++ b/src/control/calendar/components/custom-calendar/custom-calendar.tsx @@ -210,7 +210,7 @@ export const CustomCalendar = defineComponent({
{weekRange .map(_date => { - return dayjs(new Date(_date)).format('YYYY年MM月DD日'); + return dayjs(new Date(_date)).format('YYYY-MM-DD'); }) .join(' ~ ')}
@@ -224,7 +224,7 @@ export const CustomCalendar = defineComponent({ placeholder={ibiz.i18n.t( 'control.calendar.calendarUser.selectWeekRange', )} - format='YYYY年第ww周' + format={ibiz.i18n.t('control.calendar.calendarUser.weekFormat')} >
diff --git a/src/locale/en/index.ts b/src/locale/en/index.ts index aafafc32..e0dbc41b 100644 --- a/src/locale/en/index.ts +++ b/src/locale/en/index.ts @@ -389,6 +389,7 @@ export default { sunday: 'Sun', }, selectWeekRange: 'Select week range', + weekFormat: 'ww [Week] of YYYY', }, }, chart: { diff --git a/src/locale/zh-CN/index.ts b/src/locale/zh-CN/index.ts index 8545bb00..064e0387 100644 --- a/src/locale/zh-CN/index.ts +++ b/src/locale/zh-CN/index.ts @@ -351,6 +351,7 @@ export default { sunday: '周日', }, selectWeekRange: '选择周范围', + weekFormat: 'YYYY年第ww周', }, }, chart: { -- Gitee