Skip to content
This repository has been archived by the owner on Apr 30, 2024. It is now read-only.

Commit

Permalink
Merge pull request #724 from obulat/vue_header
Browse files Browse the repository at this point in the history
Vue header
  • Loading branch information
zackkrida authored Nov 16, 2020
2 parents 6ce5af9 + 7f21690 commit 67ec509
Show file tree
Hide file tree
Showing 8 changed files with 278 additions and 33 deletions.
15 changes: 6 additions & 9 deletions packages/vue-vocabulary/.storybook/main.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
module.exports = {
stories: [
'./meta/*.stories.*',
'../src/**/*.stories.*'
],
stories: ["./meta/*.stories.*", "../src/**/*.stories.*"],
addons: [
'@storybook/addon-essentials',
'@storybook/addon-docs',
'@storybook/addon-a11y'
]
}
"@storybook/addon-docs",
"@storybook/addon-essentials",
"@storybook/addon-a11y",
],
};
8 changes: 4 additions & 4 deletions packages/vue-vocabulary/.storybook/meta/usage.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@ Then in the component containing Vocabulary components, import the required comp
components using Vue.component for global registration or in the components dictionary within your component definition.

```js
import { Header, Footer, Locale } from '@creativecommons/vue-vocabulary'
import { VHeader, Footer, Locale } from '@creativecommons/vue-vocabulary'

export default {
components: {
Header,
VHeader,
Footer,
Locale
}
},
...
}
```
Expand All @@ -70,7 +70,7 @@ And your template can go like this.

```html
<div class="index">
<Header app-name="My App"/>
<VHeader app-name="My App"/>
<Footer><Locale/></Footer>
</div>
```
Expand Down
12 changes: 9 additions & 3 deletions packages/vue-vocabulary/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ import Tab from './layouts/Tabs/Tab'
import Tabs from './layouts/Tabs/Tabs'
import AppModal from './patterns/AppModal/AppModal'
import Footer from './patterns/Footer/Footer'
import Header from './patterns/Header/Header'
import Locale from './patterns/Locale/Locale'
import NavDropdown from './patterns/VHeader/NavDropdown'
import NavItem from './patterns/VHeader/NavItem'
import VHeader from './patterns/VHeader/VHeader'
import SlotRenderer from './utils/SlotRenderer/SlotRenderer'

// Export individual components
Expand All @@ -31,8 +33,10 @@ export {
Tabs,
AppModal,
Footer,
Header,
Locale,
NavDropdown,
NavItem,
VHeader,
SlotRenderer
}

Expand All @@ -49,8 +53,10 @@ export default {
Vue.component('Tabs', Tabs)
Vue.component('AppModal', AppModal)
Vue.component('Footer', Footer)
Vue.component('Header', Header)
Vue.component('Locale', Locale)
Vue.component('NavDropdown', NavDropdown)
Vue.component('NavItem', NavItem)
Vue.component('VHeader', VHeader)
Vue.component('SlotRenderer', SlotRenderer)
}
}
17 changes: 0 additions & 17 deletions packages/vue-vocabulary/src/patterns/Header/Header.vue

This file was deleted.

71 changes: 71 additions & 0 deletions packages/vue-vocabulary/src/patterns/VHeader/NavDropdown.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<template>
<div
class="navbar-item has-dropdown is-hoverable"
ref="outerDiv"
@mouseenter="openMenu"
@mouseleave="closeMenu"
>
<button
class="navbar-link is-arrowless"
aria-haspopup="menu"
aria-expanded="false"
ref="opener"
@click="toggleMenu"
>
{{ label }}
<!-- <span class="icon"><CaretDown /></span>-->
<i class="icon caret-down" />
</button>
<div class="navbar-dropdown">
<slot />
</div>
</div>
</template>

<script>
// import CaretDown from '@creativecommons/fonts/dist/assets/svg/arrows/caret-down.svg?inline'
export default {
name: "NavDropdown",
// components: {
// CaretDown
// },
data() {
return {
isOpen: false,
};
},
props: {
label: {
type: String,
required: true,
},
},
methods: {
openMenu() {
this.isOpen = true;
this.$refs.opener.setAttribute("aria-expanded", "true");
},
closeMenu() {
this.isOpen = false;
this.$refs.opener.setAttribute("aria-expanded", "false");
},
toggleMenu() {
this.isOpen = !this.isOpen;
const ariaExpanded = this.$refs.opener.getAttribute("aria-expanded");
this.$refs.opener.setAttribute("aria-expanded", `${!ariaExpanded}`);
},
},
};
</script>

<style scoped>
.navbar-link {
background: transparent;
border: none;
font-family: "Roboto Condensed", sans-serif;
font-size: 1.25rem;
font-weight: bold;
text-transform: uppercase;
line-height: 1.5;
}
</style>
54 changes: 54 additions & 0 deletions packages/vue-vocabulary/src/patterns/VHeader/NavItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<template>
<component
:is="tag"
class="navbar-item navbar-link is-arrowless"
:class="itemClasses"
v-bind="$attrs"
tabindex="0"
v-on="$listeners"
>{{ label }}
<!-- <span class="icon"><ExternalLink /></span>-->
<i class="icon external-link" v-if="isExternal" />
</component>
</template>

<script>
// import ExternalLink from '@creativecommons/fonts/dist/assets/svg/symbols/external-link.svg?inline'
// prettier-ignore
export default {
name: 'NavItem',
// components: {
// ExternalLink
// },
props: {
isExternal: {
type: Boolean,
default: () => false,
required: false
},
label: {
type: String,
required: true
},
href: {
type: String,
required: true
},
itemClasses: {
type: Object,
default: () => ({})
},
tag: {
type: String,
default: 'a'
}
}
}
</script>

<style scoped>
.navbar-item {
cursor: pointer;
background: white;
}
</style>
54 changes: 54 additions & 0 deletions packages/vue-vocabulary/src/patterns/VHeader/VHeader.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import VHeader from "./VHeader";
import ChooserLogo from "@creativecommons/vocabulary/assets/logos/products/chooser.svg?inline";
import NavItem from "./NavItem";
import NavDropdown from "./NavDropdown";
import { addDescription } from "../../utils/addDescription";

export default {
title: "Elements/VHeader",
component: VHeader,
};

let menuItems = `
<NavItem tag="a" href="/whatever" label="Item One" />
<NavItem tag="a" href="/whatever" label="Item External" :isExternal="true" />
<NavDropdown label="Item Three">
<NavItem tag="a" href="/whatever" label="Item Three A" />
<NavItem tag="a" href="/whatever" label="Item Three B" />
</NavDropdown>`;

const Template = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { VHeader, NavItem, NavDropdown },
template: `<VHeader v-bind="$props"><template #menu-items>${menuItems}</template></VHeader>`,
});

export const Default = Template.bind({});

export const ChooserHeader = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { VHeader, NavItem, ChooserLogo },
template: `<VHeader v-bind="$props">
<template #logo><ChooserLogo /></template>
<template #menu-items>
<NavItem tag="a" href="https://docs.google.com/forms/d/e/1FAIpQLSfF7MCKxlPsPuMn17v_sLYWMkxBkudQSPXCXoJKjh5GCtx63g/viewform" label="Feedback" :isExternal="true" />
</template></VHeader>`,
});
addDescription(
ChooserHeader,
"This is a sample header for the Chooser page. It uses `<ChooserLogo />` svg component as the logo, and one `<NavItem>` component."
);

export const IntlHeader = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { VHeader, NavItem, ChooserLogo },
template: `<VHeader v-bind="$props">
<template #menu-items>
<NavItem tag="a" href="/menu_item" :label="$t('Menu Item')" />
<NavItem tag="a" href="/menu_item" :label="$t('Menu Item')" :isExternal="true" />
</template></VHeader>`,
});
addDescription(
IntlHeader,
"When using i18n, you should pass translated strings to the header"
);
80 changes: 80 additions & 0 deletions packages/vue-vocabulary/src/patterns/VHeader/VHeader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<template>
<header class="vocab header">
<nav class="navbar" :aria-label="$t('header.aria.primary')">
<div class="navbar-brand has-color-white">
<a class="logo" href="/">
<!--@slot The Vue component with the site's logo -->
<slot name="logo">
<CCSearchLogo />
</slot>
</a>
<a
role="button"
:class="{ ['navbar-burger']: true, ['is-active']: isBurgerMenuActive }"
:aria-label="$t('header.aria.menu')"
aria-expanded="false"
@click="toggleBurgerActive"
@keyup.enter="toggleBurgerActive"
>
<span aria-hidden="true" />
<span aria-hidden="true" />
<span aria-hidden="true" />
</a>
</div>
<div :class="{ ['navbar-menu']: true, ['is-active']: isBurgerMenuActive }">
<div class="navbar-end">
<!--@slot Menu items, can be `NavItem`, `NavDropdown` -->
<slot name="menu-items">
<NavItem is="a" href="/item_one" label="Item One" />
<NavItem href="/item_two" label="Item Two" />
<NavDropdown label="Item Three">
<NavItem href="/item_three_a" label="Item Three A" />
<NavItem is="a" href="/item_three_b" label="Item Three B" />
</NavDropdown>
</slot>
</div>
</div>
</nav>
</header>
</template>

<script>
/**
* ### VHeader opens the page.
*
* The header displays information about the site such as its branding and
* name as well as navigation links.
*/
import NavItem from "./NavItem";
import NavDropdown from "./NavDropdown";
import CCSearchLogo from "@creativecommons/vocabulary/assets/logos/products/search.svg?inline";
export default {
name: "VHeader",
components: {
CCSearchLogo,
NavItem,
NavDropdown,
},
data: () => ({ isBurgerMenuActive: false }),
methods: {
toggleBurgerActive() {
this.isBurgerMenuActive = !this.isBurgerMenuActive;
},
},
};
</script>
<style lang="scss" scoped>
@import "~@creativecommons/vocabulary/scss/vocabulary";
.logo {
color: black;
&:hover {
color: black;
}
svg {
height: 100%;
width: auto;
}
}
</style>

0 comments on commit 67ec509

Please sign in to comment.