themes.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import { Color, colorFromHex, darken, lighten } from '../utils/colorify';
  2. import colors from './colors';
  3. export interface TalkyBaseTheme {
  4. background: Color;
  5. foreground: Color;
  6. border: Color;
  7. primaryBackground: Color;
  8. primaryForeground: Color;
  9. secondaryBackground: Color;
  10. secondaryForeground: Color;
  11. attentionBackground: Color;
  12. attentionForeground: Color;
  13. actionBackground: Color;
  14. actionForeground: Color;
  15. }
  16. export interface TalkyTheme extends TalkyBaseTheme {
  17. buttonPrimaryBackground: Color;
  18. buttonPrimaryBackgroundHover: Color;
  19. buttonPrimaryBackgroundActive: Color;
  20. buttonPrimaryText: Color;
  21. buttonSecondaryBackground: Color;
  22. buttonSecondaryBackgroundHover: Color;
  23. buttonSecondaryBackgroundActive: Color;
  24. buttonSecondaryText: Color;
  25. buttonAttentionBackground: Color;
  26. buttonAttentionBackgroundHover: Color;
  27. buttonAttentionBackgroundActive: Color;
  28. buttonAttentionText: Color;
  29. buttonActionBackground: Color;
  30. buttonActionBackgroundHover: Color;
  31. buttonActionBackgroundActive: Color;
  32. buttonActionText: Color;
  33. alertInfoBackground: Color;
  34. alertInfoForeground: Color;
  35. alertErrorBackground: Color;
  36. alertErrorForeground: Color;
  37. }
  38. const lightBase: TalkyBaseTheme = {
  39. background: colorFromHex('#fff'),
  40. foreground: colorFromHex('#444'),
  41. border: lighten(colorFromHex('#444'), 0.5),
  42. primaryBackground: colors.blue,
  43. primaryForeground: colorFromHex('#fff'),
  44. secondaryBackground: colors.grayLighter,
  45. secondaryForeground: colors.grayDark,
  46. attentionBackground: colors.pink,
  47. attentionForeground: colorFromHex('#fff'),
  48. actionBackground: colors.green,
  49. actionForeground: colorFromHex('#fff')
  50. };
  51. const darkBase: TalkyBaseTheme = {
  52. ...lightBase,
  53. background: colorFromHex('#121212'),
  54. foreground: colorFromHex('#fff'),
  55. border: lighten(colorFromHex('#121212'), 0.25),
  56. secondaryBackground: colorFromHex('#2a2a2a'),
  57. secondaryForeground: colorFromHex('#fff')
  58. };
  59. function kebabToCamel(s: string): string {
  60. return s.replace(/-([a-z])/g, g => g[1].toUpperCase());
  61. }
  62. function mergeOverrides(base: TalkyBaseTheme): TalkyBaseTheme {
  63. const baseTheme: TalkyBaseTheme = { ...base };
  64. const properties = Array.from(
  65. document.head.querySelectorAll('meta[name*=simplewebrtc-theme]')
  66. ).reduce(
  67. (a, b) => {
  68. const name = b.getAttribute('name');
  69. const content = b.getAttribute('content');
  70. if (name !== null && content !== null) {
  71. a[kebabToCamel(name.replace('simplewebrtc-theme-', ''))] = content;
  72. }
  73. return a;
  74. },
  75. {} as { [key: string]: string }
  76. );
  77. Object.keys(properties).forEach(k => {
  78. if (baseTheme.hasOwnProperty(k)) {
  79. baseTheme[k as keyof TalkyBaseTheme] = colorFromHex(properties[k]);
  80. }
  81. });
  82. return baseTheme;
  83. }
  84. function baseToFull(base: TalkyBaseTheme): TalkyTheme {
  85. return {
  86. ...base,
  87. buttonPrimaryBackground: base.primaryBackground,
  88. buttonPrimaryBackgroundHover: lighten(base.primaryBackground, 0.05),
  89. buttonPrimaryBackgroundActive: darken(base.primaryBackground, 0.05),
  90. buttonPrimaryText: base.primaryForeground,
  91. buttonSecondaryBackground: base.secondaryBackground,
  92. buttonSecondaryBackgroundHover: lighten(base.secondaryBackground, 0.05),
  93. buttonSecondaryBackgroundActive: darken(base.secondaryBackground, 0.05),
  94. buttonSecondaryText: base.secondaryForeground,
  95. buttonAttentionBackground: base.attentionBackground,
  96. buttonAttentionBackgroundHover: lighten(base.attentionBackground, 0.05),
  97. buttonAttentionBackgroundActive: darken(base.attentionBackground, 0.05),
  98. buttonAttentionText: base.attentionForeground,
  99. buttonActionBackground: base.actionBackground,
  100. buttonActionBackgroundHover: lighten(base.actionBackground, 0.05),
  101. buttonActionBackgroundActive: darken(base.actionBackground, 0.05),
  102. buttonActionText: base.actionForeground,
  103. alertInfoBackground: lighten(base.primaryBackground, 0.5),
  104. alertInfoForeground: base.primaryBackground,
  105. alertErrorBackground: lighten(base.attentionBackground, 0.5),
  106. alertErrorForeground: base.attentionBackground
  107. };
  108. }
  109. const themes: { [index: string]: TalkyTheme } = {
  110. light: baseToFull(mergeOverrides(lightBase)),
  111. dark: baseToFull(mergeOverrides(darkBase))
  112. };
  113. export default themes;