omni-color 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +1042 -0
  3. package/dist/__test__/color-interop.test.d.ts +1 -0
  4. package/dist/__test__/color-interop.test.js +82 -0
  5. package/dist/__test__/comparison_culori.test.d.ts +1 -0
  6. package/dist/__test__/comparison_culori.test.js +169 -0
  7. package/dist/__test__/interop-chroma.test.d.ts +1 -0
  8. package/dist/__test__/interop-chroma.test.js +676 -0
  9. package/dist/__test__/interop-tinycolor.test.d.ts +1 -0
  10. package/dist/__test__/interop-tinycolor.test.js +499 -0
  11. package/dist/color/__test__/baseColor.test.d.ts +2 -0
  12. package/dist/color/__test__/baseColor.test.d.ts.map +1 -0
  13. package/dist/color/__test__/baseColor.test.js +34 -0
  14. package/dist/color/__test__/baseColor.test.js.map +1 -0
  15. package/dist/color/__test__/blank.d.ts +1 -0
  16. package/dist/color/__test__/blank.js +3 -0
  17. package/dist/color/__test__/color.test.d.ts +1 -0
  18. package/dist/color/__test__/color.test.js +1073 -0
  19. package/dist/color/__test__/colorSpaces.test.d.ts +1 -0
  20. package/dist/color/__test__/colorSpaces.test.js +69 -0
  21. package/dist/color/__test__/combinations.test.d.ts +1 -0
  22. package/dist/color/__test__/combinations.test.js +665 -0
  23. package/dist/color/__test__/conversions.test.d.ts +1 -0
  24. package/dist/color/__test__/conversions.test.js +719 -0
  25. package/dist/color/__test__/deltaE.test.d.ts +1 -0
  26. package/dist/color/__test__/deltaE.test.js +120 -0
  27. package/dist/color/__test__/formats.test.d.ts +1 -0
  28. package/dist/color/__test__/formats.test.js +514 -0
  29. package/dist/color/__test__/gradients.test.d.ts +1 -0
  30. package/dist/color/__test__/gradients.test.js +414 -0
  31. package/dist/color/__test__/harmonies.test.d.ts +1 -0
  32. package/dist/color/__test__/harmonies.test.js +676 -0
  33. package/dist/color/__test__/manipulations.test.d.ts +1 -0
  34. package/dist/color/__test__/manipulations.test.js +264 -0
  35. package/dist/color/__test__/names.test.d.ts +1 -0
  36. package/dist/color/__test__/names.test.js +67 -0
  37. package/dist/color/__test__/parse.test.d.ts +1 -0
  38. package/dist/color/__test__/parse.test.js +256 -0
  39. package/dist/color/__test__/random.test.d.ts +1 -0
  40. package/dist/color/__test__/random.test.js +262 -0
  41. package/dist/color/__test__/readability.test.d.ts +1 -0
  42. package/dist/color/__test__/readability.test.js +2596 -0
  43. package/dist/color/__test__/srgb.test.d.ts +1 -0
  44. package/dist/color/__test__/srgb.test.js +43 -0
  45. package/dist/color/__test__/swatch.test.d.ts +1 -0
  46. package/dist/color/__test__/swatch.test.js +267 -0
  47. package/dist/color/__test__/temperature.test.d.ts +1 -0
  48. package/dist/color/__test__/temperature.test.js +223 -0
  49. package/dist/color/__test__/utils.test.d.ts +1 -0
  50. package/dist/color/__test__/utils.test.js +409 -0
  51. package/dist/color/__test__/validations.test.d.ts +1 -0
  52. package/dist/color/__test__/validations.test.js +239 -0
  53. package/dist/color/color.constants.d.ts +4 -0
  54. package/dist/color/color.constants.d.ts.map +1 -0
  55. package/dist/color/color.constants.js +152 -0
  56. package/dist/color/color.constants.js.map +1 -0
  57. package/dist/color/color.consts.d.ts +4 -0
  58. package/dist/color/color.consts.js +152 -0
  59. package/dist/color/color.d.ts +788 -0
  60. package/dist/color/color.d.ts.map +1 -0
  61. package/dist/color/color.helpers.d.ts +6 -0
  62. package/dist/color/color.helpers.js +4 -0
  63. package/dist/color/color.js +919 -0
  64. package/dist/color/color.js.map +1 -0
  65. package/dist/color/colorSpaces.d.ts +15 -0
  66. package/dist/color/colorSpaces.js +127 -0
  67. package/dist/color/combinations.d.ts +45 -0
  68. package/dist/color/combinations.js +562 -0
  69. package/dist/color/conversions.d.ts +16 -0
  70. package/dist/color/conversions.d.ts.map +1 -0
  71. package/dist/color/conversions.js +705 -0
  72. package/dist/color/conversions.js.map +1 -0
  73. package/dist/color/deltaE.d.ts +59 -0
  74. package/dist/color/deltaE.js +110 -0
  75. package/dist/color/formats.d.ts +128 -0
  76. package/dist/color/formats.d.ts.map +1 -0
  77. package/dist/color/formats.js +153 -0
  78. package/dist/color/formats.js.map +1 -0
  79. package/dist/color/gradients.d.ts +49 -0
  80. package/dist/color/gradients.js +672 -0
  81. package/dist/color/harmonies.d.ts +18 -0
  82. package/dist/color/harmonies.js +128 -0
  83. package/dist/color/manipulations.d.ts +29 -0
  84. package/dist/color/manipulations.js +106 -0
  85. package/dist/color/names.d.ts +38 -0
  86. package/dist/color/names.js +108 -0
  87. package/dist/color/parse.d.ts +2 -0
  88. package/dist/color/parse.js +437 -0
  89. package/dist/color/random.d.ts +30 -0
  90. package/dist/color/random.js +65 -0
  91. package/dist/color/readability.d.ts +53 -0
  92. package/dist/color/readability.js +284 -0
  93. package/dist/color/srgb.d.ts +8 -0
  94. package/dist/color/srgb.js +33 -0
  95. package/dist/color/swatch.d.ts +49 -0
  96. package/dist/color/swatch.js +118 -0
  97. package/dist/color/temperature.d.ts +26 -0
  98. package/dist/color/temperature.js +141 -0
  99. package/dist/color/utils.d.ts +49 -0
  100. package/dist/color/utils.d.ts.map +1 -0
  101. package/dist/color/utils.js +104 -0
  102. package/dist/color/utils.js.map +1 -0
  103. package/dist/color/validations.d.ts +2 -0
  104. package/dist/color/validations.d.ts.map +1 -0
  105. package/dist/color/validations.js +178 -0
  106. package/dist/color/validations.js.map +1 -0
  107. package/dist/demo/src/AppFooter.d.ts +1 -0
  108. package/dist/demo/src/AppFooter.js +4 -0
  109. package/dist/demo/src/AppHeader.d.ts +5 -0
  110. package/dist/demo/src/AppHeader.js +6 -0
  111. package/dist/demo/src/components/Card.d.ts +9 -0
  112. package/dist/demo/src/components/Card.js +9 -0
  113. package/dist/demo/src/components/Chip.d.ts +21 -0
  114. package/dist/demo/src/components/Chip.js +23 -0
  115. package/dist/demo/src/components/ColorBox.d.ts +16 -0
  116. package/dist/demo/src/components/ColorBox.js +45 -0
  117. package/dist/demo/src/components/ColorInfoCard.d.ts +7 -0
  118. package/dist/demo/src/components/ColorInfoCard.js +50 -0
  119. package/dist/demo/src/components/ExpandableCodeSnippet.d.ts +5 -0
  120. package/dist/demo/src/components/ExpandableCodeSnippet.js +17 -0
  121. package/dist/demo/src/components/Icon.d.ts +11 -0
  122. package/dist/demo/src/components/Icon.js +50 -0
  123. package/dist/demo/src/components/Icon.types.d.ts +14 -0
  124. package/dist/demo/src/components/Icon.types.js +15 -0
  125. package/dist/demo/src/components/SectionContainer.d.ts +10 -0
  126. package/dist/demo/src/components/SectionContainer.js +12 -0
  127. package/dist/demo/src/components/VSpace.d.ts +5 -0
  128. package/dist/demo/src/components/VSpace.js +4 -0
  129. package/dist/demo/src/components/inputs/Checkbox.d.ts +7 -0
  130. package/dist/demo/src/components/inputs/Checkbox.js +4 -0
  131. package/dist/demo/src/components/inputs/InputGroup.d.ts +6 -0
  132. package/dist/demo/src/components/inputs/InputGroup.js +4 -0
  133. package/dist/demo/src/components/inputs/NumberInput.d.ts +10 -0
  134. package/dist/demo/src/components/inputs/NumberInput.js +8 -0
  135. package/dist/demo/src/components/inputs/Select.d.ts +12 -0
  136. package/dist/demo/src/components/inputs/Select.js +6 -0
  137. package/dist/demo/src/components/inputs/Slider.d.ts +10 -0
  138. package/dist/demo/src/components/inputs/Slider.js +4 -0
  139. package/dist/demo/src/components/utils.d.ts +17 -0
  140. package/dist/demo/src/components/utils.js +24 -0
  141. package/dist/demo/src/demo/ColorDemo.d.ts +1 -0
  142. package/dist/demo/src/demo/ColorDemo.js +45 -0
  143. package/dist/demo/src/demo/ColorHarmonyDemo.d.ts +6 -0
  144. package/dist/demo/src/demo/ColorHarmonyDemo.js +18 -0
  145. package/dist/demo/src/demo/ColorInfo.d.ts +6 -0
  146. package/dist/demo/src/demo/ColorInfo.js +14 -0
  147. package/dist/demo/src/demo/ColorInput.d.ts +7 -0
  148. package/dist/demo/src/demo/ColorInput.js +58 -0
  149. package/dist/demo/src/demo/ColorManipulationDemo.d.ts +6 -0
  150. package/dist/demo/src/demo/ColorManipulationDemo.js +63 -0
  151. package/dist/demo/src/demo/ColorSwatch.d.ts +13 -0
  152. package/dist/demo/src/demo/ColorSwatch.js +15 -0
  153. package/dist/demo/src/demo/ReadabilityDemo.d.ts +6 -0
  154. package/dist/demo/src/demo/ReadabilityDemo.js +24 -0
  155. package/dist/demo/src/demo/combinations/AverageColorsOptionInputs.d.ts +7 -0
  156. package/dist/demo/src/demo/combinations/AverageColorsOptionInputs.js +7 -0
  157. package/dist/demo/src/demo/combinations/BlendColorsOptionInputs.d.ts +7 -0
  158. package/dist/demo/src/demo/combinations/BlendColorsOptionInputs.js +13 -0
  159. package/dist/demo/src/demo/combinations/ColorCombinationDemo.d.ts +6 -0
  160. package/dist/demo/src/demo/combinations/ColorCombinationDemo.js +78 -0
  161. package/dist/demo/src/demo/combinations/MixColorsOptionInputs.d.ts +7 -0
  162. package/dist/demo/src/demo/combinations/MixColorsOptionInputs.js +10 -0
  163. package/dist/demo/src/demo/combinations/colorCombinationDemo.consts.d.ts +4 -0
  164. package/dist/demo/src/demo/combinations/colorCombinationDemo.consts.js +12 -0
  165. package/dist/demo/src/demo/gradients/GradientOptionInputs.d.ts +10 -0
  166. package/dist/demo/src/demo/gradients/GradientOptionInputs.js +42 -0
  167. package/dist/demo/src/demo/gradients/GradientThroughCard.d.ts +6 -0
  168. package/dist/demo/src/demo/gradients/GradientThroughCard.js +50 -0
  169. package/dist/demo/src/demo/gradients/GradientToCard.d.ts +6 -0
  170. package/dist/demo/src/demo/gradients/GradientToCard.js +54 -0
  171. package/dist/demo/src/demo/gradients/GradientsDemo.d.ts +6 -0
  172. package/dist/demo/src/demo/gradients/GradientsDemo.js +6 -0
  173. package/dist/demo/src/demo/gradients/gradientOptions.consts.d.ts +3 -0
  174. package/dist/demo/src/demo/gradients/gradientOptions.consts.js +16 -0
  175. package/dist/demo/src/demo/palette/ColorPaletteDemo.d.ts +6 -0
  176. package/dist/demo/src/demo/palette/ColorPaletteDemo.js +26 -0
  177. package/dist/demo/src/demo/palette/PaletteGenerationOptions.d.ts +8 -0
  178. package/dist/demo/src/demo/palette/PaletteGenerationOptions.js +53 -0
  179. package/dist/demo/src/demo/palette/PaletteHarmonyOptions.d.ts +7 -0
  180. package/dist/demo/src/demo/palette/PaletteHarmonyOptions.js +5 -0
  181. package/dist/demo/src/main.d.ts +1 -0
  182. package/dist/demo/src/main.js +14 -0
  183. package/dist/demo/src/pages/DemoPage.d.ts +1 -0
  184. package/dist/demo/src/pages/DemoPage.js +28 -0
  185. package/dist/demo/src/pages/PlaygroundPage.d.ts +1 -0
  186. package/dist/demo/src/pages/PlaygroundPage.js +24 -0
  187. package/dist/demo/src/playground/Playground.d.ts +1 -0
  188. package/dist/demo/src/playground/Playground.js +42 -0
  189. package/dist/demo/src/playground/playgroundUtils.d.ts +16 -0
  190. package/dist/demo/src/playground/playgroundUtils.js +202 -0
  191. package/dist/demo/src/seo/PageHead.d.ts +9 -0
  192. package/dist/demo/src/seo/PageHead.js +76 -0
  193. package/dist/demo/src/seo/StructuredData.d.ts +6 -0
  194. package/dist/demo/src/seo/StructuredData.js +13 -0
  195. package/dist/demo/src/toast/ToastProvider.d.ts +2 -0
  196. package/dist/demo/src/toast/ToastProvider.js +62 -0
  197. package/dist/demo/src/toast/index.d.ts +2 -0
  198. package/dist/demo/src/toast/index.js +2 -0
  199. package/dist/demo/src/toast/toastBus.d.ts +13 -0
  200. package/dist/demo/src/toast/toastBus.js +27 -0
  201. package/dist/index.d.ts +1233 -0
  202. package/dist/index.d.ts.map +1 -0
  203. package/dist/index.js +5235 -0
  204. package/dist/index.js.map +1 -0
  205. package/dist/palette/__test__/palette.test.d.ts +1 -0
  206. package/dist/palette/__test__/palette.test.js +397 -0
  207. package/dist/palette/palette.d.ts +41 -0
  208. package/dist/palette/palette.js +126 -0
  209. package/dist/src/__test__/interop-chroma.test.d.ts +1 -0
  210. package/dist/src/__test__/interop-chroma.test.js +673 -0
  211. package/dist/src/__test__/interop-tinycolor.test.d.ts +1 -0
  212. package/dist/src/__test__/interop-tinycolor.test.js +499 -0
  213. package/dist/src/color/__test__/color.test.d.ts +1 -0
  214. package/dist/src/color/__test__/color.test.js +1071 -0
  215. package/dist/src/color/__test__/colorSpaces.test.d.ts +1 -0
  216. package/dist/src/color/__test__/colorSpaces.test.js +69 -0
  217. package/dist/src/color/__test__/combinations.test.d.ts +1 -0
  218. package/dist/src/color/__test__/combinations.test.js +665 -0
  219. package/dist/src/color/__test__/conversions.test.d.ts +1 -0
  220. package/dist/src/color/__test__/conversions.test.js +719 -0
  221. package/dist/src/color/__test__/deltaE.test.d.ts +1 -0
  222. package/dist/src/color/__test__/deltaE.test.js +120 -0
  223. package/dist/src/color/__test__/formats.test.d.ts +1 -0
  224. package/dist/src/color/__test__/formats.test.js +470 -0
  225. package/dist/src/color/__test__/gradients.test.d.ts +1 -0
  226. package/dist/src/color/__test__/gradients.test.js +414 -0
  227. package/dist/src/color/__test__/harmonies.test.d.ts +1 -0
  228. package/dist/src/color/__test__/harmonies.test.js +734 -0
  229. package/dist/src/color/__test__/manipulations.test.d.ts +1 -0
  230. package/dist/src/color/__test__/manipulations.test.js +264 -0
  231. package/dist/src/color/__test__/names.test.d.ts +1 -0
  232. package/dist/src/color/__test__/names.test.js +67 -0
  233. package/dist/src/color/__test__/parse.test.d.ts +1 -0
  234. package/dist/src/color/__test__/parse.test.js +251 -0
  235. package/dist/src/color/__test__/random.test.d.ts +1 -0
  236. package/dist/src/color/__test__/random.test.js +262 -0
  237. package/dist/src/color/__test__/readability.test.d.ts +1 -0
  238. package/dist/src/color/__test__/readability.test.js +2596 -0
  239. package/dist/src/color/__test__/swatch.test.d.ts +1 -0
  240. package/dist/src/color/__test__/swatch.test.js +267 -0
  241. package/dist/src/color/__test__/temperature.test.d.ts +1 -0
  242. package/dist/src/color/__test__/temperature.test.js +223 -0
  243. package/dist/src/color/__test__/utils.test.d.ts +1 -0
  244. package/dist/src/color/__test__/utils.test.js +409 -0
  245. package/dist/src/color/__test__/validations.test.d.ts +1 -0
  246. package/dist/src/color/__test__/validations.test.js +239 -0
  247. package/dist/src/color/color.consts.d.ts +4 -0
  248. package/dist/src/color/color.consts.js +152 -0
  249. package/dist/src/color/color.d.ts +775 -0
  250. package/dist/src/color/color.js +903 -0
  251. package/dist/src/color/colorSpaces.d.ts +15 -0
  252. package/dist/src/color/colorSpaces.js +127 -0
  253. package/dist/src/color/combinations.d.ts +45 -0
  254. package/dist/src/color/combinations.js +557 -0
  255. package/dist/src/color/conversions.d.ts +16 -0
  256. package/dist/src/color/conversions.js +705 -0
  257. package/dist/src/color/deltaE.d.ts +59 -0
  258. package/dist/src/color/deltaE.js +110 -0
  259. package/dist/src/color/formats.d.ts +126 -0
  260. package/dist/src/color/formats.js +150 -0
  261. package/dist/src/color/gradients.d.ts +49 -0
  262. package/dist/src/color/gradients.js +673 -0
  263. package/dist/src/color/harmonies.d.ts +18 -0
  264. package/dist/src/color/harmonies.js +129 -0
  265. package/dist/src/color/manipulations.d.ts +29 -0
  266. package/dist/src/color/manipulations.js +107 -0
  267. package/dist/src/color/names.d.ts +38 -0
  268. package/dist/src/color/names.js +108 -0
  269. package/dist/src/color/parse.d.ts +2 -0
  270. package/dist/src/color/parse.js +438 -0
  271. package/dist/src/color/random.d.ts +30 -0
  272. package/dist/src/color/random.js +65 -0
  273. package/dist/src/color/readability.d.ts +53 -0
  274. package/dist/src/color/readability.js +284 -0
  275. package/dist/src/color/swatch.d.ts +49 -0
  276. package/dist/src/color/swatch.js +117 -0
  277. package/dist/src/color/temperature.d.ts +26 -0
  278. package/dist/src/color/temperature.js +142 -0
  279. package/dist/src/color/utils.d.ts +57 -0
  280. package/dist/src/color/utils.js +142 -0
  281. package/dist/src/color/validations.d.ts +2 -0
  282. package/dist/src/color/validations.js +178 -0
  283. package/dist/src/index.d.ts +20 -0
  284. package/dist/src/index.js +2 -0
  285. package/dist/src/palette/__test__/palette.test.d.ts +1 -0
  286. package/dist/src/palette/__test__/palette.test.js +397 -0
  287. package/dist/src/palette/palette.d.ts +41 -0
  288. package/dist/src/palette/palette.js +127 -0
  289. package/dist/src/utils.d.ts +20 -0
  290. package/dist/src/utils.js +42 -0
  291. package/dist/utils.d.ts +20 -0
  292. package/dist/utils.js +42 -0
  293. package/package.json +96 -0
@@ -0,0 +1,202 @@
1
+ import { Color } from '../../../dist';
2
+ function getRandomElementFromArray(arr) {
3
+ return arr[Math.floor(Math.random() * arr.length)];
4
+ }
5
+ const UPDATE_COLOR_METHOD_EXAMPLES = [
6
+ { method: 'setAlpha', argOptions: [0.1, 0.3, 0.5, 0.7, 0.9] },
7
+ { method: 'spin', argOptions: [-180, -90, -45, 45, 90, 180, 270] },
8
+ { method: 'brighten', argOptions: [undefined, 20, 30, 40] },
9
+ { method: 'darken', argOptions: [undefined, 20, 30, 40] },
10
+ { method: 'saturate', argOptions: [undefined, 20, 30, 40] },
11
+ { method: 'desaturate', argOptions: [undefined, 20, 30, 40] },
12
+ { method: 'grayscale' },
13
+ {
14
+ method: 'mix',
15
+ argOptions: [
16
+ '[new Color("red")], { space: "RGB" }',
17
+ '[new Color("green")], { space: "HSL" }',
18
+ '[new Color("blue"), new Color("#fff")], { space: "LCH" }',
19
+ '[new Color(), new Color()], { space: "OKLCH" }',
20
+ ],
21
+ },
22
+ {
23
+ method: 'blend',
24
+ argOptions: [
25
+ 'new Color("red")',
26
+ 'new Color("green"), { mode: "MULTIPLY" }',
27
+ 'new Color("blue"), { mode: "OVERLAY" }',
28
+ ],
29
+ },
30
+ {
31
+ method: 'average',
32
+ argOptions: [
33
+ '[new Color()]',
34
+ '[new Color("red"), new Color("green")]',
35
+ '[new Color("sky blue")], { weights: [0.75, 0.25] }',
36
+ ],
37
+ },
38
+ ];
39
+ const GET_RESULT_COLOR_EXAMPLES = [
40
+ 'clone()',
41
+ 'getComplementaryColors()[0]',
42
+ 'getComplementaryColors()[1]',
43
+ 'getSplitComplementaryColors()[0]',
44
+ 'getSplitComplementaryColors()[1]',
45
+ 'getSplitComplementaryColors()[2]',
46
+ 'getSquareHarmonyColors()[0]',
47
+ 'getSquareHarmonyColors()[1]',
48
+ 'getSquareHarmonyColors()[2]',
49
+ 'getSquareHarmonyColors()[3]',
50
+ 'getTetradicHarmonyColors()[0]',
51
+ 'getTetradicHarmonyColors()[1]',
52
+ 'getTetradicHarmonyColors()[2]',
53
+ 'getTetradicHarmonyColors()[3]',
54
+ 'getAnalogousHarmonyColors()[0]',
55
+ 'getAnalogousHarmonyColors()[1]',
56
+ 'getAnalogousHarmonyColors()[2]',
57
+ 'getAnalogousHarmonyColors()[3]',
58
+ 'getAnalogousHarmonyColors()[4]',
59
+ 'getMonochromaticHarmonyColors()[0]',
60
+ 'getMonochromaticHarmonyColors()[1]',
61
+ 'getMonochromaticHarmonyColors()[2]',
62
+ 'getMonochromaticHarmonyColors()[3]',
63
+ 'getMonochromaticHarmonyColors()[4]',
64
+ 'getColorSwatch()[300]',
65
+ 'getColorSwatch()[400]',
66
+ 'getColorSwatch()[600]',
67
+ 'getColorSwatch()[700]',
68
+ 'getColorPalette()["secondaryColors"][0][500]',
69
+ 'getColorPalette()["info"][500]',
70
+ 'getColorPalette()["negative"][500]',
71
+ 'getColorPalette()["positive"][500]',
72
+ ];
73
+ export function getRandomStarterCode() {
74
+ const randomColorHex = Color.random({ paletteSuitable: true }).toHex();
75
+ const updateColorMethod = getRandomElementFromArray(UPDATE_COLOR_METHOD_EXAMPLES);
76
+ const updateColorMethodArgs = updateColorMethod.argOptions
77
+ ? getRandomElementFromArray(updateColorMethod.argOptions)
78
+ : undefined;
79
+ const resultColorMethod = getRandomElementFromArray(GET_RESULT_COLOR_EXAMPLES);
80
+ return `// Return a \`Color\` or any valid color format (e.g. a hex string) to see the color visualized
81
+
82
+ const color = new Color("${randomColorHex}");
83
+ console.log("color:", color);
84
+
85
+ const updated = color.${updateColorMethod.method}(${updateColorMethodArgs ?? ''});
86
+ console.log("updated color:", updated);
87
+
88
+ const result = updated.${resultColorMethod};
89
+ return result; // rendered below if valid`;
90
+ }
91
+ function formatMockedJSConsoleValue(value) {
92
+ try {
93
+ if (value === undefined) {
94
+ return 'undefined';
95
+ }
96
+ if (typeof value === 'string') {
97
+ return value;
98
+ }
99
+ if (typeof value === 'function') {
100
+ return `[Function ${value.name || 'anonymous'}]`;
101
+ }
102
+ if (value && typeof value === 'object') {
103
+ // Try to show Color nicely if it has toHexString:
104
+ if ('toHex' in value && typeof value.toHex === 'function') {
105
+ return `Color(${value.toHex()})`;
106
+ }
107
+ return JSON.stringify(value, null, 2);
108
+ }
109
+ return String(value);
110
+ }
111
+ catch {
112
+ return '[unserializable]';
113
+ }
114
+ }
115
+ const ANON_FUNCTION_TRACE_LOCATION_PREFIX = '<anonymous>:';
116
+ const ANON_FUNCTION_LINE_NUMBER_OFFSET = 4; // this is because when we define `codeRunnerFn`, the `${code}` part is on line 5
117
+ function tryToGetLineNumberFromError(error) {
118
+ if (!('stack' in error) || typeof error.stack !== 'string') {
119
+ return null;
120
+ }
121
+ const { stack } = error;
122
+ const anonFunctionTraceIndex = stack.indexOf(ANON_FUNCTION_TRACE_LOCATION_PREFIX);
123
+ if (anonFunctionTraceIndex < 0) {
124
+ return null;
125
+ }
126
+ const lineNumberPartAndRest = stack.substring(anonFunctionTraceIndex + ANON_FUNCTION_TRACE_LOCATION_PREFIX.length);
127
+ const restIndex = lineNumberPartAndRest.indexOf(':');
128
+ if (restIndex < 0) {
129
+ return null;
130
+ }
131
+ const lineNumberPart = lineNumberPartAndRest.substring(0, restIndex);
132
+ if (!lineNumberPart) {
133
+ return null;
134
+ }
135
+ const lineNumber = parseInt(lineNumberPart);
136
+ if (isNaN(lineNumber)) {
137
+ return null;
138
+ }
139
+ return lineNumber - ANON_FUNCTION_LINE_NUMBER_OFFSET;
140
+ }
141
+ function getErrorMessage(error, fallbackMessage) {
142
+ if (error && typeof error === 'object') {
143
+ const maybeLineNumber = tryToGetLineNumberFromError(error);
144
+ if ('message' in error && typeof error.message === 'string') {
145
+ return `Error${maybeLineNumber !== null ? ` (line ${maybeLineNumber})` : ''}: ${error.message}`;
146
+ }
147
+ }
148
+ return fallbackMessage;
149
+ }
150
+ export var CodeExecutionStatus;
151
+ (function (CodeExecutionStatus) {
152
+ CodeExecutionStatus["CODE_ERROR"] = "CODE_ERROR";
153
+ CodeExecutionStatus["NO_RETURNED_VALUE"] = "NO_RETURNED_VALUE";
154
+ CodeExecutionStatus["INVALID_RETURNED_VALUE"] = "INVALID_RETURNED_VALUE";
155
+ CodeExecutionStatus["SUCCESS"] = "SUCCESS";
156
+ })(CodeExecutionStatus || (CodeExecutionStatus = {}));
157
+ export async function tryToRunCode(code) {
158
+ const capturedJSConsoleOutputs = [];
159
+ const mockJSConsole = {
160
+ log: (...args) => capturedJSConsoleOutputs.push(args.map(formatMockedJSConsoleValue).join(' ')),
161
+ warn: (...args) => capturedJSConsoleOutputs.push('⚠️ ' + args.map(formatMockedJSConsoleValue).join(' ')),
162
+ error: (...args) => capturedJSConsoleOutputs.push('❌ ' + args.map(formatMockedJSConsoleValue).join(' ')),
163
+ };
164
+ let maybeColorValue;
165
+ try {
166
+ const codeRunnerFn = new Function('Color', 'console', `"use strict";
167
+ return (async () => {
168
+ ${code}
169
+ })();`);
170
+ maybeColorValue = await codeRunnerFn(Color, mockJSConsole);
171
+ }
172
+ catch (err) {
173
+ return {
174
+ consoleOutputs: capturedJSConsoleOutputs,
175
+ errorMessage: getErrorMessage(err, 'Error: invalid code'),
176
+ status: CodeExecutionStatus.CODE_ERROR,
177
+ };
178
+ }
179
+ if (!maybeColorValue) {
180
+ return {
181
+ consoleOutputs: capturedJSConsoleOutputs,
182
+ errorMessage: 'Error: no color returned',
183
+ status: CodeExecutionStatus.NO_RETURNED_VALUE,
184
+ };
185
+ }
186
+ let maybeColor;
187
+ try {
188
+ maybeColor = new Color(maybeColorValue);
189
+ }
190
+ catch (err) {
191
+ return {
192
+ consoleOutputs: capturedJSConsoleOutputs,
193
+ errorMessage: getErrorMessage(err, 'Error: invalid returned color value'),
194
+ status: CodeExecutionStatus.INVALID_RETURNED_VALUE,
195
+ };
196
+ }
197
+ return {
198
+ color: maybeColor,
199
+ consoleOutputs: capturedJSConsoleOutputs,
200
+ status: CodeExecutionStatus.SUCCESS,
201
+ };
202
+ }
@@ -0,0 +1,9 @@
1
+ type PageHeadProps = {
2
+ title: string;
3
+ description: string;
4
+ path: string;
5
+ image?: string;
6
+ type?: string;
7
+ };
8
+ export declare function PageHead({ title, description, path, image, type }: PageHeadProps): null;
9
+ export {};
@@ -0,0 +1,76 @@
1
+ import { useEffect, useMemo } from 'react';
2
+ const siteOrigin = 'https://rteammco.github.io';
3
+ const basePath = (import.meta.env.BASE_URL ?? '/').replace(/\/$/, '');
4
+ const withLeadingSlash = (value) => (value.startsWith('/') ? value : `/${value}`);
5
+ const getAbsoluteUrl = (path) => `${siteOrigin}${basePath}${withLeadingSlash(path)}`;
6
+ const resolveImageUrl = (image) => {
7
+ if (!image) {
8
+ return getAbsoluteUrl('/social-card.png');
9
+ }
10
+ if (/^https?:\/\//.test(image)) {
11
+ return image;
12
+ }
13
+ return getAbsoluteUrl(withLeadingSlash(image));
14
+ };
15
+ export function PageHead({ title, description, path, image, type = 'website' }) {
16
+ const canonicalUrl = useMemo(() => getAbsoluteUrl(path), [path]);
17
+ const imageUrl = useMemo(() => resolveImageUrl(image), [image]);
18
+ useEffect(() => {
19
+ const revertActions = [];
20
+ const updateMeta = (attribute, key, content) => {
21
+ const selector = `meta[${attribute}="${key}"]`;
22
+ let element = document.head.querySelector(selector);
23
+ if (!element) {
24
+ element = document.createElement('meta');
25
+ element.setAttribute(attribute, key);
26
+ document.head.appendChild(element);
27
+ }
28
+ const previousContent = element.getAttribute('content');
29
+ element.setAttribute('content', content);
30
+ revertActions.push(() => {
31
+ if (previousContent === null) {
32
+ element?.remove();
33
+ return;
34
+ }
35
+ element?.setAttribute('content', previousContent);
36
+ });
37
+ };
38
+ const updateCanonical = (href) => {
39
+ let link = document.head.querySelector('link[rel="canonical"]');
40
+ if (!link) {
41
+ link = document.createElement('link');
42
+ link.setAttribute('rel', 'canonical');
43
+ document.head.appendChild(link);
44
+ }
45
+ const previousHref = link.getAttribute('href');
46
+ link.setAttribute('href', href);
47
+ revertActions.push(() => {
48
+ if (previousHref === null) {
49
+ link?.remove();
50
+ return;
51
+ }
52
+ link?.setAttribute('href', previousHref);
53
+ });
54
+ };
55
+ const previousTitle = document.title;
56
+ document.title = title;
57
+ revertActions.push(() => {
58
+ document.title = previousTitle;
59
+ });
60
+ updateCanonical(canonicalUrl);
61
+ updateMeta('name', 'description', description);
62
+ updateMeta('property', 'og:title', title);
63
+ updateMeta('property', 'og:description', description);
64
+ updateMeta('property', 'og:type', type);
65
+ updateMeta('property', 'og:url', canonicalUrl);
66
+ updateMeta('property', 'og:image', imageUrl);
67
+ updateMeta('name', 'twitter:card', 'summary_large_image');
68
+ updateMeta('name', 'twitter:title', title);
69
+ updateMeta('name', 'twitter:description', description);
70
+ updateMeta('name', 'twitter:image', imageUrl);
71
+ return () => {
72
+ revertActions.reverse().forEach((revert) => revert());
73
+ };
74
+ }, [canonicalUrl, description, imageUrl, title, type]);
75
+ return null;
76
+ }
@@ -0,0 +1,6 @@
1
+ type JsonLd = Record<string, unknown>;
2
+ type StructuredDataProps = {
3
+ data: JsonLd;
4
+ };
5
+ export declare function StructuredData({ data }: StructuredDataProps): null;
6
+ export {};
@@ -0,0 +1,13 @@
1
+ import { useEffect } from 'react';
2
+ export function StructuredData({ data }) {
3
+ useEffect(() => {
4
+ const script = document.createElement('script');
5
+ script.setAttribute('type', 'application/ld+json');
6
+ script.textContent = JSON.stringify(data);
7
+ document.head.appendChild(script);
8
+ return () => {
9
+ document.head.removeChild(script);
10
+ };
11
+ }, [data]);
12
+ return null;
13
+ }
@@ -0,0 +1,2 @@
1
+ import { type PropsWithChildren } from 'react';
2
+ export declare function ToastProvider({ children }: PropsWithChildren): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,62 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useRef, useState } from 'react';
3
+ import { Icon } from '../components/Icon';
4
+ import { subscribeToToast } from './toastBus';
5
+ const DEFAULT_TOAST_DURATION_MS = 4500;
6
+ function getToastVariantStyles(toastVariant) {
7
+ switch (toastVariant) {
8
+ case 'SUCCESS':
9
+ return {
10
+ iconClassName: 'text-emerald-600 dark:text-emerald-300',
11
+ iconType: Icon.TYPE.CHECK_CIRCLE,
12
+ };
13
+ case 'ERROR':
14
+ return {
15
+ iconClassName: 'text-rose-600 dark:text-rose-300',
16
+ iconType: Icon.TYPE.X_CIRCLE,
17
+ };
18
+ case 'INFO':
19
+ default:
20
+ return {
21
+ iconClassName: 'text-blue-600 dark:text-blue-300',
22
+ iconType: Icon.TYPE.INFO_CIRCLE,
23
+ };
24
+ }
25
+ }
26
+ export function ToastProvider({ children }) {
27
+ const [toasts, setToasts] = useState([]);
28
+ const dismissTimeoutMapRef = useRef(new Map());
29
+ const dismissToast = useCallback((toastID) => {
30
+ const dismissTimeout = dismissTimeoutMapRef.current.get(toastID);
31
+ if (dismissTimeout != null) {
32
+ window.clearTimeout(dismissTimeout);
33
+ dismissTimeoutMapRef.current.delete(toastID);
34
+ }
35
+ setToasts((currentToasts) => currentToasts.filter((currentToast) => currentToast.id !== toastID));
36
+ }, []);
37
+ const enqueueToast = useCallback((toastEvent) => {
38
+ const toastID = `${Date.now()}-${Math.random().toString(16).slice(2)}`;
39
+ const toastDurationMs = toastEvent.durationMs == null ? DEFAULT_TOAST_DURATION_MS : toastEvent.durationMs;
40
+ setToasts((currentToasts) => [...currentToasts, { ...toastEvent, id: toastID }]);
41
+ if (toastDurationMs > 0) {
42
+ const dismissTimeout = window.setTimeout(() => {
43
+ dismissToast(toastID);
44
+ }, toastDurationMs);
45
+ dismissTimeoutMapRef.current.set(toastID, dismissTimeout);
46
+ }
47
+ }, [dismissToast]);
48
+ useEffect(() => {
49
+ const dismissTimeoutMap = dismissTimeoutMapRef.current;
50
+ return () => {
51
+ dismissTimeoutMap.forEach((dismissTimeout) => {
52
+ window.clearTimeout(dismissTimeout);
53
+ });
54
+ dismissTimeoutMap.clear();
55
+ };
56
+ }, []);
57
+ useEffect(() => subscribeToToast(enqueueToast), [enqueueToast]);
58
+ return (_jsxs(_Fragment, { children: [children, _jsx("div", { className: "pointer-events-none fixed right-4 bottom-4 z-50 flex max-w-sm flex-col gap-2", children: toasts.map((toast) => {
59
+ const variantStyles = getToastVariantStyles(toast.variant);
60
+ return (_jsx("div", { "aria-atomic": "true", className: "pointer-events-auto rounded-xl border border-slate-200 bg-white/95 p-3 text-left shadow-lg backdrop-blur-sm dark:border-slate-700 dark:bg-slate-900/95", role: toast.variant === 'ERROR' ? 'alert' : 'status', children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: variantStyles.iconClassName, children: _jsx(Icon, { size: 20, type: variantStyles.iconType }) }), _jsxs("div", { className: "flex-1 text-sm text-slate-800 dark:text-slate-100", children: [_jsx("p", { className: "font-medium", children: toast.message }), toast.description != null ? (_jsx("p", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: toast.description })) : null] }), _jsx("button", { "aria-label": "Dismiss alert", className: "icon-button", onClick: () => dismissToast(toast.id), type: "button", children: _jsx(Icon, { size: 18, type: Icon.TYPE.X }) })] }) }, toast.id));
61
+ }) })] }));
62
+ }
@@ -0,0 +1,2 @@
1
+ export { ToastProvider } from './ToastProvider';
2
+ export { showErrorToast, showInfoToast, showSuccessToast } from './toastBus';
@@ -0,0 +1,2 @@
1
+ export { ToastProvider } from './ToastProvider';
2
+ export { showErrorToast, showInfoToast, showSuccessToast } from './toastBus';
@@ -0,0 +1,13 @@
1
+ export type ToastVariant = 'SUCCESS' | 'ERROR' | 'INFO';
2
+ export interface ToastEvent {
3
+ description?: string;
4
+ durationMs?: number;
5
+ message: string;
6
+ variant: ToastVariant;
7
+ }
8
+ type ToastListener = (toastEvent: ToastEvent) => void;
9
+ export declare function subscribeToToast(listener: ToastListener): () => void;
10
+ export declare function showSuccessToast(message: string, durationMs?: number): void;
11
+ export declare function showInfoToast(message: string, durationMs?: number): void;
12
+ export declare function showErrorToast(message: string, error?: unknown, durationMs?: number): void;
13
+ export {};
@@ -0,0 +1,27 @@
1
+ const toastListeners = new Set();
2
+ export function subscribeToToast(listener) {
3
+ toastListeners.add(listener);
4
+ return () => {
5
+ toastListeners.delete(listener);
6
+ };
7
+ }
8
+ function showToast(toastEvent) {
9
+ toastListeners.forEach((listener) => {
10
+ listener(toastEvent);
11
+ });
12
+ }
13
+ export function showSuccessToast(message, durationMs) {
14
+ showToast({ durationMs, message, variant: 'SUCCESS' });
15
+ }
16
+ export function showInfoToast(message, durationMs) {
17
+ showToast({ durationMs, message, variant: 'INFO' });
18
+ }
19
+ export function showErrorToast(message, error, durationMs) {
20
+ const errorDescription = error instanceof Error ? error.message : error != null ? String(error) : undefined;
21
+ showToast({
22
+ description: errorDescription,
23
+ durationMs,
24
+ message,
25
+ variant: 'ERROR',
26
+ });
27
+ }