mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
chore(core): add context-menu storybook showcase and material-style notes (#12084)
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
<div mat-menu class="mat-mdc-menu-panel mdc-menu-surface mdc-menu-surface--open adf-context-menu-animate">
|
<div mat-menu class="mat-mdc-menu-panel mdc-menu-surface mdc-menu-surface--open">
|
||||||
<div id="adf-context-menu-content" class="mat-mdc-menu-content">
|
<div id="adf-context-menu-content" class="mat-mdc-menu-content">
|
||||||
@for (link of links; track link) {
|
@for (link of links; track link) {
|
||||||
@if (link.model?.visible) {
|
@if (link.model?.visible) {
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
(click)="onMenuItemClick($event, link)"
|
(click)="onMenuItemClick($event, link)"
|
||||||
>
|
>
|
||||||
@if (link.model?.icon) {
|
@if (link.model?.icon) {
|
||||||
<mat-icon [adf-icon]="link.model.icon" />
|
<mat-icon matMenuItemIcon [adf-icon]="link.model.icon" />
|
||||||
}
|
}
|
||||||
<span>{{ link.title || link.model?.title | translate }}</span>
|
<span>{{ link.title || link.model?.title | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -18,3 +18,10 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Style-loader menu: this hidden real mat-menu instance ensures Angular Material
|
||||||
|
menu component styles are registered for this custom overlay-rendered menu.
|
||||||
|
Remove it once this component is migrated to a true mat-menu + matMenuTriggerFor flow.
|
||||||
|
-->
|
||||||
|
<mat-menu aria-hidden="true" class="adf-context-menu-style-loader" />
|
||||||
|
|||||||
@@ -1,57 +1,8 @@
|
|||||||
@use '@angular/material' as mat;
|
|
||||||
|
|
||||||
@keyframes delayed-elevation {
|
|
||||||
0% {
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
@include mat.elevation(8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes menu-scale-in {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
transform: scale(0.01, 0.01);
|
|
||||||
}
|
|
||||||
|
|
||||||
25% {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scale(1, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scale(1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes menu-scale-out {
|
|
||||||
0% {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scale(1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
75% {
|
|
||||||
opacity: 0;
|
|
||||||
transform: scale(1, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 0;
|
|
||||||
transform: scale(0.01, 0.01);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
adf-context-menu {
|
adf-context-menu {
|
||||||
animation: delayed-elevation 0.5s ease-in-out 0.1s forwards;
|
> [mat-menu] {
|
||||||
|
border-radius: var(--mdc-menu-container-shape, var(--mat-sys-corner-extra-small));
|
||||||
.adf-context-menu-animate {
|
background: var(--mdc-menu-container-color, var(--mat-sys-surface-container));
|
||||||
animation: menu-scale-in 500ms cubic-bezier(0.25, 0.8, 0.25, 1) forwards;
|
color: var(--mdc-menu-item-label-text-color, var(--mat-sys-on-surface));
|
||||||
|
box-shadow: var(--mat-sys-level2);
|
||||||
&.adf-closing {
|
|
||||||
animation: menu-scale-out 500ms cubic-bezier(0.25, 0.8, 0.25, 1) forwards;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,152 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { applicationConfig, Meta, StoryObj, moduleMetadata } from '@storybook/angular';
|
||||||
|
import { ContextMenuDirective } from './context-menu.directive';
|
||||||
|
import { ContextMenuItem } from './interfaces';
|
||||||
|
import { provideStoryCore } from '../stories/core-story.providers';
|
||||||
|
|
||||||
|
interface ContextMenuStoryArgs {
|
||||||
|
enabled: boolean;
|
||||||
|
menuItemClicked: (menuItem: ContextMenuItem) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const createMenuItems = (menuItemClicked: (menuItem: ContextMenuItem) => void): ContextMenuItem[] => [
|
||||||
|
{
|
||||||
|
model: {
|
||||||
|
title: 'Open',
|
||||||
|
visible: true,
|
||||||
|
disabled: false,
|
||||||
|
icon: 'folder_open',
|
||||||
|
tooltip: 'Open item'
|
||||||
|
},
|
||||||
|
subject: {
|
||||||
|
next: (menuItem) => menuItemClicked(menuItem)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: {
|
||||||
|
title: 'Rename',
|
||||||
|
visible: true,
|
||||||
|
disabled: true,
|
||||||
|
icon: 'edit',
|
||||||
|
tooltip: 'Unavailable for read-only items'
|
||||||
|
},
|
||||||
|
subject: {
|
||||||
|
next: (menuItem) => menuItemClicked(menuItem)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: {
|
||||||
|
title: 'Delete',
|
||||||
|
visible: true,
|
||||||
|
disabled: false,
|
||||||
|
icon: 'delete',
|
||||||
|
tooltip: 'Delete item'
|
||||||
|
},
|
||||||
|
subject: {
|
||||||
|
next: (menuItem) => menuItemClicked(menuItem)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: {
|
||||||
|
title: 'Hidden action',
|
||||||
|
visible: false,
|
||||||
|
disabled: false,
|
||||||
|
icon: 'more_horiz'
|
||||||
|
},
|
||||||
|
subject: {
|
||||||
|
next: (menuItem) => menuItemClicked(menuItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const meta: Meta<ContextMenuStoryArgs> = {
|
||||||
|
title: 'Core/Context Menu/Context Menu',
|
||||||
|
decorators: [
|
||||||
|
moduleMetadata({
|
||||||
|
imports: [ContextMenuDirective]
|
||||||
|
}),
|
||||||
|
applicationConfig({
|
||||||
|
providers: [...provideStoryCore()]
|
||||||
|
})
|
||||||
|
],
|
||||||
|
argTypes: {
|
||||||
|
enabled: {
|
||||||
|
description: 'Enables or disables the context menu interaction.',
|
||||||
|
control: 'boolean',
|
||||||
|
table: {
|
||||||
|
type: { summary: 'boolean' },
|
||||||
|
defaultValue: { summary: 'true' }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
menuItemClicked: {
|
||||||
|
action: 'menuItemClicked',
|
||||||
|
description: 'Emitted when a menu item is selected.',
|
||||||
|
table: {
|
||||||
|
category: 'Actions',
|
||||||
|
type: { summary: '(menuItem: ContextMenuItem) => void' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
args: {
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
docs: {
|
||||||
|
description: {
|
||||||
|
component: 'Right-click the target area to open the context menu.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<ContextMenuStoryArgs>;
|
||||||
|
|
||||||
|
const getContextMenuTemplate = (): string => `
|
||||||
|
<div style="max-width: 520px; margin: 32px auto; font-family: var(--mat-sys-body-medium-font, sans-serif);">
|
||||||
|
<p style="margin: 0 0 12px; color: #5b6169;">Right-click inside the area below to open the menu.</p>
|
||||||
|
<div
|
||||||
|
[adf-context-menu]="links"
|
||||||
|
[adf-context-menu-enabled]="enabled"
|
||||||
|
style="min-height: 160px; border: 1px dashed #6f7d8c; border-radius: 8px; background: #f8fafc; display: grid; place-items: center; color: #1f2933; user-select: none;"
|
||||||
|
>
|
||||||
|
Context Menu Target
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const Default: Story = {
|
||||||
|
render: (args) => ({
|
||||||
|
props: {
|
||||||
|
...args,
|
||||||
|
links: createMenuItems(args.menuItemClicked)
|
||||||
|
},
|
||||||
|
template: getContextMenuTemplate()
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
export const LinksAsFunction: Story = {
|
||||||
|
render: (args) => ({
|
||||||
|
props: {
|
||||||
|
...args,
|
||||||
|
links: () => createMenuItems(args.menuItemClicked)
|
||||||
|
},
|
||||||
|
template: getContextMenuTemplate()
|
||||||
|
})
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user