components.ts

  1import { fontFamilies, fontSizes, FontWeight } from "../common"
  2import { Layer, Styles, StyleSets, Style } from "../theme/colorScheme"
  3
  4function isStyleSet(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 isStyle(key: any): key is Styles {
 17    return [
 18        "default",
 19        "active",
 20        "disabled",
 21        "hovered",
 22        "pressed",
 23        "inverted",
 24    ].includes(key)
 25}
 26function getStyle(
 27    layer: Layer,
 28    possibleStyleSetOrStyle?: any,
 29    possibleStyle?: any
 30): Style {
 31    let styleSet: StyleSets = "base"
 32    let style: Styles = "default"
 33    if (isStyleSet(possibleStyleSetOrStyle)) {
 34        styleSet = possibleStyleSetOrStyle
 35    } else if (isStyle(possibleStyleSetOrStyle)) {
 36        style = possibleStyleSetOrStyle
 37    }
 38
 39    if (isStyle(possibleStyle)) {
 40        style = possibleStyle
 41    }
 42
 43    return layer[styleSet][style]
 44}
 45
 46export function background(layer: Layer, style?: Styles): string
 47export function background(
 48    layer: Layer,
 49    styleSet?: StyleSets,
 50    style?: Styles
 51): string
 52export function background(
 53    layer: Layer,
 54    styleSetOrStyles?: StyleSets | Styles,
 55    style?: Styles
 56): string {
 57    return getStyle(layer, styleSetOrStyles, style).background
 58}
 59
 60export function borderColor(layer: Layer, style?: Styles): string
 61export function borderColor(
 62    layer: Layer,
 63    styleSet?: StyleSets,
 64    style?: Styles
 65): string
 66export function borderColor(
 67    layer: Layer,
 68    styleSetOrStyles?: StyleSets | Styles,
 69    style?: Styles
 70): string {
 71    return getStyle(layer, styleSetOrStyles, style).border
 72}
 73
 74export function foreground(layer: Layer, style?: Styles): string
 75export function foreground(
 76    layer: Layer,
 77    styleSet?: StyleSets,
 78    style?: Styles
 79): string
 80export function foreground(
 81    layer: Layer,
 82    styleSetOrStyles?: StyleSets | Styles,
 83    style?: Styles
 84): string {
 85    return getStyle(layer, styleSetOrStyles, style).foreground
 86}
 87
 88interface Text {
 89    family: keyof typeof fontFamilies
 90    color: string
 91    size: number
 92    weight?: FontWeight
 93    underline?: boolean
 94}
 95
 96export interface TextProperties {
 97    size?: keyof typeof fontSizes
 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    fontFamily: keyof typeof fontFamilies,
178    styleSet: StyleSets,
179    style: Styles,
180    properties?: TextProperties
181): Text
182export function text(
183    layer: Layer,
184    fontFamily: keyof typeof fontFamilies,
185    styleSet: StyleSets,
186    properties?: TextProperties
187): Text
188export function text(
189    layer: Layer,
190    fontFamily: keyof typeof fontFamilies,
191    style: Styles,
192    properties?: TextProperties
193): Text
194export function text(
195    layer: Layer,
196    fontFamily: keyof typeof fontFamilies,
197    properties?: TextProperties
198): Text
199export function text(
200    layer: Layer,
201    fontFamily: keyof typeof fontFamilies,
202    styleSetStyleOrProperties?: StyleSets | Styles | TextProperties,
203    styleOrProperties?: Styles | TextProperties,
204    properties?: TextProperties
205) {
206    let style = getStyle(layer, styleSetStyleOrProperties, styleOrProperties)
207
208    if (typeof styleSetStyleOrProperties === "object") {
209        properties = styleSetStyleOrProperties
210    }
211    if (typeof styleOrProperties === "object") {
212        properties = styleOrProperties
213    }
214
215    let size = fontSizes[properties?.size || "sm"]
216    let color = properties?.color || style.foreground
217
218    return {
219        family: fontFamilies[fontFamily],
220        ...properties,
221        color,
222        size,
223    }
224}
225
226export interface Border {
227    color: string
228    width: number
229    top?: boolean
230    bottom?: boolean
231    left?: boolean
232    right?: boolean
233    overlay?: boolean
234}
235
236export interface BorderProperties {
237    width?: number
238    top?: boolean
239    bottom?: boolean
240    left?: boolean
241    right?: boolean
242    overlay?: boolean
243}
244
245export function border(
246    layer: Layer,
247    styleSet: StyleSets,
248    style: Styles,
249    properties?: BorderProperties
250): Border
251export function border(
252    layer: Layer,
253    styleSet: StyleSets,
254    properties?: BorderProperties
255): Border
256export function border(
257    layer: Layer,
258    style: Styles,
259    properties?: BorderProperties
260): Border
261export function border(layer: Layer, properties?: BorderProperties): Border
262export function border(
263    layer: Layer,
264    styleSetStyleOrProperties?: StyleSets | Styles | BorderProperties,
265    styleOrProperties?: Styles | BorderProperties,
266    properties?: BorderProperties
267): Border {
268    let style = getStyle(layer, styleSetStyleOrProperties, styleOrProperties)
269
270    if (typeof styleSetStyleOrProperties === "object") {
271        properties = styleSetStyleOrProperties
272    }
273    if (typeof styleOrProperties === "object") {
274        properties = styleOrProperties
275    }
276
277    return {
278        color: style.border,
279        width: 1,
280        ...properties,
281    }
282}
283
284export function svg(
285    color: string,
286    asset: String,
287    width: Number,
288    height: Number
289) {
290    return {
291        color,
292        asset,
293        dimensions: {
294            width,
295            height,
296        },
297    }
298}