Skip to content

Commit 176523c

Browse files
committed
feat(chip): add support for custom close icon using slot and update icon prop
feat(rate): implement icon slots for rating component to allow custom icons feat(step): introduce icon slots for step component to customize step icons fix(alert): adjust icon margins for better alignment in dark and light themes fix(icon): change display property to inline-flex for better layout handling fix(radio): update icon rendering logic to use spans for better structure fix(steps): enhance step component to prioritize slot icons over props
1 parent b31b000 commit 176523c

67 files changed

Lines changed: 729 additions & 153 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/varlet-ui/src/action-sheet/ActionItem.vue

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,31 @@
55
:class="classes(n('action-item'), className, [disabled, n('--disabled')])"
66
:style="{ color }"
77
>
8-
<var-icon
9-
v-if="icon"
10-
var-action-sheet-cover
11-
:class="n('action-icon')"
12-
:namespace="namespace"
13-
:name="icon"
14-
:size="iconSize"
15-
/>
8+
<var-icon v-if="isString(icon)" :class="n('action-icon')" :namespace="namespace" :name="icon" :size="iconSize" />
9+
<span v-else-if="icon" :class="n('action-icon')">
10+
<maybe-v-node :is="renderIcon()" />
11+
</span>
1612
<div :class="n('action-name')">{{ name }}</div>
1713

1814
<var-hover-overlay :hovering="disabled ? false : hovering" />
1915
</div>
2016
</template>
2117

2218
<script lang="ts">
23-
import { defineComponent } from 'vue'
19+
import { callOrReturn, isString } from '@varlet/shared'
20+
import { defineComponent, type PropType, type VNode } from 'vue'
2421
import Hover from '../hover'
2522
import VarHoverOverlay, { useHoverOverlay } from '../hover-overlay'
2623
import VarIcon from '../icon'
2724
import Ripple from '../ripple'
28-
import { createNamespace } from '../utils/components'
25+
import { createNamespace, MaybeVNode } from '../utils/components'
2926
3027
const { name, n, classes } = createNamespace('action-sheet')
3128
3229
export default defineComponent({
3330
name,
3431
components: {
32+
MaybeVNode,
3533
VarHoverOverlay,
3634
VarIcon,
3735
},
@@ -43,16 +41,22 @@ export default defineComponent({
4341
color: String,
4442
namespace: String,
4543
iconSize: [String, Number],
46-
icon: String,
44+
icon: [String, Object, Function] as PropType<string | VNode | (() => VNode)>,
4745
},
48-
setup() {
46+
setup(props) {
4947
const { hovering, handleHovering } = useHoverOverlay()
5048
49+
function renderIcon() {
50+
return callOrReturn(props.icon)
51+
}
52+
5153
return {
5254
hovering,
55+
isString,
5356
n,
5457
classes,
5558
handleHovering,
59+
renderIcon,
5660
}
5761
},
5862
})

packages/varlet-ui/src/action-sheet/__tests__/__snapshots__/component.spec.js.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ exports[`action-sheet styles 1`] = `
88
<div class="var-popup__content var-popup--bottom var-popup--content-background-color var-elevation--3 var-popup--safe-area var-action-sheet__popup-radius" style="z-index: 2000;" role="dialog" aria-modal="true">
99
<div class="var-action-sheet var--box">
1010
<div class="var-action-sheet__title">请选择</div>
11-
<div class="var-action-sheet__action-item customClass" style="color: rgb(76, 175, 80);"><i class="var-icon var-icon--set var-icon-account-circle var-action-sheet__action-icon" style="transition-duration: 0ms; font-size: 30px;" var-action-sheet-cover=""></i>
11+
<div class="var-action-sheet__action-item customClass" style="color: rgb(76, 175, 80);"><i class="var-icon var-icon--set var-icon-account-circle var-action-sheet__action-icon" style="transition-duration: 0ms; font-size: 30px;"></i>
1212
<div class="var-action-sheet__action-name">Item 01</div>
1313
<div class="var-hover-overlay"></div>
1414
</div>
15-
<div class="var-action-sheet__action-item"><i class="var-icon var-icon--set var-icon-account-circle var-action-sheet__action-icon" style="transition-duration: 0ms;" var-action-sheet-cover=""></i>
15+
<div class="var-action-sheet__action-item"><i class="var-icon var-icon--set var-icon-account-circle var-action-sheet__action-icon" style="transition-duration: 0ms;"></i>
1616
<div class="var-action-sheet__action-name">Item 02</div>
1717
<div class="var-hover-overlay"></div>
1818
</div>

packages/varlet-ui/src/action-sheet/__tests__/component.spec.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { mount } from '@vue/test-utils'
22
import { expect, test } from 'vite-plus/test'
3-
import { createApp } from 'vue'
3+
import { createApp, h } from 'vue'
44
import VarActionSheet from '../ActionSheet'
55
import ActionSheet from '../index'
66

@@ -34,3 +34,27 @@ test('action-sheet styles', () => {
3434
expect(wrapper.html()).toMatchSnapshot()
3535
wrapper.unmount()
3636
})
37+
38+
test('action-sheet action supports vnode and render icon', () => {
39+
const wrapper = mount(VarActionSheet, {
40+
props: {
41+
teleport: null,
42+
actions: [
43+
{
44+
name: 'Item 01',
45+
icon: h('i', { class: 'i-custom-action' }),
46+
},
47+
{
48+
name: 'Item 02',
49+
icon: () => h('i', { class: 'i-custom-action-render' }),
50+
},
51+
],
52+
show: true,
53+
},
54+
})
55+
56+
expect(wrapper.find('.i-custom-action').exists()).toBe(true)
57+
expect(wrapper.find('.i-custom-action-render').exists()).toBe(true)
58+
expect(wrapper.find('.var-icon').exists()).toBe(false)
59+
wrapper.unmount()
60+
})

packages/varlet-ui/src/action-sheet/actionSheet.less

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,16 @@
4444
max-height: var(--action-sheet-action-item-height);
4545
}
4646

47-
&__action-icon[var-action-sheet-cover] {
47+
&__action-icon {
48+
display: inline-flex;
4849
margin: var(--action-sheet-icon-margin);
4950
width: var(--action-sheet-icon-size);
5051
height: var(--action-sheet-icon-size);
5152
font-size: var(--action-sheet-icon-size);
53+
54+
.var-icon {
55+
font-size: inherit;
56+
}
5257
}
5358

5459
&--disabled {

packages/varlet-ui/src/action-sheet/docs/en-US.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,14 @@ Options provide parameters to configure the style. See the `Action` data structu
153153
```html
154154
<script setup>
155155
import { Snackbar, ActionSheet } from '@varlet/ui'
156+
import { h } from 'vue'
157+
158+
const svgIcon = h('svg', { viewBox: '0 0 24 24', style: { width: '1em', height: '1em' } }, [
159+
h('path', {
160+
fill: 'currentColor',
161+
d: 'M12 2 2 7l10 5 10-5zm0 7.8L6.45 7 12 4.2 17.55 7zm-8 1.7 8 4 8-4v2.2l-8 4-8-4zm0 4 8 4 8-4v2.2l-8 4-8-4z',
162+
}),
163+
])
156164
157165
async function handleSelect() {
158166
const action = await ActionSheet({
@@ -164,7 +172,7 @@ async function handleSelect() {
164172
},
165173
{
166174
name: 'Item 02',
167-
icon: 'notebook',
175+
icon: svgIcon,
168176
color: 'var(--color-warning)',
169177
},
170178
{
@@ -345,10 +353,16 @@ function handleSelect(action) {
345353

346354
```html
347355
<script setup>
348-
import { ref } from 'vue'
356+
import { h, ref } from 'vue'
349357
import { Snackbar } from '@varlet/ui'
350358
351359
const show = ref(false)
360+
const svgIcon = h('svg', { viewBox: '0 0 24 24', style: { width: '1em', height: '1em' } }, [
361+
h('path', {
362+
fill: 'currentColor',
363+
d: 'M12 2 2 7l10 5 10-5zm0 7.8L6.45 7 12 4.2 17.55 7zm-8 1.7 8 4 8-4v2.2l-8 4-8-4zm0 4 8 4 8-4v2.2l-8 4-8-4z',
364+
}),
365+
])
352366
const actions = ref([
353367
{
354368
name: 'Item 01',
@@ -357,7 +371,7 @@ const actions = ref([
357371
},
358372
{
359373
name: 'Item 02',
360-
icon: 'notebook',
374+
icon: svgIcon,
361375
color: 'var(--color-warning)',
362376
},
363377
{
@@ -451,7 +465,7 @@ function handleSelect(action) {
451465
| ----------- | ----------------------------------- | --------- | ------- |
452466
| `name` | Action name | _string_ | `-` |
453467
| `color` | Action text color | _string_ | `-` |
454-
| `icon` | Icon, support network image address | _string_ | `-` |
468+
| `icon` | Icon, support network image address, VNode, or render function | _string \| VNode \| () => VNode_ | `-` |
455469
| `iconSize` | Icon size | _string_ | `-` |
456470
| `namespace` | Icon namespace | _string_ | `-` |
457471
| `className` | Class name | _string_ | `-` |

packages/varlet-ui/src/action-sheet/docs/zh-CN.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,14 @@ async function handleSelect(){
154154
```html
155155
<script setup>
156156
import { Snackbar, ActionSheet } from '@varlet/ui'
157+
import { h } from 'vue'
158+
159+
const svgIcon = h('svg', { viewBox: '0 0 24 24', style: { width: '1em', height: '1em' } }, [
160+
h('path', {
161+
fill: 'currentColor',
162+
d: 'M12 2 2 7l10 5 10-5zm0 7.8L6.45 7 12 4.2 17.55 7zm-8 1.7 8 4 8-4v2.2l-8 4-8-4zm0 4 8 4 8-4v2.2l-8 4-8-4z',
163+
}),
164+
])
157165
158166
async function handleSelect() {
159167
const action = await ActionSheet({
@@ -165,7 +173,7 @@ async function handleSelect() {
165173
},
166174
{
167175
name: 'Item 02',
168-
icon: 'notebook',
176+
icon: svgIcon,
169177
color: 'var(--color-warning)',
170178
},
171179
{
@@ -346,10 +354,16 @@ function handleSelect(action) {
346354

347355
```html
348356
<script setup>
349-
import { ref } from 'vue'
357+
import { h, ref } from 'vue'
350358
import { Snackbar } from '@varlet/ui'
351359
352360
const show = ref(false)
361+
const svgIcon = h('svg', { viewBox: '0 0 24 24', style: { width: '1em', height: '1em' } }, [
362+
h('path', {
363+
fill: 'currentColor',
364+
d: 'M12 2 2 7l10 5 10-5zm0 7.8L6.45 7 12 4.2 17.55 7zm-8 1.7 8 4 8-4v2.2l-8 4-8-4zm0 4 8 4 8-4v2.2l-8 4-8-4z',
365+
}),
366+
])
353367
const actions = ref([
354368
{
355369
name: 'Item 01',
@@ -358,7 +372,7 @@ const actions = ref([
358372
},
359373
{
360374
name: 'Item 02',
361-
icon: 'notebook',
375+
icon: svgIcon,
362376
color: 'var(--color-warning)',
363377
},
364378
{
@@ -453,7 +467,7 @@ function handleSelect(action) {
453467
| --- | --- | --- | --- |
454468
| `name` | 选项名称 | _string_ | `-` |
455469
| `color` | 选项文字颜色 | _string_ | `-` |
456-
| `icon` | icon 图标,支持网络图片地址 | _string_ | `-` |
470+
| `icon` | icon 图标,支持网络图片地址、VNode 或渲染函数 | _string \| VNode \| () => VNode_ | `-` |
457471
| `iconSize` | 图标尺寸 | _string_ | `-` |
458472
| `namespace` | 图标命名空间 | _string_ | `-` |
459473
| `className` | 选项附加类名 | _string_ | `-` |

packages/varlet-ui/src/action-sheet/example/index.vue

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
<script setup>
22
import { AppType, onThemeChange, watchLang } from '@varlet/cli/client'
33
import { ActionSheet, Snackbar } from '@varlet/ui'
4-
import { reactive, ref } from 'vue'
4+
import { h, reactive, ref } from 'vue'
55
import { t, use } from './locale'
66
7+
const svgIcon = h('svg', { viewBox: '0 0 24 24', style: { width: '1em', height: '1em' } }, [
8+
h('path', {
9+
fill: 'currentColor',
10+
d: 'M12 2 2 7l10 5 10-5zm0 7.8L6.45 7 12 4.2 17.55 7zm-8 1.7 8 4 8-4v2.2l-8 4-8-4zm0 4 8 4 8-4v2.2l-8 4-8-4z',
11+
}),
12+
])
13+
714
const rawActions = [
815
{
916
name: 'Item 01',
@@ -41,7 +48,7 @@ const rawCustomStyleActions = [
4148
},
4249
{
4350
name: 'Item 02',
44-
icon: 'notebook',
51+
icon: svgIcon,
4552
color: 'var(--color-warning)',
4653
},
4754
{

packages/varlet-ui/src/action-sheet/index.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { call, inBrowser } from '@varlet/shared'
2-
import { nextTick, reactive, type TeleportProps } from 'vue'
2+
import { nextTick, shallowReactive, type TeleportProps, type VNode } from 'vue'
33
import { mountInstance, withInstall, withPropsDefaultsSetter } from '../utils/components'
44
import VarActionSheet from './ActionSheet.vue'
55
import { props as actionSheetProps } from './props'
@@ -9,7 +9,7 @@ export type ActionSheetActions = ActionItem | 'close'
99
export interface ActionItem {
1010
name: string
1111
color?: string
12-
icon?: string
12+
icon?: string | VNode | (() => VNode)
1313
iconSize?: string | number
1414
namespace?: string
1515
className?: string
@@ -54,7 +54,9 @@ function ActionSheet(options?: ActionSheetOptions): Promise<ActionSheetActions |
5454
return new Promise((resolve) => {
5555
ActionSheet.close()
5656

57-
const reactiveActionSheetOptions: ActionSheetOptions = reactive(normalizeOptions(options))
57+
const reactiveActionSheetOptions = shallowReactive(
58+
normalizeOptions(options) as Record<string, any>,
59+
) as ActionSheetOptions
5860
reactiveActionSheetOptions.teleport = 'body'
5961
singletonOptions = reactiveActionSheetOptions
6062

packages/varlet-ui/src/alert/alert.less

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
--alert-padding: 16px;
33
--alert-border-radius: 4px;
44
--alert-icon-size: 22px;
5-
--alert-icon-margin: 0 12px 0 0;
5+
--alert-icon-margin: 1px 12px 0 0;
66
--alert-close-icon-size: 22px;
7-
--alert-close-icon-margin: 2px 0 0 12px;
7+
--alert-close-icon-margin: 1px 0 0 12px;
88
--alert-standard-info-text-color: var(--color-on-info);
99
--alert-standard-danger-text-color: var(--color-on-danger);
1010
--alert-standard-success-text-color: var(--color-on-success);
@@ -35,10 +35,13 @@
3535
border-radius: var(--alert-border-radius);
3636

3737
&__icon {
38+
display: inline-flex;
39+
align-items: start;
3840
margin: var(--alert-icon-margin);
41+
font-size: var(--alert-icon-size);
3942

4043
.var-icon {
41-
font-size: var(--alert-icon-size);
44+
font-size: inherit;
4245
}
4346
}
4447

@@ -61,14 +64,18 @@
6164
&__message {
6265
font-size: var(--alert-message-font-size);
6366
line-height: var(--alert-message-line-height);
67+
margin-top: 2px;
6468
}
6569

6670
&__close-icon {
71+
display: inline-flex;
72+
align-items: start;
6773
cursor: pointer;
6874
margin: var(--alert-close-icon-margin);
75+
font-size: var(--alert-close-icon-size);
6976

70-
.var-icon[alert-cover] {
71-
font-size: var(--alert-close-icon-size);
77+
.var-icon {
78+
font-size: inherit;
7279
}
7380
}
7481

packages/varlet-ui/src/alert/docs/en-US.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,9 @@ Here are the CSS variables used by the component. Styles can be customized using
149149
| `--alert-padding` | `16px` |
150150
| `--alert-border-radius` | `4px` |
151151
| `--alert-icon-size` | `22px` |
152-
| `--alert-icon-margin` | `0 12px 0 0` |
152+
| `--alert-icon-margin` | `1px 12px 0 0` |
153153
| `--alert-close-icon-size` | `22px` |
154-
| `--alert-close-icon-margin` | `2px 0 0 12px` |
154+
| `--alert-close-icon-margin` | `1px 0 0 12px` |
155155
| `--alert-standard-info-text-color` | `var(--color-on-info)` |
156156
| `--alert-standard-danger-text-color` | `var(--color-on-danger)` |
157157
| `--alert-standard-success-text-color` | `var(--color-on-success)` |

0 commit comments

Comments
 (0)