Skip to content
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

Can't open a dialog from a different component. #35

Closed
2 tasks
tutkli opened this issue Oct 17, 2023 · 3 comments · Fixed by #180
Closed
2 tasks

Can't open a dialog from a different component. #35

tutkli opened this issue Oct 17, 2023 · 3 comments · Fixed by #180
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@tutkli
Copy link
Contributor

tutkli commented Oct 17, 2023

Please provide the environment you discovered this bug in.

@angular/core: "16.2.6"
@angular/cdk: "16.2.8"
@spartan-ng/ui-core: "0.0.1-alpha.309"
@spartan-ng/ui-dialog-brain: "0.0.1-alpha.309"

Which area/package is the issue in?

dialog

Description

Currently the Angular's cdk dialog login is wrapped inside brnDialog (and brnDialogService), so it's impossible to trigger open a dialog from another component.

Say I want to open a dialog from a random button. With Angular's cdk I would do:

import {Component, inject} from "@angular/core";
import {Dialog} from "@angular/cdk/dialog";

@Component({
    selector: 'app-button',
    standalone: true,
    template: `
    <button (click)="openDialog()">Open</button>`
})
export class ButtonComponent {
    dialog = inject(Dialog);
    
    openDialog() {
        this.dialog.open(MyDialogComponent);
    }
}

BrnDialogService is made to be use only inside BrnDialog, so it removes this feature completely.
The only way to show a dialog is to have both dialog and trigger in the same template,

Please provide the exception or error you saw

No response

Other information

No response

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

  • Yes
  • No
@tutkli tutkli added the bug Something isn't working label Oct 17, 2023
@goetzrobin
Copy link
Owner

Thanks for opening this! I am looking into how to best implement this.
What would you like the template of the MyDialogComponent to look like?

The_ only way to show a dialog is to have both dialog and trigger in the same template.

It is possible to bind to the state input of the dialog.
Here is an example:

@Component({
  selector: 'combobox-component',
  standalone: true,
  imports: [
    NgForOf,
    BrnCommandImports,
    HlmCommandImports,
    BrnPopoverImports,
    HlmPopoverContentDirective,
    HlmIconComponent,
    HlmButtonDirective,
  ],
  template: `
    <brn-popover [state]="state()" (closed)="close()" sideOffset="5" closeDelay="100">
      <button class="w-[200px] justify-between" id="edit-profile" variant="outline" brnPopoverTrigger hlmBtn>
        {{ currentFramework() ? currentFramework().label : 'Select framework...' }}
        <hlm-icon size="sm" name="radixCaretSort" />
      </button>
      <brn-cmd *brnPopoverContent="let ctx" hlmPopoverContent hlm class="p-0 w-[200px]">
        <hlm-cmd-input-wrapper>
          <hlm-icon name="radixMagnifyingGlass" />
          <input placeholder="Search framework..." brnCmdInput hlm />
        </hlm-cmd-input-wrapper>
        <div *brnCmdEmpty hlmCmdEmpty>No results found.</div>
        <brn-cmd-list hlm>
          <brn-cmd-group hlm>
            <button
              *ngFor="let framework of frameworks"
              brnCmdItem
              [value]="framework.value"
              (selected)="commandSelected(framework)"
              hlm
            >
              <hlm-icon
                [class.opacity-0]="currentFramework()?.value !== framework.value"
                name="radixCheck"
                hlmCmdIcon
              />
              {{ framework.label }}
            </button>
          </brn-cmd-group>
        </brn-cmd-list>
      </brn-cmd>
    </brn-popover>
  `,
})
class ComboboxComponent {
  public frameworks = [
    {
      label: 'AnalogJs',
      value: 'analogjs',
    },
    {
      label: 'Angular',
      value: 'angular',
    },
    {
      label: 'Vue',
      value: 'vue',
    },
    {
      label: 'Nuxt',
      value: 'nuxt',
    },
    {
      label: 'React',
      value: 'react',
    },
    {
      label: 'NextJs',
      value: 'nextjs',
    },
  ];
  public currentFramework = signal<Framework | undefined>(undefined);
  public state = signal<'closed' | 'open'>('closed');

  close() {
    this.state.set('closed');
  }

  commandSelected(framework: Framework) {
    this.state.set('closed');
    if (this.currentFramework()?.value === framework.value) {
      this.currentFramework.set(undefined);
    } else {
      this.currentFramework.set(framework);
    }
  }
}

This example uses a local signal, but that is not necessary. The signal (or an BehaviorSubject) could also live in an injectable service, which allows you to open the dialog from other places

@goetzrobin
Copy link
Owner

@tutkli let me know if my explanation helps in the meantime or if you'd like me to create a more elaborate example!

@tutkli
Copy link
Contributor Author

tutkli commented Oct 18, 2023

@goetzrobin Thank you for the example, I think is a good workaround.

I think the service should create a cdk-dialog wrapper with the contents of the component we send as an argument. Similar to how Angular cdk does. So if this is the component I want to open in a dialog:

@Component({
    selector: 'app-my-dialog',
    standalone: true,
    template: `
    <p>Hello World</p>`
})
export class MyDialogComponent{}

brnDialog.open() should create:

<cdk-dialog-container>
  <app-my-dialog>
    <p>Hello World</p>
  </app-my-dialog>
</brn-dialog>

I hope this makes sense.

@goetzrobin goetzrobin added enhancement New feature or request help wanted Extra attention is needed and removed bug Something isn't working labels Dec 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants