<script setup>
import { computed, useSlots } from "vue";
import { useNamespace } from "@yh-ui/hooks";
import { useComponentTheme } from "@yh-ui/theme";
defineOptions({
  name: "YhBadge"
});
const props = defineProps({
  value: { type: [String, Number], required: false },
  max: { type: Number, required: false, default: 99 },
  isDot: { type: Boolean, required: false, default: false },
  hidden: { type: Boolean, required: false, default: false },
  type: { type: null, required: false, default: "danger" },
  showBorder: { type: Boolean, required: false, default: true },
  color: { type: String, required: false },
  offset: { type: Array, required: false },
  showZero: { type: Boolean, required: false, default: false },
  themeOverrides: { type: null, required: false }
});
import { badgeTypes } from "./badge";
const _types = badgeTypes;
const { themeStyle } = useComponentTheme(
  "badge",
  computed(() => props.themeOverrides)
);
const slots = useSlots();
const ns = useNamespace("badge");
const hasDefaultSlot = computed(() => !!slots.default);
const content = computed(() => {
  if (props.isDot) return "";
  if (slots.content) return "";
  const { value, max } = props;
  if (typeof value === "number" && typeof max === "number") {
    return value > max ? `${max}+` : value === 0 && !props.showZero ? "" : value;
  }
  return value;
});
const isShow = computed(() => {
  if (props.hidden) return false;
  if (props.isDot) return true;
  if (slots.content) return true;
  const hasContent = content.value !== "" && content.value !== null && content.value !== void 0;
  return hasContent;
});
const badgeClasses = computed(() => [
  ns.b(),
  hasDefaultSlot.value ? ns.m("fixed") : ns.m("standalone")
]);
const contentClasses = computed(() => [
  ns.e("content"),
  ns.em("content", props.type),
  ns.is("dot", props.isDot),
  ns.is("fixed", hasDefaultSlot.value),
  !props.showBorder && ns.is("no-border")
]);
const contentStyles = computed(() => {
  const styles = {};
  if (props.color) {
    styles.backgroundColor = props.color;
    if (props.showBorder) {
      styles.borderColor = props.color;
    }
  }
  if (props.offset && hasDefaultSlot.value) {
    const [x, y] = props.offset;
    styles.transform = `translate(${x}px, ${y}px)`;
  }
  return { ...themeStyle.value, ...styles };
});
</script>

<template>
  <div :class="badgeClasses">
    <!-- 被包裹的元素 -->
    <slot />

    <!-- 徽标内容 -->
    <transition name="yh-zoom-in-center" appear>
      <span v-if="isShow" :class="contentClasses" :style="contentStyles">
        <!-- 自定义内容插槽 -->
        <slot name="content" v-if="$slots.content" />
        <!-- 默认内容 -->
        <template v-else>{{ content }}</template>
      </span>
    </transition>
  </div>
</template>

<style>
@charset "UTF-8";
/**
 * YH-UI Sass Variables
 * 原具体的 CSS 变量输出规则 (:root, html.dark 等) 已移至 root.scss，以防止各组件样式编译时产生重复的全局变量 CSS 冗余。
 */
.yh-badge {
  position: relative;
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
  width: fit-content;
}
.yh-badge--standalone {
  display: inline-block;
}

.yh-badge--fixed {
  position: relative;
}

.yh-badge__content {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 18px;
  padding: 0 6px;
  font-size: var(--yh-font-size-xs);
  line-height: 18px;
  white-space: nowrap;
  text-align: center;
  border-radius: 10px;
  font-weight: var(--yh-font-weight-normal);
  transition: var(--yh-transition-base);
  box-sizing: border-box;
  background-color: var(--yh-badge-bg-color);
  color: var(--yh-badge-text-color);
}
.yh-badge__content.is-fixed {
  position: absolute;
  top: 0;
  right: 0;
  transform: translateX(50%) translateY(-50%);
  transform-origin: 100% 0;
}

.yh-badge__content.is-dot {
  width: 8px;
  height: 8px;
  padding: 0;
  border-radius: 50%;
}

.yh-badge__content:not(.is-no-border) {
  border: 1px solid var(--yh-badge-border-color);
}
.yh-badge__content--primary {
  background-color: var(--yh-color-primary);
}

.yh-badge__content--success {
  background-color: var(--yh-color-success);
}

.yh-badge__content--warning {
  background-color: var(--yh-color-warning);
}

.yh-badge__content--danger {
  background-color: var(--yh-color-danger);
}

.yh-badge__content--info {
  background-color: var(--yh-color-info);
}

.yh-zoom-in-center-enter-active,
.yh-zoom-in-center-leave-active {
  transition: all var(--yh-duration-base) var(--yh-timing-ease-in-out);
}

.yh-zoom-in-center-enter-from,
.yh-zoom-in-center-leave-to {
  opacity: 0;
  transform: scale(0);
}
</style>
