sanity-plugin-bynder-input
5.1.05.1.1
~
Modified (4 files)
Index: package/package.json
===================================================================
--- package/package.json
+++ package/package.json
@@ -1,7 +1,7 @@
{
"name": "sanity-plugin-bynder-input",
- "version": "5.1.0",
+ "version": "5.1.1",
"keywords": [
"sanity",
"sanity-plugin"
],
@@ -33,23 +33,23 @@
"./package.json": "./package.json"
},
"dependencies": {
"@bynder/compact-view": "^6.0.1",
- "@sanity/ui": "^4.0.7",
+ "@sanity/ui": "^4.2.7",
"video.js": "^7.21.7"
},
"devDependencies": {
"@sanity/tsconfig": "^2.2.1",
- "@sanity/tsdown-config": "^0.26.0",
- "@sanity/vanilla-extract-vite-plugin": "^0.2.15",
+ "@sanity/tsdown-config": "^0.27.1",
+ "@sanity/vanilla-extract-vite-plugin": "^0.2.20",
"@types/node": "^24.13.3",
- "@types/react": "^19.2.18",
+ "@types/react": "^19.3.0",
"@types/video.js": "^7.3.58",
"@vanilla-extract/css": "^1.21.2",
"oxc-transform-react": "^0.147.0",
- "react": "^19.2.8",
- "react-dom": "^19.2.8",
- "sanity": "^6.11.0",
+ "react": "^19.3.0",
+ "react-dom": "^19.3.0",
+ "sanity": "^6.16.0",
"styled-components": "^6.5.3",
"tsdown": "^0.22.14"
},
"peerDependencies": { Index: package/dist/BynderModalLayout-D-C-Fqrh.js.map
===================================================================
--- package/dist/BynderModalLayout-D-C-Fqrh.js.map
+++ package/dist/BynderModalLayout-D-C-Fqrh.js.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"BynderModalLayout-D-C-Fqrh.js","names":["{\n isOpen,\n onClose,\n portalConfig,\n compactViewOptions,\n onSuccess,\n}: {\n isOpen: boolean\n onClose: () => void\n portalConfig: PortalConfig\n compactViewOptions: CompactViewProps\n onSuccess: (assets: unknown[], addInfo: AdditionalInfo) => void\n}","<CompactView {...compactViewOptions} onSuccess={onSuccess} mode=\"SingleSelectFile\" />","<Login portal={portalConfig}>\n <CompactView {...compactViewOptions} onSuccess={onSuccess} mode=\"SingleSelectFile\" />\n </Login>","<Modal isOpen={isOpen} onClose={onClose}>\n <Login portal={portalConfig}>\n <CompactView {...compactViewOptions} onSuccess={onSuccess} mode=\"SingleSelectFile\" />\n </Login>\n </Modal>"],"sources":["../src/components/BynderModalLayout.tsx"],"sourcesContent":["import {\n type CompactViewProps,\n type PortalConfig,\n type AdditionalInfo,\n Modal,\n Login,\n CompactView,\n} from '@bynder/compact-view'\n\nexport default function BynderModalLayout({\n isOpen,\n onClose,\n portalConfig,\n compactViewOptions,\n onSuccess,\n}: {\n isOpen: boolean\n onClose: () => void\n portalConfig: PortalConfig\n compactViewOptions: CompactViewProps\n onSuccess: (assets: unknown[], addInfo: AdditionalInfo) => void\n}): React.JSX.Element {\n return (\n <Modal isOpen={isOpen} onClose={onClose}>\n <Login portal={portalConfig}>\n <CompactView {...compactViewOptions} onSuccess={onSuccess} mode=\"SingleSelectFile\" />\n </Login>\n </Modal>\n )\n}\n"],"mappings":";;;AASA,SAAwB,kBAAA,IAYF;gBAZoB,EACxC,QACA,SACA,cACA,oBACA,cALwCA,IAgBlCC;CAAiB,AAAA,EAAA,OAAA,sBAAA,EAAA,OAA+B,aAAhD,KAAA,oBAAC,aAAD;EAAa,GAAI;EAA+B;EAAW,MAAK;CAAoB,CAAA,GAAnE,EAAA,KAAA,oBAA+B,EAAA,KAAA;CADlDC,IAAAA;CAAe,AAAA,EAAA,OAAA,gBAAA,EAAA,OACbD,MADF,KAAA,oBAAC,OAAD;EAAO,QAAQ;EACbA,UAAAA;CACK,CAAA,GAFQ,EAAA,KAAA,cACbA,EAAAA,KAAAA;CAFJE,IAAAA;CADF,OACiB,EAAA,OAAA,UAAA,EAAA,OAAiB,WAAA,EAAA,OAC9BD,MADF,KAAA,oBAAC,OAAD;EAAe;EAAiB;EAC9BA,UAAAA;CAGK,CAAA,GAJQ,EAAA,KAAA,QAAiB,EAAA,KAAA,SAC9BA,EAAAA,KAAAA,4BADFC;AAMJ"}
\ No newline at end of file
+{"version":3,"file":"BynderModalLayout-D-C-Fqrh.js","names":["{\n isOpen,\n onClose,\n portalConfig,\n compactViewOptions,\n onSuccess,\n}: {\n isOpen: boolean\n onClose: () => void\n portalConfig: PortalConfig\n compactViewOptions: CompactViewProps\n onSuccess: (assets: unknown[], addInfo: AdditionalInfo) => void\n}","<CompactView {...compactViewOptions} onSuccess={onSuccess} mode=\"SingleSelectFile\" />","<Login portal={portalConfig}>\n <CompactView {...compactViewOptions} onSuccess={onSuccess} mode=\"SingleSelectFile\" />\n </Login>","<Modal isOpen={isOpen} onClose={onClose}>\n <Login portal={portalConfig}>\n <CompactView {...compactViewOptions} onSuccess={onSuccess} mode=\"SingleSelectFile\" />\n </Login>\n </Modal>","_c"],"sources":["../src/components/BynderModalLayout.tsx"],"sourcesContent":["import {\n type CompactViewProps,\n type PortalConfig,\n type AdditionalInfo,\n Modal,\n Login,\n CompactView,\n} from '@bynder/compact-view'\n\nexport default function BynderModalLayout({\n isOpen,\n onClose,\n portalConfig,\n compactViewOptions,\n onSuccess,\n}: {\n isOpen: boolean\n onClose: () => void\n portalConfig: PortalConfig\n compactViewOptions: CompactViewProps\n onSuccess: (assets: unknown[], addInfo: AdditionalInfo) => void\n}): React.JSX.Element {\n return (\n <Modal isOpen={isOpen} onClose={onClose}>\n <Login portal={portalConfig}>\n <CompactView {...compactViewOptions} onSuccess={onSuccess} mode=\"SingleSelectFile\" />\n </Login>\n </Modal>\n )\n}\n"],"mappings":";;;AASA,SAAwB,kBAAA,IAYF;gBAZoB,EACxC,QACA,SACA,cACA,oBACA,cALwCA,IAgBlCC;CAAiB,AAAA,EAAA,OAAA,sBAAA,EAAA,OAA+B,aAAhD,KAAA,oBAAC,aAAD;EAAa,GAAI;EAA+B;EAAW,MAAK;CAAoB,CAAA,GAAnE,EAAA,KAAA,oBAA+B,EAAA,KAAA;CADlDC,IAAAA;CAAe,AAAA,EAAA,OAAA,gBAAA,EAAA,OACbD,MADF,KAAA,oBAAC,OAAD;EAAO,QAAQ;EACbA,UAAAA;CACK,CAAA,GAFQ,EAAA,KAAA,cACbA,EAAAA,KAAAA;CAFJE,IAAAA;CADF,OACiB,EAAA,OAAA,UAAA,EAAA,OAAiB,WAAA,EAAA,OAC9BD,MADF,KAAA,oBAAC,OAAD;EAAe;EAAiB;EAC9BA,UAAAA;CAGK,CAAA,GAJQ,EAAA,KAAA,QAAiB,EAAA,KAAA,SAC9BA,EAAAA,KAAAA,4BADFC;AAMJ"}
\ No newline at end of file Index: package/dist/index.js.map
===================================================================
--- package/dist/index.js.map
+++ package/dist/index.js.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"index.js","names":["fieldOptions?.assetTypes && {\n // oxlint-disable-next-line no-unsafe-type-assertion\n assetTypes: fieldOptions.assetTypes.map((t) => t.toUpperCase()) as (\n | 'IMAGE'\n | 'VIDEO'\n | 'AUDIO'\n )[],\n }","(t) => t.toUpperCase()","fieldOptions?.assetTypes","fieldOptions?.assetFilter && {assetFilter: fieldOptions.assetFilter}","fieldOptions?.assetFilter","{\n ...pluginConfig.compactViewOptions,\n ...(fieldOptions?.assetTypes && {\n // oxlint-disable-next-line no-unsafe-type-assertion\n assetTypes: fieldOptions.assetTypes.map((t) => t.toUpperCase()) as (\n | 'IMAGE'\n | 'VIDEO'\n | 'AUDIO'\n )[],\n }),\n ...(fieldOptions?.assetFilter && {assetFilter: fieldOptions.assetFilter}),\n }","compactViewOptions","() => {\n onChange(PatchEvent.from([unset()]))\n }","(assets: unknown[], addInfo: AdditionalInfo) => {\n // oxlint-disable-next-line no-unsafe-type-assertion\n const asset = assets[0] as Record<string, any>\n const webImage = asset['files']?.['webImage']\n\n const aspectRatio = webImage\n ? getAspectRatio({\n width: webImage.width,\n height: webImage.height,\n })\n : undefined\n\n const persistRawFields = fieldOptions?.persistRawFields ?? pluginConfig.persistRawFields ?? true\n\n const mediaData = {\n // When `persistRawFields` is true (the default), spread the full raw Bynder\n // asset payload first; explicit fields below then override with the\n // canonical, computed, or mapped values declared in the schema.\n ...(persistRawFields ? asset : {}),\n\n _key: value?._key,\n _type: schemaType.name,\n\n id: asset['id'],\n name: asset['name'],\n databaseId: asset['databaseId'],\n type: asset['type'],\n description: asset['description'],\n\n previewUrl: getPreviewUrl(asset, addInfo),\n previewImg: webImage?.url,\n datUrl: asset['files']?.['transformBaseUrl']?.url,\n videoUrl: getVideoUrl(asset),\n aspectRatio,\n selectedUrl: addInfo.selectedFile?.url,\n width: webImage?.width,\n height: webImage?.height,\n }\n\n if (asset['type'] === 'VIDEO') {\n getVideoAspectRatio(webImage?.url ?? '')\n // oxlint-disable-next-line always-return\n .then((ratio) => {\n onChange(PatchEvent.from([set({...mediaData, aspectRatio: ratio})]))\n setIsOpen(false)\n })\n .catch((err) => {\n // video aspect ratio couldn't be set, but should still set the rest of the data\n console.error('Error setting video aspect ratio:', err)\n onChange(PatchEvent.from([set(mediaData)]))\n setIsOpen(false)\n })\n } else {\n onChange(PatchEvent.from([set(mediaData)]))\n setIsOpen(false)\n }\n }","persistRawFields","name","_key","[{src: value.previewUrl ?? ''}]","value.previewUrl ?? ''","<VideoPlayer controls poster={value.previewImg} sources={[{src: value.previewUrl ?? ''}]} />","previewImg","{width: 'auto', height: '100%', maxHeight: '20rem'}","<img\n alt=\"preview\"\n src={value.previewUrl}\n style={{width: 'auto', height: '100%', maxHeight: '20rem'}}\n />","previewUrl","() => {\n // We want the button to show a loading state if it takes a while to lazy load the modal\n startTransition(() => setShouldLoad(true))\n // Opening the modal should never trigger a loading state\n setIsOpen(true)\n }","() => setIsOpen(false)","{cursor: 'pointer'}","<Flex\n justify=\"center\"\n align=\"center\"\n marginBottom={2}\n onClick={openCompactView}\n style={{cursor: 'pointer'}}\n >\n {preview}\n </Flex>","{width: '100%'}","<Box flex={1}>\n <Button\n style={{width: '100%'}}\n loading={loading}\n disabled={readOnly}\n mode=\"ghost\"\n text={value ? 'Replace' : 'Browse'}\n title=\"Select an asset\"\n onClick={openCompactView}\n />\n </Box>","value ? 'Replace' : 'Browse'","<Box flex={1}>\n <Button\n style={{width: '100%'}}\n disabled={readOnly || !value}\n tone=\"critical\"\n mode=\"ghost\"\n text={'Remove'}\n title=\"Remove asset\"\n onClick={removeValue}\n />\n </Box>","readOnly || !value","<Flex gap={2} style={{width: '100%'}}>\n <Box flex={1}>\n <Button\n style={{width: '100%'}}\n loading={loading}\n disabled={readOnly}\n mode=\"ghost\"\n text={value ? 'Replace' : 'Browse'}\n title=\"Select an asset\"\n onClick={openCompactView}\n />\n </Box>\n <Box flex={1}>\n <Button\n style={{width: '100%'}}\n disabled={readOnly || !value}\n tone=\"critical\"\n mode=\"ghost\"\n text={'Remove'}\n title=\"Remove asset\"\n onClick={removeValue}\n />\n </Box>\n </Flex>","shouldLoad && isOpen && (\n <BynderModalLayout\n isOpen={isOpen}\n onClose={closeCompactView}\n portalConfig={pluginConfig.portalConfig}\n compactViewOptions={compactViewOptions}\n onSuccess={onSuccess}\n />\n )","portalConfig","<>\n <Flex\n justify=\"center\"\n align=\"center\"\n marginBottom={2}\n onClick={openCompactView}\n style={{cursor: 'pointer'}}\n >\n {preview}\n </Flex>\n <Flex gap={2} style={{width: '100%'}}>\n <Box flex={1}>\n <Button\n style={{width: '100%'}}\n loading={loading}\n disabled={readOnly}\n mode=\"ghost\"\n text={value ? 'Replace' : 'Browse'}\n title=\"Select an asset\"\n onClick={openCompactView}\n />\n </Box>\n <Box flex={1}>\n <Button\n style={{width: '100%'}}\n disabled={readOnly || !value}\n tone=\"critical\"\n mode=\"ghost\"\n text={'Remove'}\n title=\"Remove asset\"\n onClick={removeValue}\n />\n </Box>\n </Flex>\n {shouldLoad && isOpen && (\n <BynderModalLayout\n isOpen={isOpen}\n onClose={closeCompactView}\n portalConfig={pluginConfig.portalConfig}\n compactViewOptions={compactViewOptions}\n onSuccess={onSuccess}\n />\n )}\n </>","{value}: ComponentProps","{\n objectFit: 'contain',\n margin: 'auto',\n maxWidth: '100%',\n maxHeight: '100%',\n }","<Flex justify=\"center\" align=\"center\" height=\"fill\">\n <img\n alt=\"preview\"\n src={value?.previewImg ?? value?.previewUrl}\n style={{\n objectFit: 'contain',\n margin: 'auto',\n maxWidth: '100%',\n maxHeight: '100%',\n }}\n />\n </Flex>","value?.previewImg ?? value?.previewUrl","<Flex justify=\"center\" align=\"center\" height=\"fill\">\n <div>(no image)</div>\n </Flex>","{diff, schemaType}: DiffProps","<DiffFromTo diff={diff} schemaType={schemaType} previewComponent={Component} layout={'grid'} />"],"sources":["../src/components/BynderInput.tsx","../src/components/BynderDiff.tsx","../src/schema/bynder.asset.ts","../src/plugin.tsx"],"sourcesContent":["import type {CompactViewProps, PortalConfig, AdditionalInfo} from '@bynder/compact-view'\nimport {Box, Button, Flex} from '@sanity/ui'\nimport {useState, lazy, useTransition} from 'react'\nimport {type ObjectInputProps, PatchEvent, set, unset} from 'sanity'\n\nimport type {BynderAssetOptions, BynderAssetValue} from '../schema/bynder.asset'\n\nimport './BynderInput.css'\n\nconst VideoPlayer = lazy(() => import('./VideoPlayer'))\nconst BynderModalLayout = lazy(() => import('./BynderModalLayout'))\n\nexport interface BynderConfig {\n portalConfig: PortalConfig\n compactViewOptions: Omit<CompactViewProps, 'onSuccess'>\n /**\n * Studio-wide default for whether the full raw Bynder asset payload is\n * persisted onto documents (in addition to the canonical schema fields).\n * Field-level `persistRawFields` in `BynderAssetOptions` overrides this.\n * Defaults to `true` to preserve existing behavior.\n */\n persistRawFields?: boolean\n}\n\nexport interface BynderInputProps extends ObjectInputProps<BynderAssetValue> {\n pluginConfig: BynderConfig\n}\n\nconst getPreviewUrl = (asset: Record<string, any>, addInfo: Record<string, any>) => {\n switch (asset['type']) {\n case 'VIDEO':\n return asset['previewUrls'][0]\n default:\n return addInfo['selectedFile'] ? addInfo['selectedFile']?.url : asset['webImage'].url\n }\n}\n\nconst getVideoUrl = (asset: Record<string, any>) => {\n if (asset['type'] === 'VIDEO') {\n // if original asset is available (public videos only) use that if not fall back to the preview url\n return asset['files']?.original?.url ?? asset['previewUrls'][0]\n }\n return null\n}\n\nconst getAspectRatio = (dimensions: {width: number; height: number}): number =>\n dimensions.height / dimensions.width\n\nconst getVideoAspectRatio = (previewImageUrl: string) =>\n new Promise((resolve, reject) => {\n const img = new Image()\n\n // oxlint-disable-next-line prefer-add-event-listener\n img.onload = () => {\n resolve(\n getAspectRatio({\n width: img.width,\n height: img.height,\n }),\n )\n }\n // oxlint-disable-next-line prefer-add-event-listener\n img.onerror = (err) => reject(err)\n\n img.src = previewImageUrl\n })\n\nexport function BynderInput(props: BynderInputProps): React.JSX.Element {\n const {value, readOnly, schemaType, pluginConfig, onChange} = props\n const [isOpen, setIsOpen] = useState(false)\n\n // Merge field-level options with global plugin config\n // oxlint-disable-next-line no-unsafe-type-assertion\n const fieldOptions = schemaType.options as BynderAssetOptions | undefined\n const compactViewOptions = {\n ...pluginConfig.compactViewOptions,\n ...(fieldOptions?.assetTypes && {\n // oxlint-disable-next-line no-unsafe-type-assertion\n assetTypes: fieldOptions.assetTypes.map((t) => t.toUpperCase()) as (\n | 'IMAGE'\n | 'VIDEO'\n | 'AUDIO'\n )[],\n }),\n ...(fieldOptions?.assetFilter && {assetFilter: fieldOptions.assetFilter}),\n }\n\n const removeValue = () => {\n onChange(PatchEvent.from([unset()]))\n }\n\n const onSuccess = (assets: unknown[], addInfo: AdditionalInfo) => {\n // oxlint-disable-next-line no-unsafe-type-assertion\n const asset = assets[0] as Record<string, any>\n const webImage = asset['files']?.['webImage']\n\n const aspectRatio = webImage\n ? getAspectRatio({\n width: webImage.width,\n height: webImage.height,\n })\n : undefined\n\n const persistRawFields = fieldOptions?.persistRawFields ?? pluginConfig.persistRawFields ?? true\n\n const mediaData = {\n // When `persistRawFields` is true (the default), spread the full raw Bynder\n // asset payload first; explicit fields below then override with the\n // canonical, computed, or mapped values declared in the schema.\n ...(persistRawFields ? asset : {}),\n\n _key: value?._key,\n _type: schemaType.name,\n\n id: asset['id'],\n name: asset['name'],\n databaseId: asset['databaseId'],\n type: asset['type'],\n description: asset['description'],\n\n previewUrl: getPreviewUrl(asset, addInfo),\n previewImg: webImage?.url,\n datUrl: asset['files']?.['transformBaseUrl']?.url,\n videoUrl: getVideoUrl(asset),\n aspectRatio,\n selectedUrl: addInfo.selectedFile?.url,\n width: webImage?.width,\n height: webImage?.height,\n }\n\n if (asset['type'] === 'VIDEO') {\n getVideoAspectRatio(webImage?.url ?? '')\n // oxlint-disable-next-line always-return\n .then((ratio) => {\n onChange(PatchEvent.from([set({...mediaData, aspectRatio: ratio})]))\n setIsOpen(false)\n })\n .catch((err) => {\n // video aspect ratio couldn't be set, but should still set the rest of the data\n console.error('Error setting video aspect ratio:', err)\n onChange(PatchEvent.from([set(mediaData)]))\n setIsOpen(false)\n })\n } else {\n onChange(PatchEvent.from([set(mediaData)]))\n setIsOpen(false)\n }\n }\n\n let preview\n if (value) {\n if (value.type === 'VIDEO') {\n preview = (\n <VideoPlayer controls poster={value.previewImg} sources={[{src: value.previewUrl ?? ''}]} />\n )\n }\n if (value.type === 'IMAGE' || value.type === 'DOCUMENT') {\n preview = (\n <img\n alt=\"preview\"\n src={value.previewUrl}\n style={{width: 'auto', height: '100%', maxHeight: '20rem'}}\n />\n )\n // TODO: Add preview for audio types and empty state\n }\n }\n\n const [loading, startTransition] = useTransition()\n const [shouldLoad, setShouldLoad] = useState(false)\n const openCompactView = () => {\n // We want the button to show a loading state if it takes a while to lazy load the modal\n startTransition(() => setShouldLoad(true))\n // Opening the modal should never trigger a loading state\n setIsOpen(true)\n }\n const closeCompactView = () => setIsOpen(false)\n\n return (\n <>\n <Flex\n justify=\"center\"\n align=\"center\"\n marginBottom={2}\n onClick={openCompactView}\n style={{cursor: 'pointer'}}\n >\n {preview}\n </Flex>\n <Flex gap={2} style={{width: '100%'}}>\n <Box flex={1}>\n <Button\n style={{width: '100%'}}\n loading={loading}\n disabled={readOnly}\n mode=\"ghost\"\n text={value ? 'Replace' : 'Browse'}\n title=\"Select an asset\"\n onClick={openCompactView}\n />\n </Box>\n <Box flex={1}>\n <Button\n style={{width: '100%'}}\n disabled={readOnly || !value}\n tone=\"critical\"\n mode=\"ghost\"\n text={'Remove'}\n title=\"Remove asset\"\n onClick={removeValue}\n />\n </Box>\n </Flex>\n {shouldLoad && isOpen && (\n <BynderModalLayout\n isOpen={isOpen}\n onClose={closeCompactView}\n portalConfig={pluginConfig.portalConfig}\n compactViewOptions={compactViewOptions}\n onSuccess={onSuccess}\n />\n )}\n </>\n )\n}\n","import {Flex} from '@sanity/ui'\nimport {DiffFromTo, type SchemaType} from 'sanity'\n\ntype ComponentProps = {\n value: any\n}\n\nfunction Component({value}: ComponentProps) {\n if (value?.previewUrl || value?.previewImg) {\n return (\n <Flex justify=\"center\" align=\"center\" height=\"fill\">\n <img\n alt=\"preview\"\n src={value?.previewImg ?? value?.previewUrl}\n style={{\n objectFit: 'contain',\n margin: 'auto',\n maxWidth: '100%',\n maxHeight: '100%',\n }}\n />\n </Flex>\n )\n }\n\n return (\n <Flex justify=\"center\" align=\"center\" height=\"fill\">\n <div>(no image)</div>\n </Flex>\n )\n}\n\ntype DiffProps = {\n diff: any\n schemaType: SchemaType\n}\n\nexport function BynderDiff({diff, schemaType}: DiffProps): React.JSX.Element {\n return (\n <DiffFromTo diff={diff} schemaType={schemaType} previewComponent={Component} layout={'grid'} />\n )\n}\n","import {defineType, type ObjectDefinition, type ObjectOptions} from 'sanity'\n\nimport {BynderDiff} from '../components/BynderDiff'\n\nconst bynderAssetSchemaName = 'bynder.asset'\n\ntype BynderAssetType = 'AUDIO' | 'DOCUMENT' | 'IMAGE' | 'VIDEO'\n\ntype BynderAssetFilterJson = {\n assetType_in?: BynderAssetType[] //predefined asset types\n collectionId?: string //predefined collection id\n metapropertyOptionId_in?: string[] //predefined metaproperty IDs\n searchTerm?: string //predefined search term\n tagNames_in?: string[] //predefined tags\n isLimitedUse?: boolean //whether or not this asset is marked as Limited Use\n showToolbar?: boolean //show toolbar for predefined filters (false by default)\n}\n\nexport interface BynderAssetOptions extends ObjectOptions {\n assetTypes?: ('image' | 'video' | 'audio' | (string & {}))[]\n assetFilter?: BynderAssetFilterJson\n /**\n * When `true` (the default) the full raw Bynder asset payload is spread onto\n * the persisted document alongside the canonical fields declared in the\n * `bynder.asset` schema. Set to `false` to persist only the canonical subset\n * (the fields enumerated in `BynderAssetValue` / the schema definition).\n */\n persistRawFields?: boolean\n}\n\n/**\n * @public\n */\nexport interface BynderAssetDefinition extends Omit<\n ObjectDefinition,\n 'type' | 'fields' | 'options'\n> {\n type: typeof bynderAssetSchemaName\n options?: BynderAssetOptions\n}\n\ndeclare module 'sanity' {\n // makes type: 'bynder.asset' narrow correctly when using defineType/defineField/defineArrayMember\n export interface IntrinsicDefinitions {\n 'bynder.asset': BynderAssetDefinition\n }\n}\n\nexport interface BynderAssetValue {\n _type: typeof bynderAssetSchemaName\n _key?: string\n id?: string\n name?: string\n databaseId?: string\n type?: string\n previewUrl?: string\n previewImg?: string\n datUrl?: string\n description?: string\n aspectRatio?: number\n videoUrl?: string\n selectedUrl?: string\n width?: number\n height?: number\n /** Index signature to allow any additional Bynder asset fields */\n [key: string]: unknown\n}\n\nexport const bynderAssetSchema: ObjectDefinition = defineType({\n name: bynderAssetSchemaName,\n type: 'object',\n title: 'Bynder Asset',\n fields: [\n {\n type: 'string',\n name: 'id',\n },\n {\n type: 'string',\n name: 'name',\n },\n {\n type: 'string',\n name: 'databaseId',\n },\n {\n type: 'string',\n name: 'type',\n },\n {\n type: 'string',\n name: 'previewUrl',\n },\n {\n type: 'string',\n name: 'previewImg',\n },\n {\n type: 'string',\n name: 'datUrl',\n },\n {\n type: 'string',\n name: 'description',\n },\n {\n type: 'number',\n name: 'aspectRatio',\n },\n {\n type: 'number',\n name: 'width',\n },\n {\n type: 'number',\n name: 'height',\n },\n {\n type: 'string',\n name: 'videoUrl',\n },\n {\n type: 'string',\n name: 'selectedUrl',\n },\n ],\n components: {\n diff: BynderDiff,\n },\n})\n","import {definePlugin, type Plugin, isObjectInputProps, type SchemaType} from 'sanity'\n\nimport {BynderInput, type BynderConfig} from './components/BynderInput'\nimport {bynderAssetSchema, type BynderAssetValue} from './schema/bynder.asset'\n\nexport const bynderInputPlugin: Plugin<Partial<BynderConfig>> = definePlugin(\n (config: Partial<BynderConfig>) => {\n const reqConfig: BynderConfig = {\n portalConfig: {\n url: '',\n ...config?.portalConfig,\n },\n compactViewOptions: {\n language: 'en_US',\n ...config?.compactViewOptions,\n },\n persistRawFields: config?.persistRawFields,\n }\n\n return {\n name: 'bynder-assets',\n schema: {\n types: [bynderAssetSchema],\n },\n form: {\n components: {\n input: (props) => {\n if (isObjectInputProps(props) && isType(props.schemaType, bynderAssetSchema.name)) {\n return (\n // @ts-expect-error - TODO: fix this\n <BynderInput\n {...props}\n // oxlint-disable-next-line no-unsafe-type-assertion\n value={props.value as BynderAssetValue}\n pluginConfig={reqConfig}\n />\n )\n }\n return props.renderDefault(props)\n },\n },\n },\n }\n },\n)\n\nfunction isType(schemaType: SchemaType, name: string): boolean {\n if (schemaType.name === name) {\n return true\n }\n if (schemaType.type) {\n return isType(schemaType.type, name)\n }\n return false\n}\n"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"index.js","names":["fieldOptions?.assetTypes && {\n // oxlint-disable-next-line no-unsafe-type-assertion\n assetTypes: fieldOptions.assetTypes.map((t) => t.toUpperCase()) as (\n | 'IMAGE'\n | 'VIDEO'\n | 'AUDIO'\n )[],\n }","(t) => t.toUpperCase()","fieldOptions?.assetTypes","fieldOptions?.assetFilter && {assetFilter: fieldOptions.assetFilter}","fieldOptions?.assetFilter","{\n ...pluginConfig.compactViewOptions,\n ...(fieldOptions?.assetTypes && {\n // oxlint-disable-next-line no-unsafe-type-assertion\n assetTypes: fieldOptions.assetTypes.map((t) => t.toUpperCase()) as (\n | 'IMAGE'\n | 'VIDEO'\n | 'AUDIO'\n )[],\n }),\n ...(fieldOptions?.assetFilter && {assetFilter: fieldOptions.assetFilter}),\n }","compactViewOptions","() => {\n onChange(PatchEvent.from([unset()]))\n }","(assets: unknown[], addInfo: AdditionalInfo) => {\n // oxlint-disable-next-line no-unsafe-type-assertion\n const asset = assets[0] as Record<string, any>\n const webImage = asset['files']?.['webImage']\n\n const aspectRatio = webImage\n ? getAspectRatio({\n width: webImage.width,\n height: webImage.height,\n })\n : undefined\n\n const persistRawFields = fieldOptions?.persistRawFields ?? pluginConfig.persistRawFields ?? true\n\n const mediaData = {\n // When `persistRawFields` is true (the default), spread the full raw Bynder\n // asset payload first; explicit fields below then override with the\n // canonical, computed, or mapped values declared in the schema.\n ...(persistRawFields ? asset : {}),\n\n _key: value?._key,\n _type: schemaType.name,\n\n id: asset['id'],\n name: asset['name'],\n databaseId: asset['databaseId'],\n type: asset['type'],\n description: asset['description'],\n\n previewUrl: getPreviewUrl(asset, addInfo),\n previewImg: webImage?.url,\n datUrl: asset['files']?.['transformBaseUrl']?.url,\n videoUrl: getVideoUrl(asset),\n aspectRatio,\n selectedUrl: addInfo.selectedFile?.url,\n width: webImage?.width,\n height: webImage?.height,\n }\n\n if (asset['type'] === 'VIDEO') {\n getVideoAspectRatio(webImage?.url ?? '')\n // oxlint-disable-next-line always-return\n .then((ratio) => {\n onChange(PatchEvent.from([set({...mediaData, aspectRatio: ratio})]))\n setIsOpen(false)\n })\n .catch((err) => {\n // video aspect ratio couldn't be set, but should still set the rest of the data\n console.error('Error setting video aspect ratio:', err)\n onChange(PatchEvent.from([set(mediaData)]))\n setIsOpen(false)\n })\n } else {\n onChange(PatchEvent.from([set(mediaData)]))\n setIsOpen(false)\n }\n }","persistRawFields","name","_key","[{src: value.previewUrl ?? ''}]","value.previewUrl ?? ''","<VideoPlayer controls poster={value.previewImg} sources={[{src: value.previewUrl ?? ''}]} />","previewImg","{width: 'auto', height: '100%', maxHeight: '20rem'}","<img\n alt=\"preview\"\n src={value.previewUrl}\n style={{width: 'auto', height: '100%', maxHeight: '20rem'}}\n />","previewUrl","() => {\n // We want the button to show a loading state if it takes a while to lazy load the modal\n startTransition(() => setShouldLoad(true))\n // Opening the modal should never trigger a loading state\n setIsOpen(true)\n }","() => setIsOpen(false)","{cursor: 'pointer'}","<Flex\n justify=\"center\"\n align=\"center\"\n marginBottom={2}\n onClick={openCompactView}\n style={{cursor: 'pointer'}}\n >\n {preview}\n </Flex>","{width: '100%'}","<Box flex={1}>\n <Button\n style={{width: '100%'}}\n loading={loading}\n disabled={readOnly}\n mode=\"ghost\"\n text={value ? 'Replace' : 'Browse'}\n title=\"Select an asset\"\n onClick={openCompactView}\n />\n </Box>","value ? 'Replace' : 'Browse'","<Box flex={1}>\n <Button\n style={{width: '100%'}}\n disabled={readOnly || !value}\n tone=\"critical\"\n mode=\"ghost\"\n text={'Remove'}\n title=\"Remove asset\"\n onClick={removeValue}\n />\n </Box>","readOnly || !value","<Flex gap={2} style={{width: '100%'}}>\n <Box flex={1}>\n <Button\n style={{width: '100%'}}\n loading={loading}\n disabled={readOnly}\n mode=\"ghost\"\n text={value ? 'Replace' : 'Browse'}\n title=\"Select an asset\"\n onClick={openCompactView}\n />\n </Box>\n <Box flex={1}>\n <Button\n style={{width: '100%'}}\n disabled={readOnly || !value}\n tone=\"critical\"\n mode=\"ghost\"\n text={'Remove'}\n title=\"Remove asset\"\n onClick={removeValue}\n />\n </Box>\n </Flex>","shouldLoad && isOpen && (\n <BynderModalLayout\n isOpen={isOpen}\n onClose={closeCompactView}\n portalConfig={pluginConfig.portalConfig}\n compactViewOptions={compactViewOptions}\n onSuccess={onSuccess}\n />\n )","portalConfig","<>\n <Flex\n justify=\"center\"\n align=\"center\"\n marginBottom={2}\n onClick={openCompactView}\n style={{cursor: 'pointer'}}\n >\n {preview}\n </Flex>\n <Flex gap={2} style={{width: '100%'}}>\n <Box flex={1}>\n <Button\n style={{width: '100%'}}\n loading={loading}\n disabled={readOnly}\n mode=\"ghost\"\n text={value ? 'Replace' : 'Browse'}\n title=\"Select an asset\"\n onClick={openCompactView}\n />\n </Box>\n <Box flex={1}>\n <Button\n style={{width: '100%'}}\n disabled={readOnly || !value}\n tone=\"critical\"\n mode=\"ghost\"\n text={'Remove'}\n title=\"Remove asset\"\n onClick={removeValue}\n />\n </Box>\n </Flex>\n {shouldLoad && isOpen && (\n <BynderModalLayout\n isOpen={isOpen}\n onClose={closeCompactView}\n portalConfig={pluginConfig.portalConfig}\n compactViewOptions={compactViewOptions}\n onSuccess={onSuccess}\n />\n )}\n </>","_c","_Fragment","{value}: ComponentProps","{\n objectFit: 'contain',\n margin: 'auto',\n maxWidth: '100%',\n maxHeight: '100%',\n }","<Flex justify=\"center\" align=\"center\" height=\"fill\">\n <img\n alt=\"preview\"\n src={value?.previewImg ?? value?.previewUrl}\n style={{\n objectFit: 'contain',\n margin: 'auto',\n maxWidth: '100%',\n maxHeight: '100%',\n }}\n />\n </Flex>","value?.previewImg ?? value?.previewUrl","<Flex justify=\"center\" align=\"center\" height=\"fill\">\n <div>(no image)</div>\n </Flex>","{diff, schemaType}: DiffProps","<DiffFromTo diff={diff} schemaType={schemaType} previewComponent={Component} layout={'grid'} />","_c","\"type\"","\"previewUrls\"","\"selectedFile\"","\"webImage\"","\"files\"","\"id\"","\"name\"","\"databaseId\"","\"description\"","\"transformBaseUrl\""],"sources":["../src/components/BynderInput.tsx","../src/components/BynderDiff.tsx","../src/schema/bynder.asset.ts","../src/plugin.tsx"],"sourcesContent":["import type {CompactViewProps, PortalConfig, AdditionalInfo} from '@bynder/compact-view'\nimport {Box, Button, Flex} from '@sanity/ui'\nimport {useState, lazy, useTransition} from 'react'\nimport {type ObjectInputProps, PatchEvent, set, unset} from 'sanity'\n\nimport type {BynderAssetOptions, BynderAssetValue} from '../schema/bynder.asset'\n\nimport './BynderInput.css'\n\nconst VideoPlayer = lazy(() => import('./VideoPlayer'))\nconst BynderModalLayout = lazy(() => import('./BynderModalLayout'))\n\nexport interface BynderConfig {\n portalConfig: PortalConfig\n compactViewOptions: Omit<CompactViewProps, 'onSuccess'>\n /**\n * Studio-wide default for whether the full raw Bynder asset payload is\n * persisted onto documents (in addition to the canonical schema fields).\n * Field-level `persistRawFields` in `BynderAssetOptions` overrides this.\n * Defaults to `true` to preserve existing behavior.\n */\n persistRawFields?: boolean\n}\n\nexport interface BynderInputProps extends ObjectInputProps<BynderAssetValue> {\n pluginConfig: BynderConfig\n}\n\nconst getPreviewUrl = (asset: Record<string, any>, addInfo: Record<string, any>) => {\n switch (asset['type']) {\n case 'VIDEO':\n return asset['previewUrls'][0]\n default:\n return addInfo['selectedFile'] ? addInfo['selectedFile']?.url : asset['webImage'].url\n }\n}\n\nconst getVideoUrl = (asset: Record<string, any>) => {\n if (asset['type'] === 'VIDEO') {\n // if original asset is available (public videos only) use that if not fall back to the preview url\n return asset['files']?.original?.url ?? asset['previewUrls'][0]\n }\n return null\n}\n\nconst getAspectRatio = (dimensions: {width: number; height: number}): number =>\n dimensions.height / dimensions.width\n\nconst getVideoAspectRatio = (previewImageUrl: string) =>\n new Promise((resolve, reject) => {\n const img = new Image()\n\n // oxlint-disable-next-line prefer-add-event-listener\n img.onload = () => {\n resolve(\n getAspectRatio({\n width: img.width,\n height: img.height,\n }),\n )\n }\n // oxlint-disable-next-line prefer-add-event-listener\n img.onerror = (err) => reject(err)\n\n img.src = previewImageUrl\n })\n\nexport function BynderInput(props: BynderInputProps): React.JSX.Element {\n const {value, readOnly, schemaType, pluginConfig, onChange} = props\n const [isOpen, setIsOpen] = useState(false)\n\n // Merge field-level options with global plugin config\n // oxlint-disable-next-line no-unsafe-type-assertion\n const fieldOptions = schemaType.options as BynderAssetOptions | undefined\n const compactViewOptions = {\n ...pluginConfig.compactViewOptions,\n ...(fieldOptions?.assetTypes && {\n // oxlint-disable-next-line no-unsafe-type-assertion\n assetTypes: fieldOptions.assetTypes.map((t) => t.toUpperCase()) as (\n | 'IMAGE'\n | 'VIDEO'\n | 'AUDIO'\n )[],\n }),\n ...(fieldOptions?.assetFilter && {assetFilter: fieldOptions.assetFilter}),\n }\n\n const removeValue = () => {\n onChange(PatchEvent.from([unset()]))\n }\n\n const onSuccess = (assets: unknown[], addInfo: AdditionalInfo) => {\n // oxlint-disable-next-line no-unsafe-type-assertion\n const asset = assets[0] as Record<string, any>\n const webImage = asset['files']?.['webImage']\n\n const aspectRatio = webImage\n ? getAspectRatio({\n width: webImage.width,\n height: webImage.height,\n })\n : undefined\n\n const persistRawFields = fieldOptions?.persistRawFields ?? pluginConfig.persistRawFields ?? true\n\n const mediaData = {\n // When `persistRawFields` is true (the default), spread the full raw Bynder\n // asset payload first; explicit fields below then override with the\n // canonical, computed, or mapped values declared in the schema.\n ...(persistRawFields ? asset : {}),\n\n _key: value?._key,\n _type: schemaType.name,\n\n id: asset['id'],\n name: asset['name'],\n databaseId: asset['databaseId'],\n type: asset['type'],\n description: asset['description'],\n\n previewUrl: getPreviewUrl(asset, addInfo),\n previewImg: webImage?.url,\n datUrl: asset['files']?.['transformBaseUrl']?.url,\n videoUrl: getVideoUrl(asset),\n aspectRatio,\n selectedUrl: addInfo.selectedFile?.url,\n width: webImage?.width,\n height: webImage?.height,\n }\n\n if (asset['type'] === 'VIDEO') {\n getVideoAspectRatio(webImage?.url ?? '')\n // oxlint-disable-next-line always-return\n .then((ratio) => {\n onChange(PatchEvent.from([set({...mediaData, aspectRatio: ratio})]))\n setIsOpen(false)\n })\n .catch((err) => {\n // video aspect ratio couldn't be set, but should still set the rest of the data\n console.error('Error setting video aspect ratio:', err)\n onChange(PatchEvent.from([set(mediaData)]))\n setIsOpen(false)\n })\n } else {\n onChange(PatchEvent.from([set(mediaData)]))\n setIsOpen(false)\n }\n }\n\n let preview\n if (value) {\n if (value.type === 'VIDEO') {\n preview = (\n <VideoPlayer controls poster={value.previewImg} sources={[{src: value.previewUrl ?? ''}]} />\n )\n }\n if (value.type === 'IMAGE' || value.type === 'DOCUMENT') {\n preview = (\n <img\n alt=\"preview\"\n src={value.previewUrl}\n style={{width: 'auto', height: '100%', maxHeight: '20rem'}}\n />\n )\n // TODO: Add preview for audio types and empty state\n }\n }\n\n const [loading, startTransition] = useTransition()\n const [shouldLoad, setShouldLoad] = useState(false)\n const openCompactView = () => {\n // We want the button to show a loading state if it takes a while to lazy load the modal\n startTransition(() => setShouldLoad(true))\n // Opening the modal should never trigger a loading state\n setIsOpen(true)\n }\n const closeCompactView = () => setIsOpen(false)\n\n return (\n <>\n <Flex\n justify=\"center\"\n align=\"center\"\n marginBottom={2}\n onClick={openCompactView}\n style={{cursor: 'pointer'}}\n >\n {preview}\n </Flex>\n <Flex gap={2} style={{width: '100%'}}>\n <Box flex={1}>\n <Button\n style={{width: '100%'}}\n loading={loading}\n disabled={readOnly}\n mode=\"ghost\"\n text={value ? 'Replace' : 'Browse'}\n title=\"Select an asset\"\n onClick={openCompactView}\n />\n </Box>\n <Box flex={1}>\n <Button\n style={{width: '100%'}}\n disabled={readOnly || !value}\n tone=\"critical\"\n mode=\"ghost\"\n text={'Remove'}\n title=\"Remove asset\"\n onClick={removeValue}\n />\n </Box>\n </Flex>\n {shouldLoad && isOpen && (\n <BynderModalLayout\n isOpen={isOpen}\n onClose={closeCompactView}\n portalConfig={pluginConfig.portalConfig}\n compactViewOptions={compactViewOptions}\n onSuccess={onSuccess}\n />\n )}\n </>\n )\n}\n","import {Flex} from '@sanity/ui'\nimport {DiffFromTo, type SchemaType} from 'sanity'\n\ntype ComponentProps = {\n value: any\n}\n\nfunction Component({value}: ComponentProps) {\n if (value?.previewUrl || value?.previewImg) {\n return (\n <Flex justify=\"center\" align=\"center\" height=\"fill\">\n <img\n alt=\"preview\"\n src={value?.previewImg ?? value?.previewUrl}\n style={{\n objectFit: 'contain',\n margin: 'auto',\n maxWidth: '100%',\n maxHeight: '100%',\n }}\n />\n </Flex>\n )\n }\n\n return (\n <Flex justify=\"center\" align=\"center\" height=\"fill\">\n <div>(no image)</div>\n </Flex>\n )\n}\n\ntype DiffProps = {\n diff: any\n schemaType: SchemaType\n}\n\nexport function BynderDiff({diff, schemaType}: DiffProps): React.JSX.Element {\n return (\n <DiffFromTo diff={diff} schemaType={schemaType} previewComponent={Component} layout={'grid'} />\n )\n}\n","import {defineType, type ObjectDefinition, type ObjectOptions} from 'sanity'\n\nimport {BynderDiff} from '../components/BynderDiff'\n\nconst bynderAssetSchemaName = 'bynder.asset'\n\ntype BynderAssetType = 'AUDIO' | 'DOCUMENT' | 'IMAGE' | 'VIDEO'\n\ntype BynderAssetFilterJson = {\n assetType_in?: BynderAssetType[] //predefined asset types\n collectionId?: string //predefined collection id\n metapropertyOptionId_in?: string[] //predefined metaproperty IDs\n searchTerm?: string //predefined search term\n tagNames_in?: string[] //predefined tags\n isLimitedUse?: boolean //whether or not this asset is marked as Limited Use\n showToolbar?: boolean //show toolbar for predefined filters (false by default)\n}\n\nexport interface BynderAssetOptions extends ObjectOptions {\n assetTypes?: ('image' | 'video' | 'audio' | (string & {}))[]\n assetFilter?: BynderAssetFilterJson\n /**\n * When `true` (the default) the full raw Bynder asset payload is spread onto\n * the persisted document alongside the canonical fields declared in the\n * `bynder.asset` schema. Set to `false` to persist only the canonical subset\n * (the fields enumerated in `BynderAssetValue` / the schema definition).\n */\n persistRawFields?: boolean\n}\n\n/**\n * @public\n */\nexport interface BynderAssetDefinition extends Omit<\n ObjectDefinition,\n 'type' | 'fields' | 'options'\n> {\n type: typeof bynderAssetSchemaName\n options?: BynderAssetOptions\n}\n\ndeclare module 'sanity' {\n // makes type: 'bynder.asset' narrow correctly when using defineType/defineField/defineArrayMember\n export interface IntrinsicDefinitions {\n 'bynder.asset': BynderAssetDefinition\n }\n}\n\nexport interface BynderAssetValue {\n _type: typeof bynderAssetSchemaName\n _key?: string\n id?: string\n name?: string\n databaseId?: string\n type?: string\n previewUrl?: string\n previewImg?: string\n datUrl?: string\n description?: string\n aspectRatio?: number\n videoUrl?: string\n selectedUrl?: string\n width?: number\n height?: number\n /** Index signature to allow any additional Bynder asset fields */\n [key: string]: unknown\n}\n\nexport const bynderAssetSchema: ObjectDefinition = defineType({\n name: bynderAssetSchemaName,\n type: 'object',\n title: 'Bynder Asset',\n fields: [\n {\n type: 'string',\n name: 'id',\n },\n {\n type: 'string',\n name: 'name',\n },\n {\n type: 'string',\n name: 'databaseId',\n },\n {\n type: 'string',\n name: 'type',\n },\n {\n type: 'string',\n name: 'previewUrl',\n },\n {\n type: 'string',\n name: 'previewImg',\n },\n {\n type: 'string',\n name: 'datUrl',\n },\n {\n type: 'string',\n name: 'description',\n },\n {\n type: 'number',\n name: 'aspectRatio',\n },\n {\n type: 'number',\n name: 'width',\n },\n {\n type: 'number',\n name: 'height',\n },\n {\n type: 'string',\n name: 'videoUrl',\n },\n {\n type: 'string',\n name: 'selectedUrl',\n },\n ],\n components: {\n diff: BynderDiff,\n },\n})\n","import {definePlugin, type Plugin, isObjectInputProps, type SchemaType} from 'sanity'\n\nimport {BynderInput, type BynderConfig} from './components/BynderInput'\nimport {bynderAssetSchema, type BynderAssetValue} from './schema/bynder.asset'\n\nexport const bynderInputPlugin: Plugin<Partial<BynderConfig>> = definePlugin(\n (config: Partial<BynderConfig>) => {\n const reqConfig: BynderConfig = {\n portalConfig: {\n url: '',\n ...config?.portalConfig,\n },\n compactViewOptions: {\n language: 'en_US',\n ...config?.compactViewOptions,\n },\n persistRawFields: config?.persistRawFields,\n }\n\n return {\n name: 'bynder-assets',\n schema: {\n types: [bynderAssetSchema],\n },\n form: {\n components: {\n input: (props) => {\n if (isObjectInputProps(props) && isType(props.schemaType, bynderAssetSchema.name)) {\n return (\n // @ts-expect-error - TODO: fix this\n <BynderInput\n {...props}\n // oxlint-disable-next-line no-unsafe-type-assertion\n value={props.value as BynderAssetValue}\n pluginConfig={reqConfig}\n />\n )\n }\n return props.renderDefault(props)\n },\n },\n },\n }\n },\n)\n\nfunction isType(schemaType: SchemaType, name: string): boolean {\n if (schemaType.name === name) {\n return true\n }\n if (schemaType.type) {\n return isType(schemaType.type, name)\n }\n return false\n}\n"],"mappings":"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"}
\ No newline at end of file Index: package/dist/VideoPlayer-YpxI09aD.js.map
===================================================================
--- package/dist/VideoPlayer-YpxI09aD.js.map
+++ package/dist/VideoPlayer-YpxI09aD.js.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"VideoPlayer-YpxI09aD.js","names":["() => {\n if (videoNode.current) {\n setPlayer(videojs(videoNode.current, props))\n }\n return () => player?.dispose()\n }","[videoNode, player, props]","player?.dispose","<link href=\"https://vjs.zencdn.net/7.8.4/video-js.css\" rel=\"stylesheet\" />","<div>\n <link href=\"https://vjs.zencdn.net/7.8.4/video-js.css\" rel=\"stylesheet\" />\n <div data-vjs-player style={{marginBottom: '16px'}}>\n {/* oxlint-disable-next-line media-has-caption */}\n <video className=\"video-js vjs-16-9 vjs-big-play-centered\" ref={videoNode} />\n </div>\n </div>"],"sources":["../src/components/VideoPlayer.tsx"],"sourcesContent":["import {useEffect, useRef, useState} from 'react'\nimport videojs, {type VideoJsPlayer, type VideoJsPlayerOptions} from 'video.js'\n\nexport default function VideoPlayer(props: VideoJsPlayerOptions): React.JSX.Element {\n const videoNode = useRef<HTMLVideoElement>(null)\n const [player, setPlayer] = useState<VideoJsPlayer>()\n\n useEffect(() => {\n if (videoNode.current) {\n setPlayer(videojs(videoNode.current, props))\n }\n return () => player?.dispose()\n }, [videoNode, player, props])\n\n return (\n <div>\n <link href=\"https://vjs.zencdn.net/7.8.4/video-js.css\" rel=\"stylesheet\" />\n <div data-vjs-player style={{marginBottom: '16px'}}>\n {/* oxlint-disable-next-line media-has-caption */}\n <video className=\"video-js vjs-16-9 vjs-big-play-centered\" ref={videoNode} />\n </div>\n </div>\n )\n}\n"],"mappings":";;;;AAGA,SAAwB,YAAY,OAAgD;eAC5E,YAAY,OAAyB,IAAI,GACzC,CAAC,QAAQ,aAAa,SAAwB,GAE1CA,IAKPC;CALH,AAIeC,EAAAA,OAAAA,UAAAA,EAAAA,OAF0B,SAF/B,YACJ,UAAU,WACZ,UAAU,QAAQ,UAAU,SAAS,KAAK,CAAC,SAEhC,QAAQ,QAAQ,IAC5B,KAAA;EAAC;EAAW;EAAQ;CAAK,GADbA,EAAAA,KAAAA,QAF0B,EAAA,KAAA,uDAFzC,UAAUF,IAKPC,EAA0B;CAIzBE,IAAAA;qDAAC,KAAA,oBAAA,QAAD;EAAM,MAAK;EAA4C,KAAI;CAAc,CAAA;CAD3EC,IAAAA;CADF,2DACG,KAAA,qBAAA,OAAD,EAAA,UAAA,CACED,IACA,oBAAC,OAAD;EAAK,mBAAA;EAAgB,OAAO,EAAC,cAAc,OAAM;EAE/C,UAAA,oBAAC,SAAD;GAAO,WAAU;GAA0C,KAAK;EAAY,CAAA;CACzE,CAAA,CACF,EAAA,CAAA,2BANLC;AAQJ"}
\ No newline at end of file
+{"version":3,"file":"VideoPlayer-YpxI09aD.js","names":["() => {\n if (videoNode.current) {\n setPlayer(videojs(videoNode.current, props))\n }\n return () => player?.dispose()\n }","[videoNode, player, props]","player?.dispose","<link href=\"https://vjs.zencdn.net/7.8.4/video-js.css\" rel=\"stylesheet\" />","<div>\n <link href=\"https://vjs.zencdn.net/7.8.4/video-js.css\" rel=\"stylesheet\" />\n <div data-vjs-player style={{marginBottom: '16px'}}>\n {/* oxlint-disable-next-line media-has-caption */}\n <video className=\"video-js vjs-16-9 vjs-big-play-centered\" ref={videoNode} />\n </div>\n </div>","_c"],"sources":["../src/components/VideoPlayer.tsx"],"sourcesContent":["import {useEffect, useRef, useState} from 'react'\nimport videojs, {type VideoJsPlayer, type VideoJsPlayerOptions} from 'video.js'\n\nexport default function VideoPlayer(props: VideoJsPlayerOptions): React.JSX.Element {\n const videoNode = useRef<HTMLVideoElement>(null)\n const [player, setPlayer] = useState<VideoJsPlayer>()\n\n useEffect(() => {\n if (videoNode.current) {\n setPlayer(videojs(videoNode.current, props))\n }\n return () => player?.dispose()\n }, [videoNode, player, props])\n\n return (\n <div>\n <link href=\"https://vjs.zencdn.net/7.8.4/video-js.css\" rel=\"stylesheet\" />\n <div data-vjs-player style={{marginBottom: '16px'}}>\n {/* oxlint-disable-next-line media-has-caption */}\n <video className=\"video-js vjs-16-9 vjs-big-play-centered\" ref={videoNode} />\n </div>\n </div>\n )\n}\n"],"mappings":";;;;AAGA,SAAwB,YAAY,OAAgD;eAC5E,YAAY,OAAyB,IAAI,GACzC,CAAC,QAAQ,aAAa,SAAwB,GAE1CA,IAKPC;CALH,AAIeC,EAAAA,OAAAA,UAAAA,EAAAA,OAF0B,SAF/B,YACJ,UAAU,WACZ,UAAU,QAAQ,UAAU,SAAS,KAAK,CAAC,SAEhC,QAAQ,QAAQ,IAC5B,KAAA;EAAC;EAAW;EAAQ;CAAK,GADbA,EAAAA,KAAAA,QAF0B,EAAA,KAAA,uDAFzC,UAAUF,IAKPC,EAA0B;CAIzBE,IAAAA;qDAAC,KAAA,oBAAA,QAAD;EAAM,MAAK;EAA4C,KAAI;CAAc,CAAA;CAD3EC,IAAAA;CADF,2DACG,KAAA,qBAAA,OAAD,EAAA,UAAA,CACED,IACA,oBAAC,OAAD;EAAK,mBAAA;EAAgB,OAAO,EAAC,cAAc,OAAM;EAE/C,UAAA,oBAAC,SAAD;GAAO,WAAU;GAA0C,KAAK;EAAY,CAAA;CACzE,CAAA,CACF,EAAA,CAAA,2BANLC;AAQJ"}
\ No newline at end of file