<template>
  <component
    :is="componentType"
    class="l-list-item"
    :class="highlight ? 'l-list-item--highlight' : null"
    :style="itemStyle"
    :title="title"
    @click="onClick"
    :to="to"
    :href="href"
  >
    <div v-if="hasThumbSlot" class="l-list-item-thumbnail">
      <slot name="thumbnail" />
    </div>
    <div class="l-list-item-inner">
      <header class="l-list-item-header" v-if="title || hasHeaderSlot">
        <h3 v-if="title" class="l-list-item-title">{{ title }}</h3>
        <slot name="header" />
      </header>
      <div v-if="hasDefaultSlot" class="l-list-item-content">
        <slot></slot>
      </div>
    </div>
  </component>
</template>

<script>
export default {
  name: "l-list-item",
  props: {
    /**
     * The title of the list-item.
     */
    title: {
      type: String,
    },
    /**
     * Highlight the list-item.
     */
    highlight: {
      type: Boolean,
      default: false,
    },
    /**
     * The spacing of the list-item content.
     */
    spacing: {
      type: String,
      default: "2",
      validator: function (value) {
        return ["0", "2", "4", "6", "8"].indexOf(value) !== -1;
      },
    },
    /**
     * The size of the list item title.
     */
    size: {
      type: String,
      default: "xl",
      validator: function (value) {
        return ["xs", "sm", "base", "lg", "xl", "2xl"].indexOf(value) !== -1;
      },
    },
    /**
     * href - list-item will act as a native anchor element
     */
    href: {
      type: String,
    },
    /**
     * to - list-item will act as a nuxt-link
     */
    to: {
      type: String,
    },
  },
  computed: {
    itemSpacing() {
      return `var(--spacing-${this.spacing})`;
    },
    itemStyle() {
      return {
        "--list-item-spacing": this.itemSpacing,
        "--list-item-title": `var(--sizing-${this.size})`,
      };
    },
    hasHeaderSlot() {
      return !!this.$slots.header;
    },
    hasDefaultSlot() {
      return !!this.$slots.default;
    },
    hasThumbSlot() {
      return !!this.$slots.thumbnail;
    },
    componentType() {
      // if item has to prop, render as nuxt-link, if item has href prop, render as anchor, otherwise render as item
      if (this.to) {
        return "nuxt-link";
      } else if (this.href) {
        return "a";
      } else {
        return "article";
      }
    },
  },
  methods: {
    onClick() {
      this.$emit("click");
    },
  },
};
</script>

<style>
.l-list-item {
  transition: all var(--duration-100) ease-in-out;
  text-decoration: none;
  display: flex;
  cursor: pointer;
  min-width: var(--spacing-56);
}
.l-list-item:focus {
  background: var(--list-bg-hover);
}
.l-list-item--highlight {
  border-right: var(--spacing-1) solid var(--list-highlight);
}
.l-list-item:hover {
  background: var(--list-bg-hover);
}
.l-list-item-thumbnail {
  padding-left: var(--list-gap);
}
.l-list-item-inner {
  flex-grow: 1;
  padding: var(--list-item-spacing);
  padding: clamp(
    var(--spacing-2),
    var(--list-item-spacing),
    var(--list-item-spacing)
  );
}
.l-list-item-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--list-item-spacing);
  width: 100%;
  color: var(--list-text-meta);
  font-size: var(--sizing-sm);
}
.l-list-item-title {
  font-size: var(--list-item-title);
  color: var(--list-text);
}
.l-list-item-content {
  padding-top: var(--list-item-spacing);
  padding-top: clamp(
    var(--spacing-2),
    var(--list-item-spacing),
    var(--spacing-4)
  );
  color: var(--list-text-meta);
}
</style>
