<script setup>
import { computed, useSlots, Fragment, Comment, Text } from "vue";
import { useNamespace } from "@yh-ui/hooks";
import { useComponentTheme } from "@yh-ui/theme";
defineOptions({ name: "YhSpace" });
const props = defineProps({
  direction: { type: String, required: false, default: "horizontal" },
  size: { type: [String, Number, Array], required: false, default: "small" },
  align: { type: String, required: false, default: "center" },
  justify: { type: String, required: false, default: "start" },
  wrap: { type: Boolean, required: false, default: false },
  fill: { type: Boolean, required: false, default: false },
  spacer: { type: [String, Number], required: false },
  style: { type: [Object, String], required: false },
  themeOverrides: { type: null, required: false }
});
const slots = useSlots();
const ns = useNamespace("space");
const { themeStyle } = useComponentTheme(
  "space",
  computed(() => props.themeOverrides)
);
const sizeMap = {
  mini: 4,
  small: 8,
  medium: 16,
  large: 24
};
function resolveSize(s) {
  if (typeof s === "number") return `${s}px`;
  return `${sizeMap[s] ?? 8}px`;
}
const gapStyle = computed(() => {
  const size = props.size;
  if (Array.isArray(size)) {
    return { columnGap: resolveSize(size[0]), rowGap: resolveSize(size[1]) };
  }
  const val = resolveSize(size);
  return props.direction === "vertical" ? { rowGap: val } : { gap: val };
});
const spaceStyle = computed(
  () => ({
    ...themeStyle.value,
    display: "inline-flex",
    flexDirection: props.direction === "vertical" ? "column" : "row",
    flexWrap: props.wrap ? "wrap" : "nowrap",
    alignItems: props.align,
    justifyContent: props.justify,
    width: props.fill ? "100%" : void 0,
    ...gapStyle.value,
    ...typeof props.style === "object" ? props.style : {}
  })
);
function flattenVNodes(vnodes) {
  const result = [];
  for (const vnode of vnodes) {
    if (vnode.type === Comment) continue;
    if (vnode.type === Text && typeof vnode.children === "string" && !vnode.children.trim())
      continue;
    if (vnode.type === Fragment && Array.isArray(vnode.children)) {
      result.push(...flattenVNodes(vnode.children));
    } else if (Array.isArray(vnode)) {
      result.push(...flattenVNodes(vnode));
    } else {
      result.push(vnode);
    }
  }
  return result;
}
const children = computed(() => {
  const defaultSlot = slots.default?.();
  if (!defaultSlot) return [];
  return flattenVNodes(defaultSlot);
});
const showSpacer = computed(() => {
  return props.spacer !== void 0 && props.spacer !== null || !!slots.spacer;
});
</script>

<template>
  <div
    :class="[ns.b(), ns.m(direction), ns.is('wrap', wrap), ns.is('fill', fill)]"
    :style="spaceStyle"
  >
    <template v-for="(child, idx) in children" :key="idx">
      <div :class="ns.e('item')">
        <component :is="child" />
      </div>
      <!-- 间隔符：支持 #spacer 插槽和 spacer prop -->
      <span
        v-if="showSpacer && idx < children.length - 1"
        :class="ns.e('spacer')"
        aria-hidden="true"
      >
        <slot name="spacer">{{ spacer }}</slot>
      </span>
    </template>
    <!-- 默认插槽降级（当无 children 计算时） -->
    <slot v-if="!children.length" />
  </div>
</template>

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

.yh-space.is-wrap {
  flex-wrap: wrap;
}

.yh-space.is-fill {
  width: 100%;
}

.yh-space__item {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
}

.yh-space__spacer {
  display: inline-flex;
  align-items: center;
  color: var(--yh-text-color-placeholder);
  padding: 0 var(--yh-space-spacer-padding, 2px);
  flex-shrink: 0;
}
</style>
