
commonMain.kotlinx.css.StyleEnums.kt Maven / Gradle / Ivy
@file:Suppress("EnumEntryName")
package kotlinx.css
import kotlin.math.PI
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.roundToInt
abstract class CssValue(open val value: String) {
override fun toString() = value
}
enum class Align {
initial, inherit, unset,
auto, stretch, center, start, end, selfStart, selfEnd, flexStart, flexEnd, baseline;
override fun toString() = name.hyphenize()
}
enum class Appearance {
none,
auto,
menulistButton,
textfield,
button,
searchfield,
textarea,
pushButton,
sliderHorizontal,
checkbox,
radio,
squareButton,
menulist,
listbox,
meter,
progressBar;
override fun toString() = name.hyphenize()
}
enum class Isolation {
initial, inherit, revert, unset,
auto, isolate;
}
enum class JustifyContent {
initial, inherit, unset,
center,
start,
end,
flexStart,
flexEnd,
left,
right,
baseline,
firstBaseline,
lastBaseline,
spaceBetween,
spaceAround,
spaceEvenly,
stretch,
safeCenter,
unsafeCenter;
override fun toString() = name.hyphenize()
}
enum class JustifyItems {
initial, inherit, unset,
auto,
normal,
stretch,
center,
start,
end,
flexStart,
flexEnd,
selfStart,
selfEnd,
left,
right,
baseline;
override fun toString() = name.hyphenize()
}
enum class BackgroundRepeat {
initial, inherit, unset,
repeatX, repeatY, repeat, noRepeat;
override fun toString() = name.hyphenize()
}
enum class BackgroundAttachment {
initial, inherit, unset,
scroll, fixed, local;
}
enum class BackgroundClip {
initial, inherit, unset,
borderBox, paddingBox, contentBox, text;
override fun toString() = name.hyphenize()
}
enum class BackgroundOrigin {
initial, inherit, unset,
borderBox, paddingBox, contentBox;
override fun toString() = name.hyphenize()
}
enum class BorderCollapse {
initial, inherit, unset,
separate, collapse;
}
enum class BorderStyle {
initial, inherit, unset,
none, dotted, dashed, solid;
}
enum class BoxSizing {
initial, inherit, unset,
contentBox, borderBox;
override fun toString() = name.hyphenize()
}
enum class Clear {
initial, inherit, unset,
none, left, right, both;
}
/**
* See [CSS Color Module Level 3](https://www.w3.org/TR/2018/REC-css-color-3-20180619/)
*
* This class represents a CSS color value. String parameters to the constructor argument
* can take one of the following forms:
*
* * HTML color name, e.g. ``Red``, ``DarkSalmon`` (case-insensitive), though in this case the use of the pre-defined constants is recommended.
* * ``#rgb`` or ``#rrggbb``
* * ``rgb(0..255, 0..255, 0..255)``, ``rgb(0..100%, 0..100%, 0..100%)``, ``rgb(0..100%, 0..100%, 0..100%, 0..1)``, ``rgba(0..255, 0..255, 0..255, 0..1)``
* * ``hsl(0..360, 0-100%, 0..100%)`` or ``hsla(0..360, 0-100%, 0..100%, 0..1)``
*
* Technically, the Hue parameter to ``hsl`` or ``hsla`` can exceed ``360``, because it represents a *degree* (angle) on
* the color wheel. But as per the algorithm proposed by the W3C, the value will ultimately be capped to ``360`` through
* a series of modulus operations; see section *4.2.4. HSL color values* of the above specification.
*/
@Suppress("SpellCheckingInspection")
class Color(override val value: String) : CssValue(value) {
private var rgb: String? = null
private constructor(value: String, rgb: String) : this(value) {
this.rgb = rgb
}
companion object {
val initial = Color("initial")
val inherit = Color("inherit")
val unset = Color("unset")
val transparent = Color("transparent")
val currentColor = Color("currentColor")
// W3C predefined HTML colors (147), see the referenced specification above.
val aliceBlue = Color("aliceblue", "#f0f8ff")
val antiqueWhite = Color("antiquewhite", "#faebd7")
val aqua = Color("aqua", "#00ffff")
val aquamarine = Color("aquamarine", "#7fffd4")
val azure = Color("azure", "#f0ffff")
val beige = Color("beige", "#f5f5dc")
val bisque = Color("bisque", "#ffe4c4")
val black = Color("black", "#000000")
val blanchedAlmond = Color("blanchedalmond", "#ffebcd")
val blue = Color("blue", "#0000ff")
val blueViolet = Color("blueviolet", "#8a2be2")
val brown = Color("brown", "#a52a2a")
val burlyWood = Color("burlywood", "#deb887")
val cadetBlue = Color("cadetblue", "#5f9ea0")
val chartreuse = Color("chartreuse", "#7fff00")
val chocolate = Color("chocolate", "#d2691e")
val coral = Color("coral", "#ff7f50")
val cornflowerBlue = Color("cornflowerblue", "#6495ed")
val cornsilk = Color("cornsilk", "#fff8dc")
val crimson = Color("crimson", "#dc143c")
val cyan = Color("cyan", "#00ffff")
val darkBlue = Color("darkblue", "#00008b")
val darkCyan = Color("darkcyan", "#008b8b")
val darkGoldenrod = Color("darkgoldenrod", "#b8860b")
val darkGray = Color("darkgray", "#a9a9a9")
val darkGreen = Color("darkgreen", "#006400")
val darkGrey = Color("darkgrey", "#a9a9a9")
val darkKhaki = Color("darkkhaki", "#bdb76b")
val darkMagenta = Color("darkmagenta", "#8b008b")
val darkOliveGreen = Color("darkolivegreen", "#556b2f")
val darkOrange = Color("darkorange", "#ff8c00")
val darkOrchid = Color("darkorchid", "#9932cc")
val darkRed = Color("darkred", "#8b0000")
val darkSalmon = Color("darksalmon", "#e9967a")
val darkSeaGreen = Color("darkseagreen", "#8fbc8f")
val darkSlateBlue = Color("darkslateblue", "#483d8b")
val darkSlateGray = Color("darkslategray", "#2f4f4f")
val darkSlateGrey = Color("darkslategrey", "#2f4f4f")
val darkTurquoise = Color("darkturquoise", "#00ced1")
val darkViolet = Color("darkviolet", "#9400d3")
val deepPink = Color("deeppink", "#ff1493")
val deepSkyBlue = Color("deepskyblue", "#00bfff")
val dimGray = Color("dimgray", "#696969")
val dimGrey = Color("dimgrey", "#696969")
val dodgerBlue = Color("dodgerblue", "#1e90ff")
val firebrick = Color("firebrick", "#b22222")
val floralWhite = Color("floralwhite", "#fffaf0")
val forestGreen = Color("forestgreen", "#228b22")
val fuchsia = Color("fuchsia", "#ff00ff")
val gainsboro = Color("gainsboro", "#dcdcdc")
val ghostWhite = Color("ghostwhite", "#f8f8ff")
val gold = Color("gold", "#ffd700")
val goldenrod = Color("goldenrod", "#daa520")
val gray = Color("gray", "#808080")
val green = Color("green", "#008000")
val greenYellow = Color("greenyellow", "#adff2f")
val grey = Color("grey", "#808080")
val honeydew = Color("honeydew", "#f0fff0")
val hotPink = Color("hotpink", "#ff69b4")
val indianRed = Color("indianred", "#cd5c5c")
val indigo = Color("indigo", "#4b0082")
val ivory = Color("ivory", "#fffff0")
val khaki = Color("khaki", "#f0e68c")
val lavender = Color("lavender", "#e6e6fa")
val lavenderBlush = Color("lavenderblush", "#fff0f5")
val lawnGreen = Color("lawngreen", "#7cfc00")
val lemonChiffon = Color("lemonchiffon", "#fffacd")
val lightBlue = Color("lightblue", "#add8e6")
val lightCoral = Color("lightcoral", "#f08080")
val lightCyan = Color("lightcyan", "#e0ffff")
val lightGoldenrodYellow = Color("lightgoldenrodyellow", "#fafad2")
val lightGray = Color("lightgray", "#d3d3d3")
val lightGreen = Color("lightgreen", "#90ee90")
val lightGrey = Color("lightgrey", "#d3d3d3")
val lightPink = Color("lightpink", "#ffb6c1")
val lightSalmon = Color("lightsalmon", "#ffa07a")
val lightSeaGreen = Color("lightseagreen", "#20b2aa")
val lightSkyBlue = Color("lightskyblue", "#87cefa")
val lightSlateGray = Color("lightslategray", "#778899")
val lightSlateGrey = Color("lightslategrey", "#778899")
val lightSteelBlue = Color("lightsteelblue", "#b0c4de")
val lightYellow = Color("lightyellow", "#ffffe0")
val lime = Color("lime", "#00ff00")
val limeGreen = Color("limegreen", "#32cd32")
val linen = Color("linen", "#faf0e6")
val magenta = Color("magenta", "#ff00ff")
val maroon = Color("maroon", "#800000")
val mediumAquamarine = Color("mediumaquamarine", "#66cdaa")
val mediumBlue = Color("mediumblue", "#0000cd")
val mediumOrchid = Color("mediumorchid", "#ba55d3")
val mediumPurple = Color("mediumpurple", "#9370d8")
val mediumSeaGreen = Color("mediumseagreen", "#3cb371")
val mediumSlateBlue = Color("mediumslateblue", "#7b68ee")
val mediumSpringGreen = Color("mediumspringgreen", "#00fa9a")
val mediumTurquoise = Color("mediumturquoise", "#48d1cc")
val mediumVioletRed = Color("mediumvioletred", "#c71585")
val midnightBlue = Color("midnightblue", "#191970")
val mintCream = Color("mintcream", "#f5fffa")
val mistyRose = Color("mistyrose", "#ffe4e1")
val moccasin = Color("moccasin", "#ffe4b5")
val navajoWhite = Color("navajowhite", "#ffdead")
val navy = Color("navy", "#000080")
val oldLace = Color("oldlace", "#fdf5e6")
val olive = Color("olive", "#808000")
val oliveDrab = Color("olivedrab", "#6b8e23")
val orange = Color("orange", "#ffa500")
val orangeRed = Color("orangered", "#ff4500")
val orchid = Color("orchid", "#da70d6")
val paleGoldenrod = Color("palegoldenrod", "#eee8aa")
val paleGreen = Color("palegreen", "#98fb98")
val paleTurquoise = Color("paleturquoise", "#afeeee")
val paleVioletRed = Color("palevioletred", "#db7093")
val papayaWhip = Color("papayawhip", "#ffefd5")
val peachPuff = Color("peachpuff", "#ffdab9")
val peru = Color("peru", "#cd853f")
val pink = Color("pink", "#ffc0cb")
val plum = Color("plum", "#dda0dd")
val powderBlue = Color("powderblue", "#b0e0e6")
val purple = Color("purple", "#800080")
val red = Color("red", "#ff0000")
val rosyBrown = Color("rosybrown", "#bc8f8f")
val royalBlue = Color("royalblue", "#4169e1")
val saddleBrown = Color("saddlebrown", "#8b4513")
val salmon = Color("salmon", "#fa8072")
val sandyBrown = Color("sandybrown", "#f4a460")
val seaGreen = Color("seagreen", "#2e8b57")
val seaShell = Color("seashell", "#fff5ee")
val sienna = Color("sienna", "#a0522d")
val silver = Color("silver", "#c0c0c0")
val skyBlue = Color("skyblue", "#87ceeb")
val slateBlue = Color("slateblue", "#6a5acd")
val slateGray = Color("slategray", "#708090")
val slateGrey = Color("slategrey", "#708090")
val snow = Color("snow", "#fffafa")
val springGreen = Color("springgreen", "#00ff7f")
val steelBlue = Color("steelblue", "#4682b4")
val tan = Color("tan", "#d2b48c")
val teal = Color("teal", "#008080")
val thistle = Color("thistle", "#d8bfd8")
val tomato = Color("tomato", "#ff6347")
val turquoise = Color("turquoise", "#40e0d0")
val violet = Color("violet", "#ee82ee")
val wheat = Color("wheat", "#f5deb3")
val white = Color("white", "#ffffff")
val whiteSmoke = Color("whitesmoke", "#f5f5f5")
val yellow = Color("yellow", "#ffff00")
val yellowGreen = Color("yellowgreen", "#9acd32")
fun normalizeFractionalPercent(value: Double): Double =
value.coerceIn(minimumValue = 0.0, maximumValue = 1.0)
fun normalizePercent(value: Int): Int =
value.coerceIn(minimumValue = 0, maximumValue = 100)
fun normalizeRGB(value: Int): Int =
value.coerceIn(minimumValue = 0, maximumValue = 255)
// algorithm for capping from W3C
fun normalizeHue(value: Double): Int =
(((value % 360) + 360) % 360).roundToInt()
fun normalizeAlpha(value: Double): Double =
normalizeFractionalPercent(value)
// Match for hsl(int, int%, int%) | hsla(int, int%, int%, 0.5) | etc.
private val HSLA_REGEX by lazy {
Regex(
"^hsla?\\((-?[0-9]+\\.?[0-9]*(?:deg|grad|rad|turn)?)\\s*[, ]?\\s*(\\d{1,3})%\\s*[, ]\\s*(\\d{1,3})%\\s*[, ]?\\s*(\\d|(?:\\d?\\.\\d+))?\\)\$",
RegexOption.IGNORE_CASE
)
}
// Match for rgb(255, 255, 255) | rgba(255, 255, 255, 0.5) | rgb(100% 100% 100%) | etc.
private val RGBA_REGEX by lazy {
Regex(
"^rgba?\\((\\d{1,3}%?)\\s*[, ]\\s*(\\d{1,3}%?)\\s*[, ]\\s*(\\d{1,3}%?)[, ]?\\s*(\\d|(?:\\d?\\.\\d+))?\\)\$",
RegexOption.IGNORE_CASE
)
}
}
/**
* withAlpha preserves existing alpha value: rgba(0, 0, 0, 0.5).withAlpha(0.1) = rgba(0, 0, 0, 0.05)
*/
fun withAlpha(alpha: Double) =
when {
value.startsWith("hsl", true) -> with(fromHSLANotation()) { hsla(hue, saturation, lightness, normalizeAlpha(alpha) * this.alpha) }
else -> with(toRGBA()) { rgba(red, green, blue, normalizeAlpha(alpha) * this.alpha) }
}
/**
* changeAlpha rewrites existing alpha value: rgba(0, 0, 0, 0.5).withAlpha(0.1) = rgba(0, 0, 0, 0.1)
*/
fun changeAlpha(alpha: Double) =
when {
value.startsWith("hsl", true) -> with(fromHSLANotation()) { hsla(hue, saturation, lightness, normalizeAlpha(alpha)) }
else -> with(toRGBA()) { rgba(red, green, blue, normalizeAlpha(alpha)) }
}
// https://stackoverflow.com/questions/2049230/convert-rgba-color-to-rgb
fun blend(backgroundColor: Color): Color {
val source = this.toRGBA()
val background = backgroundColor.toRGBA()
val targetR = ((1 - source.alpha) * background.red) + (source.alpha * source.red)
val targetG = ((1 - source.alpha) * background.green) + (source.alpha * source.green)
val targetB = ((1 - source.alpha) * background.blue) + (source.alpha * source.blue)
return rgb(targetR.roundToInt(), targetG.roundToInt(), targetB.roundToInt())
}
/**
* Lighten the color by the specified percent (between 0-100), returning a new instance of Color.
*
* @param percent the percent to lighten the Color
* @return a new lightened version of this color
*/
fun lighten(percent: Int): Color {
val isHSLA = value.startsWith("hsl", ignoreCase = true)
val hsla = if (isHSLA) fromHSLANotation() else toRGBA().asHSLA()
val lightness = hsla.lightness + (hsla.lightness * (normalizePercent(percent) / 100.0)).roundToInt()
val newHSLa = hsla.copy(lightness = normalizePercent(lightness))
return if (isHSLA) {
hsla(newHSLa.hue, newHSLa.saturation, newHSLa.lightness, newHSLa.alpha)
} else {
with(newHSLa.asRGBA()) { rgba(red, green, blue, alpha) }
}
}
/**
* Darken the color by the specified percent (between 0-100), returning a new instance of Color.
*
* @param percent the percent to darken the Color
* @return a new darkened version of this color
*/
fun darken(percent: Int): Color {
val isHSLA = value.startsWith("hsl", ignoreCase = true)
val hsla = if (isHSLA) fromHSLANotation() else toRGBA().asHSLA()
val darkness = hsla.lightness - (hsla.lightness * (normalizePercent(percent) / 100.0)).roundToInt()
val newHSLa = hsla.copy(lightness = normalizePercent(darkness))
return if (isHSLA) {
hsla(newHSLa.hue, newHSLa.saturation, newHSLa.lightness, newHSLa.alpha)
} else {
with(newHSLa.asRGBA()) { rgba(red, green, blue, alpha) }
}
}
/**
* Saturate the color by the specified percent (between 0-100), returning a new instance of Color.
*
* @param percent the percent to saturate the Color
* @return a new saturated version of this color
*/
fun saturate(percent: Int): Color {
val isHSLA = value.startsWith("hsl", ignoreCase = true)
val hsla = if (isHSLA) fromHSLANotation() else toRGBA().asHSLA()
val saturation = hsla.saturation + (hsla.saturation * (normalizePercent(percent) / 100.0)).roundToInt()
val newHSLa = hsla.copy(saturation = normalizePercent(saturation))
return if (isHSLA) {
hsla(newHSLa.hue, newHSLa.saturation, newHSLa.lightness, newHSLa.alpha)
} else {
with(newHSLa.asRGBA()) { rgba(red, green, blue, alpha) }
}
}
/**
* Desaturate the color by the specified percent (between 0-100), returning a new instance of Color.
*
* @param percent the percent to desaturate the Color
* @return a new desaturated version of this color
*/
fun desaturate(percent: Int): Color {
val isHSLA = value.startsWith("hsl", ignoreCase = true)
val hsla = if (isHSLA) fromHSLANotation() else toRGBA().asHSLA()
val desaturation = hsla.saturation - (hsla.saturation * (normalizePercent(percent) / 100.0)).roundToInt()
val newHSLa = hsla.copy(saturation = normalizePercent(desaturation))
return if (isHSLA) {
hsla(newHSLa.hue, newHSLa.saturation, newHSLa.lightness, newHSLa.alpha)
} else {
with(newHSLa.asRGBA()) { rgba(red, green, blue, alpha) }
}
}
internal data class RGBA(
val red: Int,
val green: Int,
val blue: Int,
val alpha: Double = 1.0,
) {
// Algorithm adapted from http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/
fun asHSLA(): HSLA {
// scale R, G, B values into 0..1 fractions
val r = red / 255.0
val g = green / 255.0
val b = blue / 255.0
val cMax = maxOf(r, g, b)
val cMin = minOf(r, g, b)
val chroma = cMax - cMin
val lg = normalizeFractionalPercent((cMax + cMin) / 2)
val s = if (chroma != 0.0) normalizeFractionalPercent(chroma / (1.0 - abs((2.0 * lg) - 1.0))) else 0.0
val h = when (cMax) {
cMin -> 0.0
r -> 60 * (((g - b) / chroma) % 6.0)
g -> 60 * (((b - r) / chroma) + 2)
b -> 60 * (((r - g) / chroma) + 4)
else -> error("Unexpected value for max") // theoretically unreachable bc maxOf(r, g, b) above
}
return HSLA(normalizeHue(h), (s * 100).roundToInt(), (lg * 100).roundToInt(), alpha)
}
}
internal data class HSLA(
val hue: Int,
val saturation: Int,
val lightness: Int,
val alpha: Double = 1.0,
) {
// Algorithm from W3C link referenced in class comment (section 4.2.4. HSL color values)
fun asRGBA(): RGBA {
fun hueToRGB(m1: Double, m2: Double, h: Double): Double {
val hu = if (h < 0) h + 1 else if (h > 1) h - 1 else h
return when {
(hu < 1.0 / 6) -> m1 + (m2 - m1) * 6 * hu
(hu < 1.0 / 2) -> m2
(hu < 2.0 / 3) -> m1 + ((m2 - m1) * 6 * (2.0 / 3 - hu))
else -> m1
}
}
if (saturation == 0) return RGBA(lightness, lightness, lightness)
// scale H, S, V values into 0..1 fractions
val h = (hue % 360.0) / 360.0
val s = saturation / 100.0
val lg = lightness / 100.0
val m2 = if (lg < 0.5) lg * (1 + s) else (lg + s - lg * s)
val m1 = 2 * lg - m2
val r = normalizeFractionalPercent(hueToRGB(m1, m2, h + (1.0 / 3)))
val g = normalizeFractionalPercent(hueToRGB(m1, m2, h))
val b = normalizeFractionalPercent(hueToRGB(m1, m2, h - (1.0 / 3)))
return RGBA((r * 255).roundToInt(), (g * 255).roundToInt(), (b * 255).roundToInt(), alpha)
}
}
internal fun fromHSLANotation(): HSLA {
val match = HSLA_REGEX.find(value)
fun getHSLParameter(index: Int) =
match?.groups?.get(index)?.value
?: throw IllegalArgumentException("Expected hsl or hsla notation, got $value")
val hueShape = getHSLParameter(1)
val hue = normalizeHue(
when {
hueShape.endsWith("grad", true) -> hueShape.substringBefore("grad").toDouble() * (9.0 / 10)
hueShape.endsWith("rad", true) -> (hueShape.substringBefore("rad").toDouble() * 180) / PI
hueShape.endsWith("turn", true) -> hueShape.substringBefore("turn").toDouble() * 360.0
hueShape.endsWith("deg", true) -> hueShape.substringBefore("deg").toDouble()
else -> hueShape.toDouble()
}
)
val saturation = normalizePercent(getHSLParameter(2).toInt())
val lightness = normalizePercent(getHSLParameter(3).toInt())
val alpha = normalizeAlpha(match?.groups?.get(4)?.value?.toDouble() ?: 1.0)
return HSLA(hue, saturation, lightness, alpha)
}
internal fun fromRGBANotation(): RGBA {
val match = RGBA_REGEX.find(value)
fun getRGBParameter(index: Int): Int {
val group = match?.groups?.get(index)?.value
?: throw IllegalArgumentException("Expected rgb or rgba notation, got $value")
return when {
(group.endsWith('%')) -> (normalizeFractionalPercent(group.substringBefore('%').toDouble() / 100.0) * 255.0).toInt()
else -> normalizeRGB(group.toInt())
}
}
val red = getRGBParameter(1)
val green = getRGBParameter(2)
val blue = getRGBParameter(3)
val alpha = normalizeAlpha(match?.groups?.get(4)?.value?.toDouble() ?: 1.0)
return RGBA(red, green, blue, alpha)
}
internal fun toRGBA(): RGBA {
val v = rgb ?: value
return when {
v.startsWith("rgb") -> fromRGBANotation()
// Matches #rgb
v.startsWith("#") && v.length == 4 -> RGBA(
(v[1].toString() * 2).toInt(16),
(v[2].toString() * 2).toInt(16),
(v[3].toString() * 2).toInt(16)
)
// Matches both #rrggbb and #rrggbbaa
v.startsWith("#") && (v.length == 7 || v.length == 9) -> RGBA(
(v.substring(1..2)).toInt(16),
(v.substring(3..4)).toInt(16),
(v.substring(5..6)).toInt(16)
)
else -> throw IllegalArgumentException("Only hexadecimal, rgb, and rgba notations are accepted, got $v")
}
}
}
private fun String.withZeros() = this + "0".repeat(max(0, 3 - this.length))
fun hex(value: Int) = Color("#${value.toString(16).withZeros()}")
fun rgb(red: Int, green: Int, blue: Int) = Color("rgb($red, $green, $blue)")
fun rgba(red: Int, green: Int, blue: Int, alpha: Double) = Color("rgba($red, $green, $blue, ${formatAlpha(alpha)})")
fun hsl(hue: Int, saturation: Int, lightness: Int) = Color("hsl($hue, $saturation%, $lightness%)")
fun hsla(hue: Int, saturation: Int, lightness: Int, alpha: Double) = Color("hsla($hue, $saturation%, $lightness%, ${formatAlpha(alpha)})")
fun blackAlpha(alpha: Double) = Color.black.withAlpha(alpha)
fun whiteAlpha(alpha: Double) = Color.white.withAlpha(alpha)
private fun formatAlpha(alpha: Double): String =
alpha.toString().let {
if ("." in it) it else "$it.0"
}
enum class Contain {
initial, inherit, unset,
none, strict, content, size, layout, style, paint;
}
enum class Cursor {
initial, inherit, unset,
auto, default, none, // General
contextMenu, help, pointer, progress, wait, // Links & status
cell, crosshair, text, verticalText, // Selection
alias, copy, move, noDrop, notAllowed, grab, grabbing, // Drag and drop
colResize, rowResize, allScroll, // Resize & scrolling
eResize, nResize, neResize, nwResize, sResize, seResize, swResize, wResize, // Directed resize
ewResize, nsResize, neswResize, nwseResize, // Bidirectional resize
zoomIn, zoomOut; // Zoom
override fun toString() = name.hyphenize()
}
// Enquotes the value
class QuotedString(override val value: String) : CssValue(value) {
override fun toString(): String = "'$value'"
}
val String.quoted get() = QuotedString(this)
enum class Direction {
initial, inherit, unset,
ltr, rtl;
}
enum class Display {
initial, inherit, unset,
block, `inline`, runIn,
flow, flowRoot, table, flex, grid, subgrid,
listItem,
tableRowGroup, tableHeaderGroup, tableFooterGroup, tableRow, tableCell, tableColumnGroup, tableColumn, tableCaption,
contents, none,
inlineBlock, inlineListItem, inlineTable, inlineFlex, inlineGrid;
override fun toString() = name.hyphenize()
}
class FlexBasis(override val value: String) : CssValue(value) {
companion object {
val initial = FlexBasis("initial")
val inherit = FlexBasis("inherit")
val unset = FlexBasis("unset")
val auto = FlexBasis("auto")
val content = FlexBasis("content")
val minContent = FlexBasis("min-content")
val maxContent = FlexBasis("max-content")
val fitContent = FlexBasis("fit-content")
val fill = FlexBasis("fill")
val zero = FlexBasis("0")
}
}
val LinearDimension.basis get() = FlexBasis(toString())
enum class FlexWrap {
initial, inherit, unset,
nowrap, wrap, wrapReverse;
override fun toString() = name.hyphenize()
}
enum class Float {
initial, inherit, unset,
left, right, none;
override fun toString() = name.hyphenize()
}
class FontWeight(override val value: String) : CssValue(value) {
companion object {
val initial = FontWeight("initial")
val inherit = FontWeight("inherit")
val unset = FontWeight("unset")
val normal = FontWeight("normal")
val bold = FontWeight("bold")
val bolder = FontWeight("bolder")
val lighter = FontWeight("lighter")
val w900 = FontWeight("900")
val w800 = FontWeight("800")
val w700 = FontWeight("700") // same as "bold"
val w600 = FontWeight("600")
val w500 = FontWeight("500")
val w400 = FontWeight("400") // same as "normal"
val w300 = FontWeight("300")
val w200 = FontWeight("200")
val w100 = FontWeight("100")
}
}
enum class FontStyle {
initial, inherit, unset,
normal, italic;
}
enum class FlexDirection {
initial, inherit, unset,
column, columnReverse, row, rowReverse;
override fun toString() = name.hyphenize()
}
class GridAutoColumns(override val value: String) : CssValue(value) {
constructor(vararg dims: LinearDimension) : this(dims.joinToString(" "))
constructor(vararg values: GridAutoColumns) : this(values.joinToString(" "))
companion object {
val auto = GridAutoColumns("auto")
val maxContent = GridAutoColumns("max-content")
val minContent = GridAutoColumns("min-content")
fun fitContent(argument: GridAutoColumns) = GridAutoColumns("minmax(auto, max(auto, $argument))")
fun minMax(min: LinearDimension, max: LinearDimension) = GridAutoColumns("minmax($min, $max)")
fun minMax(min: GridAutoColumns, max: GridAutoColumns) = GridAutoColumns("minmax($min, $max)")
}
}
class GridAutoFlow private constructor(override val value: String) : CssValue(value) {
companion object {
val initial = GridAutoFlow("initial")
val inherit = GridAutoFlow("inherit")
val unset = GridAutoFlow("unset")
val column = GridAutoFlow("column")
val columnDense = GridAutoFlow("column dense")
val dense = GridAutoFlow("dense")
val row = GridAutoFlow("row")
val rowDense = GridAutoFlow("row dense")
}
}
class GridAutoRows(override val value: String) : CssValue(value) {
constructor(vararg dims: LinearDimension) : this(dims.joinToString(" "))
constructor(vararg values: GridAutoRows) : this(values.joinToString(" "))
companion object {
val auto = GridAutoRows("auto")
val maxContent = GridAutoRows("max-content")
val minContent = GridAutoRows("min-content")
fun fitContent(argument: GridAutoRows) = GridAutoRows("minmax(auto, max(auto, $argument))")
fun minMax(min: LinearDimension, max: LinearDimension) = GridAutoRows("minmax($min, $max)")
fun minMax(min: GridAutoRows, max: GridAutoRows) = GridAutoRows("minmax($min, $max)")
}
}
class GridColumn(override val value: String) : CssValue(value) {
companion object {
val auto = GridColumn("auto")
}
}
class GridColumnEnd(override val value: String) : CssValue(value) {
companion object {
val auto = GridColumnEnd("auto")
}
}
class GridColumnStart(override val value: String) : CssValue(value) {
companion object {
val auto = GridColumnStart("auto")
}
}
class GridRow(override val value: String) : CssValue(value) {
companion object {
val auto = GridRow("auto")
}
}
class GridRowEnd(override val value: String) : CssValue(value) {
companion object {
val auto = GridRowEnd("auto")
}
}
class GridRowStart(override val value: String) : CssValue(value) {
companion object {
val auto = GridRowStart("auto")
}
}
class GridTemplate(override val value: String) : CssValue(value) {
companion object {
val none = GridTemplate("none")
}
}
class GridTemplateAreas(override val value: String) : CssValue(value) {
companion object {
val none = GridTemplateAreas("none")
}
}
class GridTemplateColumns(override val value: String) : CssValue(value) {
constructor(vararg dims: LinearDimension) : this(dims.joinToString(" "))
constructor(vararg values: GridAutoRows) : this(values.joinToString(" "))
companion object {
val auto = GridTemplateColumns("auto")
val maxContent = GridTemplateColumns("max-content")
val minContent = GridTemplateColumns("min-content")
val none = GridTemplateColumns("none")
fun fitContent(dim: LinearDimension) = GridTemplateColumns("min(max-content, max(auto, $dim))")
fun minMax(min: LinearDimension, max: LinearDimension) = GridTemplateColumns("minmax($min, $max)")
fun minMax(min: GridTemplateColumns, max: GridTemplateColumns) = GridTemplateColumns("minmax($min, $max)")
fun repeat(argument: String) = GridTemplateColumns("repeat($argument)")
}
}
class GridTemplateRows(override val value: String) : CssValue(value) {
constructor(vararg dims: LinearDimension) : this(dims.joinToString(" "))
constructor(vararg values: GridAutoRows) : this(values.joinToString(" "))
companion object {
val auto = GridTemplateRows("auto")
val maxContent = GridTemplateRows("max-content")
val minContent = GridTemplateRows("min-content")
val none = GridTemplateRows("none")
fun fitContent(dim: LinearDimension) = GridTemplateRows("min(max-content, max(auto, $dim))")
fun minMax(min: LinearDimension, max: LinearDimension) = GridTemplateRows("minmax($min, $max)")
fun minMax(min: GridTemplateRows, max: GridTemplateRows) = GridTemplateRows("minmax($min, $max)")
fun repeat(argument: String) = GridTemplateRows("repeat($argument)")
}
}
enum class Flex {
NONE, GROW, SHRINK, GROW_SHRINK
}
enum class Hyphens {
initial, inherit, unset,
none, manual, auto;
}
enum class ListStyleType {
initial, inherit, unset,
none, disc, circle, square, decimal;
override fun toString() = name.hyphenize()
}
enum class ObjectFit {
initial, inherit, unset,
contain, cover, fill, none, scaleDown;
override fun toString() = name.hyphenize()
}
class Order(override val value: String) : CssValue(value) {
constructor(value: Int) : this(value.toString())
companion object {
val inherit = Order("inherit")
val initial = Order("initial")
val revert = Order("revert")
val revertLayer = Order("revert-layer")
val unset = Order("unset")
}
}
enum class Outline {
initial, inherit, unset,
none;
}
enum class OutlineStyle {
inherit, initial, revert, revertLayer, unset,
auto, none, dotted, dashed, solid, double, groove, ridge, inset, outset;
override fun toString() = name.hyphenize()
}
enum class Overflow {
initial, inherit, unset,
visible, hidden, scroll, auto;
}
enum class OverflowWrap {
initial, inherit, unset,
normal, anywhere, breakWord;
override fun toString() = name.hyphenize()
}
enum class OverscrollBehavior {
initial, inherit, unset,
auto, contain, none;
}
enum class PointerEvents {
initial, inherit, unset,
auto, none;
}
enum class Position {
initial, inherit, unset,
static, relative, absolute, fixed, sticky;
}
enum class ScrollBehavior {
initial, inherit, unset,
auto, smooth;
}
enum class TextAlign {
initial, inherit, unset,
left, right, center, justify, justifyAll, start, end, matchParent;
override fun toString() = name.hyphenize()
}
enum class TableLayout {
initial, inherit, unset,
auto, fixed;
}
enum class TextOverflow {
initial, inherit, unset,
clip, ellipsis;
}
enum class TextTransform {
initial, inherit, unset,
capitalize, uppercase, lowercase, none, fullWidth;
override fun toString() = name.hyphenize()
}
enum class UserSelect {
initial, inherit, unset,
none, auto, text, contain, all;
}
class VerticalAlign(override val value: String) : CssValue(value) {
companion object {
val initial = VerticalAlign("initial")
val inherit = VerticalAlign("inherit")
val unset = VerticalAlign("unset")
val baseline = VerticalAlign("baseline")
val sub = VerticalAlign("sub")
val `super` = VerticalAlign("super")
val textTop = VerticalAlign("text-top")
val textBottom = VerticalAlign("text-bottom")
val middle = VerticalAlign("middle")
val top = VerticalAlign("top")
val bottom = VerticalAlign("bottom")
}
}
val LinearDimension.up get() = VerticalAlign(toString())
val LinearDimension.down get() = VerticalAlign((-this).toString())
enum class Visibility {
initial, inherit, unset,
visible, hidden, collapse;
}
enum class WhiteSpace {
initial, inherit, unset,
normal, nowrap, pre, preWrap, preLine;
override fun toString() = name.hyphenize()
}
enum class WordBreak {
initial, inherit, unset,
normal, breakAll, breakWord, keepAll;
override fun toString() = name.hyphenize()
}
enum class WordWrap {
initial, inherit, unset,
normal, breakWord;
override fun toString() = name.hyphenize()
}
enum class Resize {
none, both,
horizontal, vertical,
block, inline,
inherit, initial, unset;
}
class Image(override val value: String) : CssValue(value) {
companion object {
val none = Image("none")
}
}
class RelativePosition(override val value: String) : CssValue(value) {
companion object {
val inherit = RelativePosition("inherit")
val initial = RelativePosition("initial")
val unset = RelativePosition("unset")
val left = RelativePosition("left")
val center = RelativePosition("center")
val right = RelativePosition("right")
val top = RelativePosition("top")
val bottom = RelativePosition("bottom")
val leftTop = RelativePosition("left top")
val leftCenter = RelativePosition("left center")
val leftBottom = RelativePosition("left bottom")
val centerTop = RelativePosition("center top")
val centerCenter = RelativePosition("center center")
val centerBottom = RelativePosition("center bottom")
val rightTop = RelativePosition("right top")
val rightCenter = RelativePosition("right center")
val rightBottom = RelativePosition("right bottom")
fun offset(xOffset: LinearDimension, yOffset: LinearDimension? = null): RelativePosition {
return if (yOffset != null) {
RelativePosition("${xOffset.value} ${yOffset.value}")
} else {
RelativePosition(xOffset.value)
}
}
fun left(xOffset: LinearDimension): RelativePosition {
return RelativePosition("left ${xOffset.value}")
}
fun right(xOffset: LinearDimension): RelativePosition {
return RelativePosition("right ${xOffset.value}")
}
fun top(yOffset: LinearDimension): RelativePosition {
return RelativePosition("top ${yOffset.value}")
}
fun bottom(yOffset: LinearDimension): RelativePosition {
return RelativePosition("bottom ${yOffset.value}")
}
fun leftTop(xOffset: LinearDimension, yOffset: LinearDimension): RelativePosition {
return RelativePosition("left ${xOffset.value} top ${yOffset.value}")
}
fun leftBottom(xOffset: LinearDimension, yOffset: LinearDimension): RelativePosition {
return RelativePosition("left ${xOffset.value} bottom ${yOffset.value}")
}
fun rightTop(xOffset: LinearDimension, yOffset: LinearDimension): RelativePosition {
return RelativePosition("right ${xOffset.value} top ${yOffset.value}")
}
fun rightBottom(xOffset: LinearDimension, yOffset: LinearDimension): RelativePosition {
return RelativePosition("right ${xOffset.value} bottom ${yOffset.value}")
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy