So I am using .svg as icons for my app, and they're hosted online. Some work and others are simply not visible. This is the code I am using.
import { SvgUri } from "react-native-svg";
import GlobalStyles from "../styles/GlobalStyles";
const DrawIcon = ({ set_code }) => {
const onError = (e) => console.log(e);
return (
<SvgUri
style={GlobalStyles.setIcon}
uri={set_code }
onError={onError}
/>
);
};
export default DrawIcon;
What I have noticed is that SVGs with viewBox="0 0 1024 1024" are the ones that aren't visible, while SVGs with viewBox="0 0 964 432" and lower are visible on the screen. The files are provided by a third party API, so I'm wondering how to make all files viewable.
Here is:
an example of a file that works
and
an example of a file that does not work
Thanks to Robert Longson for the solution. Yes, the files were indeed missing their fill data. Changing the code to:
<SvgUri
style={GlobalStyles.setIcon}
uri={set_code }
fill={'#000'}
onError={onError}
/>
fixed the problem.
Related
After a lot of error messages, especially the following one
If this is a custom font, be sure to load it with Font.loadAsync.
I managed to add Google font to a react native app with the following code:
import AppLoading from "expo-app-loading";
import {
useFonts,
Quicksand_300Light,
Quicksand_400Regular,
Quicksand_500Medium,
Quicksand_600SemiBold,
Quicksand_700Bold,
} from "#expo-google-fonts/quicksand";
const screen = () => {
let [fontLoaded] = useFonts({
Quicksand_300Light,
Quicksand_400Regular,
Quicksand_500Medium,
Quicksand_600SemiBold,
Quicksand_700Bold,
});
if (!fontLoaded) {
return <AppLoading />;
} else {
return (
I use react-navigation and at the moment, I need to add this code to every screen.
I tried to add it to app and receive again the same Font.loadAsync message.
a - How can I import the font once for the whole app?
b - How can I have all the Text in the app use that font without adding it to each Text style?
What is the simplest way to implement Multi-Platform Setup for a component in Expo. I have tried mamy diferent ways.. it was working on web but it is failing on Native and failing with Jest & #testing-library/react-native. Ideally I would like the least amount of custom config etc (do not want to eject). I expect the file structure to look like this:
Component
|- index.tsx
|- Component.native.tsx
|- Component.web.tsx
I am not sure how to do the index.tsx. I saw someone say something like this would work:
// index.tsx
// #ts-ignore
export { default } from "Component"
this didn't work so I did
// index.tsx
// #ts-ignore
export { default } from "./Component"
This worked for web, but the jest test said
Cannot find './Component'
However, Jest was able to find:
'./Component.mobile.tsx'
'./Component.web.tsx'
I tried:
// index.tsx
// #ts-ignore
import Component from "./Component";
export default Component
and the tests was the same
and the native emulator said:
Unable to resolve module ./Component
I tried using lazy loading but this does not work on web.
import { lazy, Suspense } from "react";
import { Platform } from "react-native";
import Loading from "../../components/Loading";
import { ComponentType } from "./types";
const Web = lazy(() => import("./Component.web"));
const Mobile = lazy(() => import("./Component.mobile"));
const Component: ComponentType = (props) => {
const isWeb = Platform.OS === "web";
return (
<Suspense fallback={<Loading message="Loading Component" />}>
{isWeb ? <Web {...props} /> : <Mobile {...props} />}
</Suspense>
);
};
export default Component
Questions
how to use diferent files for components depending on platform (exlude other files from build)
how to make it ok with ts in vscode
Using Expo 44. Thanks
I would use named exports. So begin by having the same component name in both files. Next I would have one file called Component.tsx and the other Component.native.tsx. That will be enough to allow the bundler to pull the native for native and the other for non-native (in other words web). That should be all you need.
I'm trying to always go on the top of the page when route changes with Nuxt.
So I've put this into my app/router.scrollBehavior.js file:
export default function (to, from, savedPosition) {
return { x: 0, y: 0 }
}
But it always returns to the last saved position (which is always null in my console by the way).
Any idea of what I could miss here?
For Nuxt v3.0.0-rc.3
Create file named route.global.ts on middleware/ folder
Then write this in file:
export default defineNuxtRouteMiddleware((to, from) => {
if (to.path !== from.path && process.client) {
window.scrollTo(0, 0)
}
})
I use Nuxt 3 (npm:nuxt3#3.0.0-rc.4-27588443.cf25525), none of the solutions work for me.
Finally this works:
/plugins/scrollToTop.js (any filename will work, just put it in the plugins folder)
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.$router.options.scrollBehavior = async (to, from, savedPosition) => {
if (to.path !== from.path && process.client) {
window.scrollTo(0, 0);
}
};
});
According to the documentation:
https://nuxtjs.org/docs/configuration-glossary/configuration-router#scrollbehavior
The router.scrollBehavior.js file must be in the app folder, which in turn is in the project's root.
the file should name router.scrollBehavior.js.
You can console.log something in this function and check if it works.
At the end, GSAP was conflicting with OP's scrolling behavior.
Removing it, solved all the issues related to Nuxt, nothing was actually wrong with the router.scrollBehavior.js file.
The top answer is not the correct way of doing it.
Create a file in app directory called router.options.js
// app/router.options.js
export default {
scrollBehavior() {
return { top: 0 }
}
}
With typescript (recommended)
// app/router.options.ts
import type { RouterOptions } from '#nuxt/schema'
export default <RouterOptions> {
scrollBehavior() {
return { top: 0 }
}
}
For Nuxt 3
My solution was to create a file in the middleware folder with the following stucture:
export default defineNuxtRouteMiddleware((to, from) => {
useNuxtApp().hook("page:finish", () => {
if (history.state.scroll) {
setTimeout(() => window.scrollTo(history.state.scroll), 0);
} else {
setTimeout(() => window.scrollTo(0, 0), 0);
}
});
})
and I named it fix-scroll-position.global.ts.
The setTimeout is used to avoid the weird jumping to the top, meaning that the user won't see the page scrolling to the top.
This snippet ensures that the page scrolls to the top when the routes change, and that the scroll position is kept when the back button is clicked. The last functionality is achieved using history.state.scroll, that checks if there is a scroll position saved from the previous route.
I don't have enough reputation for a comment, so therefore an answer. A simple note, but I think it may help some.
I struggled with this as well and nothing worked, but after a while I found out the culprit. My layout looked like this
<template>
<div id="page" class="flex flex-col h-screen overflow-scroll bg-white">
<Navbar />
<slot />
<Footer />
</div>
</template>
That div around the components has the height of the screen and the page content scrolls in that div, but therefore the window is always at the top and you won't see any scrolling when clicking on NuxtLink.
I use nuxt 3.0.0 and when I let the #page div grow with the content (ie. removing the h-screen and overflow-scroll tailwind classes), it has the scroll to top behavior even without the solutions from above.
So, if you have this problem with the stable nuxt 3 version, check your html.
I have created an react-native/typescript app with expo CLI, this generate some base code, inlcuding hooks/useCachedResources to load any resources or data that we need prior to rendering the app, in my case in this hook I load custom fonts(in particular Inter Display Font). I'm experimenting some problems because the app loads only two weights: regular and medium, If I try to use semi-bold or bold this doesnt work and use the san serif font that comes by default.
Additional data:
The fonts path its ok
Expo app doesn't show any error. I have seen in other questions errors such as fontFamily "MyFontFamily" is not a system font and has not been loaded through Font.loadAsync. This is not the case.
Font family name is in the correct format.
I'm using React Native UI Kitten and I load the fonts as they suggest in Advanced Configuration and change some especific styles.
According to some answers The out of the box support for custom fonts on Android is a little limited in React Native. It does not support font weights other than normal and bold. So I tried setting fontWeight: normal or any of the weights but nothing works.
useCachedResources hook
This come by default with expo init my-app.
import * as Font from 'expo-font';
import * as SplashScreen from 'expo-splash-screen';
import { useEffect, useState } from 'react';
// Error reporting service
import { logger } from '#utils';
export function useCachedResources(): boolean {
const [isLoadingComplete, setLoadingComplete] = useState(false);
// Load any resources or data that we need prior to rendering the app
useEffect(() => {
async function loadResourcesAndDataAsync() {
try {
await SplashScreen.preventAutoHideAsync();
// Load fonts
await Font.loadAsync({
'inter-display-regular': require('../assets/fonts/InterDisplay-Regular.ttf'),
'inter-display-medium': require('../assets/fonts/InterDisplay-Medium.ttf'),
'inter-display-semibold': require('../assets/fonts/InterDisplay-SemiBold.ttf'),
'inter-display-bold': require('../assets/fonts/InterDisplay-Bold.ttf'),
});
} catch (loadCachedResourcesError) {
logger.log(loadCachedResourcesError);
} finally {
setLoadingComplete(true);
await SplashScreen.hideAsync();
}
}
loadResourcesAndDataAsync();
}, []);
return isLoadingComplete;
}
Consuming the hook in App.tsx
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import useCachedResources from './hooks/useCachedResources';
import Navigation from './navigation';
// again this comes by defautl expo init command
export default function App(): React.ReactElement | null {
const isLoadingComplete = useCachedResources();
if (!isLoadingComplete) {
return null;
}
return (
<SafeAreaProvider>
<Navigation />
<StatusBar />
</SafeAreaProvider>
);
}
mapping.json: specific UI-Kitten configuration to change font style
I can think that the problem comes from here but the thing is, if there was a problem loading the fonts, either expo would have already thrown an error or the other fonts weights(regular/medium) would not load.
{
"strict": {
"text-font-family": "inter-display-regular",
"text-heading-1-font-size": 32,
"text-heading-1-font-weight": "normal",
"text-heading-1-font-family": "inter-display-medium",
"text-paragraph-1-font-size": 16,
"text-paragraph-1-font-weight": "normal",
"text-paragraph-1-font-family": "$text-font-family",
}
}
The problem
I have no idea if the problem comes from expo, ui kitten or if inter font can't be loaded by react native by some other reason.
In your useCachedResources try to remove 'await' keyword from SplashScreen method's:
SplashScreen.preventAutoHideAsync();
SplashScreen.hideAsync();
I'm using the react-native-mapbox-gl/maps library in my react-native app, and I'm trying to show a <MapboxGL.ShapeSource that loads a GeoJson source, like this.
I have this code that is working, however, as the GeoJson data takes a while to finish loading, I couldn't find a way to show to the user if the data is loading or it is ready, with a Spinner for instance.
My question is: is there a way to detect when the MapboxGL.ShapeSource finishes loading its data or when the MapboxGL.FillLayer is visible in the Map?
import React from 'react';
import MapboxGL from '#react-native-mapbox-gl/maps';
const DemographicsMapLayer = () => {
const dataSourceUri = 'https://gist.githubusercontent.com/victor0402/dc3b40195a55ed998a45189b7fb4939b/raw/d7021c29637621e07a82e771d89ea278de48fb99/demographics.json'
return (
<MapboxGL.ShapeSource id={'demographicSourceID'} url={dataSourceUri}>}
<MapboxGL.FillLayer
id={'Millenials'}
key={'Millenials'}
sourceID={'demographicSourceID'}
filter={['==', '$type', 'Polygon']}
style={{ fillOpacity: 0.4 }}
onLayout={e => console.log('[FillLayer] onLayout', e)}
/>
</MapboxGL.ShapeSource>
Version of the lib in my package.json file:
"#react-native-mapbox-gl/maps": "^8.1.0-rc.9",
I tried using the onLayout event in both FillLayer and ShapeSource, but couldn't get useful information, maybe I'm looking the wrong thing.