I have a row of custom buttons displayed in a VStack and a HStack, strangely the 2 rows are not aligning - see the example for the best I could achieve.
I suspect that it is due to the different content (text or SFSymbol) but the buttons "look" the same size.
To get this I had to have different spacing within the HStacks which.
Thanks
import Foundation
import SwiftUI
struct MyRoundButton: ButtonStyle {
var color: Color = .purple
func makeBody(configuration: Configuration) -> some View {
configuration
.label
.frame(height: 30)
.font(Font.system(size: 25, weight: .semibold))
.foregroundColor(configuration.isPressed ? .white : color)
.padding(23)
.background(
Circle()
.fill(configuration.isPressed ? color : color.opacity(0.25)))
}
}
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(spacing: 30) {
HStack(alignment: .center, spacing: 23) {
Group {
Button {
print ("didTap roundButton")
} label: {
Image(systemName: "camera.fill")
}
Button {
print ("didTap roundButton")
} label: {
Image(systemName: "photo.fill.on.rectangle.fill")
}
Button {
print ("didTap roundButton")
} label: {
Image(systemName: "folder.fill")
}
Button {
print ("didTap roundButton")
} label: {
Image(systemName: "trash.fill")
}.buttonStyle(MyRoundButton(color: .red))
}.buttonStyle(MyRoundButton())
}
HStack(alignment: .center, spacing: 27) {
Group {
Button {
print ("didTap roundButton")
} label: {
Text("Ja")
}.buttonStyle(MyRoundButton(color: .green))
Button {
print ("didTap roundButton")
} label: {
Text("Ja")
}.buttonStyle(MyRoundButton(color: .blue))
Button {
print ("didTap roundButton")
} label: {
Text("Ja")
}.buttonStyle(MyRoundButton(color: .orange))
Button {
print ("didTap roundButton")
} label: {
Text("Ja")
}.buttonStyle(MyRoundButton(color: .yellow))
}.buttonStyle(MyRoundButton())
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Fixed size worked as suggested, thanks.
import Foundation
import SwiftUI
struct MyRoundButton: ButtonStyle {
var color: Color = .purple
func makeBody(configuration: Configuration) -> some View {
configuration
.label
.frame(width: 30, height: 30, alignment: .center)
.font(Font.system(size: 25, weight: .semibold))
.foregroundColor(configuration.isPressed ? .white : color)
.padding(23)
.background(
Circle()
.fill(configuration.isPressed ? color : color.opacity(0.25)))
}
}
Related
I tried to change label's margin (see the attached image to the question) from px to em/rem, but i don't know where i should write styles to structure. I can't find in MUI documentation "adjacent sibling combinator".
createTheme({
MuiTextField: {
defaultProps: {
// props
},
styleOverrides: {
root: {
// styles
}
}
}
})
generated css style in inspector tab
If you are using material-ui 5:
import { createTheme } from '#mui/material';
const theme = createTheme({
components: {
MuiTextField: {
styleOverrides: {
root: {
'& label': {
margin: '2rem',
},
},
},
},
},
});
export default theme;
https://mui.com/pt/material-ui/customization/theme-components/
I finally resolve it ;) I added to InputLabel this line "& + .MuiInputBase-root" to change TextField's (and another inputs) label
MuiInputLabel: {
defaultProps: {
// props
},
styleOverrides: {
root: {
// styles
"& +.MuiInputBase-root": {
marginTop: '2em'
}
}
}
}
How can you change the style of a disabled button in Material-UI using themes ?
The following code doesn't work
const theme = createMuiTheme({
props: {
// Name of the component
MuiButtonBase: {
// The default props to change
disableRipple: true // No more ripple, on the whole application !
}
},
overrides: {
MuiButton: {
text: {
color: "red"
},
disabled: {
text: {
color: "blue"
}
}
}
}
});
function DefaultProps() {
return (
<ThemeProvider theme={theme}>
<Button disabled>Change default props</Button>
</ThemeProvider>
);
}
The following works:
const theme = createMuiTheme({
props: {
// Name of the component
MuiButtonBase: {
// The default props to change
disableRipple: true // No more ripple, on the whole application !
}
},
overrides: {
MuiButton: {
root: {
color: "red",
'&$disabled': {
color: "blue"
}
},
}
}
});
Actually my alert controller "Title" is too lengthy , so i want to resize the text and i added Css class then tried to change the style in SASS by giving font size to it unfortunately didn't worked and the buttons text are uppercase.So is there anyway to change font size of text ,buttons color and size and changing button text to lowercase?
My typescript file
import { IonicPage,AlertController} from 'ionic-angular';
import { Component,ViewChild } from '#angular/core';
import 'rxjs/add/operator/toPromise';
#IonicPage()
#Component({
selector: 'page-kpi',
templateUrl: 'kpi.html',
})
export class KpiPage {
#ViewChild(Nav) nav: Nav;
temp2:any;
lastUpdate:any;
constructor(
private alertCtrl: AlertController,
public menuCtrl : MenuController,
) {
this.platform.ready().then(() => {
this.refreshbutton();
}
});
refreshbutton(){
this.getSession();
if(this.offline == true)
{
this.offlineRefreshAlert();
}
else{
let alert = this.alertCtrl.create({
title: 'Do you really want to refresh the widgets?',
message: 'Refresh process will take time to complete.',
cssClass: 'alertLogCss',
buttons: [
{
text: 'Cancel',
role: 'cancel',
handler: () => {
alert = null;
}
},
{
text: 'Refresh now',
handler: () => {
if(this.online == true){
this.refreshdata(this.result.sid);
this.loadingrefreshdashboard();
}
if(this.offline == true){
this.offlineRefreshAlert();
}
}
}
]
});
alert.present();
}
}
}
My SASS(CSS) file
.alertLogCss{
background-color: white;
color: red;
font-size: 4px;
button{
color: red;
font-size: 5px;
}
}
You have to add css out of that's page scss block
.alertLogCss{
background-color: white;
color: red;
font-size: 4px;
button{
color: red !important;
font-size: 10px;
text-transform: lowercase !important;
}
}
Put in app.scss
I need sequentially to load one by one components from array.
Before loading next component to Loader it should be fade-out , loaded and then fade-in.
The code above blinks not correctly and show this message:
"QML State: Binding loop detected for property "when"
What have I done wrong?
Thank you
import QtQuick 2.0
Rectangle {
id: screen
width: 400
height: 400
color: "black"
Rectangle {
id: view
anchors.fill: parent
Loader {
id: loader
onLoaded: { view.state="fadeIn"; }
}
states: [
State {
name: "fadeOut";
PropertyChanges { target: view; opacity: 0.1; }
},
State {
name: "fadeIn";
PropertyChanges { target: view; opacity: 1; }
},
State {
name: "load"; when: view.opacity == 0;
StateChangeScript { script: { loader.sourceComponent=com_array[index]; } }
}
]
transitions: [
Transition {
to: "fadeIn"
NumberAnimation { properties: "opacity"; from: 0.0; to: 0.99; duration: 2000 }
},
Transition {
to: "fadeOut"
NumberAnimation { properties: "opacity"; from: 0.99; to: 0; duration: 2000 }
}
]
}
Timer {
id: timer
interval: 3000; running: true; repeat: true
onTriggered: {
++index;
if( index >= com_array.length ) {
index = 0
}
view.state="fadeOut"
}
}
// -------------------------------------------------------------------
// Components
Item {
id: list
property Component red_rect_com : Component {
Rectangle {
width: screen.width; height: screen.height
Rectangle {
anchors.fill: parent; color: "red";
}
}
}
property Component blue_rect_com : Component {
Rectangle {
width: screen.width; height: screen.height
Rectangle {
anchors.fill: parent; color: "blue";
}
}
}
}
property int index: 0
property var com_array: [ list.red_rect_com, list.blue_rect_com ]
Component.onCompleted: { loader.sourceComponent = com_array[index]; }
}
UPD
Possible this could be useful for other, full example with correction ( thanks to answer author ):
import QtQuick 2.0
Rectangle {
id: screen
width: 400
height: 400
color: "black"
Rectangle {
id: view
anchors.fill: parent
property var sourceComponent
opacity: 0
function loadComponent( component, is_first_start ) {
sourceComponent = component;
if( is_first_start ) {
fadeOut.stop(); fadeIn.start();
}
else {
fadeIn.stop(); fadeOut.start();
}
}
Loader {
id: loader
onLoaded: {
fadeOut.stop();
fadeIn.start();
}
}
NumberAnimation on opacity {
id: fadeOut;
to: 0.0;
duration: 2000;
onStopped: { loader.sourceComponent=view.sourceComponent; }
}
NumberAnimation on opacity {
id: fadeIn;
to: 1.0;
duration: 2000
}
}
Timer {
id: timer
interval: 4000; running: true; repeat: true
onTriggered: {
++index;
if( index >= com_array.length ) {
index = 0
}
view.loadComponent( com_array[index], false );
}
}
// -------------------------------------------------------------------
// Components
Item {
id: list
property Component red_rect_com : Component {
Rectangle {
width: screen.width; height: screen.height
Rectangle {
anchors.fill: parent; color: "red";
}
}
}
property Component blue_rect_com : Component {
Rectangle {
width: screen.width; height: screen.height
Rectangle {
anchors.fill: parent; color: "blue";
}
}
}
}
property int index: 0
property var com_array: [ list.red_rect_com, list.blue_rect_com ]
Component.onCompleted: { view.loadComponent( com_array[index], true ); }
}
It gives you the error because QML make connections to communicate between changes:
onStateChange is connected by PropertyChanges that changes opacity to a view's opacity property.
The onOpacityChanged signal will be connected to State's when property.
The onWhenChanged signal will be connected to the state property, thus making binding Loop.
Another thing is that when you make NumberAnimation within Transition, you do not need to specify the from and to properties. The PropertyChanges sets the correct value.
Anyway, your states does not make sense, you using them wrong.
You should also wait for fadeOut, because it will load so fast that you will not see the effect.
Simply make two animations:
Rectangle {
id: view
anchors.fill: parent
property var sourceComponent
function loadComponent(component){
fadeIn.stop(); fadeOut.start();
sourceComponent = component;
}
Loader {
id: loader
onLoaded: { fadeOut.stop(); fadeIn.start(); }
}
NumberAnimation on opacity {
id: fadeOut
to: 0.0
onStopped: { loader.sourceComponent= sourceComponent; }
}
NumberAnimation on opacity {
id: fadeIn
to: 1.0
}
}
You should also change the loading to:
property int index: 0
onIndexChanged: { view.loadComponent(com_array[index]); }
But there is better solution: using ShaderEffectSource to take a frame of Loader before changing the source, and using it to fadeOut meanwhile loading the component.
I want to implement an X button inside a textfield (x on right side of textfield) to clear entered texts. I have seen many extjs application that has this feature. How do I go about doing that? Any suggestion or comments would be really appreciated...
THanks
it looks something like this...
You have to use a Ext.form.field.Trigger. Here is a example for that
Ext.define('Ext.ux.CustomTrigger', {
extend: 'Ext.form.field.Trigger',
alias: 'widget.customtrigger',
initComponent: function () {
var me = this;
me.triggerCls = 'x-form-clear-trigger'; // native ExtJS class & icon
me.callParent(arguments);
},
// override onTriggerClick
onTriggerClick: function() {
this.setRawValue('');
}
});
Ext.create('Ext.form.FormPanel', {
title: 'Form with TriggerField',
bodyPadding: 5,
width: 350,
renderTo: Ext.getBody(),
items:[{
xtype: 'customtrigger',
fieldLabel: 'Sample Trigger',
emptyText: 'click the trigger'
}]
});
For ease of testing, here is a JSFiddle
This is what works for me with the CSS:
CSS
.x-form-clear {
background-image: url('../../resources/themes/images/default/form/clear-trigger.gif');
background-position: 0 0;
width: 17px;
height: 22px;
border-bottom: 1px solid #b5b8c8;
cursor: pointer;
cursor: hand;
overflow: hidden;
}
.x-form-clear-over {
background-position: -17px 0;
border-bottom-color: #7eadd9;
}
.x-form-clear-click {
background-position: -68px 0;
border-bottom-color: #737b8c;
}
Class
Ext.define('Ext.ux.form.field.Clear', {
extend: 'Ext.form.field.Trigger',
alias: 'widget.clearfield',
triggerBaseCls: 'x-form-clear',
onTriggerClick: function() {
this.setValue();
}
});
Usage
Ext.create('Ext.container.Container', {
renderTo: Ext.getBody(),
items: [
Ext.create('Ext.ux.form.field.Clear', {
fieldLabel: 'Clear Field',
cls: 'clear-trigger'
})
]
})
Or use this 'clearbutton' plugin: http://www.eekboom.de/ClearButton.html
I like it because it's just a plugin, one line, instead of requiring a custom subclass.
Also, it can be used on all kinds of fields, not just on a textfield.
You can use the Ext.form.field.Text with triggers in Extjs 5.0 and later, no need to define a new type.
var textfield = Ext.create('Ext.form.field.Text', {
triggers: {
clear: {
cls: 'x-form-clear-trigger',
handler: function () {
this.setValue('');
}
}
}
});
The scope of the trigger's handler is the Ext.form.field.Text component.
You can have multiple triggers, and can also use MVVM model. For example:
var textfield = Ext.create('Ext.form.field.Text', {
triggers: {
clear: {
cls: 'x-form-clear-trigger',
handler: function () {
this.setValue('');
}
},
search: {
cls: 'x-form-search-trigger',
handler: 'onSearch'
}
}
});
The search trigger uses a handler function, i.e. onSearch, that is defined in the controller of the component that has the Ext.form.field.Text object.
In ExtJS 6+, you can also just add the following 2 configs on your Ext.form.field.Text and show/hide the trigger with the built-in change listener
triggers: {
clearText: {
cls: 'clear-text-trigger-icon',
handler: function() {
this.setValue('');
}
}
},
listeners: {
change: function(textField) {
if (textField.getValue()) {
textField.setHideTrigger(false);
} else {
textField.setHideTrigger(true);
}
}
}