Skip to content

Commit

Permalink
feat: new node toolbar
Browse files Browse the repository at this point in the history
  • Loading branch information
juanfran committed Apr 15, 2024
1 parent 43b7f9c commit 05cb5fb
Show file tree
Hide file tree
Showing 26 changed files with 906 additions and 687 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@

.toolbar {
background: var(--primary-color-background);
border-radius: 8px;
border-radius: var(--radius-2);
display: flex;
flex-direction: column;
padding: 0.5rem 0;
padding: var(--size-2) 0;
transition: background 0.5s ease;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
team-up-toolbar {
position: absolute;
z-index: var(--board-tools-layer);
inset-inline-start: 70px;
inset-block-start: 70px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ interface Toolbar {
@for (toolbar of toolbars(); track toolbar.id) {
<team-up-toolbar
[editor]="toolbar.view"
[x]="toolbar.x"
[y]="toolbar.y"
[node]="toolbar.node()"
[closeMenus]="closeMenus"
[layoutOptions]="toolbar.layoutOptions" />
Expand Down
1 change: 1 addition & 0 deletions apps/team-up/src/app/styles/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@import "open-props/style";
@import "@angular/cdk/overlay-prebuilt.css";
@import "@angular/material/prebuilt-themes/deeppurple-amber.css";
@import "@simonwep/pickr/dist/themes/monolith.min.css";
@import "override-material.scss";
@import "fonts.scss";
@import "typography.scss";
Expand Down
8 changes: 6 additions & 2 deletions libs/nodes/src/lib/panel/panel.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,18 +209,22 @@ export class PanelComponent implements OnInit {
);
}

if (panel.content.borderWidth) {
if (panel.content.borderWidth !== undefined) {
this.nativeElement.style.setProperty(
'--borderWidth',
panel.content.borderWidth + 'px',
);
} else {
this.nativeElement.style.setProperty('--borderWidth', '1px');
}

if (panel.content.borderRadius) {
if (panel.content.borderRadius !== undefined) {
this.nativeElement.style.setProperty(
'--borderRadius',
panel.content.borderRadius + 'px',
);
} else {
this.nativeElement.style.setProperty('--borderRadius', '0px');
}

if (panel.content.textAlign) {
Expand Down
79 changes: 79 additions & 0 deletions libs/ui/src/lib/color-picker/color-picker.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import {
Component,
ChangeDetectionStrategy,
inject,
ElementRef,
input,
output,
OnDestroy,
afterNextRender,
effect,
} from '@angular/core';
import Pickr from '@simonwep/pickr';

@Component({
selector: 'team-up-color-picker',
template: '',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
})
export class ColorPickerComponent implements OnDestroy {
#el = inject(ElementRef);
#pickr?: Pickr;

color = input<string>();
change = output<string | undefined>();

constructor() {
afterNextRender(() => {
this.#pickr = Pickr.create({
el: this.#el.nativeElement,
theme: 'monolith',
default: this.color() || '',
swatches: [
'rgba(244, 67, 54, 1)',
'rgba(233, 30, 99, 1)',
'rgba(156, 39, 176, 1)',
'rgba(103, 58, 183, 1)',
'rgba(63, 81, 181, 1)',
'rgba(33, 150, 243, 1)',
'rgba(3, 169, 244, 1)',
'rgba(0, 188, 212, 1)',
'rgba(0, 150, 136, 1)',
'rgba(76, 175, 80, 1)',
'rgba(139, 195, 74, 1)',
'rgba(205, 220, 57, 1)',
'rgba(255, 235, 59, 1)',
'rgba(255, 193, 7, 1)',
],
components: {
preview: true,
opacity: true,
hue: true,
interaction: {
hex: true,
rgba: true,
hsla: true,
hsva: true,
input: true,
clear: true,
save: true,
},
},
});

this.#pickr.on('save', (color: Pickr.HSVaColor | null) => {
this.change.emit(color?.toHEXA().toString() ?? undefined);
this.#pickr?.hide();
});
});

effect(() => {
this.#pickr?.setColor(this.color() || '');
});
}

ngOnDestroy() {
this.#pickr?.destroy();
}
}
1 change: 1 addition & 0 deletions libs/ui/src/lib/color-picker/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ColorPickerComponent } from './color-picker.component';
1 change: 1 addition & 0 deletions libs/ui/src/lib/toolbar/node-toolbar.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export interface NodeToolbar {
borderWidth?: number;
borderRadius?: number;
textAlign?: 'start' | 'center' | 'end';
color?: string;
}
Empty file.
59 changes: 59 additions & 0 deletions libs/ui/src/lib/toolbar/options/align/option-align.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
inject,
input,
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { MatIconModule } from '@angular/material/icon';
import { Editor } from '@tiptap/core';
import { ToolbarEditorService } from '../../toolbar-editor.service';

@Component({
selector: 'team-up-toolbar-option-align',
template: `
<div class="buttons">
<button
title="Align Left"
[class.active]="editor().isActive({ textAlign: 'left' })"
(click)="command('left')">
<mat-icon>format_align_left</mat-icon>
</button>
<button
title="Align Center"
[class.active]="this.editor().isActive({ textAlign: 'center' })"
(click)="command('center')">
<mat-icon>format_align_center</mat-icon>
</button>
<button
title="Align Right"
[class.active]="editor().isActive({ textAlign: 'right' })"
(click)="command('right')">
<mat-icon>format_align_right</mat-icon>
</button>
</div>
`,
styleUrls: ['../options.scss', './option-align.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [MatIconModule],
})
export class OptionAlignComponent {
editor = input.required<Editor>();

cd = inject(ChangeDetectorRef);
#toolbarEditorService = inject(ToolbarEditorService);

command(aligment: string) {
this.editor().chain().focus().setTextAlign(aligment).run();
}

constructor() {
this.#toolbarEditorService.events$
.pipe(takeUntilDestroyed())
.subscribe(() => {
this.cd.detectChanges();
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
:host {
align-items: center;
display: flex;
gap: 8px;
}

139 changes: 139 additions & 0 deletions libs/ui/src/lib/toolbar/options/font/option-font.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import {
CdkMenuTrigger,
CdkMenu,
CdkMenuGroup,
CdkMenuItemRadio,
CdkMenuItem,
} from '@angular/cdk/menu';
import {
ChangeDetectionStrategy,
Component,
inject,
input,
signal,
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { MatIconModule } from '@angular/material/icon';
import { Editor } from '@tiptap/core';
import { ToolbarEditorService } from '../../toolbar-editor.service';
import { ColorPickerComponent } from '../../../color-picker';

@Component({
selector: 'team-up-toolbar-option-font',
template: `
<button
[cdkMenuTriggerFor]="menu"
class="standalone-item">
Font
</button>
<ng-template #menu>
<div
class="menu"
cdkMenu>
@for (option of options; track option.value) {
<button
[class.active]="isActiveFont(option.value)"
(cdkMenuItemTriggered)="commandFont(option.value)"
cdkMenuItem
class="menu-item">
{{ option.name }}
</button>
}
</div>
</ng-template>
<label
[title]="'Font Color'"
for="color-picker">
<team-up-color-picker
[color]="color() || '#000000'"
(change)="changeColor($event)" />
</label>
`,
styleUrls: ['../options.scss', './option-font.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [
MatIconModule,
CdkMenuTrigger,
CdkMenu,
CdkMenuGroup,
CdkMenuItemRadio,
CdkMenuItem,
ColorPickerComponent,
],
})
export class OptionFontComponent {
editor = input.required<Editor>();

options = [
{
type: 'text',
name: 'Default',
value: 'raleway',
},
{
type: 'text',
name: 'Sans',
value: 'sans',
},
{
type: 'text',
name: 'Serif',
value: 'serif',
},
{
type: 'text',
name: 'Mono',
value: 'mono',
},
{
type: 'text',
name: 'Handwriting',
value: 'handwritting',
},
];

color = signal<string>('#000000');

#toolbarEditorService = inject(ToolbarEditorService);

constructor() {
this.#toolbarEditorService.events$
.pipe(takeUntilDestroyed())
.subscribe((editor) => {
const color = editor.getAttributes('textStyle')['color'] ?? '#000000';

this.color.set(color);
});
}

isActiveFont(fontFamily: string) {
if (fontFamily === 'raleway') {
return false;
}

return this.editor().isActive('textStyle', {
fontFamily: `var(--font-${fontFamily})`,
});
}

commandFont(value: string) {
if (value === 'raleway') {
this.editor().chain().focus().unsetFontFamily().run();

return;
}

this.editor().chain().focus().setFontFamily(`var(--font-${value})`).run();
}

changeColor(color: string | undefined) {
this.editor()
.chain()
.focus()
.setColor(color ?? '#000')
.run();
}
}
Empty file.
Loading

0 comments on commit 05cb5fb

Please sign in to comment.