aidos-ui 3.0.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 (339) hide show
  1. package/.prettierrc +4 -0
  2. package/LICENSE +21 -0
  3. package/README.md +55 -0
  4. package/dist/Badge.d.ts +7 -0
  5. package/dist/Badge.js +22 -0
  6. package/dist/Badge.js.map +1 -0
  7. package/dist/BaseButton.d.ts +13 -0
  8. package/dist/BaseButton.js +22 -0
  9. package/dist/BaseButton.js.map +1 -0
  10. package/dist/BaseInput.d.ts +15 -0
  11. package/dist/BaseInput.js +14 -0
  12. package/dist/BaseInput.js.map +1 -0
  13. package/dist/BaseLink.d.ts +17 -0
  14. package/dist/BaseLink.js +28 -0
  15. package/dist/BaseLink.js.map +1 -0
  16. package/dist/BaseList.d.ts +6 -0
  17. package/dist/BaseList.js +14 -0
  18. package/dist/BaseList.js.map +1 -0
  19. package/dist/BaseListAddOn.d.ts +5 -0
  20. package/dist/BaseListAddOn.js +7 -0
  21. package/dist/BaseListAddOn.js.map +1 -0
  22. package/dist/BaseListItem.d.ts +27 -0
  23. package/dist/BaseListItem.js +26 -0
  24. package/dist/BaseListItem.js.map +1 -0
  25. package/dist/BaseView.d.ts +12 -0
  26. package/dist/BaseView.js +26 -0
  27. package/dist/BaseView.js.map +1 -0
  28. package/dist/Box.d.ts +5 -0
  29. package/dist/Box.js +6 -0
  30. package/dist/Box.js.map +1 -0
  31. package/dist/Button.d.ts +20 -0
  32. package/dist/Button.js +20 -0
  33. package/dist/Button.js.map +1 -0
  34. package/dist/Calendar.d.ts +18 -0
  35. package/dist/Calendar.js +57 -0
  36. package/dist/Calendar.js.map +1 -0
  37. package/dist/Card.d.ts +4 -0
  38. package/dist/Card.js +12 -0
  39. package/dist/Card.js.map +1 -0
  40. package/dist/Checkbox.d.ts +12 -0
  41. package/dist/Checkbox.js +32 -0
  42. package/dist/Checkbox.js.map +1 -0
  43. package/dist/Circle.d.ts +6 -0
  44. package/dist/Circle.js +12 -0
  45. package/dist/Circle.js.map +1 -0
  46. package/dist/Column.d.ts +6 -0
  47. package/dist/Column.js +7 -0
  48. package/dist/Column.js.map +1 -0
  49. package/dist/DarkMode.d.ts +13 -0
  50. package/dist/DarkMode.js +61 -0
  51. package/dist/DarkMode.js.map +1 -0
  52. package/dist/DateInput.d.ts +13 -0
  53. package/dist/DateInput.js +29 -0
  54. package/dist/DateInput.js.map +1 -0
  55. package/dist/DatePicker.d.ts +12 -0
  56. package/dist/DatePicker.js +34 -0
  57. package/dist/DatePicker.js.map +1 -0
  58. package/dist/DatetimeInput.d.ts +13 -0
  59. package/dist/DatetimeInput.js +31 -0
  60. package/dist/DatetimeInput.js.map +1 -0
  61. package/dist/DesignBook.d.ts +2 -0
  62. package/dist/DesignBook.js +55 -0
  63. package/dist/DesignBook.js.map +1 -0
  64. package/dist/Dialog.d.ts +17 -0
  65. package/dist/Dialog.js +86 -0
  66. package/dist/Dialog.js.map +1 -0
  67. package/dist/Dropdown.d.ts +10 -0
  68. package/dist/Dropdown.js +64 -0
  69. package/dist/Dropdown.js.map +1 -0
  70. package/dist/Emitter.d.ts +6 -0
  71. package/dist/Emitter.js +19 -0
  72. package/dist/Emitter.js.map +1 -0
  73. package/dist/FlexLayout.d.ts +11 -0
  74. package/dist/FlexLayout.js +18 -0
  75. package/dist/FlexLayout.js.map +1 -0
  76. package/dist/Icon.d.ts +12 -0
  77. package/dist/Icon.js +69 -0
  78. package/dist/Icon.js.map +1 -0
  79. package/dist/IconButton.d.ts +9 -0
  80. package/dist/IconButton.js +31 -0
  81. package/dist/IconButton.js.map +1 -0
  82. package/dist/IconLink.d.ts +9 -0
  83. package/dist/IconLink.js +31 -0
  84. package/dist/IconLink.js.map +1 -0
  85. package/dist/IconType.d.ts +1 -0
  86. package/dist/IconType.js +2 -0
  87. package/dist/IconType.js.map +1 -0
  88. package/dist/Interactable.d.ts +48 -0
  89. package/dist/Interactable.js +131 -0
  90. package/dist/Interactable.js.map +1 -0
  91. package/dist/Link.d.ts +20 -0
  92. package/dist/Link.js +22 -0
  93. package/dist/Link.js.map +1 -0
  94. package/dist/List.d.ts +11 -0
  95. package/dist/List.js +17 -0
  96. package/dist/List.js.map +1 -0
  97. package/dist/ListButtonItem.d.ts +15 -0
  98. package/dist/ListButtonItem.js +9 -0
  99. package/dist/ListButtonItem.js.map +1 -0
  100. package/dist/ListDivider.d.ts +2 -0
  101. package/dist/ListDivider.js +12 -0
  102. package/dist/ListDivider.js.map +1 -0
  103. package/dist/ListHeaderItem.d.ts +11 -0
  104. package/dist/ListHeaderItem.js +13 -0
  105. package/dist/ListHeaderItem.js.map +1 -0
  106. package/dist/ListItem.d.ts +10 -0
  107. package/dist/ListItem.js +7 -0
  108. package/dist/ListItem.js.map +1 -0
  109. package/dist/ListLinkItem.d.ts +17 -0
  110. package/dist/ListLinkItem.js +9 -0
  111. package/dist/ListLinkItem.js.map +1 -0
  112. package/dist/ListSpacer.d.ts +2 -0
  113. package/dist/ListSpacer.js +13 -0
  114. package/dist/ListSpacer.js.map +1 -0
  115. package/dist/OnVisible.d.ts +5 -0
  116. package/dist/OnVisible.js +28 -0
  117. package/dist/OnVisible.js.map +1 -0
  118. package/dist/Popover.d.ts +21 -0
  119. package/dist/Popover.js +88 -0
  120. package/dist/Popover.js.map +1 -0
  121. package/dist/ProgressBar.d.ts +8 -0
  122. package/dist/ProgressBar.js +42 -0
  123. package/dist/ProgressBar.js.map +1 -0
  124. package/dist/ProgressCircle.d.ts +6 -0
  125. package/dist/ProgressCircle.js +12 -0
  126. package/dist/ProgressCircle.js.map +1 -0
  127. package/dist/Providers.d.ts +9 -0
  128. package/dist/Providers.js +16 -0
  129. package/dist/Providers.js.map +1 -0
  130. package/dist/RangeInput.d.ts +14 -0
  131. package/dist/RangeInput.js +32 -0
  132. package/dist/RangeInput.js.map +1 -0
  133. package/dist/ResultOrError.d.ts +13 -0
  134. package/dist/ResultOrError.js +7 -0
  135. package/dist/ResultOrError.js.map +1 -0
  136. package/dist/RootView.d.ts +5 -0
  137. package/dist/RootView.js +35 -0
  138. package/dist/RootView.js.map +1 -0
  139. package/dist/Router.d.ts +2 -0
  140. package/dist/Router.js +37 -0
  141. package/dist/Router.js.map +1 -0
  142. package/dist/RouterState.d.ts +38 -0
  143. package/dist/RouterState.js +111 -0
  144. package/dist/RouterState.js.map +1 -0
  145. package/dist/Row.d.ts +6 -0
  146. package/dist/Row.js +7 -0
  147. package/dist/Row.js.map +1 -0
  148. package/dist/StackContext.d.ts +8 -0
  149. package/dist/StackContext.js +25 -0
  150. package/dist/StackContext.js.map +1 -0
  151. package/dist/StaticCheckbox.d.ts +17 -0
  152. package/dist/StaticCheckbox.js +48 -0
  153. package/dist/StaticCheckbox.js.map +1 -0
  154. package/dist/Storage.d.ts +12 -0
  155. package/dist/Storage.js +148 -0
  156. package/dist/Storage.js.map +1 -0
  157. package/dist/Stream.d.ts +9 -0
  158. package/dist/Stream.js +36 -0
  159. package/dist/Stream.js.map +1 -0
  160. package/dist/Sublist.d.ts +12 -0
  161. package/dist/Sublist.js +18 -0
  162. package/dist/Sublist.js.map +1 -0
  163. package/dist/SubmitIconInput.d.ts +9 -0
  164. package/dist/SubmitIconInput.js +25 -0
  165. package/dist/SubmitIconInput.js.map +1 -0
  166. package/dist/Tabs.d.ts +20 -0
  167. package/dist/Tabs.js +35 -0
  168. package/dist/Tabs.js.map +1 -0
  169. package/dist/Text.d.ts +25 -0
  170. package/dist/Text.js +50 -0
  171. package/dist/Text.js.map +1 -0
  172. package/dist/TextArea.d.ts +10 -0
  173. package/dist/TextArea.js +22 -0
  174. package/dist/TextArea.js.map +1 -0
  175. package/dist/TextInput.d.ts +14 -0
  176. package/dist/TextInput.js +52 -0
  177. package/dist/TextInput.js.map +1 -0
  178. package/dist/TextInputWithState.d.ts +10 -0
  179. package/dist/TextInputWithState.js +14 -0
  180. package/dist/TextInputWithState.js.map +1 -0
  181. package/dist/TextPairing.d.ts +21 -0
  182. package/dist/TextPairing.js +26 -0
  183. package/dist/TextPairing.js.map +1 -0
  184. package/dist/TimeInput.d.ts +15 -0
  185. package/dist/TimeInput.js +58 -0
  186. package/dist/TimeInput.js.map +1 -0
  187. package/dist/Tooltip.d.ts +11 -0
  188. package/dist/Tooltip.js +72 -0
  189. package/dist/Tooltip.js.map +1 -0
  190. package/dist/aria.d.ts +8 -0
  191. package/dist/aria.js +42 -0
  192. package/dist/aria.js.map +1 -0
  193. package/dist/guid.d.ts +1 -0
  194. package/dist/guid.js +7 -0
  195. package/dist/guid.js.map +1 -0
  196. package/dist/hash.d.ts +1 -0
  197. package/dist/hash.js +20 -0
  198. package/dist/hash.js.map +1 -0
  199. package/dist/index.d.ts +65 -0
  200. package/dist/index.js +66 -0
  201. package/dist/index.js.map +1 -0
  202. package/dist/jss.d.ts +110 -0
  203. package/dist/jss.js +438 -0
  204. package/dist/jss.js.map +1 -0
  205. package/dist/numberToBase.d.ts +1 -0
  206. package/dist/numberToBase.js +44 -0
  207. package/dist/numberToBase.js.map +1 -0
  208. package/dist/stateMachineContextFactory.d.ts +36 -0
  209. package/dist/stateMachineContextFactory.js +48 -0
  210. package/dist/stateMachineContextFactory.js.map +1 -0
  211. package/dist/useCookie.d.ts +9 -0
  212. package/dist/useCookie.js +65 -0
  213. package/dist/useCookie.js.map +1 -0
  214. package/dist/useKeyboard.d.ts +8 -0
  215. package/dist/useKeyboard.js +26 -0
  216. package/dist/useKeyboard.js.map +1 -0
  217. package/dist/useNavigation.d.ts +5 -0
  218. package/dist/useNavigation.js +79 -0
  219. package/dist/useNavigation.js.map +1 -0
  220. package/dist/usePromise.d.ts +1 -0
  221. package/dist/usePromise.js +12 -0
  222. package/dist/usePromise.js.map +1 -0
  223. package/dist/useRefEffect.d.ts +1 -0
  224. package/dist/useRefEffect.js +15 -0
  225. package/dist/useRefEffect.js.map +1 -0
  226. package/next-env.d.ts +5 -0
  227. package/next.config.js +21 -0
  228. package/package.json +40 -0
  229. package/scripts/publish.js +27 -0
  230. package/src/Badge.tsx +36 -0
  231. package/src/BaseButton.tsx +58 -0
  232. package/src/BaseInput.tsx +57 -0
  233. package/src/BaseLink.tsx +77 -0
  234. package/src/BaseList.tsx +29 -0
  235. package/src/BaseListAddOn.tsx +10 -0
  236. package/src/BaseListItem.tsx +117 -0
  237. package/src/BaseView.tsx +57 -0
  238. package/src/Box.tsx +20 -0
  239. package/src/Button.tsx +84 -0
  240. package/src/Calendar.tsx +125 -0
  241. package/src/Card.tsx +17 -0
  242. package/src/Checkbox.tsx +63 -0
  243. package/src/Circle.tsx +24 -0
  244. package/src/Column.tsx +12 -0
  245. package/src/DarkMode.tsx +99 -0
  246. package/src/DateInput.tsx +63 -0
  247. package/src/DatePicker.tsx +67 -0
  248. package/src/DatetimeInput.tsx +71 -0
  249. package/src/DesignBook.tsx +697 -0
  250. package/src/Dialog.tsx +144 -0
  251. package/src/Dropdown.tsx +129 -0
  252. package/src/Emitter.ts +26 -0
  253. package/src/FlexLayout.tsx +53 -0
  254. package/src/Icon.tsx +96 -0
  255. package/src/IconButton.tsx +66 -0
  256. package/src/IconLink.tsx +58 -0
  257. package/src/IconType.ts +787 -0
  258. package/src/Interactable.tsx +159 -0
  259. package/src/Link.tsx +86 -0
  260. package/src/List.tsx +41 -0
  261. package/src/ListButtonItem.tsx +69 -0
  262. package/src/ListDivider.tsx +13 -0
  263. package/src/ListHeaderItem.tsx +45 -0
  264. package/src/ListItem.tsx +27 -0
  265. package/src/ListLinkItem.tsx +76 -0
  266. package/src/ListSpacer.tsx +14 -0
  267. package/src/OnVisible.tsx +42 -0
  268. package/src/Popover.tsx +141 -0
  269. package/src/ProgressBar.tsx +63 -0
  270. package/src/ProgressCircle.tsx +38 -0
  271. package/src/Providers.tsx +33 -0
  272. package/src/RangeInput.tsx +82 -0
  273. package/src/ResultOrError.ts +15 -0
  274. package/src/RootView.tsx +55 -0
  275. package/src/Router.tsx +62 -0
  276. package/src/RouterState.tsx +154 -0
  277. package/src/Row.tsx +12 -0
  278. package/src/StackContext.tsx +52 -0
  279. package/src/StaticCheckbox.tsx +74 -0
  280. package/src/Storage.tsx +200 -0
  281. package/src/Stream.tsx +50 -0
  282. package/src/Sublist.tsx +62 -0
  283. package/src/SubmitIconInput.tsx +45 -0
  284. package/src/Tabs.tsx +103 -0
  285. package/src/Text.tsx +102 -0
  286. package/src/TextArea.tsx +45 -0
  287. package/src/TextInput.tsx +111 -0
  288. package/src/TextInputWithState.tsx +35 -0
  289. package/src/TextPairing.tsx +115 -0
  290. package/src/TimeInput.tsx +109 -0
  291. package/src/Tooltip.tsx +108 -0
  292. package/src/aria.ts +72 -0
  293. package/src/examples/ExampleDialog.tsx +28 -0
  294. package/src/guid.ts +7 -0
  295. package/src/hash.ts +21 -0
  296. package/src/index.ts +65 -0
  297. package/src/jss.tsx +607 -0
  298. package/src/numberToBase.ts +52 -0
  299. package/src/pages/Badge.mdx +30 -0
  300. package/src/pages/Button.mdx +57 -0
  301. package/src/pages/Calendar.mdx +60 -0
  302. package/src/pages/Checkbox.mdx +56 -0
  303. package/src/pages/Dialog.mdx +32 -0
  304. package/src/pages/FlexLayout.mdx +77 -0
  305. package/src/pages/Hashing.mdx +20 -0
  306. package/src/pages/Icon.mdx +63 -0
  307. package/src/pages/IconButton.mdx +144 -0
  308. package/src/pages/Link.mdx +57 -0
  309. package/src/pages/List.mdx +292 -0
  310. package/src/pages/ListHeader.mdx +94 -0
  311. package/src/pages/Popover.mdx +101 -0
  312. package/src/pages/ProgressBar.mdx +20 -0
  313. package/src/pages/ProgressCircle.mdx +35 -0
  314. package/src/pages/RangeInput.mdx +109 -0
  315. package/src/pages/Tabs.mdx +168 -0
  316. package/src/pages/Text.mdx +133 -0
  317. package/src/pages/TextInput.mdx +110 -0
  318. package/src/pages/TextPairing.mdx +155 -0
  319. package/src/pages/TimeInput.mdx +73 -0
  320. package/src/pages/Tooltip.mdx +28 -0
  321. package/src/pages/_app.tsx +561 -0
  322. package/src/pages/_document.tsx +30 -0
  323. package/src/pages/css-in-js.mdx +127 -0
  324. package/src/pages/index.mdx +58 -0
  325. package/src/pages/navigation.mdx +56 -0
  326. package/src/pages/prism.css +3 -0
  327. package/src/pages/useCookie.mdx +15 -0
  328. package/src/pages/useKeyboard.mdx +20 -0
  329. package/src/pages/useNavigation.mdx +30 -0
  330. package/src/pages/usePromise.mdx +15 -0
  331. package/src/pages/useRefEffect.mdx +49 -0
  332. package/src/stateMachineContextFactory.tsx +111 -0
  333. package/src/useCookie.tsx +89 -0
  334. package/src/useKeyboard.tsx +43 -0
  335. package/src/useNavigation.tsx +89 -0
  336. package/src/usePromise.tsx +18 -0
  337. package/src/useRefEffect.tsx +18 -0
  338. package/tsconfig.build.json +23 -0
  339. package/tsconfig.json +23 -0
package/src/jss.tsx ADDED
@@ -0,0 +1,607 @@
1
+ import CSS from "csstype";
2
+ import React, { useRef } from "react";
3
+
4
+ import { hash } from "./hash";
5
+ import { numberToBase } from "./numberToBase";
6
+
7
+ type StylesValueType = string | number | CSS.Properties<string | number>;
8
+
9
+ export type Styles = CSS.Properties<
10
+ string | number | CSS.Properties<string | number>
11
+ >;
12
+
13
+ export type JSStyle =
14
+ | Styles
15
+ | null
16
+ | false
17
+ | undefined
18
+ | { [key: string]: Styles }
19
+ | Array<JSStyle>;
20
+
21
+ const aliases: {
22
+ [alias: string]: (value: StylesValueType) => [string, StylesValueType][];
23
+ } = {
24
+ margin: (value: string) => {
25
+ if (value == null) {
26
+ return [];
27
+ }
28
+
29
+ const matches =
30
+ typeof value === "string"
31
+ ? Array.from(value.matchAll(/(.+) (.+)$/g))[0]
32
+ : null;
33
+ if (matches) {
34
+ return [
35
+ ["margin-top", matches[1]],
36
+ ["margin-bottom", matches[1]],
37
+ ["margin-left", matches[2]],
38
+ ["margin-right", matches[2]],
39
+ ];
40
+ } else {
41
+ return [
42
+ ["margin-top", value],
43
+ ["margin-bottom", value],
44
+ ["margin-left", value],
45
+ ["margin-right", value],
46
+ ];
47
+ }
48
+ },
49
+ padding: (value: string) => {
50
+ if (value == null) {
51
+ return [];
52
+ }
53
+
54
+ const matches =
55
+ typeof value === "string"
56
+ ? Array.from(value.matchAll(/(.+) (.+)$/g))[0]
57
+ : null;
58
+
59
+ if (matches) {
60
+ return [
61
+ ["padding-top", matches[1]],
62
+ ["padding-bottom", matches[1]],
63
+ ["padding-left", matches[2]],
64
+ ["padding-right", matches[2]],
65
+ ];
66
+ } else {
67
+ return [
68
+ ["padding-top", value],
69
+ ["padding-bottom", value],
70
+ ["padding-left", value],
71
+ ["padding-right", value],
72
+ ];
73
+ }
74
+ },
75
+ };
76
+
77
+ const rawHashMap = new Map<string, string>();
78
+
79
+ function createStyleNode(content: string) {
80
+ if (typeof window === "undefined") {
81
+ serverStyles.push(content);
82
+ } else {
83
+ const style = document.createElement("style");
84
+ style.appendChild(document.createTextNode(content));
85
+ document.head.appendChild(style);
86
+ }
87
+ }
88
+
89
+ const pixelStyles = new Set([
90
+ "min-height",
91
+ "height",
92
+ "max-height",
93
+ "min-width",
94
+ "width",
95
+ "max-width",
96
+ "margin",
97
+ "margin-top",
98
+ "margin-bottom",
99
+ "margin-left",
100
+ "margin-right",
101
+ "padding",
102
+ "padding-top",
103
+ "padding-bottom",
104
+ "padding-left",
105
+ "padding-right",
106
+ "border-radius",
107
+ "font-size",
108
+ "top",
109
+ "bottom",
110
+ "left",
111
+ "right",
112
+ "outline-offset",
113
+ ]);
114
+
115
+ const toPixelValue = (key: string, value): string => {
116
+ const sValue = value.toString();
117
+
118
+ if (
119
+ sValue.includes("%") ||
120
+ sValue.includes("v") ||
121
+ sValue.includes("px") ||
122
+ sValue.includes("em") ||
123
+ sValue.includes("rem")
124
+ ) {
125
+ return sValue;
126
+ }
127
+
128
+ return pixelStyles.has(key) && Number.isInteger(parseInt(value, 10))
129
+ ? `${value}px`
130
+ : value;
131
+ };
132
+
133
+ const getCSS = (key: string, value): [string, string] => {
134
+ const cssProp = key.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
135
+ const cssValue = toPixelValue(cssProp, value);
136
+ return [cssProp, cssValue];
137
+ };
138
+
139
+ const flattenJSStyle = (jsStyle: JSStyle): Styles => {
140
+ if (!jsStyle) {
141
+ return {};
142
+ } else if (Array.isArray(jsStyle)) {
143
+ // @ts-ignore
144
+ return jsStyle.reduce((acc: Styles, jsStyle: JSStyle) => {
145
+ return { ...acc, ...flattenJSStyle(jsStyle) };
146
+ }, {});
147
+ } else {
148
+ return jsStyle;
149
+ }
150
+ };
151
+
152
+ export const jss = (jsStyle: JSStyle): string => {
153
+ jsStyle = flattenJSStyle(jsStyle);
154
+
155
+ const stylesStack = Object.entries(jsStyle);
156
+ const classNames = [];
157
+
158
+ while (stylesStack.length) {
159
+ const [key, value] = stylesStack.pop();
160
+
161
+ if (aliases[key]) {
162
+ stylesStack.push(...aliases[key](value));
163
+ continue;
164
+ }
165
+
166
+ const rawHash = hash(key + JSON.stringify(value)).toString(32);
167
+ const cachedSelector = rawHashMap.get(rawHash);
168
+
169
+ if (cachedSelector != null) {
170
+ classNames.push(cachedSelector);
171
+ continue;
172
+ }
173
+
174
+ // const selector = numberToBase(rawHashMap.size);
175
+ const selector = `x${rawHash}`;
176
+ rawHashMap.set(rawHash, selector);
177
+ classNames.push(selector);
178
+
179
+ if (typeof value === "number" || typeof value === "string") {
180
+ const [cssProp, cssValue] = getCSS(key, value);
181
+ createStyleNode(`.${selector} { ${cssProp}: ${cssValue}; }`);
182
+ } else if (typeof value === "object" && key.startsWith("@media")) {
183
+ const media = key;
184
+ const cssValue = Object.entries(value)
185
+ .map(([key, value]) => {
186
+ const [cssProp, cssValue] = getCSS(key, value);
187
+ return `${cssProp}: ${cssValue}; `;
188
+ })
189
+ .join(" ");
190
+ createStyleNode(`${media} { .${selector} { ${cssValue} } }`);
191
+ } else if (typeof value === "object" && value != null) {
192
+ const cssValue = Object.entries(value)
193
+ .map(([key, value]) => {
194
+ const [cssProp, cssValue] = getCSS(key, value);
195
+ return `${cssProp}: ${cssValue}; `;
196
+ })
197
+ .join(" ");
198
+ createStyleNode(`.${selector}${key} { ${cssValue} }`);
199
+ }
200
+ }
201
+
202
+ return classNames.join(" ");
203
+ };
204
+
205
+ const serverStyles = [];
206
+
207
+ export function JSStylesProvider({
208
+ themes,
209
+ children,
210
+ }: {
211
+ themes: { dark: Theme; light: Theme };
212
+ children: JSX.Element;
213
+ }) {
214
+ const stylesRef = useRef<string[] | null>(null);
215
+
216
+ if (stylesRef.current == null) {
217
+ stylesRef.current = getBaseStyles(themes);
218
+ }
219
+
220
+ return (
221
+ <>
222
+ {stylesRef.current.map((style, i) => (
223
+ <style key={i} dangerouslySetInnerHTML={{ __html: style }} />
224
+ ))}
225
+ {children}
226
+ </>
227
+ );
228
+ }
229
+
230
+ export function JSServerStyles() {
231
+ const stylesRef = useRef<string[] | null>(null);
232
+
233
+ if (stylesRef.current == null) {
234
+ stylesRef.current = serverStyles;
235
+ }
236
+
237
+ return (
238
+ <>
239
+ {stylesRef.current.map((style, i) => (
240
+ <style key={i} dangerouslySetInnerHTML={{ __html: style }} />
241
+ ))}
242
+ </>
243
+ );
244
+ }
245
+
246
+ export type Size = "xsmall" | "small" | "medium" | "large" | "xlarge";
247
+
248
+ export type Spacing = "none" | Size;
249
+
250
+ export type Gap = Spacing;
251
+
252
+ export type Padding = Spacing | [Spacing, Spacing];
253
+
254
+ export type Margin = Spacing | [Spacing, Spacing];
255
+
256
+ export type Direction = "horizontal" | "vertical";
257
+
258
+ export type Position = "start" | "end";
259
+
260
+ export type Justify =
261
+ | "none"
262
+ | "center"
263
+ | "flex-start"
264
+ | "space-between"
265
+ | "flex-end"
266
+ | "stretch";
267
+
268
+ export type Align = "none" | "center" | "stretch" | "flex-start" | "flex-end";
269
+
270
+ export type FlexDirection = "row" | "column";
271
+
272
+ export type Color =
273
+ | "none"
274
+ | "negative"
275
+ | "warning"
276
+ | "highlight"
277
+ | "primary-background"
278
+ | "secondary-background"
279
+ | "divider"
280
+ | "inherit";
281
+
282
+ export type TextColor =
283
+ | "primary"
284
+ | "secondary"
285
+ | "highlight"
286
+ | "negative"
287
+ | "subtle"
288
+ | "light"
289
+ | "inherit";
290
+
291
+ export function cssVar(string: keyof Theme): string {
292
+ return `var(${string})`;
293
+ }
294
+
295
+ const sizes: { [size in Size]: string } = {
296
+ xsmall: cssVar("--spacing-xs"),
297
+ small: cssVar("--spacing-s"),
298
+ medium: cssVar("--spacing-m"),
299
+ large: cssVar("--spacing-l"),
300
+ xlarge: cssVar("--spacing-xl"),
301
+ };
302
+
303
+ export function getSize(size: Size): string {
304
+ return sizes[size];
305
+ }
306
+
307
+ export function getSpacing(spacing: Spacing): string {
308
+ if (spacing === "none") {
309
+ return "0px";
310
+ } else {
311
+ return getSize(spacing);
312
+ }
313
+ }
314
+
315
+ export function getPadding(padding: Padding): JSStyle {
316
+ if (Array.isArray(padding)) {
317
+ const [vertical, horizontal] = padding;
318
+ return {
319
+ paddingTop: getSpacing(vertical),
320
+ paddingBottom: getSpacing(vertical),
321
+ paddingLeft: getSpacing(horizontal),
322
+ paddingRight: getSpacing(horizontal),
323
+ };
324
+ } else {
325
+ return {
326
+ padding: getSpacing(padding),
327
+ };
328
+ }
329
+ }
330
+
331
+ export function getMargin(margin: Margin): JSStyle {
332
+ if (Array.isArray(margin)) {
333
+ const [vertical, horizontal] = margin;
334
+ return {
335
+ marginTop: getSpacing(vertical),
336
+ marginBottom: getSpacing(vertical),
337
+ marginLeft: getSpacing(horizontal),
338
+ marginRight: getSpacing(horizontal),
339
+ };
340
+ } else {
341
+ return {
342
+ margin: getSpacing(margin),
343
+ };
344
+ }
345
+ }
346
+
347
+ export type Theme = {
348
+ /* Background */
349
+ ["--overlay-background"]: string;
350
+ ["--primary-background"]: string;
351
+ ["--secondary-background"]: string;
352
+ ["--divider"]: string;
353
+ ["--strong-divider"]: string;
354
+ ["--pressed-background"]: string;
355
+ ["--hovered-background"]: string;
356
+ ["--selected-background"]: string;
357
+ ["--nav-bar"]: string;
358
+ /* Effects */
359
+ ["--warning"]: string;
360
+ ["--highlight"]: string;
361
+ ["--outline"]: string;
362
+ ["--light-highlight"]: string;
363
+ /* Text */
364
+ ["--primary-text"]: string;
365
+ ["--secondary-text"]: string;
366
+ ["--subtle-text"]: string;
367
+ ["--highlight-text"]: string;
368
+ ["--negative-text"]: string;
369
+ ["--light-text"]: string;
370
+ /* Buttons */
371
+ ["--background-button-positive"]: string;
372
+ ["--background-button-secondary"]: string;
373
+ ["--background-button-negative"]: string;
374
+ ["--background-button-disabled"]: string;
375
+ /* Spacing */
376
+ ["--spacing-xs"]: string;
377
+ ["--spacing-s"]: string;
378
+ ["--spacing-m"]: string;
379
+ ["--spacing-l"]: string;
380
+ ["--spacing-xl"]: string;
381
+ ["--spacing-xxl"]: string;
382
+ ["--spacing-xxxl"]: string;
383
+ ["--border-radius-s"]: string;
384
+ ["--border-radius-m"]: string;
385
+ ["--border-radius-l"]: string;
386
+ ["--nav-bar-height"]: string;
387
+ };
388
+
389
+ export const lightTheme: Theme = {
390
+ /* Background */
391
+ ["--overlay-background"]: "rgb(245, 246, 250)",
392
+ ["--primary-background"]: "rgb(239, 239, 244)",
393
+ ["--secondary-background"]: "rgb(232, 232, 234)",
394
+ ["--divider"]: "rgb(200, 200, 200)",
395
+ ["--strong-divider"]: "rgb(100, 100, 100)",
396
+ ["--pressed-background"]: "rgb(220, 222, 224)",
397
+ ["--hovered-background"]: "rgb(232, 235, 237)",
398
+ ["--selected-background"]: "rgb(227, 230, 232)",
399
+ ["--nav-bar"]: "rgb(232, 232, 234)",
400
+ /* Effects */
401
+ ["--warning"]: "rgb(255, 204, 0)",
402
+ ["--highlight"]: "rgb(0, 122, 255)",
403
+ ["--outline"]: "rgb(103, 176, 255)",
404
+ ["--light-highlight"]: "rgb(220, 232, 245)",
405
+ /* Text */
406
+ ["--primary-text"]: "rgb(0, 0, 0)",
407
+ ["--secondary-text"]: "rgb(100, 100, 100)",
408
+ ["--subtle-text"]: "rgb(180, 180, 180)",
409
+ ["--highlight-text"]: "rgb(0, 122, 255)",
410
+ ["--negative-text"]: "rgb(255, 59, 48)",
411
+ ["--light-text"]: "rgb(255, 255, 255)",
412
+ /* Buttons */
413
+ ["--background-button-positive"]: "rgb(0, 122, 255)",
414
+ ["--background-button-secondary"]: "rgb(218, 218, 223)",
415
+ ["--background-button-negative"]: "rgb(255, 59, 48)",
416
+ ["--background-button-disabled"]: "rgb(218, 218, 223)",
417
+ /* Spacing */
418
+ ["--spacing-xs"]: "2px",
419
+ ["--spacing-s"]: "4px",
420
+ ["--spacing-m"]: "8px",
421
+ ["--spacing-l"]: "12px",
422
+ ["--spacing-xl"]: "16px",
423
+ ["--spacing-xxl"]: "24px",
424
+ ["--spacing-xxxl"]: "32px",
425
+ ["--border-radius-s"]: "2px",
426
+ ["--border-radius-m"]: "4px",
427
+ ["--border-radius-l"]: "8px",
428
+ ["--nav-bar-height"]: "50px",
429
+ };
430
+
431
+ export const darkTheme: Theme = {
432
+ /* Background */
433
+ ["--overlay-background"]: "rgb(22, 23, 24)",
434
+ ["--primary-background"]: "rgb(42, 43, 46)",
435
+ ["--secondary-background"]: "rgb(65, 66, 67)",
436
+ ["--divider"]: "rgb(70, 72, 73)",
437
+ ["--strong-divider"]: "rgb(100, 100, 100)",
438
+ ["--pressed-background"]: "rgb(90, 92, 93)",
439
+ ["--hovered-background"]: "rgb(50, 53, 54)",
440
+ ["--selected-background"]: "rgb(65, 68, 69)",
441
+ ["--nav-bar"]: "rgb(34, 35, 36)",
442
+ /* Effects */
443
+ ["--warning"]: "rgb(255, 204, 0)",
444
+ ["--highlight"]: "rgb(50, 140, 220)",
445
+ ["--outline"]: "rgb(91, 170, 255)",
446
+ ["--light-highlight"]: "rgba(49, 57, 63)",
447
+ /* Text */
448
+ ["--primary-text"]: "rgb(255, 255, 255)",
449
+ ["--secondary-text"]: "rgb(200, 200, 200)",
450
+ ["--subtle-text"]: "rgb(140, 140, 140)",
451
+ ["--highlight-text"]: "#4ca7f8",
452
+ ["--negative-text"]: "rgb(255, 59, 48)",
453
+ ["--light-text"]: "rgb(255, 255, 255)",
454
+ /* Buttons */
455
+ ["--background-button-positive"]: "rgb(50, 140, 220)",
456
+ ["--background-button-secondary"]: "rgb(82, 83, 86)",
457
+ ["--background-button-negative"]: "rgb(255, 59, 48)",
458
+ ["--background-button-disabled"]: "rgb(70, 72, 73)",
459
+ /* Spacing */
460
+ ["--spacing-xs"]: "2px",
461
+ ["--spacing-s"]: "4px",
462
+ ["--spacing-m"]: "8px",
463
+ ["--spacing-l"]: "12px",
464
+ ["--spacing-xl"]: "16px",
465
+ ["--spacing-xxl"]: "24px",
466
+ ["--spacing-xxxl"]: "32px",
467
+ ["--border-radius-s"]: "2px",
468
+ ["--border-radius-m"]: "4px",
469
+ ["--border-radius-l"]: "8px",
470
+ ["--nav-bar-height"]: "50px",
471
+ };
472
+
473
+ export const baseStyles = `
474
+ * {
475
+ box-sizing: border-box;
476
+ border: none;
477
+ touch-action: manipulation;
478
+ font-family: sans-serif;
479
+ -webkit-font-smoothing: antialiased;
480
+ -moz-osx-font-smoothing: grayscale;
481
+ }
482
+
483
+ *:focus {
484
+ outline-color: ${cssVar("--highlight")};
485
+ }
486
+
487
+ html,
488
+ body {
489
+ margin: 0;
490
+ height: 100%;
491
+ width: 100%;
492
+ overflow: hidden;
493
+ background-color: ${cssVar("--primary-background")};
494
+ }
495
+
496
+ `;
497
+
498
+ const backgroundStyles = {
499
+ highlight: {
500
+ backgroundColor: cssVar("--highlight"),
501
+ },
502
+ warning: {
503
+ backgroundColor: cssVar("--warning"),
504
+ },
505
+ "primary-background": {
506
+ backgroundColor: cssVar("--primary-background"),
507
+ },
508
+ negative: {
509
+ backgroundColor: cssVar("--negative-text"),
510
+ },
511
+ "secondary-background": {
512
+ backgroundColor: cssVar("--secondary-background"),
513
+ },
514
+ divider: {
515
+ backgroundColor: cssVar("--divider"),
516
+ },
517
+ inherit: {
518
+ backgroundColor: "inherit",
519
+ },
520
+ };
521
+
522
+ export const getBackground = (color: Color): JSStyle => {
523
+ return backgroundStyles[color];
524
+ };
525
+
526
+ export const MOBILE = 750;
527
+ export const TABLET = 1000;
528
+ export const LAPTOP = 1200;
529
+
530
+ export const MOBILE_MEDIA = `@media (min-width: 0px) and (max-width: ${MOBILE}px)`;
531
+ export const TABLET_MEDIA = `@media (min-width: ${MOBILE}px) and (max-width: ${TABLET}px)`;
532
+ export const LAPTOP_MEDIA = `@media (min-width: ${TABLET}px) and (max-width: ${LAPTOP}px)`;
533
+ export const DESKTOP_MEDIA = `@media (min-width: ${LAPTOP}px)`;
534
+
535
+ export function mobile(jsStyle: JSStyle): { [key: string]: JSStyle } {
536
+ return {
537
+ [MOBILE_MEDIA]: jsStyle,
538
+ };
539
+ }
540
+
541
+ export function tablet(jsStyle: JSStyle): { [key: string]: JSStyle } {
542
+ return {
543
+ [TABLET_MEDIA]: jsStyle,
544
+ };
545
+ }
546
+
547
+ export function laptop(jsStyle: JSStyle): { [key: string]: JSStyle } {
548
+ return {
549
+ [LAPTOP_MEDIA]: jsStyle,
550
+ };
551
+ }
552
+
553
+ export function desktop(jsStyle: JSStyle): { [key: string]: JSStyle } {
554
+ return {
555
+ [DESKTOP_MEDIA]: jsStyle,
556
+ };
557
+ }
558
+
559
+ const textColorStyles = {
560
+ primary: {
561
+ color: cssVar("--primary-text"),
562
+ },
563
+ secondary: {
564
+ color: cssVar("--secondary-text"),
565
+ },
566
+ highlight: {
567
+ color: cssVar("--highlight-text"),
568
+ },
569
+ negative: {
570
+ color: cssVar("--negative-text"),
571
+ },
572
+ subtle: {
573
+ color: cssVar("--subtle-text"),
574
+ },
575
+ light: {
576
+ color: cssVar("--light-text"),
577
+ },
578
+ inherit: {
579
+ color: "inherit",
580
+ },
581
+ };
582
+
583
+ export const getTextColor = (color: TextColor) => {
584
+ return textColorStyles[color];
585
+ };
586
+
587
+ export function getBaseStyles(themes: { light: Theme; dark: Theme }): string[] {
588
+ const css: string[] = [];
589
+
590
+ css.push(baseStyles);
591
+
592
+ css.push(`body {
593
+ color-scheme: light;
594
+ ${Object.entries(themes.light)
595
+ .map(([key, value]) => `${key}: ${value};`)
596
+ .join("\n ")}
597
+ }`);
598
+
599
+ css.push(`body.dark-mode {
600
+ color-scheme: dark;
601
+ ${Object.entries(themes.dark)
602
+ .map(([key, value]) => `${key}: ${value};`)
603
+ .join("\n ")}
604
+ }`);
605
+
606
+ return css;
607
+ }
@@ -0,0 +1,52 @@
1
+ const LETTERS_26 = [
2
+ "a",
3
+ "b",
4
+ "c",
5
+ "d",
6
+ "e",
7
+ "f",
8
+ "g",
9
+ "h",
10
+ "i",
11
+ "j",
12
+ "k",
13
+ "l",
14
+ "m",
15
+ "n",
16
+ "o",
17
+ "p",
18
+ "q",
19
+ "r",
20
+ "s",
21
+ "t",
22
+ "u",
23
+ "v",
24
+ "w",
25
+ "x",
26
+ "y",
27
+ "z",
28
+ ];
29
+
30
+ export function numberToBase(
31
+ number: number,
32
+ base: Array<string> = LETTERS_26
33
+ ): string {
34
+ if (number <= -1) {
35
+ return "";
36
+ }
37
+
38
+ let result = [];
39
+
40
+ // To make numbers 1 indexed
41
+ number += 1;
42
+
43
+ while (number >= base.length) {
44
+ const index = number % base.length;
45
+ number = Math.floor(number / base.length) - 1;
46
+ result.push(base[index]);
47
+ }
48
+
49
+ result.push(base[number]);
50
+
51
+ return result.reverse().join("");
52
+ }
@@ -0,0 +1,30 @@
1
+ import { Badge } from "../Badge";
2
+ import { Row } from "../Row";
3
+
4
+ # Badge
5
+
6
+ This component is used to bring attention to some other element (e.g. an unread notification, an update, an important element...).
7
+
8
+ ---
9
+
10
+ The `Badge` component supports all colours and sizes
11
+
12
+ <Row gap="large" align="center" justify="center">
13
+ <Badge size="xsmall" color="negative" />
14
+ <Badge size="small" color="warning" />
15
+ <Badge size="medium" color="highlight" />
16
+ <Badge size="large" color="secondary-background" />
17
+ <Badge size="xlarge" color="divider" />
18
+ </Row>
19
+
20
+ ```js
21
+ <Row gap="large" align="center" justify="center">
22
+ <Badge size="xsmall" color="negative" />
23
+ <Badge size="small" color="warning" />
24
+ <Badge size="medium" color="highlight" />
25
+ <Badge size="large" color="secondary-background" />
26
+ <Badge size="xlarge" color="divider" />
27
+ </Row>
28
+ ```
29
+
30
+ ---