diff --git a/cypress/integration/common/report.js b/cypress/integration/common/report.js index 25f4c6e35..4bfc3c240 100644 --- a/cypress/integration/common/report.js +++ b/cypress/integration/common/report.js @@ -44,7 +44,7 @@ Given('I am logged in with a {string} role', role => { When('I click on "Report Post" from the content menu of the post', () => { cy.contains('.ds-card', davidIrvingPostTitle) - .find('.content-menu-trigger') + .find('.content-menu .base-button') .click({force: true}) cy.get('.popover .ds-menu-item-link') @@ -54,7 +54,7 @@ When('I click on "Report Post" from the content menu of the post', () => { When('I click on "Report User" from the content menu in the user info box', () => { cy.contains('.ds-card', davidIrvingPostTitle) - .get('.user-content-menu .content-menu-trigger') + .get('.user-content-menu .base-button') .click({ force: true }) cy.get('.popover .ds-menu-item-link') diff --git a/cypress/integration/common/settings.js b/cypress/integration/common/settings.js index 563d6a733..e8e968a5e 100644 --- a/cypress/integration/common/settings.js +++ b/cypress/integration/common/settings.js @@ -119,7 +119,7 @@ Then('they should be able to see my social media links', () => { }) When('I delete a social media link', () => { - cy.get("a[name='delete']") + cy.get(".base-button[title='Delete']") .click() }) @@ -129,7 +129,7 @@ Then('it gets deleted successfully', () => { }) When('I start editing a social media link', () => { - cy.get("a[name='edit']") + cy.get(".base-button[title='Edit']") .click() }) diff --git a/cypress/integration/common/steps.js b/cypress/integration/common/steps.js index c51c863d1..8e08be2cf 100644 --- a/cypress/integration/common/steps.js +++ b/cypress/integration/common/steps.js @@ -243,7 +243,7 @@ When("I type in the following text:", text => { }); Then("I select a category", () => { - cy.get("span") + cy.get(".base-button") .contains("Just for Fun") .click(); }); @@ -449,7 +449,7 @@ When("I ", name => { When( "I click on {string} from the content menu in the user info box", button => { - cy.get(".user-content-menu .content-menu-trigger").click(); + cy.get(".user-content-menu .base-button").click(); cy.get(".popover .ds-menu-item-link") .contains(button) .click({ diff --git a/webapp/assets/_new/styles/mixins/buttonStates.scss b/webapp/assets/_new/styles/mixins/buttonStates.scss new file mode 100644 index 000000000..b8e1509a6 --- /dev/null +++ b/webapp/assets/_new/styles/mixins/buttonStates.scss @@ -0,0 +1,65 @@ +@mixin buttonStates($color-scheme: primary, $filled: false) { + $main-color: $color-primary; + $active-color: $color-primary-dark; + $hover-color: $color-primary-light; + + @if $color-scheme == danger { + $main-color: $color-danger; + $active-color: $color-danger-dark; + $hover-color: $color-danger-light; + } + + color: $main-color; + border-color: $main-color; + background-color: transparent; + transition: background-color $duration-short; + + &:focus { + outline: $border-size-base dashed $main-color; + } + + &:enabled { + &:hover { + color: $color-neutral-100; + border-color: $main-color; + background-color: $main-color; + } + + &:active { + color: $color-neutral-100; + border-color: $active-color; + background-color: $active-color; + } + } + + &:disabled { + color: $color-neutral-60; + border-color: $color-neutral-60; + cursor: default; + } + + @if $filled { + color: $color-neutral-100; + border-color: $main-color; + background-color: $main-color; + + &:enabled { + &:hover { + border-color: $hover-color; + background-color: $hover-color; + } + + &:active { + color: $color-neutral-100; + border-color: $active-color; + background-color: $active-color; + } + } + + &:disabled { + color: $color-neutral-100; + background-color: $color-neutral-60; + border-color: $color-neutral-60; + } + } +} diff --git a/webapp/assets/_new/styles/resets.scss b/webapp/assets/_new/styles/resets.scss new file mode 100644 index 000000000..2784add5f --- /dev/null +++ b/webapp/assets/_new/styles/resets.scss @@ -0,0 +1,11 @@ +* { + box-sizing: border-box; +} + +button { + padding: 0; + background: transparent; + border: none; + font-family: inherit; + font-size: inherit; +} diff --git a/webapp/assets/_new/styles/tokens.scss b/webapp/assets/_new/styles/tokens.scss index 5b4b3efcc..3304c0e00 100644 --- a/webapp/assets/_new/styles/tokens.scss +++ b/webapp/assets/_new/styles/tokens.scss @@ -4,6 +4,8 @@ */ $color-primary: rgb(23, 181, 63); + $color-primary-light: rgb(96, 214, 98); + $color-primary-dark: rgb(25, 122, 49); $color-primary-active: rgb(25, 194, 67); $color-primary-inverse: rgb(241, 253, 244); $color-secondary: rgb(0, 142, 230); @@ -13,6 +15,8 @@ $color-success-active: rgb(26, 203, 71); $color-success-inverse: rgb(241, 253, 244); $color-danger: rgb(219, 57, 36); + $color-danger-light: rgb(242, 97, 65); + $color-danger-dark: rgb(158, 43, 28); $color-danger-active: rgb(224, 81, 62); $color-danger-inverse: rgb(253, 243, 242); $color-warning: rgb(230, 121, 25); @@ -246,6 +250,21 @@ $size-avatar-base: 44px; $size-avatar-large: 64px; $size-avatar-x-large: 114px; +/** + * @tokens Size Buttons + * @presenter Spacing + */ + + $size-button-base: 36px; + $size-button-small: 26px; + +/** + * @tokens Size Buttons + * @presenter Spacing + */ + + $size-icon-base: 16px; + /** * @tokens Shadow * @presenter Shadow @@ -291,6 +310,7 @@ $z-index-page-submenu: 2500; $z-index-page-header: 2000; $z-index-page-sidebar: 1500; $z-index-sticky: 100; +$z-index-post-card-link: 5; /** * @tokens Media Query diff --git a/webapp/components/CategoriesSelect/CategoriesSelect.vue b/webapp/components/CategoriesSelect/CategoriesSelect.vue index 493256546..3e240e435 100644 --- a/webapp/components/CategoriesSelect/CategoriesSelect.vue +++ b/webapp/components/CategoriesSelect/CategoriesSelect.vue @@ -3,16 +3,16 @@
- - {{ $t(`contribution.category.name.${category.slug}`) }} - +
diff --git a/webapp/components/CommentForm/CommentForm.spec.js b/webapp/components/CommentForm/CommentForm.spec.js index 47bc01982..5dde84008 100644 --- a/webapp/components/CommentForm/CommentForm.spec.js +++ b/webapp/components/CommentForm/CommentForm.spec.js @@ -74,7 +74,7 @@ describe('CommentForm.vue', () => { it('calls `clear` method when the cancel button is clicked', async () => { wrapper.vm.updateEditorContent('ok') - await wrapper.find('.cancelBtn').trigger('submit') + await wrapper.find('[data-test="cancel-button"]').trigger('submit') expect(cancelMethodSpy).toHaveBeenCalledTimes(1) }) @@ -162,13 +162,13 @@ describe('CommentForm.vue', () => { describe('cancel button is clicked', () => { it('calls `closeEditWindow` method', async () => { wrapper.vm.updateEditorContent('ok') - await wrapper.find('.cancelBtn').trigger('submit') + await wrapper.find('[data-test="cancel-button"]').trigger('submit') expect(closeMethodSpy).toHaveBeenCalledTimes(1) }) it('emits `showEditCommentMenu` event', async () => { wrapper.vm.updateEditorContent('ok') - await wrapper.find('.cancelBtn').trigger('submit') + await wrapper.find('[data-test="cancel-button"]').trigger('submit') expect(wrapper.emitted('showEditCommentMenu')).toEqual([[false]]) }) }) diff --git a/webapp/components/CommentForm/CommentForm.vue b/webapp/components/CommentForm/CommentForm.vue index 6cdd08af3..063a3d599 100644 --- a/webapp/components/CommentForm/CommentForm.vue +++ b/webapp/components/CommentForm/CommentForm.vue @@ -1,28 +1,22 @@ @@ -161,7 +162,7 @@ export default { .ds-modal { max-width: 600px !important; } -.ds-radio-option:not(.ds-button) { +.ds-radio-option { width: 100% !important; } .ds-radio-option-label { diff --git a/webapp/components/NotificationMenu/NotificationMenu.spec.js b/webapp/components/NotificationMenu/NotificationMenu.spec.js index 01c972d05..8020c8bb4 100644 --- a/webapp/components/NotificationMenu/NotificationMenu.spec.js +++ b/webapp/components/NotificationMenu/NotificationMenu.spec.js @@ -1,11 +1,11 @@ -import { config, shallowMount } from '@vue/test-utils' +import { config, mount } from '@vue/test-utils' import NotificationMenu from './NotificationMenu' const localVue = global.localVue localVue.filter('truncate', string => string) -config.stubs.dropdown = '' +config.stubs.dropdown = '' describe('NotificationMenu.vue', () => { let wrapper @@ -22,9 +22,9 @@ describe('NotificationMenu.vue', () => { } }) - describe('shallowMount', () => { + describe('mount', () => { const Wrapper = () => { - return shallowMount(NotificationMenu, { + return mount(NotificationMenu, { data, mocks, localVue, @@ -33,7 +33,7 @@ describe('NotificationMenu.vue', () => { it('counter displays 0', () => { wrapper = Wrapper() - expect(wrapper.find('ds-button-stub').text()).toEqual('0') + expect(wrapper.find('.count').text()).toEqual('0') }) it('no dropdown is rendered', () => { @@ -67,12 +67,12 @@ describe('NotificationMenu.vue', () => { it('counter displays 0', () => { wrapper = Wrapper() - expect(wrapper.find('ds-button-stub').text()).toEqual('0') + expect(wrapper.find('.count').text()).toEqual('0') }) - it('button is not primary', () => { + it('counter is not colored', () => { wrapper = Wrapper() - expect(wrapper.find('ds-button-stub').props('primary')).toBe(false) + expect(wrapper.find('.count').classes()).toContain('--inactive') }) }) @@ -130,12 +130,12 @@ describe('NotificationMenu.vue', () => { it('displays the number of unread notifications', () => { wrapper = Wrapper() - expect(wrapper.find('ds-button-stub').text()).toEqual('2') + expect(wrapper.find('.count').text()).toEqual('2') }) - it('renders primary button', () => { + it('renders the counter in red', () => { wrapper = Wrapper() - expect(wrapper.find('ds-button-stub').props('primary')).toBe(true) + expect(wrapper.find('.count').classes()).toContain('--danger') }) }) }) diff --git a/webapp/components/NotificationMenu/NotificationMenu.vue b/webapp/components/NotificationMenu/NotificationMenu.vue index 413102915..a3b085db9 100644 --- a/webapp/components/NotificationMenu/NotificationMenu.vue +++ b/webapp/components/NotificationMenu/NotificationMenu.vue @@ -1,12 +1,12 @@ diff --git a/webapp/pages/admin/users.vue b/webapp/pages/admin/users.vue index 6a7bf8adb..e56be70ab 100644 --- a/webapp/pages/admin/users.vue +++ b/webapp/pages/admin/users.vue @@ -12,7 +12,7 @@ /> - + @@ -50,14 +50,7 @@ {{ scope.row.createdAt | dateTime }} - - - - - - - - + {{ $t('admin.users.empty') }} @@ -69,8 +62,12 @@ import gql from 'graphql-tag' import { isEmail } from 'validator' import normalizeEmail from '~/components/utils/NormalizeEmail' +import HcPaginate from '~/components/Paginate/Paginate' export default { + components: { + HcPaginate, + }, data() { const pageSize = 15 return { diff --git a/webapp/pages/index.vue b/webapp/pages/index.vue index 6d0f8c669..c0b96ccbc 100644 --- a/webapp/pages/index.vue +++ b/webapp/pages/index.vue @@ -8,7 +8,7 @@
- {{ $t('donations.donate-now') }} + {{ $t('donations.donate-now') }}
@@ -43,14 +43,19 @@ - + + + @@ -238,7 +243,10 @@ export default { } } -.post-add-button { +.base-button.--circle.post-add-button { + height: 54px; + width: 54px; + font-size: 26px; z-index: 100; position: fixed; bottom: -5px; diff --git a/webapp/pages/profile/_id/_slug.vue b/webapp/pages/profile/_id/_slug.vue index 00e3648bd..e9ac89eed 100644 --- a/webapp/pages/profile/_id/_slug.vue +++ b/webapp/pages/profile/_id/_slug.vue @@ -73,9 +73,9 @@ @optimistic="optimisticFollow" @update="updateFollow" /> - + {{ $t('settings.blocked-users.unblock') }} - + diff --git a/webapp/pages/settings/embeds.vue b/webapp/pages/settings/embeds.vue index d842dbef0..22050c636 100644 --- a/webapp/pages/settings/embeds.vue +++ b/webapp/pages/settings/embeds.vue @@ -16,12 +16,12 @@ {{ $t('settings.embeds.status.change.question') }} - + {{ $t('settings.embeds.status.change.deny') }} - - + + {{ $t('settings.embeds.status.change.allow') }} - +

{{ $t('settings.embeds.info-description') }}

    diff --git a/webapp/pages/settings/index.vue b/webapp/pages/settings/index.vue index c37c27a1d..20034d5af 100644 --- a/webapp/pages/settings/index.vue +++ b/webapp/pages/settings/index.vue @@ -31,9 +31,9 @@ :placeholder="$t('settings.data.labelBio')" /> diff --git a/webapp/pages/settings/my-email-address/enter-nonce.vue b/webapp/pages/settings/my-email-address/enter-nonce.vue index 85755953a..91b2e269f 100644 --- a/webapp/pages/settings/my-email-address/enter-nonce.vue +++ b/webapp/pages/settings/my-email-address/enter-nonce.vue @@ -17,9 +17,9 @@ /> diff --git a/webapp/pages/settings/my-email-address/index.vue b/webapp/pages/settings/my-email-address/index.vue index 8b3889b0d..4e01bbb44 100644 --- a/webapp/pages/settings/my-email-address/index.vue +++ b/webapp/pages/settings/my-email-address/index.vue @@ -19,9 +19,9 @@ {{ backendErrors.message }} - + {{ $t('actions.save') }} - + diff --git a/webapp/pages/settings/my-social-media.spec.js b/webapp/pages/settings/my-social-media.spec.js index b1c9e0649..cf994e397 100644 --- a/webapp/pages/settings/my-social-media.spec.js +++ b/webapp/pages/settings/my-social-media.spec.js @@ -119,11 +119,11 @@ describe('my-social-media.vue', () => { }) it('displays the edit button', () => { - expect(wrapper.find('a[name="edit"]').exists()).toBe(true) + expect(wrapper.find('.base-button[data-test="edit-button"]').exists()).toBe(true) }) it('displays the delete button', () => { - expect(wrapper.find('a[name="delete"]').exists()).toBe(true) + expect(wrapper.find('.base-button[data-test="delete-button"]').exists()).toBe(true) }) }) @@ -138,7 +138,7 @@ describe('my-social-media.vue', () => { describe('editing social media link', () => { beforeEach(() => { - const editButton = wrapper.find('a[name="edit"]') + const editButton = wrapper.find('.base-button[data-test="edit-button"]') editButton.trigger('click') input = wrapper.find('input#editSocialMedia') }) @@ -169,7 +169,7 @@ describe('my-social-media.vue', () => { describe('deleting social media link', () => { beforeEach(() => { - const deleteButton = wrapper.find('a[name="delete"]') + const deleteButton = wrapper.find('.base-button[data-test="delete-button"]') deleteButton.trigger('click') }) diff --git a/webapp/pages/settings/my-social-media.vue b/webapp/pages/settings/my-social-media.vue index 677c4423d..6ed2f1bc6 100644 --- a/webapp/pages/settings/my-social-media.vue +++ b/webapp/pages/settings/my-social-media.vue @@ -24,22 +24,22 @@ {{ link.url }} | - - - - - - + + @@ -54,12 +54,12 @@ :placeholder="$t('settings.social-media.placeholder')" /> - + {{ editingLink.id ? $t('actions.save') : $t('settings.social-media.submit') }} - - + + {{ $t('actions.cancel') }} - + @@ -226,5 +226,10 @@ export default { .ds-list-item-prefix { align-self: center; } + + .ds-list-item-content { + display: flex; + align-items: center; + } } diff --git a/webapp/pages/settings/privacy.vue b/webapp/pages/settings/privacy.vue index 3decdefbe..f759926b7 100644 --- a/webapp/pages/settings/privacy.vue +++ b/webapp/pages/settings/privacy.vue @@ -4,7 +4,7 @@ - {{ $t('actions.save') }} + {{ $t('actions.save') }} diff --git a/webapp/pages/terms-and-conditions-confirm.vue b/webapp/pages/terms-and-conditions-confirm.vue index 24af8a23d..0716048b5 100644 --- a/webapp/pages/terms-and-conditions-confirm.vue +++ b/webapp/pages/terms-and-conditions-confirm.vue @@ -2,11 +2,11 @@

    - - + + {{ $t(`termsAndConditions.termsAndConditionsNewConfirmText`) }} - - + +

    @@ -17,7 +17,9 @@
    diff --git a/webapp/storybook/config.js b/webapp/storybook/config.js index 2631285e1..576136f92 100644 --- a/webapp/storybook/config.js +++ b/webapp/storybook/config.js @@ -2,6 +2,8 @@ import { addParameters, configure } from '@storybook/vue' import Vue from 'vue' import Vuex from 'vuex' import { action } from '@storybook/addon-actions' +// eslint-disable-next-line import/no-webpack-loader-syntax +import '!style-loader!css-loader!sass-loader!../assets/_new/styles/resets.scss' Vue.use(Vuex) Vue.component('nuxt-link', { @@ -54,4 +56,12 @@ function loadStories() { req.keys().forEach(req) } +// sort stories alphabetically +addParameters({ + options: { + storySort: (a, b) => + a[1].kind === b[1].kind ? 0 : a[1].id.localeCompare(b[1].id, { numeric: true }), + }, +}) + configure(loadStories, module)