@sats-group/ui-lib 74.2.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 (227) hide show
  1. package/.nvmrc +1 -0
  2. package/README.md +35 -0
  3. package/catalog-info.yaml +14 -0
  4. package/eslint.config.mjs +94 -0
  5. package/fonts/Inter-BoldItalic.woff +0 -0
  6. package/fonts/Inter-BoldItalic.woff2 +0 -0
  7. package/fonts/Inter-ExtraBold.woff +0 -0
  8. package/fonts/Inter-ExtraBold.woff2 +0 -0
  9. package/fonts/Inter-Italic.woff +0 -0
  10. package/fonts/Inter-Italic.woff2 +0 -0
  11. package/fonts/Inter-Regular.woff +0 -0
  12. package/fonts/Inter-Regular.woff2 +0 -0
  13. package/fonts/Inter-SemiBold.woff +0 -0
  14. package/fonts/Inter-SemiBold.woff2 +0 -0
  15. package/fonts/LICENSE.txt +92 -0
  16. package/fonts/SATSHeadline-Bold.woff +0 -0
  17. package/fonts/SATSHeadline-BoldItalic.woff +0 -0
  18. package/fonts/SATSHeadline-RegularItalic.woff +0 -0
  19. package/fonts/SATSHeadline-SemiBoldItalic.woff +0 -0
  20. package/logos/e-avatar.svg +3 -0
  21. package/logos/elixia-letter.svg +3 -0
  22. package/logos/elixia-small.svg +8 -0
  23. package/logos/elixia.svg +8 -0
  24. package/logos/s-avatar.svg +3 -0
  25. package/logos/sats-letter.svg +3 -0
  26. package/logos/sats-small.svg +3 -0
  27. package/logos/sats.svg +4 -0
  28. package/package.json +58 -0
  29. package/react/add-bem-modifiers.ts +51 -0
  30. package/react/badge/badge.scss +53 -0
  31. package/react/badge/badge.tsx +28 -0
  32. package/react/badge/badge.types.ts +34 -0
  33. package/react/badge/index.ts +2 -0
  34. package/react/banner/banner.scss +118 -0
  35. package/react/banner/banner.tsx +92 -0
  36. package/react/banner/banner.types.ts +10 -0
  37. package/react/banner/index.ts +2 -0
  38. package/react/bomb/bomb.scss +33 -0
  39. package/react/bomb/bomb.tsx +19 -0
  40. package/react/bomb/bomb.types.ts +1 -0
  41. package/react/bomb/index.ts +2 -0
  42. package/react/button/button.tsx +19 -0
  43. package/react/button/button.types.ts +3 -0
  44. package/react/button/index.ts +2 -0
  45. package/react/checkbox/checkbox.scss +218 -0
  46. package/react/checkbox/checkbox.tsx +176 -0
  47. package/react/checkbox/checkbox.types.ts +19 -0
  48. package/react/checkbox/index.ts +2 -0
  49. package/react/chip/chip.scss +46 -0
  50. package/react/chip/chip.tsx +37 -0
  51. package/react/chip/chip.types.ts +18 -0
  52. package/react/chip/index.ts +2 -0
  53. package/react/chip/remove.tsx +14 -0
  54. package/react/chip-selected/chip-selected.scss +47 -0
  55. package/react/chip-selected/chip-selected.tsx +102 -0
  56. package/react/chip-selected/chip-selected.types.ts +11 -0
  57. package/react/chip-selected/index.ts +2 -0
  58. package/react/confirmation/confirmation.scss +60 -0
  59. package/react/confirmation/confirmation.tsx +85 -0
  60. package/react/confirmation/confirmation.types.ts +24 -0
  61. package/react/confirmation/index.ts +2 -0
  62. package/react/context-menu/context-menu.scss +183 -0
  63. package/react/context-menu/context-menu.tsx +200 -0
  64. package/react/context-menu/context-menu.types.ts +71 -0
  65. package/react/context-menu/index.ts +2 -0
  66. package/react/cropped-image/cropped-image.scss +48 -0
  67. package/react/cropped-image/cropped-image.tsx +36 -0
  68. package/react/cropped-image/cropped-image.types.ts +26 -0
  69. package/react/cropped-image/index.ts +2 -0
  70. package/react/dropdown-list/dropdown-list.scss +170 -0
  71. package/react/dropdown-list/dropdown-list.tsx +116 -0
  72. package/react/dropdown-list/dropdown-list.types.ts +17 -0
  73. package/react/dropdown-list/index.ts +2 -0
  74. package/react/expander/expander.scss +115 -0
  75. package/react/expander/expander.tsx +167 -0
  76. package/react/expander/expander.types.ts +26 -0
  77. package/react/expander/index.ts +2 -0
  78. package/react/filter/filter.scss +94 -0
  79. package/react/filter/filter.tsx +99 -0
  80. package/react/filter/filter.types.ts +8 -0
  81. package/react/filter/index.ts +2 -0
  82. package/react/filter-wrapper/filter-wrapper.scss +46 -0
  83. package/react/filter-wrapper/filter-wrapper.tsx +24 -0
  84. package/react/filter-wrapper/filter-wrapper.types.ts +10 -0
  85. package/react/filter-wrapper/index.ts +2 -0
  86. package/react/flag/flag.scss +26 -0
  87. package/react/flag/flag.tsx +27 -0
  88. package/react/flag/flag.types.ts +17 -0
  89. package/react/flag/index.ts +2 -0
  90. package/react/form-content/checkbox-category.tsx +183 -0
  91. package/react/form-content/form-content.checkbox-list.tsx +126 -0
  92. package/react/form-content/form-content.checkbox-list.types.ts +36 -0
  93. package/react/form-content/form-content.radio-list.tsx +58 -0
  94. package/react/form-content/form-content.range.tsx +20 -0
  95. package/react/form-content/form-content.range.types.ts +14 -0
  96. package/react/form-content/form-content.scss +234 -0
  97. package/react/form-content/form-content.search.tsx +47 -0
  98. package/react/form-content/form-content.tsx +95 -0
  99. package/react/form-content/form-content.types.ts +55 -0
  100. package/react/form-content/index.ts +2 -0
  101. package/react/form-content/types/index.d.ts +1 -0
  102. package/react/hidden-input/hidden-input.tsx +9 -0
  103. package/react/hidden-input/hidden-input.types.ts +6 -0
  104. package/react/hidden-input/index.ts +2 -0
  105. package/react/hooks/focus-previous-element.ts +30 -0
  106. package/react/hooks/is-running-on-client.ts +1 -0
  107. package/react/hooks/use-click-outside.ts +23 -0
  108. package/react/hooks/use-escape.ts +18 -0
  109. package/react/hooks/use-event.ts +29 -0
  110. package/react/hooks/use-is-mounted.ts +11 -0
  111. package/react/hooks/use-toggle.ts +19 -0
  112. package/react/icons/16/close.tsx +12 -0
  113. package/react/icons/18/close.tsx +18 -0
  114. package/react/icons/24/arrow-down.tsx +14 -0
  115. package/react/icons/24/arrow-right.tsx +14 -0
  116. package/react/icons/24/arrow-up.tsx +14 -0
  117. package/react/icons/24/close.tsx +12 -0
  118. package/react/icons/24/remove.tsx +12 -0
  119. package/react/icons/24/search.tsx +10 -0
  120. package/react/icons/icons.md +3 -0
  121. package/react/indexed-access-type.ts +1 -0
  122. package/react/link/index.ts +2 -0
  123. package/react/link/link.scss +44 -0
  124. package/react/link/link.tsx +62 -0
  125. package/react/link/link.types.ts +37 -0
  126. package/react/link-button/index.ts +2 -0
  127. package/react/link-button/link-button.tsx +17 -0
  128. package/react/link-button/link-button.types.ts +5 -0
  129. package/react/link-card/index.ts +2 -0
  130. package/react/link-card/link-card.scss +37 -0
  131. package/react/link-card/link-card.tsx +24 -0
  132. package/react/link-card/link-card.types.ts +5 -0
  133. package/react/logos/e-avatar.tsx +12 -0
  134. package/react/logos/elixia-letter.tsx +12 -0
  135. package/react/logos/elixia-small.tsx +12 -0
  136. package/react/logos/elixia.tsx +12 -0
  137. package/react/logos/index.ts +8 -0
  138. package/react/logos/s-avatar.tsx +12 -0
  139. package/react/logos/sats-letter.tsx +12 -0
  140. package/react/logos/sats-small.tsx +12 -0
  141. package/react/logos/sats.tsx +12 -0
  142. package/react/message/hook/use-message.ts +22 -0
  143. package/react/message/index.ts +2 -0
  144. package/react/message/message.scss +92 -0
  145. package/react/message/message.tsx +60 -0
  146. package/react/message/message.types.ts +39 -0
  147. package/react/message/publish.ts +19 -0
  148. package/react/message-field/index.ts +2 -0
  149. package/react/message-field/message-field.scss +21 -0
  150. package/react/message-field/message-field.tsx +70 -0
  151. package/react/message-field/message-field.types.ts +24 -0
  152. package/react/modal/index.ts +2 -0
  153. package/react/modal/modal.scss +162 -0
  154. package/react/modal/modal.tsx +130 -0
  155. package/react/modal/modal.types.ts +36 -0
  156. package/react/modal/tab-trapper.tsx +68 -0
  157. package/react/progress-bar/index.ts +2 -0
  158. package/react/progress-bar/progress-bar.scss +71 -0
  159. package/react/progress-bar/progress-bar.tsx +81 -0
  160. package/react/progress-bar/progress-bar.types.ts +35 -0
  161. package/react/radio/index.ts +2 -0
  162. package/react/radio/radio.scss +142 -0
  163. package/react/radio/radio.tsx +87 -0
  164. package/react/radio/radio.types.ts +15 -0
  165. package/react/scale-bar/index.ts +2 -0
  166. package/react/scale-bar/scale-bar.scss +22 -0
  167. package/react/scale-bar/scale-bar.tsx +29 -0
  168. package/react/scale-bar/scale-bar.types.ts +4 -0
  169. package/react/search/index.ts +2 -0
  170. package/react/search/search.scss +207 -0
  171. package/react/search/search.tsx +255 -0
  172. package/react/search/search.types.ts +43 -0
  173. package/react/select/chevron-down.tsx +24 -0
  174. package/react/select/index.ts +2 -0
  175. package/react/select/select.scss +135 -0
  176. package/react/select/select.tsx +105 -0
  177. package/react/select/select.types.ts +19 -0
  178. package/react/select-option/README.md +3 -0
  179. package/react/select-option/index.ts +2 -0
  180. package/react/select-option/select-option.tsx +16 -0
  181. package/react/select-option/select-option.types.ts +8 -0
  182. package/react/tag/index.ts +2 -0
  183. package/react/tag/tag.scss +107 -0
  184. package/react/tag/tag.tsx +26 -0
  185. package/react/tag/tag.types.ts +30 -0
  186. package/react/text/index.ts +2 -0
  187. package/react/text/text.scss +109 -0
  188. package/react/text/text.tsx +40 -0
  189. package/react/text/text.types.ts +29 -0
  190. package/react/text-area/index.ts +2 -0
  191. package/react/text-area/text-area.scss +180 -0
  192. package/react/text-area/text-area.tsx +153 -0
  193. package/react/text-area/text-area.types.ts +24 -0
  194. package/react/text-input/index.ts +2 -0
  195. package/react/text-input/text-input.scss +233 -0
  196. package/react/text-input/text-input.tsx +106 -0
  197. package/react/text-input/text-input.types.ts +19 -0
  198. package/react/toggle/index.ts +2 -0
  199. package/react/toggle/toggle.scss +69 -0
  200. package/react/toggle/toggle.tsx +83 -0
  201. package/react/toggle/toggle.types.ts +11 -0
  202. package/react/toolbox/index.ts +2 -0
  203. package/react/toolbox/toolbox.scss +68 -0
  204. package/react/toolbox/toolbox.tsx +43 -0
  205. package/react/toolbox/toolbox.types.ts +39 -0
  206. package/react/ts/debounce.ts +12 -0
  207. package/react/types.ts +38 -0
  208. package/react/use-input-validation.ts +47 -0
  209. package/react/use-input-validation.types.ts +12 -0
  210. package/react/visually-button/index.ts +2 -0
  211. package/react/visually-button/visually-button.scss +470 -0
  212. package/react/visually-button/visually-button.tsx +130 -0
  213. package/react/visually-button/visually-button.types.ts +71 -0
  214. package/react/visually-hidden/index.ts +2 -0
  215. package/react/visually-hidden/visually-hidden.scss +6 -0
  216. package/react/visually-hidden/visually-hidden.tsx +10 -0
  217. package/tokens/corner-radius.scss +5 -0
  218. package/tokens/dark.scss +392 -0
  219. package/tokens/darkmode.scss +131 -0
  220. package/tokens/elevation.scss +57 -0
  221. package/tokens/font-faces.scss +62 -0
  222. package/tokens/font-names.scss +2 -0
  223. package/tokens/font-sizes.scss +95 -0
  224. package/tokens/light.scss +392 -0
  225. package/tokens/lightmode.scss +131 -0
  226. package/tokens/primitives.scss +137 -0
  227. package/tokens/spacing.scss +12 -0
@@ -0,0 +1,2 @@
1
+ import LinkCard from './link-card';
2
+ export default LinkCard;
@@ -0,0 +1,37 @@
1
+ @use '../../tokens/corner-radius';
2
+ @use '../../tokens/elevation';
3
+ @use '../../tokens/light';
4
+ @use '../../tokens/spacing';
5
+
6
+ .link-card {
7
+ @include elevation.level(2);
8
+
9
+ background: light.$surface-primary-default;
10
+ border-radius: corner-radius.$s;
11
+ color: light.$on-surface-primary-default;
12
+ display: grid;
13
+ gap: spacing.$s;
14
+ grid-template-columns: [first] [second];
15
+ padding: spacing.$m;
16
+ text-decoration: none;
17
+
18
+ @media (hover: hover) {
19
+ &:hover {
20
+ background: light.$surface-primary-hover;
21
+ }
22
+ }
23
+
24
+ &__title {
25
+ color: light.$on-surface-primary-default;
26
+ grid-column: 1;
27
+ }
28
+
29
+ &__icon {
30
+ grid-column: 2;
31
+ justify-self: end;
32
+ }
33
+
34
+ &__text {
35
+ grid-column: span 2;
36
+ }
37
+ }
@@ -0,0 +1,24 @@
1
+ import * as React from 'react';
2
+
3
+ import ArrowRight from '../icons/24/arrow-right';
4
+ import Text from '../text';
5
+
6
+ import { LinkCard as Props } from './link-card.types';
7
+
8
+ const LinkCard: React.FC<Props> = ({ href, text, title }) => (
9
+ <a className="link-card" href={href}>
10
+ <Text className="link-card__title" size={Text.sizes.basic}>
11
+ {title}
12
+ </Text>
13
+ <div className="link-card__icon">
14
+ <ArrowRight />
15
+ </div>
16
+ {text ? (
17
+ <div className="link-card__text">
18
+ <Text size={Text.sizes.small}>{text}</Text>
19
+ </div>
20
+ ) : null}
21
+ </a>
22
+ );
23
+
24
+ export default LinkCard;
@@ -0,0 +1,5 @@
1
+ export type LinkCard = {
2
+ href: string;
3
+ text?: string;
4
+ title: string;
5
+ };
@@ -0,0 +1,12 @@
1
+ import * as React from 'react';
2
+ const SvgEAvatar = () => (
3
+ <svg
4
+ xmlns="http://www.w3.org/2000/svg"
5
+ width={73}
6
+ height={72}
7
+ fill="currentColor"
8
+ >
9
+ <path d="m38.287 24.48-2.02 6.902h12.798l-2.41 8.446h-12.8l-2.233 7.726h17.16L46.3 56H19l11.63-40H58l-2.482 8.446h-17.23z" />
10
+ </svg>
11
+ );
12
+ export default SvgEAvatar;
@@ -0,0 +1,12 @@
1
+ import * as React from 'react';
2
+ const SvgElixiaLetter = () => (
3
+ <svg
4
+ xmlns="http://www.w3.org/2000/svg"
5
+ width={48}
6
+ height={51}
7
+ fill="currentColor"
8
+ >
9
+ <path d="m23.738 10.778-2.487 8.771h15.753l-2.968 10.735H18.284l-2.75 9.818h21.12L33.6 50.836H0L14.313 0H48l-3.054 10.735H23.738z" />
10
+ </svg>
11
+ );
12
+ export default SvgElixiaLetter;
@@ -0,0 +1,12 @@
1
+ import * as React from 'react';
2
+ const SvgElixiaSmall = () => (
3
+ <svg
4
+ xmlns="http://www.w3.org/2000/svg"
5
+ width={93}
6
+ height={21}
7
+ fill="currentColor"
8
+ >
9
+ <path d="M9.94 4.28 8.902 7.803h6.483l-1.21 4.363h-6.57L6.483 16.11h8.816l-1.296 4.363H0L5.964 0h14.002l-1.297 4.363H9.94zM32.585 16.195l-1.297 4.363H17.805L23.769.084h5.186l-4.668 16.195h8.298zM40.536 0h5.186l-5.964 20.474h-5.186zM58.514 10.489l3.544 9.985h-5.273l-2.16-6.461-5.618 6.461h-5.964l9.594-10.657L49.093 0h5.272l2.161 6.293L61.971 0h5.964zM71.047 0h5.185L70.27 20.474h-5.186zM93 0v20.474h-4.58v-4.28h-7.002l-2.42 4.28h-5.532L86 0zm-4.58 11.831V3.86l-4.582 7.971z" />
10
+ </svg>
11
+ );
12
+ export default SvgElixiaSmall;
@@ -0,0 +1,12 @@
1
+ import * as React from 'react';
2
+ const SvgElixia = () => (
3
+ <svg
4
+ xmlns="http://www.w3.org/2000/svg"
5
+ width={229}
6
+ height={52}
7
+ fill="currentColor"
8
+ >
9
+ <path d="m24.408 10.825-2.547 8.914H37.78l-2.972 11.037h-16.13l-2.76 9.975h21.65l-3.184 11.037H0L14.645 0h34.384l-3.184 11.037H24.408zM80.016 40.963 76.833 52h-33.11L58.366.212h12.735L59.641 41.175h20.375zM99.543 0h12.735L97.633 51.788H84.898zM143.69 26.53l8.702 25.258h-12.947l-5.306-16.343-13.796 16.343h-14.645l23.559-26.955L120.555 0h12.947l5.306 15.918L152.18 0h14.645zM174.465 0H187.2l-14.645 51.788H159.82zM228.376 0v51.788h-11.249V40.963h-17.192l-5.943 10.825h-13.584L211.184 0zm-11.249 29.927V9.763l-11.249 20.164z" />
10
+ </svg>
11
+ );
12
+ export default SvgElixia;
@@ -0,0 +1,8 @@
1
+ export { default as EAvatar } from './e-avatar';
2
+ export { default as ElixiaLetter } from './elixia-letter';
3
+ export { default as ElixiaSmall } from './elixia-small';
4
+ export { default as Elixia } from './elixia';
5
+ export { default as SAvatar } from './s-avatar';
6
+ export { default as SatsLetter } from './sats-letter';
7
+ export { default as SatsSmall } from './sats-small';
8
+ export { default as Sats } from './sats';
@@ -0,0 +1,12 @@
1
+ import * as React from 'react';
2
+ const SvgSAvatar = () => (
3
+ <svg
4
+ xmlns="http://www.w3.org/2000/svg"
5
+ width={73}
6
+ height={72}
7
+ fill="currentColor"
8
+ >
9
+ <path d="m42.754 33.822-2.574-2.244c-1.545-1.32-2.414-2.41-2.414-3.895 0-1.881 1.352-3.564 4.216-3.564 1.93 0 3.732.693 5.373 2.31l7.112-5.445C52.568 18.441 48.707 16 43.01 16 34.613 16 28.5 21.61 28.5 29.003c0 3.73 1.995 6.304 4.601 8.581l2.575 2.244c1.77 1.584 2.51 2.575 2.51 3.96 0 2.08-1.448 4.06-5.085 4.06-2.703 0-5.116-1.089-6.918-3.168l-7.047 5.412C21.774 53.426 26.28 56 32.457 56c9.493 0 14.995-5.875 14.995-13.63.032-3.928-2.22-6.403-4.698-8.548" />
10
+ </svg>
11
+ );
12
+ export default SvgSAvatar;
@@ -0,0 +1,12 @@
1
+ import * as React from 'react';
2
+ const SvgSatsLetter = () => (
3
+ <svg
4
+ xmlns="http://www.w3.org/2000/svg"
5
+ width={48}
6
+ height={52}
7
+ fill="currentColor"
8
+ >
9
+ <path d="m31.992 23.168-3.433-2.917c-2.059-1.716-3.217-3.132-3.217-5.063 0-2.445 1.802-4.633 5.62-4.633 2.574 0 4.977.9 7.165 3.003l9.482-7.08C45.078 3.176 39.929 0 32.335 0c-11.198 0-19.35 7.294-19.35 16.904 0 4.849 2.66 8.195 6.136 11.155l3.432 2.918c2.36 2.06 3.346 3.346 3.346 5.148 0 2.703-1.93 5.278-6.779 5.278-3.604 0-6.821-1.416-9.224-4.12L.5 44.32C4.018 48.654 10.025 52 18.262 52c12.657 0 19.994-7.637 19.994-17.72.043-5.105-2.96-8.323-6.264-11.112" />
10
+ </svg>
11
+ );
12
+ export default SvgSatsLetter;
@@ -0,0 +1,12 @@
1
+ import * as React from 'react';
2
+ const SvgSatsSmall = () => (
3
+ <svg
4
+ xmlns="http://www.w3.org/2000/svg"
5
+ width={79}
6
+ height={25}
7
+ fill="currentColor"
8
+ >
9
+ <path d="m4.514 17.404-4.232 3.27c1.599 2.307 4.42 4.038 8.37 4.038 5.831 0 9.217-3.558 9.217-8.27 0-2.403-1.41-3.846-2.915-5.192l-1.505-1.442c-.94-.866-1.41-1.539-1.41-2.404 0-1.154.752-2.212 2.538-2.212 1.223 0 2.446.481 3.574 1.731l4.232-3.27C21.35 2.02 18.903.289 15.142.289c-5.079 0-8.84 3.462-8.84 7.981 0 2.212 1.222 3.75 2.82 5.192l1.505 1.443c1.035.961 1.505 1.538 1.505 2.404 0 1.154-.846 2.404-3.103 2.404-1.787 0-3.386-.866-4.515-2.308m56.24 0-4.231 3.27c1.504 2.307 4.42 4.038 8.37 4.038 5.83 0 9.216-3.558 9.216-8.27 0-2.403-1.41-3.846-2.915-5.192l-1.505-1.442c-.94-.866-1.41-1.539-1.41-2.404 0-1.154.752-2.212 2.539-2.212 1.222 0 2.445.481 3.574 1.731l4.232-3.27C77.589 2.02 75.144.289 71.382.289c-5.078 0-8.84 3.462-8.84 7.981 0 2.212 1.222 3.75 2.821 5.192l1.505 1.443c1.034.961 1.505 1.538 1.505 2.404 0 1.154-.847 2.404-3.104 2.404-1.787 0-3.386-.866-4.514-2.308m-.752-11.73h-5.454l-5.079 18.46h-5.643l5.079-18.46h-5.831l1.41-5h17.023zM39.312 24.23V.769h-7.806L17.963 24.231h6.02l2.633-4.904h7.711v4.904zM34.327 5.288v9.039h-4.984z" />
10
+ </svg>
11
+ );
12
+ export default SvgSatsSmall;
@@ -0,0 +1,12 @@
1
+ import * as React from 'react';
2
+ const SvgSats = () => (
3
+ <svg
4
+ xmlns="http://www.w3.org/2000/svg"
5
+ width={168}
6
+ height={52}
7
+ fill="currentColor"
8
+ >
9
+ <path d="M9.6 36.2.6 43c3.4 4.8 9.4 8.4 17.8 8.4C30.8 51.4 38 44 38 34.2c0-5-3-8-6.2-10.8l-3.2-3c-2-1.8-3-3.2-3-5 0-2.4 1.6-4.6 5.4-4.6 2.6 0 5.2 1 7.6 3.6l9-6.8c-2.2-3.4-7.4-7-15.4-7-10.8 0-18.8 7.2-18.8 16.6 0 4.6 2.6 7.8 6 10.8l3.2 3c2.2 2 3.2 3.2 3.2 5 0 2.4-1.8 5-6.6 5-3.8 0-7.2-1.8-9.6-4.8m119.6 0-9 6.8c3.2 4.8 9.4 8.4 17.8 8.4 12.4 0 19.6-7.4 19.6-17.2 0-5-3-8-6.2-10.8l-3.2-3c-2-1.8-3-3.2-3-5 0-2.4 1.6-4.6 5.4-4.6 2.6 0 5.2 1 7.6 3.6l9-6.8c-2.2-3.4-7.4-7-15.4-7C141 .6 133 7.8 133 17.2c0 4.6 2.6 7.8 6 10.8l3.2 3c2.2 2 3.2 3.2 3.2 5 0 2.4-1.8 5-6.6 5-3.8 0-7.2-1.8-9.6-4.8m-1.6-24.4H116l-10.8 38.4h-12L104 11.8H91.6l3-10.4h36.2zm-44 38.6V1.6H67L38.2 50.4H51l5.6-10.2H73v10.2zM73 11v18.8H62.4z" />
10
+ </svg>
11
+ );
12
+ export default SvgSats;
@@ -0,0 +1,22 @@
1
+ import { useEffect, useState } from 'react';
2
+
3
+ import type { MessageDetail } from '../message.types';
4
+ import { subscribe } from '../publish';
5
+
6
+ export const useMessage = (
7
+ initialMessage?: MessageDetail,
8
+ ): [message: MessageDetail | undefined, clearMessage: () => void] => {
9
+ const [message, setMessage] = useState(initialMessage);
10
+
11
+ const clearMessage = () => setMessage(undefined);
12
+
13
+ const onMessage = (message: MessageDetail) => {
14
+ setMessage(message);
15
+ };
16
+
17
+ useEffect(() => subscribe(onMessage), []);
18
+
19
+ return [message, clearMessage];
20
+ };
21
+
22
+ export default useMessage;
@@ -0,0 +1,2 @@
1
+ import Message from './message';
2
+ export default Message;
@@ -0,0 +1,92 @@
1
+ @use '../../tokens/corner-radius';
2
+ @use '../../tokens/elevation';
3
+ @use '../../tokens/light';
4
+ @use '../../tokens/spacing';
5
+
6
+ .message {
7
+ background: light.$surface-primary-default;
8
+ border-radius: corner-radius.$s;
9
+ display: grid;
10
+ grid-template-columns: 1fr;
11
+ gap: spacing.$m;
12
+ overflow: hidden;
13
+ padding: spacing.$s spacing.$s spacing.$s (spacing.$s * 2);
14
+ position: relative;
15
+
16
+ &::before {
17
+ content: '';
18
+ position: absolute;
19
+ top: 0;
20
+ left: 0;
21
+ height: 100%;
22
+ width: spacing.$s;
23
+ background: light.$ge-signal-neutral;
24
+ }
25
+
26
+ @media (min-width: 600px) {
27
+ grid-template-columns: 1fr auto;
28
+ }
29
+
30
+ &--floating {
31
+ @include elevation.level(2);
32
+ }
33
+
34
+ &--inline,
35
+ &--mini {
36
+ border: 1px solid light.$ge-border-default;
37
+ }
38
+
39
+ &--mini {
40
+ padding: spacing.$xxs spacing.$xxs spacing.$xxs (spacing.$xxs * 4);
41
+
42
+ &::before {
43
+ width: spacing.$xxs * 2;
44
+ }
45
+ }
46
+
47
+ &--theme-error {
48
+ &::before {
49
+ background: light.$ge-signal-error;
50
+ }
51
+
52
+ .message__link {
53
+ color: light.$on-surface-error;
54
+ }
55
+ }
56
+
57
+ &--theme-warning {
58
+ &::before {
59
+ background: light.$ge-signal-warning;
60
+ }
61
+
62
+ .message__link {
63
+ color: light.$on-surface-warning;
64
+ }
65
+ }
66
+
67
+ &--theme-success {
68
+ &::before {
69
+ background: light.$ge-signal-success;
70
+ }
71
+
72
+ .message__link {
73
+ color: light.$on-surface-success;
74
+ }
75
+ }
76
+
77
+ &--has-button {
78
+ .message__main {
79
+ display: grid;
80
+ gap: spacing.$m;
81
+ grid-template-columns: auto 1fr;
82
+ }
83
+ }
84
+
85
+ &__link-container {
86
+ margin-top: spacing.$m;
87
+ }
88
+
89
+ &__link {
90
+ color: inherit;
91
+ }
92
+ }
@@ -0,0 +1,60 @@
1
+ import cn from 'classnames';
2
+ import * as React from 'react';
3
+
4
+ import Text from '../text';
5
+ import VisuallyButton from '../visually-button';
6
+
7
+ import { Message as Props, themes } from './message.types';
8
+
9
+ const Message: React.FC<Props> & {
10
+ themes: typeof themes;
11
+ } = ({ action, inline, link, mini, text, theme = themes.default }) => (
12
+ <div
13
+ className={cn('message', {
14
+ 'message--floating': !inline,
15
+ 'message--inline': inline,
16
+ 'message--mini': mini,
17
+ [`message--theme-${theme}`]: theme,
18
+ })}
19
+ >
20
+ <div
21
+ className={cn('message__main', {
22
+ 'message--has-button': action,
23
+ })}
24
+ >
25
+ <div>
26
+ <Text
27
+ className="message__text"
28
+ size={mini ? Text.sizes.small : Text.sizes.basic}
29
+ >
30
+ {text}
31
+ </Text>
32
+ {link ? (
33
+ <div className="message__link-container">
34
+ <Text
35
+ className="message__link"
36
+ elementName="a"
37
+ href={link.href}
38
+ size={mini ? Text.sizes.small : Text.sizes.basic}
39
+ >
40
+ {link.text}
41
+ </Text>
42
+ </div>
43
+ ) : null}
44
+ </div>
45
+ </div>
46
+ {action ? (
47
+ <div>
48
+ <VisuallyButton
49
+ {...action}
50
+ size={VisuallyButton.sizes.small}
51
+ variant={VisuallyButton.variants.secondary}
52
+ />
53
+ </div>
54
+ ) : null}
55
+ </div>
56
+ );
57
+
58
+ Message.themes = themes;
59
+
60
+ export default Message;
@@ -0,0 +1,39 @@
1
+ import { ObjectValues } from '../types';
2
+ import { VisuallyButton } from '../visually-button/visually-button.types';
3
+
4
+ export const themes = {
5
+ default: 'default',
6
+ error: 'error',
7
+ success: 'success',
8
+ warning: 'warning',
9
+ } as const;
10
+
11
+ export type Message = {
12
+ action?: VisuallyButton;
13
+ inline?: boolean;
14
+ link?: {
15
+ href: string;
16
+ text: string;
17
+ };
18
+ mini?: boolean;
19
+ text: string;
20
+ theme?: ObjectValues<typeof themes>;
21
+ };
22
+
23
+ export const isMessageType = (
24
+ maybeMessageType?: string,
25
+ ): maybeMessageType is Message['theme'] =>
26
+ maybeMessageType
27
+ ? Boolean(themes[maybeMessageType as keyof Message['theme']])
28
+ : false;
29
+
30
+ export const types: Record<string, Message['theme']> = {
31
+ default: themes.default,
32
+ error: themes.error,
33
+ success: themes.success,
34
+ warning: themes.warning,
35
+ };
36
+
37
+ export type MessageDetail = Pick<Message, 'link' | 'text' | 'theme'>;
38
+
39
+ export type Listener = (event: MessageDetail) => void;
@@ -0,0 +1,19 @@
1
+ import { Listener, MessageDetail } from './message.types';
2
+
3
+ const eventName = 'user-message';
4
+
5
+ export const publish = (message: MessageDetail) => {
6
+ if (!message) {
7
+ return;
8
+ }
9
+
10
+ window.dispatchEvent(new CustomEvent(eventName, { detail: message }));
11
+ };
12
+
13
+ const subscriber = (listener: Listener) => (event: CustomEvent) =>
14
+ listener(event.detail);
15
+
16
+ export const subscribe = (listener: Listener) => {
17
+ window.addEventListener(eventName, subscriber(listener));
18
+ return () => window.removeEventListener(eventName, subscriber(listener));
19
+ };
@@ -0,0 +1,2 @@
1
+ import MessageField from './message-field';
2
+ export default MessageField;
@@ -0,0 +1,21 @@
1
+ @use '../../tokens/light';
2
+ @use '../../tokens/spacing';
3
+
4
+ .message-field {
5
+ display: flex;
6
+ width: 100%;
7
+ gap: spacing.$xs;
8
+ align-items: center;
9
+
10
+ &__message {
11
+ flex: 1;
12
+ }
13
+
14
+ &--variant-nested {
15
+ background: light.$background-primary-default;
16
+ padding: spacing.$m;
17
+ &-small {
18
+ padding: spacing.$s;
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,70 @@
1
+ import React, { useState } from 'react';
2
+
3
+ import { MessageField as Props, variants, sizes } from './message-field.types';
4
+ import Button from '../button';
5
+ import TextArea from '../text-area';
6
+ import Send from '@sats-group/icons/16/send';
7
+ import Add from '@sats-group/icons/16/add';
8
+ import classNames from 'classnames';
9
+
10
+ const MessageField: React.FunctionComponent<Props> & {
11
+ variants: typeof variants;
12
+ sizes: typeof sizes;
13
+ } = ({
14
+ send,
15
+ input,
16
+ altButton,
17
+ variant = variants.nested,
18
+ size = sizes.default,
19
+ isSubmitting,
20
+ onAltButtonClick = () => {},
21
+ onClickFunc = () => {},
22
+ }) => {
23
+ const [hasTyped, setHasTyped] = useState(false);
24
+ return (
25
+ <div
26
+ className={classNames('message-field', {
27
+ [`message-field--variant-${variant}`]: variant,
28
+ [`message-field--variant-${variant}-${size}`]: size,
29
+ })}
30
+ >
31
+ {altButton ? (
32
+ <Button
33
+ {...altButton}
34
+ leadingIcon={<Add />}
35
+ variant={Button.variants.tertiary}
36
+ onClick={onAltButtonClick}
37
+ size={size === sizes.small ? Button.sizes.small : Button.sizes.basic}
38
+ />
39
+ ) : null}
40
+ <div className="message-field__message">
41
+ <TextArea
42
+ {...input}
43
+ onChange={e => {
44
+ setHasTyped(!!e.target.value.length);
45
+ }}
46
+ isLabelVisible={false}
47
+ size={
48
+ size === sizes.small ? TextArea.sizes.small : TextArea.sizes.default
49
+ }
50
+ isShort
51
+ />
52
+ </div>
53
+ <div>
54
+ <Button
55
+ {...send}
56
+ leadingIcon={<Send />}
57
+ disabled={!hasTyped || isSubmitting}
58
+ theme={isSubmitting ? Button.themes.spinner : Button.themes.normal}
59
+ variant={Button.variants.complete}
60
+ onClick={onClickFunc}
61
+ size={size === sizes.small ? Button.sizes.small : Button.sizes.basic}
62
+ />
63
+ </div>
64
+ </div>
65
+ );
66
+ };
67
+
68
+ MessageField.variants = variants;
69
+ MessageField.sizes = sizes;
70
+ export default MessageField;
@@ -0,0 +1,24 @@
1
+ import type { Button } from '../button/button.types';
2
+ import type { TextArea } from '../text-area/text-area.types';
3
+ import type { ObjectValues } from '../types';
4
+
5
+ export const variants = {
6
+ nested: 'nested',
7
+ standalone: 'standalone',
8
+ } as const;
9
+
10
+ export const sizes = {
11
+ default: 'default',
12
+ small: 'small',
13
+ } as const;
14
+
15
+ export type MessageField = {
16
+ send: Button;
17
+ input: TextArea;
18
+ altButton?: Button;
19
+ variant?: ObjectValues<typeof variants>;
20
+ size?: ObjectValues<typeof sizes>;
21
+ isSubmitting?: boolean;
22
+ onAltButtonClick?: () => void;
23
+ onClickFunc?: () => void;
24
+ };
@@ -0,0 +1,2 @@
1
+ import Modal from './modal';
2
+ export default Modal;