Skip to content

Commit 9af9cfa

Browse files
committed
feat(VIconBtn): create new component
1 parent 1599512 commit 9af9cfa

File tree

5 files changed

+164
-0
lines changed

5 files changed

+164
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
@use '../../styles/settings';
2+
@use '../../styles/tools';
3+
@use './variables' as *;
4+
5+
@include tools.layer('components') {
6+
.v-icon-btn {
7+
@include tools.border($icon-btn-border...);
8+
@include tools.rounded($icon-btn-border-radius);
9+
10+
&--start {
11+
margin-inline-end: $icon-btn-margin-start;
12+
}
13+
14+
&--end {
15+
margin-inline-start: $icon-btn-margin-end;
16+
}
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Styles
2+
import './VIconBtn.scss'
3+
4+
// Components
5+
import { VIcon } from '@/components/VIcon'
6+
7+
// Composables
8+
import { makeBorderProps, useBorder } from '@/composables/border'
9+
import { useBackgroundColor, useTextColor } from '@/composables/color'
10+
import { makeComponentProps } from '@/composables/component'
11+
import { makeElevationProps, useElevation } from '@/composables/elevation'
12+
import { makeRoundedProps, useRounded } from '@/composables/rounded'
13+
import { makeTagProps } from '@/composables/tag'
14+
import { makeThemeProps, provideTheme } from '@/composables/theme'
15+
16+
// Utilities
17+
import { toRef, toRefs } from 'vue'
18+
import { convertToUnit, genericComponent, propsFactory, useRender } from '@/util'
19+
20+
// Types
21+
import type { PropType } from 'vue'
22+
import type { IconValue } from '@/composables/icons'
23+
24+
export const makeVIconBtnProps = propsFactory({
25+
bgColor: String,
26+
color: String,
27+
loading: Boolean,
28+
disabled: Boolean,
29+
readonly: Boolean,
30+
icon: [String, Function, Object] as PropType<IconValue>,
31+
rotate: [Number, String],
32+
size: [Number, String],
33+
text: {
34+
type: [String, Number, Boolean],
35+
default: undefined,
36+
},
37+
38+
...makeBorderProps(),
39+
...makeComponentProps(),
40+
...makeElevationProps(),
41+
...makeRoundedProps(),
42+
...makeTagProps(),
43+
...makeThemeProps(),
44+
}, 'VIconBtn')
45+
46+
export const VIconBtn = genericComponent()({
47+
name: 'VIconBtn',
48+
49+
props: makeVIconBtnProps(),
50+
51+
setup (props, { slots }) {
52+
const { color, bgColor } = toRefs(props)
53+
54+
const { themeClasses } = provideTheme(props)
55+
const { textColorClasses, textColorStyles } = useTextColor(color)
56+
const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(bgColor)
57+
const { borderClasses } = useBorder(props)
58+
const { elevationClasses } = useElevation(props)
59+
const { roundedClasses } = useRounded(props)
60+
61+
useRender(() => (
62+
<props.tag
63+
class={[
64+
'v-icon-btn',
65+
themeClasses.value,
66+
backgroundColorClasses.value,
67+
borderClasses.value,
68+
elevationClasses.value,
69+
roundedClasses.value,
70+
textColorClasses.value,
71+
props.class,
72+
]}
73+
style={[
74+
backgroundColorStyles.value,
75+
textColorStyles.value,
76+
props.style,
77+
{
78+
'--v-icon-btn-rotate: ': props.rotate,
79+
'--v-icon-btn-size': convertToUnit(props.size),
80+
},
81+
]}
82+
>
83+
{ slots.default?.() ?? (
84+
!props.icon ? props.text : (
85+
<VIcon
86+
key="icon"
87+
icon={ props.icon }
88+
/>
89+
)
90+
)}
91+
</props.tag>
92+
))
93+
94+
return {}
95+
},
96+
})
97+
98+
export type VIconBtn = InstanceType<typeof VIconBtn>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
@use "sass:map";
2+
@use '../../styles/settings';
3+
@use "../../styles/settings/variables";
4+
@use "../../styles/tools/functions";
5+
6+
// Defaults
7+
$icon-btn-border-radius: map.get(variables.$rounded, 'circle') !default;
8+
$icon-btn-border-radius: map.get(settings.$rounded, 0) !default;
9+
$icon-btn-border-style: settings.$border-style-root !default;
10+
$icon-btn-border-thin-width: thin !default;
11+
$icon-btn-border-width: 0 !default;
12+
$icon-btn-color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity)) !default;
13+
$icon-btn-density: ('default': 0, 'comfortable': -1, 'compact': -2) !default;
14+
$icon-btn-elevation: 1 !default;
15+
$icon-btn-height: 40px !default;
16+
$icon-btn-line-height: normal !default;
17+
$icon-btn-plain-opacity: .62 !default;
18+
$icon-btn-rounded-border-radius: variables.$border-radius-root !default;
19+
$icon-btn-vertical-align: middle !default;
20+
$icon-btn-width: 40px !default;
21+
$icon-btn-margin-end: map.get(variables.$grid-gutters, 'md') !default;
22+
$icon-btn-margin-start: map.get(variables.$grid-gutters, 'md') !default;
23+
24+
$icon-btn-sizes: () !default;
25+
$icon-btn-sizes: functions.map-deep-merge(
26+
(
27+
'height': $icon-btn-height,
28+
'width': $icon-btn-width
29+
),
30+
$icon-btn-sizes
31+
);
32+
33+
$icon-btn-border: (
34+
$icon-btn-border-color,
35+
$icon-btn-border-style,
36+
$icon-btn-border-width,
37+
$icon-btn-border-thin-width
38+
) !default;
39+
40+
$icon-btn-variants: (
41+
$icon-btn-background,
42+
$icon-btn-color,
43+
$icon-btn-elevation,
44+
$icon-btn-plain-opacity,
45+
'v-icon-btn'
46+
) !default;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { VIconBtn } from './VIconBtn'

packages/vuetify/src/components/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export * from './VForm'
3838
export * from './VGrid'
3939
export * from './VHover'
4040
export * from './VIcon'
41+
export * from './VIconBtn'
4142
export * from './VImg'
4243
export * from './VInfiniteScroll'
4344
export * from './VInput'

0 commit comments

Comments
 (0)