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 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}