Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat#1417/add new menu component #3637

Merged
merged 31 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
3a8b043
[raw]
pogrib0k Jun 23, 2023
c93fefa
[raw]
pogrib0k Jun 23, 2023
0654610
feat: add disabled property to va-menu-item
pogrib0k Jun 26, 2023
a870865
Merge branch 'develop' of github.com:epicmaxco/vuestic-ui into feat#1…
pogrib0k Jul 25, 2023
90411b9
add groups of options in menu
pogrib0k Jul 25, 2023
ae0ea16
proxy dropdown props to menu component
pogrib0k Jul 26, 2023
e5c58be
Merge branch 'develop' into feat#1417/add-new-menu-component
pogrib0k Sep 11, 2023
84d86e1
[raw]
pogrib0k Oct 10, 2023
13dcfb4
feat: add more stories and refactored some pieces of code
m0ksem Oct 10, 2023
4289019
feat: add color prop
m0ksem Oct 10, 2023
3fd6799
raw
m0ksem Oct 11, 2023
d3378fc
Merge branch 'develop' into pr/pogrib0k/3637
m0ksem Nov 14, 2023
27c3ab9
fix: improve VaMenuList
m0ksem Nov 14, 2023
ce4ac18
chore: eslint fix
m0ksem Nov 14, 2023
f00945a
feat(va-menu-list): keyboard navigation
m0ksem Nov 20, 2023
767cb61
feat(va-menu): init component with dropdown and keyboard navigation
m0ksem Nov 20, 2023
28c0dfd
docs(va-menu): init docs pages for va-menu and va-menu-item
m0ksem Nov 20, 2023
32b3513
chore: eslint fix
m0ksem Nov 20, 2023
bc32112
fix: story tweaks
asvae Nov 22, 2023
c6a9b5b
fix: revert storybook changes
m0ksem Nov 23, 2023
48228c9
fix(menu): stories fixes
m0ksem Nov 23, 2023
e43adc4
chore: eslint fix
m0ksem Nov 23, 2023
54b99fd
feat(menu): use-menu
m0ksem Nov 27, 2023
7ec193d
feat(menu): improve keyboard navigation
m0ksem Nov 27, 2023
4ed064a
minor story updates
asvae Dec 6, 2023
1ecc6b2
fix(menu): bug fixes
m0ksem Dec 8, 2023
2fd8ec2
docs(menu): add api descriptions
m0ksem Dec 8, 2023
2feea87
docs(menu): add example descriptions
m0ksem Dec 8, 2023
b62663e
docs(menu): improve descriptions
m0ksem Dec 8, 2023
d0dce4b
fix(menu): remove color prop
m0ksem Dec 8, 2023
234ff72
docs(menu): improve use menu example
m0ksem Dec 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ export default
eventArgument: "The event argument is:"
},
props: {
ariaLabel: "Sets the `aria-label` attribute.",
ariaLabeledby: "Sets the `aria-labelledby` attribute.",
role: "Sets the `role` attribute.",
align: "Customizes horizontal position of component (flex based). Available values are strings: 'left', 'center', 'right', 'between', 'around', 'stretch'.",
id: "Applies `id` to internal input component. Useful for native forms.",
name: "Applies `name` to internal input component. Useful for native forms.",
Expand Down
18 changes: 17 additions & 1 deletion packages/docs/modules/page-config/blocks/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { definePageConfigBlock } from '../../types'
import Component from './index.vue'
import { VisualOptions, type ManualApiOptions, APIDescriptionOptions } from './types';
import { parseComponent } from './component-parser'
import type * as components from 'vuestic-ui/src/services/vue-plugin/components'
import { ExtractComponentProps } from 'vuestic-ui/src/utils/component-options';
import { VuesticComponent } from 'vuestic-ui/src/services/component-config';

const setup = (
componentName: string,
Expand All @@ -27,7 +30,20 @@ const setup = (
}

export default definePageConfigBlock({
setup: setup as unknown as (componentName: string, descriptionOptions: APIDescriptionOptions, manual?: ManualApiOptions, visualOptions?: VisualOptions) => ReturnType<typeof setup>,
setup: setup as unknown as <
ComponentName extends keyof typeof components,
Component extends typeof components[ComponentName] = typeof components[ComponentName]
>(
componentName: ComponentName,
descriptionOptions: {
props?: Partial<Record<keyof ExtractComponentProps<Component>, string>>,
events?: Partial<Record<keyof Component['emits'], string>>,
slots?: Record<string, string>,
methods?: Partial<Record<keyof Component['methods'], string>>,
},
manual?: ManualApiOptions,
visualOptions?: VisualOptions
) => ReturnType<typeof setup>,
component: Component,
})

2 changes: 1 addition & 1 deletion packages/docs/modules/page-config/runtime/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,4 @@ export type UnwrapPageConfigBlock<T extends Record<string, any>> = {
_blockComponent: DefineComponent,
} & T

export const defineApiDescription = (options: APIDescriptionOptions) => options;
export const defineApiDescription = <T extends APIDescriptionOptions>(options: T) => options;
15 changes: 14 additions & 1 deletion packages/docs/page-config/navigationRoutes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { navigationBadge } from './../utils/navigation/badge';
import { navigationBadge, type NavigationBadge } from "../utils/navigation/badge";

export type NavigationRoute = {
Expand Down Expand Up @@ -389,6 +388,20 @@ export const navigationRoutes: NavigationRoute[] = [
badge : navigationBadge.updated('1.8.3'),
}
},
{
name: 'menu',
displayName: 'Menu',
meta: {
badge : navigationBadge.new('1.8.4'),
}
},
{
name: 'menu-list',
displayName: 'Menu List',
meta: {
badge : navigationBadge.new('1.8.4'),
}
},
{
category: "Utility",
name: "value",
Expand Down
16 changes: 11 additions & 5 deletions packages/docs/page-config/ui-elements/dropdown/api-description.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { defineApiDescription } from "~/modules/page-config/runtime";

export default defineApiDescription({
props: {
anchor: "Anchor element. Dropdown will be opened when clicked on anchor. Can be `HTMLElement` or `CSS selector`",
closeOnAnchorClick: "Dropdown will be closed when clicked on anchor",
closeOnContentClick: "Dropdown will be closed when clicked inside dropdown content",
closeOnFocusOutside: "Dropdown will be closed when focus is outside dropdown content and anchor",
hoverOutTimeout: "Time in `ms` after mouse leave dropdown before it will be closed",
hoverOverTimeout: "Time in `ms` after mouse enter dropdown before it will be opened",
verticalScrollOnOverflow: "If true, dropdown content will adjust its height when the content is larger than available space",
Expand All @@ -11,14 +14,17 @@ export default defineApiDescription({
placement: "Dropdown content will be placed on `placement` side of anchor",
trigger: "Action that will triggered when open and close dropdown.",
target: "Dropdown content parent. Dropdown content will be attached to `target` to prevent overflow",
closeOnAnchorClick:"Dropdown will be closed when anchor is clicked",
ariaLabel: "The aria-label of the component",
role: "The `role` attribute applied to the anchor"
role: "The role attribute of the dropdown",
},
events: {
anchorClick: "The event is triggered when anchor is clicked",
clickOutside: "The event is triggered when clicked outside dropdown content and anchor",
contentClick: "The event is triggered when clicked inside dropdown content"
anchorDblclick: "The event is triggered when anchor is double clicked",
anchorRightClick: "The event is triggered when anchor is right clicked",
close: "The event is triggered when dropdown is closed",
open: "The event is triggered when dropdown is opened",
contentClick: "The event is triggered when clicked inside dropdown content",
focusOutside: "The event is triggered when focus is outside dropdown content and anchor",
clickOutside: "The event is triggered when clicked outside dropdown content and anchor"
},
slots: {
anchor: "Slot for anchor. When anchor is clicked, dropdown will be opened",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<template>
<VaMenuList
:options="['Option 1', 'Option 2', 'Option 3']"
@selected="(v) => alert(v)"
/>
</template>

<script setup>
const alert = (...args) => window.alert(...args)
</script>
18 changes: 18 additions & 0 deletions packages/docs/page-config/ui-elements/menu-list/examples/Group.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<template>
<VaMenuList
:options="options"
@selected="(v) => alert(v)"
/>
</template>

<script setup>
const alert = (...args) => window.alert(...args)

const options = [
{ id: '0', text: 'one', value: 'one', group: '' },
{ id: '1', text: 'two', value: 'two', group: 'Group 1' },
{ id: '2', text: 'three', value: 'three', group: '' },
{ id: '3', text: 'four', value: 'four', group: 'Group 2' },
{ id: '4', text: 'five', value: 'five', group: 'Group 2' },
]
</script>
18 changes: 18 additions & 0 deletions packages/docs/page-config/ui-elements/menu-list/examples/Icon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<template>
<VaMenuList
:options="options"
@selected="(v) => alert(v)"
/>
</template>

<script setup>
const alert = (...args) => window.alert(...args)

const options = [
{ id: '0', text: 'copy', value: 'one', icon: 'content_copy', rightIcon: '' },
{ id: '1', text: 'paste', value: 'two', icon: 'content_paste', rightIcon: '' },
{ id: '2', text: 'cut', value: 'three', icon: 'content_cut', rightIcon: '' },
{ id: '3', text: 'share', value: 'four', icon: '', rightIcon: 'share' },
{ id: '4', text: 'delete', value: 'five', icon: 'delete' },
]
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<template>
<VaMenuList>
<VaMenuItem @selected="alert">
Option 1
</VaMenuItem>
<VaMenuItem @selected="alert">
Option 2
</VaMenuItem>
<VaMenuItem @selected="alert">
Option 2
</VaMenuItem>
</VaMenuList>
</template>

<script setup lang="ts">
const alert = (...args) => window.alert(...args)
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<template>
<VaMenuList>
<VaMenuItem @selected="alert">
Option 1
</VaMenuItem>
<VaMenuItem @selected="alert">
Option 2
</VaMenuItem>
<VaDivider />
<VaMenuItem @selected="alert">
Option 3
</VaMenuItem>
<VaMenuItem @selected="alert">
Option 4
</VaMenuItem>
<div>
Custom divider
</div>
<VaMenuItem @selected="alert">
Option 5
</VaMenuItem>
</VaMenuList>
</template>

<script setup lang="ts">
const alert = (...args) => window.alert(...args)
</script>
49 changes: 49 additions & 0 deletions packages/docs/page-config/ui-elements/menu-list/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
export default definePageConfig({
blocks: [
block.title("Menu List"),
block.paragraph("The `VaMenuList` component is used to display structured information in selectable list format."),


block.link("VaMenu", "/ui-elements/menu", { preText: "See " }),

block.subtitle("Examples"),

block.example("Default", {
title: "Basic usage",
description: "To show menu items you can use `options` prop:",
}),
block.example("MenuItem", {
title: "Slot usage",
description: "You can also use slot and VaMenuItem component to achieve better flexibility.",
}),

block.example("Icon", {
title: "Icon",
description: "You can use `icon `and `rightIcon` properties in options or `left-icon` and `right-icon` slots in `VaMenuItem` component.",
}),

block.example("Group", {
title: "Group",
description: "You can use `group` property in options or `VaMenuGroup` component.",
}),

block.example("WithDivider", {
title: "With divider",
description: "You can use `VaDivider` component in pair with `VaMenuItem` components.",
}),

block.api("VaMenuList", {
props: {
textBy: 'When `options` prop items are an objects, this key will be used as displayed text. Can be string (path to the key) or function of type: `(option) => option.text`',
valueBy: 'When `options` prop items are an objects, this key will be used in `selected` event. Can be string (path to the key) or function of type: `(option) => option.value`',
trackBy: 'When `options` prop items are an objects, this key will be used to track selected `options`. Can be string (path to the key) or function of type: `(option) => option.track`',
groupBy: 'When `options` prop items are an objects, this key will be used to check correct option group',
disabledBy: "Specify the key in the object to be used as item `disabled` prop. Can be string (path to the key) or function of type: `(option) => option.disabled`",
options: "Available options that the user can select from",
},
events: {
selected: 'Emitted when an option is selected. Returns the selected option value as first argument and the selected option as second argument',
}
}),
],
})
41 changes: 41 additions & 0 deletions packages/docs/page-config/ui-elements/menu/api-description.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { defineApiDescription } from "~/modules/page-config/runtime";

export default defineApiDescription({
props: {
anchor: "Anchor element. Dropdown will be opened when clicked on anchor. Can be `HTMLElement` or `CSS selector`",
closeOnAnchorClick: "Dropdown will be closed when clicked on anchor",
closeOnContentClick: "Dropdown will be closed when clicked inside dropdown content",
closeOnFocusOutside: "Dropdown will be closed when focus is outside dropdown content and anchor",
hoverOutTimeout: "Time in `ms` after mouse leave dropdown before it will be closed",
hoverOverTimeout: "Time in `ms` after mouse enter dropdown before it will be opened",
verticalScrollOnOverflow: "If true, dropdown content will adjust its height when the content is larger than available space",
keepAnchorWidth: "If true, dropdown content will have exact same width as anchor",
offset: "Dropdown content will be moved by main and cross axis according to current `placement`",
placement: "Dropdown content will be placed on `placement` side of anchor",
trigger: "Action that will triggered when open and close dropdown.",
target: "Dropdown content parent. Dropdown content will be attached to `target` to prevent overflow",
role: "The role attribute of the dropdown",

textBy: 'When `options` prop items are an objects, this key will be used as displayed text. Can be string (path to the key) or function of type: `(option) => option.text`',
valueBy: 'When `options` prop items are an objects, this key will be used in `selected` event. Can be string (path to the key) or function of type: `(option) => option.value`',
trackBy: 'When `options` prop items are an objects, this key will be used to track selected `options`. Can be string (path to the key) or function of type: `(option) => option.track`',
groupBy: 'When `options` prop items are an objects, this key will be used to check correct option group',
disabledBy: "Specify the key in the object to be used as item `disabled` prop. Can be string (path to the key) or function of type: `(option) => option.disabled`",
options: "Available options that the user can select from",
},
events: {
anchorClick: "The event is triggered when anchor is clicked",
anchorDblclick: "The event is triggered when anchor is double clicked",
anchorRightClick: "The event is triggered when anchor is right clicked",
close: "The event is triggered when dropdown is closed",
open: "The event is triggered when dropdown is opened",
contentClick: "The event is triggered when clicked inside dropdown content",
focusOutside: "The event is triggered when focus is outside dropdown content and anchor",
clickOutside: "The event is triggered when clicked outside dropdown content and anchor",
selected: 'Emitted when an option is selected. Returns the selected option value as first argument and the selected option as second argument',
},
slots: {
anchor: "Slot for anchor. When anchor is clicked, dropdown will be opened",
default: "Dropdown content",
}
});
20 changes: 20 additions & 0 deletions packages/docs/page-config/ui-elements/menu/examples/Context.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<template>
<VaMenu
:options="['Option 1', 'Option 2', 'Option 3']"
preset="context"
@selected="(v) => alert(v)"
>
<template #anchor>
<va-image
class="h-[300px] w-[300px]"
src="https://picsum.photos/1500"
>
<va-badge text="Right click this image" />
</va-image>
</template>
</VaMenu>
</template>

<script setup>
const alert = (...args) => window.alert(...args)
</script>
14 changes: 14 additions & 0 deletions packages/docs/page-config/ui-elements/menu/examples/Default.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<template>
<VaMenu
:options="['Option 1', 'Option 2', 'Option 3']"
@selected="(v) => alert(v)"
>
<template #anchor>
<VaButton>Open menu</VaButton>
</template>
</VaMenu>
</template>

<script setup>
const alert = (...args) => window.alert(...args)
</script>
22 changes: 22 additions & 0 deletions packages/docs/page-config/ui-elements/menu/examples/Group.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<template>
m0ksem marked this conversation as resolved.
Show resolved Hide resolved
<VaMenu
:options="options"
@selected="(v) => alert(v)"
>
<template #anchor>
<VaButton>Open menu</VaButton>
</template>
</VaMenu>
</template>

<script setup>
const alert = (...args) => window.alert(...args)

const options = [
{ id: '0', text: 'one', value: 'one', group: '' },
{ id: '1', text: 'two', value: 'two', group: 'Group 1' },
{ id: '2', text: 'three', value: 'three', group: '' },
{ id: '3', text: 'four', value: 'four', group: 'Group 2' },
{ id: '4', text: 'five', value: 'five', group: 'Group 2' },
]
</script>
22 changes: 22 additions & 0 deletions packages/docs/page-config/ui-elements/menu/examples/Icon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<template>
<VaMenu
:options="options"
@selected="(v) => alert(v)"
>
<template #anchor>
<VaButton>Open menu</VaButton>
</template>
</VaMenu>
</template>

<script setup>
const alert = (...args) => window.alert(...args)

const options = [
{ text: 'copy', value: 'one', icon: 'content_copy' },
{ text: 'paste', value: 'two', icon: 'content_paste' },
{ text: 'cut', value: 'three', icon: 'content_cut' },
{ text: 'share', value: 'four', rightIcon: 'share' },
{ text: 'delete', value: 'five', icon: 'delete' },
]
</script>
21 changes: 21 additions & 0 deletions packages/docs/page-config/ui-elements/menu/examples/MenuItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<template>
<VaMenu>
<template #anchor>
<VaButton>Open menu</VaButton>
</template>

<VaMenuItem @selected="alert">
Option 1
</VaMenuItem>
<VaMenuItem @selected="alert">
Option 2
</VaMenuItem>
<VaMenuItem @selected="alert">
Option 2
</VaMenuItem>
</VaMenu>
</template>

<script setup lang="ts">
const alert = (...args) => window.alert(...args)
</script>
Loading
Loading