Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
coopwire-hypothesis
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
孙灵跃 Leon Sun
coopwire-hypothesis
Commits
f9fda4bc
Commit
f9fda4bc
authored
Apr 24, 2023
by
Lyza Danger Gardner
Committed by
Alejandro Celaya
Apr 28, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use Slider component from frontend-shared and drop local one
parent
89c46e70
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
10 additions
and
248 deletions
+10
-248
MenuItem.tsx
src/sidebar/components/MenuItem.tsx
+6
-3
SidebarPanel.tsx
src/sidebar/components/SidebarPanel.tsx
+1
-2
Slider.tsx
src/sidebar/components/Slider.tsx
+0
-113
MenuItem-test.js
src/sidebar/components/test/MenuItem-test.js
+2
-2
SidebarPanel-test.js
src/sidebar/components/test/SidebarPanel-test.js
+1
-1
slider-test.js
src/sidebar/components/test/slider-test.js
+0
-127
No files found.
src/sidebar/components/MenuItem.tsx
View file @
f9fda4bc
import
{
CaretUpIcon
,
MenuExpandIcon
}
from
'@hypothesis/frontend-shared'
;
import
{
CaretUpIcon
,
MenuExpandIcon
,
Slider
,
}
from
'@hypothesis/frontend-shared'
;
import
type
{
IconComponent
}
from
'@hypothesis/frontend-shared/lib/types'
;
import
classnames
from
'classnames'
;
import
type
{
ComponentChildren
,
Ref
}
from
'preact'
;
import
{
useEffect
,
useRef
}
from
'preact/hooks'
;
import
MenuKeyboardNavigation
from
'./MenuKeyboardNavigation'
;
import
Slider
from
'./Slider'
;
type
SubmenuToggleProps
=
{
title
:
string
;
...
...
@@ -305,7 +308,7 @@ export default function MenuItem({
<>
{
menuItem
}
{
hasSubmenuVisible
&&
(
<
Slider
visible=
{
isSubmenuVisible
}
>
<
Slider
direction=
{
isSubmenuVisible
?
'in'
:
'out'
}
>
<
MenuKeyboardNavigation
closeMenu=
{
onCloseSubmenu
}
visible=
{
isSubmenuVisible
}
...
...
src/sidebar/components/SidebarPanel.tsx
View file @
f9fda4bc
import
{
Dialog
}
from
'@hypothesis/frontend-shared'
;
import
{
Dialog
,
Slider
}
from
'@hypothesis/frontend-shared'
;
import
type
{
IconComponent
}
from
'@hypothesis/frontend-shared/lib/types'
;
import
type
{
ComponentChildren
}
from
'preact'
;
import
{
useCallback
,
useEffect
,
useRef
}
from
'preact/hooks'
;
...
...
@@ -6,7 +6,6 @@ import scrollIntoView from 'scroll-into-view';
import
type
{
PanelName
}
from
'../../types/sidebar'
;
import
{
useSidebarStore
}
from
'../store'
;
import
Slider
from
'./Slider'
;
export
type
SidebarPanelProps
=
{
children
:
ComponentChildren
;
...
...
src/sidebar/components/Slider.tsx
deleted
100644 → 0
View file @
89c46e70
import
type
{
ComponentChildren
}
from
'preact'
;
import
{
useCallback
,
useEffect
,
useRef
,
useState
}
from
'preact/hooks'
;
export
type
SliderProps
=
{
/** The content to hide or reveal. */
children
?:
ComponentChildren
;
/** Whether the content should be visible or not. */
visible
:
boolean
;
/** Invoked once the open/close transitions have finished */
onTransitionEnd
?:
(
direction
:
'in'
|
'out'
)
=>
void
;
};
/**
* A container which reveals its content when `visible` is `true` using
* a sliding animation.
*
* When the content is not partially or wholly visible, it is removed from the
* DOM using `display: none` so it does not appear in the keyboard navigation
* order.
*
* Currently, the only reveal/expand direction supported is top-down.
*/
export
default
function
Slider
({
children
,
visible
,
onTransitionEnd
,
}:
SliderProps
)
{
const
containerRef
=
useRef
<
HTMLDivElement
|
null
>
(
null
);
const
[
containerHeight
,
setContainerHeight
]
=
useState
(
visible
?
'auto'
:
0
);
// Whether the content is currently partially or wholly visible. This is
// different from `visible` when collapsing as it is true until the collapse
// animation completes.
const
[
contentVisible
,
setContentVisible
]
=
useState
(
visible
);
// Adjust the container height when the `visible` prop changes.
useEffect
(()
=>
{
const
isVisible
=
containerHeight
!==
0
;
if
(
visible
===
isVisible
)
{
// Do nothing after the initial mount.
return
;
}
const
el
=
containerRef
.
current
!
;
if
(
visible
)
{
// Show the content synchronously so that we can measure it here.
el
.
style
.
display
=
''
;
// Make content visible in future renders.
setContentVisible
(
true
);
// When expanding, transition the container to the current fixed height
// of the content. After the transition completes, we'll reset to "auto"
// height to adapt to future content changes.
setContainerHeight
(
el
.
scrollHeight
);
}
else
{
// When collapsing, immediately change the current height to a fixed height
// (in case it is currently "auto"), force a synchronous layout,
// then transition to 0.
//
// These steps are needed because browsers will not animate transitions
// from "auto" => "0" and may not animate "auto" => fixed height => 0
// if the layout tree transitions directly from "auto" => 0.
el
.
style
.
height
=
`
${
el
.
scrollHeight
}
px`
;
// Force a sync layout.
el
.
getBoundingClientRect
();
setContainerHeight
(
0
);
}
},
[
containerHeight
,
visible
]);
const
handleTransitionEnd
=
useCallback
(()
=>
{
if
(
visible
)
{
setContainerHeight
(
'auto'
);
onTransitionEnd
?.(
'in'
);
}
else
{
// When the collapse animation completes, stop rendering the content so
// that the browser has fewer nodes to render and the content is removed
// from keyboard navigation.
setContentVisible
(
false
);
onTransitionEnd
?.(
'out'
);
}
},
[
setContainerHeight
,
visible
,
onTransitionEnd
]);
const
isFullyVisible
=
containerHeight
===
'auto'
;
return
(
<
div
// nb. Preact uses "ontransitionend" rather than "onTransitionEnd".
// See https://bugs.chromium.org/p/chromium/issues/detail?id=961193
//
// @ts-ignore
// eslint-disable-next-line react/no-unknown-property
ontransitionend=
{
handleTransitionEnd
}
ref=
{
containerRef
}
style=
{
{
display
:
contentVisible
?
''
:
'none'
,
height
:
containerHeight
,
// When the Slider is fully open, overflow is made visible so that
// focus rings, which may extend outside the bounds of the Slider content,
// are visible.
overflow
:
isFullyVisible
?
'visible'
:
'hidden'
,
transition
:
`height 0.15s ease-in`
,
}
}
>
{
children
}
</
div
>
);
}
src/sidebar/components/test/MenuItem-test.js
View file @
f9fda4bc
...
...
@@ -190,7 +190,7 @@ describe('MenuItem', () => {
isSubmenuVisible
:
true
,
submenu
:
<
div
role
=
"menuitem"
>
Submenu
content
<
/div>
,
});
assert
.
equal
(
wrapper
.
find
(
'Slider'
).
prop
(
'
visible'
),
true
);
assert
.
equal
(
wrapper
.
find
(
'Slider'
).
prop
(
'
direction'
),
'in'
);
assert
.
equal
(
wrapper
.
find
(
'MenuKeyboardNavigation'
).
prop
(
'visible'
),
true
...
...
@@ -203,7 +203,7 @@ describe('MenuItem', () => {
isSubmenuVisible
:
false
,
submenu
:
<
div
>
Submenu
content
<
/div>
,
});
assert
.
equal
(
wrapper
.
find
(
'Slider'
).
prop
(
'
visible'
),
false
);
assert
.
equal
(
wrapper
.
find
(
'Slider'
).
prop
(
'
direction'
),
'out'
);
assert
.
equal
(
wrapper
.
find
(
'MenuKeyboardNavigation'
).
prop
(
'visible'
),
false
...
...
src/sidebar/components/test/SidebarPanel-test.js
View file @
f9fda4bc
...
...
@@ -53,7 +53,7 @@ describe('SidebarPanel', () => {
it
(
'shows content if active'
,
()
=>
{
fakeStore
.
isSidebarPanelOpen
.
returns
(
true
);
const
wrapper
=
createSidebarPanel
();
assert
.
isTrue
(
wrapper
.
find
(
'Slider'
).
prop
(
'visible'
)
);
assert
.
equal
(
wrapper
.
find
(
'Slider'
).
prop
(
'direction'
),
'in'
);
});
it
(
'hides content if not active'
,
()
=>
{
...
...
src/sidebar/components/test/slider-test.js
deleted
100644 → 0
View file @
89c46e70
import
{
mount
}
from
'enzyme'
;
import
{
checkAccessibility
}
from
'../../../test-util/accessibility'
;
import
Slider
from
'../Slider'
;
describe
(
'Slider'
,
()
=>
{
let
container
;
const
createSlider
=
(
props
=
{})
=>
{
return
mount
(
<
Slider
visible
=
{
false
}
{...
props
}
>
<
div
style
=
{{
width
:
100
,
height
:
200
}}
>
Test
content
<
/div
>
<
/Slider>
,
{
attachTo
:
container
}
);
};
beforeEach
(()
=>
{
container
=
document
.
createElement
(
'div'
);
document
.
body
.
appendChild
(
container
);
});
afterEach
(()
=>
{
container
.
remove
();
});
it
(
'should render collapsed if `visible` is false on mount'
,
()
=>
{
const
wrapper
=
createSlider
({
visible
:
false
});
const
{
height
}
=
wrapper
.
getDOMNode
().
getBoundingClientRect
();
assert
.
equal
(
height
,
0
);
// The content shouldn't be rendered, so it doesn't appear in the keyboard
// navigation order.
assert
.
equal
(
wrapper
.
getDOMNode
().
style
.
display
,
'none'
);
});
it
(
'should render expanded if `visible` is true on mount'
,
()
=>
{
const
wrapper
=
createSlider
({
visible
:
true
});
const
{
height
}
=
wrapper
.
getDOMNode
().
getBoundingClientRect
();
assert
.
equal
(
height
,
200
);
});
it
(
'should transition to expanded if `visible` changes to `true`'
,
()
=>
{
const
wrapper
=
createSlider
({
visible
:
false
});
wrapper
.
setProps
({
visible
:
true
});
const
containerStyle
=
wrapper
.
getDOMNode
().
style
;
assert
.
equal
(
containerStyle
.
height
,
'200px'
);
});
it
(
'should transition to collapsed if `visible` changes to `false`'
,
done
=>
{
const
wrapper
=
createSlider
({
visible
:
true
});
wrapper
.
setProps
({
visible
:
false
});
setTimeout
(()
=>
{
const
containerStyle
=
wrapper
.
getDOMNode
().
style
;
assert
.
equal
(
containerStyle
.
height
,
'0px'
);
done
();
},
1
);
});
it
(
'should set the container height to "auto" when an expand transition finishes'
,
()
=>
{
const
wrapper
=
createSlider
({
visible
:
false
});
wrapper
.
setProps
({
visible
:
true
});
let
containerStyle
=
wrapper
.
getDOMNode
().
style
;
assert
.
equal
(
containerStyle
.
height
,
'200px'
);
wrapper
.
find
(
'div'
).
first
().
simulate
(
'transitionend'
);
containerStyle
=
wrapper
.
getDOMNode
().
style
;
assert
.
equal
(
containerStyle
.
height
,
'auto'
);
});
it
(
'should hide overflowing content when not fully visible'
,
()
=>
{
// When fully collapsed, overflow should be hidden.
const
wrapper
=
createSlider
({
visible
:
false
});
let
containerStyle
=
wrapper
.
getDOMNode
().
style
;
assert
.
equal
(
containerStyle
.
overflow
,
'hidden'
);
// When starting to expand, or when collapsing, overflow should also be hidden.
wrapper
.
setProps
({
visible
:
true
});
assert
.
equal
(
containerStyle
.
overflow
,
'hidden'
);
// When fully visible, we make overflow visible to make focus rings or
// other content which extends beyond the bounds of the Slider visible.
wrapper
.
find
(
'div'
).
first
().
simulate
(
'transitionend'
);
containerStyle
=
wrapper
.
getDOMNode
().
style
;
assert
.
equal
(
containerStyle
.
overflow
,
'visible'
);
});
it
(
'should stop rendering content when a collapse transition finishes'
,
()
=>
{
const
wrapper
=
createSlider
({
visible
:
true
});
wrapper
.
setProps
({
visible
:
false
});
wrapper
.
find
(
'div'
).
first
().
simulate
(
'transitionend'
);
const
containerStyle
=
wrapper
.
getDOMNode
().
style
;
assert
.
equal
(
containerStyle
.
display
,
'none'
);
});
[
true
,
false
].
forEach
(
visible
=>
{
it
(
'should handle unmounting while expanding or collapsing'
,
()
=>
{
const
wrapper
=
createSlider
({
visible
});
wrapper
.
setProps
({
visible
:
!
visible
});
wrapper
.
unmount
();
});
});
it
(
'should pass a11y checks'
,
checkAccessibility
([
{
name
:
'visible'
,
content
:
()
=>
createSlider
({
visible
:
true
}),
},
{
name
:
'hidden'
,
content
:
()
=>
createSlider
({
visible
:
false
}),
},
])
);
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment