Files
openstapps/frontend/app/src/app/modules/data/elements/title-card.component.ts
2024-05-27 15:07:26 +02:00

95 lines
3.1 KiB
TypeScript

/*
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, ElementRef, HostListener, Input, OnChanges, OnInit, ViewChild} from '@angular/core';
import {SCThings} from '@openstapps/core';
import {SCIcon} from '../../../util/ion-icon/icon';
const AccordionButtonState = {
collapsed: SCIcon.expand_more,
expanded: SCIcon.expand_less,
};
@Component({
selector: 'stapps-title-card',
templateUrl: './title-card.component.html',
styleUrls: ['./title-card.component.scss'],
})
export class TitleCardComponent implements OnInit, OnChanges {
/**
* The item whose title (and description) to display
*/
@Input() item: SCThings;
@ViewChild('accordionTextArea') accordionTextArea: ElementRef;
buttonState: (typeof AccordionButtonState)[keyof typeof AccordionButtonState] =
AccordionButtonState.collapsed;
buttonShown = true;
descriptionLinesShown: number;
descriptionLinesTotal: number;
descriptionPreviewLines = 3;
descriptionLinesToDisplay = 0;
ngOnInit(): void {
if (this.item.description) {
this.descriptionLinesToDisplay = this.descriptionPreviewLines;
setTimeout(() => this.checkTextElipsis(), 100);
}
}
ngOnChanges() {
this.checkTextElipsis();
}
@HostListener('window:resize', ['$event'])
checkTextElipsis() {
if (this.accordionTextArea === undefined) {
return;
}
const element = this.accordionTextArea.nativeElement as HTMLElement;
const lineHeight = Number.parseInt(getComputedStyle(element).getPropertyValue('line-height'));
this.descriptionLinesTotal = element?.scrollHeight / lineHeight;
this.descriptionLinesShown = element?.offsetHeight / lineHeight;
if (this.buttonState === AccordionButtonState.expanded) {
this.descriptionLinesToDisplay = this.descriptionLinesTotal;
}
const isElipsed = element?.offsetHeight < element?.scrollHeight;
this.buttonShown =
(isElipsed && this.buttonState === AccordionButtonState.collapsed) ||
(!isElipsed && this.buttonState === AccordionButtonState.expanded);
}
toggleDescriptionAccordion() {
if (this.descriptionLinesToDisplay > 0) {
this.descriptionLinesToDisplay =
this.descriptionLinesToDisplay === this.descriptionPreviewLines
? this.descriptionLinesTotal
: this.descriptionPreviewLines;
}
this.buttonState =
this.buttonState === AccordionButtonState.collapsed
? AccordionButtonState.expanded
: AccordionButtonState.collapsed;
setTimeout(() => this.checkTextElipsis(), 0);
}
}