@ndla/ui 28.0.0 → 29.0.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 (86) hide show
  1. package/es/Resource/ListResource.js +8 -8
  2. package/es/TagSelector/Control.js +23 -0
  3. package/es/TagSelector/DropdownIndicator.js +66 -0
  4. package/es/TagSelector/Input.js +19 -0
  5. package/es/TagSelector/Menu.js +26 -0
  6. package/es/TagSelector/MenuList.js +22 -0
  7. package/es/TagSelector/Option.js +55 -0
  8. package/es/TagSelector/SelectContainer.js +18 -0
  9. package/es/TagSelector/TagSelector.js +161 -100
  10. package/es/TagSelector/ValueButton.js +46 -0
  11. package/es/TagSelector/ariaMessages.js +104 -0
  12. package/es/TagSelector/index.js +2 -1
  13. package/es/TagSelector/types.js +0 -0
  14. package/es/TreeStructure/ComboboxButton.js +19 -18
  15. package/es/TreeStructure/TreeStructure.js +8 -8
  16. package/es/locale/messages-en.js +40 -2
  17. package/es/locale/messages-nb.js +40 -2
  18. package/es/locale/messages-nn.js +40 -2
  19. package/es/locale/messages-se.js +40 -2
  20. package/es/locale/messages-sma.js +40 -2
  21. package/lib/Resource/ListResource.js +8 -8
  22. package/lib/TagSelector/Control.d.ts +12 -0
  23. package/lib/TagSelector/Control.js +35 -0
  24. package/lib/TagSelector/DropdownIndicator.d.ts +12 -0
  25. package/lib/TagSelector/DropdownIndicator.js +80 -0
  26. package/lib/TagSelector/Input.d.ts +12 -0
  27. package/lib/TagSelector/Input.js +33 -0
  28. package/lib/TagSelector/Menu.d.ts +12 -0
  29. package/lib/TagSelector/Menu.js +40 -0
  30. package/lib/TagSelector/MenuList.d.ts +13 -0
  31. package/lib/TagSelector/MenuList.js +36 -0
  32. package/lib/TagSelector/Option.d.ts +12 -0
  33. package/lib/TagSelector/Option.js +61 -0
  34. package/lib/TagSelector/SelectContainer.d.ts +12 -0
  35. package/lib/TagSelector/SelectContainer.js +31 -0
  36. package/lib/TagSelector/TagSelector.d.ts +14 -11
  37. package/lib/TagSelector/TagSelector.js +165 -96
  38. package/lib/TagSelector/ValueButton.d.ts +16 -0
  39. package/lib/TagSelector/ValueButton.js +55 -0
  40. package/lib/TagSelector/ariaMessages.d.ts +16 -0
  41. package/lib/TagSelector/ariaMessages.js +113 -0
  42. package/lib/TagSelector/index.d.ts +2 -1
  43. package/lib/TagSelector/index.js +3 -5
  44. package/lib/TagSelector/types.d.ts +11 -0
  45. package/lib/TagSelector/types.js +1 -0
  46. package/lib/TreeStructure/ComboboxButton.js +19 -18
  47. package/lib/TreeStructure/TreeStructure.js +7 -7
  48. package/lib/locale/messages-en.d.ts +40 -2
  49. package/lib/locale/messages-en.js +40 -2
  50. package/lib/locale/messages-nb.d.ts +40 -2
  51. package/lib/locale/messages-nb.js +40 -2
  52. package/lib/locale/messages-nn.d.ts +40 -2
  53. package/lib/locale/messages-nn.js +40 -2
  54. package/lib/locale/messages-se.d.ts +40 -2
  55. package/lib/locale/messages-se.js +40 -2
  56. package/lib/locale/messages-sma.d.ts +40 -2
  57. package/lib/locale/messages-sma.js +40 -2
  58. package/package.json +15 -14
  59. package/src/Resource/ListResource.tsx +1 -1
  60. package/src/TagSelector/Control.tsx +34 -0
  61. package/src/TagSelector/DropdownIndicator.tsx +47 -0
  62. package/src/TagSelector/Input.tsx +31 -0
  63. package/src/TagSelector/Menu.tsx +38 -0
  64. package/src/TagSelector/MenuList.tsx +30 -0
  65. package/src/TagSelector/Option.tsx +53 -0
  66. package/src/TagSelector/SelectContainer.tsx +32 -0
  67. package/src/TagSelector/TagSelector.tsx +105 -84
  68. package/src/TagSelector/ValueButton.tsx +46 -0
  69. package/src/TagSelector/ariaMessages.ts +87 -0
  70. package/src/TagSelector/index.ts +2 -1
  71. package/src/TagSelector/types.ts +12 -0
  72. package/src/TreeStructure/ComboboxButton.tsx +15 -17
  73. package/src/TreeStructure/TreeStructure.tsx +2 -11
  74. package/src/locale/messages-en.ts +41 -2
  75. package/src/locale/messages-nb.ts +41 -2
  76. package/src/locale/messages-nn.ts +41 -2
  77. package/src/locale/messages-se.ts +41 -2
  78. package/src/locale/messages-sma.ts +41 -2
  79. package/es/TagSelector/SuggestionInput.js +0 -285
  80. package/es/TagSelector/Suggestions.js +0 -97
  81. package/lib/TagSelector/SuggestionInput.d.ts +0 -19
  82. package/lib/TagSelector/SuggestionInput.js +0 -299
  83. package/lib/TagSelector/Suggestions.d.ts +0 -12
  84. package/lib/TagSelector/Suggestions.js +0 -99
  85. package/src/TagSelector/SuggestionInput.tsx +0 -287
  86. package/src/TagSelector/Suggestions.tsx +0 -139
@@ -197,11 +197,49 @@ declare const messages: {
197
197
  };
198
198
  };
199
199
  tagSelector: {
200
+ aria: {
201
+ screenReaderStatus: string;
202
+ disabled: string;
203
+ selected: string;
204
+ focused: string;
205
+ guidance: {
206
+ menu: {
207
+ updown: string;
208
+ enter: string;
209
+ escape: string;
210
+ tab: string;
211
+ };
212
+ input: {
213
+ select: string;
214
+ focused: string;
215
+ refine: string;
216
+ down: string;
217
+ left: string;
218
+ space: string;
219
+ };
220
+ value: string;
221
+ };
222
+ onChange: {
223
+ deselect: string;
224
+ clear: string;
225
+ initialFocus: string;
226
+ selectedDisabled: string;
227
+ selected: string;
228
+ };
229
+ onFocus: {
230
+ value: string;
231
+ menu: string;
232
+ of: string;
233
+ };
234
+ onFilter: string;
235
+ };
236
+ noOptions: string;
200
237
  label: string;
238
+ createLabel: string;
201
239
  placeholder: string;
202
240
  removeTag: string;
203
- hideAllTags: string;
204
- showAllTags: string;
241
+ hideTags: string;
242
+ showTags: string;
205
243
  };
206
244
  htmlTitles: {
207
245
  titleTemplate: string;
@@ -44,11 +44,49 @@ var messages = _objectSpread(_objectSpread({
44
44
  }
45
45
  },
46
46
  tagSelector: {
47
+ aria: {
48
+ screenReaderStatus: '{{count}} resultat tilgjengeleg',
49
+ disabled: 'utilgjengeleg',
50
+ selected: 'valgt',
51
+ focused: 'fokusert',
52
+ guidance: {
53
+ menu: {
54
+ updown: 'Bruk piltastar opp og ned for å velge emneknaggar',
55
+ enter: 'trykk enter for å velge den markerte emneknaggen',
56
+ escape: 'trykk escape for å lukke menyen',
57
+ tab: 'trykk tab for å velge emneknaggen og lukke menyen'
58
+ },
59
+ input: {
60
+ select: 'Emneknagg-meny',
61
+ focused: 'er fokusert',
62
+ refine: 'skriv for å filtrere lista med emneknaggar',
63
+ down: 'trykk pil ned for å åpne menyen',
64
+ left: 'trykk venstre pil for å fokusere valgte emneknaggar',
65
+ space: 'trykk mellomrom for å opprette ny emneknagg'
66
+ },
67
+ value: 'Bruk høgre og venstre pil for å navigere mellom valgte emneknaggar, trykk backspace for å fjerne den valgte emneknaggen. Dersom ingen emneknagg er valgt fjernes den siste.'
68
+ },
69
+ onChange: {
70
+ deselect: 'emneknagg {{label}}, fjerna.',
71
+ clear: 'Alle valgte emneknaggar fjerna.',
72
+ initialFocus: "Emneknaggar {{labels}}, valgt.",
73
+ selectedDisabled: 'Emneknagg {{label}} kan ikkje velgast. Velg eit anna alternativ.',
74
+ selected: 'Emneknagg {{label}}, valgt.'
75
+ },
76
+ onFocus: {
77
+ value: 'emneknagg {{label}} fokusert, {{position}}.',
78
+ menu: 'emneknagg {{label}} {{status}}, {{position}}.',
79
+ of: 'av'
80
+ },
81
+ onFilter: ' for søkeord '
82
+ },
83
+ noOptions: 'Ingen mulige val',
47
84
  label: 'Legg til emneknagg',
85
+ createLabel: 'Legg til emneknagg {{tag}}',
48
86
  placeholder: 'Skriv inn emneknagg',
49
87
  removeTag: 'Ta vekk {{name}}',
50
- hideAllTags: 'Skjul alle emneknaggar',
51
- showAllTags: 'Vis alle emneknaggar'
88
+ hideTags: 'Skjul emneknaggar',
89
+ showTags: 'Vis emneknaggar'
52
90
  },
53
91
  htmlTitles: {
54
92
  titleTemplate: titleTemplate,
@@ -197,11 +197,49 @@ declare const messages: {
197
197
  };
198
198
  };
199
199
  tagSelector: {
200
+ aria: {
201
+ screenReaderStatus: string;
202
+ disabled: string;
203
+ selected: string;
204
+ focused: string;
205
+ guidance: {
206
+ menu: {
207
+ updown: string;
208
+ enter: string;
209
+ escape: string;
210
+ tab: string;
211
+ };
212
+ input: {
213
+ select: string;
214
+ focused: string;
215
+ refine: string;
216
+ down: string;
217
+ left: string;
218
+ space: string;
219
+ };
220
+ value: string;
221
+ };
222
+ onChange: {
223
+ deselect: string;
224
+ clear: string;
225
+ initialFocus: string;
226
+ selectedDisabled: string;
227
+ selected: string;
228
+ };
229
+ onFocus: {
230
+ value: string;
231
+ menu: string;
232
+ of: string;
233
+ };
234
+ onFilter: string;
235
+ };
236
+ noOptions: string;
200
237
  label: string;
238
+ createLabel: string;
201
239
  placeholder: string;
202
240
  removeTag: string;
203
- hideAllTags: string;
204
- showAllTags: string;
241
+ hideTags: string;
242
+ showTags: string;
205
243
  };
206
244
  htmlTitles: {
207
245
  titleTemplate: string;
@@ -44,11 +44,49 @@ var messages = _objectSpread(_objectSpread({
44
44
  }
45
45
  },
46
46
  tagSelector: {
47
+ aria: {
48
+ screenReaderStatus: '{{count}} resultater tilgjengelig',
49
+ disabled: 'utilgjengelig',
50
+ selected: 'valgt',
51
+ focused: 'fokusert',
52
+ guidance: {
53
+ menu: {
54
+ updown: 'Bruk piltaster opp og ned for å velge emneknagger',
55
+ enter: 'trykk enter for å velge den markerte emneknaggen',
56
+ escape: 'trykk escape for å lukke menyen',
57
+ tab: 'trykk tab for å velge emneknaggen og lukke menyen'
58
+ },
59
+ input: {
60
+ select: 'Emneknagg-meny',
61
+ focused: 'er fokusert',
62
+ refine: 'skriv for å filtrere listen med emneknagger',
63
+ down: 'trykk pil ned for å åpne menyen',
64
+ left: 'trykk venstre pil for å fokusere valgte emneknagger',
65
+ space: 'trykk mellomrom for å opprette ny emneknagg'
66
+ },
67
+ value: 'Bruk høyre og venstre pil for å navigere mellom valgte emneknagger, trykk backspace for å fjerne den valgte emneknaggen. Dersom ingen emneknagg er valgt fjernes den siste.'
68
+ },
69
+ onChange: {
70
+ deselect: 'emneknagg {{label}}, fjernet.',
71
+ clear: 'Alle valgte emneknagger fjernet.',
72
+ initialFocus: "Emneknagger {{labels}}, valgt.",
73
+ selectedDisabled: 'Emneknagg {{label}} kan ikke velges. Velg et annet alternativ.',
74
+ selected: 'Emneknagg {{label}}, valgt.'
75
+ },
76
+ onFocus: {
77
+ value: 'emneknagg {{label}} fokusert, {{position}}.',
78
+ menu: 'emneknagg {{label}} {{status}}, {{position}}.',
79
+ of: 'av'
80
+ },
81
+ onFilter: ' for søkeord '
82
+ },
83
+ noOptions: 'Ingen valgmuligheter',
47
84
  label: 'Bija fáddágilkora',
85
+ createLabel: 'Legg til emneknagg {{tag}}',
48
86
  placeholder: 'Čále fáddágilkora',
49
87
  removeTag: 'Váldde eret {{name}}',
50
- hideAllTags: 'Čiega buot fáddágilkoriid',
51
- showAllTags: 'Čájet buot fáddágilkoriid'
88
+ hideTags: 'Skjul emneknagger',
89
+ showTags: 'Vis emneknagger'
52
90
  },
53
91
  htmlTitles: {
54
92
  titleTemplate: titleTemplate,
@@ -197,11 +197,49 @@ declare const messages: {
197
197
  };
198
198
  };
199
199
  tagSelector: {
200
+ aria: {
201
+ screenReaderStatus: string;
202
+ disabled: string;
203
+ selected: string;
204
+ focused: string;
205
+ guidance: {
206
+ menu: {
207
+ updown: string;
208
+ enter: string;
209
+ escape: string;
210
+ tab: string;
211
+ };
212
+ input: {
213
+ select: string;
214
+ focused: string;
215
+ refine: string;
216
+ down: string;
217
+ left: string;
218
+ space: string;
219
+ };
220
+ value: string;
221
+ };
222
+ onChange: {
223
+ deselect: string;
224
+ clear: string;
225
+ initialFocus: string;
226
+ selectedDisabled: string;
227
+ selected: string;
228
+ };
229
+ onFocus: {
230
+ value: string;
231
+ menu: string;
232
+ of: string;
233
+ };
234
+ onFilter: string;
235
+ };
236
+ noOptions: string;
200
237
  label: string;
238
+ createLabel: string;
201
239
  placeholder: string;
202
240
  removeTag: string;
203
- hideAllTags: string;
204
- showAllTags: string;
241
+ hideTags: string;
242
+ showTags: string;
205
243
  };
206
244
  htmlTitles: {
207
245
  titleTemplate: string;
@@ -44,11 +44,49 @@ var messages = _objectSpread(_objectSpread({
44
44
  }
45
45
  },
46
46
  tagSelector: {
47
+ aria: {
48
+ screenReaderStatus: '{{count}} resultater tilgjengelig',
49
+ disabled: 'utilgjengelig',
50
+ selected: 'valgt',
51
+ focused: 'fokusert',
52
+ guidance: {
53
+ menu: {
54
+ updown: 'Bruk piltaster opp og ned for å velge emneknagger',
55
+ enter: 'trykk enter for å velge den markerte emneknaggen',
56
+ escape: 'trykk escape for å lukke menyen',
57
+ tab: 'trykk tab for å velge emneknaggen og lukke menyen'
58
+ },
59
+ input: {
60
+ select: 'Emneknagg-meny',
61
+ focused: 'er fokusert',
62
+ refine: 'skriv for å filtrere listen med emneknagger',
63
+ down: 'trykk pil ned for å åpne menyen',
64
+ left: 'trykk venstre pil for å fokusere valgte emneknagger',
65
+ space: 'trykk mellomrom for å opprette ny emneknagg'
66
+ },
67
+ value: 'Bruk høyre og venstre pil for å navigere mellom valgte emneknagger, trykk backspace for å fjerne den valgte emneknaggen. Dersom ingen emneknagg er valgt fjernes den siste.'
68
+ },
69
+ onChange: {
70
+ deselect: 'emneknagg {{label}}, fjernet.',
71
+ clear: 'Alle valgte emneknagger fjernet.',
72
+ initialFocus: "Emneknagger {{labels}}, valgt.",
73
+ selectedDisabled: 'Emneknagg {{label}} kan ikke velges. Velg et annet alternativ.',
74
+ selected: 'Emneknagg {{label}}, valgt.'
75
+ },
76
+ onFocus: {
77
+ value: 'emneknagg {{label}} fokusert, {{position}}.',
78
+ menu: 'emneknagg {{label}} {{status}}, {{position}}.',
79
+ of: 'av'
80
+ },
81
+ onFilter: ' for søkeord '
82
+ },
83
+ noOptions: 'Ingen valgmuligheter',
47
84
  label: 'Legg til emneknagg',
85
+ createLabel: 'Legg til emneknagg {{tag}}',
48
86
  placeholder: 'Skriv inn emneknagg',
49
87
  removeTag: 'Ta vekk {{name}}',
50
- hideAllTags: 'Skjul alle emneknagger',
51
- showAllTags: 'Vis alle emneknagger'
88
+ hideTags: 'Skjul emneknagger',
89
+ showTags: 'Vis emneknagger'
52
90
  },
53
91
  htmlTitles: {
54
92
  titleTemplate: titleTemplate,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ndla/ui",
3
- "version": "28.0.0",
3
+ "version": "29.0.0",
4
4
  "description": "UI component library for NDLA.",
5
5
  "license": "GPL-3.0",
6
6
  "main": "lib/index.js",
@@ -32,19 +32,19 @@
32
32
  ],
33
33
  "dependencies": {
34
34
  "@ndla/article-scripts": "^3.0.2",
35
- "@ndla/button": "^3.6.1",
36
- "@ndla/carousel": "^1.2.23",
37
- "@ndla/core": "^2.3.5",
38
- "@ndla/forms": "^3.3.5",
35
+ "@ndla/button": "^3.7.0",
36
+ "@ndla/carousel": "^1.2.24",
37
+ "@ndla/core": "^2.3.6",
38
+ "@ndla/forms": "^3.3.6",
39
39
  "@ndla/hooks": "^1.1.6",
40
- "@ndla/icons": "^1.13.0",
41
- "@ndla/licenses": "^5.0.17",
42
- "@ndla/modal": "^1.6.0",
43
- "@ndla/notion": "^3.1.47",
44
- "@ndla/safelink": "^2.2.19",
45
- "@ndla/switch": "^0.1.13",
46
- "@ndla/tabs": "^1.1.22",
47
- "@ndla/tooltip": "^2.2.1",
40
+ "@ndla/icons": "^1.14.0",
41
+ "@ndla/licenses": "^5.0.18",
42
+ "@ndla/modal": "^1.6.1",
43
+ "@ndla/notion": "^3.1.48",
44
+ "@ndla/safelink": "^2.2.20",
45
+ "@ndla/switch": "^0.1.14",
46
+ "@ndla/tabs": "^1.1.23",
47
+ "@ndla/tooltip": "^2.2.2",
48
48
  "@ndla/types-learningpath-api": "^0.0.13",
49
49
  "@ndla/util": "^3.1.0",
50
50
  "@reach/menu-button": "^0.16.2",
@@ -58,6 +58,7 @@
58
58
  "lodash": "^4.17.20",
59
59
  "react-bem-helper": "1.4.1",
60
60
  "react-device-detect": "^2.1.2",
61
+ "react-select": "^5.4.0",
61
62
  "react-swipeable": "^6.2.0",
62
63
  "react-transition-group": "^2.5.3",
63
64
  "remarkable": "^2.0.1",
@@ -85,5 +86,5 @@
85
86
  "publishConfig": {
86
87
  "access": "public"
87
88
  },
88
- "gitHead": "f7cac264e9855369dc3061fc240ece485de041bb"
89
+ "gitHead": "2c5d6b7038c442a871b4cd69247d243cadd129da"
89
90
  }
@@ -216,7 +216,7 @@ const ListResource = ({
216
216
  const showDescription = description !== undefined;
217
217
  const imageType = showDescription ? 'normal' : 'compact';
218
218
  const linkRef = useRef<HTMLAnchorElement>(null);
219
- const firstContentType = resourceTypes?.[0].id ?? '';
219
+ const firstContentType = resourceTypes?.[0]?.id ?? '';
220
220
  const Title = ResourceTitle.withComponent(headingLevel);
221
221
  const handleClick = () => {
222
222
  if (linkRef.current) {
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Copyright (c) 2022-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import styled from '@emotion/styled';
10
+ import { spacing, utils } from '@ndla/core';
11
+ import React from 'react';
12
+ import { ControlProps } from 'react-select';
13
+ import { TagType } from './types';
14
+
15
+ const StyledTagSelectorControl = styled.div`
16
+ display: flex;
17
+ flex-wrap: wrap;
18
+ justify-content: space-between;
19
+ align-items: center;
20
+ margin: ${spacing.xxsmall};
21
+
22
+ overflow: overlay;
23
+ ${utils.scrollbar}
24
+ `;
25
+
26
+ const Control = ({ innerProps, children, innerRef }: ControlProps<TagType, true>) => {
27
+ return (
28
+ <StyledTagSelectorControl ref={innerRef} {...innerProps}>
29
+ {children}
30
+ </StyledTagSelectorControl>
31
+ );
32
+ };
33
+
34
+ export default Control;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Copyright (c) 2022-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import { ChevronDown, ChevronUp } from '@ndla/icons/common';
10
+ import React, { useMemo } from 'react';
11
+ import styled from '@emotion/styled';
12
+ import { useTranslation } from 'react-i18next';
13
+ import { DropdownIndicatorProps, components } from 'react-select';
14
+ import { iconButtonStyle } from '@ndla/button';
15
+ import { TagType } from './types';
16
+
17
+ const StyledIconWrapper = styled.span`
18
+ svg {
19
+ pointer-events: none;
20
+ }
21
+ `;
22
+
23
+ const DropdownIndicator = ({ selectProps, children, ...props }: DropdownIndicatorProps<TagType, true>) => {
24
+ const { t } = useTranslation();
25
+
26
+ const { menuIsOpen } = selectProps;
27
+ const Icon = menuIsOpen ? ChevronUp : ChevronDown;
28
+
29
+ const css = useMemo(
30
+ () => iconButtonStyle({ colorTheme: 'greyLighter', variant: 'ghost', shape: 'pill', size: 'small' }),
31
+ [],
32
+ );
33
+
34
+ return (
35
+ <components.DropdownIndicator
36
+ css={css}
37
+ {...props}
38
+ selectProps={selectProps}
39
+ aria-label={menuIsOpen ? t('tagSelector.hideTags') : t('tagSelector.showTags')}>
40
+ <StyledIconWrapper aria-hidden>
41
+ <Icon />
42
+ </StyledIconWrapper>
43
+ </components.DropdownIndicator>
44
+ );
45
+ };
46
+
47
+ export default DropdownIndicator;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Copyright (c) 2022-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import css from '@emotion/css';
10
+ import { colors, spacing } from '@ndla/core';
11
+ import React from 'react';
12
+ import { components, InputProps } from 'react-select';
13
+ import { TagType } from './types';
14
+ import { StyledValueButton } from './ValueButton';
15
+
16
+ const inputStyle = css`
17
+ && {
18
+ padding: 0 ${spacing.small};
19
+ color: ${colors.brand.primary};
20
+ margin: 0;
21
+ ${StyledValueButton} + & {
22
+ padding-left: ${spacing.xxsmall};
23
+ }
24
+ }
25
+ `;
26
+
27
+ const Input = (props: InputProps<TagType, true>) => {
28
+ return <components.Input css={inputStyle} {...props} />;
29
+ };
30
+
31
+ export default Input;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Copyright (c) 2022-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import css from '@emotion/css';
10
+ import { colors } from '@ndla/core';
11
+ import React from 'react';
12
+ import { MenuProps, components } from 'react-select';
13
+ import { StyledMenuList } from './MenuList';
14
+ import { TagType } from './types';
15
+
16
+ const menuStyle = css`
17
+ display: flex;
18
+ position: relative;
19
+ flex-direction: column;
20
+ margin: 0;
21
+ overflow: hidden;
22
+ border-top: 1px solid ${colors.brand.tertiary};
23
+ min-height: 70px;
24
+
25
+ :has(${StyledMenuList}>*:only-child) {
26
+ min-height: 40px;
27
+ }
28
+ `;
29
+
30
+ const Menu = ({ children, ...props }: MenuProps<TagType, true>) => {
31
+ return (
32
+ <components.Menu css={menuStyle} {...props}>
33
+ {children}
34
+ </components.Menu>
35
+ );
36
+ };
37
+
38
+ export default Menu;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Copyright (c) 2022-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import styled from '@emotion/styled';
10
+ import { utils } from '@ndla/core';
11
+ import React from 'react';
12
+ import { MenuListProps } from 'react-select';
13
+ import { TagType } from './types';
14
+
15
+ export const StyledMenuList = styled.div`
16
+ overflow: overlay;
17
+ ${utils.scrollbar}
18
+ display: flex;
19
+ flex-direction: column;
20
+ `;
21
+
22
+ const MenuList = ({ innerProps, innerRef, children }: MenuListProps<TagType, true>) => {
23
+ return (
24
+ <StyledMenuList ref={innerRef} {...innerProps}>
25
+ {children}
26
+ </StyledMenuList>
27
+ );
28
+ };
29
+
30
+ export default MenuList;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Copyright (c) 2022-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import React from 'react';
10
+ import { OptionProps } from 'react-select';
11
+ import { buttonStyleV2 as buttonStyle } from '@ndla/button';
12
+ import styled from '@emotion/styled';
13
+ import { colors, fonts } from '@ndla/core';
14
+ import { Done } from '@ndla/icons/editor';
15
+ import { TagType } from './types';
16
+
17
+ interface StyledProps {
18
+ selected: boolean;
19
+ focused: boolean;
20
+ }
21
+
22
+ const StyledMenuOption = styled.div<StyledProps>`
23
+ && {
24
+ background: ${({ focused }) => focused && colors.brand.lighter};
25
+ color: ${({ focused }) => focused && colors.brand.primary};
26
+ justify-content: space-between;
27
+ ${fonts.sizes(16)};
28
+ font-weight: ${fonts.weight.normal};
29
+ color: ${({ selected }) => selected && colors.brand.grey};
30
+ }
31
+ `;
32
+
33
+ const StyledCheck = styled(Done)`
34
+ width: 24px;
35
+ height: 24px;
36
+ fill: ${colors.brand.tertiary};
37
+ `;
38
+
39
+ const Option = ({ innerProps, innerRef, children, isSelected, isFocused }: OptionProps<TagType, true>) => {
40
+ return (
41
+ <StyledMenuOption
42
+ focused={isFocused}
43
+ selected={isSelected}
44
+ css={buttonStyle({ colorTheme: 'lighter', variant: 'ghost', shape: 'sharp' })}
45
+ ref={innerRef}
46
+ {...innerProps}>
47
+ {children}
48
+ {isSelected && <StyledCheck />}
49
+ </StyledMenuOption>
50
+ );
51
+ };
52
+
53
+ export default Option;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Copyright (c) 2022-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import styled from '@emotion/styled';
10
+ import { colors, fonts, misc } from '@ndla/core';
11
+ import React from 'react';
12
+ import { ContainerProps } from 'react-select';
13
+ import { TagType } from './types';
14
+
15
+ const StyledContainer = styled.div`
16
+ display: grid;
17
+ grid-template-rows: auto 1fr;
18
+ overflow: hidden;
19
+
20
+ border: 1px solid ${colors.brand.neutral7};
21
+ border-radius: ${misc.borderRadius};
22
+ &:focus-within {
23
+ border-color: ${colors.brand.tertiary};
24
+ }
25
+ ${fonts.sizes(16)};
26
+ `;
27
+
28
+ const SelectContainer = ({ innerProps, selectProps, children }: ContainerProps<TagType, true>) => {
29
+ return <StyledContainer {...innerProps}>{children}</StyledContainer>;
30
+ };
31
+
32
+ export default SelectContainer;