@tcn/ui 0.9.0 → 0.11.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 (298) hide show
  1. package/dist/bar.css +1 -0
  2. package/dist/body.css +1 -1
  3. package/dist/body.module-BbFZ7KNP.js +5 -0
  4. package/dist/body.module-BbFZ7KNP.js.map +1 -0
  5. package/dist/divider.css +1 -1
  6. package/dist/footer.css +1 -1
  7. package/dist/form/field/h_field/h_field.d.ts.map +1 -1
  8. package/dist/form/field/h_field/h_field.js +33 -35
  9. package/dist/form/field/h_field/h_field.js.map +1 -1
  10. package/dist/form/field/v_field/v_field.d.ts.map +1 -1
  11. package/dist/form/field/v_field/v_field.js +34 -36
  12. package/dist/form/field/v_field/v_field.js.map +1 -1
  13. package/dist/frame.css +1 -1
  14. package/dist/inputs/color_input/color_input.d.ts.map +1 -1
  15. package/dist/inputs/color_input/color_input.js +47 -46
  16. package/dist/inputs/color_input/color_input.js.map +1 -1
  17. package/dist/inputs/combo_box/combo_box.d.ts.map +1 -1
  18. package/dist/inputs/combo_box/combo_box.js +61 -58
  19. package/dist/inputs/combo_box/combo_box.js.map +1 -1
  20. package/dist/inputs/index.d.ts +1 -0
  21. package/dist/inputs/index.d.ts.map +1 -1
  22. package/dist/inputs/index.js +34 -31
  23. package/dist/inputs/index.js.map +1 -1
  24. package/dist/inputs/input/input.js +9 -9
  25. package/dist/inputs/input/input.js.map +1 -1
  26. package/dist/inputs/input_group/input_group.d.ts +5 -0
  27. package/dist/inputs/input_group/input_group.d.ts.map +1 -0
  28. package/dist/inputs/input_group/input_group.js +20 -0
  29. package/dist/inputs/input_group/input_group.js.map +1 -0
  30. package/dist/inputs/phone_number_input/countries_phone_information.d.ts +2 -2
  31. package/dist/inputs/phone_number_input/countries_phone_information.d.ts.map +1 -1
  32. package/dist/inputs/phone_number_input/countries_phone_information.js +5 -353
  33. package/dist/inputs/phone_number_input/countries_phone_information.js.map +1 -1
  34. package/dist/inputs/phone_number_input/phone_number_context.d.ts +24 -0
  35. package/dist/inputs/phone_number_input/phone_number_context.d.ts.map +1 -0
  36. package/dist/inputs/phone_number_input/phone_number_context.js +23 -0
  37. package/dist/inputs/phone_number_input/phone_number_context.js.map +1 -0
  38. package/dist/inputs/phone_number_input/phone_number_country_select_adapter.d.ts +19 -0
  39. package/dist/inputs/phone_number_input/phone_number_country_select_adapter.d.ts.map +1 -0
  40. package/dist/inputs/phone_number_input/phone_number_country_select_adapter.js +77 -0
  41. package/dist/inputs/phone_number_input/phone_number_country_select_adapter.js.map +1 -0
  42. package/dist/inputs/phone_number_input/phone_number_input.d.ts +16 -14
  43. package/dist/inputs/phone_number_input/phone_number_input.d.ts.map +1 -1
  44. package/dist/inputs/phone_number_input/phone_number_input.js +104 -274
  45. package/dist/inputs/phone_number_input/phone_number_input.js.map +1 -1
  46. package/dist/inputs/phone_number_input/phone_number_input_adapter.d.ts +6 -0
  47. package/dist/inputs/phone_number_input/phone_number_input_adapter.d.ts.map +1 -0
  48. package/dist/inputs/phone_number_input/phone_number_input_adapter.js +95 -0
  49. package/dist/inputs/phone_number_input/phone_number_input_adapter.js.map +1 -0
  50. package/dist/inputs/phone_number_input/sip_input.d.ts +12 -0
  51. package/dist/inputs/phone_number_input/sip_input.d.ts.map +1 -0
  52. package/dist/inputs/phone_number_input/sip_input.js +111 -0
  53. package/dist/inputs/phone_number_input/sip_input.js.map +1 -0
  54. package/dist/inputs/select/select.d.ts.map +1 -1
  55. package/dist/inputs/select/select.js +3 -2
  56. package/dist/inputs/select/select.js.map +1 -1
  57. package/dist/inputs/suggestions/suggestion_list.d.ts +4 -1
  58. package/dist/inputs/suggestions/suggestion_list.d.ts.map +1 -1
  59. package/dist/inputs/suggestions/suggestion_list.js +120 -111
  60. package/dist/inputs/suggestions/suggestion_list.js.map +1 -1
  61. package/dist/inputs/textarea/textarea.js +8 -8
  62. package/dist/inputs/textarea/textarea.js.map +1 -1
  63. package/dist/inputs/unit_input/unit_input.d.ts.map +1 -1
  64. package/dist/inputs/unit_input/unit_input.js +39 -39
  65. package/dist/inputs/unit_input/unit_input.js.map +1 -1
  66. package/dist/layouts/bar/bar.d.ts +5 -0
  67. package/dist/layouts/bar/bar.d.ts.map +1 -0
  68. package/dist/layouts/bar/bar.js +20 -0
  69. package/dist/layouts/bar/bar.js.map +1 -0
  70. package/dist/layouts/body/body.d.ts +2 -2
  71. package/dist/layouts/body/body.d.ts.map +1 -1
  72. package/dist/layouts/body/body.js +12 -12
  73. package/dist/layouts/body/body.js.map +1 -1
  74. package/dist/layouts/body/h_body.d.ts.map +1 -1
  75. package/dist/layouts/body/h_body.js +18 -12
  76. package/dist/layouts/body/h_body.js.map +1 -1
  77. package/dist/layouts/body/v_body.d.ts.map +1 -1
  78. package/dist/layouts/body/v_body.js +16 -10
  79. package/dist/layouts/body/v_body.js.map +1 -1
  80. package/dist/layouts/footer/footer.d.ts +2 -3
  81. package/dist/layouts/footer/footer.d.ts.map +1 -1
  82. package/dist/layouts/footer/footer.js +7 -7
  83. package/dist/layouts/footer/footer.js.map +1 -1
  84. package/dist/layouts/header/header.d.ts +2 -2
  85. package/dist/layouts/header/header.d.ts.map +1 -1
  86. package/dist/layouts/header/header.js +13 -21
  87. package/dist/layouts/header/header.js.map +1 -1
  88. package/dist/layouts/index.d.ts +0 -1
  89. package/dist/layouts/index.d.ts.map +1 -1
  90. package/dist/layouts/index.js +17 -19
  91. package/dist/layouts/index.js.map +1 -1
  92. package/dist/layouts/rail/rail.js +41 -41
  93. package/dist/layouts/rail/rail.js.map +1 -1
  94. package/dist/layouts/rail/side/side.d.ts.map +1 -1
  95. package/dist/layouts/rail/side/side.js +1 -1
  96. package/dist/layouts/rail/side/side.js.map +1 -1
  97. package/dist/layouts/rail/utility_strip/utility_strip.d.ts.map +1 -1
  98. package/dist/layouts/rail/utility_strip/utility_strip.js +21 -17
  99. package/dist/layouts/rail/utility_strip/utility_strip.js.map +1 -1
  100. package/dist/layouts/scaffold/scaffold.js +32 -32
  101. package/dist/layouts/scaffold/scaffold.js.map +1 -1
  102. package/dist/layouts/utility_bar/utility_bar.d.ts +2 -2
  103. package/dist/layouts/utility_bar/utility_bar.d.ts.map +1 -1
  104. package/dist/layouts/utility_bar/utility_bar.js +17 -19
  105. package/dist/layouts/utility_bar/utility_bar.js.map +1 -1
  106. package/dist/overlay/frame/frame.d.ts +8 -4
  107. package/dist/overlay/frame/frame.d.ts.map +1 -1
  108. package/dist/overlay/frame/frame.js +87 -23
  109. package/dist/overlay/frame/frame.js.map +1 -1
  110. package/dist/overlay/popper/base/dismissal_decorator.js.map +1 -1
  111. package/dist/overlay/popper/legacy/popper.d.ts.map +1 -1
  112. package/dist/overlay/popper/legacy/popper.js +52 -50
  113. package/dist/overlay/popper/legacy/popper.js.map +1 -1
  114. package/dist/panel.css +1 -0
  115. package/dist/phone_number_input.css +1 -1
  116. package/dist/rail.css +1 -1
  117. package/dist/scaffold.css +1 -1
  118. package/dist/side.css +1 -1
  119. package/dist/stacks/box/bottom_resize_handle.d.ts +2 -2
  120. package/dist/stacks/box/bottom_resize_handle.d.ts.map +1 -1
  121. package/dist/stacks/box/bottom_resize_handle.js +12 -10
  122. package/dist/stacks/box/bottom_resize_handle.js.map +1 -1
  123. package/dist/stacks/box/box.d.ts +4 -4
  124. package/dist/stacks/box/box.d.ts.map +1 -1
  125. package/dist/stacks/box/box.js +26 -26
  126. package/dist/stacks/box/box.js.map +1 -1
  127. package/dist/stacks/box/end_resize_handle.d.ts +2 -2
  128. package/dist/stacks/box/end_resize_handle.d.ts.map +1 -1
  129. package/dist/stacks/box/end_resize_handle.js +6 -5
  130. package/dist/stacks/box/end_resize_handle.js.map +1 -1
  131. package/dist/stacks/box/left_resize_handle.d.ts +2 -2
  132. package/dist/stacks/box/left_resize_handle.d.ts.map +1 -1
  133. package/dist/stacks/box/left_resize_handle.js +10 -9
  134. package/dist/stacks/box/left_resize_handle.js.map +1 -1
  135. package/dist/stacks/box/resize_handlers.d.ts +2 -2
  136. package/dist/stacks/box/resize_handlers.d.ts.map +1 -1
  137. package/dist/stacks/box/resize_handlers.js +32 -32
  138. package/dist/stacks/box/resize_handlers.js.map +1 -1
  139. package/dist/stacks/box/right_resize_handle.d.ts +2 -2
  140. package/dist/stacks/box/right_resize_handle.d.ts.map +1 -1
  141. package/dist/stacks/box/right_resize_handle.js +6 -5
  142. package/dist/stacks/box/right_resize_handle.js.map +1 -1
  143. package/dist/stacks/box/start_resize_handle.d.ts +2 -2
  144. package/dist/stacks/box/start_resize_handle.d.ts.map +1 -1
  145. package/dist/stacks/box/start_resize_handle.js +6 -6
  146. package/dist/stacks/box/start_resize_handle.js.map +1 -1
  147. package/dist/stacks/box/top_resize_handle.d.ts +2 -2
  148. package/dist/stacks/box/top_resize_handle.d.ts.map +1 -1
  149. package/dist/stacks/box/top_resize_handle.js +6 -5
  150. package/dist/stacks/box/top_resize_handle.js.map +1 -1
  151. package/dist/stacks/h_collapsible_box.d.ts.map +1 -1
  152. package/dist/stacks/h_collapsible_box.js +25 -25
  153. package/dist/stacks/h_collapsible_box.js.map +1 -1
  154. package/dist/stacks/v_collapsible_box.js +25 -25
  155. package/dist/stacks/v_collapsible_box.js.map +1 -1
  156. package/dist/suggestion_list.css +1 -1
  157. package/dist/surfaces/index.d.ts +1 -2
  158. package/dist/surfaces/index.d.ts.map +1 -1
  159. package/dist/surfaces/index.js +18 -20
  160. package/dist/surfaces/index.js.map +1 -1
  161. package/dist/surfaces/panel/panel.d.ts +5 -0
  162. package/dist/surfaces/panel/panel.d.ts.map +1 -0
  163. package/dist/surfaces/panel/panel.js +19 -0
  164. package/dist/surfaces/panel/panel.js.map +1 -0
  165. package/dist/surfaces/pop_confirm/pop_confirm.js +2 -3
  166. package/dist/surfaces/pop_confirm/pop_confirm.js.map +1 -1
  167. package/dist/surfaces/window/window.d.ts +1 -1
  168. package/dist/surfaces/window/window.d.ts.map +1 -1
  169. package/dist/surfaces/window/window.js +20 -10
  170. package/dist/surfaces/window/window.js.map +1 -1
  171. package/dist/themes/stylesheets/reset.css +1 -1
  172. package/dist/themes/stylesheets/reset.js +8 -1
  173. package/dist/themes/stylesheets/reset.js.map +1 -1
  174. package/dist/themes/theme.d.ts +2 -1
  175. package/dist/themes/theme.d.ts.map +1 -1
  176. package/dist/themes/theme.js +16 -9
  177. package/dist/themes/theme.js.map +1 -1
  178. package/dist/themes/themes/ergo/ergo_theme.css +1 -1
  179. package/dist/themes/themes/ergo/ergo_theme.js +210 -18
  180. package/dist/themes/themes/ergo/ergo_theme.js.map +1 -1
  181. package/dist/typography/body_text/body_text.d.ts.map +1 -1
  182. package/dist/typography/body_text/body_text.js +12 -10
  183. package/dist/typography/body_text/body_text.js.map +1 -1
  184. package/dist/utils/dnd/hooks/use_drag_container.d.ts.map +1 -1
  185. package/dist/utils/dnd/hooks/use_drag_container.js +22 -19
  186. package/dist/utils/dnd/hooks/use_drag_container.js.map +1 -1
  187. package/package.json +4 -2
  188. package/src/form/field/h_field/h_field.tsx +0 -4
  189. package/src/form/field/v_field/v_field.stories.tsx +8 -0
  190. package/src/form/field/v_field/v_field.tsx +1 -4
  191. package/src/form/field_set/field_set.stories.tsx +2 -1
  192. package/src/inputs/__docs__/inputs.mdx +81 -0
  193. package/src/inputs/__docs__/inputs.stories.tsx +268 -0
  194. package/src/inputs/color_input/color_input.tsx +17 -17
  195. package/src/inputs/combo_box/combo_box.tsx +17 -13
  196. package/src/inputs/index.ts +2 -0
  197. package/src/inputs/input/input.tsx +1 -1
  198. package/src/inputs/input_group/input_group.tsx +26 -0
  199. package/src/inputs/phone_number_input/countries_phone_information.ts +6 -353
  200. package/src/inputs/phone_number_input/phone_number_context.tsx +32 -0
  201. package/src/inputs/phone_number_input/phone_number_country_select_adapter.tsx +126 -0
  202. package/src/inputs/phone_number_input/phone_number_input.module.css +5 -63
  203. package/src/inputs/phone_number_input/phone_number_input.stories.tsx +180 -150
  204. package/src/inputs/phone_number_input/phone_number_input.tsx +133 -400
  205. package/src/inputs/phone_number_input/phone_number_input_adapter.tsx +123 -0
  206. package/src/inputs/phone_number_input/sip_input.tsx +147 -0
  207. package/src/inputs/select/select.tsx +13 -14
  208. package/src/inputs/suggestions/suggestion_list.module.css +1 -0
  209. package/src/inputs/suggestions/suggestion_list.stories.tsx +12 -8
  210. package/src/inputs/suggestions/suggestion_list.tsx +24 -3
  211. package/src/inputs/textarea/textarea.tsx +1 -1
  212. package/src/inputs/unit_input/unit_input.tsx +17 -17
  213. package/src/layouts/__stories__/composed.stories.tsx +0 -55
  214. package/src/layouts/__stories__/rail.stories.tsx +78 -0
  215. package/src/layouts/__stories__/scaffold.stories.tsx +90 -0
  216. package/src/layouts/__stories__/utils/content.tsx +27 -0
  217. package/src/layouts/__stories__/utils/layout_theme.css +88 -0
  218. package/src/layouts/__stories__/utils/layout_theme_provider.tsx +11 -0
  219. package/src/layouts/__stories__/utils.tsx +6 -6
  220. package/src/layouts/{utility_bar/utility_bar.module.css → bar/bar.module.css} +2 -1
  221. package/src/layouts/bar/bar.tsx +23 -0
  222. package/src/layouts/body/body.module.css +9 -4
  223. package/src/layouts/body/body.tsx +7 -6
  224. package/src/layouts/body/h_body.module.css +1 -2
  225. package/src/layouts/body/h_body.tsx +9 -4
  226. package/src/layouts/body/v_body.tsx +9 -4
  227. package/src/layouts/divider/divider.module.css +1 -1
  228. package/src/layouts/footer/footer.module.css +0 -3
  229. package/src/layouts/footer/footer.tsx +5 -6
  230. package/src/layouts/header/header.tsx +6 -15
  231. package/src/layouts/index.ts +0 -1
  232. package/src/layouts/rail/rail.module.css +9 -5
  233. package/src/layouts/rail/rail.tsx +1 -1
  234. package/src/layouts/rail/side/side.module.css +0 -1
  235. package/src/layouts/rail/side/side.tsx +1 -2
  236. package/src/layouts/rail/utility_strip/utility_strip.module.css +5 -0
  237. package/src/layouts/rail/utility_strip/utility_strip.tsx +4 -1
  238. package/src/layouts/scaffold/scaffold.module.css +10 -7
  239. package/src/layouts/scaffold/scaffold.tsx +1 -1
  240. package/src/layouts/utility_bar/utility_bar.tsx +6 -9
  241. package/src/overlay/frame/frame.module.css +2 -4
  242. package/src/overlay/frame/frame.stories.tsx +13 -10
  243. package/src/overlay/frame/frame.tsx +124 -16
  244. package/src/overlay/popper/base/dismissal_decorator.tsx +1 -1
  245. package/src/overlay/popper/legacy/popper.tsx +5 -1
  246. package/src/stacks/box/bottom_resize_handle.tsx +12 -5
  247. package/src/stacks/box/box.tsx +18 -14
  248. package/src/stacks/box/end_resize_handle.tsx +11 -6
  249. package/src/stacks/box/left_resize_handle.tsx +9 -3
  250. package/src/stacks/box/resize_handlers.ts +27 -13
  251. package/src/stacks/box/right_resize_handle.tsx +9 -3
  252. package/src/stacks/box/start_resize_handle.tsx +9 -4
  253. package/src/stacks/box/top_resize_handle.tsx +10 -4
  254. package/src/stacks/collapsible_box.stories.tsx +11 -11
  255. package/src/stacks/h_collapsible_box.tsx +5 -5
  256. package/src/stacks/v_collapsible_box.tsx +4 -4
  257. package/src/surfaces/index.ts +1 -2
  258. package/src/surfaces/panel/__stories__/panel.stories.tsx +12 -12
  259. package/src/surfaces/panel/__stories__/panel_stories.module.css +3 -3
  260. package/src/surfaces/panel/panel.module.css +1 -6
  261. package/src/surfaces/panel/panel.tsx +22 -0
  262. package/src/surfaces/window/window.tsx +14 -4
  263. package/src/themes/stories/controls_fieldset.tsx +1 -1
  264. package/src/themes/stylesheets/reset.css +8 -1
  265. package/src/themes/theme.tsx +6 -2
  266. package/src/themes/themes/ergo/__stories__/material.stories.tsx +15 -16
  267. package/src/themes/themes/ergo/ergo_theme.css +210 -18
  268. package/src/typography/body_text/body_text.tsx +2 -0
  269. package/src/utils/dnd/__stories__/draggable.stories.tsx +14 -8
  270. package/src/utils/dnd/hooks/use_drag_container.ts +13 -3
  271. package/dist/h_body.css +0 -1
  272. package/dist/h_panel.css +0 -1
  273. package/dist/header.css +0 -1
  274. package/dist/layouts/rail/main/main.d.ts +0 -6
  275. package/dist/layouts/rail/main/main.d.ts.map +0 -1
  276. package/dist/layouts/rail/main/main.js +0 -21
  277. package/dist/layouts/rail/main/main.js.map +0 -1
  278. package/dist/main.css +0 -1
  279. package/dist/surfaces/panel/h_panel.d.ts +0 -9
  280. package/dist/surfaces/panel/h_panel.d.ts.map +0 -1
  281. package/dist/surfaces/panel/h_panel.js +0 -60
  282. package/dist/surfaces/panel/h_panel.js.map +0 -1
  283. package/dist/surfaces/panel/v_panel.d.ts +0 -5
  284. package/dist/surfaces/panel/v_panel.d.ts.map +0 -1
  285. package/dist/surfaces/panel/v_panel.js +0 -19
  286. package/dist/surfaces/panel/v_panel.js.map +0 -1
  287. package/dist/utility_bar.css +0 -1
  288. package/dist/v_body.css +0 -1
  289. package/src/inputs/phone_number_input/__tests__/utils.test.ts +0 -52
  290. package/src/layouts/header/header.module.css +0 -8
  291. package/src/layouts/rail/__stories__/rail.stories.tsx +0 -64
  292. package/src/layouts/rail/__stories__/rail_stories.module.css +0 -25
  293. package/src/layouts/rail/main/main.module.css +0 -7
  294. package/src/layouts/rail/main/main.tsx +0 -26
  295. package/src/layouts/scaffold/__stories__/scaffold.stories.tsx +0 -53
  296. package/src/layouts/scaffold/__stories__/scaffold_stories.module.css +0 -31
  297. package/src/surfaces/panel/h_panel.tsx +0 -65
  298. package/src/surfaces/panel/v_panel.tsx +0 -20
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import { makeContextHook } from '../../utils/index.js';
3
+ import { OptionProps } from '../options/option.js';
4
+ import type { CountryCode } from 'libphonenumber-js';
5
+
6
+ export interface PhoneContext {
7
+ allowSip: boolean;
8
+ phoneBook: React.ReactElement<OptionProps>[];
9
+ ariaPhoneBookButtonLabel?: string;
10
+ ariaSelectLabel?: string;
11
+ value: string;
12
+ setValue: (value: string) => void;
13
+ setCountry: (country: CountryCode) => void;
14
+ sipAddress: string;
15
+ setSipAddress: (address: string) => void;
16
+ disabled?: boolean;
17
+ focusNumberInput: boolean;
18
+ setFocusNumberInput: (focus: boolean) => void;
19
+ }
20
+
21
+ export const PhoneBookContext = React.createContext<PhoneContext | undefined>(undefined);
22
+ export const usePhoneContext = makeContextHook(PhoneBookContext, 'PhoneBookContext');
23
+
24
+ export function PhoneBookProvider({
25
+ children,
26
+ value,
27
+ }: {
28
+ value: PhoneContext;
29
+ children: React.ReactNode;
30
+ }) {
31
+ return <PhoneBookContext.Provider value={value}>{children}</PhoneBookContext.Provider>;
32
+ }
@@ -0,0 +1,126 @@
1
+ import React from 'react';
2
+ import { Select } from '../select/select.js';
3
+ import { Option } from '../options/option.js';
4
+ import clsx from 'clsx';
5
+ import {
6
+ countriesPhoneInformation,
7
+ CountryPhoneInformation,
8
+ } from './countries_phone_information.js';
9
+ import { usePhoneContext } from './phone_number_context.js';
10
+
11
+ export const countryPrefixMap: Map<string, CountryPhoneInformation[]> = new Map();
12
+ export const countryCodeMap: Map<string, CountryPhoneInformation> = new Map();
13
+ countriesPhoneInformation.forEach(i => {
14
+ countryCodeMap.set(i.code, i);
15
+ if (countryPrefixMap.has(i.prefix)) {
16
+ countryPrefixMap.get(i.prefix)?.push(i);
17
+ } else {
18
+ countryPrefixMap.set(i.prefix, [i]);
19
+ }
20
+ });
21
+
22
+ export function getCountryFromValue(value: string) {
23
+ for (let x = 5; x > 1; x--) {
24
+ const prefix = value.slice(0, x);
25
+ const countriesInformation = countryPrefixMap.get(prefix);
26
+
27
+ if (countriesInformation != null) {
28
+ const countryInformation = countriesInformation.find(c => c.code === 'US');
29
+
30
+ if (countryInformation != null) {
31
+ return countryInformation;
32
+ }
33
+ }
34
+ }
35
+
36
+ return countryCodeMap.get('US');
37
+ }
38
+
39
+ export interface CountryOption {
40
+ value?: string;
41
+ label?: string;
42
+ divider?: boolean;
43
+ }
44
+
45
+ export interface CountrySelectProps {
46
+ value?: string;
47
+ onChange: (value?: string) => void;
48
+ options: CountryOption[];
49
+ disabled?: boolean;
50
+ className?: string;
51
+ 'aria-label'?: string;
52
+ }
53
+
54
+ export function PhoneNumberCountrySelectAdapter({
55
+ value,
56
+ onChange,
57
+ options,
58
+ disabled,
59
+ className,
60
+ 'aria-label': ariaLabel,
61
+ }: CountrySelectProps) {
62
+ const {
63
+ setValue,
64
+ sipAddress,
65
+ allowSip,
66
+ value: phoneValue,
67
+ setFocusNumberInput,
68
+ } = usePhoneContext();
69
+
70
+ const handleChange = React.useCallback(
71
+ (newValue: string) => {
72
+ if (newValue === 'SIP') {
73
+ setValue(`sip:${sipAddress}`);
74
+ setFocusNumberInput(true);
75
+ return;
76
+ }
77
+
78
+ onChange(newValue === 'ZZ' ? undefined : newValue);
79
+ },
80
+ [onChange, sipAddress, setValue, setFocusNumberInput]
81
+ );
82
+
83
+ const items = options
84
+ .filter(opt => !opt.divider)
85
+ .map(opt => countryCodeMap.get(opt.value || 'ZZ'))
86
+ .filter(country => country != null)
87
+ .sort((a, b) => {
88
+ if (a.code === 'US') {
89
+ return -1;
90
+ }
91
+ return Number(a.prefix) - Number(b.prefix);
92
+ })
93
+ .map(country => {
94
+ return (
95
+ <Option
96
+ key={country?.code || 'ZZ'}
97
+ value={country?.code || 'ZZ'}
98
+ label={country.prefix || ''}
99
+ keywords={country.keywords}
100
+ >
101
+ {`${country.prefix} (${country.code}) ${country.unicodeFlag}`}
102
+ </Option>
103
+ );
104
+ });
105
+
106
+ if (allowSip || phoneValue?.startsWith('sip:')) {
107
+ items.unshift(
108
+ <Option key="SIP" value="SIP" label="sip:" keywords={['sip']}>
109
+ SIP
110
+ </Option>
111
+ );
112
+ }
113
+
114
+ return (
115
+ <Select
116
+ value={value || 'ZZ'}
117
+ onChange={handleChange}
118
+ disabled={disabled}
119
+ aria-label={ariaLabel ?? 'Country'}
120
+ className={clsx(className, 'tcn-input-group-slot')}
121
+ width="auto"
122
+ >
123
+ {items}
124
+ </Select>
125
+ );
126
+ }
@@ -1,64 +1,6 @@
1
- @layer tcn-system {
2
- :where(.phone-number-input) {
3
- position: relative;
4
- opacity: 1;
5
- border-radius: 0;
6
- }
7
-
8
- :where(.phone-number-input[data-has-phone-book="false"]) {
9
- border-end-end-radius: 4px;
10
- border-start-end-radius: 4px;
11
- }
12
-
13
- :where(.phone-number-input-select) {
14
- border-end-end-radius: 0px;
15
- border-start-end-radius: 0px;
16
- }
17
-
18
- :where(.phone-number-input > *) {
19
- position: relative;
20
- z-index: 1;
21
- }
22
-
23
- :where(.phone-number-input-select:has(button)) {
24
- z-index: 2;
25
- }
26
-
27
- :where(.phone-number-input-input:has(input:focus)),
28
- :where(.phone-number-input-select:focus),
29
- :where(.phone-number-input-input:has(input:focus-visible)),
30
- :where(.phone-number-input-select:focus-visible) {
31
- z-index: 3;
32
- }
33
-
34
- :where(.phone-number-input-phone-book-popover) {
35
- border-radius: calc(4px * var(--scalar, 1));
36
- padding: 8px;
37
- background-color: rgba(254, 254, 254, 1);
38
- box-shadow: var(--raised-box-shadow), var(--drop-shadow-depth-3);
39
- min-width: calc(200px * var(--scalar, 1));
40
- }
41
-
42
- :where(.phone-number-input-phone-book) {
43
- border-start-start-radius: 0px;
44
- border-end-start-radius: 0px;
45
- height: calc(26px * var(--scalar, 1)) !important;
46
- width: calc(26px * var(--scalar, 1)) !important;
47
- min-height: calc(26px * var(--scalar, 1)) !important;
48
- min-width: calc(26px * var(--scalar, 1)) !important;
49
- max-height: calc(26px * var(--scalar, 1)) !important;
50
- max-width: calc(26px * var(--scalar, 1)) !important;
51
- }
52
-
53
- :where(.phone-number-input-obfuscated) {
54
- user-select: none;
55
- -webkit-user-select: none;
56
- cursor: default;
57
- width: 100%;
58
- height: 100%;
59
- }
60
-
61
- :where(.phone-number-input-obfuscated::selection) {
62
- background: transparent;
63
- }
1
+ .phone-number-input {
2
+ flex-grow: 1;
3
+ flex-shrink: 0;
4
+ flex-basis: 0%;
5
+ width: auto;
64
6
  }
@@ -1,160 +1,190 @@
1
- import React, { useState } from 'react';
2
- import {
3
- PhoneNumberInput as Component,
4
- PhoneNumberInputProps,
5
- } from './phone_number_input.js';
1
+ import { useState } from 'react';
2
+ import { PhoneNumberInput } from './phone_number_input.js';
3
+ import { reset } from '../../themes/index.js';
4
+ import { Theme } from '../../themes/theme.js';
5
+ import { ergoStyleSheet } from '../../themes/themes/ergo/ergo_theme.js';
6
6
  import { Option } from '../options/option.js';
7
- import styles from '../__storybook__/stories.module.css';
7
+ import { BodyText } from '../../typography/index.js';
8
+ import { HStack } from '../../stacks/h_stack.js';
8
9
 
9
- export default {
10
- title: 'Inputs/Phone Number Input',
11
- parameters: {
12
- docs: {
13
- description: {
14
- component:
15
- 'A phone number input component that allows the user to enter a phone number.',
16
- },
17
- },
18
- },
19
- tags: ['autodocs'],
10
+ export const Default = () => {
11
+ const [value, setValue] = useState<string | undefined>('');
12
+ return (
13
+ <Theme styleSheets={[reset, ergoStyleSheet]}>
14
+ <HStack>
15
+ <PhoneNumberInput value={value} onChange={setValue} />
16
+ <HStack width="200px" hAlign="center">
17
+ <BodyText>{value && value.length > 0 ? value : 'No Value'}</BodyText>
18
+ </HStack>
19
+ </HStack>
20
+ </Theme>
21
+ );
22
+ };
23
+
24
+ export const WithPlaceholder = () => {
25
+ const [value, setValue] = useState<string | undefined>('');
26
+ return (
27
+ <Theme styleSheets={[reset, ergoStyleSheet]}>
28
+ <HStack>
29
+ <PhoneNumberInput
30
+ value={value}
31
+ onChange={setValue}
32
+ placeholder="Enter phone number"
33
+ />
34
+ <HStack width="200px" hAlign="center">
35
+ <BodyText>{value && value.length > 0 ? value : 'No Value'}</BodyText>
36
+ </HStack>
37
+ </HStack>
38
+ </Theme>
39
+ );
40
+ };
41
+
42
+ export const PrefilledValue = () => {
43
+ const [value, setValue] = useState<string | undefined>('+19999999999');
44
+ return (
45
+ <Theme styleSheets={[reset, ergoStyleSheet]}>
46
+ <HStack>
47
+ <PhoneNumberInput value={value} onChange={setValue} />
48
+ <HStack width="200px" hAlign="center">
49
+ <BodyText>{value && value.length > 0 ? value : 'No Value'}</BodyText>
50
+ </HStack>
51
+ </HStack>
52
+ </Theme>
53
+ );
20
54
  };
21
55
 
22
- function Base({
23
- value: defaultValue,
24
- ...props
25
- }: Omit<PhoneNumberInputProps, 'onChange'>) {
26
- const [value, setValue] = useState<string>(defaultValue || '');
56
+ export const Disabled = () => {
57
+ const [value, setValue] = useState<string | undefined>('+12025551234');
27
58
  return (
28
- <Component
29
- value={value}
30
- onChange={value => {
31
- setValue(value);
32
- }}
33
- {...props}
34
- />
59
+ <Theme styleSheets={[reset, ergoStyleSheet]}>
60
+ <HStack>
61
+ <PhoneNumberInput value={value} onChange={setValue} disabled>
62
+ <Option value="+14355865953" label="John Doe" keywords={['john', 'doe']}>
63
+ John Doe - +1 (435) 586-5953
64
+ </Option>
65
+ <Option value="+984355865954" label="Jane Smith" keywords={['jane', 'smith']}>
66
+ Jane Smith - +98 (435) 586-5954
67
+ </Option>
68
+ <Option value="+14355865955" label="Bob Johnson" keywords={['bob', 'johnson']}>
69
+ Bob Johnson - +1 (435) 586-5955
70
+ </Option>
71
+ </PhoneNumberInput>
72
+ <HStack width="200px" hAlign="center">
73
+ <BodyText>{value && value.length > 0 ? value : 'No Value'}</BodyText>
74
+ </HStack>
75
+ </HStack>
76
+ </Theme>
35
77
  );
36
- }
78
+ };
37
79
 
38
- export function PhoneNumberInput() {
80
+ export const DefaultCountryGB = () => {
81
+ const [value, setValue] = useState<string | undefined>('');
39
82
  return (
40
- <table className={styles.story}>
41
- <thead>
42
- <tr>
43
- <th>Name</th>
44
- <th>Component</th>
45
- </tr>
46
- </thead>
47
- <tbody>
48
- <tr>
49
- <td>Baseline</td>
50
- <td>
51
- <Base />
52
- </td>
53
- </tr>
54
- <tr>
55
- <td>Disabled</td>
56
- <td>
57
- <Base disabled />
58
- </td>
59
- </tr>
60
- <tr>
61
- <td>Disabled Phone Number</td>
62
- <td>
63
- <Base disabledPhoneNumber>
64
- <Option value="+14355865953" label="John Doe" keywords={['john', 'doe']}>
65
- John Doe - +1 (435) 586-5953
66
- </Option>
67
- <Option
68
- value="+984355865954"
69
- label="Jane Smith"
70
- keywords={['jane', 'smith']}
71
- >
72
- Jane Smith - +98 (435) 586-5954
73
- </Option>
74
- <Option
75
- value="+14355865955"
76
- label="Bob Johnson"
77
- keywords={['bob', 'johnson']}
78
- >
79
- Bob Johnson - +1 (435) 586-5955
80
- </Option>
81
- </Base>
82
- </td>
83
- </tr>
84
- <tr>
85
- <td>With Value</td>
86
- <td>
87
- <Base value="+14355865953" />
88
- </td>
89
- </tr>
90
- <tr>
91
- <td>Allowed Country Codes</td>
92
- <td>
93
- <Base allowedCountryCodes={['US', 'RU', 'CN']} />
94
- </td>
95
- </tr>
96
- <tr>
97
- <td>Phone Book</td>
98
- <td>
99
- <Base>
100
- <Option value="+14355865953" label="John Doe" keywords={['john', 'doe']}>
101
- John Doe - +1 (435) 586-5953
102
- </Option>
103
- <Option
104
- value="+984355865954"
105
- label="Jane Smith"
106
- keywords={['jane', 'smith']}
107
- >
108
- Jane Smith - +98 (435) 586-5954
109
- </Option>
110
- <Option
111
- value="+14355865955"
112
- label="Bob Johnson"
113
- keywords={['bob', 'johnson']}
114
- >
115
- Bob Johnson - +1 (435) 586-5955
116
- </Option>
117
- <Option
118
- value="+14355865956"
119
- label="Obfuscated Number"
120
- keywords={['obfuscated', 'number']}
121
- obfuscate={true}
122
- >
123
- Obfuscated Number
124
- </Option>
125
- </Base>
126
- </td>
127
- </tr>
83
+ <Theme styleSheets={[reset, ergoStyleSheet]}>
84
+ <HStack>
85
+ <PhoneNumberInput value={value} onChange={setValue} defaultCountry="GB" />
86
+ <HStack width="200px" hAlign="center">
87
+ <BodyText>{value && value.length > 0 ? value : 'No Value'}</BodyText>
88
+ </HStack>
89
+ </HStack>
90
+ </Theme>
91
+ );
92
+ };
128
93
 
129
- <tr>
130
- <td>Phonebook with non-numeric values</td>
131
- <td>
132
- <Base>
133
- <Option
134
- value="+7asd84355865954"
135
- label="+7asd84355865954"
136
- keywords={['jane', 'smith']}
137
- >
138
- Jane Smith - +7asd8 (435) 586-5954
139
- </Option>
140
- <Option
141
- value="+12abc3456789"
142
- label="+12abc3456789"
143
- keywords={['alice', 'wonderland']}
144
- >
145
- Alice Wonderland - +12abc (345) 6789
146
- </Option>
147
- <Option
148
- value="+1-800-FAKE-NUM"
149
- label="+1-800-FAKE-NUM"
150
- keywords={['fake', 'number']}
151
- >
152
- Fake Number - +1-800-FAKE-NUM
153
- </Option>
154
- </Base>
155
- </td>
156
- </tr>
157
- </tbody>
158
- </table>
94
+ export const LimitedCountries = () => {
95
+ const [value, setValue] = useState<string | undefined>('');
96
+ return (
97
+ <Theme styleSheets={[reset, ergoStyleSheet]}>
98
+ <HStack>
99
+ <PhoneNumberInput
100
+ value={value}
101
+ onChange={setValue}
102
+ allowSip={false}
103
+ allowedCountryCodes={['US', 'CA', 'GB', 'AU']}
104
+ />
105
+ <HStack width="200px" hAlign="center">
106
+ <BodyText>{value && value.length > 0 ? value : 'No Value'}</BodyText>
107
+ </HStack>
108
+ </HStack>
109
+ </Theme>
159
110
  );
160
- }
111
+ };
112
+
113
+ export const LimitMaxLength = () => {
114
+ const [value, setValue] = useState<string | undefined>('');
115
+ return (
116
+ <Theme styleSheets={[reset, ergoStyleSheet]}>
117
+ <HStack>
118
+ <PhoneNumberInput value={value} onChange={setValue} limitMaxLength />
119
+ <HStack width="200px" hAlign="center">
120
+ <BodyText>{value && value.length > 0 ? value : 'No Value'}</BodyText>
121
+ </HStack>
122
+ </HStack>
123
+ </Theme>
124
+ );
125
+ };
126
+
127
+ export const WithPhoneBook = () => {
128
+ const [value, setValue] = useState<string | undefined>('');
129
+ return (
130
+ <Theme styleSheets={[reset, ergoStyleSheet]}>
131
+ <HStack>
132
+ <PhoneNumberInput value={value} onChange={setValue}>
133
+ <Option value="+14355865953" label="John Doe" keywords={['john', 'doe']}>
134
+ John Doe - +1 (435) 586-5953
135
+ </Option>
136
+ <Option value="+984355865954" label="Jane Smith" keywords={['jane', 'smith']}>
137
+ Jane Smith - +98 (435) 586-5954
138
+ </Option>
139
+ <Option value="+14355865955" label="Bob Johnson" keywords={['bob', 'johnson']}>
140
+ Bob Johnson - +1 (435) 586-5955
141
+ </Option>
142
+ <Option
143
+ value="sip:foo@bar.com"
144
+ label="Foo Sip"
145
+ keywords={['sip', 'foo', 'bar']}
146
+ >
147
+ Foo Sip - foo@bar.com
148
+ </Option>
149
+ </PhoneNumberInput>
150
+ <HStack width="200px" hAlign="center">
151
+ <BodyText>{value && value.length > 0 ? value : 'No Value'}</BodyText>
152
+ </HStack>
153
+ </HStack>
154
+ </Theme>
155
+ );
156
+ };
157
+
158
+ export const DisableSip = () => {
159
+ const [value, setValue] = useState<string | undefined>('');
160
+ return (
161
+ <Theme styleSheets={[reset, ergoStyleSheet]}>
162
+ <HStack>
163
+ <PhoneNumberInput value={value} onChange={setValue} allowSip={false} />
164
+ <HStack width="200px" hAlign="center">
165
+ <BodyText>{value && value.length > 0 ? value : 'No Value'}</BodyText>
166
+ </HStack>
167
+ </HStack>
168
+ </Theme>
169
+ );
170
+ };
171
+
172
+ // We need to display sip even if it is not allowed. This can happen if the user has a sip address in the value.
173
+ // This may happen with phone books or saved numbers within preview dials.
174
+ export const DisableSipButSipIsInValue = () => {
175
+ const [value, setValue] = useState<string | undefined>('sip:foo@bar.com');
176
+ return (
177
+ <Theme styleSheets={[reset, ergoStyleSheet]}>
178
+ <HStack>
179
+ <PhoneNumberInput value={value} onChange={setValue} allowSip={false} />
180
+ <HStack width="200px" hAlign="center">
181
+ <BodyText>{value && value.length > 0 ? value : 'No Value'}</BodyText>
182
+ </HStack>
183
+ </HStack>
184
+ </Theme>
185
+ );
186
+ };
187
+
188
+ export default {
189
+ title: 'Components/PhoneNumberInput',
190
+ };