Git Product home page Git Product logo

split-yew's Introduction

split-yew

crates-badge docsrs-badge yew-badge license-badge

This library adds a Yew component wrapper for the Split.js library. Similar to the react-split component.

This library does NOT include a component for split-grid.

split-yew has been tested with split.js version 1.6.5

Usage

Start by including the split.js module in your index.html file header tag like so:

<script type="importmap">
    {
        "imports": {
            "split.js": "https://unpkg.com/[email protected]/dist/split.es.js"
        }
    }
</script>

Make sure it is of type importmap and that the import is called split.js. Also make sure you choose the ES module version and not the CommonJS one. It is worth noting that split.js does not include a minified version of the ES module script, hence if you want one you will have to package it yourself. After that the library should work without issues.

Much like its React counterpart, you just have to surround the components you want to be in a resizable split view.

html! {
    <Split>
        <Component />
        // ...
        <Component />
    </Split>
}

CSS

split.js does not include any styling and this component does not change that. To make the split visible you should style the split root element's display layout. I personally recommend a flex layout. To make the gutter visible you should edit its style using the .gutter, .gutter-horizontal, and .gutter-vertical CSS classes.

A real life example usage of split-yew is the yew-playground's frontend. The split style is set using TailwindCSS in the app's source, and its CSS stylesheet shows how to style the gutter.

For more information on styling checkout split.js's documentation.

Documentation

You can customize the split using props. I tried to keep compatibility with the react-split component, hence you can also mostly refer to its reference as well as Split.js's documentation with some minor changes to the API.

All props

Prop Type Description Docs
class Classes Classes to apply to the split container element N/A
sizes Vec<f64> Initial sizes of each element docs
min_size f64 Minimum size of all elements (if min_sizes is specified, this will be ignored) docs
min_sizes Vec<f64> Minimum size of each element docs
max_size f64 Maximum size of all elements (if max_sizes is specified, this will be ignored) docs
max_sizes Vec<f64> Maximum size of each element docs
expand_to_min bool Grow initial sizes to min_size (default: false) docs
gutter_size f64 Gutter size in pixels (default: 10) docs
gutter_align GutterAlign Gutter alignment between elements (default: GutterAlign::Center) docs
snap_offset f64 Snap to minimum size offset in pixels (default: 30) docs
drag_interval f64 Number of pixels to drag (default: 1) docs
direction Direction Direction to split: horizontal or vertical (default: Direction::Horizontal) docs
cursor Cursor Cursor to display while dragging (default: Cursor::ColResize) docs
gutter js_sys::Function Called to create each gutter element docs
element_style js_sys::Function Called to set the style of each element docs
gutter_style js_sys::Function Called to set the style of the gutter docs
on_drag js_sys::Function Called on drag docs
on_drag_start js_sys::Function Called on drag start docs
on_drag_end js_sys::Function Called on drag end docs
collapsed usize This prop replaces the method call to collapse(index) docs

Additional Details

class prop

The Split component includes a class prop you can use to specify classes for the div that wraps all of the inner components. This can be useful to style the split, especially when using something like TailwindCSS.

min_size and max_size props

These two props originally accept two possible different types, either a single number specifying the min/max size for all components, or an array of numbers, specifying min/max sizes for each component individually.

To emulate this behavior in Rust, split-yew has four different props:

  • min_size/max_size: where you can specify a single value to apply to all components.
  • min_sizes/max_sizes: where you can specify a vector of values, one for each component.

While you can specify, for instance, both a min_size and a min_sizes at the same time; the vector variant will always take priority, as shown in the following example:

html! {
    <Split min_size={500.0} min_sizes={vec![100.0, 200.0]}>
        <ComponentA />
        <ComponentB />
    </Split>
}

In this example the two components will have a min size of 100 and 200 respectively, while the min_size={500.0} will be ignored.

Function props

Props gutter, element_style, gutter_style, on_drag, on_drag_start, and on_drag_end are supposed to accept a function or closure. Unfortunately I was not able to represent them with a yew::Callback or wasm_bindgen::Closure type. The best thing I was able to do at the moment was use a js_sys::Function type, which can still be passed as prop, as well as to the split.js library itself.

This makes passing these props a bit inconvenient, as the js_sys::Function does not include any type information about function arguments or return type, however all that information is already available in the official split.js docs, so refer to that if you need to implement one of these functions.

For the implementation itself, you can simply implement a wasm_bindgen::Closure and convert it to a js_sys::Function. The following example shows how to create such a function for the gutter prop.

let my_gutter: js_sys::Function = Closure::<dyn Fn(js_sys::BigInt, String, web_sys::Element) -> web_sys::Element>::new(
        |index, direction, pair_element| {
            // Do something with the arugments and return a value of type web_sys::Element
        },
    )
    .into_js_value()
    .into()

As shown in the example, the final type of my_gutter will be a js_sys::Function. While I don't have too much experience with passing functions from Rust to JavaScript, one caveat I did find is that with numbers I could not use a normal Rust primitive, but use js_sys::BigInt instead.

License

This project follows the MIT license.

split-yew's People

Contributors

aleb2000 avatar

Stargazers

 avatar  avatar

Watchers

 avatar

split-yew's Issues

Nothing rendering

Hello again!
I just picked up where I left off on the web component of my project, and so far split-yew compiles with the latest.
However, nothing shows up!
My html looks like this:

<!doctype html>                                                             
<html>                                                                      
  <head>                                                                    
    <meta charset="utf-8" />                                                
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- <title>Yew App</title> -->                                         
    <script type="importmap">                                               
      {                                                                     
        "imports": {                                                        
          "split.js": "https://unpkg.com/[email protected]/dist/split.es.js"   
        }                                                                   
      }                                                                     
    </script>                                                               
  </head>                                                                   
  <body></body>                                                             
</html>                                                                     

My test component looks like this:

use split_yew::Split;                     
use yew::prelude::*;                      
                                          
#[function_component(CompA)]              
pub fn comp_a() -> Html {                 
    html! {                               
        <>                                
        {"hello"}                         
        </>                               
    }                                     
}                                         
                                          
#[function_component(CompB)]              
pub fn comp_b() -> Html {                 
    html! {                               
        <>                                
        {"hello2"}                        
        </>                               
    }                                     
}                                         
#[function_component(App)]                
pub fn app() -> Html {                    
    html! {                               
        <>                                
            <Split                        
            min_size={500.0}              
            min_sizes={vec![100.0, 200.0]}
            >                             
            <CompA />                     
            <CompB />                     
            </Split>                      
            {"test2"}                     
        </>                               
    }                                     
}                                         

But there's no gutter, or any signs of Split. The text does render, but as if there was no split at all!
Help?
Thanks!

Not working with yew 0.21.0

error[E0277]: the trait bound split_yew::Split: yew::Component is not satisfied
--> ui/src/components/app/app.rs:12:10
|
12 |
| ^^^^^ the trait yew::Component is not implemented for split_yew::Split
|
= help: the trait yew::Component is implemented for ContextProvider<T>
= note: required for split_yew::Split to implement yew::BaseComponent
= note: this error originates in the macro html (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0599]: the function or associated item new exists for struct VChild<Split>, but its trait bounds were not s
atisfied
--> ui/src/components/app/app.rs:12:10
|
12 |
| ^^^^^ function or associated item cannot be called on VChild<Split> due to unsatisfied trait bounds
|
::: .cargo/git/checkouts/split-yew-84a544648acafcab/8548d2a/src/lib.rs:99:1
|
99 | pub struct Split {
| ---------------- doesn't satisfy split_yew::Split: yew::BaseComponent
|
= note: the following trait bounds were not satisfied:
split_yew::Split: yew::BaseComponent
= note: this error originates in the macro html (in Nightly builds, run with -Z macro-backtrace for more info)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.