Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit089b8a7

Browse files
editable header component (#1024)
1 parent384921f commit089b8a7

File tree

8 files changed

+243
-0
lines changed

8 files changed

+243
-0
lines changed

‎pgml-dashboard/src/components/inputs/mod.rs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@
44
// src/components/inputs/range_group
55
pubmod range_group;
66
pubuse range_group::RangeGroup;
7+
8+
// src/components/inputs/text
9+
pubmod text;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
div[data-controller="inputs-text-editable-header"] {
2+
.editable-header-container {
3+
span.material-symbols-outlined {
4+
color:#{$slate-shade-500};
5+
font-size:inherit;
6+
text-overflow:ellipsis;
7+
&.active {
8+
color:#{$slate-tint-500};
9+
}
10+
}
11+
12+
&:hover {
13+
span.material-symbols-outlined {
14+
color:#{$slate-shade-300}
15+
}
16+
}
17+
18+
&:focus,&:focus-within {
19+
span.material-symbols-outlined {
20+
color:#{$slate-tint-500};
21+
}
22+
}
23+
24+
}
25+
26+
input,input:focus {
27+
border:none;
28+
border-radius:0;
29+
border-bottom:2pxsolid#{$slate-tint-500};
30+
background:transparent;
31+
font-size:inherit;
32+
line-height:inherit;
33+
padding:0px;
34+
margin-bottom:-2px;// compensate for border space
35+
}
36+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import{Controller}from'@hotwired/stimulus'
2+
3+
exportdefaultclassextendsController{
4+
statictargets=["input","header"]
5+
6+
initialize(){
7+
this.inputTarget.addEventListener("focusout",(e)=>{
8+
this.headerTarget.innerHTML=e.target.value
9+
this.toggleEditor()
10+
})
11+
12+
// blur input on enter
13+
this.inputTarget.addEventListener("keydown",(e)=>{
14+
if(e.key=="Enter"){
15+
this.inputTarget.blur()
16+
}
17+
})
18+
}
19+
20+
toggleEditor(e){
21+
// dont toggle if click inside input
22+
if(e&&this.inputTarget.contains(e.target)){
23+
return
24+
}
25+
26+
if(this.inputTarget.style.display=="none"){
27+
this.inputTarget.style.display="block"
28+
this.headerTarget.style.display="none"
29+
this.inputTarget.focus()
30+
}else{
31+
this.inputTarget.style.display="none"
32+
this.headerTarget.style.display="flex"
33+
}
34+
}
35+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
use pgml_components::component;
2+
use sailfish::runtime::{Buffer,Render};
3+
use sailfish::TemplateOnce;
4+
use std::fmt;
5+
6+
pubenumHeaders{
7+
H1,
8+
H2,
9+
H3,
10+
H4,
11+
H5,
12+
H6,
13+
}
14+
15+
impl fmt::DisplayforHeaders{
16+
fnfmt(&self,f:&mut fmt::Formatter<'_>) -> fmt::Result{
17+
matchself{
18+
Headers::H1 =>write!(f,"h1"),
19+
Headers::H2 =>write!(f,"h2"),
20+
Headers::H3 =>write!(f,"h3"),
21+
Headers::H4 =>write!(f,"h4"),
22+
Headers::H5 =>write!(f,"h5"),
23+
Headers::H6 =>write!(f,"h6"),
24+
}
25+
}
26+
}
27+
28+
pubstructStimulusTarget{
29+
controller:Option<String>,
30+
target_name:Option<String>,
31+
}
32+
33+
implStimulusTarget{
34+
pubfnnew() ->StimulusTarget{
35+
StimulusTarget{
36+
controller:None,
37+
target_name:None,
38+
}
39+
}
40+
41+
pubfncontroller(mutself,controller:&str) ->Self{
42+
self.controller =Some(controller.to_string());
43+
self
44+
}
45+
46+
pubfntarget_name(mutself,target_name:&str) ->Self{
47+
self.target_name =Some(target_name.to_string());
48+
self
49+
}
50+
}
51+
52+
implRenderforStimulusTarget{
53+
fnrender(&self,b:&mutBuffer) ->Result<(), sailfish::RenderError>{
54+
ifself.controller.is_none() ||self.target_name.is_none(){
55+
returnformat!("").render(b);
56+
}
57+
format!(
58+
"data-{}-target=\"{}\"",
59+
self.controller.to_owned().unwrap(),
60+
self.target_name.to_owned().unwrap()
61+
)
62+
.render(b)
63+
}
64+
}
65+
66+
#[derive(TemplateOnce)]
67+
#[template(path ="inputs/text/editable_header/template.html")]
68+
pubstructEditableHeader{
69+
value:String,
70+
header_type:Headers,
71+
input_target:StimulusTarget,
72+
input_name:Option<String>,
73+
}
74+
75+
implEditableHeader{
76+
pubfnnew() ->EditableHeader{
77+
EditableHeader{
78+
value:String::from("Title Goes Here"),
79+
header_type:Headers::H3,
80+
input_target:StimulusTarget::new(),
81+
input_name:None,
82+
}
83+
}
84+
85+
pubfnheader_type(mutself,header_type:Headers) ->Self{
86+
self.header_type = header_type;
87+
self
88+
}
89+
90+
pubfnvalue(mutself,value:&str) ->Self{
91+
self.value = value.to_string();
92+
self
93+
}
94+
95+
pubfninput_target(mutself,input_target:StimulusTarget) ->Self{
96+
self.input_target = input_target;
97+
self
98+
}
99+
100+
pubfninput_name(mutself,input_name:&str) ->Self{
101+
self.input_name =Some(input_name.to_string());
102+
self
103+
}
104+
}
105+
106+
component!(EditableHeader);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<divdata-controller="inputs-text-editable-header">
2+
<divclass="editable-header-container"style="display: block"
3+
data-action="click->inputs-text-editable-header#toggleEditor">
4+
<<%= header_type.to_string() %> class="align-items-center<%= header_type.to_string() %> d-flex gap-3">
5+
<spandata-inputs-text-editable-header-target="header">
6+
<%= value %>
7+
</span>
8+
9+
<inputtype="text"class="form-control"value="<%= value %>"style="display: none"maxlength="50"
10+
name='<%= input_name.unwrap_or_else(|| "".to_string()) %>'
11+
data-inputs-text-editable-header-target="input"
12+
<%- input_target %>>
13+
14+
<div>
15+
<spanclass="material-symbols-outlined">
16+
border_color
17+
</span>
18+
</div>
19+
</<%= header_type.to_string() %>>
20+
</div>
21+
22+
23+
</div>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// This file is automatically generated.
2+
// You shouldn't modify it manually.
3+
4+
// src/components/inputs/text/editable_header
5+
pubmod editable_header;
6+
pubuse editable_header::EditableHeader;

‎pgml-dashboard/static/css/modules.scss‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
@import"../../src/components/dropdown/dropdown.scss";
55
@import"../../src/components/inputs/range_group/range_group.scss";
6+
@import"../../src/components/inputs/text/editable_header/editable_header.scss";
67
@import"../../src/components/left_nav_menu/left_nav_menu.scss";
78
@import"../../src/components/left_nav_web_app/left_nav_web_app.scss";
89
@import"../../src/components/modal/modal.scss";

‎pgml-dashboard/templates/content/playground.html‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
use crate::components::tables::large::*;
33
use crate::components::navigation::tabs::*;
44
use crate::components::inputs::range_group::RangeGroup;
5+
use crate::components::inputs::text::editable_header::{EditableHeader, Headers, StimulusTarget};
56
%>
67

78
<divclass="min-height: 100vh;"data-controller="playground">
@@ -115,5 +116,37 @@ <h3 class="h3">Inputs</h3>
115116
.cost_rate(0.144) %>
116117
</div>
117118
</div>
119+
120+
<divclass="d-flex flex-row justify-content-between">
121+
<%+ EditableHeader::new()
122+
.value("Size H1")
123+
.header_type(Headers::H1) %>
124+
<div>
125+
this is a thing that takes up space
126+
</div>
127+
</div>
128+
<divclass="d-flex flex-row justify-content-between">
129+
<%+ EditableHeader::new()
130+
.value("Size H2")
131+
.header_type(Headers::H2) %>
132+
<div>
133+
this is a thing that takes up space
134+
</div>
135+
</div>
136+
<divclass="d-flex flex-row justify-content-between">
137+
<%+ EditableHeader::new()
138+
.value("Size H3")
139+
.header_type(Headers::H3)
140+
.input_name("title")
141+
.input_target(
142+
StimulusTarget::new()
143+
.controller("some-existing-controller")
144+
.target_name("desired-target-name")
145+
) %>
146+
<div>
147+
this is a thing that takes up space
148+
</div>
149+
</div>
118150
</div>
151+
119152
</div>

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp