@okta/okta-signin-widget 7.16.0 → 7.16.1

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 (246) hide show
  1. package/README.md +5 -5
  2. package/dist/css/fonts.css +172 -0
  3. package/dist/css/okta-sign-in.next.css +1 -240
  4. package/dist/css/okta-sign-in.next.css.map +1 -1
  5. package/dist/esm/src/config/config.json.js +1 -1
  6. package/dist/js/okta-sign-in.classic.js +1 -1
  7. package/dist/js/okta-sign-in.classic.min.js +1 -1
  8. package/dist/js/okta-sign-in.js +1 -1
  9. package/dist/js/okta-sign-in.min.js +1 -1
  10. package/dist/js/okta-sign-in.next.js +61 -19
  11. package/dist/js/okta-sign-in.next.js.map +1 -1
  12. package/dist/js/okta-sign-in.next.no-polyfill.js +60 -18
  13. package/dist/js/okta-sign-in.next.no-polyfill.js.map +1 -1
  14. package/dist/js/okta-sign-in.no-polyfill.min.js +1 -1
  15. package/dist/js/okta-sign-in.oie.js +1 -1
  16. package/dist/js/okta-sign-in.oie.min.js +1 -1
  17. package/package.json +10 -5
  18. package/src/config/config.json +1 -1
  19. package/src/v3/components/AuthCoin/AuthCoin.tsx +15 -17
  20. package/src/v3/components/AuthContainer/AuthContainer.tsx +11 -17
  21. package/src/v3/components/AuthContent/AuthContent.tsx +21 -16
  22. package/src/v3/components/AuthHeader/AuthHeader.tsx +18 -19
  23. package/src/v3/components/AuthenticatorButton/AuthenticatorButton.tsx +116 -77
  24. package/src/v3/components/AuthenticatorButton/AuthenticatorButtonList.tsx +9 -3
  25. package/src/v3/components/Button/Button.tsx +16 -20
  26. package/src/v3/components/CaptchaContainer/CaptchaContainer.tsx +1 -1
  27. package/src/v3/components/Checkbox/Checkbox.tsx +33 -82
  28. package/src/v3/components/ConsentHeader/ConsentHeader.tsx +23 -23
  29. package/src/v3/components/Divider/Divider.tsx +2 -2
  30. package/src/v3/components/Form/Accordion.tsx +15 -36
  31. package/src/v3/components/Form/ElementContainer.tsx +6 -3
  32. package/src/v3/components/Form/Form.tsx +2 -4
  33. package/src/v3/components/Form/Layout.tsx +1 -1
  34. package/src/v3/components/Form/LayoutContainer.tsx +4 -2
  35. package/src/v3/components/Heading/Heading.tsx +7 -5
  36. package/src/v3/components/Icon/CustomAppIcon.tsx +13 -15
  37. package/src/v3/components/Icon/CustomOTPIcon.tsx +5 -10
  38. package/src/v3/components/Icon/DuoIcon.tsx +5 -10
  39. package/src/v3/components/Icon/EmailIcon.tsx +5 -10
  40. package/src/v3/components/Icon/GoogleOTPIcon.tsx +5 -10
  41. package/src/v3/components/Icon/IDPIcon.tsx +5 -10
  42. package/src/v3/components/Icon/OktaVerifyIcon.tsx +0 -7
  43. package/src/v3/components/Icon/OnPremMFAIcon.tsx +5 -10
  44. package/src/v3/components/Icon/PasswordIcon.tsx +5 -10
  45. package/src/v3/components/Icon/PhoneIcon.tsx +5 -10
  46. package/src/v3/components/Icon/RSAIcon.tsx +6 -11
  47. package/src/v3/components/Icon/SecurityKeyOrBiometricsIcon.tsx +5 -10
  48. package/src/v3/components/Icon/SecurityQuestionIcon.tsx +5 -10
  49. package/src/v3/components/Icon/SmartCardIcon.tsx +5 -10
  50. package/src/v3/components/Icon/SymantecIcon.tsx +5 -10
  51. package/src/v3/components/Icon/YubiKeyIcon.tsx +5 -10
  52. package/src/v3/components/Icon/index.tsx +0 -2
  53. package/src/v3/components/IdentifierContainer/IdentifierContainer.tsx +31 -47
  54. package/src/v3/components/Image/Image.tsx +42 -0
  55. package/src/v3/{src/components/CustomPluginsOdysseyCacheProvider → components/Image}/index.tsx +2 -2
  56. package/src/v3/components/ImageWithText/ImageWithText.tsx +7 -4
  57. package/src/v3/components/Images/AppIcon.tsx +16 -46
  58. package/src/v3/components/Images/DeviceIcon.tsx +16 -32
  59. package/src/v3/components/Images/LocationIcon.tsx +16 -26
  60. package/src/v3/components/Images/PhoneIcon.tsx +34 -29
  61. package/src/v3/components/Images/YubikeyDemoImage.tsx +32 -27
  62. package/src/v3/components/Images/index.tsx +0 -1
  63. package/src/v3/components/InfoBox/InfoBox.tsx +12 -12
  64. package/src/v3/components/InfoSection/InfoSection.tsx +20 -14
  65. package/src/v3/components/InformationalText/InformationalText.tsx +16 -6
  66. package/src/v3/components/InputPassword/InputPassword.tsx +31 -164
  67. package/src/v3/components/InputText/InputText.tsx +27 -103
  68. package/src/v3/components/LaunchAuthenticatorButton/LaunchAuthenticatorButton.tsx +14 -26
  69. package/src/v3/components/Link/Link.tsx +8 -20
  70. package/src/v3/components/List/List.tsx +16 -12
  71. package/src/v3/components/PIVButton/PIVButton.tsx +10 -8
  72. package/src/v3/components/PasswordRequirements/Icon.tsx +17 -23
  73. package/src/v3/components/PasswordRequirements/PasswordMatches.tsx +9 -2
  74. package/src/v3/components/PasswordRequirements/PasswordRequirementListItem.tsx +6 -5
  75. package/src/v3/components/PasswordRequirements/PasswordRequirements.tsx +5 -3
  76. package/src/v3/components/PhoneAuthenticator/PhoneAuthenticator.tsx +53 -137
  77. package/src/v3/components/QRCode/QRCode.tsx +27 -20
  78. package/src/v3/components/Radio/Radio.tsx +31 -93
  79. package/src/v3/components/ReminderPrompt/ReminderPrompt.tsx +9 -12
  80. package/src/v3/components/Select/Select.tsx +45 -92
  81. package/src/v3/components/Spinner/Spinner.tsx +6 -8
  82. package/src/v3/components/StepperButton/StepperButton.tsx +6 -10
  83. package/src/v3/components/StepperLink/StepperLink.tsx +1 -1
  84. package/src/v3/components/StepperRadio/StepperRadio.tsx +22 -43
  85. package/src/v3/components/TextWithActionLink/TextWithActionLink.tsx +1 -1
  86. package/src/v3/components/Title/Title.tsx +5 -9
  87. package/src/v3/components/WebAuthNSubmitButton/WebAuthNSubmitButton.tsx +10 -9
  88. package/src/v3/components/Widget/GlobalStyles.tsx +16 -21
  89. package/src/v3/components/Widget/index.tsx +51 -36
  90. package/src/v3/components/Widget/style.scss +295 -0
  91. package/src/v3/components/WidgetMessageContainer/WidgetMessageContainer.tsx +11 -8
  92. package/src/v3/components/hocs/withFormValidationState.tsx +2 -5
  93. package/src/v3/jest.config.js +1 -0
  94. package/src/v3/jest.setup.js +1 -0
  95. package/src/v3/package.json +11 -7
  96. package/src/v3/screenshots/base/UI_demo/UI_demo_RTL_VRT.png +0 -0
  97. package/src/v3/screenshots/base/UI_demo/UI_demo_VRT.png +0 -0
  98. package/src/v3/src/components/AuthCoin/AuthCoin.tsx +15 -17
  99. package/src/v3/src/components/AuthCoin/__snapshots__/AuthCoin.test.tsx.snap +20 -47
  100. package/src/v3/src/components/AuthContainer/AuthContainer.tsx +11 -17
  101. package/src/v3/src/components/AuthContent/AuthContent.tsx +21 -16
  102. package/src/v3/src/components/AuthHeader/AuthHeader.tsx +18 -19
  103. package/src/v3/src/components/AuthenticatorButton/AuthenticatorButton.tsx +116 -77
  104. package/src/v3/src/components/AuthenticatorButton/AuthenticatorButtonList.tsx +9 -3
  105. package/src/v3/src/components/Button/Button.tsx +16 -20
  106. package/src/v3/src/components/CaptchaContainer/CaptchaContainer.tsx +1 -1
  107. package/src/v3/src/components/Checkbox/Checkbox.tsx +33 -82
  108. package/src/v3/src/components/ConsentHeader/ConsentHeader.tsx +23 -23
  109. package/src/v3/src/components/Divider/Divider.tsx +2 -2
  110. package/src/v3/src/components/Form/Accordion.tsx +15 -36
  111. package/src/v3/src/components/Form/ElementContainer.tsx +6 -3
  112. package/src/v3/src/components/Form/Form.tsx +2 -4
  113. package/src/v3/src/components/Form/Layout.tsx +1 -1
  114. package/src/v3/src/components/Form/LayoutContainer.tsx +4 -2
  115. package/src/v3/src/components/Heading/Heading.tsx +7 -5
  116. package/src/v3/src/components/Icon/CustomAppIcon.tsx +13 -15
  117. package/src/v3/src/components/Icon/CustomOTPIcon.tsx +5 -10
  118. package/src/v3/src/components/Icon/DuoIcon.tsx +5 -10
  119. package/src/v3/src/components/Icon/EmailIcon.tsx +5 -10
  120. package/src/v3/src/components/Icon/GoogleOTPIcon.tsx +5 -10
  121. package/src/v3/src/components/Icon/IDPIcon.tsx +5 -10
  122. package/src/v3/src/components/Icon/OktaVerifyIcon.tsx +0 -7
  123. package/src/v3/src/components/Icon/OnPremMFAIcon.tsx +5 -10
  124. package/src/v3/src/components/Icon/PasswordIcon.tsx +5 -10
  125. package/src/v3/src/components/Icon/PhoneIcon.tsx +5 -10
  126. package/src/v3/src/components/Icon/RSAIcon.tsx +6 -11
  127. package/src/v3/src/components/Icon/SecurityKeyOrBiometricsIcon.tsx +5 -10
  128. package/src/v3/src/components/Icon/SecurityQuestionIcon.tsx +5 -10
  129. package/src/v3/src/components/Icon/SmartCardIcon.tsx +5 -10
  130. package/src/v3/src/components/Icon/SymantecIcon.tsx +5 -10
  131. package/src/v3/src/components/Icon/YubiKeyIcon.tsx +5 -10
  132. package/src/v3/src/components/Icon/index.tsx +0 -2
  133. package/src/v3/src/components/IdentifierContainer/IdentifierContainer.tsx +31 -47
  134. package/src/v3/src/components/Image/Image.tsx +42 -0
  135. package/src/v3/{components/CustomPluginsOdysseyCacheProvider → src/components/Image}/index.tsx +2 -2
  136. package/src/v3/src/components/ImageWithText/ImageWithText.tsx +7 -4
  137. package/src/v3/src/components/Images/AppIcon.tsx +16 -46
  138. package/src/v3/src/components/Images/DeviceIcon.tsx +16 -32
  139. package/src/v3/src/components/Images/LocationIcon.tsx +16 -26
  140. package/src/v3/src/components/Images/PhoneIcon.tsx +34 -29
  141. package/src/v3/src/components/Images/YubikeyDemoImage.tsx +32 -27
  142. package/src/v3/src/components/Images/index.tsx +0 -1
  143. package/src/v3/src/components/InfoBox/InfoBox.tsx +12 -12
  144. package/src/v3/src/components/InfoSection/InfoSection.tsx +20 -14
  145. package/src/v3/src/components/InformationalText/InformationalText.tsx +16 -6
  146. package/src/v3/src/components/InputPassword/InputPassword.tsx +31 -164
  147. package/src/v3/src/components/InputText/InputText.tsx +27 -103
  148. package/src/v3/src/components/LaunchAuthenticatorButton/LaunchAuthenticatorButton.tsx +14 -26
  149. package/src/v3/src/components/Link/Link.tsx +8 -20
  150. package/src/v3/src/components/List/List.tsx +16 -12
  151. package/src/v3/src/components/PIVButton/PIVButton.tsx +10 -8
  152. package/src/v3/src/components/PasswordRequirements/Icon.tsx +17 -23
  153. package/src/v3/src/components/PasswordRequirements/PasswordMatches.tsx +9 -2
  154. package/src/v3/src/components/PasswordRequirements/PasswordRequirementListItem.tsx +6 -5
  155. package/src/v3/src/components/PasswordRequirements/PasswordRequirements.tsx +5 -3
  156. package/src/v3/src/components/PhoneAuthenticator/PhoneAuthenticator.tsx +53 -137
  157. package/src/v3/src/components/QRCode/QRCode.tsx +27 -20
  158. package/src/v3/src/components/Radio/Radio.tsx +31 -93
  159. package/src/v3/src/components/ReminderPrompt/ReminderPrompt.tsx +9 -12
  160. package/src/v3/src/components/ReminderPrompt/__snapshots__/ReminderPrompt.test.tsx.snap +37 -17
  161. package/src/v3/src/components/Select/Select.tsx +45 -92
  162. package/src/v3/src/components/Spinner/Spinner.tsx +6 -8
  163. package/src/v3/src/components/StepperButton/StepperButton.tsx +6 -10
  164. package/src/v3/src/components/StepperLink/StepperLink.tsx +1 -1
  165. package/src/v3/src/components/StepperRadio/StepperRadio.tsx +22 -43
  166. package/src/v3/src/components/TextWithActionLink/TextWithActionLink.tsx +1 -1
  167. package/src/v3/src/components/Title/Title.tsx +5 -9
  168. package/src/v3/src/components/WebAuthNSubmitButton/WebAuthNSubmitButton.tsx +10 -9
  169. package/src/v3/src/components/Widget/GlobalStyles.tsx +16 -21
  170. package/src/v3/src/components/Widget/index.tsx +51 -36
  171. package/src/v3/src/components/Widget/style.scss +295 -0
  172. package/src/v3/src/components/WidgetMessageContainer/WidgetMessageContainer.tsx +11 -8
  173. package/src/v3/src/components/hocs/withFormValidationState.tsx +2 -5
  174. package/src/v3/src/transformer/button/__snapshots__/transformIDPButtons.test.ts.snap +0 -2
  175. package/src/v3/src/transformer/i18n/__snapshots__/transformAuthenticatorButton.test.ts.snap +4 -4
  176. package/src/v3/src/transformer/i18n/transformAuthenticatorButton.test.ts +3 -3
  177. package/src/v3/src/transformer/i18n/transformAuthenticatorButton.ts +18 -2
  178. package/src/v3/src/transformer/layout/development/transformEnumerateComponents.ts +72 -5
  179. package/src/v3/src/transformer/layout/idp/__snapshots__/transformIdpRedirect.test.ts.snap +4 -4
  180. package/src/v3/src/transformer/selectAuthenticator/__snapshots__/transformSelectAuthenticatorVerify.test.ts.snap +0 -3
  181. package/src/v3/src/transformer/selectAuthenticator/__snapshots__/transformSelectOVCustomAppMethodVerify.test.ts.snap +0 -1
  182. package/src/v3/src/transformer/selectAuthenticator/__snapshots__/utils.test.ts.snap +163 -42
  183. package/src/v3/src/transformer/selectAuthenticator/transformSelectAuthenticatorEnroll.ts +7 -1
  184. package/src/v3/src/transformer/selectAuthenticator/transformSelectAuthenticatorVerify.ts +0 -1
  185. package/src/v3/src/transformer/selectAuthenticator/transformSelectOVCustomAppMethodVerify.ts +0 -1
  186. package/src/v3/src/transformer/selectAuthenticator/utils.test.ts +117 -39
  187. package/src/v3/src/transformer/selectAuthenticator/utils.ts +102 -58
  188. package/src/v3/src/transformer/terminal/transformEmailMagicLinkOTPOnlyElements.ts +1 -3
  189. package/src/v3/src/transformer/uischema/transform.test.ts +0 -6
  190. package/src/v3/src/transformer/uischema/transform.ts +0 -2
  191. package/src/v3/src/{components/FieldLevelMessageContainer/index.tsx → types/image.ts} +10 -3
  192. package/src/v3/src/types/index.ts +1 -0
  193. package/src/v3/src/types/schema.ts +2 -1
  194. package/src/v3/src/types/widget.ts +3 -3
  195. package/src/v3/src/util/buildFieldLevelErrorMessages.ts +48 -0
  196. package/src/v3/src/util/formUtils.ts +5 -17
  197. package/src/v3/src/util/htmlContentParserUtils.tsx +3 -1
  198. package/src/v3/src/util/index.ts +2 -0
  199. package/src/v3/src/util/isLtrField.ts +22 -0
  200. package/src/v3/src/util/languageUtils.ts +14 -0
  201. package/src/v3/src/util/leonardo.d.ts +571 -0
  202. package/src/v3/src/util/mergeThemes.test.tsx +20 -7
  203. package/src/v3/src/util/mergeThemes.ts +32 -1
  204. package/src/v3/src/util/stylisPlugins.ts +21 -0
  205. package/src/v3/src/util/theme.test.ts +63 -187
  206. package/src/v3/src/util/theme.ts +274 -247
  207. package/src/v3/svgo.config.js +0 -6
  208. package/src/v3/transformer/i18n/transformAuthenticatorButton.ts +18 -2
  209. package/src/v3/transformer/layout/development/transformEnumerateComponents.ts +72 -5
  210. package/src/v3/transformer/selectAuthenticator/transformSelectAuthenticatorEnroll.ts +7 -1
  211. package/src/v3/transformer/selectAuthenticator/transformSelectAuthenticatorVerify.ts +0 -1
  212. package/src/v3/transformer/selectAuthenticator/transformSelectOVCustomAppMethodVerify.ts +0 -1
  213. package/src/v3/transformer/selectAuthenticator/utils.ts +102 -58
  214. package/src/v3/transformer/terminal/transformEmailMagicLinkOTPOnlyElements.ts +1 -3
  215. package/src/v3/transformer/uischema/transform.ts +0 -2
  216. package/src/v3/tsconfig.base.json +3 -0
  217. package/src/v3/{components/FieldLevelMessageContainer/index.tsx → types/image.ts} +10 -3
  218. package/src/v3/types/index.ts +1 -0
  219. package/src/v3/types/schema.ts +2 -1
  220. package/src/v3/types/widget.ts +3 -3
  221. package/src/v3/util/buildFieldLevelErrorMessages.ts +48 -0
  222. package/src/v3/util/formUtils.ts +5 -17
  223. package/src/v3/util/htmlContentParserUtils.tsx +3 -1
  224. package/src/v3/util/index.ts +2 -0
  225. package/src/v3/util/isLtrField.ts +22 -0
  226. package/src/v3/util/languageUtils.ts +14 -0
  227. package/src/v3/util/leonardo.d.ts +571 -0
  228. package/src/v3/util/mergeThemes.ts +32 -1
  229. package/src/v3/util/stylisPlugins.ts +21 -0
  230. package/src/v3/util/theme.ts +274 -247
  231. package/src/v3/components/CustomPluginsOdysseyCacheProvider/CustomPluginsOdysseyCacheProvider.tsx +0 -66
  232. package/src/v3/components/FieldLevelMessageContainer/FieldLevelMessageContainer.tsx +0 -55
  233. package/src/v3/components/Icon/CheckCircle.tsx +0 -30
  234. package/src/v3/components/Icon/RightArrowIcon.tsx +0 -30
  235. package/src/v3/components/Images/MobileDeviceIcon.tsx +0 -38
  236. package/src/v3/components/Widget/style.css +0 -181
  237. package/src/v3/src/components/CustomPluginsOdysseyCacheProvider/CustomPluginsOdysseyCacheProvider.tsx +0 -66
  238. package/src/v3/src/components/FieldLevelMessageContainer/FieldLevelMessageContainer.tsx +0 -55
  239. package/src/v3/src/components/Icon/CheckCircle.tsx +0 -30
  240. package/src/v3/src/components/Icon/RightArrowIcon.tsx +0 -30
  241. package/src/v3/src/components/Images/MobileDeviceIcon.tsx +0 -38
  242. package/src/v3/src/components/Widget/style.css +0 -181
  243. package/src/v3/src/transformer/uischema/setLtrFields.ts +0 -41
  244. package/src/v3/src/util/designTokens.ts +0 -249
  245. package/src/v3/transformer/uischema/setLtrFields.ts +0 -41
  246. package/src/v3/util/designTokens.ts +0 -249
@@ -10,218 +10,94 @@
10
10
  * See the License for the specific language governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- import { odysseyTheme } from '@okta/odyssey-react-mui';
13
+ import * as Tokens from '@okta/odyssey-design-tokens';
14
14
  import chroma from 'chroma-js';
15
- import { get } from 'lodash';
16
15
 
17
- import { createTheme, generatePalette } from './theme';
16
+ import { createThemeAndTokens, generatePalette } from './theme';
17
+
18
+ const WHITE_HEX = '#ffffff';
19
+ // Odyssey-defined contrast ratios for their WCAG-friendly palettes
20
+ const ODYSSEY_RATIOS = [1.1, 1.31, 1.61, 2.22, 3.32, 4.5, 4.95, 8.72, 11.73, 14.94];
18
21
 
19
22
  describe('theme utilities', () => {
20
23
  describe('generatePalette', () => {
21
- it('for light primary color', () => {
22
- const palette = generatePalette('#cc0000');
23
- expect(palette).toBeDefined();
24
- expect(palette?.main).toBe('#cc0000');
25
- expect(palette?.light).toBe('#f28f78');
26
- expect(palette?.lighter).toBe('#fff1f0');
27
- expect(palette?.dark).toBe('#640000');
28
- expect(palette?.contrastText).toBe('#ffffff');
29
- });
30
-
31
- it('for light primary color with poor contrast against white', () => {
32
- const palette = generatePalette('#6666ff');
33
- expect(palette).toBeDefined();
34
- expect(palette?.contrastText).toBe('#1d1d21');
35
- });
36
-
37
- it('for light primary color with clamped primaryColorLight', () => {
38
- const colorWithLightness60 = chroma.hsl(100, 1, 0.6);
39
- const palette = generatePalette(colorWithLightness60.hex());
40
-
24
+ it('generates a palette with Odyssey contrast ratios', () => {
25
+ const palette = generatePalette('#546Be7');
41
26
  expect(palette).toBeDefined();
42
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
43
- const derivedPrimaryColorLight = chroma(palette.light!);
44
- expect(derivedPrimaryColorLight.get('hsl.l')).toBeCloseTo(0.90, 2);
45
- });
46
-
47
- it('generates a derived theme for dark primary color', () => {
48
- const palette = generatePalette('#170f5f');
49
- expect(palette).toBeDefined();
50
- expect(palette?.main).toBe('#170f5f');
51
- expect(palette?.light).toBe('#bdb7f4');
52
- expect(palette?.lighter).toBe('#f4f0fe');
53
- expect(palette?.dark).toBe('#402ede');
54
- expect(palette?.contrastText).toBe('#ffffff');
27
+ expect(Object.keys(palette!).length).toBe(10);
28
+ const contrastRatios = Object.values(palette!).map((hue) => chroma.contrast(hue, WHITE_HEX));
29
+ // Precision of 0.5 maps to 0.2 as an allowed deviation to account for differences between
30
+ // chroma.contrast() and Leonardo's calculations
31
+ contrastRatios.forEach((ratio, i) => expect(ratio).toBeCloseTo(ODYSSEY_RATIOS[i], 0.5));
55
32
  });
56
33
 
57
34
  it('returns null for invalid colors', () => {
58
35
  // suppress warnings from when chroma-js throws
59
36
  jest.spyOn(console, 'warn').mockImplementation(() => { });
60
37
 
61
- expect(generatePalette('#12345')).toEqual({});
62
- expect(generatePalette('#ff00gg')).toEqual({});
63
- expect(generatePalette('')).toEqual({});
38
+ expect(generatePalette('#12345')).toBeNull();
39
+ expect(generatePalette('#ff00gg')).toBeNull();
40
+ expect(generatePalette('')).toBeNull();
64
41
 
65
42
  jest.restoreAllMocks();
66
43
  });
67
44
  });
68
45
 
69
- describe('createTheme', () => {
70
- it('should use brandColors.primaryColor to set theme.palette.primary.*', () => {
46
+ describe('createThemeAndTokens', () => {
47
+ // Explicitly construct OD 1.x palette because odyssey-react-mui palette's 'dark' is
48
+ // different than Tokens.PalettePrimaryDark
49
+ const defaultOdyPrimaryPalette = {
50
+ main: Tokens.PalettePrimaryMain,
51
+ light: Tokens.PalettePrimaryLight,
52
+ lighter: Tokens.PalettePrimaryLighter,
53
+ dark: Tokens.HueBlue900,
54
+ contrastText: Tokens.TypographyColorInverse,
55
+ };
56
+
57
+ it('should use brandColors.primaryColor to set PalettePrimary.* tokens', () => {
71
58
  const primaryColor = '#7950f2';
72
59
  const palette = generatePalette(primaryColor);
73
- const theme = createTheme({ primaryColor });
74
- expect(theme.palette?.primary).toEqual(palette);
60
+ const { tokensOverride: tokens } = createThemeAndTokens({ primaryColor });
61
+ // Pick a subset of the overridden primary-related design tokens to assert on
62
+ expect(tokens.PalettePrimaryMain).toEqual(palette?.CustomHue500);
63
+ expect(tokens.PalettePrimaryDark).toEqual(palette?.CustomHue700);
64
+ expect(tokens.TypographyColorAction).toEqual(palette?.CustomHue600);
75
65
  });
76
- it('should ignore brandColors if undefined', () => {
77
- const theme = createTheme();
78
- expect(theme.palette?.primary).toEqual(odysseyTheme.palette.primary);
66
+
67
+ it('should ignore brandColors if undefined and use default Odyssey theme', () => {
68
+ const { themeOverride: theme } = createThemeAndTokens();
69
+ expect(theme.palette?.primary).toEqual(defaultOdyPrimaryPalette);
79
70
  });
71
+
80
72
  it('should ignore brandColors.primaryColor if invalid', () => {
81
- // suppress warnings from when chroma-js throws
73
+ // suppress warnings from when @adobe/leonardo-contrast-color throws
82
74
  jest.spyOn(console, 'warn').mockImplementation(() => { });
83
75
  const primaryColor = '#invalid';
84
- const theme = createTheme({ primaryColor });
85
- expect(theme.palette?.primary).toEqual(odysseyTheme.palette.primary);
86
- });
87
- it('should use PalettePrimaryMain to set theme.palette.primary.*', () => {
88
- const PalettePrimaryMain = '#7950f2';
89
- const palette = generatePalette(PalettePrimaryMain);
90
- const theme = createTheme(undefined, { PalettePrimaryMain });
91
- expect(theme.palette?.primary).toEqual(palette);
92
- });
93
-
94
- it('should use PaletteDangerMain to set theme.palette.error.*', () => {
95
- const PaletteDangerMain = '#e72500';
96
- const palette = generatePalette(PaletteDangerMain);
97
- const theme = createTheme(undefined, { PaletteDangerMain });
98
- expect(theme.palette?.error).toEqual(palette);
99
- });
100
-
101
- it('should use PaletteWarningMain to set theme.palette.warning.*', () => {
102
- const PaletteWarningMain = '#a16c03';
103
- const palette = generatePalette(PaletteWarningMain);
104
- const theme = createTheme(undefined, { PaletteWarningMain });
105
- expect(theme.palette?.warning).toEqual(palette);
106
- });
107
-
108
- it('should use PaletteSuccessMain to set theme.palette.success.*', () => {
109
- const PaletteSuccessMain = '#16884a';
110
- const palette = generatePalette(PaletteSuccessMain);
111
- const theme = createTheme(undefined, { PaletteSuccessMain });
112
- expect(theme.palette?.success).toEqual(palette);
113
- });
114
-
115
- describe('should apply design tokens -> theme properties', () => {
116
- test.each([
117
- ['BorderRadiusMain', 'mixins.borderRadius', 'TEST_0'],
118
- ['BorderStyleMain', 'mixins.borderStyle', 'TEST_1'],
119
- ['BorderWidthMain', 'mixins.borderWidth', 'TEST_2'],
120
- ['TypographyColorDisabled', 'palette.text.disabled', 'TEST_3'],
121
- ['TypographyColorBody', 'palette.text.primary', 'TEST_4'],
122
- ['ShadowScale0', 'shadows[1]', 'TEST_5'],
123
- ['ShadowScale1', 'shadows[2]', 'TEST_6'],
124
- ['TypographyFamilyBody', 'typography.body1.fontFamily', 'TEST_7'],
125
- ['TypographySizeBody', 'typography.body1.fontSize', 'TEST_8'],
126
- ['TypographyStyleNormal', 'typography.body1.fontStyle', 'TEST_9'],
127
- ['TypographyLineHeightBody', 'typography.body1.lineHeight', 'TEST_10'],
128
- ['TypographyFamilyButton', 'typography.button.fontFamily', 'TEST_11'],
129
- ['TypographyColorSubordinate', 'typography.caption.color', 'TEST_12'],
130
- ['TypographyFamilyBody', 'typography.caption.fontFamily', 'TEST_13'],
131
- ['TypographySizeSubordinate', 'typography.caption.fontSize', 'TEST_14'],
132
- ['TypographyFamilyBody', 'typography.fontFamily', 'TEST_15'],
133
- ['TypographyWeightBodyBold', 'typography.fontWeightBold', 'TEST_16'],
134
- ['TypographyWeightBody', 'typography.fontWeightRegular', 'TEST_17'],
135
- ['TypographyColorHeading', 'typography.h1.color', 'TEST_18'],
136
- ['TypographyFamilyHeading', 'typography.h1.fontFamily', 'TEST_19'],
137
- ['TypographySizeHeading1', 'typography.h1.fontSize', 'TEST_20'],
138
- ['TypographyWeightHeading', 'typography.h1.fontWeight', 'TEST_21'],
139
- ['TypographyLineHeightHeading1', 'typography.h1.lineHeight', 'TEST_22'],
140
- ['TypographyColorHeading', 'typography.h2.color', 'TEST_23'],
141
- ['TypographyFamilyHeading', 'typography.h2.fontFamily', 'TEST_24'],
142
- ['TypographySizeHeading2', 'typography.h2.fontSize', 'TEST_25'],
143
- ['TypographyWeightHeading', 'typography.h2.fontWeight', 'TEST_26'],
144
- ['TypographyLineHeightHeading2', 'typography.h2.lineHeight', 'TEST_27'],
145
- ['TypographyColorHeading', 'typography.h3.color', 'TEST_28'],
146
- ['TypographyFamilyHeading', 'typography.h3.fontFamily', 'TEST_29'],
147
- ['TypographySizeHeading3', 'typography.h3.fontSize', 'TEST_30'],
148
- ['TypographyWeightHeading', 'typography.h3.fontWeight', 'TEST_31'],
149
- ['TypographyLineHeightHeading3', 'typography.h3.lineHeight', 'TEST_32'],
150
- ['TypographyColorHeading', 'typography.h4.color', 'TEST_33'],
151
- ['TypographyFamilyHeading', 'typography.h4.fontFamily', 'TEST_34'],
152
- ['TypographySizeHeading4', 'typography.h4.fontSize', 'TEST_35'],
153
- ['TypographyWeightHeading', 'typography.h4.fontWeight', 'TEST_36'],
154
- ['TypographyLineHeightHeading4', 'typography.h4.lineHeight', 'TEST_37'],
155
- ['TypographyColorHeading', 'typography.h5.color', 'TEST_38'],
156
- ['TypographyFamilyHeading', 'typography.h5.fontFamily', 'TEST_39'],
157
- ['TypographySizeHeading5', 'typography.h5.fontSize', 'TEST_40'],
158
- ['TypographyWeightHeading', 'typography.h5.fontWeight', 'TEST_41'],
159
- ['TypographyLineHeightHeading5', 'typography.h5.lineHeight', 'TEST_42'],
160
- ['TypographyColorHeading', 'typography.h6.color', 'TEST_43'],
161
- ['TypographyFamilyHeading', 'typography.h6.fontFamily', 'TEST_44'],
162
- ['TypographySizeHeading6', 'typography.h6.fontSize', 'TEST_45'],
163
- ['TypographyWeightHeading', 'typography.h6.fontWeight', 'TEST_46'],
164
- ['TypographyLineHeightHeading6', 'typography.h6.lineHeight', 'TEST_47'],
165
- ['TypographyLineHeightOverline', 'typography.overline.lineHeight', 'TEST_48'],
166
- ['TypographyFamilyBody', 'typography.subtitle1.fontFamily', 'TEST_49'],
167
- ['TypographyFamilyBody', 'typography.subtitle2.fontFamily', 'TEST_50'],
168
- ])('%s -> %s', (name, path, value) => {
169
- const theme = createTheme(undefined, { [name]: value });
170
- expect(get(theme, path)).toEqual(value);
171
- });
172
- });
173
-
174
- it('should use Spacing0..Spacing9 tokens to set the theme.spacing function', () => {
175
- const theme = createTheme(undefined, {
176
- Spacing0: '0ex',
177
- Spacing1: '2ex',
178
- Spacing2: '4ex',
179
- Spacing3: '6ex',
180
- Spacing4: '8ex',
181
- Spacing5: '10ex',
182
- Spacing6: '12ex',
183
- Spacing7: '14ex',
184
- Spacing8: '16ex',
185
- Spacing9: '18ex',
186
- });
187
- expect(typeof theme.spacing).toBe('function');
188
-
189
- if (typeof theme.spacing !== 'function') {
190
- throw new Error('theme.spacing should be a function');
191
- }
192
- expect(theme.spacing(0)).toBe('0ex');
193
- expect(theme.spacing(1)).toBe('2ex');
194
- expect(theme.spacing(2)).toBe('4ex');
195
- expect(theme.spacing(3)).toBe('6ex');
196
- expect(theme.spacing(4)).toBe('8ex');
197
- expect(theme.spacing(5)).toBe('10ex');
198
- expect(theme.spacing(6)).toBe('12ex');
199
- expect(theme.spacing(7)).toBe('14ex');
200
- expect(theme.spacing(8)).toBe('16ex');
201
- expect(theme.spacing(9)).toBe('18ex');
202
- });
203
-
204
- test('theme.tokens.PalettePrimaryMain overrides brandColors.primaryColor', () => {
205
- const theme = createTheme({ primaryColor: '#aaa' }, { PalettePrimaryMain: '#bbb' });
206
- // @ts-expect-error Property PaletteColorOptions is a union
207
- expect(theme.palette?.primary?.main).toEqual('#bbb');
208
- });
209
-
210
- test('tokens should override generated palette colors', () => {
211
- const tokens = {
212
- PalettePrimaryLight: '#77216F',
213
- PalettePrimaryMain: '#5E2750',
214
- PalettePrimaryDark: '#2C001E',
76
+ const { themeOverride: theme } = createThemeAndTokens({ primaryColor });
77
+ expect(theme.palette?.primary).toEqual(defaultOdyPrimaryPalette);
78
+ });
79
+
80
+ it('should not set palette tokens generated by brandColors for design tokens that are already set', () => {
81
+ // #ff3d3d is a bright red, #7950f2 is a bright purple
82
+ const { tokensOverride: tokens } = createThemeAndTokens({ primaryColor: '#ff3d3d' }, { PalettePrimaryMain: '#7950f2' });
83
+ // PalettePrimaryMain should be #7950f2 since it is specifically overridden but the remainder
84
+ // of the palette tokens should be red hues
85
+ expect(tokens.PalettePrimaryMain).toEqual('#7950f2');
86
+ // #8e2222 is a medium red hue
87
+ expect(tokens.PalettePrimaryDark).toEqual('#8e2222');
88
+ // #fff0f0 is a very pale red
89
+ expect(tokens.PalettePrimaryLighter).toEqual('#fff0f0');
90
+ });
91
+
92
+ it('should override non-palette Odyssey default theme values with custom tokens', () => {
93
+ const customTokens = {
94
+ BorderRadiusMain: '1rem',
95
+ TypographyColorHeading: '#77216f',
215
96
  };
216
- const palette = generatePalette('#5E2750');
217
- const theme = createTheme(undefined, tokens);
218
- expect(theme.palette?.primary).toEqual({
219
- lighter: palette.lighter, // generated
220
- light: tokens.PalettePrimaryLight, // provided
221
- main: tokens.PalettePrimaryMain, // provided
222
- dark: tokens.PalettePrimaryDark, // provided
223
- contrastText: palette.contrastText, // generated
224
- });
97
+ const { themeOverride: theme } = createThemeAndTokens(undefined, customTokens);
98
+ expect(theme.mixins?.borderRadius).toEqual(customTokens.BorderRadiusMain);
99
+ // @ts-expect-error Odyssey theme sets heading colors by default
100
+ expect(theme.typography?.h1.color).toEqual(customTokens.TypographyColorHeading);
225
101
  });
226
102
  });
227
103
  });