SCSS variable string parse to individual mixin vars - variables

I'm trying to use a variable that gets pass into a mixin to display font settings.
Some variables will display 5 items ($w,$s,$lh,$f,$t) and some will display 3, which is why I'm trying to avoid using nth(selectors) to save me from doing multiple #if #else checks inside my mixin.
/* theme_vars.scss */
$theme__font: niceFont;
$font__value_1: unquote("$w:normal, $s:1.25em, $lh:1.5em, $f:#{$theme__font}, $t:capitalize");
$font__value_2: unquote("$w:bold, $s:2em, $f:#{$theme__font}");
/* theme/header.scss */
.logo {
#include customFont($font__values_1);
}
.title {
#include customFont($font__values_2);
}
/* mixins.scss */
#mixin customFont( $w:inherit, $s:inherit, $lh:inherit, $f:inherit, $t:inherit ) {
font-weight: $w;
font-size: $s;
line-height: $lh;
font-family: $f;
text-transform: $t;
}
But the output I'm getting is this:
.logo {
font-weight: $w:normal, $s:1.25em, $lh:1.5em, $f:#{$theme__font}, $t:capitalize;
font-size: inherit;
line-height: inherit;
font-family: inherit;
text-transform: inherit;
}
Is what I'm trying to do possible?
Thanks in advance, Adam
EDIT *****
$font__value_1: (normal, 1.25em, 1em, "#{$theme__font}", capitalize);
.logo {
#include customFont($font__value_1);
}
#mixin customFont( $list ) {
$wt: nth($list, 1);
$sz: nth($list, 2);
$lh: nth($list, 3);
$ff: nth($list, 4);
$tt: nth($list, 5);
#if $wt != null { font-weight: $wt; }
#if $sz != null { font-size: $sz; }
#if $lh != null { line-height: $lh; }
#if $ff != null { font-family: $ff; }
#if $tt != null { text-transform: $tt; }
}

Use collecions. Try this for fonts variables:
$font__value_1: (normal, 1.25em, 1.5em, "#{$theme__font}", capitalize);
$font__value_2: unquote(bold, 2em, null, "#{$theme__font}", null);
Edited(#Adam O'Brien comment)
Working mixin is:
#mixin customFont( $list ) {
$wt: nth($list, 1);
$sz: nth($list, 2);
$lh: nth($list, 3);
$ff: nth($list, 4);
$tt: nth($list, 5);
if $wt != null {
font-weight: $wt;
}
if $sz != null {
font-size: $sz;
}
if $lh != null {
line-height: $lh;
}
if $ff != null {
font-family: $ff;
}
if $tt != null {
text-transform: $tt;
}
}

Related

Livewire datatables columns sorting not working

I am new to Livewire, I am implementing data table using livewire.
Requirement: I need to sort data by updated_at column in descending order. After that if user click on status , then status should be sort by Ascending then also sort by updated_at.
here is my code :
<?php
namespace App\Http\Livewire\Table;
use App\Models\RequestLog;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Mediconesystems\LivewireDatatables\BooleanColumn;
use Mediconesystems\LivewireDatatables\NumberColumn;
use Mediconesystems\LivewireDatatables\Column;
use Mediconesystems\LivewireDatatables\DateColumn;
use Mediconesystems\LivewireDatatables\Http\Livewire\LivewireDatatable;
class AdminMatch extends LivewireDatatable
{
// public $exportable = true;
public $hideable = 'buttons';
// public $model = User::class;
/**
* Write code on Method
*
* #return response()
*/
public $filter;
public function builder()
{
$matchReq= RequestLog::orderBy('request_logs.updated_at', 'desc')
->Join('users', 'users.id', 'request_logs.user_id');
return $matchReq;
}
public function columns()
{
return [
NumberColumn::name('id')
->label('ID')
->searchable()
->defaultSort('desc'),
NumberColumn::name('users.profile_code')
->label('Sender Profile Code')
->searchable()
->defaultSort('desc'),
NumberColumn::name('request_logs.receiver_profile_code')
->label('Receiver Profile Code')
->searchable()
->defaultSort('desc'),
DateColumn::name('request_logs.created_at')
->label('Request Sent')
->format('d/m/Y')
->defaultSort('desc'),
DateColumn::name('request_logs.updated_at')
->label('Request Updated')
->format('d/m/Y')
->defaultSort('desc'),
Column::callback(['status'], function($status){
if ($status == 'Unsuccessfull') {
return "<span class='badge' style='color: white; background-color: red !important'>$status</span>";
}elseif ($status == 'accept') {
return "<span class='badge' style='color: white; background-color: green !important'>$status</span>";
}elseif ($status == 'new') {
return "<span class='badge badge-info'>$status</span>";
}elseif ($status == 'in-process') {
return "<span class='badge' style='color: white; background-color: orange !important'>$status</span>";
}
// return "<span class='badge' style='color: white; background-color: !important'>$status</span>";
})->label('Status'),
Column::callback(['status','id'], function($status, $id){
// if($status == 'new'){
return "<a class='btn btn-success' href='/superadmin/match-request-view/$id'>View</a>";
// }
})->label('Action'),
];
}
}
you can see in picture when i click on status table nothing happend.

Increase a variable in Less

Is it possible to increase a variable in Less?
#i: 0;
.one { border: #i++; }
.two { border: #i++; }
.tree { border: #i++; }
or perhaps using mixins in a way, like
.increase() {
#i: #i+1;
#increase: #i;
}
To better explain the problem:
#icon_width: 32px;
.social{
background: url('snippet_with_n_images');
.facebook: background-position-x: -#icon_width*0;
.twitter: background-position-x: -#icon_width*1;
.googlep: background-position-x: -#icon_width*2;
...
.pinterest: background-position-x: -#icon_width*(n-1);
.linkedin: background-position-x: -#icon_width*n;
/*be replaced by */
.next(): {
background-position-x: -#icon_width*#i++;
}
.facebook: .next();
.twitter: .next();
.googlep: .next();
...
.pinterest: .next();
.linkedin: .next();
}
Simply speaking, it is not possible to increment the same variable without using a loop (mixin) in Less. This is because Less does lazy loading of variables and so the multiple increments result in recursive definition error. The following snippet:
#i: 0;
.one { #i: #i + 1; border: #i; }
.two { #i: #i + 1; border: #i; }
.three { #i: #i + 1; border: #i; }
when compiled would give:
NameError: Recursive variable definition for #i on line 4, column 7:
Using a mixin like in question (.increase()) would still result in the same error as provided above.
The best way to increment would be to make use of mixin loops. For the modified sample provided in the question, the loop should be like below:
#icon_width: 32px;
#social-networks: facebook, twitter, googlep, pinterest, linkedin; /* an array with list of networks */
.social{
background: url('snippet_with_n_images');
.loop-social(1); /* call loop with initial value as 1 */
}
.loop-social(#index) when (#index < length(#social-networks)){ /* iterate till index is less than array length */
#social-network: extract(#social-networks, #index); /* extract value corresponding to index from array */
.#{social-network}{ /* use extracted social network value as selector */
background-position-x: -#icon_width*#index; /* assign calculated value, the index would incremented for each iteration */
}
.loop-social(#index + 1); /* call next iteration with incremented value */
}
The above Less code when compiled would produce the following CSS:
.social {
background: url('snippet_with_n_images');
}
.social .facebook {
background-position-x: -32px;
}
.social .twitter {
background-position-x: -64px;
}
.social .googlep {
background-position-x: -96px;
}
.social .pinterest {
background-position-x: -128px;
}

Styling elements based on sibling count in LESS

I have this Less mixin (courtesy of Lea Verou):
I would like to pass a variable of max-items (8) and based on this create the rule set below with a loop. So I don't have to repeat code for every number of child elements (1,2,3,4,...).
.list-elements-count-undefined-width() {
/* one item */
&:first-child:nth-last-child(1) {
width: 100%;
}
/* two items */
&:first-child:nth-last-child(2),
&:first-child:nth-last-child(2) ~ li {
width: 50%;
}
/* three items */
&:first-child:nth-last-child(3),
&:first-child:nth-last-child(3) ~ li {
width: (100% / 3);
}
/* four items */
&:first-child:nth-last-child(4),
&:first-child:nth-last-child(4) ~ li {
width: 25%;
}
/* five items */
&:first-child:nth-last-child(5),
&:first-child:nth-last-child(5) ~ li {
width: 20%;
}
/* six items */
&:first-child:nth-last-child(6),
&:first-child:nth-last-child(6) ~ li {
width: (100% / 6);
}
}
.list-elements-count-undefined-width(#i) when (#i > 0) {
.list-elements-count-undefined-width((#i - 1));
&:first-child:nth-last-child(#{i}),
&:first-child:nth-last-child(#{i}) ~ li{
width: (100% / #i);
}
}
.list-elements-count-undefined-width(8);

Is there a way to create a less mixin that calculates a grid which divides the space available?

We prefer grids that divide the available space like this:
grid-1 = 100%
grid-2 = 50%
grid-3 = 33.33333333%
We have the following less mixin which works great except that grid-1 should equal 100%;
#column-gutter-width: 2%;
.grid {
margin-left: -#column-gutter-width;
.clearfix();
.generate-grid-units(#i) when (#i > 0){
.grid-#{i} {
width: (100% / #i) - #column-gutter-width;
margin-left: #column-gutter-width;
}
.generate-grid-units((#i - 1));
}
.generate-grid-units(6);
}
This generates the following where the only incorrect unit is grid-1:
.grid .grid-2 {
width: 48%;
margin-left: 2%;
}
.grid .grid-1 {
width: 98%;
margin-left: 2%;
}
How can we alter the math so that grid-1 = 100% but have the other grid units remain the same?
Any help would be much appreciated.
Cheers
You could try the following:
#column-gutter-width: 2%;
#num-columns: 6;
.grid {
margin-left: -#column-gutter-width;
.clearfix();
.generate-grid-units(#i) when (#i > 1){
.grid-#{i} {
width: ((100% / #i) - #column-gutter-width);
margin-left: #column-gutter-width;
&:first-child {
margin-left: 0;
}
}
.generate-grid-units((#i - 1));
}
.generate-grid-units(#num-columns);
.grid-1 {
width:100%;
}
}
To clarify:
the loop only runs when #i > 1
.grid-1 is set manually
#num-columns is actualy used to generate the grid
width: ((100% / #i) - #column-gutter-width); now outputs final value rather than an expression

What to do to make "onEntered" working?

I have a custom QDeclarativeItem subclass named Polygon.
I add a MouseArea in it but onEntered or onPressed does not working, or am i expect wrong thing to happen? I can see my polygons on the window but nothing is writing on console onPressed or onEntered.
Here is QML file:
import MyTypes 1.0
import QtQuick 1.0
import Qt 4.7
Item {
id: container
width: 350; height: 250
Polygon {
id: aPolygon
width: 20; height: 20
name: "A simple polygon"
color: "blue"
vertices:[
Point{x:20.0; y:40.0},
Point{x:40.0; y:40.0},
Point{x:40.0; y:20.0},
Point{x:20.0; y:20.0}
]
MouseArea{
anchors.fill: parent
drag.target: aPolygon
drag.axis: Drag.XandYAxis
drag.minimumX: 0
drag.maximumX: container.width - parent.width
drag.minimumY: 0
drag.maximumY: container.height - parent.width
onPressed:console.log("============== ==onPressed")
}
}
Polygon {
id: bPolygon
//anchors.centerIn: parent
width: 20; height: 20
name: "A simple polygon"
color: "blue"
vertices:[
Point{x:60.0; y:80.0},
Point{x:80.0; y:80.0},
Point{x:80.0; y:60.0},
Point{x:60.0; y:60.0}
]
MouseArea{
//hoverEnabled: false
enabled: visible
hoverEnabled: visible
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onEntered: {
console.log("============== ==onEntered")
}
}
}
}
Thanks for any idea.
Edit:
polygon.cpp
#include "polygon.h"
#include "point.h"
#include <QPainter>
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <QGraphicsSceneDragDropEvent>
#include <QFocusEvent>
#include "DeclarativeDragDropEvent.h"
using namespace std;
using namespace Qt;
Polygon::Polygon(QDeclarativeItem *parent)
: QDeclarativeItem(parent)
{
// need to disable this flag to draw inside a QDeclarativeItem
//setFlag(QDeclarativeItem::ItemHasNoContents, false);
setFlags(ItemIsSelectable|ItemIsMovable|ItemIsFocusable);
setAcceptDrops(true);
setAcceptedMouseButtons( Qt::LeftButton );
}
/*void Polygon::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
forceActiveFocus();
}
void Polygon::focusOutEvent(QFocusEvent *event)
{
cout<<"focusout"<<endl;
this->setSelected( false );
}*/
/*QVariant Polygon::itemChange(GraphicsItemChange change, const QVariant &value)
{
return QGraphicsItem::itemChange(change, value);
}*/
/*void Polygon::focusInEvent ( QFocusEvent * event ){
cout<<"focusin"<<endl;
}*/
QRectF Polygon::boundingRect() const{
QVector<QPointF> vPnt=listToVector(m_vertices);
return QPolygonF(vPnt).boundingRect();
}
QPainterPath Polygon::shape () const
{
QPainterPath path;
QVector<QPointF> vPnt=listToVector(m_vertices);
path.addPolygon(QPolygonF(vPnt));
return path;
}
QString Polygon::name() const
{
return m_name;
}
void Polygon::setName(const QString &name)
{
m_name = name;
}
QColor Polygon::color() const
{
return m_color;
}
void Polygon::setColor(const QColor &color)
{
m_color = color;
}
void Polygon::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
QPen pen(m_color, 2);
painter->setPen(pen);
painter->setRenderHints(QPainter::Antialiasing, true);
QVector<QPointF> vPnt=listToVector(m_vertices);
painter->setBrush(QBrush(m_color,Qt::SolidPattern));
painter-> drawPolygon(QPolygonF(vPnt),Qt::OddEvenFill);
}
QVector<QPointF> Polygon:: listToVector(QList<Point *> lpnt) const{
QVector<QPointF> vPnt;
for(int i=0;i<lpnt.length();i++){
vPnt.append(QPointF(lpnt.at(i)->x(),lpnt.at(i)->y()));
}
return vPnt;
}
QDeclarativeListProperty<Point> Polygon::vertices()
{
return QDeclarativeListProperty<Point>(this, 0, &Polygon::append_vertex);
}
void Polygon::append_vertex(QDeclarativeListProperty<Point> *list, Point *vertex)
{
Polygon *polygon = qobject_cast<Polygon *>(list->object);
if (polygon) {
vertex->setParentItem(polygon);
polygon->m_vertices.append(vertex);
}
}
I believe you should set hoverEnabled to true, or is this intentionally set to visible? visible is a boolean property which might be false for a MouseArea.
MouseArea {
hoverEnabled: true
}
The same goes for enabled: visible