How to style new #fluentui/react-button [v8 beta]? - fluent-ui

Is there any documentation on how to apply style customisations to the new Button? The styling using the IButtonStyles interface is broken on the new button, as per code below.
import { PrimaryButton } from '#fluentui/react';
import { Button as FluentButton } from '#fluentui/react-button';
const btnStyles = {
rootHovered: {
background: "red"
}
};
return (
<div>
<PrimaryButton styles={btnStyles}/>
<FluentButton styles={btnStyles}/>
</div>
)

Have looked into the file where the new react-button is defined, seems to need a ButtonTokens. Guessing this is along with the wider Fluent UI trend of moving to style tokens.
const btnStyle : ButtonTokens = { borderColor: 'red' }
return (
<FluentButton tokens={btnStyle} />
)

Related

React Native / Expo custom font: German umlauts out of bounds

I've added a custom font (FS Me as an OTF file) to a React Native / Expo app using useFonts from expo-font. Unfortunately, I'm running into an issue where German umlauts (ä, ö, ü) are not visible due to the viewbox of the Text element being too small. For example, take this text: Über uns.
In the app, this simply renders as Uber uns because the two dots above the "U" are out of the Text boundary. When I increase the line height to 1.4x the font size, the umlauts show. However, this a) adds some sort of padding on the bottom of the text and b) it's obviously not a very good solution to increase the line height everywhere. Increasing it on a case-to-case basis isn't a viable solution either.
I'm using a custom Text component which sets a default font like this:
import React from 'react';
import {
TextProps,
Text as RNText, // eslint-disable-line no-restricted-imports
StyleSheet,
StyleProp,
} from 'react-native';
// Animated.createAnimatedComponent requires a class component
// eslint-disable-next-line react/prefer-stateless-function
class Text extends React.Component<TextProps> {
render() {
const { children, style } = this.props;
let styles = style;
let objStyle: StyleProp<any> = {};
if (Array.isArray(style)) objStyle = StyleSheet.flatten(style);
else if (style) objStyle = { ...(style as object) };
if (!objStyle.fontFamily || objStyle.fontFamily === 'FS_Me') {
objStyle.fontFamily = 'FS_Me_400_Regular';
if (objStyle.fontWeight === 'bold' || objStyle.fontWeight === '700') {
objStyle.fontFamily = 'FS_Me_700_Bold';
objStyle.fontWeight = undefined;
}
if (objStyle.fontWeight === 'light' || objStyle.fontWeight === '300') {
objStyle.fontFamily = 'FS_Me_300_Light';
if (objStyle.fontStyle === 'italic') {
objStyle.fontFamily = 'FS_Me_300_Light_Italic';
}
objStyle.fontWeight = undefined;
}
objStyle.backgroundColor = 'red';
styles = objStyle;
}
return (
<RNText allowFontScaling={false} {...this.props} style={styles}>
{children}
</RNText>
);
}
}
export default Text;
However, this also happens when I'm using the core RN Text component and only change the font family.
Does anyone have an idea why this happens?

How to leave existing class attribute on image element - now it is being moved to a generated enclosing span

Background: Trying to use ckeditor5 as a replacement for my homegrown editor in a non-invasive way - meaning without changing my edited content or its class definitions. Would like to have WYSIWYG in the editor. Using django_ckeditor_5 as a base with my own ckeditor5 build that includes ckedito5-inspector and my extraPlugins and custom CSS. This works nicely.
Problem: When I load the following HTML into ClassicEditor (edited textarea.value):
<p>Text with inline image: <img class="someclass" src="/media/uploads/some.jpeg"></p>
in the editor view area, browser-inspection of the DOM shows:
...
<p>Text with an inline image:
<span class="image-inline ck-widget someclass ck-widget_with-resizer" contenteditable="false">
<img src="/media/uploads/some.jpeg">
<div class="ck ck-reset_all ck-widget__resizer ck-hidden">
<div ...></div></span></p>
...
Because the "someclass" class has been removed from and moved to the enclosing class attributes, my stylesheets are not able to size this image element as they would appear before editing.
If, within the ckeditor5 view, I edit the element using the browser inspector 'by hand' and add back class="someclass" to the image, ckeditor5 displays my page as I'd expect it with "someclass" and with the editing frame/tools also there. Switching to source-editing and back shows the class="someclass" on the and keeps it there after switching back to document editing mode.
(To get all this, I enabled the GeneralHtmlSupport plugin in the editor config with all allowed per instructions, and that seems to work fine.) I also added the following simple plugin:
export default class Extend extends Plugin {
static get pluginName() {
return 'Extend';
}
#updateSchema() {
const schema = this.editor.model.schema;
schema.extend('imageInline', {
allowAttributes: ['class']
});
}
init() {
const editor = this.editor;
this.#updateSchema();
}
}
to extend the imageInline model hoping that would make the Image plugin keep this class attribute.
This is the part where I need some direction on how to proceed - what should be added/modified in the Image Plugin or in my Extend plugin to keep the class attribute with the element while editing - basically to fulfill the WYSIWYG desire?
The following version does not rely on GeneralHtmlSupport but creates an imageClassAttribute model element and uses that to convert only the image class attribute and place it on the imageInline model view widget element.
import Plugin from '#ckeditor/ckeditor5-core/src/plugin';
export default class Extend extends Plugin {
static get pluginName() {
return 'Extend';
}
#updateSchema() {
const schema = this.editor.model.schema;
schema.register( 'imageClassAttribute', {
isBlock: false,
isInline: false,
isObject: true,
isSelectable: false,
isContent: true,
allowWhere: 'imageInline',
});
schema.extend('imageInline', {
allowAttributes: ['imageClassAttribute' ]
});
}
init() {
const editor = this.editor;
this.#updateSchema();
this.#setupConversion();
}
#setupConversion() {
const editor = this.editor;
const t = editor.t;
const conversion = editor.conversion;
conversion.for( 'upcast' )
.attributeToAttribute({
view: 'class',
model: 'imageClassAttribute'
});
conversion.for( 'dataDowncast' )
.attributeToAttribute({
model: 'imageClassAttribute',
view: 'class'
});
conversion.for ( 'editingDowncast' ).add( // Custom conversion helper
dispatcher =>
dispatcher.on( 'attribute:imageClassAttribute:imageInline', (evt, data, { writer, consumable, mapper }) => {
if ( !consumable.consume(data.item, evt.name) ) {
return;
}
const imageContainer = mapper.toViewElement(data.item);
const imageElement = imageContainer.getChild(0);
if ( data.attributeNewValue !== null ) {
writer.setAttribute('class', data.attributeNewValue, imageElement);
} else {
writer.removeAttribute('class', imageElement);
}
})
);
}
}
Well, Mr. Nose Tothegrind found two solutions after digging through ckeditor5 code, here's the first one. This extension Plugin restores all image attributes that are collected by GeneralHtmlSupport. It can be imported and added to a custom ckeditor5 build app.js file by adding config.extraPlugins = [ Extend ]; before the editor.create(...) statement.
import Plugin from '#ckeditor/ckeditor5-core/src/plugin';
import GeneralHtmlSupport from '#ckeditor/ckeditor5-html-support/src/generalhtmlsupport';
export default class Extend extends Plugin {
static get pluginName() {
return 'Extend';
}
static get requires() {
return [ GeneralHtmlSupport ];
}
init() {
const editor = this.editor;
this.#setupConversion();
}
#setupConversion() {
const editor = this.editor;
const t = editor.t;
const conversion = editor.conversion;
conversion.for ( 'editingDowncast' ).add( // Custom conversion helper
dispatcher =>
dispatcher.on( 'attribute:htmlAttributes:imageInline', (evt, data, { writer, mapper }) => {
const imageContainer = mapper.toViewElement(data.item);
const imageElement = imageContainer.getChild(0);
if ( data.attributeNewValue !== null ) {
const newValue = data.attributeNewValue;
if ( newValue.classes ) {
writer.setAttribute('class', newValue.classes.join(' '), imageElement);
}
if ( newValue.attributes ) {
for (const name of Object.keys(newValue.attributes)) {
writer.setAttribute( name, newValue.attributes[name], imageElement);
}
}
} else {
writer.removeAttribute('class', imageElement);
}
})
);
}a
}

How can I pass the current theme of the app into StyleSheet.create()?

Due to various limitations, I cannot store the current theme in props. I have to use a custom props that I cannot modify at the moment. I have been able to get around this by using React Context to store the current theme.
I have a class called pageStyle. In it, I have a pageContainer that I'd like to be able to set backgroundColor either to dark or light values.
I am able to get the current theme in a separate class R by using this.context.theme. R is also where I am rendering the FlatList object and passing style={pageStyle.pageContainer}.
I could create two separate pageContainers, called pageContainerDark and pageContainerLight, and have the correct respective backgroundColors for both. However, this feels messy to me. This would also require having a method for each style page to determine which pageContainer to use and is not scalable whatsoever. I have also tried using a global variable but was having some issues with this.
Is there a cleaner way to set pageContainer's backgroundColor based on the current theme?
I have attached the pageStyle.ts file below.
//pageStyle.ts
import { StyleSheet} from 'react-native';
const pageStyles = StyleSheet.create({
pageContainer: {
flex: 1,
backgroundColor: "#232323"
},
// pageContainerDark: {
// flex: 1,
// backgroundColor: "#232323"
// },
// pageContainerLight: {
// flex: 1,
// backgroundColor: "#FFFFFF"
// },
pageContentContainer: {
paddingBottom: 0
}
});
// export function getPageContainerFromPageStyles(theme: string) {
// if (theme == 'light') {
// return pageStyle.pageContainerForLightTheme
// } else {
// return pageStyle.pageContainerForDarkTheme
// }
// }
export { pageStyle };

Can I use multiple or nested elements in the Label of a Picker Item in React Native?

I'm using React Native with NativeBase and would like to make the labels of my Picker more complicated than just one plain string of text.
But is it even possible to pass elements as the label, say multiple child elements wrapped in a single top-level element?
Or do Pickers only support plain text as labels?
As requested by bennygenel, here's a version of what I've tried:
export default class ThingPicker extends React.Component {
render() {
const {
initialThing,
things,
onThingChanged,
} = this.props;
const orderedThings = things.sort();
return (
<Picker
selectedValue={initialThing}
onValueChange={onThingChanged}>
{buildThingItems(orderedThings)}
</Picker>
);
}
}
function buildThingItems(orderedThings) {
let items = orderedThings.map(th => {
const it = th === "BMD" ? (<Text key={th} label={"foo"} value={"bar"}}>Hello</Text>)
: (<Picker.Item key={th} label={th} value={th} />);
return it;
});
}
Yes! It is possible, it just might not look very "right" for React/JSX code. Just create the elements you need and assign them to the label field:
function buildThingItems(orderedThings) {
let items = orderedThings.map(th => {
const it = (<Picker.Item
key={th}
label={currency === "BMD" ? (<Text>Hello</Text>) : th}
value={th} />);
return it;
});
}

move the view up when keyboard as shown in react-native

hai i am trying to move the view up when keyboard as shown using react-native,I followed the #sherlock's comment in (How to auto-slide the window out from behind keyboard when TextInput has focus? i got an error like this
I don't know how to resolve this error, can any one help me how to resolve this, any help much appreciated.
There's a great discussion about this in the react-native github issues
https://github.com/facebook/react-native/issues/3195#issuecomment-147427391
I'd start there, but here are a couple more links you may find useful, one of which is mentioned already in the article you referenced...
[React Tips] Responding to the keyboard with React Native
Andr3wHur5t/react-native-keyboard-spacer
In my library "react-native-form-generator" (https://github.com/MichaelCereda/react-native-form-generator) i did the following.
I created a Keyboard Aware scroll view (partially modified from https://github.com/facebook/react-native/issues/3195#issuecomment-146518331)
the following it's just an excerpt
export class KeyboardAwareScrollView extends React.Component {
constructor (props) {
super(props)
this.state = {
keyboardSpace: 0,
}
this.updateKeyboardSpace = this.updateKeyboardSpace.bind(this)
this.resetKeyboardSpace = this.resetKeyboardSpace.bind(this)
}
updateKeyboardSpace (frames) {
let coordinatesHeight = frames.endCoordinates.height;
const keyboardSpace = (this.props.viewIsInsideTabBar) ? coordinatesHeight - 49 : coordinatesHeight
this.setState({
keyboardSpace: keyboardSpace,
})
}
resetKeyboardSpace () {
this.setState({
keyboardSpace: 0,
})
}
componentDidMount () {
// Keyboard events
DeviceEventEmitter.addListener('keyboardWillShow', this.updateKeyboardSpace)
DeviceEventEmitter.addListener('keyboardWillHide', this.resetKeyboardSpace)
}
componentWillUnmount () {
DeviceEventEmitter.removeAllListeners('keyboardWillShow')
DeviceEventEmitter.removeAllListeners('keyboardWillHide')
}
scrollToFocusedInput (event, reactNode, extraHeight = 69) {
const scrollView = this.refs.keyboardScrollView.getScrollResponder();
setTimeout(() => {
scrollView.scrollResponderScrollNativeHandleToKeyboard(
reactNode, extraHeight, true
)
}, 220)
}
render () {
return (
<ScrollView
ref='keyboardScrollView'
keyboardDismissMode='interactive'
contentInset={{bottom: this.state.keyboardSpace}}
showsVerticalScrollIndicator={true}
style={this.props.style}>
{this.props.children}
</ScrollView>
)
}
Then i use it like any other scrollview
import { KeyboardAwareScrollView } from 'react-native-form-generator'
...
handleFormFocus(event, reactNode){
this.refs.scroll.scrollToFocusedInput(event, reactNode)
}
...
<KeyboardAwareScrollView ref='scroll'>
<Form ref='registrationForm'
onFocus={this.handleFormFocus.bind(this)}
onChange={this.handleFormChange.bind(this)}
label="Personal Information">
........
</Form>
</KeyboardAwareScrollView>
on change my component (Form) will call scrollToFocusedInput in KeyboardAwareScrollView (using the ref).
i suggest to check the code of my library (see the link on top), or simply use it (everything it's already tested and working).
If you have further questions just comment