web-library
web-library copied to clipboard
Implement touch header navigation
To-do:
- [x] 1. Render titles, set title classes
- [ ] 2. Set current title offset
- [ ] 3. Truncate next title
@tnajdek I added the scaffold for the touch header implementation to library.jsx
.
It is based on the mobile nav POC you have already seen. But unlike the POC, it does not work with a combination of a global 'current' class with individual 'title' classes, but with 4 generic states: .forelast
, .previous
, .current
, and .next
. These classes have to be set dynamically and simultaneously on the respective titles.
It makes probably sense to dynamically add new .next
elements at the end of the list and take away old .forelast
elements, so the list would never have more than 4 list items (from the visual point of view, more elements would not matter, only the ones with the 4 classes get displayed).
If you think it would be too cumbersome this way, I can imagine to go back to the POC approach and we only set a class with the current state on the list, I could pregenerate all needed styles for .title-1
, .title-2
, .title-3
, etc. with loops in Sass too (with an arbitrary limit). In any case you will have to insert and take away the correct titles based on the user’s decisions.
Re 2.: At the moment titles are truncated with CSS when they are longer than a third of the viewport width. This should be optimized. We can remove the hard width limit and check the width (of the <span>
inside) of title pairs that show up at once. So if e.g. 'My Libray' and 'Collection 1' do fit on the screen but only if the current
title has a position slightly right to the 50% center, then we can calculate the overlap and target the transition to e.g. left: calc(50% + 17px)
.
Re 3.: Sometimes this won’t be enough, so we have to truncate a title. As far as I have seen, native apps usually only truncate titles that come next into the view but do not truncate the current
title while it moves to the previous
position on the left. In this case the apps either fade out the current title entirely or cross-fade it with a generic 'Back' text. The next
title can be full, truncated, and with offset then.
Didn't mean to close it with a commit just yet.
So far I've implemented current and previous, including the ability to return to the root of the collection tree. There is still some refactoring to be done.
@johanneskrtek what should go into .next? And into .forelast for that matter?
@tnajdek if we want the mobile header to behave like in the POC, then we cannot just change the texts in .current
and .previous
, but we have to switch classes and add elements at the end of the list and remove elements at the start of the list. we also have to update all four classes with each step. note that each switch of a class triggers a css transition.
E.g. /
is .current
. when you click, collection-1
is inserted in .next
and the .current
class has to switch to .previous
and the .next
class to .current
. a new .next
element has to be created at the end of the list.
Next click, collection-1-1
is inserted in .next
, the .previous
class has to switch to .forelast
, the .current
class has to switch to .previous
and the .next
class to .current
. the .forelast
element has to be removed and a new .next
element has to be created and so on.
Of course this has to work in both directions – if the classes are set correctly (and the elements are added/removed accordingly) it already should.
Maybe the easiest way to get the idea is by simply changing the .current
elements class to .previous
and the .previous
elements class to .forelast
in the dev tools. You will see the texts moving to the left – that’s what they should do.
Now that I am writing about it I guess forelast
should rather be called first
or before-previous
.
yepp, will do, thanks for clarifying
@johanneskrtek I believe I've got it to work nicely with animations with the above commit. Could you please have a look and confirm it works as expected?
If you're happy with it, I'm going to try address 2) on your list but again some clarification would be useful.
Finally I think we probably want a home icon (or similar) instead of /
to get back to the "root" folder.
@tnajdek looks good to me!
The logic works as expected now. Also the CSS transitions – but they are not as smooth as they could be (I think this has to do with the simultaneous transition of the left
and transform
properties. I would like to rework the structure and styles and use 3d transforms only. A quick test looked promising. So, I would suggest you wait until I commit this change until you proceed.
Re 2) In iOS it is a common pattern to optimize those headers in the following way: the titles are not truncated (unless it is inevitable) but the current
title just moves a bit to the right so both previous
and current
find enough space without overlap. The easist way I can imagine to achieve this (but if you find a better way, go for it) would be to calculate the overlap and move the current
title a little to the right. Calculating the overlap should not be too hard, as you can get the widths of the two spans in question and we also know the end position of both (left and center).
E.g. (let’s ignore paddings for now) the viewport has 320px width, previous
has 100px width and current
150px width. 100 + 150 / 2 - 320 / 2 = 15. In this case we could position current
15px to the right (with inline styles using transform: translate3d(calc(-50% + 15px), 0, 0);
Of course there will be some more details to take in account (paddings, chevron icon back, some spacing between the two titles, option icon on the right side), but you get the idea. In this step 2 we would remove the CSS truncation and tweak the header for longer titles that barely fit and in step 3 we would add a mechanism that deals with situations where step 2 is not enough anymore. If you have further questions on 2, please let me know.
We definitely shouldn’t use /
for the root, how about 'Library' (in the drafts I had 'My Library', but 'Library' makes more sense actually as it also includes the Group Libraries)?
@tnajdek I reimplemented the touch header with 3d transforms only (there has been some stuttering at the end of the transitions before). I also removed the CSS truncation for now. So we should be good for step 2.
One remark: When I click on .previous
the .current
title disappears immediately instead of getting .next
and translating out of the viewport. I don’t know what exactly is wrong there, but that’s how it looks like.
@tnajdek I realized that the touch header is missing the last step currently: so when I choose an item in the item-list, the touch header has to update a last time. In the example below collection-1-1
should have the .before-last
class (I renamed that one) and collection-1-1-1
should have .previous
@tnajdek in order to complete #84 we will need some enhancements in the touch header:
On touch devices we have an edit mode, which can be entered by clicking 'edit' in the touch header. While the user is in edit mode, the touch header should show 'cancel', 'save' and temporarily a spinner in the processing state.
Now, in Tropy we have a very similar situation in the editor toolbar: if you click on the 'link' icon, the toolbar temporarily shows different tools (in this case an input field and a button to enter the link target). We implemented this in Tropy with multiple, context-specific containers in the toolbar. Those 'context containers' can have 3 states: default, .active
and .has-active
. I chose that approach because it makes it easier to think about the tools currently being visible on the one hand, on the other hand this is a generic way to have an arbitrary amount of toolbars that can have sub-toolbars and the switch can be animated. If you click on the 'link' icon, all the currently visible tools slide out of sight upwards while simultaneously the 'sub-toolbar' slides in from the bottom edge of the toolbar. This is done by switching the .active
class of the main context toolbar to .has-active
(so it slides up) and setting the class .active
to the sub-toolbar (so it slides in).
I think this approach could work for the different states of our touch header too, which has to show different elements in different contexts. We do not necessarily have to use slide in/out, could also be a cross-fade but with those additional context containers we would be flexible to do what we want.
What do you think?
@flachware I believe touch headers are in quite decent state now, can this be closed?
Actually I believe #149 supersedes this, hence closing.
This issue is also about how to handle the space in the touch header in a better way, therefore I’m reopening it, but I made it a post 1.0 issue.