///|
pub(all) enum InputGroupAddonAlign {
InputInlineStart
InputInlineEnd
InputBlockStart
InputBlockEnd
} derive(Debug, Eq)
///|
pub(all) enum InputGroupButtonSize {
InputButtonXs
InputButtonSm
InputButtonIconXs
InputButtonIconSm
} derive(Debug, Eq)
///|
fn input_group_align_value(align : InputGroupAddonAlign) -> String {
match align {
InputInlineStart => "inline-start"
InputInlineEnd => "inline-end"
InputBlockStart => "block-start"
InputBlockEnd => "block-end"
}
}
///|
fn input_group_align_style(align : InputGroupAddonAlign) -> String {
match align {
InputInlineStart => "order:-1;padding-inline-start:0.5rem"
InputInlineEnd => "order:1;padding-inline-end:0.5rem"
InputBlockStart =>
"order:-1;width:100%;justify-content:flex-start;padding:0.5rem 0.625rem 0"
InputBlockEnd =>
"order:1;width:100%;justify-content:flex-start;padding:0 0.625rem 0.5rem"
}
}
///|
pub fn[C : @html.IsChildren] input_group(
disabled? : Bool = false,
invalid? : Bool = false,
id? : String,
class? : String,
title? : String,
attrs? : @html.Attrs,
style? : Array[String] = [],
children : C,
) -> @html.Html {
let group_attrs = ui_attrs(attrs)
.role("group")
.data_set("slot", "input-group")
if disabled {
ignore(group_attrs.aria_disabled("true").data_set("disabled", ""))
}
if invalid {
ignore(group_attrs.aria_invalid("true").data_set("invalid", ""))
}
@html.div(
id?,
class?,
title?,
attrs=group_attrs,
style=ui_styles(
[
UiBoxSizing,
UiFontSans,
UiTransition,
"position:relative;display:flex;width:100%;height:2rem;min-width:0;min-height:2rem;align-items:center;--rui-control-base-bg:var(--rui-input-background,transparent);--rui-control-base-fg:var(--rui-foreground,oklch(0.145 0 0));--rui-control-base-border:var(--rui-input,oklch(0.922 0 0));--rui-control-base-shadow:0 0 #0000;border:1px solid transparent;border-color:var(--rui-control-border,var(--rui-control-base-border,var(--rui-input,oklch(0.922 0 0))));border-radius:var(--rui-radius,0.625rem);background:var(--rui-control-bg,var(--rui-control-base-bg,var(--rui-input-background,transparent)));color:var(--rui-control-fg,var(--rui-control-base-fg,var(--rui-foreground,oklch(0.145 0 0))));box-shadow:var(--rui-control-shadow,var(--rui-control-base-shadow,0 0 #0000));outline:none",
if invalid {
InputInvalidStyle
} else {
""
},
ui_disabled_visual_style(disabled),
],
style,
),
children,
)
}
///|
pub fn[C : @html.IsChildren] input_group_addon(
align? : InputGroupAddonAlign = InputInlineStart,
for_? : String,
id? : String,
class? : String,
title? : String,
attrs? : @html.Attrs,
style? : Array[String] = [],
children : C,
) -> @html.Html {
let addon_attrs = ui_attrs(attrs)
.role("group")
.data_set("slot", "input-group-addon")
.data_set("align", input_group_align_value(align))
let addon_style = ui_styles(
[
"display:flex;height:auto;align-items:center;justify-content:center;gap:0.5rem;padding-block:0.375rem;color:var(--rui-muted-foreground,oklch(0.556 0 0));font-size:0.875rem;font-weight:500;user-select:none;cursor:text",
input_group_align_style(align),
],
style,
)
if for_ is Some(for_) {
@html.label(
for_~,
id?,
class?,
title?,
attrs=addon_attrs,
style=addon_style,
children,
)
} else {
@html.div(
id?,
class?,
title?,
attrs=addon_attrs,
style=addon_style,
children,
)
}
}
///|
pub fn[C : @html.IsChildren] input_group_text(
id? : String,
class? : String,
title? : String,
attrs? : @html.Attrs,
style? : Array[String] = [],
children : C,
) -> @html.Html {
@html.span(
id?,
class?,
title?,
attrs=ui_attrs(attrs).data_set("slot", "input-group-text"),
style=ui_styles(
[
"display:flex;align-items:center;gap:0.5rem;color:var(--rui-muted-foreground,oklch(0.556 0 0));font-size:0.875rem",
],
style,
),
children,
)
}
///|
/// Adapt a custom form control to the Input Group surface.
///
/// The callback receives the complete public control-slot attributes and the
/// shared nested-control style. Add only control-specific behavior through
/// `style`; callers never need to know the Input Group's internal data slots.
pub fn input_group_control(
attrs? : @html.Attrs,
style? : Array[String] = [],
render : (@html.Attrs, Array[String]) -> @html.Html,
) -> @html.Html {
let control_attrs = ui_attrs(attrs)
.data_set("slot", "input-group-control")
.data_set("input-group-control", "")
render(
control_attrs,
ui_styles(
[
"display:flex;width:100%;min-width:0;min-height:2rem;flex:1;border:0;border-radius:0;background:transparent;padding:0.625rem;color:inherit;font:inherit;box-shadow:none;outline:none",
],
style,
),
)
}
///|
fn input_group_button_size(size : InputGroupButtonSize) -> (ButtonSize, String) {
match size {
InputButtonXs => (Xs, "xs")
InputButtonSm => (Sm, "sm")
InputButtonIconXs => (IconXs, "icon-xs")
InputButtonIconSm => (IconSm, "icon-sm")
}
}
///|
fn input_group_button_size_style(size : InputGroupButtonSize) -> String {
match size {
InputButtonXs | InputButtonIconXs =>
"--rui-control-radius:calc(var(--rui-radius,0.625rem) - 0.1875rem)"
InputButtonSm | InputButtonIconSm => ""
}
}
///|
pub fn[C : @html.IsChildren] input_group_button(
size? : InputGroupButtonSize = InputButtonXs,
variant? : ButtonVariant = Ghost,
disabled? : Bool = false,
on_click? : @cmd.Cmd,
id? : String,
class? : String,
title? : String,
attrs? : @html.Attrs,
style? : Array[String] = [],
children : C,
) -> @html.Html {
let (button_size, size_value) = input_group_button_size(size)
button(
variant~,
size=button_size,
disabled~,
slot="input-group-button",
on_click?,
id?,
class?,
title?,
attrs=ui_attrs(attrs)
.data_set("slot", "input-group-button")
.data_set("size", size_value),
style=ui_styles(
["--rui-button-base-shadow:none", input_group_button_size_style(size)],
style,
),
children,
)
}
///|
pub fn input_group_input(
input_type? : @html.InputType = @html.Text,
name? : String,
value? : String,
placeholder? : String,
read_only? : Bool,
disabled? : Bool = false,
required? : Bool,
autofocus? : Bool,
invalid? : Bool = false,
on_change? : @cmd.Emit[String],
on_input? : @cmd.Emit[String],
id? : String,
class? : String,
title? : String,
attrs? : @html.Attrs,
style? : Array[String] = [],
) -> @html.Html {
input(
input_type~,
name?,
value?,
placeholder?,
read_only?,
disabled~,
required?,
autofocus?,
invalid~,
on_change?,
on_input?,
id?,
class?,
title?,
attrs=ui_attrs(attrs).data_set("input-group-control", ""),
slot="input-group-control",
style=ui_styles(
[
"height:100%;min-height:0;flex:1;border:0;border-radius:0;background:transparent;box-shadow:none;outline:none",
],
style,
),
)
}
///|
pub fn input_group_textarea(
name? : String,
value? : String,
rows? : Int,
cols? : Int,
placeholder? : String,
read_only? : Bool,
disabled? : Bool = false,
required? : Bool,
autofocus? : Bool,
invalid? : Bool = false,
on_change? : @cmd.Emit[String],
on_input? : @cmd.Emit[String],
id? : String,
class? : String,
title? : String,
attrs? : @html.Attrs,
style? : Array[String] = [],
) -> @html.Html {
textarea(
name?,
value?,
rows?,
cols?,
placeholder?,
read_only?,
disabled~,
required?,
autofocus?,
invalid~,
on_change?,
on_input?,
id?,
class?,
title?,
attrs=ui_attrs(attrs).data_set("input-group-control", ""),
slot="input-group-control",
style=ui_styles(
[
"min-height:5rem;flex:1;resize:none;border:0;border-radius:0;background:transparent;padding-block:0.5rem;box-shadow:none;outline:none",
],
style,
),
)
}