How to load image path correctly? - javascript

I have the folder structure like the following.
src/
components/
Icon/
Icon.js
Style.js
images/
apple.svg
google.svg
facebook.svg
index.js
I want to export the paths of images under images folder in 'images/index.js'.
I tried something like this below.
images/index.js
export const apple = './apple.svg';
export { google } from './google.svg';
export const facebook = './facebook.svg';
And I want to load the paths of those images in '/Components/Icon/Style.js' like the following.
Style.js
import styled from 'styled-components';
// I know this works fine
import apple from '../../images/apple.svg';
// This doesn't work although I want it to work.
import { google } from '../../images/index';
// This doesn't work as well although I want it to work.
import { facebook } from '../../images/index';
const Icon = styled.i`
background: blah blah blah
`;
export default Icon;
However, I couldn't load the paths of images.
What is the right way to do that?
Is it impossible?
export const apple = './apple.svg';
Is this the only way I can load the path of image?

images/index.js
import apple from './apple.svg';
import google from './google.svg';
import facebook from './facebook.svg';
export {
apple,
google,
facebook
}
Style.js
import styled from 'styled-components';
import { apple, google, facebook } from '../../images';
const Icon = styled.i`
background: blah blah blah
`;
export default Icon;
This should work, and also looks pretty clean code to my eyes!
A Recomendation
Requesting an image for every "icon" to your server feels really expensive.
Instead, since you have access to the resources I would go with this structure:
src/
components/
Icon/
Apple.js
Google.js
Facebook.js
Facebook.js
import React from 'react';
function Facebook({ width = '266', height = '266' } = {}) {
return (
<svg xmlns="http://www.w3.org/2000/svg" width={width} height={height} viewBox="0 0 266.893 266.895" enableBackground="new 0 0 266.893 266.895">
<path
fill="#3C5A99"
d="M248.082,262.307c7.854,0,14.223-6.369,14.223-14.225V18.812 c0-7.857-6.368-14.224-14.223-14.224H18.812c-7.857,0-14.224,6.367-14.224,14.224v229.27c0,7.855,6.366,14.225,14.224,14.225 H248.082z"
/>
<path
fill="#FFFFFF"
d="M182.409,262.307v-99.803h33.499l5.016-38.895h-38.515V98.777c0-11.261,3.127-18.935,19.275-18.935 l20.596-0.009V45.045c-3.562-0.474-15.788-1.533-30.012-1.533c-29.695,0-50.025,18.126-50.025,51.413v28.684h-33.585v38.895h33.585 v99.803H182.409z"
/>
</svg>
);
}
export default Facebook;
Advantages:
No network request
Reusable icon
Customizable with states (colors, shapes, etc)

Related

How can I apply drag and drop functionality (from local file browser to chonky file browser)? - Typescript, React, Chonky.io

can anyone show me how to properly apply drag and drop functionality (from local file browser to chonky file browser). I'm using React Typescript with Chonky.io library.
import React, { useMemo, useState } from 'react';
import {
FileBrowser,
FileContextMenu,
FileList,
FileNavbar,
FileToolbar,
} from 'chonky';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { DndProvider } from 'react-dnd';
const FileBrowser = ({
darkMode = false,
i18n = 'defaultLocale',
disableDragAndDrop = true,
}: IFileRepositoryProps) => {
return <DndProvider backend={HTML5Backend}>
<FileBrowser
files={files}
folderChain={folderChain}
darkMode={darkMode}
i18n={i18n}
disableDefaultFileActions={true} //to remove default file actions and replace with customized ones
fileActions={fileActions}
onFileAction={handleFileCallback}
iconComponent={customChonkyIcon}
disableDragAndDrop={disableDragAndDrop}
>
<ThemeProvider theme={overrideStyles}>
<FileNavbar />
<FileToolbar />
<FileList />
<FileContextMenu />
</ThemeProvider>
</FileBrowser>
</DndProvider>
}
This is the portion of code I've come up with but now the drag and drop within the chonky file browser is not working anymore. Would really appreciate your help with this. Thank you.

Tree shaking not working for node package

I have a node module that is generally shaped like this (simplifying for example's sake):
# color.js
export var red = '#f00';
export var yellow = '#ff0';
export var blue = '#00f';
# images.js
export var image1 = '<base64 string approximately ~ 500kb>';
export var image2 = '<base64 string approximately ~ 500kb>';
# index.js
// JavaScript tokens
import * as colorExport from './color';
import * as imagesExport from './images';
export var color = colorExport;
export var images = imagesExport;
And then in my Next.js app (also tested in Create React App) I import the value like this:
# Home
import { color } from 'my-module'
const Home = () => (
<h1 style={{ color: color.red }}>Hello!</h1>
)
export default Home
This works fine. However, in both Next.js and Create React App, when I go to build the production-ready site EVERYTHING from my-module (color and images) is included and the final bundle size is a little greater than 1MB.
Now, if I change the import statement in Home to this:
import * as color from 'my-module/color'
Then the final bundle only includes the color values as I would expect. But I would like to not have to import so specifically. Is there something obvious I'm doing wrong here?
Refactoring color and images to have a default export rather than named exports and then also rewriting the way index import and exports fixed the problem.
E.g.
# color.js
export default {
red: '#f00',
yellow: '#ff0',
blue: '#00f'
}
# index.js
export { default as color } from './color';
export { default as images } from './images';

Import SVG icons from another folder

I want to import svg icons from my icon folder, to change the color of the icons I have to give fill parameter to path inside SVG. So i need import and to show only SVG but not like <img src="icon.svg"/>.
I first put one SVG right inside the component and it shows no problem.
but I have a lot of icons I can’t put everything inside the component.
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
export const Gunicon = ({ name, height, width, color, bold }) => {
const classes = makeStyles(theme => {
/* i want to give style like this */
return {
gunicon: {
"& svg": {
height,
width,
"& path": {
fill: color,
stroke: color,
strokeWidth: bold
}
}
}
};
});
/* this is working. but i dont like this */
const ico = (
<svg height={height} width={width} viewBox="0 0 512 512">
<path d="test svg" fill={color} stroke={color} strokeWidth={bold} />
</svg>
);
return (
<div className={classes.gunicon}>
{/* dont working */}
{require(`./icons/${name}.svg`)}
{/* working */}
{ico}
</div>
);
};
when i am writing as {require("./icons/${name}.svg")}. this is showing me only path to SVG. But i want import every SVG by name and only SVG
Ok, my friend.
I guess you are using create-react-app and you don't need to configure your webpack (I hope nowadays no one knows what is webpack)
So, what did they in create-react-app is added loader for svg for you, and map source of the loaded asset to the field ReactComponent. What you need to do is:
const { ReactComponent: Icon } = require(`./icons/${name}.svg`);
return (
<Icon />
);

Using require for SVG files in React Native

Im using react-native-svg and I'm fully aware of their way to use local svg files as shown here.
What I would like to know is if there is a way to use require for svg file paths. e.g.
<Svg width={50} height={50} fill={"#CCC"} source={require("./path/to/file.svg")} />
That way I would be able to store the require in a variable and use it like:
const myImage = require("./path/to/file.svg")
<Svg width={50} height={50} fill={"#CCC"} source={myImage} />
Any ideias?
EDIT FOR MORE DETAIL
Im developing a white label app so I have a config.js file with some color values, API endpoints and source images. e.g.
//config.js
const coBrandConfig = {
firstapp: {
Target: {
BRAND_TARGET: "firstApp"
},
Login: {
LOGIN_BACKGROUND_IMAGE: require("./path/to/file.png"),
LOGIN_LOGO_IMAGE: require("./path/to/file.png"),
LOGIN_TITLE_TEXT: "FIRST APP",
LOGIN_STATUSBAR_CONTENT: "light-content",
LOGIN_BACKGROUND_COLOR: "#333" ,
LOGIN_SIMPLE_TEXT_COLOR: "#FFF",
LOGIN_TEXTINPUT_BACKGROUD_COLOR: "#FFF",
LOGIN_LOGIN_BUTTON_COLOR: "#009933",
},
},
}
module.exports = coBrandConfig["firstapp"]
Then I have a styles.js that gets and applies all of these values, which can change depending on the App variant. e.g.
import React from 'react'
import { StatusBar, Image } from "react-native"
import styled from 'styled-components/native'
import CoBrandConfig from "./config/config.js"
export function MainStyle () {
return(
<>
<StatusBar barStyle={`${CoBrandConfig.Login.LOGIN_STATUSBAR_CONTENT}`} backgroundColor={CoBrandConfig.Login.LOGIN_BACKGROUND_COLOR} />
<Image source={CoBrandConfig.Login.LOGIN_LOGO_IMAGE} />
<Svg width={50} height={50} fill={"#CCC"} source={CoBrandConfig.Login.MY_SVG} /> //HERES WHAT I WANT TO DO
<TitleText>{CoBrandConfig.Login.LOGIN_TITLE_TEXT}</TitleText>
</>
)
}
Thats why I would like to pass a require("./path/to/file.svg") to a variable.
I'm a bit late, but try adding .default.src after your require:
source={require("./path/to/file.svg").default.src}
I use this library, I hope it will be useful
npm install 'react-native-svg';
then
import { SvgUri } from 'react-native-svg';
<SvgUri
width="100%"
height="100%"
uri="url svg"
/>
Try this one
import SvgUri from 'react-native-svg-uri';
import svgExample from './file.svg';
return:
<SvgUri
width="250"
height="250"
svgXmlData={svgExample}
/>

Font Awesome 5 icons not working with React ("Could not find icon" error)

I'm trying to use Font Awesome 5 Pro (I have a license) in my React project, and I've followed the instructions in the API to the best of my ability, but I'm still having issues.
In my project, I used npm to install fontawesome, fontawesome-common-types, fontawesome-pro-light, fontawesome-pro-regular, fontawesome-pro-solid, and react-fontawesome. All those folders are in my node_modules/#fortawesome/ directory
In my App.js, I have these imports (this isn't the whole file, just the relevant snippets):
import fontawesome from '#fortawesome/fontawesome';
import FontAwesomeIcon from '#fortawesome/react-fontawesome';
import {faSpinnerThird, faCircle} from '#fortawesome/fontawesome-pro-regular/';
fontawesome.library.add(faSpinnerThird, faCircle);
Then I have another component, Spinner.js, with this code:
import React from 'react';
import FontAwesomeIcon from '#fortawesome/react-fontawesome';
const spinner = () => (
<div className="fa-layers fa-fw">
<FontAwesomeIcon icon="circle" color="#ddd" />
<FontAwesomeIcon icon="spinner-third" color="#aaa" spin />
</div>
);
export default spinner;
In another component, I'm importing the Spinner component and rendering it conditionally, but when it gets rendered, I get these errors in my browser console:
Could not find icon
Object { prefix: "fas", iconName: "circle" }
Could not find icon
Object { prefix: "fas", iconName: "spinner-third" }
I'm pretty new to React, but I think I've followed the instructions in FontAwesome's React API correctly. Any idea where I might be going wrong?
I think the problem is becuase by default the prefix is fas (Font Awesome Solid) so in the case of:
<FontAwesomeIcon icon="circle" color="#ddd" />
it is looking for the circle icon in the fas, however, you want to use the faCircle from fontawesome-pro-regular
import {faSpinnerThird, faCircle} from '#fortawesome/fontawesome-pro-regular/';
So I think you want to write something like
<FontAwesomeIcon icon={["far", "circle"]} color="#ddd" />
Also if you dont know what the prefix of is of the library you can do
fontawesome.icon(faPlus).abstract
which will give you an object like:
[{
"tag": "svg",
"attributes": {
"data-prefix": "fa",
"data-icon": "user",
"class": "svg-inline--fa fa-user fa-w-16",
"role": "img",
"xmlns": "http://www.w3.org/2000/svg",
"viewBox": "0 0 512 512"
},
"children": [
{
"tag": "path",
"attributes": {
"fill": "currentColor",
"d": "M96…112z"
}
}
]
}]
https://fontawesome.com/how-to-use/font-awesome-api
I figured it out!
By default the FontAwesomeIcon component uses the "fas" prefix (for Font Awesome Solid). You can see that in the error code I posted above. However, I was trying to load the Regular weight, from the /font-awesome-pro-regular/ directory.
I changed the FontAwesomeIcon components to use the correct prefix, like this:
<FontAwesomeIcon icon={["far", "circle"]} color="#ddd" />
And now it works as expected.
Change your App.js to include each icon individually, I believe you might be deconstructing the Icon object.
import fontawesome from '#fortawesome/fontawesome';
import FontAwesomeIcon from '#fortawesome/react-fontawesome';
import faSpinnerThird from '#fortawesome/fontawesome-pro-regular/faSpinnerThird';
import faCircle from '#fortawesome/fontawesome-pro-regular/faCircle';
fontawesome.library.add(faSpinnerThird, faCircle);
This is per the API suggestion here: https://www.npmjs.com/package/#fortawesome/react-fontawesome#build-a-library-to-reference-icons-throughout-your-app-more-conveniently

Categories