Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/assets/icons/more-horizontal.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/icons/plus.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
226 changes: 226 additions & 0 deletions src/components/Dropdown/SDropdown.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
<template>
<el-dropdown
ref="dropdown"
:split-button="splitButton"
:size="computedSize"
:type="computedType"
:placement="placement"
:trigger="computedTrigger"
:hide-on-click="hideOnClick"
:show-timeout="showTimeout"
:hide-timeout="hideTimeout"
:tabindex="tabindex"
@click="handleClick"
@command="handleSelect"
@visible-change="handleVisibleChange"
>
<span v-if="type === DropdownType.DEFAULT || splitButton">
<slot></slot>
<i v-if="!splitButton" class="el-icon-arrow-down el-icon--right"></i>
</span>
<template v-else>
<s-button
v-if="type === DropdownType.BUTTON"
:type="computedButtonType"
:size="size"
>
<slot></slot>
<i class="el-icon-arrow-down el-icon--right"></i>
</s-button>
<el-tooltip v-else :disabled="willTooltipBeDisabled">
<i class="s-icon-more"></i>
<template slot="content">
<slot></slot>
</template>
</el-tooltip>
</template>
<el-dropdown-menu :class="{'ellipsis': type === DropdownType.ELLIPSIS}">
<slot name="menu"></slot>
</el-dropdown-menu>
</el-dropdown>
</template>

<script lang="ts">
import { Vue, Component, Prop, Ref } from 'vue-property-decorator'
import { ElDropdown } from 'element-ui/types/dropdown'

import { DropdownType, DropdownSize, DropdownPlacement, DropdownTrigger } from './consts'
import { ButtonTypes } from '../Button'
import { SButton } from '../../components'

@Component({
components: {
SButton
}
})
export default class SDropdown extends Vue {
readonly DropdownType = DropdownType
/**
* A type of the dropdown component. Possible values: `"default"`, `"button"`, `"ellipsis"`.
*
* By default, it's set to `"default"`
*/
@Prop({ type: String, default: DropdownType.DEFAULT }) readonly type!: string
/**
* Button type of dropdown component. It can be used with `type="button"`.
* Possible values: `"primary"`, `"secondary"`, `"tertiary"`.
*
* By default, it's set to `"secondary"`
*/
@Prop({ type: String, default: ButtonTypes.SECONDARY }) readonly buttonType!: string
/**
* A size of the dropdown items. Possible values: `"big"`, `"medium"`, `"small"`.
* It affects on the button size if `type="button"` as well.
*
* By default, it's set to `"big"`
*/
@Prop({ type: String, default: DropdownSize.BIG }) readonly size!: string
/**
* A placement of the popup menu. You can use any value from `DropdownPlacement` enum.
*
* By default, it's set to `"bottom-end"`
*/
@Prop({ type: String, default: DropdownPlacement.BOTTOM_END }) readonly placement!: string
/**
* A trigger action of the dropdown component. Can be `"hover"` or `"click"`.
* When dropdown type is "ellipsis", `trigger = "click"`.
*
* By default, it's set to `"hover"`
*/
@Prop({ type: String, default: DropdownTrigger.HOVER }) readonly trigger!: string
/**
* Hide menu after clicking menu item.
*
* `true` by default
*/
@Prop({ type: Boolean, default: true }) readonly hideOnClick!: boolean
/**
* Displayed button group
*
* `true` by default
*/
@Prop({ type: Boolean, default: false }) readonly splitButton!: boolean
/**
* Delay time before show the dropdown (only works when trigger is `"hover"`).
*
* `250` by default
*/
@Prop({ type: Number, default: 250 }) readonly showTimeout!: number
/**
* Delay time before hide a dropdown (only works when trigger is `"hover"`).
*
* `150` by default
*/
@Prop({ type: Number, default: 150 }) readonly hideTimeout!: number
/**
* Tab index of the dropdown component.
*
* `0` by default
*/
@Prop({ type: Number, default: 0 }) readonly tabindex!: number

@Ref('dropdown') dropdown!: ElDropdown

willTooltipBeDisabled = false

get computedType () {
if (this.type === DropdownType.BUTTON) {
return this.computedButtonType
}
return ''
}

get computedTrigger (): string {
if (this.type === DropdownType.ELLIPSIS) {
return DropdownTrigger.CLICK
}
if (!(Object.values(DropdownTrigger) as Array<string>).includes(this.trigger)) {
return DropdownTrigger.HOVER
}
return this.trigger
}

get computedSize (): string {
if (this.size === DropdownSize.BIG ||
!(Object.values(DropdownSize) as Array<string>).includes(this.size)) {
return ''
}
return this.size
}

get computedButtonType (): string {
if (this.buttonType === ButtonTypes.ACTION ||
!(Object.values(ButtonTypes) as Array<string>).includes(this.buttonType)) {
console.warn(`"${this.buttonType}" button type is unsupported! Secondary button type is set.`)
return ButtonTypes.SECONDARY
}
return this.buttonType
}

mounted (): void {
if (this.splitButton) {
this.$nextTick(() => {
this.dropdown.$children[0].$children.forEach(button => {
button.$el.classList.add(this.size, this.computedButtonType)
})
})
}
if (this.type === DropdownType.ELLIPSIS) {
this.$watch('$refs.dropdown.visible', (visible) => { this.willTooltipBeDisabled = visible })
}
}

handleClick (): void {
this.$emit('click')
}

handleSelect (command: string): void {
this.$emit('select', command)
}

handleVisibleChange (isAppear: boolean): void {
this.$emit('visible-change', isAppear)
}
}
</script>

<style lang="scss">
@import "../../styles/variables.scss";

.el-dropdown {
> .el-button-group {
> .el-button {
float: left;
}
.el-dropdown__caret-button {
&.secondary {
&::before {
background-color: $color-neutral-border;
}
&:hover, &:active, &:focus {
&::before {
background-color: $color-main-brand;
}
}
}
&.tertiary {
&::before {
background-color: transparent;
}
&:hover, &:active, &:focus {
&::before {
background-color: transparent;
}
}
}
}
}
> i {
cursor: pointer;
}
}
.ellipsis.el-popper[x-placement^=bottom] {
margin-top: 25px;
margin-left: 12px;
}
</style>
56 changes: 56 additions & 0 deletions src/components/Dropdown/SDropdownItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<template>
<el-dropdown-item
:command="value"
:disabled="disabled"
:divided="divided"
:icon="computedIcon"
>
<slot></slot>
</el-dropdown-item>
</template>

<script lang="ts">
import { Vue, Component, Prop } from 'vue-property-decorator'
import { ElDropdownItem } from 'element-ui/types/dropdown-item'

@Component
export default class SDropdownItem extends Vue {
/**
* A value of the dropdown item which will be returned from select method
* of the dropdown component. It can be `string/number/object` type
*/
@Prop() readonly value!: any
/**
* Disabled state of the dropdown item
*
* `false` by default
*/
@Prop({ type: Boolean, default: false }) readonly disabled!: boolean
/**
* Display the divider of the dropdown item
*
* `false` by default
*/
@Prop({ type: Boolean, default: false }) readonly divided!: boolean
/**
* An icon of the dropdown item
*/
@Prop({ type: String }) readonly icon!: string

get computedIcon (): string {
// TODO: add checks for invalid icons
return `s-icon-${this.icon}`
}
}
</script>

<style lang="scss">
@import "../../styles/variables.scss";

.el-dropdown-menu__item:not(.is-disabled) {
&:hover, &:focus {
background-color: $color-neutral-placeholder;
color: $color-basic-black;
}
}
</style>
23 changes: 23 additions & 0 deletions src/components/Dropdown/consts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Size } from '../../types/size'

export enum DropdownType {
DEFAULT = 'default',
BUTTON = 'button',
ELLIPSIS = 'ellipsis'
}

export enum DropdownPlacement {
TOP = 'top',
TOP_START = 'top-start',
TOP_END = 'top-end',
BOTTOM = 'bottom',
BOTTOM_START = 'bottom-start',
BOTTOM_END = 'bottom-end'
}

export enum DropdownTrigger {
HOVER = 'hover',
CLICK = 'click'
}

export const DropdownSize = Size
12 changes: 12 additions & 0 deletions src/components/Dropdown/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import SDropdown from './SDropdown.vue'
import SDropdownItem from './SDropdownItem.vue'
import { DropdownPlacement, DropdownSize, DropdownTrigger, DropdownType } from './consts'

export {
SDropdown,
SDropdownItem,
DropdownPlacement,
DropdownSize,
DropdownTrigger,
DropdownType
}
4 changes: 2 additions & 2 deletions src/components/Layout/App/SApp.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import { Vue, Component } from 'vue-property-decorator'

import { SAside } from '../Aside'
import { SContainer, ContainerDirection } from '../Container'
import { SContainer } from '../Container'
import { SFooter } from '../Footer'
import { SHeader } from '../Header'
import { SMain } from '../Main'
Expand All @@ -36,7 +36,7 @@ import { SMain } from '../Main'
}
})
export default class SApp extends Vue {
readonly ContainerDirection = ContainerDirection
// TODO: add properties for header, footer, aside height
}
</script>

Expand Down
2 changes: 1 addition & 1 deletion src/components/Layout/Header/SHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default class SHeader extends Vue {

<style lang="scss">
.el-header {
padding: 16px;
padding: 12px;
box-shadow: 0px 0px 8px rgba(45, 41, 38, 0.2);
font-size: 18px;
}
Expand Down
3 changes: 2 additions & 1 deletion src/components/Tooltip/STooltip.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
:hide-after="closeDelay"
:tabindex="tabindex"
>
<slot slot="content" name="content"></slot>
<slot></slot>
</el-tooltip>
</template>
Expand All @@ -34,7 +35,7 @@ export default class STooltip extends Vue {
*/
@Prop({ default: TooltipTheme.DARK, type: String }) readonly theme!: TooltipEffect
/**
* Content of the tooltip
* Content of the tooltip. You can set content from `content` slot as well
*/
@Prop({ default: '', type: String }) readonly content!: string
/**
Expand Down
3 changes: 3 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { SButton, SButtonGroup } from './Button'
import { SCard } from './Card'
import { SCol } from './Layout/Col'
import { SContainer } from './Layout/Container'
import { SDropdown, SDropdownItem } from './Dropdown'
import { SFooter } from './Layout/Footer'
import { SForm, SFormItem } from './Form'
import { SHeader } from './Layout/Header'
Expand All @@ -24,6 +25,8 @@ export {
SCard,
SCol,
SContainer,
SDropdown,
SDropdownItem,
SFooter,
SForm,
SFormItem,
Expand Down
Loading