diff --git a/package.json b/package.json index ba63f08f..f789a566 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@soramitsu/soramitsu-js-ui", - "version": "0.2.1", + "version": "0.2.2", "private": false, "publishConfig": { "registry": "https://nexus.iroha.tech/repository/npm-soramitsu-private/" diff --git a/src/assets/icons/create.svg b/src/assets/icons/create.svg new file mode 100644 index 00000000..0ef0864d --- /dev/null +++ b/src/assets/icons/create.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/icons/file-upload.svg b/src/assets/icons/file-upload.svg new file mode 100644 index 00000000..60eac80c --- /dev/null +++ b/src/assets/icons/file-upload.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/refresh-red.svg b/src/assets/icons/refresh-red.svg new file mode 100644 index 00000000..d4db0de1 --- /dev/null +++ b/src/assets/icons/refresh-red.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/assets/icons/refresh.svg b/src/assets/icons/refresh.svg index d4db0de1..3c460cf8 100644 --- a/src/assets/icons/refresh.svg +++ b/src/assets/icons/refresh.svg @@ -1,12 +1,12 @@ - - - + + + - + diff --git a/src/components/Button/SButton.vue b/src/components/Button/SButton.vue index e03446f6..7f0e4a64 100644 --- a/src/components/Button/SButton.vue +++ b/src/components/Button/SButton.vue @@ -218,24 +218,16 @@ export default class SButton extends Vue { } background-color: $color-neutral-placeholder; border-color: $color-neutral-placeholder; - &:hover, &:active, &:focus, &:disabled { // TODO: ux designers will create this state - background-color: $color-neutral-placeholder; - border-color: $color-neutral-placeholder; - } - &:disabled:hover { - background-color: $color-neutral-placeholder; - border-color: $color-neutral-placeholder; + &:hover, &:active, &:focus, &:disabled, &:disabled:hover { + background-color: $color-neutral-hover; + border-color: $color-neutral-hover; } &.alternative { background-color: $color-basic-white; border-color: $color-neutral-border; - &:hover, &:active, &:focus, &:disabled { // TODO: ux designers will create this state - background-color: $color-basic-white; - border-color: $color-neutral-border; - } - &:disabled:hover { - background-color: $color-basic-white; - border-color: $color-neutral-border; + &:hover, &:active, &:focus, &:disabled, &:disabled:hover { + background-color: $color-neutral-placeholder; + border-color: $color-neutral-placeholder; } } } diff --git a/src/components/Card/SCard.vue b/src/components/Card/SCard.vue index c7cb4451..6ecbbc98 100644 --- a/src/components/Card/SCard.vue +++ b/src/components/Card/SCard.vue @@ -48,6 +48,7 @@ export default class SCard extends Vue { .el-card__header { border-bottom-color: $color-basic-white; padding-bottom: 0; + text-align: left; } .el-card__body { padding: 18px 20px; diff --git a/src/components/Collapse/SCollapseItem.vue b/src/components/Collapse/SCollapseItem.vue index 38a43d0d..c55719ad 100644 --- a/src/components/Collapse/SCollapseItem.vue +++ b/src/components/Collapse/SCollapseItem.vue @@ -33,7 +33,7 @@ export default class SCollapseItem extends Vue { diff --git a/src/components/Input/SInput.vue b/src/components/Input/SInput.vue index d9613bca..8c6d2e0c 100644 --- a/src/components/Input/SInput.vue +++ b/src/components/Input/SInput.vue @@ -3,16 +3,16 @@ class="s-input" :class="computedClasses" > - {{ placeholder }} + {{ placeholder }} + diff --git a/src/components/Layout/Footer/SFooter.vue b/src/components/Layout/Footer/SFooter.vue index 0c07ac20..84adf789 100644 --- a/src/components/Layout/Footer/SFooter.vue +++ b/src/components/Layout/Footer/SFooter.vue @@ -10,13 +10,12 @@ import { Vue, Component, Prop } from 'vue-property-decorator' @Component export default class SFooter extends Vue { /** - * Height of a component. Default value is `"56px"`. + * Height of the footer component. Default value is `"56px"`. * * In this context, the value of the height property must match the valid value of the * **CSS height** property. For instance, `"auto"`, `"200px"`, `"100vh"` etc. */ @Prop({ default: '56px', type: String }) readonly height!: string - // TODO: 56px is set because of big size right? } diff --git a/src/components/Layout/Header/SHeader.vue b/src/components/Layout/Header/SHeader.vue index 263efafc..2715d822 100644 --- a/src/components/Layout/Header/SHeader.vue +++ b/src/components/Layout/Header/SHeader.vue @@ -10,13 +10,12 @@ import { Vue, Component, Prop } from 'vue-property-decorator' @Component export default class SHeader extends Vue { /** - * Height of a component. Default value is `"56px"`. + * Height of the header component. Default value is `"56px"`. * * In this context, the value of the height property must match the valid value of the * **CSS height** property. For instance, `"auto"`, `"200px"`, `"100vh"` etc. */ @Prop({ default: '56px', type: String }) readonly height!: string - // TODO: 56px is set because of big size right? } diff --git a/src/components/ScrollSections/SScrollSectionItem.vue b/src/components/ScrollSections/SScrollSectionItem.vue index fee3d230..43406972 100644 --- a/src/components/ScrollSections/SScrollSectionItem.vue +++ b/src/components/ScrollSections/SScrollSectionItem.vue @@ -38,7 +38,7 @@ export default class SScrollSectionItem extends Vue { margin-top: 10px; } &:last-child { - margin-bottom: 120%; + margin-bottom: 10px; } .title { font-weight: bold; diff --git a/src/components/ScrollSections/SScrollSections.vue b/src/components/ScrollSections/SScrollSections.vue index 0e293651..18ec3e78 100644 --- a/src/components/ScrollSections/SScrollSections.vue +++ b/src/components/ScrollSections/SScrollSections.vue @@ -1,6 +1,6 @@ @@ -47,9 +48,34 @@ export default class SScrollSections extends Vue { */ @Prop({ default: '#D0021B', type: String }) readonly hoverColor!: string /** - * `VueRouter` instance from `vue-router`. If it's null, then routing will be unavailable while scrolling. + * `VueRouter` instance from `vue-router`. If it's null, then routing will be unavailable while scrolling */ @Prop({ type: Object }) readonly router!: VueRouter + /** + * If the parent flag is set, then the parent component will be used for scrolling events and calculations, + * otherwise - the `window` object. + * + * `false` by default + */ + @Prop({ type: Boolean, default: false }) readonly parent!: boolean + /** + * Top offset if there are other elements on the layout above it. + * + * By default, it's set to `0` + */ + @Prop({ type: Number, default: 0 }) readonly topOffset!: number + /** + * Flex size numbers for each element of scroll sections component. + * + * For instance, `{ main: 4, menu: 1, sections: 2 }`. + * `main` - size of all scroll sections component. + * If menu size is not set, then it will be calculated based on menu and sections size. + * `menu` - size of the menu. + * `sections` - size of the sections part. + * + * `{ menu: 1, sections: 2 }` by default + */ + @Prop({ type: Object, default: { menu: 1, sections: 2 } }) readonly flexSize!: any menuItems: Vue[] = [] activeSection = '' @@ -59,14 +85,18 @@ export default class SScrollSections extends Vue { if (this.$children.length === 0) { return } - this.menuItems = this.$children - window.addEventListener('scroll', this.handleScroll) + let children = this.$children + while (!children.every((item: any) => item.section)) { + children = children[0].$children + } + this.menuItems = children + this.scrollableParent.addEventListener('scroll', this.handleScroll) this.handleInitialState() }) } destroyed (): void { - window.removeEventListener('scroll', this.handleScroll) + this.scrollableParent.removeEventListener('scroll', this.handleScroll) } get computedStyles (): object { @@ -83,6 +113,23 @@ export default class SScrollSections extends Vue { return styles } + get computedFlex (): object { + const flexObject = { menu: {}, sections: {} } as any + if (!this.flexSize) { + return flexObject + } + if (this.flexSize.main && this.flexSize.main > this.flexSize.menu + this.flexSize.sections) { + flexObject.empty = { flex: this.flexSize.main - (this.flexSize.menu + this.flexSize.sections) } + } + flexObject.menu.flex = this.flexSize.menu + flexObject.sections.flex = this.flexSize.sections + return flexObject + } + + get scrollableParent (): any { + return this.parent ? this.$parent.$el : window + } + private handleInitialState (): void { if (this.router && this.router.currentRoute.hash) { this.menuItems.forEach((sectionComponent: any) => { @@ -90,7 +137,11 @@ export default class SScrollSections extends Vue { (sectionComponent.$el as HTMLElement).scrollIntoView() } }) - } else if (window.scrollY <= (this.menuItems[0].$el as HTMLElement).offsetTop) { + let scrollY = this.scrollableParent.scrollY || this.scrollableParent.scrollTop + if (this.topOffset) { + scrollY += this.topOffset + } + } else if (scrollY <= (this.menuItems[0].$el as HTMLElement).offsetTop) { this.activeSection = (this.menuItems[0] as any).section this.menuItems[0].$el.classList.add('active') if (!this.router) { @@ -101,7 +152,11 @@ export default class SScrollSections extends Vue { } private handleScroll (): void { - const fromTop = Math.round(window.scrollY) + let scrollY = this.scrollableParent.scrollY || this.scrollableParent.scrollTop + if (this.topOffset) { + scrollY += this.topOffset + } + const fromTop = Math.round(scrollY) this.menuItems.forEach((sectionComponent, index) => { const section = sectionComponent.$el as HTMLElement const upperBound = section.offsetTop <= fromTop @@ -141,7 +196,6 @@ export default class SScrollSections extends Vue { } .s-scroll-menu { font-weight: 600; - flex: 1; ul { position: sticky; top: 0; @@ -174,6 +228,6 @@ export default class SScrollSections extends Vue { } } .s-scroll-content { - flex: 2; + padding-bottom: 90%; } diff --git a/src/index.ts b/src/index.ts index 49e71e99..a26da146 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,6 +11,8 @@ import { SCollapse, SCollapseItem, SContainer, + SDropdown, + SDropdownItem, SFooter, SForm, SFormItem, @@ -40,6 +42,8 @@ const elements = [ { component: SCollapse, name: Components.SCollapse }, { component: SCollapseItem, name: Components.SCollapseItem }, { component: SContainer, name: Components.SContainer }, + { component: SDropdown, name: Components.SDropdown }, + { component: SDropdownItem, name: Components.SDropdownItem }, { component: SFooter, name: Components.SFooter }, { component: SForm, name: Components.SForm }, { component: SFormItem, name: Components.SFormItem }, @@ -78,6 +82,8 @@ export { SCollapse, SCollapseItem, SContainer, + SDropdown, + SDropdownItem, SFooter, SForm, SFormItem, diff --git a/src/stories/SInput.stories.ts b/src/stories/SInput.stories.ts index 63da4ba9..f1269566 100644 --- a/src/stories/SInput.stories.ts +++ b/src/stories/SInput.stories.ts @@ -152,3 +152,21 @@ export const withTextLimit = () => ({ input: 'Here is an example of limited text' }) }) + +export const textFileInput = () => ({ + components: { SInput }, + template: ``, + data: () => ({ + input: '' + }), + props: { + accept: { + default: text('Accept', '*/*') + } + } +}) diff --git a/src/styles/icons.scss b/src/styles/icons.scss index 2bb3863c..40048b78 100644 --- a/src/styles/icons.scss +++ b/src/styles/icons.scss @@ -1,5 +1,12 @@ /* TODO: fix icons due to external usage */ .s-icon- { + &file { + position: absolute; + background-image: url('~@/assets/icons/file-upload.svg'); + width: 24px; + height: 24px; + } + &refresh { position: absolute; background-image: url('~@/assets/icons/refresh.svg'); @@ -7,6 +14,20 @@ height: 16px; } + &refresh-red { + position: absolute; + background-image: url('~@/assets/icons/refresh-red.svg'); + width: 16px; + height: 16px; + } + + &create { + position: absolute; + background-image: url('~@/assets/icons/create.svg'); + width: 16px; + height: 16px; + } + &plus-small { position: absolute; background-image: url('~@/assets/icons/plus.svg'); diff --git a/src/types/components.ts b/src/types/components.ts index 59b46ab3..660cbfe4 100644 --- a/src/types/components.ts +++ b/src/types/components.ts @@ -9,6 +9,8 @@ export enum Components { SCollapse = 'SCollapse', SCollapseItem = 'SCollapseItem', SContainer = 'SContainer', + SDropdown = 'SDropdown', + SDropdownItem = 'SDropdownItem', SFooter = 'SFooter', SForm = 'SForm', SFormItem = 'SFormItem',