Merge pull request #11912 from element-plus/dev

D2M
This commit is contained in:
Jeremy
2023-03-08 23:31:03 +08:00
committed by GitHub
16 changed files with 74 additions and 26 deletions

View File

@@ -1,5 +1,16 @@
## Changelog
### 2.2.36
_2023-03-08_
#### Bug fixes
- Components [select] Filter duplicate emits of "update options" (#11884 by @godxiaoji)
- Components [table] useZIndex is called outside setup (#11895 by @Mario34) (#11900)
- Components [select] filter all ElOption item labels (#11909 by @godxiaoji)
- Components [global-config] global injection (#11899 by @jw-foss)
### 2.2.35
_2023-03-07_

View File

@@ -83,6 +83,7 @@ const CustomizedHeader: FunctionalComponent<
groupCells.push(
<div
class="flex items-center justify-center custom-header-cell"
role="columnheader"
style={{
...cells[columnIndex].props!.style,
width: `${width}px`,

View File

@@ -61,6 +61,7 @@ export function useGlobalComponentSettings(
computed(() => config.value?.zIndex || defaultInitialZIndex)
)
const size = computed(() => unref(sizeFallback) || config.value?.size || '')
provideGlobalConfig(computed(() => unref(config) || {}))
return {
ns,

View File

@@ -5,7 +5,6 @@
:z-index="zIndex"
:overlay-class="[ns.is('message-box'), modalClass]"
:mask="modal"
is-global
>
<div
role="dialog"

View File

@@ -1,7 +1,6 @@
import { createVNode, defineComponent, h, renderSlot } from 'vue'
import { PatchFlags, buildProps, definePropType } from '@element-plus/utils'
import { useNamespace, useSameTarget } from '@element-plus/hooks'
import { useGlobalComponentSettings } from '@element-plus/components/config-provider'
import type { CSSProperties, ExtractPropTypes } from 'vue'
import type { ZIndexProperty } from 'csstype'
@@ -25,9 +24,6 @@ export const overlayProps = buildProps({
zIndex: {
type: definePropType<ZIndexProperty>([String, Number]),
},
isGlobal: {
type: Boolean,
},
} as const)
export type OverlayProps = ExtractPropTypes<typeof overlayProps>
@@ -47,9 +43,7 @@ export default defineComponent({
setup(props, { slots, emit }) {
// No reactivity on this prop because when its rendering with a global
// component, this will be a constant flag.
const ns = props.isGlobal
? useGlobalComponentSettings(BLOCK).ns
: useNamespace(BLOCK)
const ns = useNamespace(BLOCK)
const onMaskClick = (e: MouseEvent) => {
emit('click', e)

View File

@@ -1,26 +1,55 @@
import { defineComponent } from 'vue'
import type { Component, VNode } from 'vue'
import { isFunction, isString } from '@element-plus/utils'
import type { Component, VNode, VNodeNormalizedChildren } from 'vue'
export default defineComponent({
name: 'ElOptions',
emits: ['update-options'],
setup(_, { slots, emit }) {
let cachedOptions: any[] = []
function isSameOptions(a: any[], b: any[]) {
if (a.length !== b.length) return false
for (const [index] of a.entries()) {
if (a[index] != b[index]) {
return false
}
}
return true
}
return () => {
const children = slots.default?.()!
const filteredOptions: any[] = []
function filterOptions(children?: VNodeNormalizedChildren) {
if (!Array.isArray(children)) return
;(children as VNode[]).forEach((item) => {
const name = ((item?.type || {}) as Component)?.name
if (name === 'ElOptionGroup') {
filterOptions(
!isString(item.children) &&
!Array.isArray(item.children) &&
isFunction(item.children?.default)
? item.children?.default()
: item.children
)
} else if (name === 'ElOption') {
filteredOptions.push(item.props?.label)
} else if (Array.isArray(item.children)) {
filterOptions(item.children)
}
})
}
if (children.length) {
const options = (children![0]?.children as VNode[])?.[0]?.children || []
if (options && options.length) {
const filteredOptions = (options as VNode[])
.filter(
(item: VNode) =>
((item?.type || {}) as Component)?.name === 'ElOption'
)
.map((item: VNode) => item.props?.label)
filterOptions(children![0]?.children)
}
emit('update-options', filteredOptions)
}
if (!isSameOptions(filteredOptions, cachedOptions)) {
cachedOptions = filteredOptions
emit('update-options', filteredOptions)
}
return children

View File

@@ -36,7 +36,7 @@ const TableV2HeaderRow = defineComponent({
}
return (
<div class={props.class} style={style}>
<div class={props.class} style={style} role="row">
{Cells}
</div>
)

View File

@@ -94,7 +94,12 @@ const TableV2Header = defineComponent({
if (props.height <= 0) return
return (
<div ref={headerRef} class={props.class} style={unref(headerStyle)}>
<div
ref={headerRef}
class={props.class}
style={unref(headerStyle)}
role="rowgroup"
>
<div style={unref(rowStyle)} class={ns.e('header')}>
{renderDynamicRows()}
{renderFixedRows()}

View File

@@ -210,6 +210,7 @@ const TableV2Row = defineComponent({
ref={rowRef}
class={props.class}
style={_measured ? style : exceptHeightStyle}
role="row"
{...attrs}
{...unref(eventHandlers)}
>
@@ -224,6 +225,7 @@ const TableV2Row = defineComponent({
ref={rowRef}
class={props.class}
style={style}
role="row"
{...unref(eventHandlers)}
>
{ColumnCells}

View File

@@ -122,7 +122,7 @@ const CellRenderer: FunctionalComponent<CellRendererProps> = (
}
return (
<div class={kls} style={cellStyle} {...extraCellProps}>
<div class={kls} style={cellStyle} {...extraCellProps} role="cell">
{IconOrPlaceholder}
{Cell}
</div>

View File

@@ -82,7 +82,7 @@ const HeaderCellRenderer: FunctionalComponent<HeaderCellRendererProps> = (
// For now we don't deliver resizable column feature since it has some UX issue.
return (
<div {...cellWrapperProps}>
<div {...cellWrapperProps} role="columnheader">
{Cell}
{sortable && (

View File

@@ -228,6 +228,7 @@ const TableGrid = defineComponent({
width={width}
height={unref(gridHeight)}
class={ns.e('body')}
role="rowgroup"
scrollbarStartGap={scrollbarStartGap}
scrollbarEndGap={scrollbarEndGap}
scrollbarAlwaysOn={scrollbarAlwaysOn}

View File

@@ -2,6 +2,7 @@
import { h, inject, ref } from 'vue'
import { debounce } from 'lodash-unified'
import { getStyle, hasClass } from '@element-plus/utils'
import { useZIndex } from '@element-plus/hooks'
import { createTablePopper, getCell, getColumnByCell } from '../util'
import { TABLE_INJECTION_KEY } from '../tokens'
import type { TableColumnCtx } from '../table-column/defaults'
@@ -12,6 +13,7 @@ function useEvents<T>(props: Partial<TableBodyProps<T>>) {
const parent = inject(TABLE_INJECTION_KEY)
const tooltipContent = ref('')
const tooltipTrigger = ref(h('div'))
const { nextZIndex } = useZIndex()
const handleEvent = (event: Event, row: T, name: string) => {
const table = parent
const cell = getCell(event)
@@ -112,6 +114,7 @@ function useEvents<T>(props: Partial<TableBodyProps<T>>) {
parent?.refs.tableWrapper,
cell,
cell.innerText || cell.textContent,
nextZIndex,
tooltipOptions
)
}

View File

@@ -9,7 +9,7 @@ import {
isObject,
throwError,
} from '@element-plus/utils'
import { useDelayedToggle, useZIndex } from '@element-plus/hooks'
import { useDelayedToggle } from '@element-plus/hooks'
import type { PopperInstance } from '@element-plus/components/popper'
import type { Nullable } from '@element-plus/utils'
import type { TableColumnCtx } from './table-column/defaults'
@@ -331,6 +331,7 @@ export function createTablePopper(
parentNode: HTMLElement | undefined,
trigger: HTMLElement,
popperContent: string,
nextZIndex: () => number,
tooltipOptions?: TableOverflowTooltipOptions
) {
// TODO transition
@@ -341,7 +342,6 @@ export function createTablePopper(
} as TableOverflowTooltipOptions,
tooltipOptions
)
const { nextZIndex } = useZIndex()
const ns = parentNode?.dataset.prefix
const scrollContainer = parentNode?.querySelector(`.${ns}-scrollbar__wrap`)
function renderContent(): HTMLDivElement {

View File

@@ -639,6 +639,7 @@ const createGrid = ({
{
key: 0,
class: ns.e('wrapper'),
role: props.role,
},
[
h(

View File

@@ -158,6 +158,7 @@ export const virtualizedGridProps = buildProps({
vScrollbarSize: scrollbarSize,
scrollbarStartGap: startGap,
scrollbarEndGap: endGap,
role: String,
...virtualizedProps,
} as const)