@comicrelief/component-library 5.4.0 → 5.7.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 (85) hide show
  1. package/.circleci/config.yml +1 -1
  2. package/dist/components/Atoms/Button/Button.js +3 -1
  3. package/dist/components/Atoms/ButtonWithStates/ButtonWithStates.js +91 -0
  4. package/dist/components/Atoms/ButtonWithStates/ButtonWithStates.md +13 -0
  5. package/dist/components/Atoms/Checkbox/Checkbox.js +5 -3
  6. package/dist/components/Atoms/ErrorText/ErrorText.js +3 -1
  7. package/dist/components/Atoms/Icons/Arrow.js +3 -1
  8. package/dist/components/Atoms/Icons/AtSign.js +2 -1
  9. package/dist/components/Atoms/Icons/Chevron.js +3 -1
  10. package/dist/components/Atoms/Icons/Download.js +3 -1
  11. package/dist/components/Atoms/Icons/External.js +3 -1
  12. package/dist/components/Atoms/Icons/Favourite.js +3 -1
  13. package/dist/components/Atoms/Icons/Internal.js +3 -1
  14. package/dist/components/Atoms/Input/Input.js +6 -4
  15. package/dist/components/Atoms/Label/Label.js +5 -2
  16. package/dist/components/Atoms/Link/Link.js +31 -6
  17. package/dist/components/Atoms/Link/Link.style.js +3 -3
  18. package/dist/components/Atoms/Pagination/Item/Item.js +3 -1
  19. package/dist/components/Atoms/Pagination/List/List.js +5 -3
  20. package/dist/components/Atoms/Pagination/Pagination.js +3 -1
  21. package/dist/components/Atoms/Picture/Picture.js +3 -1
  22. package/dist/components/Atoms/RadioButton/RadioButton.js +3 -1
  23. package/dist/components/Atoms/RichText/RichText.js +4 -2
  24. package/dist/components/Atoms/Select/Select.js +3 -1
  25. package/dist/components/Atoms/SocialIcons/Icon/Icon.js +6 -4
  26. package/dist/components/Atoms/SocialIcons/SocialIcons.js +5 -3
  27. package/dist/components/Atoms/Text/Text.js +3 -1
  28. package/dist/components/Atoms/TextArea/TextArea.js +3 -1
  29. package/dist/components/Atoms/TextInputWithDropdown/TextInputWithDropdown.js +5 -2
  30. package/dist/components/Molecules/Accordion/Accordion.js +3 -1
  31. package/dist/components/Molecules/Box/Box.js +3 -1
  32. package/dist/components/Molecules/Card/Card.js +3 -1
  33. package/dist/components/Molecules/CardDs/CardDs.js +8 -6
  34. package/dist/components/Molecules/Countdown/Countdown.style.js +2 -2
  35. package/dist/components/Molecules/HeroBanner/HeroBanner.js +3 -3
  36. package/dist/components/Molecules/Lookup/Lookup.js +201 -0
  37. package/dist/components/Molecules/PartnerLink/PartnerLink.js +3 -1
  38. package/dist/components/Molecules/Promo/Promo.style.js +4 -4
  39. package/dist/components/Molecules/SchoolLookup/SchoolLookup.js +3 -1
  40. package/dist/components/Molecules/SearchInput/SearchInput.js +3 -1
  41. package/dist/components/Molecules/SearchResult/SearchResult.js +5 -5
  42. package/dist/components/Molecules/ShareButton/ShareButton.js +3 -1
  43. package/dist/components/Molecules/SimpleSchoolLookup/SimpleSchoolLookup.js +112 -0
  44. package/dist/components/Molecules/SimpleSchoolLookup/SimpleSchoolLookup.md +7 -0
  45. package/dist/components/Molecules/SingleMessage/SingleMessage.js +1 -1
  46. package/dist/components/Molecules/SingleMessage/__snapshots__/SingleMessage.test.js.snap +8 -0
  47. package/dist/components/Molecules/SingleMessageDS/SingleMessageDs.js +3 -1
  48. package/dist/components/Molecules/SingleMessageDS/SingleMessageDs.style.js +9 -9
  49. package/dist/components/Molecules/Typeahead/Typeahead.js +3 -1
  50. package/dist/components/Molecules/VideoBanner/VideoBanner.js +1 -1
  51. package/dist/components/Organisms/CookieBanner/CookieBanner.style.js +4 -4
  52. package/dist/components/Organisms/Donate/Form/Form.js +3 -1
  53. package/dist/components/Organisms/Donate/GivingSelector/GivingSelector.js +4 -4
  54. package/dist/components/Organisms/Donate/MoneyBox/MoneyBox.js +3 -1
  55. package/dist/components/Organisms/EmailSignUp/EmailSignUp.js +3 -1
  56. package/dist/components/Organisms/EmailSignUp/EmailSignUp.style.js +7 -7
  57. package/dist/components/Organisms/Footer/Footer.js +7 -4
  58. package/dist/components/Organisms/Footer/Footer.md +8 -1
  59. package/dist/components/Organisms/Footer/Nav/Nav.js +12 -7
  60. package/dist/components/Organisms/Footer/Nav/Nav.style.js +8 -8
  61. package/dist/components/Organisms/Footer/__snapshots__/Footer.test.js.snap +31 -6
  62. package/dist/components/Organisms/Header/Burger/BurgerMenu.style.js +3 -3
  63. package/dist/components/Organisms/Header/Header.js +3 -1
  64. package/dist/components/Organisms/Header/Nav/Nav.js +3 -3
  65. package/dist/components/Organisms/MarketingPreferencesDS/_TextInput.js +3 -1
  66. package/dist/components/Organisms/Membership/Form/Form.js +3 -1
  67. package/dist/components/Organisms/Membership/MoneyBox/MoneyBox.js +3 -1
  68. package/dist/index.js +24 -0
  69. package/dist/utils/internalLinkHelper.js +27 -5
  70. package/package.json +14 -13
  71. package/src/components/Atoms/ButtonWithStates/ButtonWithStates.js +64 -0
  72. package/src/components/Atoms/ButtonWithStates/ButtonWithStates.md +13 -0
  73. package/src/components/Atoms/Link/Link.js +23 -8
  74. package/src/components/Molecules/Lookup/Lookup.js +148 -0
  75. package/src/components/Molecules/SimpleSchoolLookup/SimpleSchoolLookup.js +63 -0
  76. package/src/components/Molecules/SimpleSchoolLookup/SimpleSchoolLookup.md +7 -0
  77. package/src/components/Molecules/SingleMessage/SingleMessage.js +1 -1
  78. package/src/components/Molecules/SingleMessage/__snapshots__/SingleMessage.test.js.snap +8 -0
  79. package/src/components/Organisms/Footer/Footer.js +5 -3
  80. package/src/components/Organisms/Footer/Footer.md +8 -1
  81. package/src/components/Organisms/Footer/Nav/Nav.js +4 -3
  82. package/src/components/Organisms/Footer/__snapshots__/Footer.test.js.snap +31 -6
  83. package/src/components/Organisms/Header/Nav/Nav.js +1 -1
  84. package/src/index.js +3 -0
  85. package/src/utils/internalLinkHelper.js +23 -5
@@ -1,12 +1,9 @@
1
- import React from 'react';
1
+ import React, { useEffect, useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
 
4
4
  import StyledLink, { HelperText, IconWrapper } from './Link.style';
5
5
  import whiteListed from '../../../utils/whiteListed';
6
-
7
- const domainRegEx = new RegExp(
8
- '(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]'
9
- );
6
+ import { getDomain } from '../../../utils/internalLinkHelper';
10
7
 
11
8
  let window = '';
12
9
 
@@ -22,19 +19,37 @@ const Link = ({
22
19
  iconFirst,
23
20
  ...rest
24
21
  }) => {
22
+ const [documentHost, setDocumentHost] = useState('');
25
23
  /**
26
24
  * If we haven't specifically set the target via props, check if
27
25
  * this is an internal link OR on our whitelist before making it a '_self' link
28
26
  */
29
27
  if (target === null) {
30
- const isExternalLink = domainRegEx.test(href);
28
+ // Use our helper function to determine the raw domains to compare
29
+ const currentDomain = getDomain(documentHost);
30
+ const linkDomain = getDomain(href);
31
+
32
+ // Additional check for applications that need more control
33
+ const isWhiteListOverridden = rest.overrideWhiteList === true;
34
+
35
+ /**
36
+ * If the link has no domain supplied (likely '/' or '#')
37
+ * OR has the same domain as the current page, don't open
38
+ * in a new tab
39
+ */
40
+ const isExternalLink = linkDomain !== '' && (currentDomain !== linkDomain);
31
41
  const isWhiteListed = whiteListed(href);
32
- window = !isExternalLink || isWhiteListed ? '_self' : '_blank';
42
+
43
+ window = isExternalLink && (isWhiteListOverridden || !isWhiteListed) ? '_blank' : '_self';
33
44
  } else {
34
45
  window = target === 'blank' ? '_blank' : '_self';
35
46
  }
36
47
  const hasIcon = icon !== null;
37
48
 
49
+ useEffect(() => {
50
+ setDocumentHost(document.location.host);
51
+ }, []);
52
+
38
53
  return (
39
54
  <StyledLink
40
55
  {...rest}
@@ -46,7 +61,7 @@ const Link = ({
46
61
  underline={underline}
47
62
  >
48
63
  {children}
49
- {target === 'blank' && <HelperText>(opens in new window)</HelperText>}
64
+ {window === '_blank' && <HelperText>(opens in new window)</HelperText>}
50
65
  {hasIcon && <IconWrapper type={type}>{icon}</IconWrapper>}
51
66
  </StyledLink>
52
67
  );
@@ -0,0 +1,148 @@
1
+ import React, { useCallback, useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import styled, { css } from 'styled-components';
4
+ import TextInputWithDropdown from '../../Atoms/TextInputWithDropdown/TextInputWithDropdown';
5
+ import spacing from '../../../theme/shared/spacing';
6
+ import ButtonWithStates from '../../Atoms/ButtonWithStates/ButtonWithStates';
7
+
8
+ const StyledButton = styled(ButtonWithStates)`${({ theme }) => css`
9
+ color: ${theme.color('grey_dark')};
10
+ border: 2px solid ${theme.color('grey_dark')};
11
+ background-color: ${theme.color('white')};
12
+ padding-left: ${spacing('lg')};
13
+ padding-right: ${spacing('lg')};
14
+
15
+ &:hover {
16
+ color: ${theme.color('grey_dark')};
17
+ background-color: ${theme.color('white')};
18
+ }
19
+ `}`;
20
+
21
+ const KEY_CODE_ENTER = 13;
22
+
23
+ /**
24
+ * A simple lookup component
25
+ *
26
+ * The `lookupHandler` should be an async function which is called when a lookup is triggered
27
+ * (either by hitting enter or clicking the button)
28
+ *
29
+ * It will receive the current search term and should:
30
+ * - take care of any validation on the search term
31
+ * - perform the actual lookup request
32
+ * - return an array of options (or an empty array if none were found)
33
+ * - only throw errors with user-friendly messages
34
+ *
35
+ * Any errors thrown will be caught and the message will be displayed to the user.
36
+ *
37
+ * The `onSelect` function will receive the chosen option.
38
+ *
39
+ * @param name
40
+ * @param label
41
+ * @param placeholder
42
+ * @param buttonText
43
+ * @param lookupHandler
44
+ * @param mapOptionToString
45
+ * @param onSelect
46
+ * @param noResultsMessage
47
+ * @param dropdownInstruction
48
+ * @param rest
49
+ * @returns {JSX.Element}
50
+ * @constructor
51
+ */
52
+ const Lookup = ({
53
+ name,
54
+ label,
55
+ placeholder,
56
+ buttonText,
57
+ lookupHandler,
58
+ mapOptionToString,
59
+ onSelect,
60
+ noResultsMessage,
61
+ dropdownInstruction,
62
+ ...rest
63
+ }) => {
64
+ const [query, setQuery] = useState('');
65
+ const [errorMessage, setErrorMessage] = useState('');
66
+ const [options, setOptions] = useState([]);
67
+ const [isSearching, setIsSearching] = useState(false);
68
+
69
+ const handler = useCallback(async () => {
70
+ setErrorMessage('');
71
+ setIsSearching(true);
72
+ try {
73
+ // If lookupHandler throws an error, the message will be displayed to the user
74
+ const results = await lookupHandler(query);
75
+ setOptions(results);
76
+ if (results.length === 0) {
77
+ setErrorMessage(noResultsMessage);
78
+ }
79
+ } catch (error) {
80
+ setErrorMessage(error.message);
81
+ }
82
+ setIsSearching(false);
83
+ }, [query, setOptions, setErrorMessage, noResultsMessage, lookupHandler]);
84
+
85
+ return (
86
+ <div {...rest}>
87
+ <TextInputWithDropdown
88
+ css={{ marginBottom: spacing('md') }}
89
+ name={name}
90
+ id={name}
91
+ value={query}
92
+ options={options.map(mapOptionToString)}
93
+ label={label}
94
+ placeholder={placeholder}
95
+ onChange={e => {
96
+ setQuery(e.target.value);
97
+ setErrorMessage('');
98
+ setOptions([]);
99
+ }}
100
+ onKeyPress={e => {
101
+ const keyCode = e.keyCode || e.which;
102
+ if (keyCode === KEY_CODE_ENTER) {
103
+ e.preventDefault();
104
+ return handler();
105
+ }
106
+ return null;
107
+ }}
108
+ onSelect={(text, index) => {
109
+ const selection = options[index];
110
+ onSelect(selection);
111
+ setQuery('');
112
+ setErrorMessage('');
113
+ setOptions([]);
114
+ }}
115
+ errorMsg={errorMessage}
116
+ dropdownInstruction={dropdownInstruction}
117
+ />
118
+ <StyledButton
119
+ type="button"
120
+ onClick={() => handler()}
121
+ loading={isSearching}
122
+ disabled={isSearching}
123
+ loadingText="Searching"
124
+ >
125
+ {buttonText}
126
+ </StyledButton>
127
+ </div>
128
+ );
129
+ };
130
+
131
+ Lookup.propTypes = {
132
+ name: PropTypes.string.isRequired,
133
+ label: PropTypes.string.isRequired,
134
+ placeholder: PropTypes.string.isRequired,
135
+ buttonText: PropTypes.string.isRequired,
136
+ lookupHandler: PropTypes.func.isRequired,
137
+ mapOptionToString: PropTypes.func.isRequired,
138
+ onSelect: PropTypes.func.isRequired,
139
+ noResultsMessage: PropTypes.string,
140
+ dropdownInstruction: PropTypes.string
141
+ };
142
+
143
+ Lookup.defaultProps = {
144
+ noResultsMessage: 'Sorry, could not find any results for your search',
145
+ dropdownInstruction: ''
146
+ };
147
+
148
+ export default Lookup;
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import axios from 'axios';
4
+
5
+ import Lookup from '../Lookup/Lookup';
6
+
7
+ const schoolFetcher = async query => {
8
+ if (!query || !query.trim()) {
9
+ throw new Error('Please enter a search query');
10
+ }
11
+
12
+ if (query.length < 2) {
13
+ throw new Error('Please enter at least two characters');
14
+ }
15
+
16
+ try {
17
+ const res = await axios.get(
18
+ 'https://lookups.sls.comicrelief.com/schools/lookup',
19
+ { timeout: 10000, params: { query } }
20
+ );
21
+ return res.data.data.schools;
22
+ } catch (error) {
23
+ // if (typeof Sentry !== 'undefined') {
24
+ // Sentry.captureException(error);
25
+ // }
26
+ throw new Error('Sorry, something unexpected went wrong. Please try again or enter your school manually');
27
+ }
28
+ };
29
+
30
+ const schoolToString = school => `${school.name}, ${school.post_code}`;
31
+
32
+ /**
33
+ * The component library's school lookup component uses a typeahead/search-as-you-type approach.
34
+ *
35
+ * Given the API we use is v flaky and can be slow, this isn't really ideal.
36
+ *
37
+ * This version just has a simple input + a button (or you can hit enter) to trigger the search.
38
+ *
39
+ * @param onSelect
40
+ * @param rest
41
+ * @returns {JSX.Element}
42
+ * @constructor
43
+ */
44
+ const SimpleSchoolLookup = ({ onSelect, ...rest }) => (
45
+ <Lookup
46
+ name="school_lookup"
47
+ label="Enter the name or postcode of your organisation"
48
+ placeholder="Enter name or postcode..."
49
+ buttonText="Find school"
50
+ dropdownInstruction="Please select an organisation from the list below"
51
+ noResultsMessage="Sorry, could not find anything matching your search"
52
+ lookupHandler={schoolFetcher}
53
+ mapOptionToString={schoolToString}
54
+ onSelect={onSelect}
55
+ {...rest}
56
+ />
57
+ );
58
+
59
+ SimpleSchoolLookup.propTypes = {
60
+ onSelect: PropTypes.func.isRequired
61
+ };
62
+
63
+ export default SimpleSchoolLookup;
@@ -0,0 +1,7 @@
1
+ ```js
2
+
3
+ import SimpleSchoolLookup from './SimpleSchoolLookup';
4
+
5
+ <SimpleSchoolLookup onSelect={data => console.log(data)}/>
6
+
7
+ ```
@@ -15,7 +15,7 @@ import {
15
15
 
16
16
  const allPlayers = {};
17
17
 
18
- /** Single Message is our main component usually to build landing pages */
18
+ /* Single Message is our main component usually to build landing pages */
19
19
  const SingleMessage = ({
20
20
  backgroundColor,
21
21
  copyFirst,
@@ -896,6 +896,10 @@ exports[`renders Single Message with full width image and no text correctly 1`]
896
896
  z-index: 1;
897
897
  }
898
898
 
899
+ @media (min-width:740px) {
900
+
901
+ }
902
+
899
903
  @media (min-width:740px) {
900
904
  .c0 {
901
905
  -webkit-flex-direction: row;
@@ -1010,6 +1014,10 @@ exports[`renders Single Message with no Image correctly 1`] = `
1010
1014
  padding: 1rem;
1011
1015
  }
1012
1016
 
1017
+ @media (min-width:740px) {
1018
+
1019
+ }
1020
+
1013
1021
  @media (min-width:740px) {
1014
1022
  .c0 {
1015
1023
  -webkit-flex-direction: row;
@@ -31,7 +31,7 @@ const Footer = ({
31
31
  <Logo sizeSm="48px" sizeMd="72px" rotate={false} campaign={campaign} />
32
32
  </Brand>
33
33
  </FooterBranding>
34
- <FooterNav navItems={navItems} />
34
+ <FooterNav navItems={navItems} {...rest} />
35
35
  <FooterCopyright>
36
36
  <Text tag="p" color="grey">
37
37
  {footerCopy}
@@ -46,13 +46,15 @@ const Footer = ({
46
46
  Footer.propTypes = {
47
47
  navItems: PropTypes.objectOf(PropTypes.shape),
48
48
  footerCopy: PropTypes.string,
49
- campaign: PropTypes.string
49
+ campaign: PropTypes.string,
50
+ overrideWhiteList: PropTypes.bool
50
51
  };
51
52
 
52
53
  Footer.defaultProps = {
53
54
  navItems: {},
54
55
  footerCopy: '',
55
- campaign: 'Comic Relief'
56
+ campaign: 'Comic Relief',
57
+ overrideWhiteList: false
56
58
  };
57
59
 
58
60
  export default Footer;
@@ -4,5 +4,12 @@
4
4
  import data from './data/data';
5
5
  import footerCopy from './data/footerCopy';
6
6
 
7
- <Footer navItems={data} footerCopy={footerCopy.copy} campaign="Comic Relief" />;
7
+ <>
8
+ <p>Standard footer</p>
9
+ <Footer navItems={data} footerCopy={footerCopy.copy} campaign="Comic Relief" />
10
+
11
+ <p>Overrides whitelist functionality for external usage</p>
12
+ <Footer navItems={data} footerCopy={footerCopy.copy} campaign="Comic Relief" overrideWhiteList />
13
+ </>
14
+
8
15
  ```
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
4
4
  import Text from '../../../Atoms/Text/Text';
5
5
  import { sizes } from '../../../../theme/shared/breakpoint';
6
6
  import NavHelper from '../../../../utils/navHelper';
7
- import InternalLinkHelper from '../../../../utils/internalLinkHelper';
7
+ import { InternalLinkHelper } from '../../../../utils/internalLinkHelper';
8
8
 
9
9
  import {
10
10
  Nav,
@@ -16,7 +16,7 @@ import {
16
16
  SubNavLink
17
17
  } from './Nav.style';
18
18
 
19
- const FooterNav = ({ navItems }) => {
19
+ const FooterNav = ({ navItems, ...rest }) => {
20
20
  const { menuGroups } = navItems;
21
21
  const [isExpandable] = useState(false);
22
22
  const [isSubMenuOpen, setIsSubMenuOpen] = useState({});
@@ -78,6 +78,7 @@ const FooterNav = ({ navItems }) => {
78
78
  aria-haspopup="true"
79
79
  role="button"
80
80
  onClick={toggleSubMenu(group.id)}
81
+ {...rest}
81
82
  >
82
83
  <Text color="white">{group.title}</Text>
83
84
  </NavLink>
@@ -103,7 +104,7 @@ const FooterNav = ({ navItems }) => {
103
104
  group.links.length % 2 === 0 && group.links.length > 2
104
105
  }
105
106
  >
106
- <SubNavLink href={thisUrl} inline role="menuitem">
107
+ <SubNavLink href={thisUrl} inline role="menuitem" {...rest}>
107
108
  <Text color="white">{child.title}</Text>
108
109
  </SubNavLink>
109
110
  </SubNavItem>
@@ -27,7 +27,7 @@ exports[`renders correctly 1`] = `
27
27
  font-family: 'Montserrat',Helvetica,Arial,sans-serif;
28
28
  }
29
29
 
30
- .c25 {
30
+ .c26 {
31
31
  color: #969598;
32
32
  font-size: 1rem;
33
33
  line-height: 1rem;
@@ -69,6 +69,21 @@ exports[`renders correctly 1`] = `
69
69
  border-bottom: 2px solid #000000;
70
70
  }
71
71
 
72
+ .c24 {
73
+ border: 0;
74
+ -webkit-clip: rect(0 0 0 0);
75
+ clip: rect(0 0 0 0);
76
+ -webkit-clip-path: inset(50%);
77
+ clip-path: inset(50%);
78
+ height: 1px;
79
+ margin: -1px;
80
+ overflow: hidden;
81
+ padding: 0;
82
+ position: absolute;
83
+ white-space: nowrap;
84
+ width: 1px;
85
+ }
86
+
72
87
  .c5 {
73
88
  -webkit-text-decoration: none;
74
89
  text-decoration: none;
@@ -313,7 +328,7 @@ exports[`renders correctly 1`] = `
313
328
  align-items: center;
314
329
  }
315
330
 
316
- .c24 {
331
+ .c25 {
317
332
  display: block;
318
333
  width: 100%;
319
334
  height: 100%;
@@ -321,7 +336,7 @@ exports[`renders correctly 1`] = `
321
336
  margin-top: 3rem;
322
337
  }
323
338
 
324
- .c24 p {
339
+ .c25 p {
325
340
  font-size: 15px;
326
341
  line-height: 24px;
327
342
  margin-bottom: 5px;
@@ -528,7 +543,7 @@ exports[`renders correctly 1`] = `
528
543
  }
529
544
 
530
545
  @media (min-width:1024px) {
531
- .c24 p {
546
+ .c25 p {
532
547
  font-size: 16px;
533
548
  line-height: 27px;
534
549
  }
@@ -1166,6 +1181,11 @@ exports[`renders correctly 1`] = `
1166
1181
  >
1167
1182
  Link comp with only URL
1168
1183
  </span>
1184
+ <span
1185
+ className="c24"
1186
+ >
1187
+ (opens in new window)
1188
+ </span>
1169
1189
  </a>
1170
1190
  </li>
1171
1191
  <li
@@ -1206,6 +1226,11 @@ exports[`renders correctly 1`] = `
1206
1226
  >
1207
1227
  Test non-whitelisted external link
1208
1228
  </span>
1229
+ <span
1230
+ className="c24"
1231
+ >
1232
+ (opens in new window)
1233
+ </span>
1209
1234
  </a>
1210
1235
  </li>
1211
1236
  </ul>
@@ -1213,10 +1238,10 @@ exports[`renders correctly 1`] = `
1213
1238
  </ul>
1214
1239
  </nav>
1215
1240
  <div
1216
- className="c24"
1241
+ className="c25"
1217
1242
  >
1218
1243
  <p
1219
- className="c25"
1244
+ className="c26"
1220
1245
  color="grey"
1221
1246
  size="s"
1222
1247
  >
@@ -5,7 +5,7 @@ import Text from '../../../Atoms/Text/Text';
5
5
  import BurgerMenu from '../Burger/BurgerMenu';
6
6
  import { sizes } from '../../../../theme/shared/breakpoint';
7
7
  import NavHelper from '../../../../utils/navHelper';
8
- import InternalLinkHelper from '../../../../utils/internalLinkHelper';
8
+ import { InternalLinkHelper } from '../../../../utils/internalLinkHelper';
9
9
  import whiteListed from '../../../../utils/whiteListed';
10
10
 
11
11
  import {
package/src/index.js CHANGED
@@ -29,6 +29,7 @@ export { default as SocialIcons } from './components/Atoms/SocialIcons/SocialIco
29
29
  export { default as TextInputWithDropdown } from './components/Atoms/TextInputWithDropdown/TextInputWithDropdown';
30
30
  export { default as ErrorText } from './components/Atoms/ErrorText/ErrorText';
31
31
  export { default as Label } from './components/Atoms/Label/Label';
32
+ export { default as ButtonWithStates } from './components/Atoms/ButtonWithStates/ButtonWithStates';
32
33
 
33
34
  /* Molecules */
34
35
  export { default as HeroBanner } from './components/Molecules/HeroBanner/HeroBanner';
@@ -58,6 +59,8 @@ export { default as Countdown } from './components/Molecules/Countdown/Countdown
58
59
  export { default as Banner } from './components/Molecules/Banner/Banner';
59
60
  export { default as Chip } from './components/Molecules/Chip/Chip';
60
61
  export { default as Descriptor } from './components/Molecules/Descriptor/Descriptor';
62
+ export { default as Lookup } from './components/Molecules/Lookup/Lookup';
63
+ export { default as SimpleSchoolLookup } from './components/Molecules/SimpleSchoolLookup/SimpleSchoolLookup';
61
64
 
62
65
  /* Organisms */
63
66
  export { default as EmailSignUp } from './components/Organisms/EmailSignUp/EmailSignUp';
@@ -1,14 +1,32 @@
1
- const InternalLinkHelper = link => {
2
- const domainRegEx = new RegExp(
3
- '(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]'
4
- );
1
+ const domainRegEx = new RegExp(
2
+ '(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]'
3
+ );
5
4
 
5
+ const InternalLinkHelper = link => {
6
6
  // Check our URL for a domain pattern, if so return it
7
7
  if (domainRegEx.test(link)) {
8
8
  return link;
9
9
  }
10
+
10
11
  // If domain-free and internal, prefix it with slash if it doesn't already have one
11
12
  return link.substring(0, 1) === '/' ? link : `/${link}`;
12
13
  };
13
14
 
14
- export default InternalLinkHelper;
15
+ const getDomain = url => {
16
+ let thisURL = url;
17
+
18
+ // Strip out protocol
19
+ thisURL = url.replace(/(https?:\/\/)?(www.)?/i, '');
20
+
21
+ // Strip out subdirectory/path
22
+ if (thisURL.indexOf('/') !== -1) {
23
+ const [splitURL] = thisURL.split('/');
24
+ thisURL = splitURL;
25
+ }
26
+
27
+ return thisURL;
28
+ };
29
+
30
+ export {
31
+ InternalLinkHelper, getDomain
32
+ };