components.ts

  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}