Skip to content

Commit

Permalink
chore(toolbar): workaround with toggle group
Browse files Browse the repository at this point in the history
  • Loading branch information
pimenovoleg committed Jan 11, 2025
1 parent 0356287 commit 8bb879d
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 9 deletions.
1 change: 1 addition & 0 deletions packages/primitives/toggle-group/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './src/toggle-group-item.directive';
export * from './src/toggle-group-item.token';
export * from './src/toggle-group-without-focus.directive';
export * from './src/toggle-group.directive';
export * from './src/toggle-group.token';
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { BooleanInput } from '@angular/cdk/coercion';
import { booleanAttribute, Directive, input, model, output, signal } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { RdxToggleGroupToken } from './toggle-group.token';

let nextId = 0;

@Directive({
selector: '[rdxToggleGroupWithoutFocus]',
exportAs: 'rdxToggleGroupWithoutFocus',
standalone: true,
providers: [
{ provide: RdxToggleGroupToken, useExisting: RdxToggleGroupWithoutFocusDirective },
{ provide: NG_VALUE_ACCESSOR, useExisting: RdxToggleGroupWithoutFocusDirective, multi: true }
],
host: {
role: 'group',
'(focusout)': 'onTouched?.()'
}
})
export class RdxToggleGroupWithoutFocusDirective implements ControlValueAccessor {
/**
* @ignore
*/
readonly id: string = `rdx-toggle-group-${nextId++}`;

/**
* @group Props
*/
readonly value = model<string | string[] | undefined>(undefined);

/**
* @group Props
*/
readonly type = input<'single' | 'multiple'>('single');

/**
* Whether the toggle group is disabled.
* @defaultValue false
* @group Props
*/
readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });

/**
* Event emitted when the selected toggle button changes.
* @group Emits
*/
readonly onValueChange = output<string[] | string | undefined>();

/**
* The value change callback.
*/
private onChange?: (value: string | string[] | undefined) => void;

/**
* onTouch function registered via registerOnTouch (ControlValueAccessor).
*/
protected onTouched?: () => void;

/**
* Toggle a value.
* @param value The value to toggle.
* @ignore
*/
toggle(value: string): void {
if (this.disabled()) {
return;
}

if (this.type() === 'single') {
this.value.set(value);
} else {
this.value.set(
((currentValue) =>
currentValue && Array.isArray(currentValue)
? currentValue.includes(value)
? currentValue.filter((v) => v !== value) // delete
: [...currentValue, value] // update
: [value])(this.value())
);
}

this.onValueChange.emit(this.value());
this.onChange?.(this.value());
}

/**
* Select a value from Angular forms.
* @param value The value to select.
* @ignore
*/
writeValue(value: string): void {
this.value.set(value);
}

/**
* Register a callback to be called when the value changes.
* @param fn The callback to register.
* @ignore
*/
registerOnChange(fn: (value: string | string[] | undefined) => void): void {
this.onChange = fn;
}

/**
* Register a callback to be called when the toggle group is touched.
* @param fn The callback to register.
* @ignore
*/
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}

private readonly accessorDisabled = signal(false);

/**
* Set the disabled state of the toggle group.
* @param isDisabled Whether the toggle group is disabled.
* @ignore
*/
setDisabledState(isDisabled: boolean): void {
this.accessorDisabled.set(isDisabled);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BooleanInput } from '@angular/cdk/coercion';
import { booleanAttribute, Directive, input, model, output, signal } from '@angular/core';
import { booleanAttribute, Directive, forwardRef, input, model, output, signal } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { RdxRovingFocusGroupDirective } from '@radix-ng/primitives/roving-focus';
import { RdxToggleGroupToken } from './toggle-group.token';
Expand All @@ -12,10 +12,9 @@ let nextId = 0;
@Directive({
selector: '[rdxToggleGroup]',
exportAs: 'rdxToggleGroup',
standalone: true,
providers: [
{ provide: RdxToggleGroupToken, useExisting: RdxToggleGroupDirective },
{ provide: NG_VALUE_ACCESSOR, useExisting: RdxToggleGroupDirective, multi: true }
{ provide: RdxToggleGroupToken, useExisting: forwardRef(() => RdxToggleGroupDirective) },
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RdxToggleGroupDirective), multi: true }
],
hostDirectives: [{ directive: RdxRovingFocusGroupDirective, inputs: ['dir', 'orientation', 'loop'] }],
host: {
Expand Down
13 changes: 10 additions & 3 deletions packages/primitives/toggle-group/src/toggle-group.token.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { inject, InjectionToken } from '@angular/core';
import type { RdxToggleGroupDirective } from './toggle-group.directive';

export const RdxToggleGroupToken = new InjectionToken<RdxToggleGroupDirective>('RdxToggleGroupToken');
export interface IRdxToggleGroup {
toggle(value: string): void;

export function injectToggleGroup(): RdxToggleGroupDirective {
disabled: any;
value: any;
type: any;
}

export const RdxToggleGroupToken = new InjectionToken<IRdxToggleGroup>('RdxToggleGroupToken');

export function injectToggleGroup(): IRdxToggleGroup {
return inject(RdxToggleGroupToken);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Directive } from '@angular/core';
import { RdxToggleGroupDirective } from '@radix-ng/primitives/toggle-group';
import { RdxToggleGroupWithoutFocusDirective } from '@radix-ng/primitives/toggle-group';

// TODO: set rovingFocus - false
@Directive({
selector: '[rdxToolbarToggleGroup]',
hostDirectives: [{ directive: RdxToggleGroupDirective, inputs: ['value', 'type', 'disabled'] }]
hostDirectives: [{ directive: RdxToggleGroupWithoutFocusDirective, inputs: ['value', 'type', 'disabled'] }]
})
export class RdxToolbarToggleGroupDirective {}

0 comments on commit 8bb879d

Please sign in to comment.