1- import ' ../../styles/horizontal-scroll.css' ;
21import Component from ' @glimmer/component' ;
3- import { trackedRef } from ' ember-ref-bucket' ;
4- import { action } from ' @ember/object' ;
5- import { debounce , cancel } from ' @ember/runloop' ;
6- import { tracked } from ' @glimmer/tracking' ;
7- // eslint-disable-next-line @typescript-eslint/no-unused-vars
8- import { on } from ' @ember/modifier' ;
9- // eslint-disable-next-line @typescript-eslint/no-unused-vars
10- import { fn } from ' @ember/helper' ;
112// eslint-disable-next-line @typescript-eslint/no-unused-vars
123import { array } from ' @ember/helper' ;
134// eslint-disable-next-line @typescript-eslint/no-unused-vars
14- import htmlSafe from ' brn/helpers/html-safe' ;
15- // eslint-disable-next-line @typescript-eslint/no-unused-vars
16- import createRef from ' ember-ref-bucket/modifiers/create-ref' ;
17- // eslint-disable-next-line @typescript-eslint/no-unused-vars
185import UiTabButton from ' brn/components/ui/tab-button' ;
196// eslint-disable-next-line @typescript-eslint/no-unused-vars
7+ import UiHorizontalScroll from ' brn/components/ui/horizontal-scroll' ;
8+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
209import autofitText from ' brn/modifiers/autofit-text' ;
2110
2211interface SubgroupItem {
@@ -34,10 +23,6 @@ interface SubgroupNavigationSignature {
3423}
3524
3625export default class SubgroupNavigation extends Component <SubgroupNavigationSignature > {
37- @trackedRef (' container' ) container! : HTMLUListElement ;
38- @tracked scrollIteration = 0 ;
39- debounceTimer: ReturnType <typeof debounce > | undefined = undefined ;
40-
4126 get sortedExercises(): SubgroupItem [] {
4227 const group = this .args .group as SubgroupItem [] | undefined ;
4328 if (! group || ! Array .isArray (group )) return [];
@@ -48,104 +33,22 @@ export default class SubgroupNavigation extends Component<SubgroupNavigationSign
4833 });
4934 }
5035
51- get showLeftScrollButton() {
52- return this .hasScrollAtAll && this .container ?.scrollLeft > 0 ;
53- }
54- get showRightScrollButton() {
55- if (! this .hasScrollAtAll ) {
56- return false ;
57- }
58- const scrollSize = this .container ?.offsetWidth + this .container ?.scrollLeft ;
59- const result = scrollSize <= this .container ?.scrollWidth ;
60- return result ;
61- }
62- get hasScrollAtAll() {
63- this .scrollIteration ; // track iteration
64- if (! this .container ) {
65- return false ;
66- }
67- return this .container ?.scrollWidth > this .container ?.offsetWidth ;
68- }
69-
70- @action scroll(direction : ' right' | ' left' ) {
71- const position = this .container .scrollLeft ;
72- const offset = 150 ;
73- const newPosition =
74- direction === ' right' ? position + offset : position - offset ;
75- this .container .scrollTo ({
76- top: 0 ,
77- left: newPosition ,
78- behavior: ' smooth' ,
79- });
80- }
81-
82- @action onScroll() {
83- cancel (this .debounceTimer );
84- this .debounceTimer = debounce (this , this .updateScroll , 100 );
85- }
86-
87- updateScroll() {
88- this .scrollIteration ++ ;
89- }
90-
91- willDestroy() {
92- super .willDestroy ();
93- cancel (this .debounceTimer );
94- }
95-
9636 <template >
97- <div class =" hs-container" ...attributes >
98- <div class =" full relative overflow-hidden" >
99- {{#if this . showLeftScrollButton }}
100- <div class =" scroll-fade scroll-fade--left" ></div >
101- <button
102- type =" button"
103- class =" scroll-btn bg-purple-primary hover:opacity-75 focus:outline-hidden absolute left-0 z-20 flex items-center justify-center w-8 h-8 text-white rounded-full shadow-md"
104-
105- {{on " click" ( fn this . scroll " left" ) }}
106- aria-label =" Scroll left"
107- >
108- <svg xmlns =" http://www.w3.org/2000/svg" class =" w-5 h-5" viewBox =" 0 0 20 20" fill =" currentColor" >
109- <path fill-rule =" evenodd" d =" M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule =" evenodd" />
110- </svg >
111- </button >
112- {{/if }}
113- <ul
114- class =" hs no-scrollbar"
115- style ={{htmlSafe " scroll-behavior: smooth;" }}
116- {{createRef " container" }}
117- {{on " scroll" this . onScroll}}
118- >
119- {{#each this . sortedExercises as | exercise | }}
120- <li class =" item" >
121- <UiTabButton
122- data-test-active-link ={{exercise.name }}
123- class =" pl-3 pr-3"
124- @ small ={{ true }}
125- @ route =" group.series.subgroup"
126- @ models ={{array exercise.id }}
127- @ title ={{exercise.name }}
128- @ tooltip ={{exercise.description }}
129- {{autofitText exercise.name }}
130- />
131- </li >
132- {{/each }}
133- </ul >
134- {{#if this . showRightScrollButton }}
135- <div class =" scroll-fade scroll-fade--right" ></div >
136- <button
137- type =" button"
138- class =" scroll-btn bg-purple-primary hover:opacity-75 focus:outline-hidden absolute right-0 z-20 flex items-center justify-center w-8 h-8 text-white rounded-full shadow-md"
139-
140- {{on " click" ( fn this . scroll " right" ) }}
141- aria-label =" Scroll right"
142- >
143- <svg xmlns =" http://www.w3.org/2000/svg" class =" w-5 h-5" viewBox =" 0 0 20 20" fill =" currentColor" >
144- <path fill-rule =" evenodd" d =" M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule =" evenodd" />
145- </svg >
146- </button >
147- {{/if }}
148- </div >
149- </div >
37+ <UiHorizontalScroll ...attributes >
38+ {{#each this . sortedExercises as | exercise | }}
39+ <li class =" item" >
40+ <UiTabButton
41+ data-test-active-link ={{exercise.name }}
42+ class =" pl-3 pr-3"
43+ @ small ={{ true }}
44+ @ route =" group.series.subgroup"
45+ @ models ={{array exercise.id }}
46+ @ title ={{exercise.name }}
47+ @ tooltip ={{exercise.description }}
48+ {{autofitText exercise.name }}
49+ />
50+ </li >
51+ {{/each }}
52+ </UiHorizontalScroll >
15053 </template >
15154}
0 commit comments