goetzrobin / spartan

Cutting-edge tools powering Angular full-stack development.
https://spartan.ng
MIT License
1.22k stars 133 forks source link

Accordion: allow to set open/closed state through Input. #144

Closed juancarlosgzs closed 6 months ago

juancarlosgzs commented 6 months ago

Which scope/s are relevant/related to the feature request?

accordion

Information

It's a very common usecase to have, at least, the first accordion item open by default but right now, there is not an straightforward way to handle such situation with our Accordion.

I'd suggest to have an optional @Input() in the hlmAccordionItem that determines the default state, the "problem" with this solution is that I think it would, at least theoretically, allow to open multiple accordions at the same time (This is something that could actually be needed in the future tbh, but I understand this depends in what your goal is with the component itself)

Another option could be by setting a value in the hlmAccordion and set in there which accordion you want to be "active", just like in the tabs component, the issue with this second option is that it would require some kind of id (or maybe simply use the index itself) to idetify the hlmAccordionItem to be opened.

Just some random thoughts.

Describe any alternatives/workarounds you're currently using

Right now it's needed to trigger a click on the element programatically to handle such situations, which turns out to be a bit annoying, specially taking into account the time it takes for the element to ACTUALLY render, which could lead to a race situation.

Example:

@Component({
  imports: [
    CommonModule,
    HlmAccordionModule,
    BrnAccordionModule,
    HlmButtonModule,
    HlmIconModule,
    HlmSeparatorModule,
    BrnSeparatorModule,
  ],
  providers: [],
  template: `
    <div hlmAccordion>
      <div hlmAccordionItem>
        <button hlmAccordionTrigger #firstAccordionTrigger>
          Is it accessible?
          <hlm-icon hlmAccIcon />
        </button>
        <brn-accordion-content hlm
          >Yes. It adheres to the WAI-ARIA design pattern.</brn-accordion-content
        >
      </div>

      <div hlmAccordionItem>
        <button hlmAccordionTrigger>
          Is it styled?
          <hlm-icon hlmAccIcon />
        </button>
        <brn-accordion-content hlm>
          Yes. It comes with default styles that match the other components' aesthetics.
        </brn-accordion-content>
      </div>
    </div>
  `,
  selector: 'nx-cart',
  standalone: true,
})
export class CartComponent implements AfterViewInit {
  @ViewChild('firstAccordionTrigger') firstAccordionTrigger?: ElementRef;

  constructor() {}

  ngAfterViewInit(): void {
    setTimeout(() => {
      this.firstAccordionTrigger?.nativeElement?.click();
    }, 100);
  }
}

PD: If there are other alternatives that comes to mind, please let me know 😁

I would be willing to submit a PR to fix this issue

goetzrobin commented 6 months ago

Thanks for suggesting this @juancarlosgzs! I think we can definitely add some functionality like that!