Stylus - o poder das funções

Funções são bastante parecidas com mixins, no Stylus. A grande diferença é que elas podem retornar valores! Vamos ver como elas funcionam? ;)

Podemos, por exemplo, criar uma função que soma dois valores passados como argumento:

1
2
3
4
5
add( a, b )
a + b

.wrapper
width add( 600px, 15 )

Que compila para:

1
2
3
.wrapper {
width: 615px;
}

Valores padrão

Podemos também passar valores default para os argumentos:

1
2
3
4
5
6
add( a, b = a )
a + b

add( 10, 5 ) // => 15

add( 10 ) // => 20

Os valores default dos argumentos nada mais são do que atribuições. Logo, nós podemos também passar funções como valores default:

1
2
3
4
add( a, b = unit( a, px ) )
a + b

add( 20 ) // => 40px

Repare que o resultado de add( 20 ) não é 20px, e sim 40px. A função unit() faz parte do Stylus. Ela adiciona uma unidade de medida ao valor passado no primeiro parâmetro. O que nós estamos fazendo é atribuir para b, o valor passado para a, e ainda adicionando a unidade px.

Já conseguiu imaginar as milhões de possibilidades que você pode fazer com isso? xD

Parâmetros nomeados

Podemos também passar valores específicos para as funções. Veja o exemplo:

1
2
3
4
subtract( a, b )
a - b

subtract( b: 10, a: 20 ) // => 10

Se nós somente passássemos os valores ( 10, 20 ) para a função subtract, o resultado seria -10. Mas nós podemos nomear os valores, não necessitando assim passar os parâmetros na mesma ordem em que foram definidos na função. Por isso o resultado é 10 positivo. :D

Você ainda pode passar apenas um dos valores. Se o outro não for passado, ele será undefined, então podemos utilizar valores padrão para os parâmetros que não são obrigatórios:

1
2
3
4
subtract( a = 5, b )
a - b

subtract( b: 2 ) // => 3

Locurage! :D

Retorno de múltiplos valores

Podemos retornar valores como se estivéssemos usando um array em JS. Se atribuirmos vários valores à uma variável, usamos a notação de array para obter um valor. Exemplo:

1
2
3
sizes = 15px 20px

sizes[0] // => 15px

O mesmo vale para funções. A diferença é que precisamos invocá-la antes de pegar o valor:

1
2
3
4
sizes()
15px 10px

sizes()[1] // => 10px

Uma exceção para esses casos, é quando os valores de retorno são identificadores.

No exemplo abaixo, os valores de retorno podem se confundir com atribuições para propriedades:

1
2
3
4
5
swap( a, b )
b a

body
swap(10, 20)

Se fizermos isso, tentando usar swap como mixin, temos como resultado:

1
2
3
body {
b: 10;
}

E se tentarmos usar como função, retornando um valor:

1
2
body
width swap( 10, 20 )

Temos como resultado:

1
2
3
body {
width: b: 10;;
}

Ou seja: Nada a ver, né meu!

Para remover a ambiguidade, você pode usar parênteses, ou então a palavra-chave return:

1
2
3
4
5
swap( a, b )
( b a )

body
padding swap( 10px, 20px )

Que retorna:

1
2
3
body {
padding: 20px 10px;
}

Ou ainda, usando return:

1
2
3
4
5
swap( a, b )
return b a

body
padding swap( 10px, 20px )

O resultado é o mesmo :)

Funções como parâmetro

Também é possível usar funções como parâmetros, para usar como um callback:

1
2
3
4
5
6
7
8
9
10
11
12
add( a, b )
a + b

sub( a, b )
a - b

invoke( a, b, fn )
fn( a, b )

body
padding invoke( 10px, 20, add )
margin invoke( 8px, 5, sub )

Que vai compilar para:

1
2
3
4
body {
padding: 30px;
margin: 3px;
}

E isso é apenas o começo do que você pode fazer usando funções no Stylus! Para conhecer todas as possibilidades, visite a documentação oficial, na sessão de functions :D

Até o próximo!

Sobre o #1postperday: https://blog.da2k.com.br/2014/12/31/um-post-por-dia/

Tem alguma sugestão para os próximos posts do #1postperday? Deixe ela aqui: https://github.com/fdaciuk/fdaciuk.github.io/issues/1