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 extends Object {
 89    family: keyof typeof fontFamilies
 90    color: string
 91    size: number
 92    weight?: FontWeight
 93    underline?: boolean
 94}
 95
 96export interface TextStyle extends Object {
 97    family: keyof typeof fontFamilies
 98    color: string
 99    size: number
100    weight?: FontWeight
101    underline?: boolean
102}
103
104export interface TextProperties {
105    size?: keyof typeof fontSizes
106    weight?: FontWeight
107    underline?: boolean
108    color?: string
109    features?: FontFeatures
110}
111
112interface FontFeatures {
113    /** Contextual Alternates: Applies a second substitution feature based on a match of a character pattern within a context of surrounding patterns */
114    calt?: boolean
115    /** Case-Sensitive Forms: Shifts various punctuation marks up to a position that works better with all-capital sequences */
116    case?: boolean
117    /** Capital Spacing: Adjusts inter-glyph spacing for all-capital text */
118    cpsp?: boolean
119    /** Fractions: Replaces figures separated by a slash with diagonal fractions */
120    frac?: boolean
121    /** Standard Ligatures: Replaces a sequence of glyphs with a single glyph which is preferred for typographic purposes */
122    liga?: boolean
123    /** Oldstyle Figures: Changes selected figures from the default or lining style to oldstyle form. */
124    onum?: boolean
125    /** Ordinals: Replaces default alphabetic glyphs with the corresponding ordinal forms for use after figures */
126    ordn?: boolean
127    /** Proportional Figures: Replaces figure glyphs set on uniform (tabular) widths with corresponding glyphs set on proportional widths */
128    pnum?: boolean
129    /** Stylistic set 01 */
130    ss01?: boolean
131    /** Stylistic set 02 */
132    ss02?: boolean
133    /** Stylistic set 03 */
134    ss03?: boolean
135    /** Stylistic set 04 */
136    ss04?: boolean
137    /** Stylistic set 05 */
138    ss05?: boolean
139    /** Stylistic set 06 */
140    ss06?: boolean
141    /** Stylistic set 07 */
142    ss07?: boolean
143    /** Stylistic set 08 */
144    ss08?: boolean
145    /** Stylistic set 09 */
146    ss09?: boolean
147    /** Stylistic set 10 */
148    ss10?: boolean
149    /** Stylistic set 11 */
150    ss11?: boolean
151    /** Stylistic set 12 */
152    ss12?: boolean
153    /** Stylistic set 13 */
154    ss13?: boolean
155    /** Stylistic set 14 */
156    ss14?: boolean
157    /** Stylistic set 15 */
158    ss15?: boolean
159    /** Stylistic set 16 */
160    ss16?: boolean
161    /** Stylistic set 17 */
162    ss17?: boolean
163    /** Stylistic set 18 */
164    ss18?: boolean
165    /** Stylistic set 19 */
166    ss19?: boolean
167    /** Stylistic set 20 */
168    ss20?: boolean
169    /** Subscript: Replaces default glyphs with subscript glyphs */
170    subs?: boolean
171    /** Superscript: Replaces default glyphs with superscript glyphs */
172    sups?: boolean
173    /** Swash: Replaces default glyphs with swash glyphs for stylistic purposes */
174    swsh?: boolean
175    /** Titling: Replaces default glyphs with titling glyphs for use in large-size settings */
176    titl?: boolean
177    /** Tabular Figures: Replaces figure glyphs set on proportional widths with corresponding glyphs set on uniform (tabular) widths */
178    tnum?: boolean
179    /** Slashed Zero: Replaces default zero with a slashed zero for better distinction between "0" and "O" */
180    zero?: boolean
181}
182
183export function text(
184    layer: Layer,
185    fontFamily: keyof typeof fontFamilies,
186    styleSet: StyleSets,
187    style: Styles,
188    properties?: TextProperties
189): Text
190export function text(
191    layer: Layer,
192    fontFamily: keyof typeof fontFamilies,
193    styleSet: StyleSets,
194    properties?: TextProperties
195): Text
196export function text(
197    layer: Layer,
198    fontFamily: keyof typeof fontFamilies,
199    style: Styles,
200    properties?: TextProperties
201): Text
202export function text(
203    layer: Layer,
204    fontFamily: keyof typeof fontFamilies,
205    properties?: TextProperties
206): Text
207export function text(
208    layer: Layer,
209    fontFamily: keyof typeof fontFamilies,
210    styleSetStyleOrProperties?: StyleSets | Styles | TextProperties,
211    styleOrProperties?: Styles | TextProperties,
212    properties?: TextProperties
213) {
214    let style = getStyle(layer, styleSetStyleOrProperties, styleOrProperties)
215
216    if (typeof styleSetStyleOrProperties === "object") {
217        properties = styleSetStyleOrProperties
218    }
219    if (typeof styleOrProperties === "object") {
220        properties = styleOrProperties
221    }
222
223    let size = fontSizes[properties?.size || "sm"]
224    let color = properties?.color || style.foreground
225
226    return {
227        family: fontFamilies[fontFamily],
228        ...properties,
229        color,
230        size,
231    }
232}
233
234export interface Border {
235    color: string
236    width: number
237    top?: boolean
238    bottom?: boolean
239    left?: boolean
240    right?: boolean
241    overlay?: boolean
242}
243
244export interface BorderProperties {
245    width?: number
246    top?: boolean
247    bottom?: boolean
248    left?: boolean
249    right?: boolean
250    overlay?: boolean
251}
252
253export function border(
254    layer: Layer,
255    styleSet: StyleSets,
256    style: Styles,
257    properties?: BorderProperties
258): Border
259export function border(
260    layer: Layer,
261    styleSet: StyleSets,
262    properties?: BorderProperties
263): Border
264export function border(
265    layer: Layer,
266    style: Styles,
267    properties?: BorderProperties
268): Border
269export function border(layer: Layer, properties?: BorderProperties): Border
270export function border(
271    layer: Layer,
272    styleSetStyleOrProperties?: StyleSets | Styles | BorderProperties,
273    styleOrProperties?: Styles | BorderProperties,
274    properties?: BorderProperties
275): Border {
276    let style = getStyle(layer, styleSetStyleOrProperties, styleOrProperties)
277
278    if (typeof styleSetStyleOrProperties === "object") {
279        properties = styleSetStyleOrProperties
280    }
281    if (typeof styleOrProperties === "object") {
282        properties = styleOrProperties
283    }
284
285    return {
286        color: style.border,
287        width: 1,
288        ...properties,
289    }
290}
291
292export function svg(
293    color: string,
294    asset: String,
295    width: Number,
296    height: Number
297) {
298    return {
299        color,
300        asset,
301        dimensions: {
302            width,
303            height,
304        },
305    }
306}