mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
Merge branch 'dev' into fix/upload-photo-wall
This commit is contained in:
25
.github/workflows/welcome.yml
vendored
Normal file
25
.github/workflows/welcome.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: PR Open Greeting
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
pr-open-greeting:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions-cool/check-user-permission@v2
|
||||
id: isTeamMember
|
||||
with:
|
||||
require: 'write'
|
||||
- uses: actions-awesome/pr-helper@1.0.15
|
||||
if: steps.isTeamMember.outputs.require-result == 'false'
|
||||
with:
|
||||
actions: 'add-assignees, add-reviewers, greeting, add-labels'
|
||||
assignees: 'element-plus/backers'
|
||||
reviewers: 'element-plus/backers'
|
||||
labels: 'Contribution::Community'
|
||||
token: ${{ github.token }}
|
||||
pr-number: ${{ github.event.pull_request.number }}
|
||||
greeting-message: 'Hello %user%, thank you for contributing to %repo%, please see our [guideline](%guideline%) to see how to make contribution'
|
||||
greeting-guideline-address: 'https://github.com/element-plus/element-plus/blob/dev/CONTRIBUTING.md'
|
||||
@@ -1,4 +1,58 @@
|
||||
## Changelog
|
||||
|
||||
### 2.0.6
|
||||
|
||||
_2022-03-11_
|
||||
|
||||
#### Features
|
||||
|
||||
- [el-table] support always show scrollbar & get selection rows (#6469 by @msidolphin)
|
||||
- Extract eslint config to separate package (#6495 by @sxzz)
|
||||
- Export dayjs instance, closes #6498 (#6517 by @sxzz)
|
||||
- Components [select]add collapse-tags-tooltip (#6245 by @Alanscut)
|
||||
- Components [select-v2]add collapse-tags-tooltip (#6532 by @Alanscut)
|
||||
- Components [cascader]add collapse-tags-tooltip (#6331 by @Alanscut)
|
||||
|
||||
#### Bug fixes
|
||||
|
||||
- Deps update all non-major dependencies (#6448 by @renovate[bot])
|
||||
- Components [el-select] optimize prefix size & selected style (#6267 by @msidolphin)
|
||||
- Components [el-table] defaultSort not working (#6322 by @msidolphin)
|
||||
- [el-table] fixed columns display when horizontal cannot scroll (#6320 by @msidolphin)
|
||||
- Components [el-checkbox] modelValue (#6168 by @gjfei) (#6169)
|
||||
- Components[select] (#6446 by @gjfei) (#6474)
|
||||
- Components [el-collapse] collapse item key pressing jumping (#6462 by @JeremyWuuuuu)
|
||||
- Components [message] offset error (#6497 by @Alanscut)
|
||||
- Components[select] namespace (#6486 by @gjfei)
|
||||
- Components el-select-allow-dynamically-update-options (#6473 by @gjfei)
|
||||
- Components [el-tooltip] close the dropdown after set disabled (#6467 by @Alanscut)
|
||||
- Docs improve component typings (#6524 by @sxzz)
|
||||
- Workflow coverage (#6518 by @sxzz)
|
||||
- Components [upload] fileList prop should sync uploadFiles (#6492 by @exherb)
|
||||
- Components [rate] fix disbaledVoidIcon typo (#6456 by @Shana-AE)
|
||||
- Components [select] display error when setting persistent to false (#6522 by @Alanscut)
|
||||
- Components [el-input] pass input-style props to input-wrapper (#6506 by @zt123123)
|
||||
- Components [el-table] escape special html characters (#6520 by @msidolphin)
|
||||
- Components [autocomplete] fix shaking at first open (#6342 by @freedomlang)
|
||||
- Components [el-upload] jitter when remove file in the list (#6505 by @msidolphin)
|
||||
- Components [el-menu] icon is not to the right of the text (#6268 by @Alanscut)
|
||||
- Test(components): [select] click icon twice (#6471 by @Alanscut)
|
||||
- Chore(project): add escape-html as dependency for main entry (#6534 by @JeremyWuuuuu)
|
||||
|
||||
#### Refactors
|
||||
|
||||
- Components!: refactor form (#5401 by @sxzz)
|
||||
- Components [row] refactor (#6354 by @sxzz)
|
||||
- Docs [form] improve docs and typings (#6447 by @sxzz)
|
||||
- Improve build dts (#6457 by @sxzz)
|
||||
- Components [cascader,cascader-panel] add namespace (#5589 by @gjfei)
|
||||
- Components [breadcrumb] switch to script-setup syntax (#6073 by @buqiyuan)
|
||||
- Theme-chalk message css var & add getCssVarName (#6488 by @YunYouJun)
|
||||
- Utils remove isFF (#6507 by @btea)
|
||||
- Theme-chalk [upload] use bem rewrite upload scss & fix bugs (#6508 by @YunYouJun)
|
||||
- Perf(components): [el-table] optimize the performance of expand rows (#6480 by @msidolphin)
|
||||
- Style(components): rename disabled to is-disabled (#6475 by @freedomlang)
|
||||
|
||||
|
||||
### 2.0.5
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ Don't do:
|
||||
</template>
|
||||
```
|
||||
|
||||
:::demo When using multiple selection, all selected tags will display by default, You can set `collapse-tags = true` to fold selected tags.
|
||||
:::demo When using multiple selection, all selected tags will display by default. You can set `collapse-tags = true` to fold selected tags. You can check them when mouse hover collapse text by using `collapse-tags-tooltip` attribute.
|
||||
|
||||
cascader/multiple-selection
|
||||
|
||||
@@ -149,6 +149,7 @@ cascader/panel
|
||||
| clearable | whether selected value can be cleared | boolean | — | false |
|
||||
| show-all-levels | whether to display all levels of the selected value in the input | boolean | — | true |
|
||||
| collapse-tags | whether to collapse tags in multiple selection mode | boolean | - | false |
|
||||
| collapse-tags-tooltip | whether show all selected tags when mouse hover text of collapse-tags. To use this, `collapse-tags` must be true | boolean | - | false |
|
||||
| separator | option label separator | string | — | ' / ' |
|
||||
| filterable | whether the options can be searched | boolean | — | — |
|
||||
| filter-method | customize search logic, the first parameter is `node`, the second is `keyword`, and need return a boolean value indicating whether it hits. | function(node, keyword) | - | - |
|
||||
|
||||
@@ -85,7 +85,7 @@ import { ElMessage } from 'element-plus'
|
||||
|
||||
In this case you should call `ElMessage(options)`. We have also registered methods for different types, e.g. `ElMessage.success(options)`. You can call `ElMessage.closeAll()` to manually close all the instances.
|
||||
|
||||
## App context inheritance <el-tag>> 2.0.2</el-tag>
|
||||
## App context inheritance <el-tag> >= 2.0.3</el-tag>
|
||||
|
||||
Now message accepts a `context` as second parameter of the message constructor which allows you to inject current app's context to message which allows you to inherit all the properties of the app.
|
||||
|
||||
@@ -106,26 +106,29 @@ const { appContext } = getCurrentInstance()!
|
||||
ElMessage({}, appContext)
|
||||
```
|
||||
|
||||
## Options
|
||||
## Message API
|
||||
|
||||
| Attribute | Description | Type | Accepted Values | Default |
|
||||
| ------------------------ | ------------------------------------------------------------------------------ | -------------------- | -------------------------- | ------------- |
|
||||
| message | message text | string / VNode | — | — |
|
||||
| type | message type | string | success/warning/info/error | info |
|
||||
| icon | custom icon component, overrides `type` | string / Component | — | — |
|
||||
| dangerouslyUseHTMLString | whether `message` is treated as HTML string | boolean | — | false |
|
||||
| custom-class | custom class name for Message | string | — | — |
|
||||
| duration | display duration, millisecond. If set to 0, it will not turn off automatically | number | — | 3000 |
|
||||
| show-close | whether to show a close button | boolean | — | false |
|
||||
| center | whether to center the text | boolean | — | false |
|
||||
| on-close | callback function when closed with the message instance as the parameter | function | — | — |
|
||||
| offset | set the distance to the top of viewport | number | — | 20 |
|
||||
| appendTo | set the root element for the message | string / HTMLElement | - | document.body |
|
||||
| grouping | merge messages with the same content, type of VNode message is not supported | boolean | — | false |
|
||||
### Options
|
||||
|
||||
## Methods
|
||||
| Attribute | Description | Type | Default |
|
||||
| -------------------------- | ------------------------------------------------------------------------------ | --------------------------------------------- | --------------- |
|
||||
| `message` | message text | `string \| VNode \| (() => VNode)` | — |
|
||||
| `type` | message type | `'success' \| 'warning' \| 'info' \| 'error'` | `'info'` |
|
||||
| `icon` | custom icon component, overrides `type` | `string \| Component` | — |
|
||||
| `dangerouslyUseHTMLString` | whether `message` is treated as HTML string | `boolean` | `false` |
|
||||
| `custom-class` | custom class name for Message | `string` | — |
|
||||
| `duration` | display duration, millisecond. If set to 0, it will not turn off automatically | `number` | `3000` |
|
||||
| `show-close` | whether to show a close button | `boolean` | `false` |
|
||||
| `center` | whether to center the text | `boolean` | `false` |
|
||||
| `on-close` | callback function when closed with the message instance as the parameter | `function` | — |
|
||||
| `offset` | set the distance to the top of viewport | `number` | `20` |
|
||||
| `appendTo` | set the root element for the message | `string \| HTMLElement` | `document.body` |
|
||||
| `grouping` | merge messages with the same content, type of VNode message is not supported | `boolean` | `false` |
|
||||
|
||||
### Methods
|
||||
|
||||
`Message` and `this.$message` returns the current Message instance. To manually close the instance, you can call `close` on it.
|
||||
| Method | Description |
|
||||
| ---- | ---- |
|
||||
| close | close the Message |
|
||||
|
||||
| Method | Description |
|
||||
| ------- | ----------------- |
|
||||
| `close` | close the Message |
|
||||
|
||||
@@ -39,6 +39,8 @@ select-v2/multiple
|
||||
|
||||
## Hide extra tags when the selected items are too many.
|
||||
|
||||
You can collapse tags to a text by using `collapse-tags` attribute. You can check them when mouse hover collapse text by using `collapse-tags-tooltip` attribute.
|
||||
|
||||
:::demo
|
||||
|
||||
select-v2/hide-extra-tags
|
||||
@@ -135,6 +137,7 @@ select-v2/remote-search
|
||||
| clearable | whether select can be cleared | boolean | — | false |
|
||||
| clear-icon | custom clear icon | string / component | — | CircleClose |
|
||||
| collapse-tags | whether to collapse tags to a text when multiple selecting | boolean | — | false |
|
||||
| collapse-tags-tooltip | whether show all selected tags when mouse hover text of collapse-tags. To use this, `collapse-tags` must be true | boolean | true / false | false |
|
||||
| multiple-limit | maximum number of options user can select when multiple is true. No limit when set to 0 | number | — | 0 |
|
||||
| name | the name attribute of select input | string | — | — |
|
||||
| effect | Tooltip theme, built-in theme: `dark` / `light` | string | string | light |
|
||||
|
||||
@@ -47,7 +47,7 @@ select/clearable
|
||||
|
||||
Multiple select uses tags to display selected options.
|
||||
|
||||
:::demo Set `multiple` attribute for `el-select` to enable multiple mode. In this case, the value of `v-model` will be an array of selected options. By default the selected options will be displayed as Tags. You can collapse them to a text by using `collapse-tags` attribute.
|
||||
:::demo Set `multiple` attribute for `el-select` to enable multiple mode. In this case, the value of `v-model` will be an array of selected options. By default the selected options will be displayed as Tags. You can collapse them to a text by using `collapse-tags` attribute. You can check them when mouse hover collapse text by using `collapse-tags-tooltip` attribute.
|
||||
|
||||
select/multiple
|
||||
|
||||
@@ -120,6 +120,7 @@ If the binding value of Select is an object, make sure to assign `value-key` as
|
||||
| size | size of Input | string | large/default/small | default |
|
||||
| clearable | whether select can be cleared | boolean | — | false |
|
||||
| collapse-tags | whether to collapse tags to a text when multiple selecting | boolean | — | false |
|
||||
| collapse-tags-tooltip | whether show all selected tags when mouse hover text of collapse-tags. To use this, `collapse-tags` must be true | boolean | true / false | false |
|
||||
| multiple-limit | maximum number of options user can select when `multiple` is `true`. No limit when set to 0 | number | — | 0 |
|
||||
| name | the name attribute of select input | string | — | — |
|
||||
| effect | Tooltip theme, built-in theme: `dark` / `light` | string | string | light |
|
||||
|
||||
@@ -7,6 +7,16 @@
|
||||
<span class="example-demonstration">Collapse tags</span>
|
||||
<el-cascader :options="options" :props="props" collapse-tags clearable />
|
||||
</div>
|
||||
<div class="example-block">
|
||||
<span class="example-demonstration">Collapse tags tooltip</span>
|
||||
<el-cascader
|
||||
:options="options"
|
||||
:props="props"
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
clearable
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
@@ -1,12 +1,27 @@
|
||||
<template>
|
||||
<el-select-v2
|
||||
v-model="value"
|
||||
:options="options"
|
||||
placeholder="Please select"
|
||||
style="width: 240px"
|
||||
multiple
|
||||
collapse-tags
|
||||
/>
|
||||
<div style="display: inline-block">
|
||||
<p style="margin: 10px">use collapse-tags</p>
|
||||
<el-select-v2
|
||||
v-model="value"
|
||||
:options="options"
|
||||
placeholder="Please select"
|
||||
style="width: 240px"
|
||||
multiple
|
||||
collapse-tags
|
||||
/>
|
||||
</div>
|
||||
<div style="display: inline-block; margin-left: 20px">
|
||||
<p style="margin: 10px">use collapse-tags-tooltip</p>
|
||||
<el-select-v2
|
||||
v-model="value2"
|
||||
:options="options"
|
||||
placeholder="Please select"
|
||||
style="width: 240px"
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@@ -14,6 +29,7 @@ import { ref } from 'vue'
|
||||
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
|
||||
|
||||
const value = ref([])
|
||||
const value2 = ref([])
|
||||
const options = Array.from({ length: 1000 }).map((_, idx) => ({
|
||||
value: `Option ${idx + 1}`,
|
||||
label: `${initials[idx % 10]}${idx}`,
|
||||
|
||||
@@ -1,34 +1,58 @@
|
||||
<template>
|
||||
<el-select
|
||||
v-model="value1"
|
||||
multiple
|
||||
placeholder="Select"
|
||||
style="width: 240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
<div style="display: inline-block">
|
||||
<p style="margin-left: 10px">default</p>
|
||||
<el-select
|
||||
v-model="value1"
|
||||
multiple
|
||||
placeholder="Select"
|
||||
style="width: 240px"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
|
||||
<el-select
|
||||
v-model="value2"
|
||||
multiple
|
||||
collapse-tags
|
||||
style="margin-left: 20px; width: 240px"
|
||||
placeholder="Select"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div style="display: inline-block; margin-left: 20px">
|
||||
<p style="margin-left: 10px">use collapse-tags</p>
|
||||
<el-select
|
||||
v-model="value2"
|
||||
multiple
|
||||
collapse-tags
|
||||
placeholder="Select"
|
||||
style="width: 240px"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div style="display: inline-block; margin-left: 20px">
|
||||
<p style="margin-left: 10px">use collapse-tags-tooltip</p>
|
||||
<el-select
|
||||
v-model="value3"
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
placeholder="Select"
|
||||
style="width: 240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@@ -36,6 +60,7 @@ import { ref } from 'vue'
|
||||
|
||||
const value1 = ref([])
|
||||
const value2 = ref([])
|
||||
const value3 = ref([])
|
||||
const options = [
|
||||
{
|
||||
value: 'Option1',
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
"@vueuse/core": "^7.7.1",
|
||||
"async-validator": "^4.0.7",
|
||||
"dayjs": "^1.10.8",
|
||||
"escape-html": "^1.0.3",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lodash-unified": "^1.0.2",
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
trigger="click"
|
||||
:transition="`${ns.namespace.value}-zoom-in-top`"
|
||||
persistent
|
||||
@show="onSuggestionShow"
|
||||
@before-show="onSuggestionShow"
|
||||
>
|
||||
<div
|
||||
ref="listboxRef"
|
||||
|
||||
@@ -54,6 +54,7 @@ export interface Tag {
|
||||
text: string
|
||||
hitState?: boolean
|
||||
closable: boolean
|
||||
isCollapseTag: boolean
|
||||
}
|
||||
|
||||
export interface ElCascaderPanelContext {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { EVENT_CODE } from '@element-plus/constants'
|
||||
import { triggerEvent } from '@element-plus/test-utils'
|
||||
import { ArrowDown, Check, CircleClose } from '@element-plus/icons-vue'
|
||||
import { POPPER_CONTAINER_SELECTOR } from '@element-plus/hooks'
|
||||
import { hasClass } from '@element-plus/utils'
|
||||
import Cascader from '../src/index.vue'
|
||||
|
||||
jest.mock('lodash-unified', () => {
|
||||
@@ -30,6 +31,10 @@ const OPTIONS = [
|
||||
value: 'ningbo',
|
||||
label: 'Ningbo',
|
||||
},
|
||||
{
|
||||
value: 'wenzhou',
|
||||
label: 'Wenzhou',
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
@@ -241,13 +246,40 @@ describe('Cascader.vue', () => {
|
||||
modelValue: [
|
||||
['zhejiang', 'hangzhou'],
|
||||
['zhejiang', 'ningbo'],
|
||||
['zhejiang', 'wenzhou'],
|
||||
],
|
||||
},
|
||||
})
|
||||
await nextTick()
|
||||
const [firstTag, secondTag] = wrapper.findAll(TAG)
|
||||
expect(firstTag.text()).toBe('Zhejiang / Hangzhou')
|
||||
expect(secondTag.text()).toBe('+ 1')
|
||||
const tags = wrapper.findAll(TAG).filter((item) => {
|
||||
return !hasClass(item.element, 'in-tooltip')
|
||||
})
|
||||
expect(tags[0].text()).toBe('Zhejiang / Hangzhou')
|
||||
expect(tags.length).toBe(2)
|
||||
})
|
||||
|
||||
test('collapse tags tooltip', async () => {
|
||||
const wrapper = mount(Cascader, {
|
||||
props: {
|
||||
options: OPTIONS,
|
||||
props: { multiple: true },
|
||||
collapseTags: true,
|
||||
collapseTagsTooltip: true,
|
||||
modelValue: [
|
||||
['zhejiang', 'hangzhou'],
|
||||
['zhejiang', 'ningbo'],
|
||||
['zhejiang', 'wenzhou'],
|
||||
],
|
||||
},
|
||||
})
|
||||
await nextTick()
|
||||
expect(wrapper.findAll(TAG).length).toBe(5)
|
||||
const tags = wrapper.findAll(TAG).filter((item) => {
|
||||
return hasClass(item.element, 'in-tooltip')
|
||||
})
|
||||
expect(tags[0].text()).toBe('Zhejiang / Hangzhou')
|
||||
expect(tags[1].text()).toBe('Zhejiang / Ningbo')
|
||||
expect(tags[2].text()).toBe('Zhejiang / Wenzhou')
|
||||
})
|
||||
|
||||
test('filterable', async () => {
|
||||
|
||||
@@ -88,7 +88,44 @@
|
||||
disable-transitions
|
||||
@close="deleteTag(tag)"
|
||||
>
|
||||
<span>{{ tag.text }}</span>
|
||||
<template v-if="tag.isCollapseTag === false">
|
||||
<span>{{ tag.text }}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-tooltip
|
||||
:teleported="false"
|
||||
:disabled="popperVisible || !collapseTagsTooltip"
|
||||
:fallback-placements="['bottom', 'top', 'right', 'left']"
|
||||
placement="bottom"
|
||||
effect="light"
|
||||
>
|
||||
<template #default>
|
||||
<span>{{ tag.text }}</span>
|
||||
</template>
|
||||
<template #content>
|
||||
<div class="el-cascader__collapse-tags">
|
||||
<div
|
||||
v-for="(tag2, idx) in allPresentTags"
|
||||
:key="idx"
|
||||
class="el-cascader__collapse-tag"
|
||||
>
|
||||
<el-tag
|
||||
:key="tag2.key"
|
||||
class="in-tooltip"
|
||||
type="info"
|
||||
:size="tagSize"
|
||||
:hit="tag2.hitState"
|
||||
:closable="tag2.closable"
|
||||
disable-transitions
|
||||
@close="deleteTag(tag2)"
|
||||
>
|
||||
<span>{{ tag2.text }}</span>
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-tag>
|
||||
<input
|
||||
v-if="filterable && !isDisabled"
|
||||
@@ -286,6 +323,10 @@ export default defineComponent({
|
||||
default: true,
|
||||
},
|
||||
collapseTags: Boolean,
|
||||
collapseTagsTooltip: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
debounce: {
|
||||
type: Number,
|
||||
default: 300,
|
||||
@@ -341,6 +382,7 @@ export default defineComponent({
|
||||
const inputValue = ref('')
|
||||
const searchInputValue = ref('')
|
||||
const presentTags: Ref<Tag[]> = ref([])
|
||||
const allPresentTags: Ref<Tag[]> = ref([])
|
||||
const suggestions: Ref<CascaderNode[]> = ref([])
|
||||
const isOnComposition = ref(false)
|
||||
|
||||
@@ -436,6 +478,7 @@ export default defineComponent({
|
||||
text: node.calcText(showAllLevels, separator),
|
||||
hitState: false,
|
||||
closable: !isDisabled.value && !node.isDisabled,
|
||||
isCollapseTag: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -452,6 +495,10 @@ export default defineComponent({
|
||||
const nodes = checkedNodes.value
|
||||
const tags: Tag[] = []
|
||||
|
||||
const allTags: Tag[] = []
|
||||
nodes.forEach((node) => allTags.push(genTag(node)))
|
||||
allPresentTags.value = allTags
|
||||
|
||||
if (nodes.length) {
|
||||
const [first, ...rest] = nodes
|
||||
const restCount = rest.length
|
||||
@@ -464,6 +511,7 @@ export default defineComponent({
|
||||
key: -1,
|
||||
text: `+ ${restCount}`,
|
||||
closable: false,
|
||||
isCollapseTag: true,
|
||||
})
|
||||
} else {
|
||||
rest.forEach((node) => tags.push(genTag(node)))
|
||||
@@ -488,6 +536,9 @@ export default defineComponent({
|
||||
presentTags.value.forEach((tag) => {
|
||||
tag.hitState = false
|
||||
})
|
||||
allPresentTags.value.forEach((tag) => {
|
||||
tag.hitState = false
|
||||
})
|
||||
}
|
||||
|
||||
filtering.value = true
|
||||
@@ -701,6 +752,7 @@ export default defineComponent({
|
||||
inputValue,
|
||||
searchInputValue,
|
||||
presentTags,
|
||||
allPresentTags,
|
||||
suggestions,
|
||||
isDisabled,
|
||||
isOnComposition,
|
||||
|
||||
@@ -209,7 +209,10 @@ export default defineComponent({
|
||||
const validateIcon = computed(
|
||||
() => ValidateComponentsMap[validateState.value]
|
||||
)
|
||||
const containerStyle = computed(() => rawAttrs.style as StyleValue)
|
||||
const containerStyle = computed<StyleValue>(() => [
|
||||
rawAttrs.style,
|
||||
props.inputStyle,
|
||||
])
|
||||
const computedTextareaStyle = computed<StyleValue>(() => [
|
||||
props.inputStyle,
|
||||
_textareaCalcStyle.value,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { nextTick } from 'vue'
|
||||
import { nextTick, h, ref } from 'vue'
|
||||
import { getStyle } from '@element-plus/utils'
|
||||
import { rAF } from '@element-plus/test-utils/tick'
|
||||
import { ElMessage } from '..'
|
||||
@@ -106,6 +106,26 @@ describe('Message on command', () => {
|
||||
expect(htmlElement.querySelector(selector)).toBeFalsy()
|
||||
})
|
||||
|
||||
test('it should render vnode function', async () => {
|
||||
const i = ref(0)
|
||||
|
||||
Message({
|
||||
message: () => h('div', i.value),
|
||||
})
|
||||
|
||||
await rAF()
|
||||
expect(document.querySelector(selector)?.textContent).toMatchInlineSnapshot(
|
||||
`"0"`
|
||||
)
|
||||
|
||||
i.value++
|
||||
|
||||
await rAF()
|
||||
expect(document.querySelector(selector)?.textContent).toMatchInlineSnapshot(
|
||||
`"1"`
|
||||
)
|
||||
})
|
||||
|
||||
describe('context inheritance', () => {
|
||||
it('should globally inherit context correctly', () => {
|
||||
expect(ElMessage._context).toBe(null)
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
isString,
|
||||
isElement,
|
||||
debugWarn,
|
||||
isFunction,
|
||||
} from '@element-plus/utils'
|
||||
import { useZIndex } from '@element-plus/hooks'
|
||||
import { messageConfig } from '@element-plus/components/config-provider/src/config-provider'
|
||||
@@ -101,7 +102,11 @@ const message: MessageFn & Partial<Message> & { _context: AppContext | null } =
|
||||
const vm = createVNode(
|
||||
MessageConstructor,
|
||||
props,
|
||||
isVNode(messageContent) ? { default: () => messageContent } : null
|
||||
isFunction(messageContent)
|
||||
? { default: messageContent }
|
||||
: isVNode(messageContent)
|
||||
? { default: () => messageContent }
|
||||
: null
|
||||
)
|
||||
|
||||
vm.appContext = context || message._context
|
||||
|
||||
@@ -33,7 +33,11 @@ export const messageProps = buildProps({
|
||||
default: '',
|
||||
},
|
||||
message: {
|
||||
type: definePropType<string | VNode>([String, Object]),
|
||||
type: definePropType<string | VNode | (() => VNode)>([
|
||||
String,
|
||||
Object,
|
||||
Function,
|
||||
]),
|
||||
default: '',
|
||||
},
|
||||
onClose: {
|
||||
|
||||
@@ -55,7 +55,7 @@ export const rateProps = buildProps({
|
||||
type: iconPropType,
|
||||
default: () => Star,
|
||||
},
|
||||
disabledvoidIcon: {
|
||||
disabledVoidIcon: {
|
||||
type: iconPropType,
|
||||
default: () => StarFilled,
|
||||
},
|
||||
|
||||
@@ -155,7 +155,7 @@ export default defineComponent({
|
||||
getValueFromMap(props.modelValue, componentMap.value)
|
||||
)
|
||||
const voidComponent = computed(() =>
|
||||
rateDisabled.value ? props.disabledvoidIcon : props.voidIcon
|
||||
rateDisabled.value ? props.disabledVoidIcon : props.voidIcon
|
||||
)
|
||||
const activeComponent = computed(() =>
|
||||
getValueFromMap(currentValue.value, componentMap.value)
|
||||
|
||||
@@ -52,6 +52,8 @@ interface SelectProps {
|
||||
disabled?: boolean
|
||||
clearable?: boolean
|
||||
multiple?: boolean
|
||||
collapseTags?: boolean
|
||||
collapseTagsTooltip?: boolean
|
||||
filterable?: boolean
|
||||
remote?: boolean
|
||||
multipleLimit?: number
|
||||
@@ -101,6 +103,8 @@ const createSelect = (
|
||||
:disabled="disabled"
|
||||
:clearable="clearable"
|
||||
:multiple="multiple"
|
||||
:collapseTags="collapseTags"
|
||||
:collapseTagsTooltip="collapseTagsTooltip"
|
||||
:filterable="filterable"
|
||||
:multiple-limit="multipleLimit"
|
||||
:popper-append-to-body="popperAppendToBody"
|
||||
@@ -141,6 +145,8 @@ const createSelect = (
|
||||
disabled: false,
|
||||
clearable: false,
|
||||
multiple: false,
|
||||
collapseTags: false,
|
||||
collapseTagsTooltip: false,
|
||||
remote: false,
|
||||
filterable: false,
|
||||
reserveKeyword: false,
|
||||
@@ -559,6 +565,62 @@ describe('Select', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('collapseTags', () => {
|
||||
it('use collapseTags', async () => {
|
||||
const wrapper = createSelect({
|
||||
data: () => {
|
||||
return {
|
||||
multiple: true,
|
||||
collapseTags: true,
|
||||
value: [],
|
||||
}
|
||||
},
|
||||
})
|
||||
await nextTick()
|
||||
const vm = wrapper.vm as any
|
||||
const options = getOptions()
|
||||
options[0].click()
|
||||
await nextTick()
|
||||
expect(vm.value.length).toBe(1)
|
||||
expect(vm.value[0]).toBe(vm.options[0].value)
|
||||
options[1].click()
|
||||
await nextTick()
|
||||
options[2].click()
|
||||
await nextTick()
|
||||
expect(vm.value.length).toBe(3)
|
||||
const tags = wrapper.findAll('.el-tag').filter((item) => {
|
||||
return !hasClass(item.element, 'in-tooltip')
|
||||
})
|
||||
expect(tags.length).toBe(2)
|
||||
})
|
||||
|
||||
it('use collapseTagsTooltip', async () => {
|
||||
const wrapper = createSelect({
|
||||
data: () => {
|
||||
return {
|
||||
multiple: true,
|
||||
collapseTags: true,
|
||||
collapseTagsTooltip: true,
|
||||
value: [],
|
||||
}
|
||||
},
|
||||
})
|
||||
await nextTick()
|
||||
const vm = wrapper.vm as any
|
||||
const options = getOptions()
|
||||
options[0].click()
|
||||
await nextTick()
|
||||
expect(vm.value.length).toBe(1)
|
||||
expect(vm.value[0]).toBe(vm.options[0].value)
|
||||
options[1].click()
|
||||
await nextTick()
|
||||
options[2].click()
|
||||
await nextTick()
|
||||
expect(vm.value.length).toBe(3)
|
||||
expect(wrapper.findAll('.el-tag')[4].element.textContent).toBe('c2')
|
||||
})
|
||||
})
|
||||
|
||||
describe('manually set modelValue', () => {
|
||||
it('set modelValue in single select', async () => {
|
||||
const wrapper = createSelect({
|
||||
|
||||
@@ -24,6 +24,10 @@ export const SelectProps = {
|
||||
default: 'light',
|
||||
},
|
||||
collapseTags: Boolean,
|
||||
collapseTagsTooltip: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
defaultFirstOption: Boolean,
|
||||
disabled: Boolean,
|
||||
estimatedOptionHeight: {
|
||||
|
||||
@@ -66,7 +66,53 @@
|
||||
type="info"
|
||||
disable-transitions
|
||||
>
|
||||
<el-tooltip
|
||||
v-if="collapseTagsTooltip"
|
||||
:disabled="dropdownMenuVisible"
|
||||
:fallback-placements="['bottom', 'top', 'right', 'left']"
|
||||
:effect="effect"
|
||||
placement="bottom"
|
||||
:teleported="false"
|
||||
>
|
||||
<template #default>
|
||||
<span
|
||||
:class="nsSelectV2.e('tags-text')"
|
||||
:style="{
|
||||
maxWidth: `${tagMaxWidth}px`,
|
||||
}"
|
||||
>+ {{ modelValue.length - 1 }}</span
|
||||
>
|
||||
</template>
|
||||
<template #content>
|
||||
<div :class="nsSelectV2.e('selection')">
|
||||
<div
|
||||
v-for="(selected, idx) in states.cachedOptions"
|
||||
:key="idx"
|
||||
:class="nsSelectV2.e('selected-item')"
|
||||
>
|
||||
<el-tag
|
||||
:key="getValueKey(selected)"
|
||||
:closable="!selectDisabled && !selected.disabled"
|
||||
:size="collapseTagSize"
|
||||
class="in-tooltip"
|
||||
type="info"
|
||||
disable-transitions
|
||||
@close="deleteTag($event, selected)"
|
||||
>
|
||||
<span
|
||||
:class="nsSelectV2.e('tags-text')"
|
||||
:style="{
|
||||
maxWidth: `${tagMaxWidth}px`,
|
||||
}"
|
||||
>{{ getLabel(selected) }}</span
|
||||
>
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-tooltip>
|
||||
<span
|
||||
v-else
|
||||
:class="nsSelectV2.e('tags-text')"
|
||||
:style="{
|
||||
maxWidth: `${tagMaxWidth}px`,
|
||||
|
||||
@@ -3,6 +3,7 @@ import { mount } from '@vue/test-utils'
|
||||
import { EVENT_CODE } from '@element-plus/constants'
|
||||
import { CircleClose, ArrowUp, CaretTop } from '@element-plus/icons-vue'
|
||||
import { POPPER_CONTAINER_SELECTOR } from '@element-plus/hooks'
|
||||
import { hasClass } from '@element-plus/utils'
|
||||
import Select from '../src/select.vue'
|
||||
import Group from '../src/option-group.vue'
|
||||
import Option from '../src/option.vue'
|
||||
@@ -920,6 +921,56 @@ describe('Select', () => {
|
||||
mockInputWidth.mockRestore()
|
||||
})
|
||||
|
||||
test('multiple select with collapseTagsTooltip', async () => {
|
||||
wrapper = _mount(
|
||||
`
|
||||
<el-select v-model="selectedList" multiple collapseTags collapse-tags-tooltip placeholder="请选择">
|
||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
`,
|
||||
() => ({
|
||||
options: [
|
||||
{
|
||||
value: '选项1',
|
||||
label: '黄金糕',
|
||||
},
|
||||
{
|
||||
value: '选项2',
|
||||
label: '双皮奶',
|
||||
},
|
||||
{
|
||||
value: '选项3',
|
||||
label: '蚵仔煎',
|
||||
},
|
||||
{
|
||||
value: '选项4',
|
||||
label: '龙须面',
|
||||
},
|
||||
{
|
||||
value: '选项5',
|
||||
label: '北京烤鸭',
|
||||
},
|
||||
],
|
||||
selectedList: [],
|
||||
})
|
||||
)
|
||||
await wrapper.find('.select-trigger').trigger('click')
|
||||
const options = getOptions()
|
||||
|
||||
options[0].click()
|
||||
await nextTick()
|
||||
options[1].click()
|
||||
await nextTick()
|
||||
options[2].click()
|
||||
await nextTick()
|
||||
const triggerWrappers = wrapper.findAll('.el-tooltip__trigger')
|
||||
expect(triggerWrappers[0]).toBeDefined()
|
||||
const tags = wrapper.findAll('.el-select__tags-text')
|
||||
expect(tags.length).toBe(5)
|
||||
expect(tags[4].element.textContent).toBe('蚵仔煎')
|
||||
})
|
||||
|
||||
test('multiple remove-tag', async () => {
|
||||
wrapper = _mount(
|
||||
`
|
||||
@@ -1435,9 +1486,17 @@ describe('Select', () => {
|
||||
vm.isCollapsed = true
|
||||
vm.isClearable = false
|
||||
await nextTick()
|
||||
expect(wrapper.findAll('.el-tag').length).toBe(2)
|
||||
expect(
|
||||
wrapper.findAll('.el-tag').filter((item) => {
|
||||
return !hasClass(item.element, 'in-tooltip')
|
||||
}).length
|
||||
).toBe(2)
|
||||
await wrapper.find('.el-tag__close').trigger('click')
|
||||
expect(wrapper.findAll('.el-tag').length).toBe(2)
|
||||
expect(
|
||||
wrapper.findAll('.el-tag').filter((item) => {
|
||||
return !hasClass(item.element, 'in-tooltip')
|
||||
}).length
|
||||
).toBe(2)
|
||||
expect(wrapper.findAll('.el-tag__close').length).toBe(0)
|
||||
|
||||
// test for collapse select if is clearable
|
||||
@@ -1445,9 +1504,17 @@ describe('Select', () => {
|
||||
vm.isCollapsed = true
|
||||
vm.isClearable = true
|
||||
await nextTick()
|
||||
expect(wrapper.findAll('.el-tag__close').length).toBe(1)
|
||||
expect(
|
||||
wrapper.findAll('.el-tag__close').filter((item) => {
|
||||
return !hasClass(item.element.parentElement, 'in-tooltip')
|
||||
}).length
|
||||
).toBe(1)
|
||||
await wrapper.find('.el-tag__close').trigger('click')
|
||||
expect(wrapper.findAll('.el-tag').length).toBe(2)
|
||||
expect(
|
||||
wrapper.findAll('.el-tag').filter((item) => {
|
||||
return !hasClass(item.element, 'in-tooltip')
|
||||
}).length
|
||||
).toBe(2)
|
||||
expect(wrapper.findAll('.el-tag__close').length).toBe(0)
|
||||
})
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
getCurrentInstance,
|
||||
onBeforeUnmount,
|
||||
reactive,
|
||||
nextTick,
|
||||
} from 'vue'
|
||||
import { useNamespace } from '@element-plus/hooks'
|
||||
import { useOption } from './useOption'
|
||||
@@ -74,7 +75,9 @@ export default defineComponent({
|
||||
})
|
||||
// if option is not selected, remove it from cache
|
||||
if (select.cachedOptions.get(key) === vm && !doesSelected) {
|
||||
select.cachedOptions.delete(key)
|
||||
nextTick(() => {
|
||||
select.cachedOptions.delete(key)
|
||||
})
|
||||
}
|
||||
select.onOptionDestroy(key, vm)
|
||||
})
|
||||
|
||||
@@ -57,7 +57,50 @@
|
||||
:type="tagType"
|
||||
disable-transitions
|
||||
>
|
||||
<span :class="nsSelect.e('tags-text')"
|
||||
<el-tooltip
|
||||
v-if="collapseTagsTooltip"
|
||||
:disabled="dropMenuVisible"
|
||||
:fallback-placements="['bottom', 'top', 'right', 'left']"
|
||||
:effect="effect"
|
||||
placement="bottom"
|
||||
:teleported="false"
|
||||
>
|
||||
<template #default>
|
||||
<span :class="nsSelect.e('tags-text')"
|
||||
>+ {{ selected.length - 1 }}</span
|
||||
>
|
||||
</template>
|
||||
<template #content>
|
||||
<div :class="nsSelect.e('collapse-tags')">
|
||||
<div
|
||||
v-for="(item, idx) in selected"
|
||||
:key="idx"
|
||||
:class="nsSelect.e('collapse-tag')"
|
||||
>
|
||||
<el-tag
|
||||
:key="getValueKey(item)"
|
||||
class="in-tooltip"
|
||||
:closable="!selectDisabled && !item.isDisabled"
|
||||
:size="collapseTagSize"
|
||||
:hit="item.hitState"
|
||||
:type="tagType"
|
||||
disable-transitions
|
||||
:style="{ margin: '2px' }"
|
||||
@close="deleteTag($event, item)"
|
||||
>
|
||||
<span
|
||||
:class="nsSelect.e('tags-text')"
|
||||
:style="{
|
||||
maxWidth: inputWidth - 75 + 'px',
|
||||
}"
|
||||
>{{ item.currentLabel }}</span
|
||||
>
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-tooltip>
|
||||
<span v-else :class="nsSelect.e('tags-text')"
|
||||
>+ {{ selected.length - 1 }}</span
|
||||
>
|
||||
</el-tag>
|
||||
@@ -322,6 +365,10 @@ export default defineComponent({
|
||||
default: 'value',
|
||||
},
|
||||
collapseTags: Boolean,
|
||||
collapseTagsTooltip: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
popperAppendToBody: {
|
||||
type: Boolean,
|
||||
default: undefined,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { createPopper } from '@popperjs/core'
|
||||
import { get } from 'lodash-unified'
|
||||
import escapeHtml from 'escape-html'
|
||||
import { hasOwn, off, on } from '@element-plus/utils'
|
||||
import { useZIndex } from '@element-plus/hooks'
|
||||
import type {
|
||||
@@ -326,6 +327,7 @@ export function createTablePopper(
|
||||
const isLight = tooltipEffect === 'light'
|
||||
const content = document.createElement('div')
|
||||
content.className = `el-popper ${isLight ? 'is-light' : 'is-dark'}`
|
||||
popperContent = escapeHtml(popperContent)
|
||||
content.innerHTML = popperContent
|
||||
content.style.zIndex = String(nextZIndex())
|
||||
document.body.appendChild(content)
|
||||
|
||||
@@ -33,7 +33,10 @@
|
||||
alt=""
|
||||
/>
|
||||
<div
|
||||
v-if="file.status === 'uploading' || listType !== 'picture-card'"
|
||||
v-if="
|
||||
listType !== 'picture' &&
|
||||
(file.status === 'uploading' || listType !== 'picture-card')
|
||||
"
|
||||
:class="nsUpload.be('list', 'item-info')"
|
||||
>
|
||||
<a
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
"@vueuse/core": "^7.7.1",
|
||||
"async-validator": "^4.0.7",
|
||||
"dayjs": "^1.10.8",
|
||||
"escape-html": "^1.0.3",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lodash-unified": "^1.0.2",
|
||||
|
||||
@@ -149,6 +149,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
@include e(collapse-tags) {
|
||||
white-space: normal;
|
||||
z-index: var(--el-index-normal);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
@include e(collapse-tag) {
|
||||
line-height: inherit;
|
||||
height: inherit;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@include e(suggestion-panel) {
|
||||
border-radius: var(--el-cascader-menu-radius);
|
||||
}
|
||||
|
||||
@@ -104,12 +104,17 @@
|
||||
.#{$namespace}-list-leave-active {
|
||||
transition: all 1s;
|
||||
}
|
||||
|
||||
.#{$namespace}-list-enter-from,
|
||||
.#{$namespace}-list-leave-active {
|
||||
.#{$namespace}-list-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(-30px);
|
||||
}
|
||||
|
||||
.#{$namespace}-list-leave-active {
|
||||
position: absolute !important;
|
||||
}
|
||||
|
||||
.#{$namespace}-opacity-transition {
|
||||
transition: opacity var(--el-transition-duration)
|
||||
cubic-bezier(0.55, 0, 0.1, 1);
|
||||
|
||||
@@ -129,6 +129,10 @@
|
||||
color: var(--el-menu-text-color);
|
||||
}
|
||||
|
||||
& .#{$namespace}-sub-menu__title {
|
||||
padding-right: 40px;
|
||||
}
|
||||
|
||||
& .#{$namespace}-menu-item.is-active,
|
||||
& .#{$namespace}-sub-menu.is-active > .#{$namespace}-sub-menu__title {
|
||||
color: var(--el-menu-active-color);
|
||||
|
||||
@@ -159,6 +159,20 @@
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
@include e(collapse-tags) {
|
||||
white-space: normal;
|
||||
z-index: var(--el-index-normal);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
@include e(collapse-tag) {
|
||||
line-height: inherit;
|
||||
height: inherit;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.#{$namespace}-select__tags {
|
||||
.#{$namespace}-tag {
|
||||
box-sizing: border-box;
|
||||
|
||||
@@ -113,24 +113,20 @@
|
||||
}
|
||||
|
||||
@include b(upload-list) {
|
||||
margin: 0;
|
||||
margin: 10px 0 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
|
||||
position: relative;
|
||||
@include e(item) {
|
||||
transition: all 0.5s cubic-bezier(0.55, 0, 0.1, 1);
|
||||
font-size: 14px;
|
||||
color: var(--el-text-color-regular);
|
||||
margin-top: 4px;
|
||||
margin-bottom: 5px;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
width: 100%;
|
||||
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 1px;
|
||||
|
||||
.#{bem('progress')} {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
@@ -148,10 +144,6 @@
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
& .#{bem('icon', '', 'upload-success')} {
|
||||
color: var(--el-color-success);
|
||||
}
|
||||
@@ -160,10 +152,12 @@
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 50%;
|
||||
cursor: pointer;
|
||||
opacity: 0.75;
|
||||
color: var(--el-text-color-regular);
|
||||
transition: opacity var(--el-transition-duration);
|
||||
transform: translateY(-50%);
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
@@ -179,6 +173,7 @@
|
||||
cursor: pointer;
|
||||
opacity: 1;
|
||||
color: var(--el-color-primary);
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@@ -296,6 +291,7 @@
|
||||
display: inline-flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
margin: 0;
|
||||
#{getCssVarName('upload-list', 'picture-card', 'size')}: 148px;
|
||||
|
||||
.#{bem('upload-list', 'item')} {
|
||||
@@ -426,7 +422,6 @@
|
||||
box-sizing: border-box;
|
||||
margin-top: 10px;
|
||||
padding: 10px;
|
||||
height: 92px;
|
||||
|
||||
.#{bem('icon', '' ,'check')},
|
||||
.#{bem('icon', '' ,'circle-check')} {
|
||||
@@ -450,10 +445,11 @@
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.#{bem('icon', '' ,'close')} {
|
||||
top: 5px;
|
||||
}
|
||||
& .#{bem('icon', '' ,'close')} {
|
||||
top: 5px;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
"allowJs": true,
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"types": ["node", "vite/client", "../typings/components"],
|
||||
"paths": {
|
||||
"element-plus": ["../packages/element-plus"]
|
||||
},
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"include": ["**/*"]
|
||||
|
||||
7
pnpm-lock.yaml
generated
7
pnpm-lock.yaml
generated
@@ -54,6 +54,7 @@ importers:
|
||||
cz-conventional-changelog: ^3.3.0
|
||||
dayjs: ^1.10.8
|
||||
esbuild: ^0.14.25
|
||||
escape-html: ^1.0.3
|
||||
eslint: ^8.10.0
|
||||
eslint-define-config: ^1.2.5
|
||||
expect-type: ^0.13.0
|
||||
@@ -103,6 +104,7 @@ importers:
|
||||
'@vueuse/core': 7.7.1_vue@3.2.31
|
||||
async-validator: 4.0.7
|
||||
dayjs: 1.10.8
|
||||
escape-html: 1.0.3
|
||||
lodash: 4.17.21
|
||||
lodash-es: 4.17.21
|
||||
lodash-unified: 1.0.2_da03a4540fbd16bbaafbb96724306afd
|
||||
@@ -242,6 +244,7 @@ importers:
|
||||
async-validator: ^4.0.7
|
||||
csstype: ^2.6.19
|
||||
dayjs: ^1.10.8
|
||||
escape-html: ^1.0.3
|
||||
lodash: ^4.17.21
|
||||
lodash-es: ^4.17.21
|
||||
lodash-unified: ^1.0.2
|
||||
@@ -255,6 +258,7 @@ importers:
|
||||
'@vueuse/core': 7.7.1_vue@3.2.31
|
||||
async-validator: 4.0.7
|
||||
dayjs: 1.10.8
|
||||
escape-html: 1.0.3
|
||||
lodash: 4.17.21
|
||||
lodash-es: 4.17.21
|
||||
lodash-unified: 1.0.2_da03a4540fbd16bbaafbb96724306afd
|
||||
@@ -5986,7 +5990,6 @@ packages:
|
||||
|
||||
/escape-html/1.0.3:
|
||||
resolution: {integrity: sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=}
|
||||
dev: true
|
||||
|
||||
/escape-string-regexp/1.0.5:
|
||||
resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=}
|
||||
@@ -9951,7 +9954,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/path-name/1.0.0:
|
||||
resolution: {integrity: sha1-jKBjpj3nmC36lXYO2v/RAhRJTyQ=}
|
||||
resolution: {integrity: sha512-/dcAb5vMXH0f51yvMuSUqFpxUcA8JelbRmE5mW/p4CUJxrNgK24IkstnV7ENtg2IDGBOu6izKTG6eilbnbNKWQ==}
|
||||
dev: true
|
||||
|
||||
/path-parse/1.0.7:
|
||||
|
||||
Reference in New Issue
Block a user