From 65fd604a3bef2003c2e4b4bc4f51ed5ee0cf2efb Mon Sep 17 00:00:00 2001 From: Stefan Popov Date: Tue, 8 Sep 2020 11:48:21 +0400 Subject: [PATCH 1/8] Add select components --- src/components/DatePicker/SDatePicker.vue | 1 - src/components/Select/SOption.vue | 32 ++ src/components/Select/SOptionGroup.vue | 34 ++ src/components/Select/SSelect.vue | 378 ++++++++++++++++++++++ src/components/Select/consts.ts | 4 + src/components/Select/index.ts | 6 + src/components/index.ts | 4 + src/index.ts | 9 + src/types/components.ts | 3 + 9 files changed, 470 insertions(+), 1 deletion(-) create mode 100644 src/components/Select/SOption.vue create mode 100644 src/components/Select/SOptionGroup.vue create mode 100644 src/components/Select/SSelect.vue create mode 100644 src/components/Select/consts.ts create mode 100644 src/components/Select/index.ts diff --git a/src/components/DatePicker/SDatePicker.vue b/src/components/DatePicker/SDatePicker.vue index 18f8f5be..6fc7d7c9 100644 --- a/src/components/DatePicker/SDatePicker.vue +++ b/src/components/DatePicker/SDatePicker.vue @@ -52,7 +52,6 @@ export default class SDatePicker extends Vue { * `"year"`/`"month"`/`"date"`/`"dates"`/`"datetime"`/`"week"`/`"datetimerange"`/`"daterange"`/`"monthrange"` */ @Prop({ type: String, default: PickerTypes.DATE }) readonly type!: string - /** * Input type of the datepicker component. Available values: `"input"`, `"select"`. * `"input"` can be set only when `type` is not range. Otherwise, `"select"` will be set automatically. diff --git a/src/components/Select/SOption.vue b/src/components/Select/SOption.vue new file mode 100644 index 00000000..1cea17fa --- /dev/null +++ b/src/components/Select/SOption.vue @@ -0,0 +1,32 @@ + + + + + diff --git a/src/components/Select/SOptionGroup.vue b/src/components/Select/SOptionGroup.vue new file mode 100644 index 00000000..df01ef52 --- /dev/null +++ b/src/components/Select/SOptionGroup.vue @@ -0,0 +1,34 @@ + + + + + diff --git a/src/components/Select/SSelect.vue b/src/components/Select/SSelect.vue new file mode 100644 index 00000000..0af0626a --- /dev/null +++ b/src/components/Select/SSelect.vue @@ -0,0 +1,378 @@ + + + + + diff --git a/src/components/Select/consts.ts b/src/components/Select/consts.ts new file mode 100644 index 00000000..0484a8e2 --- /dev/null +++ b/src/components/Select/consts.ts @@ -0,0 +1,4 @@ +export enum InputTypes { + INPUT = 'input', + SELECT = 'select' +} diff --git a/src/components/Select/index.ts b/src/components/Select/index.ts new file mode 100644 index 00000000..fa6ba46e --- /dev/null +++ b/src/components/Select/index.ts @@ -0,0 +1,6 @@ +import SSelect from './SSelect.vue' +import SOption from './SOption.vue' +import SOptionGroup from './SOptionGroup.vue' +import { InputTypes } from './consts' + +export { SSelect, SOption, SOptionGroup, InputTypes } diff --git a/src/components/index.ts b/src/components/index.ts index 6a7f0ed5..e6622472 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -24,6 +24,7 @@ import { SMenu, SMenuItem, SMenuItemGroup, SSubmenu } from './Menu' import { SPagination } from './Pagination' import { SRow } from './Layout/Row' import { SScrollSectionItem, SScrollSections } from './ScrollSections' +import { SSelect, SOption, SOptionGroup } from './Select' import { STab, STabs } from './Tab' import { STable, STableColumn } from './Table' import { STooltip } from './Tooltip' @@ -57,10 +58,13 @@ export { SMenu, SMenuItem, SMenuItemGroup, + SOption, + SOptionGroup, SPagination, SRow, SScrollSectionItem, SScrollSections, + SSelect, SSubmenu, STab, STabs, diff --git a/src/index.ts b/src/index.ts index 2a066fa5..e8d3487e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,10 +29,13 @@ import { SMenu, SMenuItem, SMenuItemGroup, + SOption, + SOptionGroup, SPagination, SRow, SScrollSectionItem, SScrollSections, + SSelect, SSubmenu, STab, STabs, @@ -74,10 +77,13 @@ const components = [ { component: SMenu, name: Components.SMenu }, { component: SMenuItem, name: Components.SMenuItem }, { component: SMenuItemGroup, name: Components.SMenuItemGroup }, + { component: SOption, name: Components.SOption }, + { component: SOptionGroup, name: Components.SOptionGroup }, { component: SPagination, name: Components.SPagination }, { component: SRow, name: Components.SRow }, { component: SScrollSectionItem, name: Components.SScrollSectionItem }, { component: SScrollSections, name: Components.SScrollSections }, + { component: SSelect, name: Components.SSelect }, { component: SSubmenu, name: Components.SSubmenu }, { component: STab, name: Components.STab }, { component: STabs, name: Components.STabs }, @@ -136,9 +142,12 @@ export { SMenuItem, SMenuItemGroup, SPagination, + SOption, + SOptionGroup, SRow, SScrollSectionItem, SScrollSections, + SSelect, SSubmenu, STab, STabs, diff --git a/src/types/components.ts b/src/types/components.ts index 780ae75d..3b1a4701 100644 --- a/src/types/components.ts +++ b/src/types/components.ts @@ -27,10 +27,13 @@ export enum Components { SMenu = 'SMenu', SMenuItem = 'SMenuItem', SMenuItemGroup = 'SMenuItemGroup', + SOption = 'SOption', + SOptionGroup = 'SOptionGroup', SPagination = 'SPagination', SRow = 'SRow', SScrollSectionItem = 'SScrollSectionItem', SScrollSections = 'SScrollSections', + SSelect = 'SSelect', SSubmenu = 'SSubmenu', STab = 'STab', STabs = 'STabs', From 0119efbf40e8bd9852c0caeb4d91096ac296871b Mon Sep 17 00:00:00 2001 From: Stefan Popov Date: Tue, 8 Sep 2020 11:48:47 +0400 Subject: [PATCH 2/8] Add story for select component --- src/stories/Select/SSelect.stories.ts | 153 ++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 src/stories/Select/SSelect.stories.ts diff --git a/src/stories/Select/SSelect.stories.ts b/src/stories/Select/SSelect.stories.ts new file mode 100644 index 00000000..0fb66cba --- /dev/null +++ b/src/stories/Select/SSelect.stories.ts @@ -0,0 +1,153 @@ +import { text, withKnobs, boolean, number } from '@storybook/addon-knobs' + +import { SSelect, SRow, SCol, SOption } from '../../components' +import { InputTypes } from '../../components/Select' + +export default { + component: SSelect, + title: 'Design System/Select', + decorators: [withKnobs], + excludeStories: /.*Data$/ +} + +export const differentInputsData = Object.values(InputTypes).map(inputType => ({ inputType, model: '' })) +export const optionsData = [ + { label: 'First', value: 'first' }, + { label: 'Second', value: 'second' }, + { label: 'Third', value: 'third' } +] + +export const configurable = () => ({ + components: { SSelect, SOption, SRow, SCol }, + template: ` + +
"{{ item.inputType }}" input type
+ + + +
+
`, + data: () => ({ + model: '', + items: differentInputsData, + options: optionsData + }), + props: { + disabled: { + default: boolean('Disabled', false) + }, + loading: { + default: boolean('Loading', false) + }, + multiple: { + default: boolean('Multiple', false) + }, + clearable: { + default: boolean('Clearable', false) + }, + multipleLimit: { + default: number('Multiple limit', 0) + }, + placeholder: { + default: text('Placeholder', 'Select') + }, + multipleTextPrefix: { + default: text('Multiple text prefix', 'Data') + }, + loadingText: { + default: text('Loading text', 'Loading') + }, + noDataText: { + default: text('No data text', 'No data') + } + }, + methods: { + handleChange: (selected) => console.log('handleChange', selected) + } +}) + +export const multiple = () => ({ + components: { SSelect, SOption, SRow, SCol }, + template: ` + +
"{{ item.inputType }}" input type
+ + + +
+
`, + data: () => ({ + model: '', + items: differentInputsData, + options: optionsData + }), + props: { + multipleLimit: { + default: number('Multiple limit', 0) + }, + multipleTextPrefix: { + default: text('Multiple text prefix', 'Data') + } + }, + methods: { + handleChange: (selected) => console.log('handleChange', selected) + } +}) + +export const disabled = () => ({ + components: { SSelect, SOption, SRow, SCol }, + template: ` + +
{{ item.label }}
+ + + +
+
`, + data: () => ({ + items: differentInputsData.flatMap(item => [ + { ...item, label: `"${item.inputType}" input type` }, + { ...item, model: 'first', label: `"${item.inputType}" input type with selected value` } + ]), + options: optionsData + }) +}) From 64cf6b31988dc358e5d637f550afba341827d29c Mon Sep 17 00:00:00 2001 From: Stefan Popov Date: Tue, 8 Sep 2020 11:49:09 +0400 Subject: [PATCH 3/8] Add story for option component --- src/stories/Select/SOption.stories.ts | 44 +++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/stories/Select/SOption.stories.ts diff --git a/src/stories/Select/SOption.stories.ts b/src/stories/Select/SOption.stories.ts new file mode 100644 index 00000000..79770041 --- /dev/null +++ b/src/stories/Select/SOption.stories.ts @@ -0,0 +1,44 @@ +import { text, withKnobs, boolean } from '@storybook/addon-knobs' + +import { SSelect, SRow, SCol, SOption } from '../../components' + +export default { + component: SOption, + title: 'Design System/Select/Option', + decorators: [withKnobs], + excludeStories: /.*Data$/ +} + +export const optionsData = [ + { label: 'First', value: 'first' }, + { label: 'Second', value: 'second' }, + { label: 'Third', value: 'third' } +] +export const configurable = () => ({ + components: { SSelect, SOption, SRow, SCol }, + template: ` + + + + + + + `, + data: () => ({ + model: '', + options: optionsData + }), + props: { + disabled: { + default: boolean('Disabled', false) + }, + label: { + default: text('Label', 'Custom') + } + } +}) From 259a660dbf79f957f993b80ff2c7e79ec9990859 Mon Sep 17 00:00:00 2001 From: Stefan Popov Date: Tue, 8 Sep 2020 11:49:30 +0400 Subject: [PATCH 4/8] Add story for option group component --- src/stories/Select/SOptionGroup.stories.ts | 53 ++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/stories/Select/SOptionGroup.stories.ts diff --git a/src/stories/Select/SOptionGroup.stories.ts b/src/stories/Select/SOptionGroup.stories.ts new file mode 100644 index 00000000..49c9a274 --- /dev/null +++ b/src/stories/Select/SOptionGroup.stories.ts @@ -0,0 +1,53 @@ +import { text, withKnobs, boolean } from '@storybook/addon-knobs' + +import { SSelect, SRow, SCol, SOption, SOptionGroup } from '../../components' + +export default { + component: SOptionGroup, + title: 'Design System/Select/Option Group', + decorators: [withKnobs], + excludeStories: /.*Data$/ +} + +export const optionsData = [ + { label: 'First', value: 'first' }, + { label: 'Second', value: 'second' }, + { label: 'Third', value: 'third' } +] +export const configurable = () => ({ + components: { SSelect, SOption, SRow, SCol, SOptionGroup }, + template: ` + + + + + + + + + + + `, + data: () => ({ + model: '', + options: optionsData + }), + props: { + disabled: { + default: boolean('Disabled', false) + }, + label: { + default: text('Label', 'Custom') + } + } +}) From e4ed15337285938bb688f83e6ffe99e31353194e Mon Sep 17 00:00:00 2001 From: Stefan Popov Date: Wed, 9 Sep 2020 11:01:21 +0400 Subject: [PATCH 5/8] Fix pagination props and styles --- src/components/Pagination/SPagination.vue | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/components/Pagination/SPagination.vue b/src/components/Pagination/SPagination.vue index f05fc612..4f1b1aaa 100644 --- a/src/components/Pagination/SPagination.vue +++ b/src/components/Pagination/SPagination.vue @@ -77,13 +77,13 @@ export default class SPagination extends Vue { */ @Prop({ default: '', type: String }) readonly popperClass!: string /** - * Custom class name for the total element of the pagination component + * Styles object for the total element of the pagination component */ - @Prop({ default: '', type: String }) readonly totalClass!: string + @Prop() readonly totalStyle!: object /** - * Custom class name for the sizes element of the pagination component + * Styles object for the sizes element of the pagination component */ - @Prop({ default: '', type: String }) readonly sizesClass!: string + @Prop() readonly sizesStyle!: object /** * Text of the previous button */ @@ -118,11 +118,15 @@ export default class SPagination extends Vue { const items = Array.from(this.pagination.$el.childNodes) as Array this.totalItem = items.find(item => item.className === 'el-pagination__total') this.sizesItem = items.find(item => item.className === 'el-pagination__sizes') - if (this.totalItem && this.totalClass) { - (this.totalItem as Element).classList.add(this.totalClass) + if (this.totalItem && this.totalStyle) { + for (const styleProp in this.totalStyle) { + (this.totalItem as HTMLElement).style[styleProp] = this.totalStyle[styleProp] + } } - if (this.sizesItem && this.sizesClass) { - (this.sizesItem as Element).classList.add(this.sizesClass) + if (this.sizesItem && this.sizesStyle) { + for (const styleProp in this.sizesStyle) { + (this.sizesItem as HTMLElement).style[styleProp] = this.sizesStyle[styleProp] + } } } @@ -239,6 +243,7 @@ export default class SPagination extends Vue { } .el-pagination__total, .per-page-text, .el-pagination__jump { color: $color-neutral-secondary; + font-weight: normal; } .el-pager li { color: $color-basic-black; From 1a1374921175184d3ea056bf375eade1bc35bbb3 Mon Sep 17 00:00:00 2001 From: Stefan Popov Date: Thu, 10 Sep 2020 09:23:40 +0400 Subject: [PATCH 6/8] Fix styles --- src/components/Select/SSelect.vue | 51 +++++++++++++++++++++++++------ src/styles/icons.scss | 1 + 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/components/Select/SSelect.vue b/src/components/Select/SSelect.vue index 0af0626a..8ed019e1 100644 --- a/src/components/Select/SSelect.vue +++ b/src/components/Select/SSelect.vue @@ -12,7 +12,6 @@ :clearable="clearable" :multiple-limit="multipleLimit" :no-data-text="noDataText" - @change="handleChange" @blur="handleBlur" @focus="handleFocus" @visible-change="handleVisibleChange" @@ -149,6 +148,9 @@ export default class SSelect extends Vue { if (this.disabled) { cssClasses.push('disabled') } + if ((!this.multiple && this.model) || (this.multiple && this.model.length !== 0)) { + cssClasses.push('has-value') + } return cssClasses } @@ -159,10 +161,6 @@ export default class SSelect extends Vue { return !!(this.model && this.model.length !== 0 && this.placeholder) } - handleChange (selected: any): void { - this.$emit('change', selected) - } - handleBlur (event: Event): void { this.focused = false this.$emit('blur', event) @@ -197,6 +195,7 @@ export default class SSelect extends Vue {