Shoutem change default fontFamily not work - javascript

im newbie in react native! I'm used shoutem/ui in my project.
I have problem when modify default fontFamily. here is my code, please check then help me some solution to handle this.
thanks so much guys.
const theme = _.merge(getTheme(), {
defaultFont: {
fontFamily: 'Rubik-Italic',
},
'shoutem.ui.NavigationBar': {
'.clear': {
container: {
backgroundColor: params.primaryColor,
borderBottomColor: 'transparent',
position: 'relative',
},
'shoutem.ui.Title': {
color: 'white',
fontSize: 16,
},
},
'.normal': {
container: {
position: 'relative'
},
'shoutem.ui.Button': {
'shoutem.ui.Icon': {
color: params.colorTextAlpha,
},
'shoutem.ui.Text': {
color: params.colorTextAlpha,
},
},
'shoutem.ui.Title': {
color: params.colorText,
},
}
},
'shoutem.ui.Row': {
'.fix': {
paddingHorizontal: 10,
paddingVertical: 10,
}
}
});

What you want to do is override the theme variables.
Import the default theme variables and the getTheme function:
import {
getTheme,
defaultThemeVariables,
} from '#shoutem/ui';
Then define your custom variables:
const myThemeVariables = {
...defaultThemeVariables,
title: { fontFamily: 'MyFont' },
};
And then define your custom theme that uses those variables:
const myTheme = getTheme(myThemeVariables);
There is no more defaultFont setting you can override, so you'll have to be specific unfortunately.
Furthermore, you have to import the StyleProvider:
import { StyleProvider } from '#shoutem/theme';
And use it to control the style of your components:
render() {
return (
<StyleProvider style={myTheme}>
// your components here
</StyleProvider>
);
}
}

Related

In React SharePoint WebPart what are the differences between using 'html-react-parser' & using 'dompurify eslint-plugin-risxss' to securely show HTML

I am trying to build a React.js SharePoint modern web part, which have the following capabilities:-
Inside the Web Part settings page >> there are 2 fields named as "Who We Are" & "Our Value" which allow the user to enter HTML.
The web part will render 2 buttons "Who We Are" & "Our Value" >> and when the user clicks on any button >> a Popup will be shown with the entered HTML code in step-1
Something as follow:-
But to be able to render HTML code as Rich-Text inside my Web Part, i have to use the dangerouslySetInnerHTML attribute inside the .tsx file. as follow:-
import * as React from 'react';
import { useId, useBoolean } from '#fluentui/react-hooks';
import {
getTheme,
mergeStyleSets,
FontWeights,
Modal,
IIconProps,
IStackProps,
} from '#fluentui/react';
import { IconButton, IButtonStyles } from '#fluentui/react/lib/Button';
export const MYModal2 = (myprops) => {
const [isModalOpen, { setTrue: showModal, setFalse: hideModal }] = useBoolean(false);
const [isPopup, setisPopup] = React.useState(true);
const titleId = useId('title');
React.useEffect(() => {
showModal();
}, [isPopup]);
function ExitHandler() {
hideModal();
setisPopup(current => !current)
myprops.handler();
}
return (
<div>
<Modal
titleAriaId={titleId}
isOpen={isModalOpen}
onDismiss={ExitHandler}
isBlocking={true}
containerClassName={contentStyles.container}
>
<div className={contentStyles.header}>
<span id={titleId}>Modal Popup</span>
<IconButton
styles={iconButtonStyles}
iconProps={cancelIcon}
ariaLabel="Close popup modal"
onClick={ExitHandler}
/>
</div>
<div className={contentStyles.body}>
<p dangerouslySetInnerHTML={{__html:myprops.OurValue}}>
</p>
</div>
</Modal>
</div>
);
};
const cancelIcon: IIconProps = { iconName: 'Cancel' };
const theme = getTheme();
const contentStyles = mergeStyleSets({
container: {
display: 'flex',
flexFlow: 'column nowrap',
alignItems: 'stretch',
},
header: [
// eslint-disable-next-line deprecation/deprecation
theme.fonts.xLarge,
{
flex: '1 1 auto',
borderTop: '4px solid ${theme.palette.themePrimary}',
color: theme.palette.neutralPrimary,
display: 'flex',
alignItems: 'center',
fontWeight: FontWeights.semibold,
padding: '12px 12px 14px 24px',
},
],
body: {
flex: '4 4 auto',
padding: '0 24px 24px 24px',
overflowY: 'hidden',
selectors: {
p: { margin: '14px 0' },
'p:first-child': { marginTop: 0 },
'p:last-child': { marginBottom: 0 },
},
},
});
const stackProps: Partial<IStackProps> = {
horizontal: true,
tokens: { childrenGap: 40 },
styles: { root: { marginBottom: 20 } },
};
const iconButtonStyles: Partial<IButtonStyles> = {
root: {
color: theme.palette.neutralPrimary,
marginLeft: 'auto',
marginTop: '4px',
marginRight: '2px',
},
rootHovered: {
color: theme.palette.neutralDark,
},
};
And to secure the dangerouslySetInnerHTML, i did the following steps:-
1- Inside my Node.Js CMD >> i run this command inside my project directory:-
npm install dompurify eslint-plugin-risxss
2- Then inside my above .tsx i made the following modifications:-
I added this import import { sanitize } from 'dompurify';
An I replaced this unsafe code <p dangerouslySetInnerHTML={{__html:myprops.OurValue}}></p> with this <div dangerouslySetInnerHTML={{ __html: sanitize(myprops.OurValue) }} />
So I have the following question:-
Now my approach (of using sanitize(myprops.OurValue) will/should securely render HTML as Rich-Text inside the popup since i am using the sanitize function which is part of the dompurify eslint-plugin-risxss. but i read another approach which mentioned that to securely render HTML as Rich-Text inside the popup, we can use the html-react-parser package as follow {parse(myprops.OurValue)}. So what are the differences between using 'html-react-parser' & using 'dompurify eslint-plugin-risxss' to securely render an HTML code as Rich-Text inside the React web part's popup?
Here is my Full web part code:-
inside the MyModalPopupWebPart.ts:-
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '#microsoft/sp-core-library';
import {
IPropertyPaneConfiguration,
PropertyPaneTextField
} from '#microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '#microsoft/sp-webpart-base';
import * as strings from 'MyModalPopupWebPartStrings';
import MyModalPopup from './components/MyModalPopup';
import { IMyModalPopupProps } from './components/IMyModalPopupProps';
export interface IMyModalPopupWebPartProps {
description: string;
WhoWeAre: string;
OurValue:string;
}
export default class MyModalPopupWebPart extends BaseClientSideWebPart<IMyModalPopupWebPartProps> {
public render(): void {
const element: React.ReactElement<IMyModalPopupProps> = React.createElement(
MyModalPopup,
{
description: this.properties.description,
WhoWeAre: this.properties.WhoWeAre,
OurValue: this.properties.OurValue
}
);
ReactDom.render(element, this.domElement);
}
protected onDispose(): void {
ReactDom.unmountComponentAtNode(this.domElement);
}
protected get dataVersion(): Version {
return Version.parse('1.0');
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription
},
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneTextField('WhoWeAre', {
label: "who We Are",
multiline: true
}),
PropertyPaneTextField('OurValue', {
label: "Our value"
}), PropertyPaneTextField('description', {
label: "Description",
multiline: true
}),
]
}
]
}
]
};
}
}
inside the MyModalPopup.tsx:-
import * as React from 'react';
import { IMyModalPopupProps } from './IMyModalPopupProps';
import { DefaultButton } from '#fluentui/react/lib/Button';
import { MYModal } from './MYModal';
import { MYModal2 } from './MYModal2';
interface IPopupState {
showModal: string;
}
export default class MyModalPopup extends React.Component<IMyModalPopupProps, IPopupState> {
constructor(props: IMyModalPopupProps, state: IPopupState) {
super(props);
this.state = {
showModal: ''
};
this.handler = this.handler.bind(this);
this.Buttonclick = this.Buttonclick.bind(this);
}
handler() {
this.setState({
showModal: ''
})
}
private Buttonclick(e, whichModal) {
e.preventDefault();
this.setState({ showModal: whichModal });
}
public render(): React.ReactElement<IMyModalPopupProps> {
const { showModal } = this.state;
return (
<div>
<DefaultButton onClick={(e) => this.Buttonclick(e, 'our-value')} text="Our Value" />
{ showModal === 'our-value' && <MYModal2 OurValue={this.props.OurValue} myprops={this.state} handler={this.handler} />}
<DefaultButton onClick={(e) => this.Buttonclick(e, 'who-we-are')} text="Who We Are" />
{ showModal === 'who-we-are' && <MYModal WhoWeAre={this.props.WhoWeAre} myprops={this.state} handler={this.handler} />}
</div>
);
}
}
Actually, html-react-parser returns ReactJs object, and its return type is like React.createElement or like type of called JSX.
Using DOMPurify.sanitize will return safe pure HTML elements which those are different to the object that html-react-parser returns. the risxss ESLint plugin will force you to use sanitizing with any kind of sanitize function or library, that I left an answer to your other question to how to Sanitize your string HTML.
Eventually, using sanitizing is better because is the html-react-parser will convert your string HTML to ReactJs object with some tiny changes that would be dangerous because it is possible to have some script of string HTML in the project and it maybe will be harmful it just remove the onclick or onload, etc, from HTML tags but sanitizing will remove all possible harmful tags. also sanitizing will receive configuration, which means you can have your own options for sanitizing.

React How to use different states with click event

In short:
I'm implementing Simon-Says game app in React Native. (user sees a sequence of flashing buttons, needs to press the buttons in the correct order).
I want to know how to use 2 different states in TouchableOpacity, one of them as a condition to press the button, one for changing the style of the button, and also being notified for this specific press.
So,
I'm having a problem to implement the playerTurn(),
because I'm not sure how to pass the canPress state to the TouchableOpacity button,
considering I'm passing style state that changes in compTurn()
(function that shows a sequence of flashing buttons - then computer turn's over)
In the player turn, things I need to consider:
after the state canPress changes, the user will be allowed to press on the buttons
user presses one of the 4 buttons
the method playerTurn() will be notified which button did the player pressed. (I'm asking how can I get that notification from the button to the method?)
after that, I can push it's choice to the playerSeq array (if pressed green - pushes 1, etc) and call function that changes the style state (greenFlash for example)
code in short :
export default class App extends Component{
constructor (props){
super(props);
this.seq=[1,2,3,1,4] //will be random, this is just for testing
this.playerSeq=[]
...
this.state = {
canPress: false,
greenB: {
backgroundColor: 'darkgreen'
}, ...
playerTurn(){
this.setState({canPress: true})
// if the user pressed on the green button, then I push 1 to the playerSequence
// More functionality will be here
}
render(){
return (..
<TouchableOpacity style={[styles.greenB, this.state.greenB]}></TouchableOpacity>
//I ALSO WANT TO PASS THE STATE CANPRESS + NOTIFY PLAYERTURN() THAT THE USER PRESSED ON THIS BUTTON
Full code: (not the full game, note that I'm learning react just in the past few days)
export default class App extends Component{
constructor (props){
super(props);
this.flash=0
this.round=1
this.seq=[1,2,3,1,4] //will be random, this is just for testing
this.playerSeq=[]
this.win=false
this.ok=true
this.score=0
this.state = {
canPress: false,
greenB: {
backgroundColor: 'darkgreen'
},
yellowB: {
backgroundColor: 'orange'
},
blueB: {
backgroundColor: 'blue'
},
redB: {
backgroundColor: 'red'
}
}
this.play=this.play.bind(this)
this.greenFlash=this.greenFlash.bind(this)
this.blueFlash=this.blueFlash.bind(this)
this.redFlash=this.redFlash.bind(this)
this.playerTurn=this.playerTurn.bind(this)
}
play(){
this.flash=0
this.round=1 //round will increase, this is just for test
this.win=false
this.ok=true
this.score=0
this.compTurn();
this.playerTurn();
}
playerTurn(){
this.setState({canPress: true})
}
compTurn() {
let intervalId = setInterval(()=> {
if (this.flash==this.round) {
clearInterval(intervalId);
}
else {
if (this.seq[this.flash]==1){
this.greenFlash();
}
if (this.seq[this.flash]==2){
this.yellowFlash();
}
if (this.seq[this.flash]==3){
this.blueFlash();
}
if (this.seq[this.flash]==4){
this.redFlash();
}
this.flash++;
}
}
, 1500);
}
greenFlash(){
setTimeout(() => {
this.setState( {
greenB:{
...this.state.style1, backgroundColor: 'lightgreen'
}
})
}, 200);
setTimeout(() => {
this.setState( {
greenB:{
...this.state.style1, backgroundColor: 'darkgreen'
}
})
}, 1000);
}
yellowFlash(){
setTimeout(() => {
this.setState( {
yellowB:{
...this.state.style1, backgroundColor: 'yellow'
}
})
}, 200);
setTimeout(() => {
this.setState( {
yellowB:{
...this.state.style1, backgroundColor: 'orange'
}
})
}, 1000);
}
blueFlash(){
setTimeout(() => {
this.setState( {
blueB:{
...this.state.style1, backgroundColor: 'lightblue'
}
})
}, 200);
setTimeout(() => {
this.setState( {
blueB:{
...this.state.style1, backgroundColor: 'blue'
}
})
}, 1000);
}
redFlash(){
setTimeout(() => {
this.setState( {
redB:{
...this.state.style1, backgroundColor: 'pink'
}
})
}, 200);
setTimeout(() => {
this.setState( {
redB:{
...this.state.style1, backgroundColor: 'red'
}
})
}, 1000);
}
render(){
return (
<View>
<TouchableOpacity style={styles.playB}
onPress={this.play}>
<Text style={{
color:'white',
height: 30,
width:60,
}}>START</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.greenB, this.state.greenB]}></TouchableOpacity>
<TouchableOpacity style={[styles.yellowB, this.state.yellowB]}></TouchableOpacity>
<TouchableOpacity style={[styles.blueB, this.state.blueB]}></TouchableOpacity>
<TouchableOpacity style={[styles.redB, this.state.redB]}></TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
greenB:{
padding: 5,
height: 80,
width: 80,
borderRadius:160,
},
yellowB:{
padding: 5,
height: 80,
width: 80,
borderRadius:160,
},
blueB:{
padding: 5,
height: 80,
width: 80,
borderRadius:160,
},
redB:{
padding: 5,
height: 80,
width: 80,
borderRadius:160,
},
playB:{
alignSelf: 'center',
backgroundColor: 'blue',
}
});
Looks like you want to enable clicking on the buttons if state.canPress = true right? Then upon clicking, you wish to notify by calling playerTurn()?
You can do something like this for e.g your green button.
<TouchableOpacity style={[styles.greenB, this.state.greenB]} onPress={this.state.canPress && () => {
this.playerTurn(1);
// Whatever you want to do on green button pressed by player in here.
}>
</TouchableOpacity>
this.setState also has a callback function as its second parameter, which may be more useful in your flash method.

How to make Data and Vuex reactive?

There is such a code:
<template>
<div class="chart"
v-bind:style="chartStyleObject">
</div>
</template>
<script>
export default{
data () {
return {
chartStyleObject: {
width: this.$store.state.chartStyleObject.width,
height: this.$store.state.chartStyleObject.height,
marginTop: this.$store.state.chartStyleObject.marginTop,
marginRight: this.$store.state.chartStyleObject.marginRight,
marginBottom: this.$store.state.chartStyleObject.marginBottom,
marginLeft: this.$store.state.chartStyleObject.marginLeft,
},
},
}
}
And such a repository:
const axios = require("axios");
export const state = () => ({
chartStyleObject: {
height: '247px',
width: '500px',
marginTop: '15px',
marginRight: '0px',
marginBottom: '0px',
marginLeft: '15px',
},
});
export const mutations = {
changeChartDraggableEventState (state, EventState) {
state.chartDraggableEventState = EventState;
},
changeChartHeight (state, height) {
state.chartStyleObject.height = height;
},
changeHeightWrapper (state, HeightWrapper) {
state.chartStyleObject.HeightWrapper = HeightWrapper;
},
changeWidthWrapper (state, WidthWrapper) {
state.chartStyleObject.WidthWrapper = WidthWrapper;
},
changeChartMarginLeft (state, MarginLeft) {
state.chartStyleObject.marginLeft = MarginLeft;
},
changeChartMarginTop (state, MarginTop) {
state.chartStyleObject.marginTop = MarginTop;
},
};
Problem:
If I change the state of the repository through mutations, then the properties of the repository change correctly.
But!
The data properties on which the same storage properties are tied for some reason does not change.
(Despite the fact that repository property was changed)
My question is:
Why does this happen - if dates property, as well as repositories property, in theory, should be reactive?
And which approach is the most correct in this case to solve this problem? (writing directly the storage properties in the code seems like a very cumbersome decision.)
When you assign the values in
chartStyleObject: {
width: this.$store.state.chartStyleObject.width, // here
height: this.$store.state.chartStyleObject.height,
marginTop: this.$store.state.chartStyleObject.marginTop,
marginRight: this.$store.state.chartStyleObject.marginRight,
marginBottom: this.$store.state.chartStyleObject.marginBottom,
marginLeft: this.$store.state.chartStyleObject.marginLeft,
},
you are assigning values to the width, height and so on. You assign to them the current values of the state variables.
If you want the properties of chartStyleObject to change whenever the store's state changes, either map the state directly in the template (or wheverever you use it) or create a computed:
export default {
computed: {
chartStyleObject() {
return {
width: this.$store.state.chartStyleObject.width,
height: this.$store.state.chartStyleObject.height,
marginTop: this.$store.state.chartStyleObject.marginTop,
marginRight: this.$store.state.chartStyleObject.marginRight,
marginBottom: this.$store.state.chartStyleObject.marginBottom,
marginLeft: this.$store.state.chartStyleObject.marginLeft,
};
},
},
}

Seems you're trying to access 'ReactNative.createClass'

I run the following codes to create a component that renders a view but it generated some error. The codes are as follows:
var React = require('react-native');
var Dictionary = React.createClass({
render: function() {
var layout =
<React.View style = { styles.parent } >
<React.Text>
Type something in English:
</React.Text>
<React.TextInput />
<React.Text style = { styles.germanLabel } >
It's German equivalent is:
</React.Text>
<React.Text style = { styles.germanWord } >
</React.Text>
</React.View>
;
return layout;
},
});
var styles = React.StyleSheet.create({
// For the container View
parent: {
padding: 16
},
// For the Text Label
germanLabel: {
marginTop: 20,
fontWeight: 'bold'
},
// For the Text meaning
germanWord: {
marginTop: 15,
fontSize: 30,
fontStyle: 'italic'
}
});
React.AppRegistry.registerComponent('Dictionary', () => Dictionary);
and got the following error:
I even tried including import React, { Component } from 'react'; but it doesn't work. Could it be because of outdated version or something? I am not very good in react-native.

Change color of react-big-calendar events

I need to make a calendar with events and I decided to use react-big-calendar. But I need to make events of different colors. So each event will have some category and each category has corresponding color. How can I change the color of the event with react?
Result should look something like this
Sorry, I haven't read the documentation really well. It can be done with the help of eventPropGetter attribute. I've made it like this:
eventStyleGetter: function(event, start, end, isSelected) {
console.log(event);
var backgroundColor = '#' + event.hexColor;
var style = {
backgroundColor: backgroundColor,
borderRadius: '0px',
opacity: 0.8,
color: 'black',
border: '0px',
display: 'block'
};
return {
style: style
};
},
render: function () {
return (
<Layout active="plan" title="Planning">
<div className="content-app fixed-header">
<div className="app-body">
<div className="box">
<BigCalendar
events={this.events}
defaultDate={new Date()}
defaultView='week'
views={[]}
onSelectSlot={(this.slotSelected)}
onSelectEvent={(this.eventSelected)}
eventPropGetter={(this.eventStyleGetter)}
/>
</div>
</div>
</div>
</Layout>
);
}
Additional tip on how to style different kinds of events: In the myEvents array of event objects, I gave each object a boolean property isMine, then I defined:
<BigCalendar
// other props here
eventPropGetter={
(event, start, end, isSelected) => {
let newStyle = {
backgroundColor: "lightgrey",
color: 'black',
borderRadius: "0px",
border: "none"
};
if (event.isMine){
newStyle.backgroundColor = "lightgreen"
}
return {
className: "",
style: newStyle
};
}
}
/>
This solution is simple !
eventPropGetter={(event) => {
const backgroundColor = event.allday ? 'yellow' : 'blue';
return { style: { backgroundColor } }
}}
change the condition according to your need and it is done.
Siva Surya's solution is the fastest, and I have added the color property as well. Thanks...
import React, {useEffect, useLayoutEffect} from 'react';
import { Calendar, momentLocalizer,globalizeLocalizer } from 'react-big-calendar'
import moment from 'moment';
import { connect } from 'frontity';
import BackgroundWrapper from 'react-big-calendar/lib/BackgroundWrapper';
const MyCalendar = ({ actions, state, objetoBloque, formato }) => {
const localizer = momentLocalizer(moment);
const myEventsList = [
{
title: 'My Event',
start: '2022-06-21T13:45:00-05:00',
end: '2022-06-25T14:00:00-05:00',
// elcolor:'red'
colorEvento:'red'
},
{
title: 'Otro',
start: '2022-06-15T13:45:00-05:00',
end: '2022-06-23T14:00:00-05:00',
colorEvento:'green',
color:'white'
}
];
return(
<div>
<Calendar
// defaultDate = {defaultDate}
localizer={localizer}
events={myEventsList}
startAccessor="start"
endAccessor="end"
style={{ height: 500 }}
BackgroundWrapper = "red"
eventPropGetter={(myEventsList) => {
const backgroundColor = myEventsList.colorEvento ? myEventsList.colorEvento : 'blue';
const color = myEventsList.color ? myEventsList.color : 'blue';
return { style: { backgroundColor ,color} }
}}
/>
</div>
)
}
export default connect(MyCalendar);
Searching for how to change the border colour of an event also lead me here, and I couldn't find the answer anywhere else, but found that adding the following done the trick:
border: "black",
borderStyle: "solid"

Categories