Skip to content

Instantly share code, notes, and snippets.

@Smileek
Created April 28, 2025 08:20
Show Gist options
  • Save Smileek/0b942c714b3a7d8760966d896c7338da to your computer and use it in GitHub Desktop.
Save Smileek/0b942c714b3a7d8760966d896c7338da to your computer and use it in GitHub Desktop.
Props Propagating
import { ComponentTheme } from "@/types/ComponentTheme";
import { IconSvg } from "@/types/IconSvg";
export interface MyButtonProps {
theme?: ComponentTheme;
small?: boolean;
icon?: IconSvg;
rightIcon?: IconSvg;
counter?: number;
disabled?: boolean;
loading?: boolean;
}
export const defaultMyButtonProps: MyButtonProps = {
theme: ComponentTheme.BLUE,
small: false,
icon: undefined,
rightIcon: undefined,
counter: undefined,
disabled: false,
loading: false,
};
<template>
<button class="my-fancy-style">
<slot></slot>
{{ counter }}
</button>
</template>
<script lang="ts" setup>
import { defaultMyButtonProps, MyButtonProps } from "./MyButton.props";
const props = withDefaults(defineProps<MyButtonProps>(), defaultMyButtonProps);
</script>
<template>
<component
:is="props.to ? RouterLink : 'a'"
:to="props.to"
:href="props.href"
class="my-link-button"
>
<MyButton v-bind="propsToPass">
<slot></slot>
</MyButton>
</component>
</template>
<script lang="ts" setup>
import { computed } from "vue";
import { RouteLocationRaw, RouterLink } from "vue-router";
import MyButton from "@/components/MyButton/MyButton.vue";
import { defaultMyButtonProps, MyButtonProps } from "@/components/MyButton/MyButton.props";
interface MyLinkButtonProps {
to?: RouteLocationRaw;
href?: string;
}
const props = defineProps<MyButtonProps & MyLinkButtonProps>();
const propsToPass = computed(() =>
Object.fromEntries(
Object.entries(props).filter(([key, _]) =>
Object.hasOwn(defaultMyButtonProps, key)
)
)
);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment