Skip to content

golota60/oxytail

Repository files navigation

Oxytail

Styled widget library built on top of floem, inspired by daisyUI


Features:

  • Cross-system support
  • HIGHLY customizable - modify and create your own themes easily
  • Supports dynamic theme switching(example needed!)
  • Built on top of Floem
  • Loosely inspired by daisyUI

Showcase:

Installation

oxytail consists of the main "base" package(oxytail-base), which loads the theme you want, and theme packages(currently only oxytail-theme-dark. More coming soon!).

Next, you need to choose your theme, and install it. Currently, oxytail comes with only one theme, oxytail-theme-dark, but if it doesn't suit your needs you can easily write your own one. It's still early days for this project, so some widgets are missing.

First, add floem, oxytail-base(to load a theme) and oxytail-theme-dark(or any other theme)

cargo add floem oxytail-base oxytail-theme-dark

Done! Now, initialize the theme, and simply use floem like normal, except import your widgets from oxytail-base instead! You can't mix&match both floem and oxytail widgets as needed.

use floem::kurbo::Size;
use floem::peniko::Color;
use floem::reactive::create_signal;
use floem::view::View;
use floem::views::{h_stack, label, v_stack, Decorators};
use floem::window::WindowConfig;
use floem::Application;
use oxytail_base::{init_theme, widgets::button::button};
use oxytail_theme_dark::Theme;

fn app_view() -> impl View {
    // Create a reactive signal with a counter value, defaulting to 0
    let (counter, set_counter) = create_signal(0);

    // Create a vertical layout
    v_stack((
        // The counter value updates automatically, thanks to reactivity
        label(move || format!("Value: {}", counter.get())),
        // Create a horizontal layout
        h_stack((
            button(|| "Increment", None).on_click_stop(move |_| {
                set_counter.update(|value| *value += 1);
            }),
            button(|| "Decrement", None).on_click_stop(move |_| {
                set_counter.update(|value| *value -= 1);
            }),
        )),
    ))
}

fn main() {
    let window_config = WindowConfig::default()
        .size(Size {
            width: 1200.0,
            height: 500.0,
        })
        // 1. We don't want any default `floem` styling to be interfering with ours,
        // so we need to disable the default styling.
        .apply_default_theme(false);

    // 2. We need to initialize our theme
    init_theme(Theme::Dark);
    // That's all! Now import some widgets from `oxytail_base` and you're using oxytail!

    let root_view = app_view();
    let root_view = root_view.style(|s| {
        s.width_full()
            .background(Color::rgb8(29, 35, 42))
            .color(Color::rgb8(166, 173, 187))
            .padding(16.)
    });

    let app = Application::new().window(move |_| root_view, Some(window_config));

    app.run();
}

Documentation/Examples

The best showcase is examples/widget-gallery package. Run it with cargo run -p widget-gallery. Docs.rs soon.

Contributing

If you notice any bugs, missing features or nice-to-haves, don't hesistate to open an issue.

If you want to submit a custom theme(or just link your own in this README for other people to know) to be a part of this library, also don't hesitate and simply create a new package in the workspace(see oxytail-theme-dark folder for guidance).writing your own theme

If you need some widgets which currently don't exist, please consider submitting them to the upstream floem library first.

If you think some of the docs are unclear, also feel free to create an issue!

Roadmap

Obviously, we do not have many widgets which are present in daisyUI. The most immediate roadmap focuses on two things: More widgets, more prop support and more themes.

Expect breaking changes.

Short term roadmap(primitives only):

  • Toggles(toggle)
  • Visual Dividers(text_divider)
  • Radio buttons(radio_button)
  • H1/H2/H3/H4/H5 Equivalents(text_header)
  • Dropdowns/Selects
  • Tooltips
  • Badges
  • Progress bars
  • your suggestion

Notes

The idea for this project came from my slight frustration when developing this tauri-based desk manager app. While for that project tauri is an awesome pick, I was looking for a native solution, i.e. not using system WebView. I've chosen floem as a base, because of their really friendly and extensible styling.

I'm only aware of one other widget library for floem, and it's floem-ui-kit. I really like the simplicity of it, but I wanted something more customizable.