How to float text around image in react native - css

I am trying to achieve a very common effect in react native of having text wrap around an image. On the web you would assign a float property to the image and follow it with a p tag. .
Here is a RNPlay example I've been working on. I think the method I currently have is a bit hackish, and doesn't properly work since the text does not align with the top of the image and flow down. Is there a proper and clean way to accomplish this?

You can use a Text as container instead of the typical View.
<Text style={{flex: 1}}>
<Image source={Images.IconExplore} style={{ width: 16, height: 16 }} />
<Text> Your past has been in control for far too long. It's time to shift to a higher expression of what you are capable of so you can create the life you want to live.</Text>
</Text>

Unfortunately, there is still no easy way to do it, even after the introduction of nested Views inside Text. Surprisingly in the iOS community this seems to be non-trivial.
iphone - How to implement the effect of "float" for image, just like in CSS style
https://github.com/Cocoanetics/DTCoreText/issues/438
One idea that comes to mind that would be worth tinkering around with is measuring the text, dimensions and/or character count, and depending on the size of the image, divide the text into two Text components, one that goes to the right/left and the other that goes below the image.
There is this under-promoted React Native library that might help, which allows you to measure the width and height of a Text component based on its content:
https://github.com/alinz/react-native-swiss-knife/blob/master/lib/text/index.ios.js

Related

Calculate space among elements to put in the right position the element

This is the final result:
As you can see in the pic, each line in blue is separated by each element.
I want to try this, I have already designed the elements:
But I don't know how to put in the right place each line, here's a complete example:
https://codesandbox.io/s/stoic-pond-luh0l
The way I'm trying to solve this is with this line:
<FlowDivider style={{ left: 240 * index + 1 }} />
But I don't know what's the right operation for this problem... Thanks!
First of all, you should put styles in classess instead of style attribute.
Back to the question:
I have two ideas for that task.
Just separate icons from the descriptions. And it will be easy. Just use flex and combine icons and separators.
Set fixed width for the section with cards. Create section with separators outside of the static flow. Set the same width for separators section and use flex to set equal gaps. (assumption is that all cards has the same layout)
But i prefere to use first method. It's easier to resolve and manage.
P.S. If you ask just for math algorithm:
It's not that easy, because you have changeable card width. That's your constants which you need to include in your algorithm:
icon width: 50px, padding from both card sides: 30px. Variables which you need to include: gaps between cards(15-35px), cards width minus icon width(it's hard, because it's relative, and you don't have that information).
So to fulfill your idea you need to get card width, calculate distance between two icons, and than you will know how much space you need between separators. Soooo, i don't recommend that approach;)
I don't use grid lately, so i'm not able to give you easy answer with grid.

How do I use both contain and cover background image in react?

So I have something like this :
return (
//set mushroom forest background, make it fill screen
<div className="App" style={ {
backgroundImage: `url(${pools})`,
backgroundPosition: 'center',
backgroundSize: 'contain, cover',
backgroundRepeat: 'no-repeat'
}}>
I want to use both cover and contain for my background image, but it seems to choose 1 and render with it rather than applying both.
But when I render it with react, the image isn't stretched to the page. It only seems to pick up the first of either contain or cover, and use that for rendering the image. Anyone know how to make a background image do both contain and cover in react? The syntax I have there works just fine in its CSS equivalent.
I'm really trying to assign two values to a CSS style in react, using the syntax and have it work. Right now it either fills the whole page, but cuts off part of the image, or leaves white space on the sides but displays the whole image. I've found CSS tutorials using both cover and contain at the same time, is there some special syntax I need to use in react or JavaScript to make this work?
I've tried putting two styles into an array, using two strings such as ['contains', 'cover'] but that doesn't seem to work either.
Edit: Figured out a way around it, not sure if you can do this double value assignment thing is css at all, think I was mostly misreading a guide to doing something.

Do not make the width of the button proportionnel to the width of the popup window

I want to make a button in a popup window as Script Lab as follows. Note that, in Script Lab, the width of the button is enough to hold the sentence in one line, even though the popup window is not very wide:
I almost use the same code as ScriptLab:
import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';
... ...
return (
<div style={{ height: '100vh', display: 'flex', flexDirection: 'column'}}>
<PrimaryButton
style={{ margin: 'auto' }}
text="Open link in new window"
// tslint:disable-next-line: jsx-no-lambda
onClick={() => {
window.open(this.props.url);
}}
/>
</div>
);
Here is my result, where the width of the button is proportionnel to the width of the popup window. As a consequence, the sentence needs to be displayed in 2 rows, which is not what I want.
Does anyone know how to amend the code to get the effect like Script Lab?
Edit 1:
I have made a sandbox: https://codesandbox.io/s/relaxed-feather-i6jz6?file=/src/App.js
Now, the problem is, if we Open In New Window and open https://i6jz6.csb.app/ in a new browser tab several times, we may see a little adjustment of the font of the text in the button. Does anyone know how to avoid that?
On button width:
In order to not have the width of the button grow proportionately with the container you can enforce the width: auto on the button. This way it will only be as wide as it needs to be to contain the text. Value auto is also better than having a fixed width, because it can automatically wrap the text if the popup becomes too narrow to display the text in one line (with fixed width your button would overflow instead - which looks really bad).
On font adjustments
For the font adjustments you experience - this is a very common thing on web and it even has its own name - FOUT (Flash of Unstyled Text). It happens when you use custom fonts on the page, because these are files like any other and so they take some time to download. Browsers prefer displaying the content as early as possible (even without custom fonts loaded) to displaying the perfect content (by waiting on all resources) with some speed penalty.
The only way (at least that I know) to completely avoid FOUT is to use system fonts instead of custom fonts (github does that for example).
If that's not an option, you can minimize the FOUT by caching the fonts on client machines for long times. This way they will experience the flash briefly on the first visit, but not on subsequent ones.
You can also try to minimize the FOUT by telling the browser to try to preload the font files that will be needed for the page (part of the reason why FOUT happens is that browser discovers the fonts very late) https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content
Set a fixed width to the button.Setting a fixed width will make it unproportional to the width of the pop-up window.
width:280px;
Second Option: If you use min-width, the button width will decrease to a point.
Third Option: If you use max-width, the button width will increase upto a point.
Fourth Option: You can also use '#media' queries to customize the width according to size of the screen.
You don't want the button's text to wrap, so you'll need to change the font size, which you can do when you find that the button's height increases when the text wraps. I suggest that you create a invisible, but not 'display: none', possibly 'off-screen' version of the button so that the real button's font is changed after you know the right size is needed. Alternatively, what about an image or glyph instead of text, and a Title for the button text?

SVG styling of text with NVD3 library

I have created a very simple chart with NVD3.js as can be seen on this fiddle.
The problem lies with the title (text in the middle) which consists of a number and a symbol (%).
I need both those parts to be styled separate but this seems to be a real pain.
I have discovered I can only style an SVG through inline style tags so I already applied :
<div id="svgDiv"><svg id="test2" fill='#58B957' letter-spacing='-3px'></svg></div>
to get the color and spacing right. Now I still need the %-symbol to be a lot smaller than the number. Which I can't apply to the full svg, because this would make everything smaller.
I have tried all manners of adding classes, id's, wrapping them in tspan's etc; yet I can't figure it out.
Please tell me there's a straightforward solution for this?
I dont think there is a direct way in nvd3 but you can do this trick to empty the text and fill with tspan.
var text1 = d3.select(".nv-pie-title").text("");//get the title clear it
text1.append("tspan").attr("class", "number").text("85")//make first tspan
text1.append("tspan").attr("class", "percent").text("%")//make second tspan
working code here

SVG text disappears on larger label

I am using Morris.js for making charts. Morris.js uses SVG to draw the graphs. I have set up a JSbin here: JSbin example
Morris.js uses Raphael to draw the svg graphs. The issue is with the labels on the X-Axis. They disappear when the size of labels is too large. I tinkered around with the size of the div element holding the graph and font size of the labels but since the labels are dynamically generated for various users I cannot decide on a fixed value. An ideal solution would be to have the text wrapped up. What can be done to counter the situation?
Morris.js uses the following snippet to make the text svg element.
this.raphael.text(xPos, yPos, text).attr('font-size', '11').attr('font-family', 'calibri').attr('fill', this.options.gridTextColor);
It seems raphael supports multiline strings by putting "\n" in the text. This could be a cheap solution for you, systematically replacing " " by "\n" in your labels.
The other (more tricky) solution would be to replace the "text" element in the SVG generated by raphael by a foreign element that allows word wrapping:
<foreignObject x="20" y="10" width="150" height="200">
<p xmlns="http://www.w3.org/1999/xhtml">Wrapping text using some foreignObject in SVG!</p>
</foreignObject>
or if you need a fallback:
<switch>
<foreignObject x="160" y="10" width="150" height="200"><p xmlns="http://www.w3.org/1999/xhtml">Wrapping text using some foreignObject in SVG!</p></foreignObject>
<text x="20" y="20">Your SVG viewer cannot display html.</text>
</switch>
I don't know the best way to do this replacement of "text" by a foreign object: either after the Morris rendering or by hacking Morris/Raphael.
I think the problem definition need more clarification,
at my end the code you have sent works fine, also I have replicated the same in JSFIDDLE that is also working fine..
I think the label problem is done automatically as I have tested the default size you have kept was carrying width 385px when looking in to CSS and 518px when looking the same, in both case the rendered labels were different, in-fact the label exceeding certain width were not rendered. SO there is no meaning to set style and override.
I think the things are built in library. So its a long way to go, or change the library.
let me know which will be convenient way, I will help you accordingly :)
Edit:
However, you can change property of GridTextSize: that is 16 by default
Fiddle2 here I have updated
'gridTextSize:8' that displays all text in size 8.
Not perfect but will do :)
Download not minimized morris.js from there. In zip-archive you can find a file morris.js. Open it in edit mode and change value of default label angle parameter (line 133):
133 | xLabelAngle: 90,//original value 0
Now, if you really need it minimized, you can compress file by any online js compress tool.

Resources