Skip to content

Commit d62fbc6

Browse files
committed
Support top level links
1 parent edd2d15 commit d62fbc6

File tree

7 files changed

+115
-20
lines changed

7 files changed

+115
-20
lines changed

definitions.kt

+20
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,24 @@ enum class TextAutoResize(val string: String) {
336336
Truncate("TRUNCATE"),
337337
}
338338

339+
/// Type of hyperlink
340+
@Serializable
341+
enum class HyperlinkType(val string: String) {
342+
@SerialName("URL")
343+
Url("URL"),
344+
@SerialName("NODE")
345+
Node("NODE"),
346+
}
347+
348+
@Serializable
349+
data class Hyperlink (
350+
val type: HyperlinkType? = null,
351+
/// URL being linked to, if URL type
352+
val url: String? = null,
353+
/// ID of frame hyperlink points to, if NODE type
354+
val nodeId: String? = null
355+
)
356+
339357
/// Metadata for character formatting
340358
///
341359
/// [Figma documentation](https://www.figma.com/developers/api#typestyle-type)
@@ -357,6 +375,8 @@ data class TypeStyle (
357375
val textDecoration: TextDecoration? = null,
358376
/// Dimensions along which text will auto resize, default is that the text does not auto-resize
359377
val textAutoResize: TextAutoResize? = null,
378+
/// Link to a URL or frame
379+
val hyperlink: Hyperlink? = null,
360380
/// Line height in px
361381
val lineHeightPx: Double
362382
)

definitions.swift

+24-1
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,26 @@ public enum TextAutoResize: String, Codable {
287287
case truncate = "TRUNCATE"
288288
}
289289

290+
/// Type of hyperlink
291+
public enum HyperlinkType: String, Codable {
292+
case url = "URL"
293+
case node = "NODE"
294+
}
295+
296+
public struct Hyperlink: Codable {
297+
public let type: HyperlinkType?
298+
/// URL being linked to, if URL type
299+
public let url: String?
300+
/// ID of frame hyperlink points to, if NODE type
301+
public let nodeId: String?
302+
303+
public init(type: HyperlinkType?, url: String?, nodeId: String?) {
304+
self.type = type
305+
self.url = url
306+
self.nodeId = nodeId
307+
}
308+
}
309+
290310
/// Metadata for character formatting
291311
///
292312
/// [Figma documentation](https://www.figma.com/developers/api#typestyle-type)
@@ -307,10 +327,12 @@ public struct TypeStyle: Codable {
307327
public let textDecoration: TextDecoration?
308328
/// Dimensions along which text will auto resize, default is that the text does not auto-resize
309329
public let textAutoResize: TextAutoResize?
330+
/// Link to a URL or frame
331+
public let hyperlink: Hyperlink?
310332
/// Line height in px
311333
public let lineHeightPx: Double
312334

313-
public init(fontFamily: String, paragraphSpacing: Double?, italic: Bool?, fontWeight: Double, fontSize: Double, textCase: TextCase?, textDecoration: TextDecoration?, textAutoResize: TextAutoResize?, lineHeightPx: Double) {
335+
public init(fontFamily: String, paragraphSpacing: Double?, italic: Bool?, fontWeight: Double, fontSize: Double, textCase: TextCase?, textDecoration: TextDecoration?, textAutoResize: TextAutoResize?, hyperlink: Hyperlink?, lineHeightPx: Double) {
314336
self.fontFamily = fontFamily
315337
self.paragraphSpacing = paragraphSpacing
316338
self.italic = italic
@@ -319,6 +341,7 @@ public struct TypeStyle: Codable {
319341
self.textCase = textCase
320342
self.textDecoration = textDecoration
321343
self.textAutoResize = textAutoResize
344+
self.hyperlink = hyperlink
322345
self.lineHeightPx = lineHeightPx
323346
}
324347
}

example-figma-files/gov-uk-design-system-components/get-started-page.html

+6-4
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@
133133
data-figma-name="Content: Body"
134134
data-figma-id="863:121"
135135
>Last updated: 26 March 2023</div
136-
><div
136+
><a
137137
style="
138138
color: var(--Link-Default);
139139
font: 300 19px / 24px GDS Transport Website, arial, sans-serif;
@@ -144,7 +144,8 @@
144144
"
145145
data-figma-name="Action: Link"
146146
data-figma-id="863:122"
147-
>Original File</div
147+
href="#"
148+
>Original File</a
148149
></div
149150
><div
150151
style="
@@ -464,7 +465,7 @@
464465
components from this file using the Assets navigation tab next to
465466
the Layers navigation tab.</p
466467
></div
467-
><div
468+
><a
468469
style="
469470
color: var(--Link-Default);
470471
font: 400 19px / 24px GDS Transport Website, arial, sans-serif;
@@ -475,7 +476,8 @@
475476
"
476477
data-figma-name="Action: Link"
477478
data-figma-id="780:110"
478-
>Download GDS Transport</div
479+
href="https://www.dropbox.com/sh/r505onxpqmgan0i/AABpCj5rAzK98eolXHYIifvXa?dl=0"
480+
>Download GDS Transport</a
479481
><div
480482
style="
481483
color: var(--Text-Secondary);

figma-schema/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ pub use self::{
2828
rectangle::Rectangle,
2929
style::{Style, StyleType},
3030
styles::Styles,
31-
type_style::{TextAutoResize, TextCase, TextDecoration, TypeStyle},
31+
type_style::{Hyperlink, HyperlinkType, TextAutoResize, TextCase, TextDecoration, TypeStyle},
3232
vector::Vector,
3333
};

figma-schema/src/type_style.rs

+22
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,26 @@ pub enum TextAutoResize {
2929
Truncate,
3030
}
3131

32+
/// Type of hyperlink
33+
#[derive(Debug, Deserialize, Serialize)]
34+
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
35+
#[typeshare::typeshare]
36+
pub enum HyperlinkType {
37+
Url,
38+
Node,
39+
}
40+
41+
#[derive(Debug, Deserialize, Serialize)]
42+
#[serde(rename_all = "camelCase")]
43+
#[typeshare::typeshare]
44+
pub struct Hyperlink {
45+
pub r#type: Option<HyperlinkType>,
46+
/// URL being linked to, if URL type
47+
pub url: Option<String>,
48+
/// ID of frame hyperlink points to, if NODE type
49+
pub node_id: Option<String>,
50+
}
51+
3252
/// Metadata for character formatting
3353
///
3454
/// [Figma documentation](https://www.figma.com/developers/api#typestyle-type)
@@ -55,6 +75,8 @@ pub struct TypeStyle {
5575
pub text_decoration: Option<TextDecoration>,
5676
/// Dimensions along which text will auto resize, default is that the text does not auto-resize
5777
pub text_auto_resize: Option<TextAutoResize>,
78+
/// Link to a URL or frame
79+
pub hyperlink: Option<Hyperlink>,
5880
/// Line height in px
5981
pub line_height_px: f64,
6082
}

src/to_html/mod.rs

+26-14
Original file line numberDiff line numberDiff line change
@@ -114,22 +114,34 @@ fn node_to_html(node: &Node, parent: Option<&Node>, css_variables: &mut CSSVaria
114114
Some(c) => c,
115115
};
116116

117-
html! {
118-
div(
119-
style?=style.as_deref(),
120-
data-figma-name=&node.name,
121-
data-figma-id=&node.id
122-
) {
123-
@ if !characters.contains('\n') {
124-
: &characters
125-
} else {
126-
@ for line in characters.split('\n') {
127-
p(style="margin: 0;") {
128-
: line
129-
}
117+
let inner = html! {
118+
@ if !characters.contains('\n') {
119+
: &characters
120+
} else {
121+
@ for line in characters.split('\n') {
122+
p(style="margin: 0;") {
123+
: line
130124
}
131125
}
132-
}
126+
}
127+
};
128+
let hyperlink = node.style.as_ref().and_then(|s| s.hyperlink.as_ref());
129+
130+
html! {
131+
@ if let Some(hyperlink) = hyperlink {
132+
a(
133+
style?=style.as_deref(),
134+
data-figma-name=&node.name,
135+
data-figma-id=&node.id,
136+
href=hyperlink.url.as_deref().unwrap_or("#")
137+
) { : &inner }
138+
} else {
139+
div(
140+
style?=style.as_deref(),
141+
data-figma-name=&node.name,
142+
data-figma-id=&node.id
143+
) { : &inner }
144+
}
133145
}
134146
.to_string()
135147
}

typescript/index.d.ts

+16
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,20 @@ export enum TextAutoResize {
237237
Truncate = "TRUNCATE",
238238
}
239239

240+
/** Type of hyperlink */
241+
export enum HyperlinkType {
242+
Url = "URL",
243+
Node = "NODE",
244+
}
245+
246+
export interface Hyperlink {
247+
type?: HyperlinkType;
248+
/** URL being linked to, if URL type */
249+
url?: string;
250+
/** ID of frame hyperlink points to, if NODE type */
251+
nodeId?: string;
252+
}
253+
240254
/**
241255
* Metadata for character formatting
242256
*
@@ -259,6 +273,8 @@ export interface TypeStyle {
259273
textDecoration?: TextDecoration;
260274
/** Dimensions along which text will auto resize, default is that the text does not auto-resize */
261275
textAutoResize?: TextAutoResize;
276+
/** Link to a URL or frame */
277+
hyperlink?: Hyperlink;
262278
/** Line height in px */
263279
lineHeightPx: number;
264280
}

0 commit comments

Comments
 (0)