Skip to content

Commit

Permalink
Merge pull request #120 from bethinkpl/IT-4121-vue3-poc
Browse files Browse the repository at this point in the history
IT-5005 | Vue 3
  • Loading branch information
kvas-damian authored Apr 20, 2023
2 parents 24f5d6c + e20b8be commit f834909
Show file tree
Hide file tree
Showing 101 changed files with 6,491 additions and 8,153 deletions.
4 changes: 4 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,9 @@ module.exports = {
// Required for Vue 3 migration
'vue/no-deprecated-slot-attribute': 'error',
'vue/no-deprecated-slot-scope-attribute': 'error',

// https://v3-migration.vuejs.org/breaking-changes/key-attribute.html
'vue/no-v-for-template-key': ['off'],
'vue/no-v-for-template-key-on-child': 'error',
},
};
24 changes: 16 additions & 8 deletions .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,36 @@ const path = require('path');
module.exports = {
stories: ['../lib/**/*.stories.@(js|mdx|ts)'],
addons: [
'@storybook/addon-actions',
'@storybook/addon-docs',
'@storybook/addon-controls',
'@storybook/addon-actions',
'@storybook/addon-storysource',
'@storybook/addon-viewport',
'storybook-addon-designs',
],
core: {
builder: 'webpack5',
},
webpackFinal: async (config) => {
let vueLoaderRule = config.module.rules.find(
(r) =>
r.test &&
r.test.toString().includes('vue') &&
r.loader &&
r.loader.includes('vue-loader'),
);

// `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
// You can change the configuration based on that.
// 'PRODUCTION' is used when building the static version of storybook.

// // Storybook provides file-loader rule for svg. We have to disable it to make vue-svg-loader working
// // Storybook provides assets rule for svg. We have to disable it to make vue-svg-loader working
let fileLoaderRule = config.module.rules.find(
(r) =>
// it can be another rule with file loader
// we should get only svg related
r.test &&
r.test.toString().includes('svg') &&
// file-loader might be resolved to js file path so "endsWith" is not reliable enough
r.loader &&
r.loader.includes('file-loader'),
r.type &&
r.type === 'asset/resource',
);
fileLoaderRule.test = new RegExp(
fileLoaderRule.test.source.replace('svg|', ''),
Expand All @@ -51,7 +59,7 @@ module.exports = {
},
{
test: /\.svg$/,
use: ['vue-svg-loader'],
use: ['vue-loader', 'vue-svg-loader'],
},
);

Expand Down
9 changes: 3 additions & 6 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,14 @@ module.exports = {
transform: {
'^.+\\.js$': 'babel-jest',
'^.+\\.ts$': 'ts-jest',
'.*\\.(vue)$': 'vue-jest',
'.*\\.(vue)$': '@vue/vue3-jest',
'^.+\\.scss': '<rootDir>/lib/js/tests/emptyTransformer.ts',
'^.+\\.svg$': '<rootDir>/lib/js/tests/emptyTransformer.ts',
},
moduleFileExtensions: ['js', 'vue', 'json', 'ts'],

setupFilesAfterEnv: ['<rootDir>/lib/js/typings.d.ts', '<rootDir>/lib/js/tests/globals.ts'],
globals: {
'ts-jest': {
tsconfig: './tsconfig.json',
isolatedModules: true,
},
testEnvironmentOptions: {
customExportConditions: ['node', 'node-addons'],
},
};
11 changes: 3 additions & 8 deletions lib/js/components/Badges/Badge/Badge.spec.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';

import Badge from './Badge.vue';
import { BADGE_COLORS } from './Badge.consts';

describe('Badge', () => {
const createComponent = ({ label = '' } = {}) => {
const localVue = createLocalVue();

return shallowMount(Badge, {
localVue,
mocks: {},
propsData: {
props: {
label,
color: BADGE_COLORS.NEUTRAL,
},
stubs: {},
} as any,
});
};

Expand Down
8 changes: 5 additions & 3 deletions lib/js/components/Badges/Badge/Badge.stories.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import Badge from './Badge.vue';
import { BADGE_COLORS } from './Badge.consts';

import { Args, ArgTypes, Meta, StoryFn } from '@storybook/vue';
import { Args, ArgTypes, Meta, StoryFn } from '@storybook/vue3';

export default {
title: 'Components/Badges/Badge',
component: Badge,
} as Meta<typeof Badge>;

const StoryTemplate: StoryFn<typeof Badge> = (argTypes) => ({
const StoryTemplate: StoryFn<typeof Badge> = (args) => ({
components: { Badge },
props: Object.keys(argTypes),
setup() {
return { ...args };
},
template:
'<div style="display: flex"><Badge :color="color" :label="label"><img alt="Badge" style="width: 100%; height: 100%" :src="iconUrl" /></Badge></div>',
});
Expand Down
10 changes: 3 additions & 7 deletions lib/js/components/Badges/BadgeScore/BadgeScore.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';

import BadgeScore from './BadgeScore.vue';
import { BADGE_SCORE_COLORS, BADGE_SCORE_SIZES } from './BadgeScore.consts';
Expand All @@ -9,16 +9,12 @@ describe('BadgeScore', () => {
color = BADGE_SCORE_COLORS.SUCCESS as string,
size = BADGE_SCORE_SIZES.MEDIUM as string,
} = {}) => {
const localVue = createLocalVue();

return shallowMount(BadgeScore, {
localVue,
mocks: {},
propsData: {
props: {
color,
size,
text,
},
} as any,
});
};

Expand Down
14 changes: 9 additions & 5 deletions lib/js/components/Badges/BadgeScore/BadgeScore.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import BadgeScore from './BadgeScore.vue';
import { BADGE_SCORE_COLORS, BADGE_SCORE_SIZES } from './BadgeScore.consts';
import { ICONS } from '../../Icons/Icon';

import { Meta, StoryFn } from '@storybook/vue';
import { Meta, StoryFn } from '@storybook/vue3';

export default {
title: 'Components/Badges/BadgeScore',
Expand All @@ -17,9 +17,11 @@ const StoryTemplate: StoryFn<{
size: string;
icon: string;
fullWidth: boolean;
}> = (argTypes) => ({
}> = (args) => ({
components: { BadgeScore },
props: Object.keys(argTypes),
setup() {
return { ...args };
},
template:
'<badge-score :color="color" :suffix="suffix" :text="text" :size="size" :icon="ICONS[icon]" :fullWidth="fullWidth" />',
data() {
Expand Down Expand Up @@ -62,9 +64,11 @@ Interactive.parameters = {
};

/* STATIC STORIES */
const StaticStoryTemplate: StoryFn<{}> = (argTypes) => ({
const StaticStoryTemplate: StoryFn<{}> = (args) => ({
components: { BadgeScore },
props: Object.keys(argTypes),
setup() {
return { ...args };
},
template:
'<badge-score :color="BADGE_SCORE_COLORS.WARNING" suffix="%" text="1" :full-width="fullWidth" />',
data() {
Expand Down
7 changes: 4 additions & 3 deletions lib/js/components/Badges/BadgeScore/BadgeScore.vue
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ $badge-score-colors: (
min-width: $badge-score-small-min-width;
padding: $space-xxs $space-xxs;
#{$self}__suffix {
@include label-l-default-bold;
}
Expand All @@ -159,7 +160,7 @@ $badge-score-colors: (
<script lang="ts">
import { BADGE_SCORE_COLORS, BADGE_SCORE_SIZES } from './BadgeScore.consts';
import WnlIcon, { ICONS, ICON_SIZES } from '../../Icons/Icon';
import { VueConstructor } from 'vue';
import { toRaw } from 'vue';
export default {
name: 'BadgeScore',
Expand All @@ -186,8 +187,8 @@ export default {
icon: {
type: Object,
default: null,
validator(icon: VueConstructor) {
return Object.values(ICONS).includes(icon);
validator(icon) {
return Object.values(ICONS).includes(toRaw(icon));
},
},
size: {
Expand Down
47 changes: 25 additions & 22 deletions lib/js/components/Banner/Banner.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@ import Banner from './Banner.vue';
import { BANNER_COLORS, BANNER_LAYOUTS } from './Banner.consts';
import { ICONS } from '../Icons/Icon';

import { Args, ArgTypes, Meta, StoryFn } from '@storybook/vue';
import { Args, ArgTypes, Meta, StoryFn } from '@storybook/vue3';

export default {
title: 'Components/Banner',
component: Banner,
} as Meta<typeof Banner>;

const StoryTemplate: StoryFn<typeof Banner> = (argTypes, { updateArgs }) => ({
const StoryTemplate: StoryFn<typeof Banner> = (args, { updateArgs }) => ({
components: { Banner },
props: Object.keys(argTypes),
setup() {
return { ...args };
},
data() {
return {
ICONS: Object.freeze(ICONS),
Expand All @@ -24,25 +26,26 @@ const StoryTemplate: StoryFn<typeof Banner> = (argTypes, { updateArgs }) => ({
});
},
},
template: `<banner
:closable='closable'
:icon='ICONS[icon]'
:color='color'
:title='title'
:buttonText='buttonText'
:layout='layout'
:is-expanded='isExpanded'
:is-icon-hidden-on-mobile='isIconHiddenOnMobile'
@update:isExpanded='onIsExpandedUpdated'
>
<template v-slot:defaultText><span v-if='defaultText' v-html='defaultText'/></template>
<template v-slot:expandedText>
<div v-if='expandedText' v-html='expandedText'/>
</template>
<template v-slot:rightSlot>
<div v-if='rightSlot' v-html='rightSlot'/>
</template>
</banner>`,
template: `
<banner
:closable="closable"
:icon="ICONS[icon]"
:color="color"
:title="title"
:buttonText="buttonText"
:layout="layout"
:is-expanded="isExpanded"
:is-icon-hidden-on-mobile="isIconHiddenOnMobile"
@update:isExpanded="onIsExpandedUpdated"
>
<template #defaultText><span v-html="defaultText" /></template>
<template v-if="expandedText" #expandedText>
<div v-html="expandedText" />
</template>
<template v-if="rightSlot" #rightSlot>
<div v-html="rightSlot" />
</template>
</banner>`,
});

export const Interactive = StoryTemplate.bind({});
Expand Down
39 changes: 11 additions & 28 deletions lib/js/components/Banner/Banner.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@
<div class="ds-banner__textWrapper">
<div class="ds-banner__titleWrapper">
<div class="ds-banner__title" v-text="title" />
<div
v-if="$slots.defaultText && $slots.defaultText.length > 0"
class="ds-banner__defaultText"
>
<div v-if="$slots.defaultText" class="ds-banner__defaultText">
<slot name="defaultText" />
</div>
</div>
Expand All @@ -28,50 +25,38 @@
:color="BUTTON_COLORS.NEUTRAL"
:type="BUTTON_TYPES.OUTLINED"
:size="BUTTON_SIZES.SMALL"
@click.native="$emit('button-clicked')"
@click="$emit('button-clicked')"
>{{ buttonText }}
</ds-button>
</div>
<div
v-if="$slots.rightSlot && $slots.rightSlot.length > 0"
class="ds-banner__rightSlot"
>
<div v-if="$slots.rightSlot" class="ds-banner__rightSlot">
<slot name="rightSlot" />
</div>
</div>
</div>
</div>
<div
v-if="$slots.expandedText && $slots.expandedText.length > 0"
class="ds-banner__expander"
>
<div v-if="$slots.expandedText" class="ds-banner__expander">
<ds-icon-button
:size="ICON_BUTTON_SIZES.SMALL"
:icon="isExpandedInternal ? ICONS.FA_CHEVRON_UP : ICONS.FA_CHEVRON_DOWN"
:color="ICON_BUTTON_COLORS.NEUTRAL"
:radius="BUTTON_RADIUSES.CAPSULE"
:touchable="false"
@click.native="toggleExpandedText"
@click="toggleExpandedText"
/>
</div>
<div
v-if="!($slots.expandedText && $slots.expandedText.length > 0) && closable"
class="ds-banner__close"
>
<div v-if="!$slots.expandedText && closable" class="ds-banner__close">
<ds-icon-button
:size="ICON_BUTTON_SIZES.SMALL"
:icon="ICONS.FA_XMARK"
:color="ICON_BUTTON_COLORS.NEUTRAL"
:radius="BUTTON_RADIUSES.CAPSULE"
:touchable="false"
@click.native="$emit('close')"
@click="$emit('close')"
/>
</div>
</div>
<div
v-if="$slots.expandedText && $slots.expandedText.length > 0 && isExpandedInternal"
class="ds-banner__expandedContainer"
>
<div v-if="$slots.expandedText && isExpandedInternal" class="ds-banner__expandedContainer">
<ds-divider :prominence="DIVIDER_PROMINENCES.STRONG" />
<div class="ds-banner__expandedText">
<slot name="expandedText" />
Expand Down Expand Up @@ -299,9 +284,6 @@
</style>

<script lang="ts">
import { VueConstructor } from 'vue';
import { Prop } from 'vue/types/options';
import DsButton, {
BUTTON_RADIUSES,
BUTTON_TYPES,
Expand All @@ -313,6 +295,7 @@ import DsIcon from '../Icons/Icon';
import DsIconButton, { ICON_BUTTON_COLORS, ICON_BUTTON_SIZES } from '../Buttons/IconButton';
import { ICONS } from '../Icons/Icon';
import { BANNER_COLORS, BANNER_LAYOUTS } from './Banner.consts';
import { toRaw } from 'vue';
export default {
name: 'Banner',
Expand All @@ -324,9 +307,9 @@ export default {
},
props: {
icon: {
type: Object as Prop<VueConstructor>,
type: Object,
default: null,
validator: (icon: VueConstructor) => Object.values(ICONS).includes(icon),
validator: (icon) => Object.values(ICONS).includes(toRaw(icon)),
},
buttonText: {
type: String,
Expand Down
Loading

0 comments on commit f834909

Please sign in to comment.