React Native best practice for positioning, favor percentages and calculations over flex? - react-native

Coming from a web background it would be considered bad practice to (or not possible) to absolutely position elements and calculate their position in a layout based on the window dimensions. In react-native, we have access to the dimensions of the view port through the React.Dimensions.
For example: let {height, width} = Dimensions.get('window')
I can now use that to center a 100px element by setting it so:
left: (width/2) - 50
I much prefer this to using more traditional css techniques. Is there a reason why this shouldn't be done? In a browser the viewport could change if the user resizes the window, but on mobile the viewport size will be static.

In my opinion, favor the declarative and dynamic solution when possible (flex over number calculations). But it's a mix of both eventually for a lot of apps.
This blog post compares some layout methods in react native and could help you with better understanding when to use what.

Related

Since React Native uses pixels or percentages for units, how do we handle accessibility of larger text for input

Since React Native uses only pixels or percentages for units, how do we handle accessibility of larger text?
I know I can disable font scaling, but that is what I specifically do not want to do.
I am asking specifically for TextInput since there are other parts of the screen which won't change even if you scale up like the bottom nav bar. Because say we set a widget for time input on the browser we can say 5em to limit it to 5 character sizes regardless of the size of the text.
One way I can think of is to use * 16 in place of em but that does not work when you scale up the font since 16 is fixed.
Also I am looking for something that works in Expo. AccessibilityInfo does not appear to provide the size and I can't find any information on accessing the value of Dynamic Type
My crazy idea at the moment is to have a transparent Text that I has an onLayout and I obtain the size of the component and set it in a context that all my custom TextInput will use as a measurement that has a size based on number of characters.
react-native-elements is utilizing a helper function called normalize for font scaling which is implemented as follows.
import { moderateScale } from 'react-native-size-matters';
function normalize(number, factor = 0.25) {
return moderateScale(number, factor);
}
export default normalize
I'm currently using react-native-size-matters on developing UIs for multiple devices along with above font scaling by react-native-elements. Works fine in almost all the time.
Check out the react-native-size-matters repo is you have doubts on the implementation. Author has a good article written on explaining his approach as well.
PixelRatio.getFontScale() allows you to get the font scale that adjusts its number based on the user's choice of dynamic type.
The number you can use as a multiplier on the widths to increase or decrease depending on the font size if a dynamic font size is used.
One thing to note though, changing the size does not trigger a re-render unlike useColorScheme() since there's no context provided that has this information.

Dynamic/scrollable container size in Cytoscape (+ cy.fit() issues)

So I've been giving Cytoscape a try recently. My project's goal is basically a collaborative graph that people will be able to add/remove nodes to/from, making it grow in the process. The graph will include many compound nodes.
Most of the examples I've seen use container div that takes 100% of the screen space. This is fine for "controlled" graphs but won't work in my case because its size is intended to be dynamic.
Here's a JSFiddle using the circle layout within a fixed 3000px/3000px container:
https://jsfiddle.net/Jeto143/zj8ed82a/5/
Is there any way to have the container size be dynamic as opposed to stating it explicitly? Or do I have to compute the new optimal container size each time somehow, and then call cy.resize()?
edit: actually, using 100%/100% into cy.fit() might just work no matter how large the network is gonna be, so please ignore this question is this is the case.
Is there a recommended layout for displaying large/unknown amounts of data in a non-hierarchical way that would "smartly" place nodes (including compound ones) in the most efficient way possible, all the while avoiding any overlap? (I guess that's a lot to ask...)
Why doesn't cy.fit() seem to be working in my example? I'm using it both at graph initialization and when CTRL+clicking nodes (to show closed neighborhood), but it doesn't seem to like the 3000x3000px container (seems better with 100%x100%).
edit: also ignore this question if you ignored 1., as again it seems fine with 100%/100%.
Any help/suggestions would be greatly appreciated.
Thank you very much in advance.
TLDR: It's (1).
Cytoscape has a pannable viewport, like a map. You can define the dimensions of the viewport (div) in CSS. What's displayed in the viewport is a function of the positions of the nodes, the zoom level, and the pan level -- just like what is visible in a map's viewport is a function of zoom, pan, and positions of points of interest.
So either you have to
(a) rethink your UI in terms of zoom and pan and use those in-built facilities in Cytoscape, or
(b) disable zoom and pan in Cytoscape (probably stay at (0, 0) at zoom 1) and let the user scroll the page as you add content to the graph and resize its container div to accommodate the new content.

How best to create a Windows 8 Metro Hub Page

I want to create a Windows 8 Metro application that has a fancy "hub" page similar to the following:
http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/3482.landing_2D00_branded_5F00_thumb_5F00_287109A4.jpg
The key elements are: Horizontal Panorama style scrolling page but with "sections" that are data bound. I've had a look around for implementations and have come up short.
Seems to me it would be possible to do with a ScrollViewer that contains a Horizontal Stackpanel that has the elements that make up each section. But seeing as this is such a common Metro design pattern, I figure there is probably an easier / recommended way of implementing.
Just wondering if someone can give me some tips. How would you do it?
When you start using VariableSizedWrapGrid all things get their own relative sizes. http://msdn.microsoft.com/en-us/library/windows/apps/br227651.aspx
Set the ColumnSpan and RowSpan properties to make things double size, tripple size etc...
For me I make the first item in the collection double width, double height by setting ColumnSpan and RowSpan to 2. All other items get this ColumnSpan and Rowspan to 1, and it's getting a nice effect.
In addition to what Hans mentioned, I would highly recommend going through the existing Metro Style App Samples. Learning from working examples works better than any documentation.

Javascript + CSS: Converting from absolute positioned elements to CSS Transforms (left, top, width, height to translateX, translateY, scale)

I'd like to convert a Javascript carousel to work smoothly on the iOS devices iPad and iPhone, and Android devices which use webkit that is able to take advantage of hardware acceleration of CSS transforms.
Is there already a library or some snippets of code that would allow position and size setting?
I found jquery.animate-enhanced which may be close but it requires animations, and also does feature detection - I want to do something simpler, it looks significantly more complex than that.
There are several complexities I suspect the solution needs to address:
-Simple reuse of code to use either top / left CSS attributes or CSS transforms with translation (and any recalculation needed to convert them)
-Using the scale transform instead of setting width and height
Setup steps like:
-Setting -webkit-transform-style to preserve-3d
-Setting -webkit-transform-origin if needed (and what to?)
I see Zepto in the tags, so it seems like you've considered it and it didn't work? Zepto does use CSS3 for its animations.
I would try something like this as a first guess. You'll need to do your feature detection outside of the 'animateLeft' method because the animation apis are different between jquery and zepto.
Maybe something like this (psuedocode):
isTouchy = Modernizr.touch
var slideRight = function() {
if (isTouchy) {
Zepto('#carosel').animate(...)
} else {
jQuery('#carosel').slideRight() //sorry, don't know the api
}
}
http://zeptojs.com/#animate
http://modernizr.com/

Create an omnidirectional scrollview

I want to create an omnidirectional scrollview that works pretty much like the one in the "Wall of Sound" app. As in, the user should be able to pull into any direction and never get to an end. I want to keep the move to be smooth (and not see the pages change as you would in a standard scrollview). Does anyone know how that can be done? Or would I need OpenGL for that?
Create a 3x3 grid of views, each the size of the viewport. As the scrollview moves into another section, rearrange the views to constantly put the viewport in the center. In most cases 3x3 is sufficient, but if redrawing the views is expensive, you may want to use a larger grid (5x5 for instance). This requires that you have some mechanism for splitting up your full view into tiles.
You can implement the same thing using CALayer if you like. If you go that way, you should consider instead using CATiledLayer. See Matt Long's quick introduction on CIMGF.