Skip to main content

Arbitrary

Struct Arbitrary 

Source
pub struct Arbitrary<Str, ArrayStr, MapStr, ArrayMatched> {
    pub namespace: Str,
    pub prop: PropertyName<Str, ArrayStr>,
    pub shadow_color_replacement: Option<Str>,
    pub disambiguate: Option<ArbitraryDisambiguate<ArrayMatched>>,
    pub template: Option<PropertyName<Str, ArrayStr>>,
    pub extra_rule_css: Option<ArrayStr>,
    pub extra_css: Option<MapStr>,
    pub extra_class: Option<Str>,
}
Expand description

Define a plugin supporting arbitrary values, i.e all selectors in the form <namespace>-[...] (i.e the modifier is wrapped in square brackets).

It directly copies the contents given inside brackets as the value of the <prop> CSS propertie(s).

By default, all values are allowed by the plugin and it’s up to the final user to only use valid CSS values for the property. However, if several Arbitrary plugins share the same namespace, it’s required to disambiguate which plugins should handle the selector. In this case, Arbitrary::disambiguate should be used to only handle the selector if the arbitrary CSS value has a specific CSS type or a specific manual hint.

§Example

use encre_css::{Config, generate};
use encre_css::prelude::build_plugin::*;

const PLUGIN: StaticPlugin = Plugin::Arbitrary(Arbitrary {
    namespace: "mask",
    prop: SingleProp("mask-position"),
    ..Arbitrary::default()
});

let mut config = Config::default();
config.register_plugin(&PLUGIN);

let generated = generate(["mask-[25%]", "mask-[left_center]"], &config);

assert!(generated.ends_with(r".mask-\[25\%\] {
  mask-position: 25%;
}

.mask-\[left_center\] {
  mask-position: left center;
}"));

§Example in TOML

[[custom_plugins]]

[custom_plugins.Arbitrary]
namespace = "mask"
prop = "mask-position"

Fields§

§namespace: Str

The namespace (i.e common prefix) that all classes need to start with in order to be matched by this plugin.

§prop: PropertyName<Str, ArrayStr>

The CSS property name of the generated CSS rule.

It can be a single property using PropertyName::SingleProp or a list of properties using PropertyName::MultipleProps, in which case the value will be copied for all properties.

§shadow_color_replacement: Option<Str>

If the arbitrary value is a shadow, replace all the colors used by a single CSS variable given as string.

This field should only be used for shadows that need to have their colors separately set using a dedicated utility class.

If the value contains a placeholder {}, it will be replaced by the previous color value.

§Example
use encre_css::{Config, generate};
use encre_css::prelude::build_plugin::*;

const PLUGIN_SHADOW: StaticPlugin = Plugin::Arbitrary(Arbitrary {
    namespace: "custom-shadow",
    prop: SingleProp("box-shadow"),
    shadow_color_replacement: Some("var(--shadow-color, {})"),
    ..Arbitrary::default()
});

const PLUGIN_SHADOW_COLOR: StaticPlugin = Plugin::Color(Color {
    namespace: "custom-shadow-color",
    prop: SingleProp("--shadow-color"),
    ..Color::default()
});

let mut config = Config::default();
config.register_plugin(&PLUGIN_SHADOW);
config.register_plugin(&PLUGIN_SHADOW_COLOR);

let generated = generate(["custom-shadow-[10px_5px_5px_red]", "custom-shadow-color-blue-100"], &config);

assert!(generated.ends_with(r"
.custom-shadow-\[10px_5px_5px_red\] {
  box-shadow: 10px 5px 5px var(--shadow-color, red);
}

.custom-shadow-color-blue-100 {
  --shadow-color: oklch(93.2% .032 255.585);
}"));
§disambiguate: Option<ArbitraryDisambiguate<ArrayMatched>>§template: Option<PropertyName<Str, ArrayStr>>

Define a format string used to modify the generated CSS value…

In practice, you give a string containing a {} placeholder to this field (wrapped in the same PropertyName variant as the prop field) and it will be replaced during CSS generation by the value matched by the plugin kind and options.

For instance, it can be used to specify a CSS unit when using the Number plugin kind or to wrap the value in a CSS function like translate or blur.

You should use the same property name variant as prop, otherwise the plugin matches will be silently ignored. Check the examples below to see two correct usages.

§Example
use encre_css::{Config, generate};
use encre_css::prelude::build_plugin::*;

pub(crate) const PLUGIN_SINGLE_PROP: StaticPlugin = Plugin::Number(Number {
    namespace: "custom-stroke",
    prop: SingleProp("stroke-width"),
    template: Some(SingleProp("{}px")),
    ..Number::default()
});

pub(crate) const PLUGIN_MULTIPLE_PROPS: StaticPlugin = Plugin::Number(Number {
    namespace: "custom-move",
    prop: MultipleProps(&["translate", "rotate"]),
    template: Some(MultipleProps(&["{}px", "{}deg"])),
    ..Number::default()
});

let mut config = Config::default();
config.register_plugin(&PLUGIN_SINGLE_PROP);
config.register_plugin(&PLUGIN_MULTIPLE_PROPS);

let generated = generate(["custom-stroke-42", "custom-move-3"], &config);

assert!(generated.ends_with(".custom-stroke-42 {
  stroke-width: 42px;
}

.custom-move-3 {
  translate: 3px;
  rotate: 3deg;
}"));
§Example in TOML
[[custom_plugins]]

[custom_plugins.Number]
namespace = "custom-stroke"
prop = "stroke-width"
template = "{}px"

[[custom_plugins]]

[custom_plugins.Number]
namespace = "custom-move"
prop = ["translate", "rotate"]
template = ["{}px", "{}deg"]
§extra_rule_css: Option<ArrayStr>

Add one or several extra CSS line(s) inside the CSS rule generated for the utility class.

This field takes an array which represents the CSS lines that will be properly indented and added, one after another, in the order they are defined, to the CSS rule.

§Example
use encre_css::{Config, generate};
use encre_css::prelude::build_plugin::*;

const PLUGIN: StaticPlugin = Plugin::Spacing(Spacing {
    namespace: "custom-translate-x",
    prop: SingleProp("--translate-x"),
    extra_rule_css: Some(&["transform: translate(var(--translate-x), 12px);"]),
    ..Spacing::default()
});

let mut config = Config::default();
config.register_plugin(&PLUGIN);

let generated = generate(["custom-translate-x-8"], &config);

assert!(generated.ends_with(".custom-translate-x-8 {
  --translate-x: 2rem;
  transform: translate(var(--translate-x), 12px);
}"));
§Example in TOML
[[custom_plugins]]

[custom_plugins.Spacing]
namespace = "custom-translate-x"
prop = "--translate-x"
extra_rule_css = ["transform: translate(var(--translate-x), 12px);"]
§extra_css: Option<MapStr>

Add one or several extra CSS line(s) outside the CSS rule generated for the utility class.

The argument is a map which allows choosing the added CSS based on the modifier value.

§Example
use encre_css::{Config, generate};
use encre_css::prelude::build_plugin::*;

const SPIN_ANIMATION: &str = "@keyframes anim-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}\n\n";

const FADE_IN_ANIMATION: &str = "@keyframes anim-fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}\n\n";

const PLUGIN: StaticPlugin = Plugin::ListValues(ListValues {
    prop: SingleProp("animation"),
    values: map! {
        "custom-animate-spin" => "anim-spin",
        "custom-animate-fade-in" => "anim-fade-in",
    },
    extra_css: Some(map! {
        "custom-animate-spin" => SPIN_ANIMATION,
        "custom-animate-fade-in" => FADE_IN_ANIMATION,
    }),
    ..ListValues::default()
});

let mut config = Config::default();
config.register_plugin(&PLUGIN);

let generated = generate(["custom-animate-spin"], &config);

assert!(generated.ends_with("@keyframes anim-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.custom-animate-spin {
  animation: anim-spin;
}"));
§Example in TOML
[[custom_plugins]]

[custom_plugins.ListValues]
prop = "animation"

[custom_plugins.ListValues.values]
custom-animate-spin = "anim-spin"
custom-animate-fade-in = "anim-fade-in"

[custom_plugins.ListValues.extra_css]
custom-animate-spin = """@keyframes anim-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}\n\n"""
custom-animate-fade-in = """@keyframes anim-fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}\n\n"""
§extra_class: Option<Str>

Add a suffix string to the class selector of the generated CSS rule.

§Example
use encre_css::{Config, generate};
use encre_css::prelude::build_plugin::*;

pub(crate) const PLUGIN: StaticPlugin = Plugin::Spacing(Spacing {
    namespace: "custom-divide",
    prop: SingleProp("margin-inline"),
    extra_class: Some(" > :not(:last-child)"),
    ..Spacing::default()
});

let mut config = Config::default();
config.register_plugin(&PLUGIN);

let generated = generate(["custom-divide-2"], &config);

assert!(generated.ends_with(".custom-divide-2 > :not(:last-child) {
  margin-inline: 0.5rem;
}"));
§Example in TOML
[[custom_plugins]]

[custom_plugins.Spacing]
namespace = "custom-divide"
prop = "margin-inline"
extra_class = " > :not(:last-child)"

Implementations§

Source§

impl<ArrayStr, MapStr, ArrayMatched> Arbitrary<&'static str, ArrayStr, MapStr, ArrayMatched>

Source

pub const fn default() -> Self

Make a default Arbitrary plugin kind.

All required fields are initialized with empty values and optional fields are initialized with None.

You should at least set Arbitrary::namespace and Arbitrary::prop after calling this function.

This function is intended to be used as an automatic filler for default values using the struct update syntax.

The difference with Arbitrary::default_dynamic is that this function can only be used to build a plugin using static structures like &[]s, &'static strs.

§Example
use encre_css::prelude::build_plugin::*;

const PLUGIN: StaticPlugin = Plugin::Arbitrary(Arbitrary {
    namespace: "gap",
    prop: SingleProp("gap"),
    ..Arbitrary::default()
});
Source§

impl<ArrayStr, MapStr, ArrayMatched> Arbitrary<String, ArrayStr, MapStr, ArrayMatched>

Source

pub fn default_dynamic() -> Self

Make a default Arbitrary plugin kind.

All required fields are initialized with empty values and optional fields are initialized with None.

You should at least set Arbitrary::namespace and Arbitrary::prop after calling this function.

This function is intended to be used as an automatic filler for default values using the struct update syntax.

The difference with Arbitrary::default is that this function can only be used to build a plugin using heap-allocated structures like Strings, Vecs.

§Example
use encre_css::prelude::build_plugin::*;

fn main() {
    // Note: the DynamicPlugin type hint is required to help the compiler
    // find the concrete types of type parameters
    let _plugin: DynamicPlugin = Plugin::Arbitrary(Arbitrary {
        namespace: "gap".to_string(),
        prop: SingleProp("gap".to_string()),
        ..Arbitrary::default_dynamic()
    });
}

This example is equivalent to the one of Arbitrary::default.

Trait Implementations§

Source§

impl<Str: Clone, ArrayStr: Clone, MapStr: Clone, ArrayMatched: Clone> Clone for Arbitrary<Str, ArrayStr, MapStr, ArrayMatched>

Source§

fn clone(&self) -> Arbitrary<Str, ArrayStr, MapStr, ArrayMatched>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<Str: Debug, ArrayStr: Debug, MapStr: Debug, ArrayMatched: Debug> Debug for Arbitrary<Str, ArrayStr, MapStr, ArrayMatched>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de, Str, ArrayStr, MapStr, ArrayMatched> Deserialize<'de> for Arbitrary<Str, ArrayStr, MapStr, ArrayMatched>
where Str: Deserialize<'de>, ArrayStr: Deserialize<'de>, MapStr: Deserialize<'de>, ArrayMatched: Deserialize<'de>,

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<Str, ArrayStr, MapStr, ArrayMatched> Serialize for Arbitrary<Str, ArrayStr, MapStr, ArrayMatched>
where Str: Serialize, ArrayStr: Serialize, MapStr: Serialize, ArrayMatched: Serialize,

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<Str, ArrayStr, MapStr, ArrayMatched> Freeze for Arbitrary<Str, ArrayStr, MapStr, ArrayMatched>
where Str: Freeze, PropertyName<Str, ArrayStr>: Freeze, Option<Str>: Freeze, Option<ArbitraryDisambiguate<ArrayMatched>>: Freeze, Option<PropertyName<Str, ArrayStr>>: Freeze, Option<ArrayStr>: Freeze, Option<MapStr>: Freeze,

§

impl<Str, ArrayStr, MapStr, ArrayMatched> RefUnwindSafe for Arbitrary<Str, ArrayStr, MapStr, ArrayMatched>

§

impl<Str, ArrayStr, MapStr, ArrayMatched> Send for Arbitrary<Str, ArrayStr, MapStr, ArrayMatched>
where Str: Send, PropertyName<Str, ArrayStr>: Send, Option<Str>: Send, Option<ArbitraryDisambiguate<ArrayMatched>>: Send, Option<PropertyName<Str, ArrayStr>>: Send, Option<ArrayStr>: Send, Option<MapStr>: Send,

§

impl<Str, ArrayStr, MapStr, ArrayMatched> Sync for Arbitrary<Str, ArrayStr, MapStr, ArrayMatched>
where Str: Sync, PropertyName<Str, ArrayStr>: Sync, Option<Str>: Sync, Option<ArbitraryDisambiguate<ArrayMatched>>: Sync, Option<PropertyName<Str, ArrayStr>>: Sync, Option<ArrayStr>: Sync, Option<MapStr>: Sync,

§

impl<Str, ArrayStr, MapStr, ArrayMatched> Unpin for Arbitrary<Str, ArrayStr, MapStr, ArrayMatched>
where Str: Unpin, PropertyName<Str, ArrayStr>: Unpin, Option<Str>: Unpin, Option<ArbitraryDisambiguate<ArrayMatched>>: Unpin, Option<PropertyName<Str, ArrayStr>>: Unpin, Option<ArrayStr>: Unpin, Option<MapStr>: Unpin,

§

impl<Str, ArrayStr, MapStr, ArrayMatched> UnsafeUnpin for Arbitrary<Str, ArrayStr, MapStr, ArrayMatched>
where Str: UnsafeUnpin, PropertyName<Str, ArrayStr>: UnsafeUnpin, Option<Str>: UnsafeUnpin, Option<ArbitraryDisambiguate<ArrayMatched>>: UnsafeUnpin, Option<PropertyName<Str, ArrayStr>>: UnsafeUnpin, Option<ArrayStr>: UnsafeUnpin, Option<MapStr>: UnsafeUnpin,

§

impl<Str, ArrayStr, MapStr, ArrayMatched> UnwindSafe for Arbitrary<Str, ArrayStr, MapStr, ArrayMatched>
where Str: UnwindSafe, PropertyName<Str, ArrayStr>: UnwindSafe, Option<Str>: UnwindSafe, Option<ArbitraryDisambiguate<ArrayMatched>>: UnwindSafe, Option<PropertyName<Str, ArrayStr>>: UnwindSafe, Option<ArrayStr>: UnwindSafe, Option<MapStr>: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.