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