feat: input and related components add attrs (#65)

This commit is contained in:
luoxiaozero 2024-01-02 11:23:55 +08:00 committed by GitHub
parent 1e4832a6d0
commit 789ea6772a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 72 additions and 7 deletions

View file

@ -173,6 +173,12 @@ pub fn AutoCompletePage() -> impl IntoView {
<td>"Default::default()"</td> <td>"Default::default()"</td>
<td>"Additional classes for the autocomplete element."</td> <td>"Additional classes for the autocomplete element."</td>
</tr> </tr>
<tr>
<td>"attr:"</td>
<td>"Vec<(&'static str, Attribute)>"</td>
<td>"Default::default()"</td>
<td>"The dom attrs of the input element inside the component."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
<h3>"AutoCompleteOption Properties"</h3> <h3>"AutoCompleteOption Properties"</h3>

View file

@ -57,6 +57,12 @@ pub fn DatePickerPage() -> impl IntoView {
<td>"Default::default()"</td> <td>"Default::default()"</td>
<td>"Addtional classes for the date picker element."</td> <td>"Addtional classes for the date picker element."</td>
</tr> </tr>
<tr>
<td>"attr:"</td>
<td>"Vec<(&'static str, Attribute)>"</td>
<td>"Default::default()"</td>
<td>"The dom attrs of the input element inside the component."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
</div> </div>

View file

@ -104,6 +104,26 @@ pub fn InputPage() -> impl IntoView {
</DemoCode> </DemoCode>
</Demo> </Demo>
<h3>"Input attrs"</h3>
<Demo>
<Space>
<label for="demo-input-attrs">"Do you like cheese?"</label>
<Input attr:id="demo-input-attrs" />
</Space>
<DemoCode slot>
{highlight_str!(
r#"
view! {
<label for="demo-input-attrs">"Do you like cheese?"</label>
<Input attr:id="demo-input-attrs"/>
}
"#,
"rust"
)}
</DemoCode>
</Demo>
<h2>"Prefix & Suffix"</h2> <h2>"Prefix & Suffix"</h2>
<Demo> <Demo>
<Space vertical=true> <Space vertical=true>
@ -219,6 +239,12 @@ pub fn InputPage() -> impl IntoView {
<td>"Default::default()"</td> <td>"Default::default()"</td>
<td>"Addtional classes for the input element."</td> <td>"Addtional classes for the input element."</td>
</tr> </tr>
<tr>
<td>"attr:"</td>
<td>"Vec<(&'static str, Attribute)>"</td>
<td>"Default::default()"</td>
<td>"The dom attrs of the input element inside the component."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
<h3>"Input Slots"</h3> <h3>"Input Slots"</h3>

View file

@ -114,6 +114,12 @@ pub fn InputNumberPage() -> impl IntoView {
<td>"Default::default()"</td> <td>"Default::default()"</td>
<td>"Addtional classes for the input element."</td> <td>"Addtional classes for the input element."</td>
</tr> </tr>
<tr>
<td>"attr:"</td>
<td>"Vec<(&'static str, Attribute)>"</td>
<td>"Default::default()"</td>
<td>"The dom attrs of the input element inside the component."</td>
</tr>
</tbody> </tbody>
</Table> </Table>
<h3>"T impl"</h3> <h3>"T impl"</h3>

View file

@ -12,7 +12,8 @@ view! {
## TimePicker Props ## TimePicker Props
| Name | Type | Default | Description | | Name | Type | Default | Description |
| ----- | ----------------------------- | -------------------- | ---------------------------------------------- | | ----- | -------------------------------- | -------------------- | -------------------------------------------------------- |
| class | `MaybeSignal<String>` | `Default::default()` | Addtional classes for the time picker element. | | class | `MaybeSignal<String>` | `Default::default()` | Addtional classes for the time picker element. |
| value | `RwSignal<Option<NaiveTime>>` | `Default::default()` | Set the TimePicker value. | | value | `RwSignal<Option<NaiveTime>>` | `Default::default()` | Set the TimePicker value. |
| attr: | `Vec<(&'static str, Attribute)>` | `Default::default()` | The dom attrs of the input element inside the component. |

View file

@ -38,6 +38,7 @@ pub fn AutoComplete(
#[prop(optional)] auto_complete_prefix: Option<AutoCompletePrefix>, #[prop(optional)] auto_complete_prefix: Option<AutoCompletePrefix>,
#[prop(optional)] auto_complete_suffix: Option<AutoCompleteSuffix>, #[prop(optional)] auto_complete_suffix: Option<AutoCompleteSuffix>,
#[prop(optional)] comp_ref: ComponentRef<AutoCompleteRef>, #[prop(optional)] comp_ref: ComponentRef<AutoCompleteRef>,
#[prop(attrs)] attrs: Vec<(&'static str, Attribute)>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("auto-complete", include_str!("./auto-complete.css")); mount_style("auto-complete", include_str!("./auto-complete.css"));
let theme = use_theme(Theme::light); let theme = use_theme(Theme::light);
@ -133,6 +134,7 @@ pub fn AutoComplete(
on:keydown=on_keydown on:keydown=on_keydown
> >
<Input <Input
attrs
value value
placeholder placeholder
disabled disabled

View file

@ -15,6 +15,7 @@ pub use theme::DatePickerTheme;
pub fn DatePicker( pub fn DatePicker(
#[prop(optional, into)] value: RwSignal<Option<NaiveDate>>, #[prop(optional, into)] value: RwSignal<Option<NaiveDate>>,
#[prop(optional, into)] class: MaybeSignal<String>, #[prop(optional, into)] class: MaybeSignal<String>,
#[prop(attrs)] attrs: Vec<(&'static str, Attribute)>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("date-picker", include_str!("./date-picker.css")); mount_style("date-picker", include_str!("./date-picker.css"));
let date_picker_ref = create_node_ref::<html::Div>(); let date_picker_ref = create_node_ref::<html::Div>();
@ -73,7 +74,7 @@ pub fn DatePicker(
view! { view! {
<Binder target_ref=date_picker_ref> <Binder target_ref=date_picker_ref>
<div ref=date_picker_ref> <div ref=date_picker_ref>
<Input class value=show_date_text on_focus=open_panel on_blur=on_input_blur> <Input attrs class value=show_date_text on_focus=open_panel on_blur=on_input_blur>
<InputSuffix slot> <InputSuffix slot>
<Icon icon=Icon::from(AiIcon::AiCalendarOutlined) style="font-size: 18px"/> <Icon icon=Icon::from(AiIcon::AiCalendarOutlined) style="font-size: 18px"/>
</InputSuffix> </InputSuffix>

View file

@ -51,6 +51,7 @@ pub fn Input(
#[prop(optional)] input_suffix: Option<InputSuffix>, #[prop(optional)] input_suffix: Option<InputSuffix>,
#[prop(optional)] comp_ref: ComponentRef<InputRef>, #[prop(optional)] comp_ref: ComponentRef<InputRef>,
#[prop(optional, into)] class: MaybeSignal<String>, #[prop(optional, into)] class: MaybeSignal<String>,
#[prop(attrs)] attrs: Vec<(&'static str, Attribute)>,
) -> impl IntoView { ) -> impl IntoView {
let theme = use_theme(Theme::light); let theme = use_theme(Theme::light);
mount_style("input", include_str!("./input.css")); mount_style("input", include_str!("./input.css"));
@ -125,6 +126,19 @@ pub fn Input(
comp_ref.load(InputRef { input_ref }); comp_ref.load(InputRef { input_ref });
}); });
#[cfg(debug_assertions)]
{
const INNER_ATTRS: [&'static str; 4] = ["type", "class", "disabled", "placeholder"];
attrs.iter().for_each(|attr| {
if INNER_ATTRS.contains(&attr.0) {
logging::warn!(
"Thaw: The '{}' attribute already exists on elements inside the Input component, which may cause conflicts.",
attr.0
);
}
});
}
view! { view! {
<div <div
class=class_list![ class=class_list![
@ -142,6 +156,7 @@ pub fn Input(
}} }}
<input <input
{..attrs}
type=move || variant.get().as_str() type=move || variant.get().as_str()
prop:value=move || { prop:value=move || {
value_trigger.track(); value_trigger.track();

View file

@ -12,6 +12,7 @@ pub fn InputNumber<T>(
#[prop(optional, into)] disabled: MaybeSignal<bool>, #[prop(optional, into)] disabled: MaybeSignal<bool>,
#[prop(optional, into)] invalid: MaybeSignal<bool>, #[prop(optional, into)] invalid: MaybeSignal<bool>,
#[prop(optional, into)] class: MaybeSignal<String>, #[prop(optional, into)] class: MaybeSignal<String>,
#[prop(attrs)] attrs: Vec<(&'static str, Attribute)>,
) -> impl IntoView ) -> impl IntoView
where where
T: Add<Output = T> + Sub<Output = T>, T: Add<Output = T> + Sub<Output = T>,
@ -47,7 +48,7 @@ where
value.set(value.get_untracked() - step.get_untracked()); value.set(value.get_untracked() - step.get_untracked());
}); });
view! { view! {
<Input class value=input_value allow_value placeholder disabled invalid> <Input attrs class value=input_value allow_value placeholder disabled invalid>
<InputSuffix slot> <InputSuffix slot>
<Button disabled variant=ButtonVariant::Link on_click=sub> <Button disabled variant=ButtonVariant::Link on_click=sub>
<Icon icon=Icon::from(AiIcon::AiMinusOutlined) style="font-size: 18px"/> <Icon icon=Icon::from(AiIcon::AiMinusOutlined) style="font-size: 18px"/>

View file

@ -14,6 +14,7 @@ pub use theme::TimePickerTheme;
pub fn TimePicker( pub fn TimePicker(
#[prop(optional, into)] value: RwSignal<Option<NaiveTime>>, #[prop(optional, into)] value: RwSignal<Option<NaiveTime>>,
#[prop(optional, into)] class: MaybeSignal<String>, #[prop(optional, into)] class: MaybeSignal<String>,
#[prop(attrs)] attrs: Vec<(&'static str, Attribute)>,
) -> impl IntoView { ) -> impl IntoView {
mount_style("time-picker", include_str!("./time-picker.css")); mount_style("time-picker", include_str!("./time-picker.css"));
let time_picker_ref = create_node_ref::<html::Div>(); let time_picker_ref = create_node_ref::<html::Div>();
@ -73,7 +74,7 @@ pub fn TimePicker(
view! { view! {
<Binder target_ref=time_picker_ref> <Binder target_ref=time_picker_ref>
<div ref=time_picker_ref> <div ref=time_picker_ref>
<Input class value=show_time_text on_focus=open_panel on_blur=on_input_blur> <Input attrs class value=show_time_text on_focus=open_panel on_blur=on_input_blur>
<InputSuffix slot> <InputSuffix slot>
<Icon <Icon
icon=Icon::from(AiIcon::AiClockCircleOutlined) icon=Icon::from(AiIcon::AiClockCircleOutlined)