Stencil version: #stencil/core#1.3.0
I want to use Font Awesome inside my Stencil component.
I followed these steps from https://fontawesome.com/how-to-use/on-the-web/setup/using-package-managers
Create a "Stencil component starter" project
Install Font Awesome: npm install --save-dev #fortawesome/fontawesome-free
Reference Font Awesome inside src/index.html:
<script src="../node_modules/#fortawesome/fontawesome-free/css/all.css"></script>
<script src="../node_modules/#fortawesome/fontawesome-free/js/all.js"></script>
Add the icon inside my component:
render() {
return (
<button>
<i class="fas fa-camera"></i>
</button>
);
}
I'm not able to include font awesome inside my stencil component. I'm stuck here: <i class="fas fa-camera"></i>
Basically this problem is not only related to font-awesome and stenciljs its a general "custom-font" with "web-components" problem.
Here is a link to the thread with working solution. I Tried it out by myself works perfectly.
https://stackoverflow.com/a/57623658/8196542
I made a demo repo for using icons in stenciljs here:
https://github.com/drygnet/stenciljs-icons-example
Example components with different approaches for:
FontAwesome, Office UI Fabric and Material Icons
I found an elegant way to integrate font awesome with stencilJS.
Install the FontAwesome npm
npm install --save-dev #fortawesome/fontawesome-free;
Then inside your component in your component css file add the #import statement
#import "~#fortawesome/fontawesome-free/css/all.css";
Documentation:
CSS #import
Sample code:
import { Component, Prop, h } from '#stencil/core';
#Component({
tag: 'my-tooltip',
styleUrl: 'my-tooltip.css', // add the #import statement inside the CSS file
shadow: true,
})
export class MyTooltip {
#Prop() text: string;
render() {
return (<div>
<slot />
--
<i class="fa-solid fa-circle-question"></i>
--
</div>);
}
}
------ [my-tooltip.css file] -----
#import "~#fortawesome/fontawesome-free/css/all.css";
Related
How to create a settings option for a website that allows users to change the background color, language, dark mode and light mode?
I want Settings Option Which is similar to Qwant Homepage settings
You must provide a code, remember that this forum seeks to solve problems.
I've made a quick example of how you can make a theme system.
You can use two buttons and useState to toggle this. Also, you can use cookies to storage the actual theme of the user.
This is an example component:
First, install
npm install js-cookie
Then, create a component file:
import React, { useState } from 'react';
const Toggler = () => {
const toggleTheme = (themeType) => {
Cookies.set('theme', themeType);
};
return (
<div>
<button onClick={() => toggleTheme('light')}>Light Theme</button>
<button onClick={() => toggleTheme('dark')}>Dark Theme</button>
<p>Current theme is {theme}</p>
</div>
);
}
export default Toggler;
Then you can call Toggler from other components. Also you can get the mode with Cookies.get('theme')
import Cookies from 'js-cookie';
const [theme, setTheme] = useState(Cookies.get('theme') || 'light');
Once you have the theme, you can use this as conditional for your styles or html code.
So I am using storybook for my svelte + tailwind app, and I am now trying to make sure that I can toggle darkmode.
So for my tailwind.config.js I added this
module.exports = {
darkMode: "class",
and I installed this addon to storybook
https://github.com/hipstersmoothie/storybook-dark-mode
with this config .storybook/preview.js
export const parameters = {
darkMode: {
darkClass: "dark",
stylePreview: false,
},
And by looking in the DOM of the storybook iframe I can see that "dark" is applied to the body.
But when I create a component with this HTML
<div class="inline">
<div class="w-8 h-8 bg-blue-500 dark:bg-green-500" />
</div>
the box is always blue.
So I thought maybe purgecss was removing it, and so I added safelist: ["dark"] to it's options but without any luck.
So to make things more complicated I tested this component
<div class="inline">
<div class="w-8 h-8 bg-blue-500 dark:bg-green-500" />
</div>
<div class="inline dark">
<div class="w-8 h-8 bg-blue-500 dark:bg-green-500" />
</div>
and to my surprise, one of the boxes turned green.
Honestly, I am not entirely sure if this is because of svelte, storybook, tailwind, or the darkmode storybook plugin.
But I would really appreciate help if anyone has seen something similar
You could try ignoring purgecss when watching for storybook.
I am not sure about your exact setup but in my case I added a conditional in postcss.config.js for storybook to work correctly:
const isProduction =
!process.env.ROLLUP_WATCH &&
!process.env.LIVERELOAD &&
process.env.NODE_ENV !== 'development'
module.exports = {
plugins: [
require('tailwindcss'),
...(isProduction ? [purgecss] : [])
]
};
My .storybook/preview.js contains the following:
export const parameters = {
darkMode: {
stylePreview: true,
darkClass: 'dark',
lightClass: 'light',
}
}
The only thing which still doesn't work after this is the white text in dark mode, so I had to add .dark { color: white; } to my css.
I had this issue as well but it was because I defined a prefix of vc- in my tailwind.config.js file.
When I configured the addon https://github.com/hipstersmoothie/storybook-dark-mode, I used the class dark not vc-dark in .storybook/preview.js:
export const parameters = {
darkMode: {
dark: { ...themes.dark },
light: { ...themes.light },
darkClass: 'dark',
stylePreview: true
}
}
should be
export const parameters = {
darkMode: {
dark: { ...themes.dark },
light: { ...themes.light },
darkClass: 'vc-dark',
stylePreview: true
}
}
Not sure if you, (OP), have a prefix defined in your tailwind.config.js file but it's something to watch out for, if others are having the same issue.
Even with the prefix, you can still use the dark variant normally, just don't forget to use the prefix when referencing class names after the variant:
<div class="vc-bg-blue-500 dark:vc-bg-green-500" />
This happens because components are rendered inside of an iframe and storybook-dark-mode (SDM) only sets the class to "dark" on the body of the main document.
I verified this by inspecting and adding it manually. Assuming that you have darkMode: 'class' set in your tailwind config, you should see it work as soon as you set <body class="dark"> inside that iframe. This is why when OP wrapped it in a parent with "dark", it worked for that instance only.
First attempt
The question to me is how to get that class applied to the body of the iframe as well? Reading SDM docs, it implies that it would apply it to the app as well as the preview window, but that doesn't seem to happen for me.
Interestingly, there is an add-on called storybook-tailwind-dark-mode (STDM) which adds "dark" to the <html> of the iframed document, so that's good; but it's a separate button. You can have your components render in dark or light mode independent of dark mode on the app itself.
This is currently the only way it's working for me and I'd like to see/make a fork off one of these where it does both at once.
FWIW, without Tailwind, we were using a ThemeProvider from StyledComponents that leveraged useDarkMode() from SDM to then pass that down to all the StyledComponents (which we're migrating away from in favor of Tailwind). It would be nice to leverage that somehow.
Final answer
That previous paragraph gave me some inspiration. Storybook has decorators, which are basically functions that return components. We can wrap our stories with some HTML and give it a class based on useDarkMode().
Below is more or less what I ended up using and it's working great. One button to control dark mode, no need for an additional tailwind-specific dependency, and I'm still able to use my StyledComponent theming for the components that haven't been migrated yet.
.storybook/theme.js
import React from 'react'
import { ThemeProvider } from 'styled-components'
import { themeV2, GlobalStylesV2 } from 'propritary-design-library'
import { useDarkMode } from 'storybook-dark-mode'
import '../src/index.css'
const ThemeDecorator = storyFn => {
const mode = useDarkMode() ? 'dark' : 'light'
return (
<ThemeProvider theme={themeV2(mode)}>
<section className={mode}>
<GlobalStylesV2 />
{storyFn()}
</section>
</ThemeProvider>
)
}
export default ThemeDecorator
.storybook/preview.js
import { addDecorator } from '#storybook/react'
import ThemeDecorator from './theme'
addDecorator(ThemeDecorator)
export const parameters = {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
}
I am trying to use the Font-Awesome SVG icons with Vuetify. But I don't manage to display icons.
I installed the necessary packages with:
npm install #fortawesome/fontawesome-svg-core #fortawesome/vue-fontawesome #fortawesome/free-solid-svg-icons -D
And the Vuetify plugin file looks like this:
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
import colors from 'vuetify/es5/util/colors'
import { library } from '#fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '#fortawesome/vue-fontawesome'
import { fas } from '#fortawesome/free-solid-svg-icons'
Vue.component('font-awesome-icon', FontAwesomeIcon)
library.add(fas)
Vue.use(Vuetify, {
iconfont: 'faSvg',
theme: {
primary: colors.blue.darken2,
accent: colors.grey.darken3,
secondary: colors.amber.darken3,
info: colors.teal.lighten1,
warning: colors.amber.base,
error: colors.deepOrange.accent4,
success: colors.green.accent3
}
})
Trying to show a icon:
<v-icon color="white" round>fa-times</v-icon>
It's really simple. Nuxt js + Vuetify 2:
npm i -D #fortawesome/fontawesome-free
U can check your package.json file:
"devDependencies": {
"#fortawesome/fontawesome-free": "^5.11.2"
}
In nuxt.config.js file:
vuetify: {
defaultAssets: {icons: 'fa'}
}
That's all! U can use:
<v-icon>fa-times</v-icon>
You should use the icons: { iconfont: 'faSvg' } syntax.
If anyone is using the #nuxtjs/vuetify module, you can configure the iconset in vuetify to use faSvg and then use the fontawesome-module for SVG icons. At this time of writing, vuetify is using the free solid icons in most of its components, so including all solid icons should be enough. You can configure this in the fontawesome-module so:
...otherNuxtConfigStuff,
buildModules: [
...otherBuildModules,
// https://github.com/nuxt-community/fontawesome-module
['#nuxtjs/fontawesome', {
icons: {
solid: true,
// here you can include other icons you need
brands: [
'faYoutube',
'faVimeo',
'faVimeoV'
]
}
}],
// https://github.com/nuxt-community/vuetify-module
['#nuxtjs/vuetify', {
...otherVuetifyConfigStuff,
icons: {
iconfont: 'faSvg'
}
}]
]
}
Make sure you don't change the component option in the fontawesome configuration because vuetify uses the default component name font-awesome-icon.
I want to build a web application with React with multiple HTML pages.
For example login.html and index.html. I've created these HTML pages and mapped them to URIs with my backend. So I have localhost:8080/login and localhost:8080/index. Unfortunately, React only uses the index.html file to render content!
So index.html works and the React content is shown: localhost:3000/index.html
<!-- index.html -->
...
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="wizard"></div>
</body>
...
<!-- index.tsx -->
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import FetchData from "./FetchData";
import 'bootstrap/dist/css/bootstrap.min.css';
import './index.css';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(
<div className="d-flex flex-column">
<div className="bg-dark text-light AppHeading">Self-Service-Webwizard</div>
<div className="bg-white"><FetchData /></div>
</div>,
document.getElementById('wizard') as HTMLElement
);
registerServiceWorker();
But wizardLogin.html doesn't show the React content: localhost:3000/wizardLogin.html
<!-- wizardLogin.html -->
...
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div>Wizard login</div>
<div id="wizardLogin"></div>
</body>
...
<!-- LoginPage.tsx -->
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import './index.css';
import registerServiceWorker from './registerServiceWorker';
import LoginForm from "./LoginForm";
ReactDOM.render(
<div>
<div><h1>Wizard Login.tsx</h1></div>
<div><LoginForm/></div>
</div>,
document.getElementById('wizardLogin') as HTMLElement
)
;
registerServiceWorker();
Am I doing something wrong or is it not possible to serve multiple HTML files with React?
Github: https://github.com/The-Taskmanager/SelfServiceWebwizard
if you are use create react app you must eject your project first
because you must change your entry point in Webpack configuration
first eject ( if you do not have webpack config file )
npm run eject
and after that go to config file
in webpack.config.js
entry: {
index: [
require.resolve('react-dev-utils/webpackHotDevClient'),
require.resolve('./polyfills'),
require.resolve('react-error-overlay'),
paths.appIndexJs,
],
admin:[
require.resolve('react-dev-utils/webpackHotDevClient'),
require.resolve('./polyfills'),
require.resolve('react-error-overlay'),
paths.appSrc + "/admin.js",
]
},
output: {
path: paths.appBuild,
pathinfo: true,
filename: 'static/js/[name].bundle.js',
chunkFilename: 'static/js/[name].chunk.js',
publicPath: publicPath,
devtoolModuleFilenameTemplate: info =>
path.resolve(info.absoluteResourcePath),
},
after that you should add Wepack plugin and added that to your project
new HtmlWebpackPlugin({
inject: true,
chunks: ["index"],
template: paths.appHtml,
}),
new HtmlWebpackPlugin({
inject: true,
chunks: ["admin"],
template: paths.appHtml,
filename: 'admin.html',
}),
also you should rewrite urls
historyApiFallback: {
disableDotRule: true,
// 指明哪些路径映射到哪个html
rewrites: [
{ from: /^\/admin.html/, to: '/build/admin.html' },
]
}
you can read this page for more informations
http://imshuai.com/create-react-app-multiple-entry-points/
Ejecting the app didn't seem like the right option. I found this answer which seems to work better.
Here is a quote from the answer.
How to model a react application as a multi page app. There are many
ways, however, one would be to structure your files like so:
./app --> main page for your app
./app/page1/ --> page 1 of your app
./app/page2/ --> page 2 of your app
...
In this way, each 'page' would contain a self contained react project.
Your main application page could contain hyperlinks that load these
pages, or you could load them asynchronously in your javascript code.
An alternative which I am using right now is to use a different toolchain. I am using Gatsby which has support for multiple pages. You could also use next.js, however it requires a nodejs express server as the backend.
I think you need a router. Here is great react router library which you can use
https://reacttraining.com/react-router/web/example/basic
So far I've learned that React native doesn't support multiple HTML pages because it's an single page application. I kept index.html as single HTML page and solved the issue with conditional rendering in react. When a condition is fullfilled then I'm rendering another React .tsx-file.
I am using Paper-Button but I am facing issue that the button text always gets capitalized instead or normal case.
I do not see any CSS or Javascript property being applied to make it upper case.
How should I resolve this problem?
I had the same issue and I solved the problem via adjusting the default theme. Add the following code to a file (name of your choice).js
import { createMuiTheme } from '#material-ui/core/styles';
const theme = createMuiTheme({
typography: {
button: {
textTransform: 'none'
}
}
});
export default theme;
You can then add the file to your app in index.js. I named it theme.js:
...
import theme from './theme';
...
const app = () => (
<ThemeProvider theme={theme}>
<CssBaseline />
<App />
</ThemeProvider>
);
ReactDOM.render(app, document.getElementById('root'));
As was mentioned in the comments above, the material design spec for buttons specifies that the text should be uppercase, but you can easily override its CSS property:
paper-button {
text-transform: none;
}
Inspired by the the CSS style above here is the inline styling for localized Button text transformation -
import {Button} from '#material-ui/core';
// Begin Component Logic
<Button style={{textTransform: 'none'}}>
Hello World
</Button>
// End Component Logic
If you use Mui 5 then you can use the sx syntax
<Button sx={{textTransform: "none"}}/>