@comicrelief/component-library 5.6.0 → 5.7.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 (27) hide show
  1. package/.github/workflows/main.yml +131 -0
  2. package/.github/workflows/pr-checks.yml +17 -0
  3. package/README.md +6 -6
  4. package/dist/components/Atoms/ButtonWithStates/ButtonWithStates.js +91 -0
  5. package/dist/components/Atoms/ButtonWithStates/ButtonWithStates.md +13 -0
  6. package/dist/components/Atoms/Link/Link.js +17 -4
  7. package/dist/components/Molecules/Lookup/Lookup.js +201 -0
  8. package/dist/components/Molecules/SimpleSchoolLookup/SimpleSchoolLookup.js +112 -0
  9. package/dist/components/Molecules/SimpleSchoolLookup/SimpleSchoolLookup.md +7 -0
  10. package/dist/components/Molecules/SingleMessage/__snapshots__/SingleMessage.test.js.snap +8 -0
  11. package/dist/components/Organisms/Footer/Footer.js +4 -3
  12. package/dist/components/Organisms/Footer/Footer.md +8 -1
  13. package/dist/components/Organisms/Footer/Nav/Nav.js +10 -5
  14. package/dist/index.js +24 -0
  15. package/package.json +2 -1
  16. package/src/components/Atoms/ButtonWithStates/ButtonWithStates.js +64 -0
  17. package/src/components/Atoms/ButtonWithStates/ButtonWithStates.md +13 -0
  18. package/src/components/Atoms/Link/Link.js +12 -4
  19. package/src/components/Molecules/Lookup/Lookup.js +148 -0
  20. package/src/components/Molecules/SimpleSchoolLookup/SimpleSchoolLookup.js +63 -0
  21. package/src/components/Molecules/SimpleSchoolLookup/SimpleSchoolLookup.md +7 -0
  22. package/src/components/Molecules/SingleMessage/__snapshots__/SingleMessage.test.js.snap +8 -0
  23. package/src/components/Organisms/Footer/Footer.js +5 -3
  24. package/src/components/Organisms/Footer/Footer.md +8 -1
  25. package/src/components/Organisms/Footer/Nav/Nav.js +3 -2
  26. package/src/index.js +3 -0
  27. package/.circleci/config.yml +0 -54
@@ -0,0 +1,131 @@
1
+ name: Main
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ lint:
7
+ name: Lint
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - name: Checkout
11
+ uses: actions/checkout@v3
12
+
13
+ - name: Set up Node
14
+ uses: actions/setup-node@v3
15
+ with:
16
+ node-version: 14
17
+
18
+ - name: Restore packages cache
19
+ uses: actions/cache@v3
20
+ with:
21
+ path: '**/node_modules'
22
+ key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
23
+
24
+ - name: Install dependencies
25
+ run: yarn install --frozen-lockfile --ignore-scripts
26
+
27
+ - name: Run ESLint
28
+ run: yarn lint
29
+
30
+ unit-test:
31
+ name: Unit test
32
+ runs-on: ubuntu-latest
33
+ steps:
34
+ - name: Checkout
35
+ uses: actions/checkout@v3
36
+
37
+ - name: Set up Node
38
+ uses: actions/setup-node@v3
39
+ with:
40
+ node-version: 14
41
+
42
+ - name: Restore packages cache
43
+ uses: actions/cache@v3
44
+ with:
45
+ path: '**/node_modules'
46
+ key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
47
+
48
+ - name: Install dependencies
49
+ run: yarn install --frozen-lockfile --ignore-scripts
50
+
51
+ - name: Build
52
+ run: yarn build
53
+
54
+ - name: Run unit tests
55
+ run: yarn test --maxWorkers=2
56
+ env:
57
+ NODE_OPTIONS: --max_old_space_size=4096
58
+
59
+ cypress:
60
+ name: Cypress test
61
+ needs:
62
+ - lint
63
+ - unit-test
64
+ runs-on: ubuntu-latest
65
+ steps:
66
+ - name: Checkout
67
+ uses: actions/checkout@v3
68
+
69
+ - name: Set up Node
70
+ uses: actions/setup-node@v3
71
+ with:
72
+ node-version: 14
73
+
74
+ # see https://github.com/marketplace/actions/cypress-io
75
+ - name: Run Cypress tests
76
+ uses: cypress-io/github-action@v2
77
+ with:
78
+ start: yarn styleguide
79
+ command: yarn cy:run
80
+ wait-on: http://localhost:6060
81
+ env:
82
+ NODE_OPTIONS: --max_old_space_size=4096
83
+
84
+ # NOTE: screenshots will be generated only if the tests failed
85
+ # thus we store screenshots only on failures
86
+ - name: Upload screenshots
87
+ uses: actions/upload-artifact@v3
88
+ if: failure()
89
+ with:
90
+ name: cypress-screenshots
91
+ path: cypress/screenshots
92
+
93
+ # Test run video was always captured, so this action uses "always()" condition
94
+ - name: Upload videos
95
+ uses: actions/upload-artifact@v3
96
+ if: always()
97
+ with:
98
+ name: cypress-videos
99
+ path: cypress/videos
100
+
101
+ publish:
102
+ name: Publish package to npm
103
+ if: github.ref == 'refs/heads/master'
104
+ needs: cypress
105
+ runs-on: ubuntu-latest
106
+ steps:
107
+ - name: Checkout
108
+ uses: actions/checkout@v3
109
+
110
+ - name: Set up Node
111
+ uses: actions/setup-node@v3
112
+ with:
113
+ node-version: 14
114
+
115
+ - name: Restore packages cache
116
+ uses: actions/cache@v3
117
+ with:
118
+ path: '**/node_modules'
119
+ key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
120
+
121
+ - name: Install dependencies
122
+ run: yarn install --frozen-lockfile --ignore-scripts
123
+
124
+ - name: Build
125
+ run: yarn build
126
+
127
+ - name: Release
128
+ run: yarn semantic-release
129
+ env:
130
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
131
+ NPM_TOKEN: ${{ secrets.NPM_PUBLISHING_TOKEN }}
@@ -0,0 +1,17 @@
1
+ name: PR
2
+
3
+ on: [pull_request]
4
+
5
+ jobs:
6
+ # https://github.com/amannn/action-semantic-pull-request#example-config
7
+ check-semantic-pr:
8
+ name: Semantic pull request
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ # Please look up the latest version from
12
+ # https://github.com/amannn/action-semantic-pull-request/releases
13
+ - uses: amannn/action-semantic-pull-request@v4.4.0
14
+ env:
15
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16
+ with:
17
+ validateSingleCommit: true
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  Comic Relief React Component Library
2
2
  --------------
3
3
 
4
- [![CircleCI](https://circleci.com/gh/comicrelief/component-library.svg?style=svg)](https://circleci.com/gh/comicrelief/component-library)
4
+ [![GitHub Actions](https://github.com/comicrelief/component-library/actions/workflows/main.yml/badge.svg)](https://github.com/comicrelief/component-library/actions)
5
5
  [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
6
6
 
7
7
  React components to be shared across Comic Relief applications
@@ -27,24 +27,24 @@ import { HeroBanner } from '@comic-relief/component-library';
27
27
 
28
28
  ### Develop
29
29
 
30
- To install CR-CL locally run
30
+ To install CR-CL locally, run:
31
31
 
32
32
  ```
33
33
  $ yarn install
34
34
  ```
35
35
 
36
- To start
36
+ To start the dev build and server:
37
37
  ```
38
38
  $ yarn styleguide
39
39
  ```
40
40
 
41
- To test
41
+ To test:
42
42
  ```
43
43
  $ yarn test
44
44
  ```
45
- _Test will run through all jest tests and watch for any changes on snapshots._
45
+ _Test will run through all Jest tests and watch for any changes on snapshots._
46
46
 
47
- To update snapshots
47
+ To update snapshots with desired changes brought in through your work:
48
48
  ```
49
49
  $ yarn test -u
50
50
  ```
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+
10
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/slicedToArray"));
11
+
12
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/objectWithoutProperties"));
13
+
14
+ var _react = _interopRequireWildcard(require("react"));
15
+
16
+ var _styledComponents = _interopRequireDefault(require("styled-components"));
17
+
18
+ var _ScaleLoader = _interopRequireDefault(require("react-spinners/ScaleLoader"));
19
+
20
+ var _spacing = _interopRequireDefault(require("../../../theme/shared/spacing"));
21
+
22
+ var _Button = _interopRequireDefault(require("../Button/Button"));
23
+
24
+ var _excluded = ["children", "loadingText", "loading", "disabled"];
25
+
26
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
27
+
28
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
29
+
30
+ var ButtonWithDisabledState = (0, _styledComponents.default)(_Button.default).withConfig({
31
+ displayName: "ButtonWithStates__ButtonWithDisabledState",
32
+ componentId: "sc-7gb81g-0"
33
+ })(["&:disabled{cursor:not-allowed;opacity:0.75;}"]);
34
+
35
+ var LoaderContainer = _styledComponents.default.div.withConfig({
36
+ displayName: "ButtonWithStates__LoaderContainer",
37
+ componentId: "sc-7gb81g-1"
38
+ })(["", ""], function (_ref) {
39
+ var withMargin = _ref.withMargin;
40
+ return withMargin ? "\n margin-top: ".concat((0, _spacing.default)('xsm'), ";\n margin-left: ").concat((0, _spacing.default)('md'), ";\n") : '';
41
+ }); // A button with loading and disabled states.
42
+
43
+
44
+ var ButtonWithStates = /*#__PURE__*/_react.default.forwardRef(function (_ref2, ref) {
45
+ var children = _ref2.children,
46
+ loadingText = _ref2.loadingText,
47
+ loading = _ref2.loading,
48
+ disabled = _ref2.disabled,
49
+ rest = (0, _objectWithoutProperties2.default)(_ref2, _excluded);
50
+
51
+ var _useState = (0, _react.useState)(null),
52
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
53
+ loaderColour = _useState2[0],
54
+ setLoaderColour = _useState2[1]; // Can't see a simpler way to get the button's text colour, without reading the value
55
+ // via JavaScript.
56
+ // (e.g. the `theme.buttonColours` helper returns a CSS string split into an array -
57
+ // don't really want to be parsing that.)
58
+ // (And can't use inherit because ScaleLoader's color prop is actually setting its
59
+ // background color.)
60
+
61
+
62
+ var getLoaderColour = (0, _react.useCallback)(function (node) {
63
+ if (node && typeof window.getComputedStyle === 'function') {
64
+ var textColour = window.getComputedStyle(node).color;
65
+
66
+ if (textColour) {
67
+ setLoaderColour(textColour);
68
+ }
69
+ }
70
+ }, []);
71
+ return /*#__PURE__*/_react.default.createElement(ButtonWithDisabledState, Object.assign({
72
+ ref: ref,
73
+ disabled: disabled
74
+ }, rest), loading ? loadingText : children, /*#__PURE__*/_react.default.createElement(LoaderContainer, {
75
+ ref: getLoaderColour,
76
+ withMargin: loading
77
+ }, /*#__PURE__*/_react.default.createElement(_ScaleLoader.default, {
78
+ height: 16,
79
+ width: 2,
80
+ loading: loading,
81
+ color: loaderColour
82
+ })));
83
+ });
84
+
85
+ ButtonWithStates.defaultProps = {
86
+ loading: false,
87
+ disabled: false,
88
+ loadingText: 'Loading'
89
+ };
90
+ var _default = ButtonWithStates;
91
+ exports.default = _default;
@@ -0,0 +1,13 @@
1
+ ## Disabled and loading
2
+
3
+ ```js
4
+ import ButtonWithStates from './ButtonWithStates';
5
+
6
+ <ButtonWithStates
7
+ type="submit"
8
+ loading
9
+ disabled
10
+ >
11
+ Enter prize draw
12
+ </ButtonWithStates>
13
+ ```
@@ -7,9 +7,11 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports.default = void 0;
9
9
 
10
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/slicedToArray"));
11
+
10
12
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/objectWithoutProperties"));
11
13
 
12
- var _react = _interopRequireDefault(require("react"));
14
+ var _react = _interopRequireWildcard(require("react"));
13
15
 
14
16
  var _Link = _interopRequireWildcard(require("./Link.style"));
15
17
 
@@ -37,14 +39,22 @@ var Link = function Link(_ref) {
37
39
  iconFirst = _ref.iconFirst,
38
40
  rest = (0, _objectWithoutProperties2.default)(_ref, _excluded);
39
41
 
42
+ var _useState = (0, _react.useState)(''),
43
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
44
+ documentHost = _useState2[0],
45
+ setDocumentHost = _useState2[1];
40
46
  /**
41
47
  * If we haven't specifically set the target via props, check if
42
48
  * this is an internal link OR on our whitelist before making it a '_self' link
43
49
  */
50
+
51
+
44
52
  if (target === null) {
45
53
  // Use our helper function to determine the raw domains to compare
46
- var currentDomain = (0, _internalLinkHelper.getDomain)(document.location.host);
47
- var linkDomain = (0, _internalLinkHelper.getDomain)(href);
54
+ var currentDomain = (0, _internalLinkHelper.getDomain)(documentHost);
55
+ var linkDomain = (0, _internalLinkHelper.getDomain)(href); // Additional check for applications that need more control
56
+
57
+ var isWhiteListOverridden = rest.overrideWhiteList === true;
48
58
  /**
49
59
  * If the link has no domain supplied (likely '/' or '#')
50
60
  * OR has the same domain as the current page, don't open
@@ -53,12 +63,15 @@ var Link = function Link(_ref) {
53
63
 
54
64
  var isExternalLink = linkDomain !== '' && currentDomain !== linkDomain;
55
65
  var isWhiteListed = (0, _whiteListed.default)(href);
56
- window = isExternalLink && !isWhiteListed ? '_blank' : '_self';
66
+ window = isExternalLink && (isWhiteListOverridden || !isWhiteListed) ? '_blank' : '_self';
57
67
  } else {
58
68
  window = target === 'blank' ? '_blank' : '_self';
59
69
  }
60
70
 
61
71
  var hasIcon = icon !== null;
72
+ (0, _react.useEffect)(function () {
73
+ setDocumentHost(document.location.host);
74
+ }, []);
62
75
  return /*#__PURE__*/_react.default.createElement(_Link.default, Object.assign({}, rest, {
63
76
  color: color,
64
77
  href: href,
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+
10
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
+
12
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/asyncToGenerator"));
13
+
14
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/slicedToArray"));
15
+
16
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/objectWithoutProperties"));
17
+
18
+ var _styledComponents = _interopRequireWildcard(require("styled-components"));
19
+
20
+ var _react = _interopRequireWildcard(require("react"));
21
+
22
+ var _TextInputWithDropdown = _interopRequireDefault(require("../../Atoms/TextInputWithDropdown/TextInputWithDropdown"));
23
+
24
+ var _spacing = _interopRequireDefault(require("../../../theme/shared/spacing"));
25
+
26
+ var _ButtonWithStates = _interopRequireDefault(require("../../Atoms/ButtonWithStates/ButtonWithStates"));
27
+
28
+ var _excluded = ["name", "label", "placeholder", "buttonText", "lookupHandler", "mapOptionToString", "onSelect", "noResultsMessage", "dropdownInstruction"];
29
+
30
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
31
+
32
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
33
+
34
+ var StyledButton = (0, _styledComponents.default)(_ButtonWithStates.default).withConfig({
35
+ displayName: "Lookup__StyledButton",
36
+ componentId: "sc-uu5bpv-0"
37
+ })(["", ""], function (_ref) {
38
+ var theme = _ref.theme;
39
+ return (0, _styledComponents.css)(["color:", ";border:2px solid ", ";background-color:", ";padding-left:", ";padding-right:", ";&:hover{color:", ";background-color:", ";}"], theme.color('grey_dark'), theme.color('grey_dark'), theme.color('white'), (0, _spacing.default)('lg'), (0, _spacing.default)('lg'), theme.color('grey_dark'), theme.color('white'));
40
+ });
41
+ var KEY_CODE_ENTER = 13;
42
+ /**
43
+ * A simple lookup component
44
+ *
45
+ * The `lookupHandler` should be an async function which is called when a lookup is triggered
46
+ * (either by hitting enter or clicking the button)
47
+ *
48
+ * It will receive the current search term and should:
49
+ * - take care of any validation on the search term
50
+ * - perform the actual lookup request
51
+ * - return an array of options (or an empty array if none were found)
52
+ * - only throw errors with user-friendly messages
53
+ *
54
+ * Any errors thrown will be caught and the message will be displayed to the user.
55
+ *
56
+ * The `onSelect` function will receive the chosen option.
57
+ *
58
+ * @param name
59
+ * @param label
60
+ * @param placeholder
61
+ * @param buttonText
62
+ * @param lookupHandler
63
+ * @param mapOptionToString
64
+ * @param onSelect
65
+ * @param noResultsMessage
66
+ * @param dropdownInstruction
67
+ * @param rest
68
+ * @returns {JSX.Element}
69
+ * @constructor
70
+ */
71
+
72
+ var Lookup = function Lookup(_ref2) {
73
+ var name = _ref2.name,
74
+ label = _ref2.label,
75
+ placeholder = _ref2.placeholder,
76
+ buttonText = _ref2.buttonText,
77
+ lookupHandler = _ref2.lookupHandler,
78
+ mapOptionToString = _ref2.mapOptionToString,
79
+ _onSelect = _ref2.onSelect,
80
+ noResultsMessage = _ref2.noResultsMessage,
81
+ dropdownInstruction = _ref2.dropdownInstruction,
82
+ rest = (0, _objectWithoutProperties2.default)(_ref2, _excluded);
83
+
84
+ var _useState = (0, _react.useState)(''),
85
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
86
+ query = _useState2[0],
87
+ setQuery = _useState2[1];
88
+
89
+ var _useState3 = (0, _react.useState)(''),
90
+ _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
91
+ errorMessage = _useState4[0],
92
+ setErrorMessage = _useState4[1];
93
+
94
+ var _useState5 = (0, _react.useState)([]),
95
+ _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
96
+ options = _useState6[0],
97
+ setOptions = _useState6[1];
98
+
99
+ var _useState7 = (0, _react.useState)(false),
100
+ _useState8 = (0, _slicedToArray2.default)(_useState7, 2),
101
+ isSearching = _useState8[0],
102
+ setIsSearching = _useState8[1];
103
+
104
+ var handler = (0, _react.useCallback)( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
105
+ var results;
106
+ return _regenerator.default.wrap(function _callee$(_context) {
107
+ while (1) {
108
+ switch (_context.prev = _context.next) {
109
+ case 0:
110
+ setErrorMessage('');
111
+ setIsSearching(true);
112
+ _context.prev = 2;
113
+ _context.next = 5;
114
+ return lookupHandler(query);
115
+
116
+ case 5:
117
+ results = _context.sent;
118
+ setOptions(results);
119
+
120
+ if (results.length === 0) {
121
+ setErrorMessage(noResultsMessage);
122
+ }
123
+
124
+ _context.next = 13;
125
+ break;
126
+
127
+ case 10:
128
+ _context.prev = 10;
129
+ _context.t0 = _context["catch"](2);
130
+ setErrorMessage(_context.t0.message);
131
+
132
+ case 13:
133
+ setIsSearching(false);
134
+
135
+ case 14:
136
+ case "end":
137
+ return _context.stop();
138
+ }
139
+ }
140
+ }, _callee, null, [[2, 10]]);
141
+ })), [query, setOptions, setErrorMessage, noResultsMessage, lookupHandler]);
142
+ return /*#__PURE__*/_react.default.createElement("div", rest, /*#__PURE__*/_react.default.createElement(_StyledTextInputWithDropdown, {
143
+ name: name,
144
+ id: name,
145
+ value: query,
146
+ options: options.map(mapOptionToString),
147
+ label: label,
148
+ placeholder: placeholder,
149
+ onChange: function onChange(e) {
150
+ setQuery(e.target.value);
151
+ setErrorMessage('');
152
+ setOptions([]);
153
+ },
154
+ onKeyPress: function onKeyPress(e) {
155
+ var keyCode = e.keyCode || e.which;
156
+
157
+ if (keyCode === KEY_CODE_ENTER) {
158
+ e.preventDefault();
159
+ return handler();
160
+ }
161
+
162
+ return null;
163
+ },
164
+ onSelect: function onSelect(text, index) {
165
+ var selection = options[index];
166
+
167
+ _onSelect(selection);
168
+
169
+ setQuery('');
170
+ setErrorMessage('');
171
+ setOptions([]);
172
+ },
173
+ errorMsg: errorMessage,
174
+ dropdownInstruction: dropdownInstruction,
175
+ $_css: (0, _spacing.default)('md')
176
+ }), /*#__PURE__*/_react.default.createElement(StyledButton, {
177
+ type: "button",
178
+ onClick: function onClick() {
179
+ return handler();
180
+ },
181
+ loading: isSearching,
182
+ disabled: isSearching,
183
+ loadingText: "Searching"
184
+ }, buttonText));
185
+ };
186
+
187
+ Lookup.defaultProps = {
188
+ noResultsMessage: 'Sorry, could not find any results for your search',
189
+ dropdownInstruction: ''
190
+ };
191
+ var _default = Lookup;
192
+ exports.default = _default;
193
+
194
+ var _StyledTextInputWithDropdown = (0, _styledComponents.default)(_TextInputWithDropdown.default).withConfig({
195
+ displayName: "Lookup___StyledTextInputWithDropdown",
196
+ componentId: "sc-uu5bpv-1"
197
+ })(function (p) {
198
+ return {
199
+ marginBottom: p.$_css
200
+ };
201
+ });
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+
10
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/objectWithoutProperties"));
11
+
12
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
13
+
14
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/asyncToGenerator"));
15
+
16
+ var _react = _interopRequireDefault(require("react"));
17
+
18
+ var _axios = _interopRequireDefault(require("axios"));
19
+
20
+ var _Lookup = _interopRequireDefault(require("../Lookup/Lookup"));
21
+
22
+ var _excluded = ["onSelect"];
23
+
24
+ var schoolFetcher = /*#__PURE__*/function () {
25
+ var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(query) {
26
+ var res;
27
+ return _regenerator.default.wrap(function _callee$(_context) {
28
+ while (1) {
29
+ switch (_context.prev = _context.next) {
30
+ case 0:
31
+ if (!(!query || !query.trim())) {
32
+ _context.next = 2;
33
+ break;
34
+ }
35
+
36
+ throw new Error('Please enter a search query');
37
+
38
+ case 2:
39
+ if (!(query.length < 2)) {
40
+ _context.next = 4;
41
+ break;
42
+ }
43
+
44
+ throw new Error('Please enter at least two characters');
45
+
46
+ case 4:
47
+ _context.prev = 4;
48
+ _context.next = 7;
49
+ return _axios.default.get('https://lookups.sls.comicrelief.com/schools/lookup', {
50
+ timeout: 10000,
51
+ params: {
52
+ query: query
53
+ }
54
+ });
55
+
56
+ case 7:
57
+ res = _context.sent;
58
+ return _context.abrupt("return", res.data.data.schools);
59
+
60
+ case 11:
61
+ _context.prev = 11;
62
+ _context.t0 = _context["catch"](4);
63
+ throw new Error('Sorry, something unexpected went wrong. Please try again or enter your school manually');
64
+
65
+ case 14:
66
+ case "end":
67
+ return _context.stop();
68
+ }
69
+ }
70
+ }, _callee, null, [[4, 11]]);
71
+ }));
72
+
73
+ return function schoolFetcher(_x) {
74
+ return _ref.apply(this, arguments);
75
+ };
76
+ }();
77
+
78
+ var schoolToString = function schoolToString(school) {
79
+ return "".concat(school.name, ", ").concat(school.post_code);
80
+ };
81
+ /**
82
+ * The component library's school lookup component uses a typeahead/search-as-you-type approach.
83
+ *
84
+ * Given the API we use is v flaky and can be slow, this isn't really ideal.
85
+ *
86
+ * This version just has a simple input + a button (or you can hit enter) to trigger the search.
87
+ *
88
+ * @param onSelect
89
+ * @param rest
90
+ * @returns {JSX.Element}
91
+ * @constructor
92
+ */
93
+
94
+
95
+ var SimpleSchoolLookup = function SimpleSchoolLookup(_ref2) {
96
+ var onSelect = _ref2.onSelect,
97
+ rest = (0, _objectWithoutProperties2.default)(_ref2, _excluded);
98
+ return /*#__PURE__*/_react.default.createElement(_Lookup.default, Object.assign({
99
+ name: "school_lookup",
100
+ label: "Enter the name or postcode of your organisation",
101
+ placeholder: "Enter name or postcode...",
102
+ buttonText: "Find school",
103
+ dropdownInstruction: "Please select an organisation from the list below",
104
+ noResultsMessage: "Sorry, could not find anything matching your search",
105
+ lookupHandler: schoolFetcher,
106
+ mapOptionToString: schoolToString,
107
+ onSelect: onSelect
108
+ }, rest));
109
+ };
110
+
111
+ var _default = SimpleSchoolLookup;
112
+ exports.default = _default;
@@ -0,0 +1,7 @@
1
+ ```js
2
+
3
+ import SimpleSchoolLookup from './SimpleSchoolLookup';
4
+
5
+ <SimpleSchoolLookup onSelect={data => console.log(data)}/>
6
+
7
+ ```