Skip to content

Commit

Permalink
Merge pull request #11882 from element-plus/dev
Browse files Browse the repository at this point in the history
D2M
  • Loading branch information
jw-foss committed Mar 7, 2023
2 parents c75ba99 + a83fd9b commit c6e4f4d
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 30 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.en-US.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
## Changelog

### 2.2.35

_2023-03-07_

#### Bug fixes

- Components [select] console warning (#11868 by @jw-foss)
- Components [global-config] (#11866 by @jw-foss)
- Components [overlay] namespace issue (#11881 by @jw-foss)

### 2.2.34

_2023-03-06_
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import ConfigProvider from '../src/config-provider'
import type { PropType } from 'vue'
import type { VueWrapper } from '@vue/test-utils'
import type { Language } from '@element-plus/locale'
import type { ComponentSize } from '@element-plus/constants'
import type { ConfigProviderProps } from '../src/config-provider-props'

const TestComp = defineComponent({
Expand Down Expand Up @@ -244,20 +245,27 @@ describe('config-provider', () => {
})

describe('global component configs', () => {
it('should use global configured settings', () => {
it('should use global configured settings', async () => {
const namespace = 'test'
const locale = Chinese
const zIndex = 1000
const block = 'button'
const size = 'large'
const receiverRef = ref()
const fallback = ref('' as ComponentSize)
const ReceiverComponent = defineComponent({
setup() {
receiverRef.value = useGlobalComponentSettings(block)
receiverRef.value = useGlobalComponentSettings(block, fallback)
},
template: '<div></div>',
})
mount(() => (
<ConfigProvider zIndex={zIndex} locale={locale} namespace={namespace}>
<ConfigProvider
zIndex={zIndex}
locale={locale}
namespace={namespace}
size={size}
>
<ReceiverComponent />
</ConfigProvider>
))
Expand All @@ -266,6 +274,12 @@ describe('config-provider', () => {
expect(vm.ns.namespace).toBe(namespace)
expect(vm.locale.locale).toBe(locale)
expect(vm.zIndex.currentZIndex).toBeGreaterThanOrEqual(zIndex)
expect(vm.size).toBe(size)

fallback.value = 'small'
await nextTick()

expect(vm.size).toBe('small')
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ export function useGlobalConfig(
}

// for components like `ElMessage` `ElNotification` `ElMessageBox`.
export function useGlobalComponentSettings(block: string) {
export function useGlobalComponentSettings(
block: string,
sizeFallback?: MaybeRef<ConfigProviderContext['size']>
) {
const config = useGlobalConfig()

const ns = useNamespace(
Expand All @@ -57,11 +60,13 @@ export function useGlobalComponentSettings(block: string) {
const zIndex = useZIndex(
computed(() => config.value?.zIndex || defaultInitialZIndex)
)
const size = computed(() => unref(sizeFallback) || config.value?.size || '')

return {
ns,
locale,
zIndex,
size,
}
}

Expand Down
19 changes: 11 additions & 8 deletions packages/components/message-box/src/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
:z-index="zIndex"
:overlay-class="[ns.is('message-box'), modalClass]"
:mask="modal"
is-global
>
<div
role="dialog"
Expand Down Expand Up @@ -169,7 +170,6 @@ import {
useSameTarget,
} from '@element-plus/hooks'
import ElInput from '@element-plus/components/input'
import { useFormSize } from '@element-plus/components/form'
import { ElOverlay } from '@element-plus/components/overlay'
import {
TypeComponents,
Expand Down Expand Up @@ -249,7 +249,15 @@ export default defineComponent({
emits: ['vanish', 'action'],
setup(props, { emit }) {
// const popup = usePopup(props, doClose)
const { locale, zIndex, ns } = useGlobalComponentSettings('message-box')
const {
locale,
zIndex,
ns,
size: btnSize,
} = useGlobalComponentSettings(
'message-box',
computed(() => props.buttonSize)
)
const { t } = locale
const { nextZIndex } = zIndex
Expand Down Expand Up @@ -304,11 +312,6 @@ export default defineComponent({
const contentId = useId()
const inputId = useId()
const btnSize = useFormSize(
computed(() => props.buttonSize),
{ prop: true, form: true, formItem: true }
)
const iconComponent = computed(
() => state.icon || TypeComponentsMap[state.type] || ''
)
Expand Down Expand Up @@ -469,7 +472,7 @@ export default defineComponent({
// locks the screen to prevent scroll
if (props.lockScroll) {
useLockscreen(visible)
useLockscreen(visible, { ns })
}
// restore to prev active element.
Expand Down
24 changes: 24 additions & 0 deletions packages/components/overlay/__tests__/overlay.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { nextTick, ref } from 'vue'
import { mount } from '@vue/test-utils'
import { describe, expect, test } from 'vitest'
import { ElMessageBox } from '@element-plus/components/message-box'
import ConfigProvider from '@element-plus/components/config-provider'
import Overlay from '../src/overlay'

const AXIOM = 'Rem is the best girl'
Expand Down Expand Up @@ -42,4 +44,26 @@ describe('Overlay.vue', () => {

expect(wrapper.find(selector).exists()).toBe(true)
})

test('global', async () => {
const testNamespace = 'test'
const callout = () => {
ElMessageBox.prompt('Title', 'Description')
}
const wrapper = mount(() => {
return (
<ConfigProvider namespace={testNamespace}>
<button onClick={callout}>{AXIOM}</button>
</ConfigProvider>
)
})

expect(document.body.querySelector(`.${testNamespace}-overlay`)).toBeNull()
await wrapper.find('button').trigger('click')
await nextTick()

expect(
document.body.querySelector(`.${testNamespace}-overlay`)
).toBeDefined()
})
})
12 changes: 11 additions & 1 deletion packages/components/overlay/src/overlay.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
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'
Expand All @@ -24,6 +25,9 @@ export const overlayProps = buildProps({
zIndex: {
type: definePropType<ZIndexProperty>([String, Number]),
},
isGlobal: {
type: Boolean,
},
} as const)
export type OverlayProps = ExtractPropTypes<typeof overlayProps>

Expand All @@ -32,14 +36,20 @@ export const overlayEmits = {
}
export type OverlayEmits = typeof overlayEmits

const BLOCK = 'overlay'

export default defineComponent({
name: 'ElOverlay',

props: overlayProps,
emits: overlayEmits,

setup(props, { slots, emit }) {
const ns = useNamespace('overlay')
// 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 onMaskClick = (e: MouseEvent) => {
emit('click', e)
Expand Down
29 changes: 29 additions & 0 deletions packages/components/select/src/options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { defineComponent } from 'vue'

import type { Component, VNode } from 'vue'

export default defineComponent({
name: 'ElOptions',
emits: ['update-options'],
setup(_, { slots, emit }) {
return () => {
const children = slots.default?.()!

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)

emit('update-options', filteredOptions)
}
}

return children
}
},
})
12 changes: 11 additions & 1 deletion packages/components/select/src/select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,9 @@
]"
>
<el-option v-if="showNewOption" :value="query" :created="true" />
<slot />
<el-options @update-options="onOptionsRendered">
<slot />
</el-options>
</el-scrollbar>
<template
v-if="
Expand Down Expand Up @@ -296,6 +298,7 @@ import ElOption from './option.vue'
import ElSelectMenu from './select-dropdown.vue'
import { useSelect, useSelectStates } from './useSelect'
import { selectKey } from './token'
import ElOptions from './options'
import type { PropType } from 'vue'
import type { ComponentSize } from '@element-plus/constants'
Expand All @@ -309,6 +312,7 @@ export default defineComponent({
ElInput,
ElSelectMenu,
ElOption,
ElOptions,
ElTag,
ElScrollbar,
ElTooltip,
Expand Down Expand Up @@ -429,6 +433,7 @@ export default defineComponent({
const { t } = useLocale()
const states = useSelectStates(props)
const {
optionList,
optionsArray,
selectSize,
readonly,
Expand Down Expand Up @@ -591,7 +596,12 @@ export default defineComponent({
return tooltipRef.value?.popperRef?.contentRef
})
const onOptionsRendered = (v) => {
optionList.value = v
}
return {
onOptionsRendered,
tagInMultiLine,
prefixWidth,
selectSize,
Expand Down
14 changes: 1 addition & 13 deletions packages/components/select/src/useSelect.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
// @ts-nocheck
import {
computed,
getCurrentInstance,
nextTick,
onUpdated,
reactive,
ref,
shallowRef,
Expand Down Expand Up @@ -98,20 +96,9 @@ export const useSelect = (props, states: States, ctx) => {
const hoverOption = ref(-1)
const queryChange = shallowRef<QueryChangeCtx>({ query: '' })
const groupQueryChange = shallowRef('')
const instance = getCurrentInstance()
const optionList = ref<string[]>([])
let originClientHeight = 0

onUpdated(() => {
const childrens = instance?.slots.default?.()[0].children
if (childrens && childrens.length) {
const options = childrens
.filter((item) => item.type.name === 'ElOption')
.map((item) => item.props.label)
optionList.value = options
}
})

const { form, formItem } = useFormItem()

const readonly = computed(
Expand Down Expand Up @@ -913,6 +900,7 @@ export const useSelect = (props, states: States, ctx) => {
}

return {
optionList,
optionsArray,
selectSize,
handleResize,
Expand Down
30 changes: 29 additions & 1 deletion packages/hooks/__tests__/use-lockscreen.test.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { defineComponent, nextTick, onMounted, ref } from 'vue'
import { computed, defineComponent, nextTick, onMounted, ref } from 'vue'
import { mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import { hasClass } from '@element-plus/utils'

import { useLockscreen } from '../use-lockscreen'
import { useNamespace } from '../use-namespace'

const kls = 'el-popup-parent--hidden'

Expand Down Expand Up @@ -52,4 +53,31 @@ describe('useLockscreen', () => {
expect(hasClass(document.body, kls)).toBe(false)
}, 250)
})

it('should render a different namespace than the given one', async () => {
const namespace = 'test'
const wrapper = mount({
setup() {
const ns = useNamespace(
'lock',
computed(() => namespace)
)
const trigger = ref(false)
useLockscreen(trigger, { ns })
onMounted(() => {
trigger.value = true
})
return () => () => undefined
},
})

mount(wrapper)

await nextTick()
expect(hasClass(document.body, `${namespace}-lock-parent--hidden`)).toBe(
true
)

wrapper.unmount()
})
})

0 comments on commit c6e4f4d

Please sign in to comment.