@ndla/video-search 8.0.38-alpha.0 → 8.0.40-alpha.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.
@@ -33,6 +33,7 @@ const StyledVideoResultWrapper = styled("div", {
33
33
  export const VideoResultList = _ref => {
34
34
  let {
35
35
  videos,
36
+ existsMoreVideos,
36
37
  isLoading,
37
38
  translations,
38
39
  locale,
@@ -51,7 +52,7 @@ export const VideoResultList = _ref => {
51
52
  }, `${video.id}-${index}`))
52
53
  }), isLoading && /*#__PURE__*/_jsx(SpinnerWrapper, {
53
54
  children: /*#__PURE__*/_jsx(Spinner, {})
54
- }), !!videos.length && /*#__PURE__*/_jsx(Button, {
55
+ }), existsMoreVideos && /*#__PURE__*/_jsx(Button, {
55
56
  onClick: onShowMore,
56
57
  children: translations.loadMoreVideos
57
58
  })]
package/es/VideoSearch.js CHANGED
@@ -10,7 +10,6 @@ import { useCallback, useEffect, useState } from "react";
10
10
  import { SearchLine } from "@ndla/icons/common";
11
11
  import { IconButton, Input } from "@ndla/primitives";
12
12
  import { styled } from "@ndla/styled-system/jsx";
13
- import { usePrevious } from "@ndla/util";
14
13
  import { VideoResultList } from "./VideoResultList";
15
14
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
16
15
  const VideoSearchWrapper = styled("div", {
@@ -20,12 +19,13 @@ const VideoSearchWrapper = styled("div", {
20
19
  gap: "xsmall"
21
20
  }
22
21
  });
23
- const StyledForm = styled("form", {
22
+ const InputWrapper = styled("div", {
24
23
  base: {
25
24
  display: "flex",
26
25
  gap: "xsmall"
27
26
  }
28
27
  });
28
+ const VIDEO_FETCH_LIMIT = 10;
29
29
  export const VideoSearch = _ref => {
30
30
  let {
31
31
  onVideoSelect,
@@ -38,53 +38,57 @@ export const VideoSearch = _ref => {
38
38
  const [offset, setOffset] = useState(0);
39
39
  const [videos, setVideos] = useState([]);
40
40
  const [isLoading, setIsLoading] = useState(false);
41
- const previousQuery = usePrevious(query);
42
- const fetchVideos = useCallback(async (query, offset) => {
41
+ const fetchVideos = useCallback(async (query, offset, isAppending) => {
43
42
  setIsLoading(true);
44
43
  try {
45
- const isAppending = query === previousQuery;
46
44
  const results = await searchVideos({
47
45
  query,
48
46
  offset: offset,
49
- limit: 10
47
+ limit: VIDEO_FETCH_LIMIT
50
48
  });
51
49
  setVideos(prev => isAppending ? prev.concat(results) : results);
52
50
  } catch (e) {
53
51
  onError(e);
54
52
  }
55
53
  setIsLoading(false);
56
- }, [searchVideos, previousQuery, onError]);
54
+ }, [searchVideos, onError]);
57
55
  useEffect(() => {
58
56
  fetchVideos("", 0);
59
57
  // eslint-disable-next-line react-hooks/exhaustive-deps
60
58
  }, []);
61
- const onSubmit = useCallback(e => {
62
- e.preventDefault();
63
- e.stopPropagation();
59
+ const onSearch = useCallback(() => {
64
60
  setOffset(0);
65
- fetchVideos(query, offset);
66
- }, [fetchVideos, offset, query]);
61
+ fetchVideos(query, 0);
62
+ }, [fetchVideos, query]);
67
63
  const onShowMore = useCallback(() => {
68
- const newOffset = offset + 10;
64
+ const newOffset = offset + VIDEO_FETCH_LIMIT;
69
65
  setOffset(newOffset);
70
- fetchVideos(query, newOffset);
66
+ fetchVideos(query, newOffset, true);
71
67
  }, [fetchVideos, offset, query]);
72
68
  const onQueryChange = useCallback(e => {
73
69
  setQuery(e.target.value);
74
70
  }, []);
71
+ const onEnter = e => {
72
+ if (e.key === "Enter") {
73
+ onSearch();
74
+ }
75
+ };
75
76
  return /*#__PURE__*/_jsxs(VideoSearchWrapper, {
76
- children: [/*#__PURE__*/_jsxs(StyledForm, {
77
- onSubmit: onSubmit,
77
+ children: [/*#__PURE__*/_jsxs(InputWrapper, {
78
+ role: "search",
78
79
  children: [/*#__PURE__*/_jsx(Input, {
79
80
  type: "search",
80
81
  placeholder: translations.searchPlaceholder,
81
82
  value: query,
82
- onChange: onQueryChange
83
+ onChange: onQueryChange,
84
+ onKeyDown: onEnter
83
85
  }), /*#__PURE__*/_jsx(IconButton, {
84
86
  variant: "primary",
85
87
  type: "submit",
86
88
  "aria-label": translations.searchButtonTitle,
87
89
  title: translations.searchButtonTitle,
90
+ onKeyDown: onEnter,
91
+ onClick: onSearch,
88
92
  children: /*#__PURE__*/_jsx(SearchLine, {})
89
93
  })]
90
94
  }), /*#__PURE__*/_jsx(VideoResultList, {
@@ -93,7 +97,8 @@ export const VideoSearch = _ref => {
93
97
  translations: translations,
94
98
  locale: locale,
95
99
  onVideoSelect: onVideoSelect,
96
- onShowMore: onShowMore
100
+ onShowMore: onShowMore,
101
+ existsMoreVideos: videos.length === offset + VIDEO_FETCH_LIMIT
97
102
  })]
98
103
  });
99
104
  };
@@ -9,11 +9,12 @@ import { BrightcoveApiType } from "@ndla/types-embed";
9
9
  import { VideoTranslations } from "./VideoSearch";
10
10
  interface Props {
11
11
  videos: BrightcoveApiType[];
12
+ existsMoreVideos: boolean;
12
13
  isLoading: boolean;
13
14
  translations: VideoTranslations;
14
15
  locale: string;
15
16
  onVideoSelect: (video: BrightcoveApiType) => void;
16
17
  onShowMore: () => void;
17
18
  }
18
- export declare const VideoResultList: ({ videos, isLoading, translations, locale, onVideoSelect, onShowMore }: Props) => import("react/jsx-runtime").JSX.Element;
19
+ export declare const VideoResultList: ({ videos, existsMoreVideos, isLoading, translations, locale, onVideoSelect, onShowMore, }: Props) => import("react/jsx-runtime").JSX.Element;
19
20
  export {};
@@ -39,6 +39,7 @@ const StyledVideoResultWrapper = (0, _jsx2.styled)("div", {
39
39
  const VideoResultList = _ref => {
40
40
  let {
41
41
  videos,
42
+ existsMoreVideos,
42
43
  isLoading,
43
44
  translations,
44
45
  locale,
@@ -57,7 +58,7 @@ const VideoResultList = _ref => {
57
58
  }, `${video.id}-${index}`))
58
59
  }), isLoading && /*#__PURE__*/(0, _jsxRuntime.jsx)(SpinnerWrapper, {
59
60
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.Spinner, {})
60
- }), !!videos.length && /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.Button, {
61
+ }), existsMoreVideos && /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.Button, {
61
62
  onClick: onShowMore,
62
63
  children: translations.loadMoreVideos
63
64
  })]
@@ -8,7 +8,6 @@ var _react = require("react");
8
8
  var _common = require("@ndla/icons/common");
9
9
  var _primitives = require("@ndla/primitives");
10
10
  var _jsx2 = require("@ndla/styled-system/jsx");
11
- var _util = require("@ndla/util");
12
11
  var _VideoResultList = require("./VideoResultList");
13
12
  var _jsxRuntime = require("react/jsx-runtime");
14
13
  /**
@@ -26,12 +25,13 @@ const VideoSearchWrapper = (0, _jsx2.styled)("div", {
26
25
  gap: "xsmall"
27
26
  }
28
27
  });
29
- const StyledForm = (0, _jsx2.styled)("form", {
28
+ const InputWrapper = (0, _jsx2.styled)("div", {
30
29
  base: {
31
30
  display: "flex",
32
31
  gap: "xsmall"
33
32
  }
34
33
  });
34
+ const VIDEO_FETCH_LIMIT = 10;
35
35
  const VideoSearch = _ref => {
36
36
  let {
37
37
  onVideoSelect,
@@ -44,53 +44,57 @@ const VideoSearch = _ref => {
44
44
  const [offset, setOffset] = (0, _react.useState)(0);
45
45
  const [videos, setVideos] = (0, _react.useState)([]);
46
46
  const [isLoading, setIsLoading] = (0, _react.useState)(false);
47
- const previousQuery = (0, _util.usePrevious)(query);
48
- const fetchVideos = (0, _react.useCallback)(async (query, offset) => {
47
+ const fetchVideos = (0, _react.useCallback)(async (query, offset, isAppending) => {
49
48
  setIsLoading(true);
50
49
  try {
51
- const isAppending = query === previousQuery;
52
50
  const results = await searchVideos({
53
51
  query,
54
52
  offset: offset,
55
- limit: 10
53
+ limit: VIDEO_FETCH_LIMIT
56
54
  });
57
55
  setVideos(prev => isAppending ? prev.concat(results) : results);
58
56
  } catch (e) {
59
57
  onError(e);
60
58
  }
61
59
  setIsLoading(false);
62
- }, [searchVideos, previousQuery, onError]);
60
+ }, [searchVideos, onError]);
63
61
  (0, _react.useEffect)(() => {
64
62
  fetchVideos("", 0);
65
63
  // eslint-disable-next-line react-hooks/exhaustive-deps
66
64
  }, []);
67
- const onSubmit = (0, _react.useCallback)(e => {
68
- e.preventDefault();
69
- e.stopPropagation();
65
+ const onSearch = (0, _react.useCallback)(() => {
70
66
  setOffset(0);
71
- fetchVideos(query, offset);
72
- }, [fetchVideos, offset, query]);
67
+ fetchVideos(query, 0);
68
+ }, [fetchVideos, query]);
73
69
  const onShowMore = (0, _react.useCallback)(() => {
74
- const newOffset = offset + 10;
70
+ const newOffset = offset + VIDEO_FETCH_LIMIT;
75
71
  setOffset(newOffset);
76
- fetchVideos(query, newOffset);
72
+ fetchVideos(query, newOffset, true);
77
73
  }, [fetchVideos, offset, query]);
78
74
  const onQueryChange = (0, _react.useCallback)(e => {
79
75
  setQuery(e.target.value);
80
76
  }, []);
77
+ const onEnter = e => {
78
+ if (e.key === "Enter") {
79
+ onSearch();
80
+ }
81
+ };
81
82
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(VideoSearchWrapper, {
82
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(StyledForm, {
83
- onSubmit: onSubmit,
83
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(InputWrapper, {
84
+ role: "search",
84
85
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.Input, {
85
86
  type: "search",
86
87
  placeholder: translations.searchPlaceholder,
87
88
  value: query,
88
- onChange: onQueryChange
89
+ onChange: onQueryChange,
90
+ onKeyDown: onEnter
89
91
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.IconButton, {
90
92
  variant: "primary",
91
93
  type: "submit",
92
94
  "aria-label": translations.searchButtonTitle,
93
95
  title: translations.searchButtonTitle,
96
+ onKeyDown: onEnter,
97
+ onClick: onSearch,
94
98
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.SearchLine, {})
95
99
  })]
96
100
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_VideoResultList.VideoResultList, {
@@ -99,7 +103,8 @@ const VideoSearch = _ref => {
99
103
  translations: translations,
100
104
  locale: locale,
101
105
  onVideoSelect: onVideoSelect,
102
- onShowMore: onShowMore
106
+ onShowMore: onShowMore,
107
+ existsMoreVideos: videos.length === offset + VIDEO_FETCH_LIMIT
103
108
  })]
104
109
  });
105
110
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ndla/video-search",
3
- "version": "8.0.38-alpha.0",
3
+ "version": "8.0.40-alpha.0",
4
4
  "description": "A simple library for searching NDLA videos",
5
5
  "license": "GPL-3.0",
6
6
  "main": "lib/index.js",
@@ -26,14 +26,14 @@
26
26
  "es"
27
27
  ],
28
28
  "dependencies": {
29
- "@ndla/icons": "^8.0.27-alpha.0",
29
+ "@ndla/icons": "^8.0.28-alpha.0",
30
30
  "@ndla/licenses": "^8.0.3-alpha.0",
31
- "@ndla/primitives": "^1.0.38-alpha.0",
31
+ "@ndla/primitives": "^1.0.40-alpha.0",
32
32
  "@ndla/styled-system": "^0.0.23",
33
33
  "@ndla/util": "^5.0.0-alpha.0"
34
34
  },
35
35
  "devDependencies": {
36
- "@ndla/preset-panda": "^0.0.36",
36
+ "@ndla/preset-panda": "^0.0.37",
37
37
  "@ndla/types-embed": "^5.0.3-alpha.0",
38
38
  "@pandacss/dev": "^0.46.0"
39
39
  },
@@ -44,5 +44,5 @@
44
44
  "publishConfig": {
45
45
  "access": "public"
46
46
  },
47
- "gitHead": "fa8b235f77c036a235f87c3e5875a2e938cb0ccd"
47
+ "gitHead": "e79c68709bfa94d73a608d460f271f41f9f04e09"
48
48
  }