cosmic/widget/button/
link.rs1use super::{Builder, ButtonClass};
7use crate::Element;
8use crate::prelude::*;
9use crate::widget::icon::{self, Handle};
10use crate::widget::{button, row, tooltip};
11use iced_core::font::Weight;
12use iced_core::text::LineHeight;
13use iced_core::widget::Id;
14use iced_core::{Alignment, Length, Padding};
15use std::borrow::Cow;
16
17pub type Button<'a, Message> = Builder<'a, Message, Hyperlink>;
18
19pub struct Hyperlink {
20 trailing_icon: bool,
21}
22
23pub fn link<'a, Message>(label: impl Into<Cow<'a, str>> + 'static) -> Button<'a, Message> {
25 Button::new(
26 label,
27 Hyperlink {
28 trailing_icon: false,
29 },
30 )
31}
32
33impl<'a, Message> Button<'a, Message> {
34 pub fn new(label: impl Into<Cow<'a, str>> + 'static, link: Hyperlink) -> Self {
35 Self {
36 id: Id::unique(),
37 label: label.into(),
38 #[cfg(feature = "a11y")]
39 name: Cow::Borrowed(""),
40 #[cfg(feature = "a11y")]
41 description: Cow::Borrowed(""),
42 tooltip: Cow::Borrowed(""),
43 on_press: None,
44 width: Length::Shrink,
45 height: Length::Shrink,
46 padding: Padding::from(4),
47 spacing: 0,
48 icon_size: 16,
49 line_height: 20,
50 font_size: 14,
51 font_weight: Weight::Normal,
52 class: ButtonClass::Link,
53 variant: link,
54 }
55 }
56
57 pub const fn trailing_icon(mut self, set: bool) -> Self {
58 self.variant.trailing_icon = set;
59 self
60 }
61}
62
63#[inline(never)]
64pub fn icon() -> Handle {
65 icon::from_svg_bytes(&include_bytes!("external-link.svg")[..]).symbolic(true)
66}
67
68impl<'a, Message: Clone + 'static> From<Button<'a, Message>> for Element<'a, Message> {
69 fn from(mut builder: Button<'a, Message>) -> Element<'a, Message> {
70 let mut button: super::Button<'a, Message> = row::with_capacity(2)
71 .push({
72 crate::widget::text(builder.label.to_string())
74 .size(builder.font_size)
75 .line_height(LineHeight::Absolute(builder.line_height.into()))
76 .font(crate::font::Font {
77 weight: builder.font_weight,
78 ..crate::font::default()
79 })
80 })
81 .push_maybe(if builder.variant.trailing_icon {
82 Some(icon().icon().size(builder.icon_size))
83 } else {
84 None
85 })
86 .padding(builder.padding)
87 .width(builder.width)
88 .height(builder.height)
89 .spacing(builder.spacing)
90 .align_y(Alignment::Center)
91 .apply(button::custom)
92 .padding(0)
93 .id(builder.id)
94 .on_press_maybe(builder.on_press.take())
95 .class(builder.class);
96
97 #[cfg(feature = "a11y")]
98 {
99 if !builder.label.is_empty() {
100 button = button.name(builder.label);
101 }
102
103 button = button.description(builder.description);
104 }
105
106 if builder.tooltip.is_empty() {
107 button.into()
108 } else {
109 tooltip(
110 button,
111 crate::widget::text(builder.tooltip)
112 .size(builder.font_size)
113 .font(crate::font::Font {
114 weight: builder.font_weight,
115 ..crate::font::default()
116 }),
117 tooltip::Position::Top,
118 )
119 .into()
120 }
121 }
122}