-
Notifications
You must be signed in to change notification settings - Fork 0
menu: стилизация, сторисы, обёртки #34
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
base: feature/styles-debug
Are you sure you want to change the base?
Changes from 2 commits
37e722d
7593a1c
7896268
49b3c9f
0b96fe8
0f93319
ef0716b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| import { Component, Input, ViewChild } from '@angular/core'; | ||
| import { Menu } from 'primeng/menu'; | ||
| import { MenuItem, PrimeTemplate } from 'primeng/api'; | ||
|
|
||
| export interface MenuModel extends MenuItem { | ||
| caption?: string; | ||
| } | ||
|
|
||
| @Component({ | ||
| selector: 'menu', | ||
| host: { style: 'display: contents' }, | ||
| standalone: true, | ||
| imports: [Menu, PrimeTemplate], | ||
| template: ` | ||
| <p-menu #menuRef [model]="model" [popup]="popup" [appendTo]="popup ? 'body' : null"> | ||
| <ng-template pTemplate="item" let-item> | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. опять же вопрос с кастомизациями. разработчикам не придется свои шаблоны передавать?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| <a | ||
| class="p-menu-item-link" | ||
| role="menuitem" | ||
| tabindex="0" | ||
| [class.p-disabled]="item.disabled" | ||
| [attr.href]="item.url || null" | ||
| [attr.target]="item.target || null" | ||
| (click)="!item.disabled && item.command && item.command({ originalEvent: $event, item: item })" | ||
| > | ||
| @if (item.icon) { | ||
| <span [class]="item.icon + ' p-menu-item-icon'"></span> | ||
| } | ||
| @if ($any(item).caption) { | ||
| <div class="menu-item-label"> | ||
| <span class="p-menu-item-label">{{ item.label }}</span> | ||
| <small class="menu-item-caption">{{ $any(item).caption }}</small> | ||
| </div> | ||
| } @else { | ||
| <span class="p-menu-item-label">{{ item.label }}</span> | ||
| } | ||
| </a> | ||
| </ng-template> | ||
| </p-menu> | ||
| `, | ||
| }) | ||
| export class MenuComponent { | ||
| @ViewChild('menuRef') menuRef!: Menu; | ||
|
|
||
| @Input() model: MenuModel[] = []; | ||
| @Input() popup = false; | ||
|
|
||
| toggle(event: Event): void { | ||
| this.menuRef.toggle(event); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| export const menuCss = ({ dt }: { dt: (token: string) => string }): string => ` | ||
| .p-menu.p-component { | ||
| padding: ${dt('menu.extend.paddingY')} ${dt('menu.extend.paddingX')}; | ||
| } | ||
|
|
||
| .p-menu .p-menu-item-content .p-menu-item-link .p-menu-item-label { | ||
| font-family: ${dt('fonts.fontFamily.base')}; | ||
| font-size: ${dt('fonts.fontSize.300')}; | ||
| font-weight: ${dt('fonts.fontWeight.regular')}; | ||
| line-height: ${dt('fonts.lineHeight.400')}; | ||
| } | ||
|
|
||
| .p-menu .p-menu-item-content .menu-item-label { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: ${dt('menu.extend.extItem.caption.gap')}; | ||
| } | ||
|
|
||
| .p-menu .p-menu-item-content .menu-item-caption { | ||
| font-family: ${dt('fonts.fontFamily.base')}; | ||
| font-size: ${dt('fonts.fontSize.200')}; | ||
| font-weight: ${dt('fonts.fontWeight.regular')}; | ||
| color: ${dt('menu.colorScheme.light.extend.extItem.caption.color')}; | ||
| } | ||
|
|
||
| .p-menu .p-menu-item:not(.p-disabled) .p-menu-item-content:hover, | ||
| .p-menu .p-menu-item:not(.p-disabled) .p-menu-item-content:hover .p-menu-item-link, | ||
| .p-menu .p-menu-item:not(.p-disabled) .p-menu-item-content:hover .p-menu-item-label, | ||
| .p-menu .p-menu-item:not(.p-disabled) .p-menu-item-content:hover .p-menu-item-icon { | ||
| background: ${dt('menu.colorScheme.light.item.focusBackground')}; | ||
| color: ${dt('menu.colorScheme.light.item.focusColor')}; | ||
| } | ||
|
|
||
| .p-menu .p-menu-item.p-menuitem-checked > .p-menu-item-content, | ||
| .p-menu .p-menu-item.p-focus > .p-menu-item-content { | ||
| background: ${dt('menu.extend.extItem.activeBackground')}; | ||
| color: ${dt('menu.extend.extItem.activeColor')}; | ||
| } | ||
|
|
||
| .p-menu .p-menu-item.p-menuitem-checked > .p-menu-item-content .p-menu-item-link, | ||
| .p-menu .p-menu-item.p-menuitem-checked > .p-menu-item-content .p-menu-item-label, | ||
| .p-menu .p-menu-item.p-focus > .p-menu-item-content .p-menu-item-link, | ||
| .p-menu .p-menu-item.p-focus > .p-menu-item-content .p-menu-item-label { | ||
| color: ${dt('menu.extend.extItem.activeColor')}; | ||
| } | ||
|
|
||
| .p-menu .p-menu-item.p-menuitem-checked > .p-menu-item-content .p-menu-item-icon, | ||
| .p-menu .p-menu-item.p-focus > .p-menu-item-content .p-menu-item-icon { | ||
| color: ${dt('menu.colorScheme.light.extend.extItem.icon.activeColor')}; | ||
| } | ||
|
|
||
| .p-menu .p-menu-item.p-menuitem-checked:not(.p-disabled) > .p-menu-item-content:hover { | ||
| background: ${dt('menu.colorScheme.light.item.focusBackground')}; | ||
| color: ${dt('menu.colorScheme.light.item.focusColor')}; | ||
| } | ||
|
|
||
| .p-menu .p-menu-item.p-menuitem-checked:not(.p-disabled) > .p-menu-item-content:hover .p-menu-item-icon { | ||
| color: ${dt('menu.colorScheme.light.item.focusColor')}; | ||
| } | ||
|
|
||
| .p-menu .p-menu-submenu-label { | ||
| text-transform: uppercase; | ||
| font-size: ${dt('fonts.fontSize.200')}; | ||
| font-family: ${dt('fonts.fontFamily.heading')}; | ||
| line-height: ${dt('fonts.lineHeight.400')}; | ||
| } | ||
| `; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| import { Component } from '@angular/core'; | ||
| import { MenuComponent, MenuModel } from '../../../../lib/components/menu/menu.component'; | ||
|
|
||
| const template = ` | ||
| <div class="bg-surface-ground"> | ||
| <menu [model]="items"></menu> | ||
| </div> | ||
| `; | ||
|
|
||
| @Component({ | ||
| selector: 'app-menu-basic', | ||
| standalone: true, | ||
| imports: [MenuComponent], | ||
| template, | ||
| }) | ||
| export class MenuBasicComponent { | ||
| items: MenuModel[] = [ | ||
| { label: 'Новый заказ' }, | ||
| { label: 'Поиск отправления' }, | ||
| { separator: true }, | ||
| { label: 'Экспорт' }, | ||
| ]; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| import { Component } from '@angular/core'; | ||
| import { MenuComponent, MenuModel } from '../../../../lib/components/menu/menu.component'; | ||
|
|
||
| const template = ` | ||
| <div class="bg-surface-ground"> | ||
| <menu [model]="items"></menu> | ||
| </div> | ||
| `; | ||
|
|
||
| @Component({ | ||
| selector: 'app-menu-custom', | ||
| standalone: true, | ||
| imports: [MenuComponent], | ||
| template, | ||
| }) | ||
| export class MenuCustomComponent { | ||
| items: MenuModel[] = [ | ||
| { | ||
| label: 'Создать отправление', | ||
| caption: 'Оформление нового заказа', | ||
| icon: 'ti ti-file-plus', | ||
| }, | ||
| { | ||
| label: 'Найти посылку', | ||
| caption: 'Поиск по трек-номеру', | ||
| icon: 'ti ti-map-pin', | ||
| }, | ||
| { separator: true }, | ||
| { | ||
| label: 'Экспорт данных', | ||
| caption: 'Выгрузка в CSV или Excel', | ||
| icon: 'ti ti-download', | ||
| }, | ||
| ]; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| import { Component } from '@angular/core'; | ||
| import { MenuComponent, MenuModel } from '../../../../lib/components/menu/menu.component'; | ||
|
|
||
| const template = ` | ||
| <div class="bg-surface-ground"> | ||
| <menu [model]="items"></menu> | ||
| </div> | ||
| `; | ||
|
|
||
| @Component({ | ||
| selector: 'app-menu-grouped', | ||
| standalone: true, | ||
| imports: [MenuComponent], | ||
| template, | ||
| }) | ||
| export class MenuGroupedComponent { | ||
| items: MenuModel[] = [ | ||
| { | ||
| label: 'Заказы', | ||
| items: [ | ||
| { label: 'Новый заказ', icon: 'ti ti-plus' }, | ||
| { label: 'Список заказов', icon: 'ti ti-list' }, | ||
| { label: 'Архив', icon: 'ti ti-archive' }, | ||
| ], | ||
| }, | ||
| { | ||
| label: 'Отправления', | ||
| items: [ | ||
| { label: 'Создать накладную', icon: 'ti ti-file-invoice' }, | ||
| { label: 'Отследить посылку', icon: 'ti ti-map-pin' }, | ||
| { label: 'Отменить отправление', icon: 'ti ti-ban' }, | ||
| ], | ||
| }, | ||
| ]; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import { Component, ViewChild } from '@angular/core'; | ||
| import { Button } from 'primeng/button'; | ||
| import { MenuComponent, MenuModel } from '../../../../lib/components/menu/menu.component'; | ||
|
|
||
| const template = ` | ||
| <div class="bg-surface-ground"> | ||
| <p-button label="Действия с заказом" severity="contrast" (onClick)="toggle($event)"></p-button> | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. кнопка должна быть наша
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| <menu #menuRef [model]="items" [popup]="true"></menu> | ||
| </div> | ||
| `; | ||
|
|
||
| @Component({ | ||
| selector: 'app-menu-popup', | ||
| standalone: true, | ||
| imports: [MenuComponent, Button], | ||
| template, | ||
| }) | ||
| export class MenuPopupComponent { | ||
| @ViewChild('menuRef') menuRef!: MenuComponent; | ||
|
|
||
| items: MenuModel[] = [ | ||
| { label: 'Создать отправление', icon: 'ti ti-file-plus' }, | ||
| { label: 'Найти по трек-номеру', icon: 'ti ti-search' }, | ||
| { separator: true }, | ||
| { label: 'Экспорт данных', icon: 'ti ti-download' }, | ||
| ]; | ||
|
|
||
| toggle(event: Event): void { | ||
| this.menuRef.toggle(event); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import { Component } from '@angular/core'; | ||
| import { MenuComponent, MenuModel } from '../../../../lib/components/menu/menu.component'; | ||
|
|
||
| const template = ` | ||
| <div class="bg-surface-ground"> | ||
| <menu [model]="items"></menu> | ||
| </div> | ||
| `; | ||
|
|
||
| @Component({ | ||
| selector: 'app-menu-with-icons', | ||
| standalone: true, | ||
| imports: [MenuComponent], | ||
| template, | ||
| }) | ||
| export class MenuWithIconsComponent { | ||
| items: MenuModel[] = [ | ||
| { label: 'Создать отправление', icon: 'ti ti-file-plus' }, | ||
| { label: 'Открыть список заказов', icon: 'ti ti-folder-open' }, | ||
| { label: 'Сохранить черновик', icon: 'ti ti-device-floppy' }, | ||
| { separator: true }, | ||
| { label: 'Распечатать накладную', icon: 'ti ti-printer' }, | ||
| { label: 'Экспорт данных', icon: 'ti ti-download' }, | ||
| ]; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
для чего?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AxyIX делает хост-элемент menu прозрачным для layout (flex/grid родителя его не видят). Без этого menu был бы блочным элементом, ломающим позиционирование.