mirror of
https://github.com/adoyle0/thaw.git
synced 2025-03-13 05:59:49 -04:00
feat: color_picker component
This commit is contained in:
parent
95dcd6f992
commit
81a3c36886
2 changed files with 100 additions and 4 deletions
|
@ -32,6 +32,52 @@
|
|||
z-index: 1000;
|
||||
}
|
||||
|
||||
.melt-color-picker-popover__layer {
|
||||
height: 176px;
|
||||
.melt-color-picker-popover__panel {
|
||||
position: relative;
|
||||
height: 180px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.melt-color-picker-popover__layer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.melt-color-picker-popover__layer--shadowed {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background-image: linear-gradient(rgba(0, 0, 0, 0), rgb(0, 0, 0));
|
||||
}
|
||||
|
||||
.melt-color-picker-slider {
|
||||
height: 12px;
|
||||
padding-right: 12px;
|
||||
background-image: linear-gradient(
|
||||
90deg,
|
||||
red,
|
||||
rgb(255, 255, 0) 16.66%,
|
||||
rgb(0, 255, 0) 33.33%,
|
||||
rgb(0, 255, 255) 50%,
|
||||
rgb(0, 0, 255) 66.66%,
|
||||
rgb(255, 0, 255) 83.33%,
|
||||
red
|
||||
);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.melt-color-picker-slider__handle {
|
||||
position: relative;
|
||||
left: 0;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 6px;
|
||||
box-sizing: border-box;
|
||||
border: 2px solid white;
|
||||
cursor: pointer;
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
use crate::{mount_style, teleport::Teleport, utils::maybe_rw_signal::MaybeRwSignal};
|
||||
use leptos::*;
|
||||
use leptos_dom::helpers::WindowListenerHandle;
|
||||
use wasm_bindgen::__rt::IntoJsResult;
|
||||
|
||||
#[component]
|
||||
|
@ -58,6 +59,7 @@ pub fn ColorPicker(#[prop(optional, into)] value: MaybeRwSignal<String>) -> impl
|
|||
is_show_popover.set(false);
|
||||
});
|
||||
on_cleanup(move || timer.remove());
|
||||
let hue = create_rw_signal(0);
|
||||
view! {
|
||||
<div class="melt-color-picker-trigger" on:click=show_popover ref=trigger_ref>
|
||||
<div class="melt-color-picker-trigger__content" style=move || style.get()>
|
||||
|
@ -73,9 +75,57 @@ pub fn ColorPicker(#[prop(optional, into)] value: MaybeRwSignal<String>) -> impl
|
|||
}
|
||||
>
|
||||
|
||||
<div class="melt-color-picker-popover__panel">
|
||||
<div class="melt-color-picker-popover__layer"></div>
|
||||
<div class="melt-color-picker-popover__layer--shadowed"></div>
|
||||
<div></div>
|
||||
</div>
|
||||
<HueSlider hue/>
|
||||
</div>
|
||||
</Teleport>
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn HueSlider(hue: RwSignal<u16>) -> impl IntoView {
|
||||
let rail_ref = create_node_ref::<html::Div>();
|
||||
let mouse = store_value(Vec::<WindowListenerHandle>::new());
|
||||
|
||||
let on_mouse_down = move |_| {
|
||||
let on_mouse_move = window_event_listener(ev::mousemove, move |ev| {
|
||||
if let Some(rail) = rail_ref.get_untracked() {
|
||||
let rect = rail.get_bounding_client_rect();
|
||||
let ev_x = f64::from(ev.x());
|
||||
let value = (ev_x - rect.x()) / (rect.width() - 12.0) * 360.0;
|
||||
let value = if value < 0.0 {
|
||||
0
|
||||
} else if value > 359.0 {
|
||||
359
|
||||
} else {
|
||||
value.round().to_string().parse::<u16>().unwrap()
|
||||
};
|
||||
hue.set(value);
|
||||
}
|
||||
});
|
||||
let on_mouse_up = window_event_listener(ev::mouseup, move |_| {
|
||||
mouse.update_value(|value| {
|
||||
for handle in value.drain(..).into_iter() {
|
||||
handle.remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
mouse.update_value(|value| {
|
||||
value.push(on_mouse_move);
|
||||
value.push(on_mouse_up);
|
||||
});
|
||||
};
|
||||
view! {
|
||||
<div class="melt-color-picker-slider" ref=rail_ref>
|
||||
<div
|
||||
class="melt-color-picker-slider__handle"
|
||||
on:mousedown=on_mouse_down
|
||||
style=move || format!("left: {}%", f32::from(hue.get()) / 359.0 * 100.0)
|
||||
></div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue