diff --git a/public/ebury-logo-sm.png b/public/ebury-logo-sm.png new file mode 100644 index 000000000..2ad6056f2 Binary files /dev/null and b/public/ebury-logo-sm.png differ diff --git a/src/components/ec-mobile-header/__snapshots__/ec-mobile-header.spec.ts.snap b/src/components/ec-mobile-header/__snapshots__/ec-mobile-header.spec.ts.snap new file mode 100644 index 000000000..832e84d10 --- /dev/null +++ b/src/components/ec-mobile-header/__snapshots__/ec-mobile-header.spec.ts.snap @@ -0,0 +1,32 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`EcMobileHeader > should render properly 1`] = ` +
+ + +
+`; diff --git a/src/components/ec-mobile-header/ec-mobile-header.spec.ts b/src/components/ec-mobile-header/ec-mobile-header.spec.ts new file mode 100644 index 000000000..f4fda027e --- /dev/null +++ b/src/components/ec-mobile-header/ec-mobile-header.spec.ts @@ -0,0 +1,22 @@ +import { type ComponentMountingOptions, mount } from '@vue/test-utils'; + +import EcMobileHeader from './ec-mobile-header.vue'; + +describe('EcMobileHeader', () => { + const logoTemplate = ''; + + function mountMobileHeader(mountOpts?: ComponentMountingOptions) { + return mount(EcMobileHeader, { + ...mountOpts, + }); + } + + it('should render properly', () => { + const wrapper = mountMobileHeader({ + slots: { + logo: logoTemplate, + }, + }); + expect(wrapper.element).toMatchSnapshot(); + }); +}); diff --git a/src/components/ec-mobile-header/ec-mobile-header.story.ts b/src/components/ec-mobile-header/ec-mobile-header.story.ts new file mode 100644 index 000000000..b94c5be90 --- /dev/null +++ b/src/components/ec-mobile-header/ec-mobile-header.story.ts @@ -0,0 +1,50 @@ +import type { Meta, StoryFn } from '@storybook/vue3'; +import { computed, ref, watchEffect } from 'vue'; + +import EcMobileHeader from './ec-mobile-header.vue'; + +enum LogoName { + EBURY = 'ebury-logo-sm', + CHAMELEON = 'ebury-chameleon-logo', +} + +interface StoryArgs { + logo: string, +} + +export default { + title: 'Mobile Header', + component: EcMobileHeader, +} as Meta; + +export const basic: StoryFn = storyArgs => ({ + components: { EcMobileHeader }, + setup() { + const logo = ref(''); + watchEffect(() => { + logo.value = storyArgs.logo; + }); + const logoPath = computed(() => `/${logo.value}.png`); + return { + logoPath, + }; + }, + template: ` + + + + `, +}); + +basic.args = { + logo: LogoName.EBURY, +}; + +basic.argTypes = { + logo: { + options: Object.values(LogoName), + control: { type: 'select' }, + }, +}; diff --git a/src/components/ec-mobile-header/ec-mobile-header.vue b/src/components/ec-mobile-header/ec-mobile-header.vue new file mode 100644 index 000000000..8e516f66b --- /dev/null +++ b/src/components/ec-mobile-header/ec-mobile-header.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/src/components/ec-mobile-header/index.ts b/src/components/ec-mobile-header/index.ts new file mode 100644 index 000000000..b369c6cf2 --- /dev/null +++ b/src/components/ec-mobile-header/index.ts @@ -0,0 +1 @@ +export { default } from './ec-mobile-header.vue'; diff --git a/src/components/ec-navigation/__snapshots__/ec-navigation.spec.ts.snap b/src/components/ec-navigation/__snapshots__/ec-navigation.spec.ts.snap index 3bdd37dd1..d1597896b 100644 --- a/src/components/ec-navigation/__snapshots__/ec-navigation.spec.ts.snap +++ b/src/components/ec-navigation/__snapshots__/ec-navigation.spec.ts.snap @@ -273,6 +273,40 @@ exports[`EcNavigation > should render branding logo and name when given 1`] = ` `; +exports[`EcNavigation > should render mobile header if "isResponsive" prop is true 1`] = ` +
+ + +
+`; + exports[`EcNavigation > should render with custom attributes 1`] = `
{ expect(wrapper.element).toMatchSnapshot(); expect(wrapper.findAllByDataTest('ec-navigation__block').length).toBe(5); }); + + it('should render mobile header if "isResponsive" prop is true', () => { + const wrapper = mountNavigation({ + isResponsive: true, + }); + + expect(wrapper.element).toMatchSnapshot(); + }); }); diff --git a/src/components/ec-navigation/ec-navigation.story.ts b/src/components/ec-navigation/ec-navigation.story.ts index 6aba9f2c8..f0ce7a64e 100644 --- a/src/components/ec-navigation/ec-navigation.story.ts +++ b/src/components/ec-navigation/ec-navigation.story.ts @@ -1,4 +1,5 @@ import type { Meta, StoryFn } from '@storybook/vue3'; +import { useMediaQuery } from '@vueuse/core'; import { ref, watchEffect } from 'vue'; import { fixedContainerDecorator } from '../../../.storybook/utils'; @@ -83,3 +84,79 @@ basic.args = { showBrandingLogo: true, showCopyright: true, }; + +export const responsive: StoryFn = storyArgs => ({ + components: { EcNavigation }, + setup() { + const showCopyright = ref(false); + const isCollapsable = ref(false); + const isCollapsed = ref(false); + const isResponsive = ref(false); + const args = ref({}); + + watchEffect(() => { + const { + showCopyright: showCopyrightFromArgs, + isCollapsable: isCollapsableFromArgs, + isCollapsed: isCollapsedFromArgs, + isResponsive: isResponsiveFromArgs, + ...rest + } = storyArgs; + showCopyright.value = showCopyrightFromArgs; + isCollapsable.value = isCollapsableFromArgs; + isCollapsed.value = isCollapsedFromArgs; + isResponsive.value = isResponsiveFromArgs || useMediaQuery('(max-width: 1279px)').value; + args.value = rest; + }); + + return { + showCopyright, + isCollapsable, + isCollapsed, + isResponsive, + args, + styles: ref({ + placeholder: { + backgroundColor: 'hsla(var(--ec-gray-color-level-8), .1)', + }, + }), + }; + }, + template: ` + + + + + + + + `, +}); + +responsive.args = { + branding: { + name: 'My Branding', + logo: '/ebury-logo-sm.png', + }, + isCollapsable: false, + isCollapsed: false, + showBrandingLogo: true, + showCopyright: true, +}; diff --git a/src/components/ec-navigation/ec-navigation.vue b/src/components/ec-navigation/ec-navigation.vue index 8666b295f..f779a5739 100644 --- a/src/components/ec-navigation/ec-navigation.vue +++ b/src/components/ec-navigation/ec-navigation.vue @@ -1,5 +1,16 @@