1import { font_families, font_sizes, FontWeight } from "../common"
2import { Layer, Styles, StyleSets, Style } from "../theme/create_theme"
3
4function is_style_set(key: any): key is StyleSets {
5 return [
6 "base",
7 "variant",
8 "on",
9 "accent",
10 "positive",
11 "warning",
12 "negative",
13 ].includes(key)
14}
15
16function is_style(key: any): key is Styles {
17 return [
18 "default",
19 "active",
20 "disabled",
21 "hovered",
22 "pressed",
23 "inverted",
24 ].includes(key)
25}
26function get_style(
27 layer: Layer,
28 possible_style_set_or_style?: any,
29 possible_style?: any
30): Style {
31 let style_set: StyleSets = "base"
32 let style: Styles = "default"
33 if (is_style_set(possible_style_set_or_style)) {
34 style_set = possible_style_set_or_style
35 } else if (is_style(possible_style_set_or_style)) {
36 style = possible_style_set_or_style
37 }
38
39 if (is_style(possible_style)) {
40 style = possible_style
41 }
42
43 return layer[style_set][style]
44}
45
46export function background(layer: Layer, style?: Styles): string
47export function background(
48 layer: Layer,
49 style_set?: StyleSets,
50 style?: Styles
51): string
52export function background(
53 layer: Layer,
54 style_set_or_styles?: StyleSets | Styles,
55 style?: Styles
56): string {
57 return get_style(layer, style_set_or_styles, style).background
58}
59
60export function border_color(layer: Layer, style?: Styles): string
61export function border_color(
62 layer: Layer,
63 style_set?: StyleSets,
64 style?: Styles
65): string
66export function border_color(
67 layer: Layer,
68 style_set_or_styles?: StyleSets | Styles,
69 style?: Styles
70): string {
71 return get_style(layer, style_set_or_styles, style).border
72}
73
74export function foreground(layer: Layer, style?: Styles): string
75export function foreground(
76 layer: Layer,
77 style_set?: StyleSets,
78 style?: Styles
79): string
80export function foreground(
81 layer: Layer,
82 style_set_or_styles?: StyleSets | Styles,
83 style?: Styles
84): string {
85 return get_style(layer, style_set_or_styles, style).foreground
86}
87
88export interface TextStyle extends Object {
89 family: keyof typeof font_families
90 color: string
91 size: number
92 weight?: FontWeight
93 underline?: boolean
94}
95
96export interface TextProperties {
97 size?: keyof typeof font_sizes
98 weight?: FontWeight
99 underline?: boolean
100 color?: string
101 features?: FontFeatures
102}
103
104interface FontFeatures {
105 /** Contextual Alternates: Applies a second substitution feature based on a match of a character pattern within a context of surrounding patterns */
106 calt?: boolean
107 /** Case-Sensitive Forms: Shifts various punctuation marks up to a position that works better with all-capital sequences */
108 case?: boolean
109 /** Capital Spacing: Adjusts inter-glyph spacing for all-capital text */
110 cpsp?: boolean
111 /** Fractions: Replaces figures separated by a slash with diagonal fractions */
112 frac?: boolean
113 /** Standard Ligatures: Replaces a sequence of glyphs with a single glyph which is preferred for typographic purposes */
114 liga?: boolean
115 /** Oldstyle Figures: Changes selected figures from the default or lining style to oldstyle form. */
116 onum?: boolean
117 /** Ordinals: Replaces default alphabetic glyphs with the corresponding ordinal forms for use after figures */
118 ordn?: boolean
119 /** Proportional Figures: Replaces figure glyphs set on uniform (tabular) widths with corresponding glyphs set on proportional widths */
120 pnum?: boolean
121 /** Stylistic set 01 */
122 ss01?: boolean
123 /** Stylistic set 02 */
124 ss02?: boolean
125 /** Stylistic set 03 */
126 ss03?: boolean
127 /** Stylistic set 04 */
128 ss04?: boolean
129 /** Stylistic set 05 */
130 ss05?: boolean
131 /** Stylistic set 06 */
132 ss06?: boolean
133 /** Stylistic set 07 */
134 ss07?: boolean
135 /** Stylistic set 08 */
136 ss08?: boolean
137 /** Stylistic set 09 */
138 ss09?: boolean
139 /** Stylistic set 10 */
140 ss10?: boolean
141 /** Stylistic set 11 */
142 ss11?: boolean
143 /** Stylistic set 12 */
144 ss12?: boolean
145 /** Stylistic set 13 */
146 ss13?: boolean
147 /** Stylistic set 14 */
148 ss14?: boolean
149 /** Stylistic set 15 */
150 ss15?: boolean
151 /** Stylistic set 16 */
152 ss16?: boolean
153 /** Stylistic set 17 */
154 ss17?: boolean
155 /** Stylistic set 18 */
156 ss18?: boolean
157 /** Stylistic set 19 */
158 ss19?: boolean
159 /** Stylistic set 20 */
160 ss20?: boolean
161 /** Subscript: Replaces default glyphs with subscript glyphs */
162 subs?: boolean
163 /** Superscript: Replaces default glyphs with superscript glyphs */
164 sups?: boolean
165 /** Swash: Replaces default glyphs with swash glyphs for stylistic purposes */
166 swsh?: boolean
167 /** Titling: Replaces default glyphs with titling glyphs for use in large-size settings */
168 titl?: boolean
169 /** Tabular Figures: Replaces figure glyphs set on proportional widths with corresponding glyphs set on uniform (tabular) widths */
170 tnum?: boolean
171 /** Slashed Zero: Replaces default zero with a slashed zero for better distinction between "0" and "O" */
172 zero?: boolean
173}
174
175export function text(
176 layer: Layer,
177 font_family: keyof typeof font_families,
178 style_set: StyleSets,
179 style: Styles,
180 properties?: TextProperties
181): TextStyle
182export function text(
183 layer: Layer,
184 font_family: keyof typeof font_families,
185 style_set: StyleSets,
186 properties?: TextProperties
187): TextStyle
188export function text(
189 layer: Layer,
190 font_family: keyof typeof font_families,
191 style: Styles,
192 properties?: TextProperties
193): TextStyle
194export function text(
195 layer: Layer,
196 font_family: keyof typeof font_families,
197 properties?: TextProperties
198): TextStyle
199export function text(
200 layer: Layer,
201 font_family: keyof typeof font_families,
202 style_set_style_or_properties?: StyleSets | Styles | TextProperties,
203 style_or_properties?: Styles | TextProperties,
204 properties?: TextProperties
205) {
206 const style = get_style(
207 layer,
208 style_set_style_or_properties,
209 style_or_properties
210 )
211
212 if (typeof style_set_style_or_properties === "object") {
213 properties = style_set_style_or_properties
214 }
215 if (typeof style_or_properties === "object") {
216 properties = style_or_properties
217 }
218
219 const size = font_sizes[properties?.size || "sm"]
220 const color = properties?.color || style.foreground
221
222 return {
223 family: font_families[font_family],
224 ...properties,
225 color,
226 size,
227 }
228}
229
230export interface Border {
231 color: string
232 width: number
233 top?: boolean
234 bottom?: boolean
235 left?: boolean
236 right?: boolean
237 overlay?: boolean
238}
239
240export interface BorderProperties {
241 width?: number
242 top?: boolean
243 bottom?: boolean
244 left?: boolean
245 right?: boolean
246 overlay?: boolean
247}
248
249export function border(
250 layer: Layer,
251 style_set: StyleSets,
252 style: Styles,
253 properties?: BorderProperties
254): Border
255export function border(
256 layer: Layer,
257 style_set: StyleSets,
258 properties?: BorderProperties
259): Border
260export function border(
261 layer: Layer,
262 style: Styles,
263 properties?: BorderProperties
264): Border
265export function border(layer: Layer, properties?: BorderProperties): Border
266export function border(
267 layer: Layer,
268 style_set_or_properties?: StyleSets | Styles | BorderProperties,
269 style_or_properties?: Styles | BorderProperties,
270 properties?: BorderProperties
271): Border {
272 const style = get_style(layer, style_set_or_properties, style_or_properties)
273
274 if (typeof style_set_or_properties === "object") {
275 properties = style_set_or_properties
276 }
277 if (typeof style_or_properties === "object") {
278 properties = style_or_properties
279 }
280
281 return {
282 color: style.border,
283 width: 1,
284 ...properties,
285 }
286}
287
288export function svg(
289 color: string,
290 asset: string,
291 width: number,
292 height: number
293) {
294 return {
295 color,
296 asset,
297 dimensions: {
298 width,
299 height,
300 },
301 }
302}