@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

Button v1.0

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

Usage

An e-button has attributes that must be provided

<e-button
  :modelValue=""
/>

Attributes

ValueTypeOptionalDefault
textStringyesbutton text
titleStringyes``
themeButtonThemeyesButtonTheme.Secondary
typeButtonTypeyesButtonType.Default
inverseBooleanyesfalse
disabledBooleanyesfalse

Examples

Below an interactive e-button sandbox can be found.

e-button example

Source Code

e-button.vue
<script setup lang="ts">
import { computed } from 'vue';
import { includes } from 'lodash-es';

import { ButtonTheme, type ButtonThemes } from 'types/button/ButtonTheme';
import { ButtonType } from 'types/button/ButtonType';

export type Props = {
  text?: string;
  title?: string;
  theme?: ButtonThemes;
  type?: ButtonType;
  inverse?: boolean;
  disabled?: boolean;
};
const props = withDefaults(defineProps<Props>(), {
  text: 'button text',
  title: null,
  theme: ButtonTheme.Secondary,
  type: ButtonType.Default,
  inverse: false,
  disabled: false
});

const emit = defineEmits<{
  (e: 'clicked', event: MouseEvent): void;
}>();

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

  switch (props.theme) {
    case ButtonTheme.Plain:
      result.push('plain');
      break;
    case ButtonTheme.Primary:
      result.push('primary');
      break;
    case ButtonTheme.Secondary:
    default:
      result.push('accent');
  }

  if (props.inverse) {
    result.push('inverse');
  }

  return result;
});

const buttonType = computed(() => {
  const buttonTypes = [ButtonType.Default, ButtonType.Submit, ButtonType.Reset];
  let result: ButtonType = ButtonType.Default;

  if (includes(buttonTypes, props.type)) {
    result = props.type;
  }

  return result;
});

const isDisabled = computed(() => {
  return props.disabled;
});
</script>

<template>
  <button
    class="e-button"
    :class="buttonClasses"
    :type="buttonType"
    :disabled="isDisabled"
    @click="emit('clicked', $event)"
  >
    <span
      class="e-button-text"
      :title="title || text"
      :aria-label="text"
      v-text="text"
    />
  </button>
</template>

<style scoped lang="scss">
@mixin theme_button(
  $background-color,
  $border,
  $text-color,
  $hover-background-color,
  $hover-border,
  $hover-text-color
) {
  & {
    background-color: $background-color;
    border: $border;

    .e-button-text {
      color: $text-color;
    }

    &:not(:disabled) {
      &:focus {
        background-color: $hover-background-color;
        border: $hover-border;

        .e-button-text {
          color: $hover-text-color;
        }
      }

      &:hover {
        background-color: $hover-background-color;
        border: $hover-border;

        .e-button-text {
          color: $hover-text-color;
        }
      }
    }
  }
}

.e-button {
  border-radius: 15px;
  display: flex;
  height: 44px;
  width: fit-content;
  transition: ease 0.1s;
  text-decoration: none;
  justify-content: center;
  cursor: pointer;

  .e-button-text {
    margin: auto 12px;
    white-space: nowrap;
    font-family: var(--e-navigation-button-font-family);
    font-size: var(--e-navigation-button-font-size);
    font-weight: var(--e-navigation-button-font-weight);
    text-transform: var(--e-navigation-button-font-caps);
  }

  &:disabled {
    cursor: not-allowed;
    user-select: none;
  }

  &.plain {
    display: flex;
    gap: 10px;
    height: 44px;
    align-items: center;

    @include theme_button(
      var(--e-gray),
      none,
      var(--e-gray-0),
      var(--e-gray-400),
      none,
      var(--e-gray-0)
    );

    &:disabled {
      @include theme_button(
        var(--e-disabled),
        none,
        var(--e-gray-200),
        var(--e-disabled),
        none,
        var(--e-gray-200)
      );
    }
  }

  &.primary {
    @include theme_button(
      var(--e-accent),
      var(--e-accent) 2px solid,
      var(--e-gray-0),
      var(--e-red-500),
      var(--e-red-500) 2px solid,
      var(--e-gray-50)
    );

    &.inverse {
      @include theme_button(
        var(--e-white),
        var(--e-white) 2px solid,
        var(--e-accent),
        var(--e-accent-200),
        var(--e-accent-200) 2px solid,
        var(--e-white)
      );

      &:disabled {
        @include theme_button(
          var(--e-gray-200),
          var(--e-disabled) 2px solid,
          var(--e-disabled),
          var(--e-disabled),
          var(--e-gray-200) 2px solid,
          var(--e-disabled)
        );
      }
    }

    &:disabled {
      @include theme_button(
        var(--e-disabled),
        var(--e-disabled) 2px solid,
        var(--e-gray-200),
        var(--e-disabled),
        var(--e-disabled) 2px solid,
        var(--e-gray-200)
      );
    }
  }

  &.accent {
    @include theme_button(
      (var(--e-accent), 0%),
      var(--e-accent) 2px solid,
      var(--e-accent),
      var(--e-accent),
      var(--e-red-500) 2px solid,
      var(--e-red-500)
    );

    &.inverse {
      @include theme_button(
        var(--e-accent),
        var(--e-white) 2px solid,
        var(--e-white),
        var(--e-accent),
        var(--e-accent-200) 2px solid,
        var(--e-accent-200)
      );

      &:disabled {
        @include theme_button(
          var(--e-disabled),
          var(--e-disabled) 2px solid,
          var(--e-gray-200),
          var(--e-disabled),
          var(--e-disabled) 2px solid,
          var(--e-gray-200)
        );
      }
    }

    &:disabled {
      @include theme_button(
        var(--e-gray-200),
        var(--e-disabled) 2px solid,
        var(--e-disabled),
        var(--e-disabled),
        var(--e-gray-200) 2px solid,
        var(--e-disabled)
      );
    }
  }
}
</style>
Last Updated:: 11/1/24, 10:37 AM
Contributors: Marcel Lommers
Prev
Booleans
Next
Checkboxes