Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions spec/grid_template_columns_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require "./spec_helper"

module CSS::GridTemplateColumnsSpec
class Style < CSS::Stylesheet
rule div do
grid_template_columns :none
grid_template_columns line_names(:start), 1.fr, line_names(:end)
grid_template_columns minmax(120.px, 1.fr), fit_content(240.px)
grid_template_columns repeat(3, line_names(:col_start), 1.fr, line_names(:col_end))
grid_template_columns repeat(:auto_fit, 200.px)
grid_template_columns repeat(:auto_fit, minmax(min(380.px, 100.percent), 1.fr))
grid_template_columns :subgrid, line_names(:alpha, :beta), repeat(2, line_names(:gamma))
grid_template_columns :masonry
end
end

describe "Style.to_s" do
it "renders grid-template-columns values" do
expected = <<-CSS
div {
grid-template-columns: none;
grid-template-columns: [start] 1fr [end];
grid-template-columns: minmax(120px, 1fr) fit-content(240px);
grid-template-columns: repeat(3, [col_start] 1fr [col_end]);
grid-template-columns: repeat(auto-fit, 200px);
grid-template-columns: repeat(auto-fit, minmax(min(380px, 100%), 1fr));
grid-template-columns: subgrid [alpha beta] repeat(2, [gamma]);
grid-template-columns: masonry;
}
CSS

Style.to_s.should eq(expected)
end
end
end
29 changes: 29 additions & 0 deletions spec/grid_template_rows_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require "./spec_helper"

module CSS::GridTemplateRowsSpec
class Style < CSS::Stylesheet
rule div do
grid_template_rows :none
grid_template_rows line_names(:start), 1.fr, line_names(:end)
grid_template_rows repeat(:auto_fit, minmax(min(380.px, 100.percent), 1.fr))
grid_template_rows :subgrid, line_names(:alpha, :beta), repeat(2, line_names(:gamma))
grid_template_rows :masonry
end
end

describe "Style.to_s" do
it "renders grid-template-rows values" do
expected = <<-CSS
div {
grid-template-rows: none;
grid-template-rows: [start] 1fr [end];
grid-template-rows: repeat(auto-fit, minmax(min(380px, 100%), 1fr));
grid-template-rows: subgrid [alpha beta] repeat(2, [gamma]);
grid-template-rows: masonry;
}
CSS

Style.to_s.should eq(expected)
end
end
end
3 changes: 2 additions & 1 deletion src/css/calc_function_call.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ require "./function_call"
require "./calculation"

module CSS
struct CalcFunctionCall < FunctionCall
struct CalcFunctionCall
include FunctionCall
getter calculation : Calculation

def initialize(@calculation)
Expand Down
4 changes: 4 additions & 0 deletions src/css/enums/grid_auto_repeat.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
css_enum GridAutoRepeat do
AutoFill
AutoFit
end
5 changes: 5 additions & 0 deletions src/css/enums/grid_track_keyword.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
css_enum GridTrackKeyword do
MinContent
MaxContent
Auto
end
3 changes: 3 additions & 0 deletions src/css/enums/masonry.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
css_enum Masonry do
Masonry
end
3 changes: 3 additions & 0 deletions src/css/enums/subgrid.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
css_enum Subgrid do
Subgrid
end
2 changes: 1 addition & 1 deletion src/css/function_call.cr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module CSS
abstract struct FunctionCall
module FunctionCall
abstract def function_name : String
abstract def arguments : String

Expand Down
181 changes: 181 additions & 0 deletions src/css/grid_template_columns.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
require "./function_call"
require "./min_function_call"

module CSS
alias GridLineName = String | Symbol

struct GridLineNames
getter names : Array(String)

def initialize(*names : GridLineName)
@names = names.map(&.to_s).to_a
end

def to_s(io : IO)
io << "["
io << names.join(" ")
io << "]"
end

def to_css_value
to_s
end
end

alias GridLengthUnit = CmValue | MmValue | InValue | PxValue | PtValue | PcValue | EmValue | RemValue | ExValue | ChValue | LhValue | RlhValue | VhValue | VwValue | VmaxValue | VminValue | SvwValue | SvhValue | LvwValue | LvhValue | DvwValue | DvhValue
alias GridLength = GridLengthUnit | Int32 | CalcFunctionCall
alias GridLengthPercentage = GridLength | PercentValue | CalcFunctionCall | MinFunctionCall

alias GridTrackBreadth = GridLengthPercentage | CSS::FrValue | CSS::Enums::GridTrackKeyword
alias GridInflexibleBreadth = GridLengthPercentage | CSS::Enums::GridTrackKeyword
alias GridFixedBreadth = GridLengthPercentage

struct GridMinmaxFunctionCall
include FunctionCall
getter min : GridInflexibleBreadth
getter max : GridTrackBreadth

def initialize(@min : GridInflexibleBreadth, @max : GridTrackBreadth)
end

def function_name : String
"minmax"
end

def arguments : String
"#{min.to_css_value}, #{max.to_css_value}"
end
end

struct GridMinmaxFixedFunctionCall
include FunctionCall
getter min : GridFixedBreadth | GridInflexibleBreadth
getter max : GridTrackBreadth | GridFixedBreadth

def initialize(@min : GridFixedBreadth, @max : GridTrackBreadth)
end

def initialize(@min : GridInflexibleBreadth, @max : GridFixedBreadth)
end

def function_name : String
"minmax"
end

def arguments : String
"#{min.to_css_value}, #{max.to_css_value}"
end
end

struct GridFitContentFunctionCall
include FunctionCall
getter size : GridLengthPercentage

def initialize(@size : GridLengthPercentage)
end

def function_name : String
"fit-content"
end

def arguments : String
size.to_css_value.to_s
end
end

alias GridTrackSize = GridTrackBreadth | GridMinmaxFunctionCall | GridMinmaxFixedFunctionCall | GridFitContentFunctionCall
alias GridFixedSize = GridFixedBreadth | GridMinmaxFixedFunctionCall

alias GridRepeatTrackItem = GridLineNames | GridTrackSize
alias GridRepeatFixedItem = GridLineNames | GridFixedSize

struct GridTrackRepeatFunctionCall
include FunctionCall
getter count : Int32
getter tracks : Array(GridRepeatTrackItem)

def initialize(@count : Int32, *tracks : GridRepeatTrackItem)
@tracks = tracks.map(&.as(GridRepeatTrackItem)).to_a
validate_tracks
end

def function_name : String
"repeat"
end

def arguments : String
"#{count.to_css_value}, #{format_tracks(tracks)}"
end

private def validate_tracks
has_track_size = tracks.any? { |item| item.is_a?(GridTrackSize) }
raise ArgumentError.new("repeat() requires at least one track size") unless has_track_size
end

private def format_tracks(values)
values.map(&.to_css_value).join(" ")
end
end

struct GridAutoRepeatFunctionCall
include FunctionCall
getter count : CSS::Enums::GridAutoRepeat
getter tracks : Array(GridRepeatFixedItem)

def initialize(@count : CSS::Enums::GridAutoRepeat, *tracks : GridRepeatFixedItem)
@tracks = tracks.map(&.as(GridRepeatFixedItem)).to_a
validate_tracks
end

def function_name : String
"repeat"
end

def arguments : String
"#{count.to_css_value}, #{format_tracks(tracks)}"
end

private def validate_tracks
has_track_size = tracks.any? { |item| item.is_a?(GridFixedSize) }
raise ArgumentError.new("repeat(auto-fill/auto-fit, ...) requires at least one fixed track size") unless has_track_size
end

private def format_tracks(values)
values.map(&.to_css_value).join(" ")
end
end

struct GridNameRepeatFunctionCall
include FunctionCall
getter count : Int32 | CSS::Enums::GridAutoRepeat
getter names : Array(GridLineNames)

def initialize(@count, *names : GridLineNames)
@names = names.map(&.as(GridLineNames)).to_a
validate_names
end

def function_name : String
"repeat"
end

def arguments : String
"#{count.to_css_value}, #{format_tracks(names)}"
end

private def validate_names
raise ArgumentError.new("repeat() requires at least one line name group") if names.empty?

if count.is_a?(CSS::Enums::GridAutoRepeat) && count == CSS::Enums::GridAutoRepeat::AutoFit
raise ArgumentError.new("repeat(auto-fit, <line-names>+) is not allowed")
end
end

private def format_tracks(values)
values.map(&.to_css_value).join(" ")
end
end

alias GridTrackListValue = GridLineNames | GridTrackSize | GridTrackRepeatFunctionCall | GridAutoRepeatFunctionCall | GridNameRepeatFunctionCall
alias GridLineNameListItem = GridLineNames | GridNameRepeatFunctionCall
end
3 changes: 2 additions & 1 deletion src/css/linear_gradient_function_call.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ module CSS
# comma-separated segment. To group multiple tokens inside a single
# segment (e.g. a color stop like `red 10%`), pass a `Tuple`; its items
# are joined with spaces.
struct LinearGradientFunctionCall < FunctionCall
struct LinearGradientFunctionCall
include FunctionCall
getter arguments : String

def initialize(*values)
Expand Down
3 changes: 2 additions & 1 deletion src/css/local_function_call.cr
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
require "./function_call"

module CSS
struct LocalFunctionCall < FunctionCall
struct LocalFunctionCall
include FunctionCall
getter name : String

def initialize(@name)
Expand Down
29 changes: 29 additions & 0 deletions src/css/min_function_call.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require "./function_call"

module CSS
# Represents a `min()` function call.
struct MinFunctionCall
include FunctionCall

getter arguments : String

def initialize(*values)
@arguments = build_arguments(values)
end

def function_name : String
"min"
end

private def build_arguments(values : Tuple) : String
values.map { |value| format(value) }.join(", ")
end

private def format(value) : String
return value if value.is_a?(String)
return value.to_css_value.to_s if value.responds_to?(:to_css_value)

value.to_s
end
end
end
3 changes: 2 additions & 1 deletion src/css/radial_gradient_function_call.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ module CSS
# comma-separated segment. To group multiple tokens inside a single
# segment (e.g. a color stop like `red 10%`), pass a `Tuple`; its items
# are joined with spaces.
struct RadialGradientFunctionCall < FunctionCall
struct RadialGradientFunctionCall
include FunctionCall
getter arguments : String

def initialize(*values)
Expand Down
3 changes: 2 additions & 1 deletion src/css/rgb_function_call.cr
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
require "./function_call"

module CSS
struct RgbFunctionCall < FunctionCall
struct RgbFunctionCall
include FunctionCall
getter red : Int32
getter green : Int32
getter blue : Int32
Expand Down
3 changes: 2 additions & 1 deletion src/css/transform_function_call.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ require "./function_call"

module CSS
# Represents a CSS transform function call such as rotateX() or translate().
struct TransformFunctionCall < FunctionCall
struct TransformFunctionCall
include FunctionCall
getter function_name : String
getter arguments : String

Expand Down
3 changes: 2 additions & 1 deletion src/css/url_function_call.cr
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
require "./function_call"

module CSS
struct UrlFunctionCall < FunctionCall
struct UrlFunctionCall
include FunctionCall
getter url : String

def initialize(@url)
Expand Down
Loading