@@ -5,9 +5,10 @@ import {
55}  from  '@gouvfr-lasuite/ui-kit' ; 
66import  {  useRouter  }  from  'next/navigation' ; 
77import  {  useState  }  from  'react' ; 
8+ import  {  useTranslation  }  from  'react-i18next' ; 
89import  {  css  }  from  'styled-components' ; 
910
10- import  {  Box ,  Icon ,  Text  }  from  '@/components' ; 
11+ import  {  Box ,  BoxButton ,   Icon ,  Text  }  from  '@/components' ; 
1112import  {  useCunninghamTheme  }  from  '@/cunningham' ; 
1213import  { 
1314  Doc , 
@@ -20,6 +21,7 @@ import { useResponsiveStore } from '@/stores';
2021
2122import  SubPageIcon  from  './../assets/sub-page-logo.svg' ; 
2223import  {  DocTreeItemActions  }  from  './DocTreeItemActions' ; 
24+ import  {  useKeyboardActivation  }  from  './hooks/useKeyboardActivation' ; 
2325
2426const  ItemTextCss  =  css ` 
2527  overflow :  hidden; 
@@ -38,14 +40,23 @@ export const DocSubPageItem = (props: TreeViewNodeProps<Doc>) => {
3840  const  {  node }  =  props ; 
3941  const  {  spacingsTokens }  =  useCunninghamTheme ( ) ; 
4042  const  {  isDesktop }  =  useResponsiveStore ( ) ; 
41-   const  [ actionsOpen ,  setActionsOpen ]  =  useState ( false ) ; 
43+   const  {  t }  =  useTranslation ( ) ; 
44+ 
45+   const  [ menuOpen ,  setMenuOpen ]  =  useState ( false ) ; 
46+   const  isSelectedNow  =  treeContext ?. treeData . selectedNode ?. id  ===  doc . id ; 
47+   const  isActive  =  node . isFocused  ||  menuOpen  ||  isSelectedNow ; 
4248
4349  const  router  =  useRouter ( ) ; 
4450  const  {  togglePanel }  =  useLeftPanelStore ( ) ; 
4551
4652  const  {  emoji,  titleWithoutEmoji }  =  getEmojiAndTitle ( doc . title  ||  '' ) ; 
4753  const  displayTitle  =  titleWithoutEmoji  ||  untitledDocument ; 
4854
55+   const  handleActivate  =  ( )  =>  { 
56+     treeContext ?. treeData . setSelectedNode ( doc ) ; 
57+     router . push ( `/docs/${ doc . id }  ) ; 
58+   } ; 
59+ 
4960  const  afterCreate  =  ( createdDoc : Doc )  =>  { 
5061    const  actualChildren  =  node . data . children  ??  [ ] ; 
5162
@@ -76,62 +87,66 @@ export const DocSubPageItem = (props: TreeViewNodeProps<Doc>) => {
7687    } 
7788  } ; 
7889
90+   useKeyboardActivation ( 
91+     [ 'Enter' ,  ' ' ] , 
92+     isActive  &&  ! menuOpen , 
93+     handleActivate , 
94+     true , 
95+   ) ; 
96+ 
97+   const  docTitle  =  doc . title  ||  untitledDocument ; 
98+   const  hasChildren  =  ( doc . children ?. length  ||  0 )  >  0 ; 
99+   const  isExpanded  =  node . isOpen ; 
100+   const  isSelected  =  isSelectedNow ; 
101+   const  ariaLabel  =  docTitle ; 
102+ 
79103  return  ( 
80104    < Box 
81105      className = "--docs-sub-page-item" 
82106      draggable = { doc . abilities . move  &&  isDesktop } 
83107      $position = "relative" 
108+       role = "treeitem" 
109+       aria-label = { ariaLabel } 
110+       aria-selected = { isSelected } 
111+       aria-expanded = { hasChildren  ? isExpanded  : undefined } 
84112      $css = { css ` 
85-         background-color : ${ actionsOpen  
86-           ? 'var(--c--theme--colors--greyscale-100)'  
87-           : 'var(--c--theme--colors--greyscale-000)' }  ;
88- 
89-         .light-doc-item-actions  { 
90-           display : ${ actionsOpen  ||  ! isDesktop  ? 'flex'  : 'none' }  
91-           position :  absolute; 
92-           right :  0 ; 
93-           background : ${ isDesktop  
94-             ? 'var(--c--theme--colors--greyscale-100)'  
95-             : 'var(--c--theme--colors--greyscale-000)' }  ;
96-         } 
97- 
98-         .c__tree-view--node .isSelected  { 
99-           .light-doc-item-actions  { 
100-             background :  var (--c--theme--colors--greyscale-100 ); 
101-           } 
113+         .c__tree-view--node  { 
114+           padding : ${ spacingsTokens [ '3xs' ] }  
115+           border-radius :  4px  ; 
102116        } 
103117
104-         & : hover  { 
118+         . c__tree-view--node : hover  { 
105119          background-color :  var (--c--theme--colors--greyscale-100 ); 
106-            border-radius :   4 px ;  
120+         }  
107121
108-           .light-doc-item-actions  { 
109-             display :  flex; 
110-             background :  var (--c--theme--colors--greyscale-100 ); 
111-           } 
122+         .light-doc-item-actions  { 
123+           display :  flex; 
124+           opacity : ${ isActive  ||  ! isDesktop  ? 1  : 0 }  
125+           position :  absolute; 
126+           right :  0 ; 
127+           top :  0 ; 
128+           height :  100%  ; 
129+           z-index :  10 ; 
112130        } 
113131
114132        .row .preview  &  { 
115133          background-color :  inherit; 
116134        } 
117135      ` } 
118136    > 
119-       < TreeViewItem 
120-         { ...props } 
121-         onClick = { ( )  =>  { 
122-           treeContext ?. treeData . setSelectedNode ( props . node . data . value  as  Doc ) ; 
123-           router . push ( `/docs/${ props . node . data . value . id }  ) ; 
124-         } } 
125-       > 
126-         < Box 
127-           data-testid = { `doc-sub-page-item-${ props . node . data . value . id }  } 
137+       < TreeViewItem  { ...props }  onClick = { handleActivate } > 
138+         < BoxButton 
139+           onClick = { ( e )  =>  { 
140+             e . stopPropagation ( ) ; 
141+             handleActivate ( ) ; 
142+           } } 
128143          $width = "100%" 
129144          $direction = "row" 
130145          $gap = { spacingsTokens [ 'xs' ] } 
131-           role = "button" 
132-           tabIndex = { 0 } 
133146          $align = "center" 
134147          $minHeight = "24px" 
148+           data-testid = { `doc-sub-page-item-${ doc . id }  } 
149+           aria-label = { `${ t ( 'Open document' ) } ${ docTitle }  } 
135150        > 
136151          < Box  $width = "16px"  $height = "16px" > 
137152            < DocIcon  emoji = { emoji }  defaultIcon = { < SubPageIcon  /> }  $size = "sm"  /> 
@@ -157,25 +172,28 @@ export const DocSubPageItem = (props: TreeViewNodeProps<Doc>) => {
157172                iconName = "group" 
158173                $size = "16px" 
159174                $variation = "400" 
175+                 aria-hidden = "true" 
160176              /> 
161177            ) } 
162178          </ Box > 
163- 
164-           < Box 
165-             $direction = "row" 
166-             $align = "center" 
167-             className = "light-doc-item-actions" 
168-           > 
169-             < DocTreeItemActions 
170-               doc = { doc } 
171-               isOpen = { actionsOpen } 
172-               onOpenChange = { setActionsOpen } 
173-               parentId = { node . data . parentKey } 
174-               onCreateSuccess = { afterCreate } 
175-             /> 
176-           </ Box > 
177-         </ Box > 
179+         </ BoxButton > 
178180      </ TreeViewItem > 
181+ 
182+       < Box 
183+         $direction = "row" 
184+         $align = "center" 
185+         className = "light-doc-item-actions" 
186+         role = "toolbar" 
187+         aria-label = { `${ t ( 'Actions for' ) } ${ docTitle }  } 
188+       > 
189+         < DocTreeItemActions 
190+           doc = { doc } 
191+           isOpen = { menuOpen } 
192+           onOpenChange = { setMenuOpen } 
193+           parentId = { node . data . parentKey } 
194+           onCreateSuccess = { afterCreate } 
195+         /> 
196+       </ Box > 
179197    </ Box > 
180198  ) ; 
181199} ; 
0 commit comments