11import Component from ' @glimmer/component' ;
2- import { cached } from ' @glimmer/tracking' ;
32import { hash } from ' @ember/helper' ;
43
54import { Types } from ' tabster' ;
6- import { TrackedSet } from ' tracked-built-ins' ;
75// The consumer will need to provide types for tracked-toolbox.
86// Or.. better yet, we PR to trakcked-toolbox to provide them
97// eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -21,6 +19,7 @@ const TABSTER_CONFIG = JSON.stringify({
2119 },
2220});
2321
22+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2423export interface ItemSignature <Value = any > {
2524 /**
2625 * The button element will have aria-pressed="true" on it when the button is in the pressed state.
@@ -46,9 +45,11 @@ export interface ItemSignature<Value = any> {
4645 };
4746}
4847
48+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4949export type Item <Value = any > = ComponentLike <ItemSignature <Value >>;
5050
51- export interface SingleSignature <Value > {
51+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
52+ export class ToggleGroup <Value = any > extends Component <{
5253 Element: HTMLDivElement ;
5354 Args: {
5455 /**
@@ -63,136 +64,16 @@ export interface SingleSignature<Value> {
6364 *
6465 * When none of the toggles are selected, undefined will be passed.
6566 */
66- onChange? : (value : Value | undefined ) => void ;
67+ onChange: (value : Value | undefined ) => void ;
6768 };
6869 Blocks: {
6970 default: [
7071 {
71- /**
72- * The Toggle Switch
73- */
7472 Item: Item ;
7573 },
7674 ];
7775 };
78- }
79-
80- export interface MultiSignature <Value = any > {
81- Element: HTMLDivElement ;
82- Args: {
83- /**
84- * Optionally set the initial toggle state
85- */
86- value? : Value [] | Set <Value > | Value ;
87- /**
88- * Callback for when the toggle-group's state is changed.
89- *
90- * Can be used to control the state of the component.
91- *
92- *
93- * When none of the toggles are selected, undefined will be passed.
94- */
95- onChange? : (value : Set <Value >) => void ;
96- };
97- Blocks: {
98- default: [
99- {
100- /**
101- * The Toggle Switch
102- */
103- Item: Item ;
104- },
105- ];
106- };
107- }
108-
109- interface PrivateSingleSignature <Value = any > {
110- Element: HTMLDivElement ;
111- Args: {
112- type? : ' single' ;
113-
114- /**
115- * Optionally set the initial toggle state
116- */
117- value? : Value ;
118- /**
119- * Callback for when the toggle-group's state is changed.
120- *
121- * Can be used to control the state of the component.
122- *
123- *
124- * When none of the toggles are selected, undefined will be passed.
125- */
126- onChange? : (value : Value | undefined ) => void ;
127- };
128- Blocks: {
129- default: [
130- {
131- Item: Item ;
132- },
133- ];
134- };
135- }
136-
137- interface PrivateMultiSignature <Value = any > {
138- Element: HTMLDivElement ;
139- Args: {
140- type: ' multi' ;
141- /**
142- * Optionally set the initial toggle state
143- */
144- value? : Value [] | Set <Value > | Value ;
145- /**
146- * Callback for when the toggle-group's state is changed.
147- *
148- * Can be used to control the state of the component.
149- *
150- *
151- * When none of the toggles are selected, undefined will be passed.
152- */
153- onChange? : (value : Set <Value >) => void ;
154- };
155- Blocks: {
156- default: [
157- {
158- Item: Item ;
159- },
160- ];
161- };
162- }
163-
164- function isMulti(x : ' single' | ' multi' | undefined ): x is ' multi' {
165- return x === ' multi' ;
166- }
167-
168- export class ToggleGroup <Value = any > extends Component <
169- PrivateSingleSignature <Value > | PrivateMultiSignature <Value >
170- > {
171- // See: https://github.com/typed-ember/glint/issues/715
172- <template >
173- {{#if ( isMulti this . args.type) }}
174- <MultiToggleGroup
175- @ value ={{this .args.value }}
176- @ onChange ={{this .args.onChange }}
177- ...attributes
178- as | x |
179- >
180- {{yield x }}
181- </MultiToggleGroup >
182- {{else }}
183- <SingleToggleGroup
184- @ value ={{this .args.value }}
185- @ onChange ={{this .args.onChange }}
186- ...attributes
187- as | x |
188- >
189- {{yield x }}
190- </SingleToggleGroup >
191- {{/if }}
192- </template >
193- }
194-
195- class SingleToggleGroup <Value = any > extends Component <SingleSignature <Value >> {
76+ }> {
19677 @localCopy (' args.value' ) activePressed? : Value ;
19778
19879 handleToggle = (value : Value ) => {
@@ -215,47 +96,3 @@ class SingleToggleGroup<Value = any> extends Component<SingleSignature<Value>> {
21596 </div >
21697 </template >
21798}
218-
219- class MultiToggleGroup <Value = any > extends Component <MultiSignature <Value >> {
220- /**
221- * Normalizes @value to a Set
222- * and makes sure that even if the input Set is reactive,
223- * we don't mistakenly dirty it.
224- */
225- @cached
226- get activePressed(): TrackedSet <Value > {
227- let value = this .args .value ;
228-
229- if (! value ) {
230- return new TrackedSet ();
231- }
232-
233- if (Array .isArray (value )) {
234- return new TrackedSet (value );
235- }
236-
237- if (value instanceof Set ) {
238- return new TrackedSet (value );
239- }
240-
241- return new TrackedSet ([value ]);
242- }
243-
244- handleToggle = (value : Value ) => {
245- if (this .activePressed .has (value )) {
246- this .activePressed .delete (value );
247- } else {
248- this .activePressed .add (value );
249- }
250-
251- this .args .onChange ?.(new Set <Value >(this .activePressed .values ()));
252- };
253-
254- isPressed = (value : Value ) => this .activePressed .has (value );
255-
256- <template >
257- <div data-tabster ={{TABSTER_CONFIG }} ...attributes >
258- {{yield ( hash Item =( component Toggle onChange =this . handleToggle isPressed =this . isPressed) ) }}
259- </div >
260- </template >
261- }
0 commit comments