@ndla/video-search 8.0.155-alpha.0 → 8.0.156-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.
package/es/VideoListItem.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoListItem.mjs","names":[],"sources":["../src/VideoListItem.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { CloseLine, PanoramaPhotosphere } from \"@ndla/icons\";\nimport { getLicenseByNBTitle, type LicenseLocaleType } from \"@ndla/licenses\";\nimport { Image, Text, ListItemContent, ListItemRoot, Button, IconButton } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { BrightcoveApiType } from \"@ndla/types-embed\";\nimport { useState } from \"react\";\nimport type { VideoTranslations } from \"./types\";\n\nconst ButtonWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n gap: \"small\",\n },\n});\n\nconst PreviewIframe = styled(\"iframe\", {\n base: {\n minHeight: \"surface.xxsmall\",\n },\n});\n\nconst PreviewWrapper = styled(\"div\", {\n base: {\n display: \"grid\",\n gap: \"xsmall\",\n gridTemplateColumns: \"repeat(3,1fr)\",\n padding: \"small\",\n borderBlockEnd: \"1px solid\",\n borderColor: \"stroke.subtle\",\n },\n});\n\nconst StyledImage = styled(Image, {\n base: {\n minWidth: \"surface.xxsmall\",\n height: \"surface.4xsmall\",\n objectFit: \"cover\",\n border: \"1px solid\",\n borderColor: \"stroke.subtle\",\n },\n});\n\nconst StyledVideoMeta = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"xxsmall\",\n },\n});\nconst StyledListItemContent = styled(ListItemContent, {\n base: {\n alignItems: \"flex-end\",\n tabletDown: {\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n },\n },\n});\n\nconst StyledIconButton = styled(IconButton, {\n base: {\n marginLeft: \"auto\",\n },\n});\n\nconst StyledListItemRoot = styled(ListItemRoot, {\n base: {\n paddingBlock: \"medium\",\n tabletDown: {\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n },\n },\n});\n\ninterface LicenseProps {\n license: LicenseLocaleType | string;\n}\nconst License = ({ license }: LicenseProps) => {\n if (typeof license === \"string\") return <Text>{license}</Text>;\n if (license.url?.length) {\n return (\n <a href={license.url} rel=\"license\">\n {license.abbreviation}\n </a>\n );\n }\n return <Text>{license.abbreviation}</Text>;\n};\n\ninterface VideoListItemProps {\n video: BrightcoveApiType;\n translations: VideoTranslations;\n locale: string;\n onVideoSelect: (video: BrightcoveApiType) => void;\n}\n\nexport const VideoListItem = ({ video, onVideoSelect, translations, locale }: VideoListItemProps) => {\n const [isPreviewing, setIsPreviewing] = useState(false);\n const license = video.custom_fields?.license ? getLicenseByNBTitle(video.custom_fields.license, locale) : \"\";\n\n return (\n <li>\n <StyledListItemRoot nonInteractive>\n <StyledImage src={video.images?.thumbnail?.src} alt=\"\" variant=\"rounded\" />\n <StyledListItemContent>\n <StyledVideoMeta>\n <Text textStyle=\"title.medium\">\n {video.name}\n {video.projection === \"equirectangular\" && (\n <PanoramaPhotosphere\n aria-hidden={false}\n aria-label={translations.is360Video}\n title={translations.is360Video}\n />\n )}\n </Text>\n <Text>{video.custom_fields?.licenseinfo ?? \"\"}</Text>\n <License license={license} />\n </StyledVideoMeta>\n <ButtonWrapper>\n <Button\n variant=\"secondary\"\n size=\"small\"\n onClick={() => setIsPreviewing((p) => !p)}\n aria-expanded={isPreviewing}\n aria-controls={`video-preview-${video.id}`}\n >\n {translations.previewVideo}\n </Button>\n <Button size=\"small\" onClick={() => onVideoSelect(video)}>\n {translations.addVideo}\n </Button>\n </ButtonWrapper>\n </StyledListItemContent>\n </StyledListItemRoot>\n {!!isPreviewing && (\n <PreviewWrapper id={`video-preview-${video.id}`}>\n <div />\n <PreviewIframe\n title={video.name}\n src={`//players.brightcove.net/${video.account_id}/BkLm8fT_default/index.html?videoId=${video.id}`}\n allowFullScreen\n />\n <StyledIconButton\n variant=\"secondary\"\n aria-label={translations.close}\n title={translations.close}\n onClick={() => setIsPreviewing(false)}\n >\n <CloseLine />\n </StyledIconButton>\n </PreviewWrapper>\n )}\n </li>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;AAgBA,MAAM,gBAAgB,OAAO,OAAO,EAClC,MAAM;CACJ,SAAS;CACT,KAAK;
|
|
1
|
+
{"version":3,"file":"VideoListItem.mjs","names":[],"sources":["../src/VideoListItem.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { CloseLine, PanoramaPhotosphere } from \"@ndla/icons\";\nimport { getLicenseByNBTitle, type LicenseLocaleType } from \"@ndla/licenses\";\nimport { Image, Text, ListItemContent, ListItemRoot, Button, IconButton } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { BrightcoveApiType } from \"@ndla/types-embed\";\nimport { useState } from \"react\";\nimport type { VideoTranslations } from \"./types\";\n\nconst ButtonWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n gap: \"small\",\n },\n});\n\nconst PreviewIframe = styled(\"iframe\", {\n base: {\n minHeight: \"surface.xxsmall\",\n },\n});\n\nconst PreviewWrapper = styled(\"div\", {\n base: {\n display: \"grid\",\n gap: \"xsmall\",\n gridTemplateColumns: \"repeat(3,1fr)\",\n padding: \"small\",\n borderBlockEnd: \"1px solid\",\n borderColor: \"stroke.subtle\",\n },\n});\n\nconst StyledImage = styled(Image, {\n base: {\n minWidth: \"surface.xxsmall\",\n height: \"surface.4xsmall\",\n objectFit: \"cover\",\n border: \"1px solid\",\n borderColor: \"stroke.subtle\",\n },\n});\n\nconst StyledVideoMeta = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"xxsmall\",\n },\n});\nconst StyledListItemContent = styled(ListItemContent, {\n base: {\n alignItems: \"flex-end\",\n tabletDown: {\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n },\n },\n});\n\nconst StyledIconButton = styled(IconButton, {\n base: {\n marginLeft: \"auto\",\n },\n});\n\nconst StyledListItemRoot = styled(ListItemRoot, {\n base: {\n paddingBlock: \"medium\",\n tabletDown: {\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n },\n },\n});\n\ninterface LicenseProps {\n license: LicenseLocaleType | string;\n}\nconst License = ({ license }: LicenseProps) => {\n if (typeof license === \"string\") return <Text>{license}</Text>;\n if (license.url?.length) {\n return (\n <a href={license.url} rel=\"license\">\n {license.abbreviation}\n </a>\n );\n }\n return <Text>{license.abbreviation}</Text>;\n};\n\ninterface VideoListItemProps {\n video: BrightcoveApiType;\n translations: VideoTranslations;\n locale: string;\n onVideoSelect: (video: BrightcoveApiType) => void;\n}\n\nexport const VideoListItem = ({ video, onVideoSelect, translations, locale }: VideoListItemProps) => {\n const [isPreviewing, setIsPreviewing] = useState(false);\n const license = video.custom_fields?.license ? getLicenseByNBTitle(video.custom_fields.license, locale) : \"\";\n\n return (\n <li>\n <StyledListItemRoot nonInteractive>\n <StyledImage src={video.images?.thumbnail?.src} alt=\"\" variant=\"rounded\" />\n <StyledListItemContent>\n <StyledVideoMeta>\n <Text textStyle=\"title.medium\">\n {video.name}\n {video.projection === \"equirectangular\" && (\n <PanoramaPhotosphere\n aria-hidden={false}\n aria-label={translations.is360Video}\n title={translations.is360Video}\n />\n )}\n </Text>\n <Text>{video.custom_fields?.licenseinfo ?? \"\"}</Text>\n <License license={license} />\n </StyledVideoMeta>\n <ButtonWrapper>\n <Button\n variant=\"secondary\"\n size=\"small\"\n onClick={() => setIsPreviewing((p) => !p)}\n aria-expanded={isPreviewing}\n aria-controls={`video-preview-${video.id}`}\n >\n {translations.previewVideo}\n </Button>\n <Button size=\"small\" onClick={() => onVideoSelect(video)}>\n {translations.addVideo}\n </Button>\n </ButtonWrapper>\n </StyledListItemContent>\n </StyledListItemRoot>\n {!!isPreviewing && (\n <PreviewWrapper id={`video-preview-${video.id}`}>\n <div />\n <PreviewIframe\n title={video.name}\n src={`//players.brightcove.net/${video.account_id}/BkLm8fT_default/index.html?videoId=${video.id}`}\n allowFullScreen\n />\n <StyledIconButton\n variant=\"secondary\"\n aria-label={translations.close}\n title={translations.close}\n onClick={() => setIsPreviewing(false)}\n >\n <CloseLine />\n </StyledIconButton>\n </PreviewWrapper>\n )}\n </li>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoResultList.mjs","names":[],"sources":["../src/VideoResultList.tsx"],"sourcesContent":["/**\n * Copyright (c) 2017-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { Text, Button, Spinner } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { BrightcoveApiType } from \"@ndla/types-embed\";\nimport type { VideoTranslations } from \"./types\";\nimport { VideoListItem } from \"./VideoListItem\";\n\nconst StyledList = styled(\"ul\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"xxsmall\",\n listStyle: \"none\",\n width: \"100%\",\n },\n});\n\nconst StyledVideoResultWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"medium\",\n alignItems: \"center\",\n },\n});\n\ninterface Props {\n videos: BrightcoveApiType[];\n existsMoreVideos: boolean;\n isLoading: boolean;\n translations: VideoTranslations;\n locale: string;\n onVideoSelect: (video: BrightcoveApiType) => void;\n onShowMore: () => void;\n}\n\nexport const VideoResultList = ({\n videos,\n existsMoreVideos,\n isLoading,\n translations,\n locale,\n onVideoSelect,\n onShowMore,\n}: Props) => {\n return (\n <StyledVideoResultWrapper>\n {!videos.length && !isLoading ? (\n <Text>{translations.noResults}</Text>\n ) : (\n <StyledList>\n {videos.map((video, index) => (\n <VideoListItem\n key={`${video.id}-${index}`}\n video={video}\n translations={translations}\n locale={locale}\n onVideoSelect={onVideoSelect}\n />\n ))}\n </StyledList>\n )}\n {!!isLoading && <Spinner />}\n {!!existsMoreVideos && <Button onClick={onShowMore}>{translations.loadMoreVideos}</Button>}\n </StyledVideoResultWrapper>\n );\n};\n"],"mappings":";;;;;;;;;;;;AAcA,MAAM,aAAa,OAAO,MAAM,EAC9B,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;CACL,WAAW;CACX,OAAO;
|
|
1
|
+
{"version":3,"file":"VideoResultList.mjs","names":[],"sources":["../src/VideoResultList.tsx"],"sourcesContent":["/**\n * Copyright (c) 2017-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { Text, Button, Spinner } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { BrightcoveApiType } from \"@ndla/types-embed\";\nimport type { VideoTranslations } from \"./types\";\nimport { VideoListItem } from \"./VideoListItem\";\n\nconst StyledList = styled(\"ul\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"xxsmall\",\n listStyle: \"none\",\n width: \"100%\",\n },\n});\n\nconst StyledVideoResultWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"medium\",\n alignItems: \"center\",\n },\n});\n\ninterface Props {\n videos: BrightcoveApiType[];\n existsMoreVideos: boolean;\n isLoading: boolean;\n translations: VideoTranslations;\n locale: string;\n onVideoSelect: (video: BrightcoveApiType) => void;\n onShowMore: () => void;\n}\n\nexport const VideoResultList = ({\n videos,\n existsMoreVideos,\n isLoading,\n translations,\n locale,\n onVideoSelect,\n onShowMore,\n}: Props) => {\n return (\n <StyledVideoResultWrapper>\n {!videos.length && !isLoading ? (\n <Text>{translations.noResults}</Text>\n ) : (\n <StyledList>\n {videos.map((video, index) => (\n <VideoListItem\n key={`${video.id}-${index}`}\n video={video}\n translations={translations}\n locale={locale}\n onVideoSelect={onVideoSelect}\n />\n ))}\n </StyledList>\n )}\n {!!isLoading && <Spinner />}\n {!!existsMoreVideos && <Button onClick={onShowMore}>{translations.loadMoreVideos}</Button>}\n </StyledVideoResultWrapper>\n );\n};\n"],"mappings":";;;;;;;;;;;;AAcA,MAAM,aAAa,OAAO,MAAM,EAC9B,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;CACL,WAAW;CACX,OAAO;AACT,EACF,CAAC;AAED,MAAM,2BAA2B,OAAO,OAAO,EAC7C,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;CACL,YAAY;AACd,EACF,CAAC;AAYD,MAAa,mBAAmB,EAC9B,QACA,kBACA,WACA,cACA,QACA,eACA,iBACW;CACX,OACE,qBAAC,0BAAD,EAAA,UAAA;EACG,CAAC,OAAO,UAAU,CAAC,YAClB,oBAAC,MAAD,EAAA,UAAO,aAAa,UAAgB,CAAA,IAEpC,oBAAC,YAAD,EAAA,UACG,OAAO,KAAK,OAAO,UAClB,oBAAC,eAAD;GAES;GACO;GACN;GACO;EAChB,GALM,GAAG,MAAM,GAAG,GAAG,OAKrB,CACF,EACS,CAAA;EAEb,CAAC,CAAC,aAAa,oBAAC,SAAD,CAAU,CAAA;EACzB,CAAC,CAAC,oBAAoB,oBAAC,QAAD;GAAQ,SAAS;aAAa,aAAa;EAAuB,CAAA;CACjE,EAAA,CAAA;AAE9B"}
|
package/es/VideoSearch.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoSearch.mjs","names":[],"sources":["../src/VideoSearch.tsx"],"sourcesContent":["/**\n * Copyright (c) 2017-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { SearchLine } from \"@ndla/icons\";\nimport { IconButton, Input } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { BrightcoveApiType } from \"@ndla/types-embed\";\nimport { type ChangeEvent, useCallback, useEffect, useState, type KeyboardEvent } from \"react\";\nimport type { VideoTranslations } from \"./types\";\nimport { VideoResultList } from \"./VideoResultList\";\n\ninterface Props {\n onVideoSelect: (video: BrightcoveApiType) => void;\n searchVideos: (query: VideoQueryType) => Promise<BrightcoveApiType[]>;\n onError: (e: unknown) => void;\n translations: VideoTranslations;\n locale: string;\n}\n\nexport interface VideoQueryType {\n query: string;\n offset: number;\n limit: number;\n}\n\nconst VideoSearchWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"xsmall\",\n },\n});\n\nconst InputWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n gap: \"xsmall\",\n },\n});\n\nconst VIDEO_FETCH_LIMIT = 10;\n\nexport const VideoSearch = ({ onVideoSelect, searchVideos, onError, translations, locale }: Props) => {\n const [query, setQuery] = useState(\"\");\n const [offset, setOffset] = useState(0);\n const [videos, setVideos] = useState<BrightcoveApiType[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n\n const fetchVideos = useCallback(\n async (query: string, offset: number, isAppending?: boolean) => {\n setIsLoading(true);\n try {\n const results = await searchVideos({\n query,\n offset: offset,\n limit: VIDEO_FETCH_LIMIT,\n });\n setVideos((prev) => (isAppending ? prev.concat(results) : results));\n } catch (e) {\n onError(e);\n }\n setIsLoading(false);\n },\n [searchVideos, onError],\n );\n\n useEffect(() => {\n fetchVideos(\"\", 0);\n // oxlint-disable-next-line react/exhaustive-deps\n }, []);\n\n const onSearch = useCallback(() => {\n setOffset(0);\n fetchVideos(query, 0);\n }, [fetchVideos, query]);\n\n const onShowMore = useCallback(() => {\n const newOffset = offset + VIDEO_FETCH_LIMIT;\n setOffset(newOffset);\n fetchVideos(query, newOffset, true);\n }, [fetchVideos, offset, query]);\n\n const onQueryChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value);\n }, []);\n\n const onEnter = (e: KeyboardEvent<HTMLInputElement | HTMLButtonElement>) => {\n if (e.key === \"Enter\") {\n onSearch();\n }\n };\n\n return (\n <VideoSearchWrapper>\n <InputWrapper role=\"search\">\n <Input\n type=\"search\"\n placeholder={translations.searchPlaceholder}\n value={query}\n onChange={onQueryChange}\n onKeyDown={onEnter}\n />\n <IconButton\n variant=\"primary\"\n type=\"submit\"\n aria-label={translations.searchButtonTitle}\n title={translations.searchButtonTitle}\n onKeyDown={onEnter}\n onClick={onSearch}\n >\n <SearchLine />\n </IconButton>\n </InputWrapper>\n <VideoResultList\n videos={videos}\n isLoading={isLoading}\n translations={translations}\n locale={locale}\n onVideoSelect={onVideoSelect}\n onShowMore={onShowMore}\n existsMoreVideos={videos.length === offset + VIDEO_FETCH_LIMIT}\n />\n </VideoSearchWrapper>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;AA8BA,MAAM,qBAAqB,OAAO,OAAO,EACvC,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;
|
|
1
|
+
{"version":3,"file":"VideoSearch.mjs","names":[],"sources":["../src/VideoSearch.tsx"],"sourcesContent":["/**\n * Copyright (c) 2017-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { SearchLine } from \"@ndla/icons\";\nimport { IconButton, Input } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { BrightcoveApiType } from \"@ndla/types-embed\";\nimport { type ChangeEvent, useCallback, useEffect, useState, type KeyboardEvent } from \"react\";\nimport type { VideoTranslations } from \"./types\";\nimport { VideoResultList } from \"./VideoResultList\";\n\ninterface Props {\n onVideoSelect: (video: BrightcoveApiType) => void;\n searchVideos: (query: VideoQueryType) => Promise<BrightcoveApiType[]>;\n onError: (e: unknown) => void;\n translations: VideoTranslations;\n locale: string;\n}\n\nexport interface VideoQueryType {\n query: string;\n offset: number;\n limit: number;\n}\n\nconst VideoSearchWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"xsmall\",\n },\n});\n\nconst InputWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n gap: \"xsmall\",\n },\n});\n\nconst VIDEO_FETCH_LIMIT = 10;\n\nexport const VideoSearch = ({ onVideoSelect, searchVideos, onError, translations, locale }: Props) => {\n const [query, setQuery] = useState(\"\");\n const [offset, setOffset] = useState(0);\n const [videos, setVideos] = useState<BrightcoveApiType[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n\n const fetchVideos = useCallback(\n async (query: string, offset: number, isAppending?: boolean) => {\n setIsLoading(true);\n try {\n const results = await searchVideos({\n query,\n offset: offset,\n limit: VIDEO_FETCH_LIMIT,\n });\n setVideos((prev) => (isAppending ? prev.concat(results) : results));\n } catch (e) {\n onError(e);\n }\n setIsLoading(false);\n },\n [searchVideos, onError],\n );\n\n useEffect(() => {\n fetchVideos(\"\", 0);\n // oxlint-disable-next-line react/exhaustive-deps\n }, []);\n\n const onSearch = useCallback(() => {\n setOffset(0);\n fetchVideos(query, 0);\n }, [fetchVideos, query]);\n\n const onShowMore = useCallback(() => {\n const newOffset = offset + VIDEO_FETCH_LIMIT;\n setOffset(newOffset);\n fetchVideos(query, newOffset, true);\n }, [fetchVideos, offset, query]);\n\n const onQueryChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value);\n }, []);\n\n const onEnter = (e: KeyboardEvent<HTMLInputElement | HTMLButtonElement>) => {\n if (e.key === \"Enter\") {\n onSearch();\n }\n };\n\n return (\n <VideoSearchWrapper>\n {/* oxlint-disable-next-line jsx-a11y/prefer-tag-over-role - the search element isn't supported well enough */}\n <InputWrapper role=\"search\">\n <Input\n type=\"search\"\n placeholder={translations.searchPlaceholder}\n value={query}\n onChange={onQueryChange}\n onKeyDown={onEnter}\n />\n <IconButton\n variant=\"primary\"\n type=\"submit\"\n aria-label={translations.searchButtonTitle}\n title={translations.searchButtonTitle}\n onKeyDown={onEnter}\n onClick={onSearch}\n >\n <SearchLine />\n </IconButton>\n </InputWrapper>\n <VideoResultList\n videos={videos}\n isLoading={isLoading}\n translations={translations}\n locale={locale}\n onVideoSelect={onVideoSelect}\n onShowMore={onShowMore}\n existsMoreVideos={videos.length === offset + VIDEO_FETCH_LIMIT}\n />\n </VideoSearchWrapper>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;AA8BA,MAAM,qBAAqB,OAAO,OAAO,EACvC,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;AACP,EACF,CAAC;AAED,MAAM,eAAe,OAAO,OAAO,EACjC,MAAM;CACJ,SAAS;CACT,KAAK;AACP,EACF,CAAC;AAED,MAAM,oBAAoB;AAE1B,MAAa,eAAe,EAAE,eAAe,cAAc,SAAS,cAAc,aAAoB;CACpG,MAAM,CAAC,OAAO,YAAY,SAAS,EAAE;CACrC,MAAM,CAAC,QAAQ,aAAa,SAAS,CAAC;CACtC,MAAM,CAAC,QAAQ,aAAa,SAA8B,CAAC,CAAC;CAC5D,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAEhD,MAAM,cAAc,YAClB,OAAO,OAAe,QAAgB,gBAA0B;EAC9D,aAAa,IAAI;EACjB,IAAI;GACF,MAAM,UAAU,MAAM,aAAa;IACjC;IACQ;IACR,OAAO;GACT,CAAC;GACD,WAAW,SAAU,cAAc,KAAK,OAAO,OAAO,IAAI,OAAQ;EACpE,SAAS,GAAG;GACV,QAAQ,CAAC;EACX;EACA,aAAa,KAAK;CACpB,GACA,CAAC,cAAc,OAAO,CACxB;CAEA,gBAAgB;EACd,YAAY,IAAI,CAAC;CAEnB,GAAG,CAAC,CAAC;CAEL,MAAM,WAAW,kBAAkB;EACjC,UAAU,CAAC;EACX,YAAY,OAAO,CAAC;CACtB,GAAG,CAAC,aAAa,KAAK,CAAC;CAEvB,MAAM,aAAa,kBAAkB;EACnC,MAAM,YAAY,SAAS;EAC3B,UAAU,SAAS;EACnB,YAAY,OAAO,WAAW,IAAI;CACpC,GAAG;EAAC;EAAa;EAAQ;CAAK,CAAC;CAE/B,MAAM,gBAAgB,aAAa,MAAqC;EACtE,SAAS,EAAE,OAAO,KAAK;CACzB,GAAG,CAAC,CAAC;CAEL,MAAM,WAAW,MAA2D;EAC1E,IAAI,EAAE,QAAQ,SACZ,SAAS;CAEb;CAEA,OACE,qBAAC,oBAAD,EAAA,UAAA,CAEE,qBAAC,cAAD;EAAc,MAAK;YAAnB,CACE,oBAAC,OAAD;GACE,MAAK;GACL,aAAa,aAAa;GAC1B,OAAO;GACP,UAAU;GACV,WAAW;EACZ,CAAA,GACD,oBAAC,YAAD;GACE,SAAQ;GACR,MAAK;GACL,cAAY,aAAa;GACzB,OAAO,aAAa;GACpB,WAAW;GACX,SAAS;aAET,oBAAC,YAAD,CAAa,CAAA;EACH,CAAA,CACA;KACd,oBAAC,iBAAD;EACU;EACG;EACG;EACN;EACO;EACH;EACZ,kBAAkB,OAAO,WAAW,SAAS;CAC9C,CAAA,CACiB,EAAA,CAAA;AAExB"}
|
package/lib/VideoListItem.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoListItem.js","names":["Image","ListItemContent","IconButton","ListItemRoot","Text","PanoramaPhotosphere","Button","CloseLine"],"sources":["../src/VideoListItem.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { CloseLine, PanoramaPhotosphere } from \"@ndla/icons\";\nimport { getLicenseByNBTitle, type LicenseLocaleType } from \"@ndla/licenses\";\nimport { Image, Text, ListItemContent, ListItemRoot, Button, IconButton } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { BrightcoveApiType } from \"@ndla/types-embed\";\nimport { useState } from \"react\";\nimport type { VideoTranslations } from \"./types\";\n\nconst ButtonWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n gap: \"small\",\n },\n});\n\nconst PreviewIframe = styled(\"iframe\", {\n base: {\n minHeight: \"surface.xxsmall\",\n },\n});\n\nconst PreviewWrapper = styled(\"div\", {\n base: {\n display: \"grid\",\n gap: \"xsmall\",\n gridTemplateColumns: \"repeat(3,1fr)\",\n padding: \"small\",\n borderBlockEnd: \"1px solid\",\n borderColor: \"stroke.subtle\",\n },\n});\n\nconst StyledImage = styled(Image, {\n base: {\n minWidth: \"surface.xxsmall\",\n height: \"surface.4xsmall\",\n objectFit: \"cover\",\n border: \"1px solid\",\n borderColor: \"stroke.subtle\",\n },\n});\n\nconst StyledVideoMeta = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"xxsmall\",\n },\n});\nconst StyledListItemContent = styled(ListItemContent, {\n base: {\n alignItems: \"flex-end\",\n tabletDown: {\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n },\n },\n});\n\nconst StyledIconButton = styled(IconButton, {\n base: {\n marginLeft: \"auto\",\n },\n});\n\nconst StyledListItemRoot = styled(ListItemRoot, {\n base: {\n paddingBlock: \"medium\",\n tabletDown: {\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n },\n },\n});\n\ninterface LicenseProps {\n license: LicenseLocaleType | string;\n}\nconst License = ({ license }: LicenseProps) => {\n if (typeof license === \"string\") return <Text>{license}</Text>;\n if (license.url?.length) {\n return (\n <a href={license.url} rel=\"license\">\n {license.abbreviation}\n </a>\n );\n }\n return <Text>{license.abbreviation}</Text>;\n};\n\ninterface VideoListItemProps {\n video: BrightcoveApiType;\n translations: VideoTranslations;\n locale: string;\n onVideoSelect: (video: BrightcoveApiType) => void;\n}\n\nexport const VideoListItem = ({ video, onVideoSelect, translations, locale }: VideoListItemProps) => {\n const [isPreviewing, setIsPreviewing] = useState(false);\n const license = video.custom_fields?.license ? getLicenseByNBTitle(video.custom_fields.license, locale) : \"\";\n\n return (\n <li>\n <StyledListItemRoot nonInteractive>\n <StyledImage src={video.images?.thumbnail?.src} alt=\"\" variant=\"rounded\" />\n <StyledListItemContent>\n <StyledVideoMeta>\n <Text textStyle=\"title.medium\">\n {video.name}\n {video.projection === \"equirectangular\" && (\n <PanoramaPhotosphere\n aria-hidden={false}\n aria-label={translations.is360Video}\n title={translations.is360Video}\n />\n )}\n </Text>\n <Text>{video.custom_fields?.licenseinfo ?? \"\"}</Text>\n <License license={license} />\n </StyledVideoMeta>\n <ButtonWrapper>\n <Button\n variant=\"secondary\"\n size=\"small\"\n onClick={() => setIsPreviewing((p) => !p)}\n aria-expanded={isPreviewing}\n aria-controls={`video-preview-${video.id}`}\n >\n {translations.previewVideo}\n </Button>\n <Button size=\"small\" onClick={() => onVideoSelect(video)}>\n {translations.addVideo}\n </Button>\n </ButtonWrapper>\n </StyledListItemContent>\n </StyledListItemRoot>\n {!!isPreviewing && (\n <PreviewWrapper id={`video-preview-${video.id}`}>\n <div />\n <PreviewIframe\n title={video.name}\n src={`//players.brightcove.net/${video.account_id}/BkLm8fT_default/index.html?videoId=${video.id}`}\n allowFullScreen\n />\n <StyledIconButton\n variant=\"secondary\"\n aria-label={translations.close}\n title={translations.close}\n onClick={() => setIsPreviewing(false)}\n >\n <CloseLine />\n </StyledIconButton>\n </PreviewWrapper>\n )}\n </li>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;AAgBA,MAAM,iBAAA,GAAA,wBAAA,QAAuB,OAAO,EAClC,MAAM;CACJ,SAAS;CACT,KAAK;
|
|
1
|
+
{"version":3,"file":"VideoListItem.js","names":["Image","ListItemContent","IconButton","ListItemRoot","Text","PanoramaPhotosphere","Button","CloseLine"],"sources":["../src/VideoListItem.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { CloseLine, PanoramaPhotosphere } from \"@ndla/icons\";\nimport { getLicenseByNBTitle, type LicenseLocaleType } from \"@ndla/licenses\";\nimport { Image, Text, ListItemContent, ListItemRoot, Button, IconButton } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { BrightcoveApiType } from \"@ndla/types-embed\";\nimport { useState } from \"react\";\nimport type { VideoTranslations } from \"./types\";\n\nconst ButtonWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n gap: \"small\",\n },\n});\n\nconst PreviewIframe = styled(\"iframe\", {\n base: {\n minHeight: \"surface.xxsmall\",\n },\n});\n\nconst PreviewWrapper = styled(\"div\", {\n base: {\n display: \"grid\",\n gap: \"xsmall\",\n gridTemplateColumns: \"repeat(3,1fr)\",\n padding: \"small\",\n borderBlockEnd: \"1px solid\",\n borderColor: \"stroke.subtle\",\n },\n});\n\nconst StyledImage = styled(Image, {\n base: {\n minWidth: \"surface.xxsmall\",\n height: \"surface.4xsmall\",\n objectFit: \"cover\",\n border: \"1px solid\",\n borderColor: \"stroke.subtle\",\n },\n});\n\nconst StyledVideoMeta = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"xxsmall\",\n },\n});\nconst StyledListItemContent = styled(ListItemContent, {\n base: {\n alignItems: \"flex-end\",\n tabletDown: {\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n },\n },\n});\n\nconst StyledIconButton = styled(IconButton, {\n base: {\n marginLeft: \"auto\",\n },\n});\n\nconst StyledListItemRoot = styled(ListItemRoot, {\n base: {\n paddingBlock: \"medium\",\n tabletDown: {\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n },\n },\n});\n\ninterface LicenseProps {\n license: LicenseLocaleType | string;\n}\nconst License = ({ license }: LicenseProps) => {\n if (typeof license === \"string\") return <Text>{license}</Text>;\n if (license.url?.length) {\n return (\n <a href={license.url} rel=\"license\">\n {license.abbreviation}\n </a>\n );\n }\n return <Text>{license.abbreviation}</Text>;\n};\n\ninterface VideoListItemProps {\n video: BrightcoveApiType;\n translations: VideoTranslations;\n locale: string;\n onVideoSelect: (video: BrightcoveApiType) => void;\n}\n\nexport const VideoListItem = ({ video, onVideoSelect, translations, locale }: VideoListItemProps) => {\n const [isPreviewing, setIsPreviewing] = useState(false);\n const license = video.custom_fields?.license ? getLicenseByNBTitle(video.custom_fields.license, locale) : \"\";\n\n return (\n <li>\n <StyledListItemRoot nonInteractive>\n <StyledImage src={video.images?.thumbnail?.src} alt=\"\" variant=\"rounded\" />\n <StyledListItemContent>\n <StyledVideoMeta>\n <Text textStyle=\"title.medium\">\n {video.name}\n {video.projection === \"equirectangular\" && (\n <PanoramaPhotosphere\n aria-hidden={false}\n aria-label={translations.is360Video}\n title={translations.is360Video}\n />\n )}\n </Text>\n <Text>{video.custom_fields?.licenseinfo ?? \"\"}</Text>\n <License license={license} />\n </StyledVideoMeta>\n <ButtonWrapper>\n <Button\n variant=\"secondary\"\n size=\"small\"\n onClick={() => setIsPreviewing((p) => !p)}\n aria-expanded={isPreviewing}\n aria-controls={`video-preview-${video.id}`}\n >\n {translations.previewVideo}\n </Button>\n <Button size=\"small\" onClick={() => onVideoSelect(video)}>\n {translations.addVideo}\n </Button>\n </ButtonWrapper>\n </StyledListItemContent>\n </StyledListItemRoot>\n {!!isPreviewing && (\n <PreviewWrapper id={`video-preview-${video.id}`}>\n <div />\n <PreviewIframe\n title={video.name}\n src={`//players.brightcove.net/${video.account_id}/BkLm8fT_default/index.html?videoId=${video.id}`}\n allowFullScreen\n />\n <StyledIconButton\n variant=\"secondary\"\n aria-label={translations.close}\n title={translations.close}\n onClick={() => setIsPreviewing(false)}\n >\n <CloseLine />\n </StyledIconButton>\n </PreviewWrapper>\n )}\n </li>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;AAgBA,MAAM,iBAAA,GAAA,wBAAA,QAAuB,OAAO,EAClC,MAAM;CACJ,SAAS;CACT,KAAK;AACP,EACF,CAAC;AAED,MAAM,iBAAA,GAAA,wBAAA,QAAuB,UAAU,EACrC,MAAM,EACJ,WAAW,kBACb,EACF,CAAC;AAED,MAAM,kBAAA,GAAA,wBAAA,QAAwB,OAAO,EACnC,MAAM;CACJ,SAAS;CACT,KAAK;CACL,qBAAqB;CACrB,SAAS;CACT,gBAAgB;CAChB,aAAa;AACf,EACF,CAAC;AAED,MAAM,eAAA,GAAA,wBAAA,QAAqBA,iBAAAA,OAAO,EAChC,MAAM;CACJ,UAAU;CACV,QAAQ;CACR,WAAW;CACX,QAAQ;CACR,aAAa;AACf,EACF,CAAC;AAED,MAAM,mBAAA,GAAA,wBAAA,QAAyB,OAAO,EACpC,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;AACP,EACF,CAAC;AACD,MAAM,yBAAA,GAAA,wBAAA,QAA+BC,iBAAAA,iBAAiB,EACpD,MAAM;CACJ,YAAY;CACZ,YAAY;EACV,eAAe;EACf,YAAY;CACd;AACF,EACF,CAAC;AAED,MAAM,oBAAA,GAAA,wBAAA,QAA0BC,iBAAAA,YAAY,EAC1C,MAAM,EACJ,YAAY,OACd,EACF,CAAC;AAED,MAAM,sBAAA,GAAA,wBAAA,QAA4BC,iBAAAA,cAAc,EAC9C,MAAM;CACJ,cAAc;CACd,YAAY;EACV,eAAe;EACf,YAAY;CACd;AACF,EACF,CAAC;AAKD,MAAM,WAAW,EAAE,cAA4B;CAC7C,IAAI,OAAO,YAAY,UAAU,OAAO,iBAAA,GAAA,kBAAA,KAACC,iBAAAA,MAAD,EAAA,UAAO,QAAc,CAAA;CAC7D,IAAI,QAAQ,KAAK,QACf,OACE,iBAAA,GAAA,kBAAA,KAAC,KAAD;EAAG,MAAM,QAAQ;EAAK,KAAI;YACvB,QAAQ;CACR,CAAA;CAGP,OAAO,iBAAA,GAAA,kBAAA,KAACA,iBAAAA,MAAD,EAAA,UAAO,QAAQ,aAAmB,CAAA;AAC3C;AASA,MAAa,iBAAiB,EAAE,OAAO,eAAe,cAAc,aAAiC;CACnG,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,UAA4B,KAAK;CACtD,MAAM,UAAU,MAAM,eAAe,WAAA,GAAA,eAAA,qBAA8B,MAAM,cAAc,SAAS,MAAM,IAAI;CAE1G,OACE,iBAAA,GAAA,kBAAA,MAAC,MAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,MAAC,oBAAD;EAAoB,gBAAA;YAApB,CACE,iBAAA,GAAA,kBAAA,KAAC,aAAD;GAAa,KAAK,MAAM,QAAQ,WAAW;GAAK,KAAI;GAAG,SAAQ;EAAW,CAAA,GAC1E,iBAAA,GAAA,kBAAA,MAAC,uBAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,MAAC,iBAAD,EAAA,UAAA;GACE,iBAAA,GAAA,kBAAA,MAACA,iBAAAA,MAAD;IAAM,WAAU;cAAhB,CACG,MAAM,MACN,MAAM,eAAe,qBACpB,iBAAA,GAAA,kBAAA,KAACC,YAAAA,qBAAD;KACE,eAAa;KACb,cAAY,aAAa;KACzB,OAAO,aAAa;IACrB,CAAA,CAEC;;GACN,iBAAA,GAAA,kBAAA,KAACD,iBAAAA,MAAD,EAAA,UAAO,MAAM,eAAe,eAAe,GAAS,CAAA;GACpD,iBAAA,GAAA,kBAAA,KAAC,SAAD,EAAkB,QAAU,CAAA;EACb,EAAA,CAAA,GACjB,iBAAA,GAAA,kBAAA,MAAC,eAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,KAACE,iBAAAA,QAAD;GACE,SAAQ;GACR,MAAK;GACL,eAAe,iBAAiB,MAAM,CAAC,CAAC;GACxC,iBAAe;GACf,iBAAe,iBAAiB,MAAM;aAErC,aAAa;EACR,CAAA,GACR,iBAAA,GAAA,kBAAA,KAACA,iBAAAA,QAAD;GAAQ,MAAK;GAAQ,eAAe,cAAc,KAAK;aACpD,aAAa;EACR,CAAA,CACK,EAAA,CAAA,CACM,EAAA,CAAA,CACL;KACnB,CAAC,CAAC,gBACD,iBAAA,GAAA,kBAAA,MAAC,gBAAD;EAAgB,IAAI,iBAAiB,MAAM;YAA3C;GACE,iBAAA,GAAA,kBAAA,KAAC,OAAD,CAAM,CAAA;GACN,iBAAA,GAAA,kBAAA,KAAC,eAAD;IACE,OAAO,MAAM;IACb,KAAK,4BAA4B,MAAM,WAAW,sCAAsC,MAAM;IAC9F,iBAAA;GACD,CAAA;GACD,iBAAA,GAAA,kBAAA,KAAC,kBAAD;IACE,SAAQ;IACR,cAAY,aAAa;IACzB,OAAO,aAAa;IACpB,eAAe,gBAAgB,KAAK;cAEpC,iBAAA,GAAA,kBAAA,KAACC,YAAAA,WAAD,CAAY,CAAA;GACI,CAAA;EACJ;GAEhB,EAAA,CAAA;AAER"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoResultList.js","names":["Text","VideoListItem","Spinner","Button"],"sources":["../src/VideoResultList.tsx"],"sourcesContent":["/**\n * Copyright (c) 2017-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { Text, Button, Spinner } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { BrightcoveApiType } from \"@ndla/types-embed\";\nimport type { VideoTranslations } from \"./types\";\nimport { VideoListItem } from \"./VideoListItem\";\n\nconst StyledList = styled(\"ul\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"xxsmall\",\n listStyle: \"none\",\n width: \"100%\",\n },\n});\n\nconst StyledVideoResultWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"medium\",\n alignItems: \"center\",\n },\n});\n\ninterface Props {\n videos: BrightcoveApiType[];\n existsMoreVideos: boolean;\n isLoading: boolean;\n translations: VideoTranslations;\n locale: string;\n onVideoSelect: (video: BrightcoveApiType) => void;\n onShowMore: () => void;\n}\n\nexport const VideoResultList = ({\n videos,\n existsMoreVideos,\n isLoading,\n translations,\n locale,\n onVideoSelect,\n onShowMore,\n}: Props) => {\n return (\n <StyledVideoResultWrapper>\n {!videos.length && !isLoading ? (\n <Text>{translations.noResults}</Text>\n ) : (\n <StyledList>\n {videos.map((video, index) => (\n <VideoListItem\n key={`${video.id}-${index}`}\n video={video}\n translations={translations}\n locale={locale}\n onVideoSelect={onVideoSelect}\n />\n ))}\n </StyledList>\n )}\n {!!isLoading && <Spinner />}\n {!!existsMoreVideos && <Button onClick={onShowMore}>{translations.loadMoreVideos}</Button>}\n </StyledVideoResultWrapper>\n );\n};\n"],"mappings":";;;;;;;;;;;;AAcA,MAAM,cAAA,GAAA,wBAAA,QAAoB,MAAM,EAC9B,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;CACL,WAAW;CACX,OAAO;
|
|
1
|
+
{"version":3,"file":"VideoResultList.js","names":["Text","VideoListItem","Spinner","Button"],"sources":["../src/VideoResultList.tsx"],"sourcesContent":["/**\n * Copyright (c) 2017-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { Text, Button, Spinner } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { BrightcoveApiType } from \"@ndla/types-embed\";\nimport type { VideoTranslations } from \"./types\";\nimport { VideoListItem } from \"./VideoListItem\";\n\nconst StyledList = styled(\"ul\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"xxsmall\",\n listStyle: \"none\",\n width: \"100%\",\n },\n});\n\nconst StyledVideoResultWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"medium\",\n alignItems: \"center\",\n },\n});\n\ninterface Props {\n videos: BrightcoveApiType[];\n existsMoreVideos: boolean;\n isLoading: boolean;\n translations: VideoTranslations;\n locale: string;\n onVideoSelect: (video: BrightcoveApiType) => void;\n onShowMore: () => void;\n}\n\nexport const VideoResultList = ({\n videos,\n existsMoreVideos,\n isLoading,\n translations,\n locale,\n onVideoSelect,\n onShowMore,\n}: Props) => {\n return (\n <StyledVideoResultWrapper>\n {!videos.length && !isLoading ? (\n <Text>{translations.noResults}</Text>\n ) : (\n <StyledList>\n {videos.map((video, index) => (\n <VideoListItem\n key={`${video.id}-${index}`}\n video={video}\n translations={translations}\n locale={locale}\n onVideoSelect={onVideoSelect}\n />\n ))}\n </StyledList>\n )}\n {!!isLoading && <Spinner />}\n {!!existsMoreVideos && <Button onClick={onShowMore}>{translations.loadMoreVideos}</Button>}\n </StyledVideoResultWrapper>\n );\n};\n"],"mappings":";;;;;;;;;;;;AAcA,MAAM,cAAA,GAAA,wBAAA,QAAoB,MAAM,EAC9B,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;CACL,WAAW;CACX,OAAO;AACT,EACF,CAAC;AAED,MAAM,4BAAA,GAAA,wBAAA,QAAkC,OAAO,EAC7C,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;CACL,YAAY;AACd,EACF,CAAC;AAYD,MAAa,mBAAmB,EAC9B,QACA,kBACA,WACA,cACA,QACA,eACA,iBACW;CACX,OACE,iBAAA,GAAA,kBAAA,MAAC,0BAAD,EAAA,UAAA;EACG,CAAC,OAAO,UAAU,CAAC,YAClB,iBAAA,GAAA,kBAAA,KAACA,iBAAAA,MAAD,EAAA,UAAO,aAAa,UAAgB,CAAA,IAEpC,iBAAA,GAAA,kBAAA,KAAC,YAAD,EAAA,UACG,OAAO,KAAK,OAAO,UAClB,iBAAA,GAAA,kBAAA,KAACC,sBAAAA,eAAD;GAES;GACO;GACN;GACO;EAChB,GALM,GAAG,MAAM,GAAG,GAAG,OAKrB,CACF,EACS,CAAA;EAEb,CAAC,CAAC,aAAa,iBAAA,GAAA,kBAAA,KAACC,iBAAAA,SAAD,CAAU,CAAA;EACzB,CAAC,CAAC,oBAAoB,iBAAA,GAAA,kBAAA,KAACC,iBAAAA,QAAD;GAAQ,SAAS;aAAa,aAAa;EAAuB,CAAA;CACjE,EAAA,CAAA;AAE9B"}
|
package/lib/VideoSearch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoSearch.js","names":["Input","IconButton","SearchLine","VideoResultList"],"sources":["../src/VideoSearch.tsx"],"sourcesContent":["/**\n * Copyright (c) 2017-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { SearchLine } from \"@ndla/icons\";\nimport { IconButton, Input } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { BrightcoveApiType } from \"@ndla/types-embed\";\nimport { type ChangeEvent, useCallback, useEffect, useState, type KeyboardEvent } from \"react\";\nimport type { VideoTranslations } from \"./types\";\nimport { VideoResultList } from \"./VideoResultList\";\n\ninterface Props {\n onVideoSelect: (video: BrightcoveApiType) => void;\n searchVideos: (query: VideoQueryType) => Promise<BrightcoveApiType[]>;\n onError: (e: unknown) => void;\n translations: VideoTranslations;\n locale: string;\n}\n\nexport interface VideoQueryType {\n query: string;\n offset: number;\n limit: number;\n}\n\nconst VideoSearchWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"xsmall\",\n },\n});\n\nconst InputWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n gap: \"xsmall\",\n },\n});\n\nconst VIDEO_FETCH_LIMIT = 10;\n\nexport const VideoSearch = ({ onVideoSelect, searchVideos, onError, translations, locale }: Props) => {\n const [query, setQuery] = useState(\"\");\n const [offset, setOffset] = useState(0);\n const [videos, setVideos] = useState<BrightcoveApiType[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n\n const fetchVideos = useCallback(\n async (query: string, offset: number, isAppending?: boolean) => {\n setIsLoading(true);\n try {\n const results = await searchVideos({\n query,\n offset: offset,\n limit: VIDEO_FETCH_LIMIT,\n });\n setVideos((prev) => (isAppending ? prev.concat(results) : results));\n } catch (e) {\n onError(e);\n }\n setIsLoading(false);\n },\n [searchVideos, onError],\n );\n\n useEffect(() => {\n fetchVideos(\"\", 0);\n // oxlint-disable-next-line react/exhaustive-deps\n }, []);\n\n const onSearch = useCallback(() => {\n setOffset(0);\n fetchVideos(query, 0);\n }, [fetchVideos, query]);\n\n const onShowMore = useCallback(() => {\n const newOffset = offset + VIDEO_FETCH_LIMIT;\n setOffset(newOffset);\n fetchVideos(query, newOffset, true);\n }, [fetchVideos, offset, query]);\n\n const onQueryChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value);\n }, []);\n\n const onEnter = (e: KeyboardEvent<HTMLInputElement | HTMLButtonElement>) => {\n if (e.key === \"Enter\") {\n onSearch();\n }\n };\n\n return (\n <VideoSearchWrapper>\n <InputWrapper role=\"search\">\n <Input\n type=\"search\"\n placeholder={translations.searchPlaceholder}\n value={query}\n onChange={onQueryChange}\n onKeyDown={onEnter}\n />\n <IconButton\n variant=\"primary\"\n type=\"submit\"\n aria-label={translations.searchButtonTitle}\n title={translations.searchButtonTitle}\n onKeyDown={onEnter}\n onClick={onSearch}\n >\n <SearchLine />\n </IconButton>\n </InputWrapper>\n <VideoResultList\n videos={videos}\n isLoading={isLoading}\n translations={translations}\n locale={locale}\n onVideoSelect={onVideoSelect}\n onShowMore={onShowMore}\n existsMoreVideos={videos.length === offset + VIDEO_FETCH_LIMIT}\n />\n </VideoSearchWrapper>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;AA8BA,MAAM,sBAAA,GAAA,wBAAA,QAA4B,OAAO,EACvC,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;
|
|
1
|
+
{"version":3,"file":"VideoSearch.js","names":["Input","IconButton","SearchLine","VideoResultList"],"sources":["../src/VideoSearch.tsx"],"sourcesContent":["/**\n * Copyright (c) 2017-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { SearchLine } from \"@ndla/icons\";\nimport { IconButton, Input } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { BrightcoveApiType } from \"@ndla/types-embed\";\nimport { type ChangeEvent, useCallback, useEffect, useState, type KeyboardEvent } from \"react\";\nimport type { VideoTranslations } from \"./types\";\nimport { VideoResultList } from \"./VideoResultList\";\n\ninterface Props {\n onVideoSelect: (video: BrightcoveApiType) => void;\n searchVideos: (query: VideoQueryType) => Promise<BrightcoveApiType[]>;\n onError: (e: unknown) => void;\n translations: VideoTranslations;\n locale: string;\n}\n\nexport interface VideoQueryType {\n query: string;\n offset: number;\n limit: number;\n}\n\nconst VideoSearchWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"xsmall\",\n },\n});\n\nconst InputWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n gap: \"xsmall\",\n },\n});\n\nconst VIDEO_FETCH_LIMIT = 10;\n\nexport const VideoSearch = ({ onVideoSelect, searchVideos, onError, translations, locale }: Props) => {\n const [query, setQuery] = useState(\"\");\n const [offset, setOffset] = useState(0);\n const [videos, setVideos] = useState<BrightcoveApiType[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n\n const fetchVideos = useCallback(\n async (query: string, offset: number, isAppending?: boolean) => {\n setIsLoading(true);\n try {\n const results = await searchVideos({\n query,\n offset: offset,\n limit: VIDEO_FETCH_LIMIT,\n });\n setVideos((prev) => (isAppending ? prev.concat(results) : results));\n } catch (e) {\n onError(e);\n }\n setIsLoading(false);\n },\n [searchVideos, onError],\n );\n\n useEffect(() => {\n fetchVideos(\"\", 0);\n // oxlint-disable-next-line react/exhaustive-deps\n }, []);\n\n const onSearch = useCallback(() => {\n setOffset(0);\n fetchVideos(query, 0);\n }, [fetchVideos, query]);\n\n const onShowMore = useCallback(() => {\n const newOffset = offset + VIDEO_FETCH_LIMIT;\n setOffset(newOffset);\n fetchVideos(query, newOffset, true);\n }, [fetchVideos, offset, query]);\n\n const onQueryChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value);\n }, []);\n\n const onEnter = (e: KeyboardEvent<HTMLInputElement | HTMLButtonElement>) => {\n if (e.key === \"Enter\") {\n onSearch();\n }\n };\n\n return (\n <VideoSearchWrapper>\n {/* oxlint-disable-next-line jsx-a11y/prefer-tag-over-role - the search element isn't supported well enough */}\n <InputWrapper role=\"search\">\n <Input\n type=\"search\"\n placeholder={translations.searchPlaceholder}\n value={query}\n onChange={onQueryChange}\n onKeyDown={onEnter}\n />\n <IconButton\n variant=\"primary\"\n type=\"submit\"\n aria-label={translations.searchButtonTitle}\n title={translations.searchButtonTitle}\n onKeyDown={onEnter}\n onClick={onSearch}\n >\n <SearchLine />\n </IconButton>\n </InputWrapper>\n <VideoResultList\n videos={videos}\n isLoading={isLoading}\n translations={translations}\n locale={locale}\n onVideoSelect={onVideoSelect}\n onShowMore={onShowMore}\n existsMoreVideos={videos.length === offset + VIDEO_FETCH_LIMIT}\n />\n </VideoSearchWrapper>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;AA8BA,MAAM,sBAAA,GAAA,wBAAA,QAA4B,OAAO,EACvC,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;AACP,EACF,CAAC;AAED,MAAM,gBAAA,GAAA,wBAAA,QAAsB,OAAO,EACjC,MAAM;CACJ,SAAS;CACT,KAAK;AACP,EACF,CAAC;AAED,MAAM,oBAAoB;AAE1B,MAAa,eAAe,EAAE,eAAe,cAAc,SAAS,cAAc,aAAoB;CACpG,MAAM,CAAC,OAAO,aAAA,GAAA,MAAA,UAAqB,EAAE;CACrC,MAAM,CAAC,QAAQ,cAAA,GAAA,MAAA,UAAsB,CAAC;CACtC,MAAM,CAAC,QAAQ,cAAA,GAAA,MAAA,UAA2C,CAAC,CAAC;CAC5D,MAAM,CAAC,WAAW,iBAAA,GAAA,MAAA,UAAyB,KAAK;CAEhD,MAAM,eAAA,GAAA,MAAA,aACJ,OAAO,OAAe,QAAgB,gBAA0B;EAC9D,aAAa,IAAI;EACjB,IAAI;GACF,MAAM,UAAU,MAAM,aAAa;IACjC;IACQ;IACR,OAAO;GACT,CAAC;GACD,WAAW,SAAU,cAAc,KAAK,OAAO,OAAO,IAAI,OAAQ;EACpE,SAAS,GAAG;GACV,QAAQ,CAAC;EACX;EACA,aAAa,KAAK;CACpB,GACA,CAAC,cAAc,OAAO,CACxB;CAEA,CAAA,GAAA,MAAA,iBAAgB;EACd,YAAY,IAAI,CAAC;CAEnB,GAAG,CAAC,CAAC;CAEL,MAAM,YAAA,GAAA,MAAA,mBAA6B;EACjC,UAAU,CAAC;EACX,YAAY,OAAO,CAAC;CACtB,GAAG,CAAC,aAAa,KAAK,CAAC;CAEvB,MAAM,cAAA,GAAA,MAAA,mBAA+B;EACnC,MAAM,YAAY,SAAS;EAC3B,UAAU,SAAS;EACnB,YAAY,OAAO,WAAW,IAAI;CACpC,GAAG;EAAC;EAAa;EAAQ;CAAK,CAAC;CAE/B,MAAM,iBAAA,GAAA,MAAA,cAA6B,MAAqC;EACtE,SAAS,EAAE,OAAO,KAAK;CACzB,GAAG,CAAC,CAAC;CAEL,MAAM,WAAW,MAA2D;EAC1E,IAAI,EAAE,QAAQ,SACZ,SAAS;CAEb;CAEA,OACE,iBAAA,GAAA,kBAAA,MAAC,oBAAD,EAAA,UAAA,CAEE,iBAAA,GAAA,kBAAA,MAAC,cAAD;EAAc,MAAK;YAAnB,CACE,iBAAA,GAAA,kBAAA,KAACA,iBAAAA,OAAD;GACE,MAAK;GACL,aAAa,aAAa;GAC1B,OAAO;GACP,UAAU;GACV,WAAW;EACZ,CAAA,GACD,iBAAA,GAAA,kBAAA,KAACC,iBAAAA,YAAD;GACE,SAAQ;GACR,MAAK;GACL,cAAY,aAAa;GACzB,OAAO,aAAa;GACpB,WAAW;GACX,SAAS;aAET,iBAAA,GAAA,kBAAA,KAACC,YAAAA,YAAD,CAAa,CAAA;EACH,CAAA,CACA;KACd,iBAAA,GAAA,kBAAA,KAACC,wBAAAA,iBAAD;EACU;EACG;EACG;EACN;EACO;EACH;EACZ,kBAAkB,OAAO,WAAW,SAAS;CAC9C,CAAA,CACiB,EAAA,CAAA;AAExB"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ndla/video-search",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "8.0.
|
|
4
|
+
"version": "8.0.156-alpha.0",
|
|
5
5
|
"description": "A simple library for searching NDLA videos",
|
|
6
6
|
"license": "GPL-3.0",
|
|
7
7
|
"exports": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@ndla/icons": "^8.0.89-alpha.0",
|
|
34
34
|
"@ndla/licenses": "^10.0.12-alpha.0",
|
|
35
|
-
"@ndla/primitives": "^1.0.
|
|
35
|
+
"@ndla/primitives": "^1.0.130-alpha.0",
|
|
36
36
|
"@ndla/styled-system": "^0.0.49"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"publishConfig": {
|
|
48
48
|
"access": "public"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "609d5d044ece059de95a3142847ad9ab8737f468"
|
|
51
51
|
}
|