IconButton.vue 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. <template>
  2. <Touchable
  3. :pressedColor="pressedBackgroundColor"
  4. :innerStyle="style"
  5. touchable
  6. @click="(e) => emit('click', e)"
  7. v-bind="$attrs"
  8. >
  9. <Icon v-if="icon" v-bind="props" />
  10. <slot />
  11. </Touchable>
  12. </template>
  13. <script setup lang="ts">
  14. import { computed } from 'vue';
  15. import { propGetThemeVar, useTheme, type ViewStyle } from '../theme/ThemeDefine';
  16. import { selectStyleType } from '../theme/ThemeTools';
  17. import type { IconProps } from './Icon.vue';
  18. import Icon from './Icon.vue';
  19. import Touchable from '../feedback/Touchable.vue';
  20. export type IconButtonShapeType = 'round'|'square-full'|'custom';
  21. export interface IconButtonProps extends IconProps {
  22. /**
  23. * 按钮按下时的背景颜色
  24. * @default PressedColor(Color.white)
  25. */
  26. pressedBackgroundColor?: string,
  27. /**
  28. * 按钮边距
  29. */
  30. padding?: number,
  31. /**
  32. * 按钮形状预设
  33. * @default round
  34. */
  35. shape?: IconButtonShapeType;
  36. /**
  37. * 是否禁用
  38. * @default false
  39. */
  40. disabled?: boolean|undefined;
  41. /**
  42. * 按钮样式
  43. */
  44. buttonStyle?: ViewStyle;
  45. /**
  46. * 按钮大小
  47. */
  48. buttonSize?: number|string;
  49. /**
  50. * 按钮背景颜色
  51. */
  52. backgroundColor?: string;
  53. }
  54. const emit = defineEmits(['click']);
  55. const theme = useTheme();
  56. const props = withDefaults(defineProps<IconButtonProps>(), {
  57. shape: 'custom',
  58. pressedBackgroundColor: () => propGetThemeVar('IconButtonPressedColor', 'pressed.white')
  59. });
  60. const style = computed(() => {
  61. return {
  62. flexDirection: 'row',
  63. justifyContent: 'center',
  64. alignItems: 'center',
  65. padding: props.padding,
  66. width: theme.resolveThemeSize(props.buttonSize),
  67. height: theme.resolveThemeSize(props.buttonSize),
  68. backgroundColor: theme.resolveThemeColor(props.backgroundColor),
  69. ...selectStyleType(props.shape, 'round', {
  70. "round": {
  71. borderRadius: theme.resolveThemeSize('IconButtonRoundBorderRadius', 50),
  72. },
  73. "custom": {},
  74. "square-full": {
  75. height: '100%',
  76. aspectRatio: 1,
  77. borderRadius: 0,
  78. },
  79. }),
  80. opacity: props.disabled ? theme.getVar('IconButtonDisabledOpacity', 0.4) : 1,
  81. ...props.buttonStyle,
  82. };
  83. });
  84. defineOptions({
  85. options: {
  86. inheritAttrs: false,
  87. virtualHost: true,
  88. }
  89. })
  90. </script>