Skip to content
This repository has been archived by the owner on Jul 12, 2020. It is now read-only.

Commit

Permalink
Enhance box component heading
Browse files Browse the repository at this point in the history
Box headings are anchored to the top right corner of the box.
Such a heading style causes the box content to overflow at times.

Using the new seamless option with the light option causes unintended
output as well.

Let’s enhance the box component heading style, using a separate top
horizontal section instead, fixing the content overflow.

In addition, let’s support markdown parsing for the header, which pairs
Nicely with the new support for various icon sizes.

Lastly, let’s give the light option priority over the seamless option if
both options are mistakenly used.
  • Loading branch information
ang-zeyu committed Feb 4, 2020
1 parent 8d23dcc commit f61a637
Showing 1 changed file with 96 additions and 42 deletions.
138 changes: 96 additions & 42 deletions src/TipBox.vue
Original file line number Diff line number Diff line change
@@ -1,25 +1,38 @@
<template>
<div class="alert container" :class="[boxStyle, addClass, lightStyle, seamlessStyle]" :style="customStyle">
<div v-if="!isDefault" class="icon-wrapper" :class="[iconStyle]">
<slot name="_icon">
<span v-html="iconType"></span>
</slot>
<div class="alert box-container" :class="[boxStyle, addClass, lightStyle, seamlessStyle]" :style="customStyle">
<div v-if="headerBool" :class="['box-header-wrapper', { 'alert-dismissible': dismissible }]">
<div v-show="!isDefault" class="icon-wrapper" :class="[iconStyle]">
<slot name="_icon">
<span v-html="iconType"></span>
</slot>
</div>
<div class="box-header">
<slot name="_header"></slot>
</div>
<button v-show="dismissible" type="button" class="close close-with-heading" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div v-if="isSeamless" class="vertical-divider" :class="[boxStyle]"></div>
<div class="contents" :class="[fontBlack, seamlessStyle]">
<h6 v-if="headerContent" class="heading">{{ headerContent }}</h6>
<button v-if="dismissible" type="button" class="close dismiss-button" data-dismiss="alert" aria-label="Close">
<div v-if="horizontalDividerBool" class="horizontal-divider" :class="boxStyle" aria-hidden="true"></div>
<div :class="['box-body-wrapper', { 'alert-dismissible': dismissible && !headerBool, 'box-body-wrapper-with-heading': headerBool }]">
<div v-show="!isDefault && !headerBool" class="icon-wrapper" :class="[iconStyle]">
<slot name="_icon">
<span v-html="iconType"></span>
</slot>
</div>
<div v-if="verticalDividerBool" class="vertical-divider" :class="boxStyle" aria-hidden="true"></div>
<div class="contents" :class="[fontBlack, seamlessStyle]">
<slot></slot>
</div>
<button v-show="dismissible && !headerBool" type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<slot></slot>
</div>
</div>
</template>

<script>
import { toBoolean } from './utils/utils';
export default {
props: {
dismissible: {
Expand Down Expand Up @@ -58,18 +71,10 @@
type: String,
default: ''
},
heading: {
type: String,
default: null,
},
light: {
type: Boolean,
default: false,
},
header: {
type: String,
default: null,
},
seamless: {
type: Boolean,
default: false,
Expand All @@ -80,10 +85,16 @@
return this.type === 'none'
},
isSeamless() {
return toBoolean(this.seamless);
return !this.light && this.seamless;
},
verticalDividerBool() {
return this.isSeamless && !this.headerBool;
},
horizontalDividerBool() {
return this.isSeamless && this.headerBool;
},
headerContent() {
return this.header || this.heading;
headerBool() {
return this.$slots._header;
},
boxStyle() {
switch (this.type) {
Expand All @@ -104,21 +115,21 @@
},
lightStyle() {
if (this.light) {
switch (this.type) {
switch (this.type) {
case 'warning':
return 'border-warning text-warning alert-border-left';
return 'border-warning text-warning alert-border-left';
case 'info':
case 'definition':
return 'border-info text-info alert-border-left';
return 'border-info text-info alert-border-left';
case 'success':
case 'tip':
return 'border-sucess text-success alert-border-left';
return 'border-success text-success alert-border-left';
case 'important':
case 'wrong':
return 'border-danger text-danger alert-border-left';
return 'border-danger text-danger alert-border-left';
default:
return '';
}
return 'alert-border-left';
}
}
return '';
},
Expand All @@ -140,7 +151,7 @@
return style;
},
seamlessStyle() {
if (this.seamless) {
if (this.isSeamless) {
return 'seamless';
}
return '';
Expand Down Expand Up @@ -182,14 +193,33 @@
</script>

<style scoped>
.container {
.box-container {
width: 100%;
padding: 0;
border-radius: 6px;
}
.box-header-wrapper {
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
border-radius: 6px;
padding: 0.28em 1.25rem;
border-radius: 6px 6px 0 0;
}
.container.seamless {
.box-body-wrapper {
display: flex;
flex-direction: row;
width: 100%;
padding: 0.75rem 1.25rem;
}
.box-container.seamless > .box-body-wrapper {
padding: 0.75rem 0.5rem;
}
.box-container.seamless {
background-color: transparent;
border-color: transparent;
}
Expand All @@ -207,21 +237,32 @@
margin: -13px -27px 0 15px;
}
.dismiss-button {
position: relative;
top: -2px;
clear: right;
color: inherit;
height: 100%;
margin-right: -6px;
margin-left: 21px;
.box-body-wrapper-with-heading {
padding-top: 0.5rem;
}
.alert-dismissible {
padding-right: 4rem;
}
.box-header {
font-weight: 500;
}
.icon-wrapper {
display: flex;
margin-right: .5em;
}
.close-with-heading {
top: auto;
padding: 0 1.25rem;
}
.close-with-heading > span {
vertical-align: text-top;
}
.contents {
padding: 0 6px;
width: 100%;
Expand Down Expand Up @@ -250,4 +291,17 @@
.vertical-divider {
width: 4px;
}
.horizontal-divider {
margin: 0 auto;
width: calc(100% - 2.5rem);
height: 3px;
}
</style>

<!-- TODO move this once we upgrade vue-loader version for scoped deep selectors -->
<style>
div.box-header > * {
margin-bottom: 0;
}
</style>

0 comments on commit f61a637

Please sign in to comment.