<template>  
  <PlanetarTabs
    :class="`planetar-example-card planetar-example-card--${activeTab}`"
    :style="iframeHeight && activeTab === 'example' ? `height: ${iframeHeight}` : ''"
    :id="kebabCase(fileName) + `-example-card`"
    :tabLabels="tabLabels"
    :activeTab.sync="activeTab"
  >
    <template v-for="(tabLabel, index) in tabLabels" v-slot:[index]>
      <div class="pa-lg" v-if="tabLabel === 'example' && exampleComponent" :key="tabLabel + index">
        <component :is="exampleComponent" />
      </div>
      <iframe
        v-if="tabLabel === 'example' && iframe"
        style="width: 100%; height: 100%"
        :src="iframe"
        frameborder="0"
        :key="tabLabel + index"
      />
      <CodeBlock
        class="t-body1"
        v-else-if="parts[tabLabel]"
        lang="html"
        :content="parts[tabLabel]"
        :key="tabLabel + index"
      />
    </template>
  </PlanetarTabs>
</template>

<script>
import { kebabCase } from 'case-anything';
import { PlanetarTabs } from '@planetar/atoms';
import { dynamicImport } from '@planetar/utils';
import { CodeBlock } from '@planetar/markdown';
import { getTagHtmlFromCodeString, jsDocBlockNoIndentation } from '../helpers/regexp';
export default {
  name: 'ExampleCard',
  components: {
    PlanetarTabs: PlanetarTabs,
    CodeBlock: CodeBlock
  },
  props: {
    /**
     * Relative from the `src` folder.
     * @example 'examples/MyBtn/Example1.vue'
     */
    filePath: {
      type: String,
      required: true
    },

    /**
     * When `true` the JSDoc above the default export will be stripped from displayed source code in the script tab.
     */
    stripJSDocDescription: {
      type: Boolean,
      default: false
    },

    /**
     * If you want to host the actual example that's being rendered somewhere else and render it via iframe instead -- to be able to isolate all CSS -- you can do this by passing the iframe URL.
     */
    iframe: {
      type: String
    },

    /**
     * The height you want to pass to the iframe. If pixels it must include 'px'.
     * @example '800px'
     */
    iframeHeight: {
      type: String
    }
  },
  created: function created() {
    var _this = this;

    var parseComponent = this.parseComponent,
        filePath = this.filePath,
        iframe = this.iframe;
    var extension = filePath.split('.').slice(-1)[0];
    this.lang = extension;
    dynamicImport(filePath, extension, 'string').then(function (componentString) {
      parseComponent(componentString);
      _this.dynamicImports++;
    });
    if (iframe) return;
    dynamicImport(filePath, extension, 'component').then(function (componentExport) {
      _this.exampleComponent = componentExport.default;
      _this.dynamicImports++;
    });
  },
  watch: {
    dynamicImports: function dynamicImports(count) {
      var _this2 = this;

      var requiredImportsCount = this.iframe ? 1 : 2;
      if (count >= requiredImportsCount) this.$nextTick(function () {
        return _this2.$emit('mounted');
      });
    }
  },
  data: function data() {
    var propsSeparateTab = this.propsSeparateTab,
        filePath = this.filePath;
    var fileName = filePath.split('/').slice(-1)[0].replace(/\.vue|\.tsx|\.jsx/, '');
    return {
      dynamicImports: 0,
      fileName: fileName,
      activeTab: 'example',
      tabLabels: ['example'],
      lang: '',
      exampleComponent: null,
      parts: {
        template: '',
        script: '',
        style: ''
      }
    };
  },
  computed: {},
  methods: {
    kebabCase: kebabCase,
    parseComponent: function parseComponent(componentCodeString) {
      var stripJSDocDescription = this.stripJSDocDescription;
      var template = getTagHtmlFromCodeString('template', componentCodeString);
      var script = getTagHtmlFromCodeString('script', componentCodeString);
      var style = getTagHtmlFromCodeString('style', componentCodeString);
      var notAVueFile = !template && !script && !style;

      if (notAVueFile) {
        script = componentCodeString;

        if (stripJSDocDescription) {
          script = script.replace(jsDocBlockNoIndentation, '');
        }

        this.parts.script = script;
        this.tabLabels.push('script');
        return;
      }

      if (template) {
        this.parts.template = template;
        this.tabLabels.push('template');
      }

      if (script) {
        if (stripJSDocDescription) {
          script = script.replace(jsDocBlockNoIndentation, '');
        }

        this.parts.script = script;
        this.tabLabels.push('script');
      }

      if (style) {
        this.parts.style = style;
        this.tabLabels.push('style');
      }
    }
  }
};
</script>

<style>
@charset "UTF-8";
/** global styles */
/**
 * * There is no pure black in this interface, instead there is the awesomeness that is Blue-Zodiac.
 * * Use blue-zodiac instead of black, and use it’s opacity variants for text and icon colors.
 * */
/**
 * * primary is always used to signify what is of primary importance to the user. It can be applied to any action that is considered primary, and there can be up to two elements of primary importance per view. (Never more than two.)
 * */
/**
 * * Breezy and beautiful, Sail is used to signify what is of secondary importance to the user.
 * */
/**
 * * Using Blue-Ribbon is powerful. It signifies to the user that they can take action on an item, whether that item is an icon or a text link.
 * * Listed along-side Blue-Ribbon are the colors Azure-Skies and Endeavor. These two colors work along-side Blue-Ribbon in the interface, but are named with unique names due to their presence in the logo mark.
 * */
/**
 * * The subtlety of Stone allows it to serve as background color, and as a tool to separate elements on the page. Use Stone for backgrounds, less important elements, and divider lines.
 * */
/**
 * * Use the Error color to signify to the user that they need to take a corrective action.
 * */
/**
 * * Success is used to let the user know that an input was successful.
 * */
/**
 * * Dark mode colours
 * */
/**
 * * Color Map
 * */
/**
 * * Color mixin to be used like:
 * * +C(color, primary)
 * * +C(background, secondary)
 * */
/**
 * * For overwriting quasar variables
 * */
/**
 * * There is no pure black in this interface, instead there is the awesomeness that is Blue-Zodiac.
 * * Use blue-zodiac instead of black, and use it’s opacity variants for text and icon colors.
 * */
/**
 * * primary is always used to signify what is of primary importance to the user. It can be applied to any action that is considered primary, and there can be up to two elements of primary importance per view. (Never more than two.)
 * */
/**
 * * Breezy and beautiful, Sail is used to signify what is of secondary importance to the user.
 * */
/**
 * * Using Blue-Ribbon is powerful. It signifies to the user that they can take action on an item, whether that item is an icon or a text link.
 * * Listed along-side Blue-Ribbon are the colors Azure-Skies and Endeavor. These two colors work along-side Blue-Ribbon in the interface, but are named with unique names due to their presence in the logo mark.
 * */
/**
 * * The subtlety of Stone allows it to serve as background color, and as a tool to separate elements on the page. Use Stone for backgrounds, less important elements, and divider lines.
 * */
/**
 * * Use the Error color to signify to the user that they need to take a corrective action.
 * */
/**
 * * Success is used to let the user know that an input was successful.
 * */
/**
 * * Dark mode colours
 * */
/**
 * * Color Map
 * */
/**
 * * Color mixin to be used like:
 * * +C(color, primary)
 * * +C(background, secondary)
 * */
/**
 * * For overwriting quasar variables
 * */
.planetar-example-card {
  border: #D9E2F1 thin solid;
  border: var(--q-color-stone-dark, #D9E2F1) thin solid;
  min-height: 127px;
}
</style>