Skip to content

Commit

Permalink
feat(NcHeaderButton): Add a button only alternative for the header menu
Browse files Browse the repository at this point in the history
This allows us to have one single place for styling the header actions,
as currently the button-only variants use custom styles (unified search, assistent).

Signed-off-by: Ferdinand Thiessen <[email protected]>
  • Loading branch information
susnux committed Sep 11, 2024
1 parent 73ee73b commit 93eeaec
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 38 deletions.
139 changes: 139 additions & 0 deletions src/components/NcHeaderButton/NcHeaderButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<!--
- SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->

<docs>
This component is made to be used in the Nextcloud top header,
similar to the NcHeaderMenu but to be used when only a trigger button is needed, e.g. when opening a dialog.

```
<template>
<div id="nextcloud-header">
<NcHeaderButton id="search-dialog"
aria-label="Search"
@click="showDialog = true">
<template #icon>
<Magnify />
</template>
</NcHeaderButton>

<NcDialog name="Search"
size="normal"
:open.sync="showDialog">
<NcTextField label="Search for files, comments, contacts…"
type="search"
:value.sync="query" />
<NcEmptyContent name="Search"
:description="query ? `No results for '${query}'` : 'Start typing to search'">
<template #icon>
<Magnify />
</template>
</NcEmptyContent>
</NcDialog>
</div>
</template>
<script>
import Magnify from 'vue-material-design-icons/Magnify'
export default {
components: {
Magnify,
},
data() {
return {
showDialog: false,
query: '',
}
},
}
</script>
<style>
#nextcloud-header {
display: flex;
justify-content: right;
background-color: var(--color-primary);
height: var(--header-height, 50px);
padding-right: 12px;
}
</style>
```
</docs>

<template>
<!-- We need a wrapper for server styles to apply -->
<div :id="id" class="header-menu">
<NcButton type="tertiary-no-background"
class="header-menu__trigger"
:aria-label="ariaLabel"
:aria-describedby="descriptionId"
size="large"
@click.prevent="$emit('click', $event)">
<template #icon>
<!-- @slot Icon trigger slot. Make sure the svg path
is at least 16px. Usually mdi icon works at 20px -->
<slot name="icon" />
</template>
</NcButton>

<span v-if="description"
:id="descriptionId"
class="header-menu__description hidden-visually">
{{ description }}
</span>
</div>
</template>

<script>
import GenRandomId from '../../utils/GenRandomId.js'
import NcButton from '../NcButton/index.js'
export default {
name: 'NcHeaderButton',
components: {
NcButton,
},
props: {
/**
* Unique id for this menu
*/
id: {
type: String,
required: true,
},
/**
* `aria-label` attribute of the button
*/
ariaLabel: {
type: String,
required: true,
},
/**
* Additional visually hidden description text for the button
*/
description: {
type: String,
default: null,
},
},
emits: [
'click',
],
data() {
return {
descriptionId: GenRandomId(),
}
},
}
</script>

<style lang="scss" scoped>
@import '../NcHeaderMenu/header-menu__trigger';
</style>
6 changes: 6 additions & 0 deletions src/components/NcHeaderButton/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

export { default } from './NcHeaderButton.vue'
50 changes: 12 additions & 38 deletions src/components/NcHeaderMenu/NcHeaderMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ This component is made to be used in the Nextcloud top header.
<Magnify />
</template>
<div>
<input placeholder="Search for files, comments, contacts..." type="search" style="width: 99%;" />
<NcTextField label="Search for files, comments, contacts…"
style="padding-inline: 8px;"
type="search"
:value.sync="query" />
<NcEmptyContent
name="Search"
description="Start typing to search">
:description="query ? `No results for '${query}'` : 'Start typing to search'">
<template #icon>
<Magnify />
</template>
Expand All @@ -34,6 +37,11 @@ export default {
components: {
Magnify,
},
data() {
return {
query: '',
}
},
}
</script>
<style>
Expand Down Expand Up @@ -328,33 +336,9 @@ export default {
// Also used for menu top-right positioning
$externalMargin: 8px;
.header-menu {
position: relative;
width: var(--header-height);
height: var(--header-height);
#{&}__trigger {
--button-size: var(--header-height) !important;
height: var(--header-height);
opacity: .85;
// header is filled with primary or image background
filter: none !important;
color: var(--color-background-plain-text, var(--color-primary-text)) !important;
&:focus-visible {
outline: none !important;
box-shadow: none !important;
}
}
&--opened &__trigger,
&__trigger:hover,
&__trigger:focus,
&__trigger:active {
opacity: 1;
}
@import './header-menu__trigger';
.header-menu {
&__wrapper {
position: fixed;
z-index: 2000;
Expand Down Expand Up @@ -393,14 +377,4 @@ $externalMargin: 8px;
}
}
}
@media only screen and (max-width: $breakpoint-small-mobile) {
.header-menu {
width: var(--default-clickable-area);
#{&}__trigger {
--button-size: var(--default-clickable-area) !important;
}
}
}
</style>
37 changes: 37 additions & 0 deletions src/components/NcHeaderMenu/header-menu__trigger.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.header-menu {
position: relative;
width: var(--header-height);
height: var(--header-height);

#{&}__trigger {
--button-size: var(--header-height) !important;
height: var(--header-height);
opacity: .85;

// header is filled with primary or image background
filter: none !important;
color: var(--color-background-plain-text, var(--color-primary-text)) !important;

&:focus-visible {
outline: none !important;
box-shadow: none !important;
}
}

&--opened &__trigger,
&__trigger:hover,
&__trigger:focus,
&__trigger:active {
opacity: 1;
}
}

@media only screen and (max-width: $breakpoint-small-mobile) {
.header-menu {
width: var(--default-clickable-area);

#{&}__trigger {
--button-size: var(--default-clickable-area) !important;
}
}
}
1 change: 1 addition & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export { default as NcEllipsisedOption } from './NcEllipsisedOption/index.js'
export { default as NcEmojiPicker } from './NcEmojiPicker/index.js'
export { default as NcEmptyContent } from './NcEmptyContent/index.js'
export { default as NcGuestContent } from './NcGuestContent/index.js'
export { default as NcHeaderButton } from './NcHeaderButton/index.js'
export { default as NcHeaderMenu } from './NcHeaderMenu/index.js'
export { default as NcHighlight } from './NcHighlight/index.js'
export { default as NcIconSvgWrapper } from './NcIconSvgWrapper/index.js'
Expand Down
7 changes: 7 additions & 0 deletions styleguide.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ module.exports = async () => {
'src/components/NcContent/*.vue',
'src/components/NcDashboard*/*.vue',
'src/components/NcDialog*/*.vue',
'src/components/NcHeader*/*.vue',
'src/components/NcListItem*/*.vue',
'src/components/NcMultiselect*/*.vue',
'src/components/NcRichContenteditable/!(NcRichContenteditable).vue',
Expand Down Expand Up @@ -253,6 +254,12 @@ module.exports = async () => {
'src/components/NcTextArea/*.vue',
],
},
{
name: 'NcHeader',
components: [
'src/components/NcHeader*/*.vue',
],
},
{
name: 'NcListItems',
components: [
Expand Down

0 comments on commit 93eeaec

Please sign in to comment.