/ client_code / theme.py
theme.py
  1  # SPDX-License-Identifier: MIT
  2  #
  3  # Copyright (c) 2021 The Anvil Extras project team members listed at
  4  # https://github.com/anvilistas/anvil-extras/graphs/contributors
  5  #
  6  # This software is published at https://github.com/anvilistas/anvil-extras
  7  
  8  import anvil
  9  
 10  __version__ = "3.1.0"
 11  
 12  M3_DEFAULT_SCHEMES = {
 13      "Material": {
 14          "dark": {
 15              "Primary": "#D0BCFF",
 16              "Primary Container": "#4F378B",
 17              "On Primary": "#371E73",
 18              "On Primary Container": "#EADDFF",
 19              "Secondary": "#CCC2DC",
 20              "Secondary Container": "#4A4458",
 21              "On Secondary": "#332D41",
 22              "On Secondary Container": "#E8DEF8",
 23              "Tertiary": "#EFB8C8",
 24              "Tertiary Container": "#633B48",
 25              "On Tertiary": "#492532",
 26              "On Tertiary Container": "#FFD8E4",
 27              "Error": "#F2B8B5",
 28              "Background": "#1C1B1F",
 29              "Surface": "#1C1B1F",
 30              "On Background": "#E6E1E5",
 31              "On Surface": "#E6E1E5",
 32              "Surface Variant": "#49454F",
 33              "On Surface Variant": "#CAC4D0",
 34              "Outline": "#938F99",
 35              "On Disabled": "rgba(230, 225, 229, 0.38)",
 36              "Disabled Container": "rgba(230, 225, 229, 0.12)",
 37              "Light Overlay 1": "rgba(232, 222, 248, 0.08)",
 38              "Light Overlay 2": "rgba(232, 222, 248, 0.12)",
 39              "Dark Overlay 1": "rgba(232, 222, 248, 0.08)",
 40              "Dark Overlay 2": "rgba(232, 222, 248, 0.12)",
 41              "Primary Overlay 1": "rgba(208, 188, 255, 0.05)",
 42              "Primary Overlay 2": "rgba(208, 188, 255, 0.08)",
 43              "Primary Overlay 3": "rgba(208, 188, 255, 0.11)",
 44          },
 45          "light": {
 46              "Primary": "#6750A4",
 47              "Primary Container": "#EADDFF",
 48              "On Primary": "#FFFFFF",
 49              "On Primary Container": "#21005E",
 50              "Secondary": "#625B71",
 51              "Secondary Container": "#E8DEF8",
 52              "On Secondary": "#FFFFFF",
 53              "On Secondary Container": "#1E192B",
 54              "Tertiary": "#7D5260",
 55              "Tertiary Container": "#FFD8E4",
 56              "On Tertiary": "#FFFFFF",
 57              "On Tertiary Container": "#370B1E",
 58              "Error": "#B3261E",
 59              "Background": "#FFFBFE",
 60              "Surface": "#FFFBFE",
 61              "On Background": "#1C1B1F",
 62              "On Surface": "#1C1B1F",
 63              "Surface Variant": "#E7E0EC",
 64              "On Surface Variant": "#49454E",
 65              "Outline": "#79747E",
 66              "On Disabled": "rgba(28, 27, 31, 0.38)",
 67              "Disabled Container": "rgba(28, 27, 31, 0.12)",
 68              "Light Overlay 1": "rgba(255, 255, 255, 0.08)",
 69              "Light Overlay 2": "rgba(255, 255, 255, 0.12)",
 70              "Dark Overlay 1": "rgba(30, 25, 43, 0.08)",
 71              "Dark Overlay 2": "rgba(30, 25, 43, 0.12)",
 72              "Primary Overlay 1": "rgba(103, 80, 164, 0.05)",
 73              "Primary Overlay 2": "rgba(103, 80, 164, 0.08)",
 74              "Primary Overlay 3": "rgba(103, 80, 164, 0.11)",
 75          },
 76      },
 77      "Rally": {
 78          "dark": {
 79              "Primary": "#1EB980",
 80              "Primary Container": "#005235",
 81              "On Primary": "#003824",
 82              "On Primary Container": "#73FBBC",
 83              "Secondary": "#B4CCBC",
 84              "Secondary Container": "#364B3F",
 85              "On Secondary": "#20352A",
 86              "On Secondary Container": "#D0E8D8",
 87              "Tertiary": "#A4CDDD",
 88              "Tertiary Container": "#234C5A",
 89              "On Tertiary": "#063542",
 90              "On Tertiary Container": "#C0E9FA",
 91              "Error": "#D64D47",
 92              "Background": "#191C1A",
 93              "Surface": "#191C1A",
 94              "On Background": "#E1E3DF",
 95              "On Surface": "#E1E3DF",
 96              "Surface Variant": "#404943",
 97              "On Surface Variant": "#C0C9C1",
 98              "Outline": "#8A938C",
 99              "On Disabled": "#85858B",
100              "Disabled Container": "rgba(133, 133, 139, 0.12)",
101              "Light Overlay 1": "rgba(208, 232, 216, 0.2)",
102              "Light Overlay 2": "rgba(208, 232, 216, 0.5)",
103              "Dark Overlay 1": "rgba(208, 232, 216, 0.2)",
104              "Dark Overlay 2": "rgba(208, 232, 216, 0.5)",
105              "Primary Overlay 1": "rgba(30, 185, 128, 0.05)",
106              "Primary Overlay 2": "rgba(30, 185, 128, 0.08)",
107              "Primary Overlay 3": "rgba(30, 185, 128, 0.11)",
108          },
109          "light": {
110              "Primary": "#006C48",
111              "Primary Container": "#00A36C",
112              "On Primary": "#FFFFFF",
113              "On Primary Container": "#002113",
114              "Secondary": "#496455",
115              "Secondary Container": "#CBEAD6",
116              "On Secondary": "#FFFFFF",
117              "On Secondary Container": "#052014",
118              "Tertiary": "#326576",
119              "Tertiary Container": "#B8EAFF",
120              "On Tertiary": "#FFFFFF",
121              "On Tertiary Container": "#001F28",
122              "Error": "#D64D47",
123              "Background": "#FBFDF8",
124              "Surface": "#FBFDF8",
125              "On Background": "#191C1A",
126              "On Surface": "#191C1A",
127              "Surface Variant": "#DCE5DD",
128              "On Surface Variant": "#404943",
129              "Outline": "#707973",
130              "On Disabled": "rgba(25, 28, 26, 0.38)",
131              "Disabled Container": "rgba(25, 28, 26, 0.12)",
132              "Light Overlay 1": "rgba(255, 255, 255, 0.8)",
133              "Light Overlay 2": "rgba(255, 255, 255, 0.12)",
134              "Dark Overlay 1": "rgba(5, 32, 20, 0.8)",
135              "Dark Overlay 2": "rgba(51, 51, 61, 0.12)",
136              "Primary Overlay 1": "rgba(0, 108, 72, 0.05)",
137              "Primary Overlay 2": "rgba(0, 108, 72, 0.08)",
138              "Primary Overlay 3": "rgba(0, 108, 72, 0.11)",
139          },
140      },
141      "Mykonos": {
142          "dark": {
143              "Primary": "#3CD9ED",
144              "Primary Container": "#004F57",
145              "On Primary": "#00363D",
146              "On Primary Container": "#96F0FF",
147              "Secondary": "#AFCBD0",
148              "Secondary Container": "#314B4F",
149              "On Secondary": "#1A3438",
150              "On Secondary Container": "#CBE8ED",
151              "Tertiary": "#B9C6ED",
152              "Tertiary Container": "#394667",
153              "On Tertiary": "#23304F",
154              "On Tertiary Container": "#DAE2FF",
155              "Error": "#FFB4AB",
156              "Background": "#191C1D",
157              "Surface": "#191C1D",
158              "On Background": "#E1E3E3",
159              "On Surface": "#E1E3E3",
160              "Surface Variant": "#3F484A",
161              "On Surface Variant": "#BFC8CA",
162              "Outline": "#899294",
163              "On Disabled": "rgba(225, 227, 227, 0.38)",
164              "Disabled Container": "rgba(225, 227, 227, 0.12)",
165              "Light Overlay 1": "rgba(203, 232, 237, 0.08)",
166              "Light Overlay 2": "rgba(203, 232, 237, 0.12)",
167              "Dark Overlay 1": "rgba(203, 232, 237, 0.08)",
168              "Dark Overlay 2": "rgba(203, 232, 237, 0.12)",
169              "Primary Overlay 1": "rgba(60, 217, 237, 0.05)",
170              "Primary Overlay 2": "rgba(60, 217, 237, 0.08)",
171              "Primary Overlay 3": "rgba(60, 217, 237, 0.11)",
172          },
173          "light": {
174              "Primary": "#006874",
175              "Primary Container": "#96F0FF",
176              "On Primary": "#FFFFFF",
177              "On Primary Container": "#001F24",
178              "Secondary": "#486367",
179              "Secondary Container": "#CBE8ED",
180              "On Secondary": "#FFFFFF",
181              "On Secondary Container": "#031F23",
182              "Tertiary": "#515E80",
183              "Tertiary Container": "#DAE2FF",
184              "On Tertiary": "#FFFFFF",
185              "On Tertiary Container": "#0C1A39",
186              "Error": "#BA1A1A",
187              "Background": "#FAFDFD",
188              "Surface": "#FAFDFD",
189              "On Background": "#191C1D",
190              "On Surface": "#191C1D",
191              "Surface Variant": "#DBE4E6",
192              "On Surface Variant": "#3F484A",
193              "Outline": "#6F797A",
194              "On Disabled": "rgba(25, 28, 29, 0.38)",
195              "Disabled Container": "rgba(25, 28, 29, 0.12)",
196              "Light Overlay 1": "rgba(255, 255, 255, 0.08)",
197              "Light Overlay 2": "rgba(255, 255, 255, 0.12)",
198              "Dark Overlay 1": "rgba(3, 31, 35, 0.08)",
199              "Dark Overlay 2": "rgba(3, 31, 35, 0.12)",
200              "Primary Overlay 1": "rgba(0, 104, 116, 0.05)",
201              "Primary Overlay 2": "rgba(0, 104, 116, 0.08)",
202              "Primary Overlay 3": "rgba(0, 104, 116, 0.11)",
203          },
204      },
205      "Manarola": {
206          "dark": {
207              "Primary": "#FFB59B",
208              "Primary Container": "#7B2E0E",
209              "On Primary": "#5B1A00",
210              "On Primary Container": "#FFDBCF",
211              "Secondary": "#E7BDB0",
212              "Secondary Container": "#5D4036",
213              "On Secondary": "#442A21",
214              "On Secondary Container": "#FFDBCF",
215              "Tertiary": "#D5C68E",
216              "Tertiary Container": "#50461A",
217              "On Tertiary": "#393005",
218              "On Tertiary Container": "#F2E2A7",
219              "Error": "#FFB4AB",
220              "Background": "#201A18",
221              "Surface": "#201A18",
222              "On Background": "#EDE0DC",
223              "On Surface": "#EDE0DC",
224              "Surface Variant": "#53433E",
225              "On Surface Variant": "#D8C2BB",
226              "Outline": "#A08D86",
227              "On Disabled": "rgba(237, 224, 220, 0.38)",
228              "Disabled Container": "rgba(237, 224, 220, 0.12)",
229              "Light Overlay 1": "rgba(255, 219, 207, 0.08)",
230              "Light Overlay 2": "rgba(255, 219, 207, 0.12)",
231              "Dark Overlay 1": "rgba(255, 219, 207, 0.08)",
232              "Dark Overlay 2": "rgba(255, 219, 207, 0.12)",
233              "Primary Overlay 1": "rgba(255, 181, 155, 0.05)",
234              "Primary Overlay 2": "rgba(255, 181, 155, 0.08)",
235              "Primary Overlay 3": "rgba(255, 181, 155, 0.11)",
236          },
237          "light": {
238              "Primary": "#9A4523",
239              "Primary Container": "#FFDBCF",
240              "On Primary": "#FFFFFF",
241              "On Primary Container": "#380D00",
242              "Secondary": "#77574C",
243              "Secondary Container": "#FFDBCF",
244              "On Secondary": "#FFFFFF",
245              "On Secondary Container": "#2C160D",
246              "Tertiary": "#695E2F",
247              "Tertiary Container": "#F2E2A7",
248              "On Tertiary": "#FFFFFF",
249              "On Tertiary Container": "#221B00",
250              "Error": "#BA1A1A",
251              "Background": "#FFFBFF",
252              "Surface": "#FFFBFF",
253              "On Background": "#201A18",
254              "On Surface": "#201A18",
255              "Surface Variant": "#F5DED6",
256              "On Surface Variant": "#53433E",
257              "Outline": "#85736D",
258              "On Disabled": "rgba(32, 26, 24, 0.38)",
259              "Disabled Container": "rgba(32, 26, 24, 0.12)",
260              "Light Overlay 1": "rgba(255, 255, 255, 0.08)",
261              "Light Overlay 2": "rgba(255, 255, 255, 0.12)",
262              "Dark Overlay 1": "rgba(44, 22, 13, 0.08)",
263              "Dark Overlay 2": "rgba(44, 22, 13, 0.12)",
264              "Primary Overlay 1": "rgba(154, 69, 35, 0.05)",
265              "Primary Overlay 2": "rgba(154, 69, 35, 0.08)",
266              "Primary Overlay 3": "rgba(154, 69, 35, 0.11)",
267          },
268      },
269  }
270  
271  
272  class Colors:
273      def __init__(self, schemes=None, scheme=None, variant=None):
274          self.schemes = schemes or M3_DEFAULT_SCHEMES
275          self._scheme = scheme or tuple(self.schemes.keys())[0]
276          self._variant = variant or self.variants[0]
277          self._set_scheme(self.scheme, self.variant)
278  
279      def _set_scheme(self, scheme, variant):
280          try:
281              anvil.app.theme_colors.update(self.schemes[scheme][variant])
282          except KeyError:
283              raise ValueError(f"{scheme} {variant} is not defined.")
284  
285      def set_scheme(self, scheme, variant):
286          self._set_scheme(scheme, variant)
287          self._scheme = scheme
288          self._variant = variant
289  
290      @property
291      def variants(self):
292          return tuple(self.schemes[self._scheme].keys())
293  
294      @property
295      def scheme(self):
296          return self._scheme
297  
298      @scheme.setter
299      def scheme(self, scheme):
300          self._set_scheme(scheme, self.variant)
301          self._scheme = scheme
302  
303      @property
304      def variant(self):
305          return self._variant
306  
307      @variant.setter
308      def variant(self, variant):
309          self._set_scheme(self.scheme, variant)
310          self._variant = variant
311  
312      def toggle_variant(self):
313          current = self.variants.index(self.variant)
314          self.variant = self.variants(not current)