@econnect/webcomponents-library
Documentation
Styleguide
Documentation
Styleguide
  • Getting Started

    • Installation
    • Patch Notes
    • Styleguide
  • Styling

    • e-connect colors
  • UI Components

    • Form

      • Search Field
      • Form Field
      • Forms
    • Filter

      • Filter
      • Search Filter
    • Grid

      • Grid
      • Grid Row
    • Inputs

      • File Input
      • Input Checkbox
      • Input Dropdown
      • Input Date
      • Input Date Time
      • Input Date Time Local
      • Input File
      • Input Label
      • Input Multi Select
      • Input Number
      • Input Radio
      • Input Range
      • Input Select
      • Input Switch
      • Input Slider
      • Input Text
      • Input TextArea
      • Input Time
      • Input Time Range
    • Controls

      • Booleans
      • Button
      • Checkboxes
      • Date Displays
      • Dropdown Lists
      • Text Displays
    • Headers

      • e-header
    • Cards

      • e-card
    • Images

      • Icon
      • Images
      • Flag Image
      • Hamburger
    • Iframe
    • Pager
    • Settings
    • Document Validation
    • Navigation

      • Navigation
      • Navigation Menu
      • Navigation Footer
      • Navigation Button
      • Navigation Button Item
      • Navigation Search Item

e-header v1.0

The <e-header> component is a component that can be used for .

Usage

An e-header has attributes that must be provided,

<e-header
  :text="'example text'"
/>

Attributes

icon | Type: String | Default: ''
color | Type: String | Default: ''
text | Type: String | required
subText | Type: String | Default: ''
subTextColor | Type: String | Default: ''
type | Type: String | Default: 'border'
heading | Type: String | Default: h2
functionList | Type: FunctionModel[] | Default: []

const testData = {
  text: 'example text',
  icon: '',
  type: 'border',
  heading: 'h2'
}

Examples

Below a few interactive examples of e-header can be found.

basic
<e-header
  :text="'h2 example'"
/>
<e-header
  :text="'h3 example'"
  :heading="'h3'"
/>
<e-header
  :text="'h4 example'"
  :heading="'h4'"
/>

h2 example

h3 example

h4 example

with icon
<e-header
  :text="'h2 example'"
  :icon="'checked-circle'"
/>
<e-header
  :text="'h3 example'"
  :icon="'checked-circle'"
  :heading="'h3'"
/>
<e-header
  :text="'h4 example'"
  :icon="'checked-circle'"
  :heading="'h4'"
/>

h2 example

h3 example

h4 example

overwrite color
<e-header
  :text="'h2 example'"
  :icon="'checked-circle'"
  :color="'red'"
/>
<e-header
  :text="'h3 example'"
  :icon="'checked-circle'"
  :color="'white'"
  :heading="'h3'"
/>
<e-header
  :text="'h4 example'"
  :icon="'checked-circle'"
  :color="'blue'"
  :heading="'h4'"
/>

h2 example

h3 example

h4 example

Source Code

e-header.vue
<script setup lang="ts">
import { computed } from 'vue';
import { isEmpty, merge } from 'lodash-es';

import { FunctionModel } from 'types/FunctionModel';
import { HeadingType } from 'types/General';
import { ThemeStyle, type ThemeStyles } from 'types/Themes';

import EIcon from '../e-icon/e-icon.vue';
import EFunctionBar from '../e-function-bar/e-function-bar.vue';

export type Props = {
  icon?: string;
  color?: string;
  text?: string;
  subText?: string;
  subTextColor?: string;
  collapsible?: boolean;
  type?: ThemeStyles;
  heading?: HeadingType;
  functionList?: FunctionModel[];
};
const props = withDefaults(defineProps<Props>(), {
  icon: null,
  color: '',
  text: null,
  subText: null,
  collapsible: false,
  subTextColor: '',
  type: ThemeStyle.Border,
  heading: HeadingType.H2,
  functionList: () => {
    return [] as FunctionModel[];
  }
});

const emit = defineEmits<{
  (e: 'emit:function', func: FunctionModel): void;
  (e: 'emit:collapse'): void;
}>();

const classes = computed(() => {
  const result = [];

  if (props.type) result.push(props.type);
  if (props.collapsible) result.push('collapsible');

  return result;
});

const iconColor = computed(() => {
  if (!isEmpty(props.color)) return props.color;

  switch (props.heading) {
    case HeadingType.H2:
    case HeadingType.H3:
    case HeadingType.H4:
      return `var(--e-${props.heading}-color)`;
    default:
      return 'var(--e-foreground)';
  }
});

const headerText = computed(() => {
  return props.text;
});
const headerSubText = computed(() => {
  return props.subText;
});
const hasSubText = computed(() => !isEmpty(headerSubText.value));

const headerPrimaryStyle = computed(() => {
  // only overwrite, if a color is provided
  return {
    color: isEmpty(props.color) ? '' : props.color
  };
});
const headerSubStyle = computed(() => {
  return {
    color: isEmpty(props.subTextColor) ? iconColor.value : props.subTextColor
  };
});

const headerFunctions = computed(() => {
  const result: FunctionModel[] = [];

  if (!isEmpty(props.functionList)) {
    merge(result, props.functionList);
  }

  return result;
});

const hasFunctions = computed(() => {
  return !isEmpty(headerFunctions.value);
});

function handleEmit(func: FunctionModel) {
  emit('emit:function', func);
}
</script>

<template>
  <div
    class="e-header"
    :class="classes"
    @click="props.collapsible && emit('emit:collapse')"
  >
    <div
      v-if="icon"
      class="header-icon"
    >
      <e-icon
        :icon="[icon]"
        :color="iconColor"
        :focusable="false"
      />
    </div>

    <div class="header-content">
      <div class="primary-header">
        <component
          :is="heading"
          class="header-text"
          :style="headerPrimaryStyle"
          :title="headerText"
          :aria-label="headerText"
        >
          {{ headerText }}
        </component>

        <e-function-bar
          v-if="hasFunctions"
          :function-list="headerFunctions"
          @emit:function="handleEmit"
        />
      </div>

      <div
        v-if="hasSubText"
        class="sub-header"
      >
        <p
          :style="headerSubStyle"
          :aria-label="headerSubText"
          :title="headerSubText"
          v-text="headerSubText"
        />
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
$primary-height: 40px;

.e-header {
  width: 100%;
  display: flex;
  flex-direction: row;
  gap: 15px;
  overflow: hidden;

  &.collapsible {
    cursor: pointer;
  }

  .header-icon {
    display: flex;
    flex-direction: row;
    align-items: center;
    height: $primary-height;

    .e-icon {
      height: 30px;
      width: 30px;
      pointer-events: none;
    }
  }

  .header-content {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    overflow: hidden;
    justify-content: space-between;

    .primary-header,
    .sub-header {
      align-items: center;
      display: flex;
      flex: 1 1 auto;
      gap: 15px;
      justify-content: space-between;
      flex-direction: row;
      overflow: hidden;
      text-overflow: ellipsis;
      min-width: 0;

      .header-text {
        display: block;
        margin: 0;
        padding: 0;
        border-bottom: none;
        overflow: hidden;
        text-align: left;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      .e-function-bar {
        flex: 0 0 auto;
      }
    }

    .primary-header {
      height: $primary-height;
    }
    .sub-header {
      p {
        margin: 0;
      }
    }
  }

  &.solid,
  &.border {
    margin: 0;
  }
}
</style>
Last Updated:: 10/10/24, 2:56 PM
Contributors: AzureAD\MarcelLommers, Marcel Lommers, Justin Berghahn