Skip to content

Commit

Permalink
feat(NavDrawer): navigation drawer resizeable
Browse files Browse the repository at this point in the history
  • Loading branch information
gravitano committed Sep 8, 2023
1 parent d9cec7b commit 2b58444
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 9 deletions.
25 changes: 25 additions & 0 deletions packages/nav-drawer/src/NavDrawer.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {ref} from 'vue';
import Button from '@morpheme/button';
import {colors} from './colors';
import NavDrawerCustom from './stories/NavDrawerCustom.vue';
import NavDrawerResizer from './NavDrawerResizer.vue';

export default {
title: 'Components/NavigationDrawer',
Expand Down Expand Up @@ -409,3 +410,27 @@ export const Top: StoryFn<typeof NavDrawer> = (args) => ({
</main>
`,
});

export const Resizer: StoryFn<typeof NavDrawer> = (args) => ({
components: {NavDrawer, Button},
setup() {
const isOpen = ref(true);

return {args, isOpen};
},
template: `
<NavDrawer
v-model="isOpen"
color="primary"
shadow="lg"
expand-on-resizer-click
>
<p class="font-semibold p-4 truncate">
Hover on the edge to resize
</p>
</NavDrawer>
<main>
Main content
</main>
`,
});
74 changes: 66 additions & 8 deletions packages/nav-drawer/src/NavDrawer.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<script setup lang="ts">
import {useVModel} from '@vueuse/core';
import {computed} from 'vue';
import {computed, ref, watch} from 'vue';
import {Colors} from './colors';
import {navDrawerHeights, NavDrawerHeights} from './types';
import {useDraggable} from '@vueuse/core';
export interface Props {
color?: Colors | string;
Expand All @@ -23,6 +24,12 @@ export interface Props {
expandOnHover?: boolean;
expanded?: boolean;
height?: NavDrawerHeights | string;
resizer?: boolean;
maxWidth?: number;
minWidth?: number;
miniOnResizerClick?: boolean;
hideOnResizerClick?: boolean;
expandOnResizerClick?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
Expand All @@ -33,21 +40,26 @@ const props = withDefaults(defineProps<Props>(), {
closeOnOverlayClick: true,
mini: false,
height: 'screen',
minWidth: 62,
maxWidth: 248,
});
defineOptions({
inheritAttrs: false,
});
const emit =
defineEmits<{
(e: 'update:modelValue', value: string): void;
(e: 'update:expanded', value: boolean): void;
(e: 'clickOverlay'): void;
}>();
const emit = defineEmits<{
(e: 'update:modelValue', value: string): void;
(e: 'update:expanded', value: boolean): void;
(e: 'update:mini', value: boolean): void;
(e: 'clickOverlay'): void;
(e: 'clickResizer', event: any): void;
}>();
const isOpen = useVModel(props, 'modelValue', emit);
const isExpanded = useVModel(props, 'expanded', emit);
const mini = useVModel(props, 'mini', emit);
const drawer = ref<HTMLElement>();
const classes = computed(() => {
const shadowClass =
Expand All @@ -67,7 +79,7 @@ const classes = computed(() => {
'nav-drawer--left': props.left,
'nav-drawer--bottom': props.bottom,
'nav-drawer--top': props.top,
'nav-drawer--mini': props.mini,
'nav-drawer--mini': mini.value,
'nav-drawer--expand-on-hover': props.expandOnHover,
'nav-drawer--expanded': isExpanded.value,
},
Expand Down Expand Up @@ -126,8 +138,42 @@ const styles = computed(() => {
return styles;
});
const resizerEl = ref<HTMLElement>();
const {x} = useDraggable(resizerEl);
watch(x, (newX) => {
if (newX <= props.minWidth) return;
if (newX >= props.maxWidth) return;
if (!drawer.value) return;
drawer.value.style.userSelect = 'none';
drawer.value.style.setProperty('--nav-drawer-width', `${newX}px`);
});
function onResizerClicked(event: any) {
if (props.miniOnResizerClick) {
mini.value = !mini.value;
}
if (props.expandOnResizerClick) {
isExpanded.value = !isExpanded.value;
}
if (props.hideOnResizerClick) {
isOpen.value = false;
}
emit('clickResizer', event);
}
defineSlots<{
default?: (props: {}) => any;
resizer?: (props: {
resizer: boolean | undefined;
onClick: (event: any) => void;
}) => any;
}>();
</script>

Expand All @@ -148,9 +194,21 @@ defineSlots<{
:class="classes"
v-bind="$attrs"
:style="styles"
ref="drawer"
@mouseover="onMouseOver"
@mouseout="onMouseOut"
>
<slot name="resizer" v-bind="{resizer, onClick: onResizerClicked}">
<button
v-if="resizer"
aria-label="Resizer"
ref="resizer"
class="nav-drawer__resizer"
@click="onResizerClicked"
>
<div class="sr-only">Click and hold to resize</div>
</button>
</slot>
<slot />
</aside>
</transition>
Expand Down
31 changes: 30 additions & 1 deletion packages/themes/src/morpheme/_nav-drawer.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
// expanded
--nav-drawer-inexpanded-width: var(--nav-drawer-mini-width);
--nav-drawer-expanded-width: 248px;

// resizer
--nav-drawer-resizer-width: 6px;
--nav-drawer-resizer-bg-color: transparent;
--nav-drawer-resizer-hover-bg-color: var(--color-gray-400);
}

.nav-drawer {
Expand All @@ -25,6 +30,7 @@
box-shadow: var(--nav-drawer-shadow);
border: var(--nav-drawer-border);
width: var(--nav-drawer-width);
position: relative;

/* variants */
&-default {
Expand All @@ -34,16 +40,19 @@
&-primary {
--nav-drawer-bg-color: var(--color-primary-500);
--nav-drawer-text-color: var(--color-white);
--nav-drawer-resizer-hover-bg-color: var(--color-primary-400);
}

&-dark {
--nav-drawer-bg-color: var(--color-gray-800);
--nav-drawer-text-color: var(--color-white);
--nav-drawer-resizer-hover-bg-color: var(--color-gray-700);
}

&-secondary {
--nav-drawer-bg-color: var(--color-secondary-500);
--nav-drawer-text-color: var(--color-white);
--nav-drawer-resizer-hover-bg-color: var(--color-secondary-400);
}

/* modifiers */
Expand Down Expand Up @@ -188,7 +197,9 @@
background-color: rgba(0, 0, 0, 0.5);
position: fixed;
z-index: 10;
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
transition-property: color, background-color, border-color,
text-decoration-color, fill, stroke, opacity, box-shadow, transform,
filter, backdrop-filter;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 300ms;
}
Expand All @@ -210,4 +221,22 @@
&--expand-on-hover.nav-drawer--expanded {
--nav-drawer-width: var(--nav-drawer-expanded-width);
}

&__resizer {
appearance: none;
height: 100%;
width: var(--nav-drawer-resizer-width);
background-color: var(--nav-drawer-resizer-bg-color);
position: absolute;
right: 0;
cursor: col-resize;
transition: background-color 0.3s ease-out;

&:hover,
&:active {
cursor: col-resize;
background-color: var(--nav-drawer-resizer-hover-bg-color);
box-shadow: var(--effect-shadow-lg);
}
}
}

0 comments on commit 2b58444

Please sign in to comment.