I am using react-native-render-html to transfer a string into html elements while developing React Native Apps. I received the string by RESTful APIs from backend, and there has already had width and height set in <img> tag:
<img class="aligncenter" src="https://www.allfin.com/u/cms/www/201811/13142949sf02.jpg" width="600" height="408" />
But I want the image to be resized to the largest width of the window, so I use :
imagesMaxWidth={Dimensions.get('window').width}
The whole segment is below:
<ScrollView style={styles.content}>
<Text style={styles.title}>{this.props.title}</Text>
<Text>{this.props.date}</Text>
<HTML
html={this.props.content}
imagesMaxWidth={Dimensions.get('window').width - 40}
/>
</ScrollView>
But the image could not be resized to the max width of the window.
So how could I set this?
Thank you
Use ignoredStyles prop to ignore width and height of the original pictures. Use ignoredStyles={['height', 'width']} to fix the issue.
With the latest 5.0 pre-releases, there is a much cleaner solution. Use the brand new contentWidth prop with useWindowDimensions hook, and images will automatically scale to content width!
yarn add react-native-render-html#unstable
import * as React from 'react';
import {ScrollView, StyleSheet, useWindowDimensions} from 'react-native';
import HTML from 'react-native-render-html';
const html = `
<img class="aligncenter" src="https://www.allfin.com/u/cms/www/201811/13142949sf02.jpg" width="600" height="408" />
`;
export default function App() {
const {width} = useWindowDimensions();
return (
<ScrollView contentContainerStyle={styles.container}>
<HTML contentWidth={width} html={html} />
</ScrollView>
);
}
const styles = StyleSheet.create({
container: {
flexGrow: 1,
},
});
Result:
In addition, if you want this behavior and don't want images to be greater than, let's say, 300, you can use the new computeEmbeddedMaxWidth prop:
import * as React from 'react';
import {ScrollView, StyleSheet, useWindowDimensions} from 'react-native';
import HTML from 'react-native-render-html';
const html = `
<img class="aligncenter" src="https://www.allfin.com/u/cms/www/201811/13142949sf02.jpg" width="600" height="408" />
`;
function computeEmbeddedMaxWidth(contentWidth, tagName) {
if (tagName === 'img') {
return Math.min(contentWidth, 300);
}
return contentWidth;
}
export default function App() {
const {width} = useWindowDimensions();
return (
<ScrollView contentContainerStyle={styles.container}>
<HTML
contentWidth={width}
computeImagesMaxWidth={computeImagesMaxWidth}
html={html}
/>
</ScrollView>
);
}
const styles = StyleSheet.create({
container: {
flexGrow: 1,
},
});
Result:
Related
How can I write on the picture
I have a small card that contains a picture and I want to write on the picture, how can I do that
import React from "react";
import {
Box, Image, Badge, Text, Stack,
useColorMode, Button, Flex, Spacer
}
from "#chakra-ui/react";
const InterestCard = () => {
// Hook to toggle dark mode
const { colorMode, toggleColorMode } = useColorMode();
return (
<Box w="130.7px" rounded="20px"
h='125.04px'
overflow="hidden" mt={10}>
<Image src="https://media.geeksforgeeks.org/wp-content/uploads/20210727094649/img1.jpg"
alt="Card Image" boxSize="300px">
</Image>
</Box>
);
}
export default InterestCard;
My goal is to have my header and content to be 100% of the width of the page. I have no css files but instead am using mantine for styles.
I've tried editing widths to 100% on different components with no luck.
The end goal once I've got my page using 100% width is using display grid to organise my components in columns.
I would like my WeatherComponent to fill the full width so say gridColumnStart: 1 to 4
TodoList to start and end 1 to 2
and NewsComponent to start and end 2 to 4.
This is my dashboard where components are rendered:
import { Container } from '#mantine/core';
import { Group } from '#mantine/core';
import NewsComponent from '../components/NewsComponent';
import TodoList from '../components/TodoList';
import WeatherComponent from '../components/WeatherComponent';
const Dashboard = () => {
return (
<Container style={{ display: 'grid', gap: '20px' }}>
<Group style={{ gridColumn: '1 / span 3' }}>
<WeatherComponent />
</Group>
<Group style={{ gridColumnStart: 1, gridColumnEnd: 1.5 }}>
<TodoList />
</Group>
<Group style={{ gridColumnStart: 1.5, gridColumnEnd: 3 }}>
<NewsComponent />
</Group>
</Container>
);
};
export default Dashboard;
And this is my WeatherComponent which is basically serving as my Header:
import axios from 'axios';
import { Weather } from '../types';
import UserForm from './UserForm';
import { Title, Text, Container } from '#mantine/core';
import { useEffect, useState, createContext } from 'react';
export const WeatherContext = createContext<any>(null);
const WeatherComponent = () => {
const [weather, setWeather] = useState<Weather | null>();
const fetchWeatherData = async () => {
const response = await axios.get('http://mock-api-call/weather/get-weather');
setWeather(response.data.result.weather);
};
useEffect(() => {
fetchWeatherData();
}, []);
return (
<Container>
<WeatherContext.Provider value={weather?.forcast}>
<UserForm />
</WeatherContext.Provider>
<Title order={2}>Today's Weather</Title>
<Text size="lg">
{weather?.forcast} with a low of {weather?.min} and a high of {weather?.max}
</Text>
<Text size="md" data-testid="description">
{weather?.description}
</Text>
</Container>
);
};
export default WeatherComponent;
Ideally I'd like to use mantine stylings to reach 100% and not create a css file to style *.
To prevent mantine from enforcing max-width on the container element, use the fluid prop on the container.
return (
<Container fluid>
{content}
</Container
)
Solved!
I changed the width of the WeatherComponents Container to 100% and it fixed the issue.
in WeatherComponent
return (
<Container style={{ width: '100%' }}>
)
I'm creating a reusable component using Reactstrap. What I want to do is display an image in the input field as below
What happens is this
How to get the image to the front??
InputFieldWithImage.js
import {
Input,
InputGroup,
InputGroupAddon,
InputGroupText,
Button
} from 'reactstrap';
import { Form, FormGroup } from 'reactstrap';
import Amy from './../../assets/images/Amy.png';
import Image from 'react-bootstrap/Image';
function InputFieldWithImage(props) {
const [inputType] = useState(props.type);
const [inputValue, setInputValue] = useState('');
function handleChange(event) {
console.log('Input.js');
// console.log(inputValue);
setInputValue(event.target.value);
if (props.onChange) props.onChange(event);
}
return (
<>
<InputGroup>
<Input
type={inputType}
value={inputValue}
name="input-form"
onChange={handleChange}
class="inputclass"
/>
<InputGroupAddon addonType="append" >
<Image
style={{ width:50, height: 50, marginLeft: -70 }}
src={Amy}
roundedCircle
/>
</InputGroupAddon>
</InputGroup>
</>
);
}
export default InputFieldWithImage;
You could simply handle this issue using CSS by giving the picture "position: absolute"
and the Input container "position: "relative".
This seems like an easy question at first but it's actually tricky.
Better to go directly to the example. I've created a snack with the sample code here https://snack.expo.io/BkSNtNrWV
I want to have a list of items with given aspect ratio (say 3:2) and the items should take as much space as possible with a maximum limit on size. This sample code does it:
<View>
<FlatList style={{backgroundColor:'lightgray'}}
data={[{key: 'a'},{key: 'b'}]}
renderItem={({item}) =>
<View style ={styles.pink}></View>
}/>
</View>
const styles = StyleSheet.create({
pink: {
backgroundColor: "#A37E93",
maxHeight: 150,
aspectRatio: 3/2,
borderWidth: 1,
}});
And this is the result:
However, the problem is that I would like to have the items aligned to the center. I tried to wrap the list item in a flexbox with 'row' direction but that caused the item to have 0 height => not displayed. Justify content didn't help either (it's possible that I do it incorrectly).
Does anyone know how to solve this please?
Updated the code. Add flex to inner item and wrap the view inside another with screen width.
import * as React from 'react';
import { Text, View, StyleSheet,FlatList,Dimensions } from 'react-native';
import { Constants } from 'expo';
const{width} = Dimensions.get('window')
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default class App extends React.Component {
render() {
return (
<View>
<FlatList style={{backgroundColor:'lightgray'}}
data={[{key: 'a'},{key: 'b'}]}
renderItem={({item}) =>
<View style={styles.item}>
<View style ={styles.pink}></View>
</View>
}
/>
</View>
);
}
}
const styles = StyleSheet.create({
item:{
width:width,
height:150,
alignItems:'center'
},
pink: {
flex:1,
backgroundColor: "#A37E93",
maxHeight:150,
aspectRatio:3/2,
borderWidth:1,
}
});
In my react native App, i am just trying to add a shared component called RoundImageComponent and added a RoundImageComponent.style to add css styles. When use this Round image component, width of the image will be passed as props according to the requirement in the application. In some cases, width will be not added to the component tag as follow,
RoundImageComponent width={90} roundImage="https://media.wired.com/photos/593222b926780e6c04d2a195/master/w_2400,c_limit/Zuck-TA-AP_17145748750763.jpg" />
or
RoundImageComponent roundImage="https://media.wired.com/photos/593222b926780e6c04d2a195/master/w_2400,c_limit/Zuck-TA-AP_17145748750763.jpg" />
RoundImageComponent Code
import React from 'react';
import {
Text,
View,
} from 'react-native';
import Config from 'react-native-config';
import SplashScreen from 'react-native-splash-screen';
import RoundImageComponent from "./shared/avatar/RoundImageComponent";
import styles from './App.styles';
const resolveSession = async () => {
// const session = sessionActions.getSession();
SplashScreen.hide();
};
setTimeout(() => {
resolveSession();
}, 2000);
const App = () => (
<View style={styles.container}>
<RoundImageComponent width={90}roundImage="https://media.wired.com/photos/593222b926780e6c04d2a195/master/w_2400,c_limit/Zuck-TA-AP_17145748750763.jpg" />
</View>
);
export default App;
RoundImageComponent
import {
StyleSheet,
} from 'react-native';
import { container, primaryText } from '../../theme/base';
export const defaultImage = {
height: 100,
borderRadius: 50,
width: 100
}
const styles = StyleSheet.create({
container: {
...container,
},
userDefinedImage: {
...defaultImage,
width: 40
}
});
export default styles;
When user pass the width as prop, image width should override to the default width and otherwise image width should remain as default width.
Is it possible to do with on this way?
This is possible by passing props to styles. Suppose this as my CustomTextComponent:
export CustomTextComponent = (props)=>{
return (
<Text style={[{fontFamily:"Lato", color:"#000", ...props.style}]}>
{props.children}
</Text>
)
}
Now I want to set different color at different level lets say red and green then
for red
<CustomTextComponent style={{color:'red'}}>
red colored text
</CustomTextComponent>
for green
<CustomTextComponent style={{color:'green'}}>
red colored text
</CustomTextComponent>
Note: Your ...props.style is should be after your default styling. because your last mentioned will override previous one.
You can also make use of default props value in some cases.(lib PropsType)
Yes, it's possible.
You can override the current style prop by passing another one just after it. It would looks something like this:
const styles = StyleSheet.create({
default: {
backgroundColor: red,
color: blue,
},
});
<View>
<DefaultComponent style={styles.default} />
<CustomComponent style={[styles.default, { backgroundColor: none }]} />
</View>
Hope it helps