@orangelogic/orange-dam-content-browser-sdk 2.1.55 → 2.2.0-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (281) hide show
  1. package/.env +1 -0
  2. package/.eslintignore +2 -0
  3. package/.eslintrc.json +82 -0
  4. package/.releaserc +17 -0
  5. package/.travis.yml +20 -0
  6. package/CBSDKdemo.html +315 -0
  7. package/GitVersion.yml +18 -0
  8. package/azure-pipeline.yaml +94 -0
  9. package/clientlib.config.js +36 -0
  10. package/config/env.js +105 -0
  11. package/config/getHttpsConfig.js +67 -0
  12. package/config/jest/babelTransform.js +30 -0
  13. package/config/jest/cssTransform.js +14 -0
  14. package/config/jest/fileTransform.js +41 -0
  15. package/config/modules.js +135 -0
  16. package/config/paths.js +79 -0
  17. package/config/webpack/persistentCache/createEnvironmentHash.js +10 -0
  18. package/config/webpack.config.js +762 -0
  19. package/config/webpackDevServer.config.js +128 -0
  20. package/config-overrides.js +8 -0
  21. package/gab_extension/GAB.html +85 -0
  22. package/gab_extension/GoogleChrome/manifest.json +28 -0
  23. package/gab_extension/GoogleChrome/src/assets/icon48.png +0 -0
  24. package/gab_extension/GoogleChrome/src/background/index.js +6 -0
  25. package/gab_extension/GoogleChrome/src/scripts/index.js +347 -0
  26. package/gab_extension/MozillaFirefox/manifest.json +20 -0
  27. package/gab_extension/MozillaFirefox/src/assets/icon.png +0 -0
  28. package/gab_extension/MozillaFirefox/src/background/index.js +5 -0
  29. package/gab_extension/MozillaFirefox/src/scripts/index.js +347 -0
  30. package/gab_extension/README.md +11 -0
  31. package/gab_extension/Safari/Orange DAM Asset Browser Extension/Orange DAM Asset Browser Extension.xcodeproj/project.pbxproj +927 -0
  32. package/gab_extension/Safari/Orange DAM Asset Browser Extension/Orange DAM Asset Browser Extension.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  33. package/gab_extension/Safari/Orange DAM Asset Browser Extension/Orange DAM Asset Browser Extension.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  34. package/gab_extension/Safari/Orange DAM Asset Browser Extension/Orange DAM Asset Browser Extension.xcodeproj/project.xcworkspace/xcuserdata/oldevmac01.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  35. package/gab_extension/Safari/Orange DAM Asset Browser Extension/Orange DAM Asset Browser Extension.xcodeproj/xcuserdata/oldevmac01.xcuserdatad/xcschemes/xcschememanagement.plist +19 -0
  36. package/gab_extension/Safari/Orange DAM Asset Browser Extension/Shared (App)/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
  37. package/gab_extension/Safari/Orange DAM Asset Browser Extension/Shared (App)/Assets.xcassets/AppIcon.appiconset/Contents.json +63 -0
  38. package/gab_extension/Safari/Orange DAM Asset Browser Extension/Shared (App)/Assets.xcassets/Contents.json +6 -0
  39. package/gab_extension/Safari/Orange DAM Asset Browser Extension/Shared (App)/Assets.xcassets/LargeIcon.imageset/Contents.json +20 -0
  40. package/gab_extension/Safari/Orange DAM Asset Browser Extension/Shared (App)/Base.lproj/Main.html +23 -0
  41. package/gab_extension/Safari/Orange DAM Asset Browser Extension/Shared (App)/Resources/Icon.png +0 -0
  42. package/gab_extension/Safari/Orange DAM Asset Browser Extension/Shared (App)/Resources/Script.js +24 -0
  43. package/gab_extension/Safari/Orange DAM Asset Browser Extension/Shared (App)/Resources/Style.css +61 -0
  44. package/gab_extension/Safari/Orange DAM Asset Browser Extension/Shared (App)/ViewController.swift +81 -0
  45. package/gab_extension/Safari/Orange DAM Asset Browser Extension/Shared (Extension)/SafariWebExtensionHandler.swift +26 -0
  46. package/gab_extension/Safari/Orange DAM Asset Browser Extension/iOS (App)/AppDelegate.swift +24 -0
  47. package/gab_extension/Safari/Orange DAM Asset Browser Extension/iOS (App)/Base.lproj/LaunchScreen.storyboard +36 -0
  48. package/gab_extension/Safari/Orange DAM Asset Browser Extension/iOS (App)/Base.lproj/Main.storyboard +38 -0
  49. package/gab_extension/Safari/Orange DAM Asset Browser Extension/iOS (App)/Info.plist +27 -0
  50. package/gab_extension/Safari/Orange DAM Asset Browser Extension/iOS (App)/SceneDelegate.swift +18 -0
  51. package/gab_extension/Safari/Orange DAM Asset Browser Extension/iOS (Extension)/Info.plist +13 -0
  52. package/gab_extension/Safari/Orange DAM Asset Browser Extension/macOS (App)/AppDelegate.swift +21 -0
  53. package/gab_extension/Safari/Orange DAM Asset Browser Extension/macOS (App)/Base.lproj/Main.storyboard +125 -0
  54. package/gab_extension/Safari/Orange DAM Asset Browser Extension/macOS (App)/Info.plist +8 -0
  55. package/gab_extension/Safari/Orange DAM Asset Browser Extension/macOS (App)/Orange DAM Asset Browser Extension.entitlements +12 -0
  56. package/gab_extension/Safari/Orange DAM Asset Browser Extension/macOS (Extension)/Info.plist +13 -0
  57. package/gab_extension/Safari/Orange DAM Asset Browser Extension/macOS (Extension)/Orange DAM Asset Browser Extension.entitlements +10 -0
  58. package/package.json +8 -49
  59. package/public/index.html +92 -0
  60. package/scripts/build.js +218 -0
  61. package/scripts/start.js +154 -0
  62. package/scripts/test.js +53 -0
  63. package/src/App.tsx +98 -0
  64. package/src/AppContext.ts +18 -0
  65. package/src/GlobalConfigContext.ts +46 -0
  66. package/src/components/ArrayClamp/ArrayClamp.styled.ts +42 -0
  67. package/src/components/ArrayClamp/ArrayClamp.tsx +167 -0
  68. package/src/components/ArrayClamp/index.ts +1 -0
  69. package/src/components/Browser/Browser.styled.ts +82 -0
  70. package/src/components/Browser/Browser.tsx +284 -0
  71. package/src/components/Browser/BrowserItem.tsx +98 -0
  72. package/src/components/ControlBar/ControlBar.constants.tsx +66 -0
  73. package/src/components/ControlBar/ControlBar.styled.ts +82 -0
  74. package/src/components/ControlBar/ControlBar.tsx +528 -0
  75. package/src/components/ControlBar/Facet/Facet.tsx +113 -0
  76. package/src/components/ControlBar/Facet/index.ts +1 -0
  77. package/src/components/FormatDialog/CropPreviewer/CropPreviewer.tsx +224 -0
  78. package/{build/components/FormatDialog/CropPreviewer/index.d.ts → src/components/FormatDialog/CropPreviewer/index.ts} +1 -1
  79. package/src/components/FormatDialog/CustomRendition/CustomRendition.constants.ts +24 -0
  80. package/src/components/FormatDialog/CustomRendition/CustomRendition.styled.ts +57 -0
  81. package/src/components/FormatDialog/CustomRendition/CustomRendition.tsx +178 -0
  82. package/src/components/FormatDialog/CustomRendition/index.ts +1 -0
  83. package/src/components/FormatDialog/CustomRendition/transformations/Crop.tsx +249 -0
  84. package/src/components/FormatDialog/CustomRendition/transformations/Extension.tsx +54 -0
  85. package/src/components/FormatDialog/CustomRendition/transformations/Format.tsx +86 -0
  86. package/src/components/FormatDialog/CustomRendition/transformations/Resize.tsx +176 -0
  87. package/src/components/FormatDialog/CustomRendition/transformations/Rotate.tsx +101 -0
  88. package/{build/components/FormatDialog/CustomRendition/transformations/index.d.ts → src/components/FormatDialog/CustomRendition/transformations/index.ts} +1 -3
  89. package/src/components/FormatDialog/FormatDialog.styled.ts +137 -0
  90. package/src/components/FormatDialog/FormatDialog.tsx +1533 -0
  91. package/src/components/FormatDialog/Previewer/Previewer.styled.ts +31 -0
  92. package/src/components/FormatDialog/Previewer/Previewer.tsx +143 -0
  93. package/src/components/FormatDialog/Previewer/index.ts +1 -0
  94. package/src/components/FormatDialog/ProxyMenu/ProxyMenu.styled.ts +88 -0
  95. package/src/components/FormatDialog/ProxyMenu/ProxyMenu.tsx +74 -0
  96. package/src/components/FormatDialog/ProxyMenu/index.ts +1 -0
  97. package/src/components/FormatDialog/TrackingParameters/TrackingParameters.tsx +59 -0
  98. package/src/components/FormatDialog/TrackingParameters/index.ts +1 -0
  99. package/src/components/FormatDialog/index.ts +1 -0
  100. package/src/components/Header/Header.styled.ts +51 -0
  101. package/src/components/Header/Header.tsx +118 -0
  102. package/src/components/Loader/Loader.tsx +37 -0
  103. package/src/components/Loader/index.ts +1 -0
  104. package/src/components/NoResult/NoResult.tsx +37 -0
  105. package/src/components/NoResult/index.tsx +1 -0
  106. package/src/components/Result/AssetCard/AssetCard.styled.ts +120 -0
  107. package/src/components/Result/AssetCard/AssetCard.tsx +192 -0
  108. package/src/components/Result/AssetCard/AssetCardWrapper.styled.ts +35 -0
  109. package/src/components/Result/AssetCard/AssetCardWrapper.tsx +165 -0
  110. package/src/components/Result/AssetCard/index.ts +1 -0
  111. package/src/components/Result/AssetPreview/AssetPreview.styled.ts +108 -0
  112. package/src/components/Result/AssetPreview/AssetPreview.tsx +78 -0
  113. package/src/components/Result/AssetPreview/ImagePreview/ImagePreview.tsx +42 -0
  114. package/src/components/Result/AssetPreview/ImagePreview/index.ts +1 -0
  115. package/src/components/Result/AssetPreview/OtherPreview/OtherPreview.styled.ts +23 -0
  116. package/src/components/Result/AssetPreview/OtherPreview/OtherPreview.tsx +28 -0
  117. package/src/components/Result/AssetPreview/OtherPreview/index.ts +1 -0
  118. package/src/components/Result/AssetPreview/VideoPreview/VideoPreview.tsx +132 -0
  119. package/src/components/Result/AssetPreview/VideoPreview/index.ts +1 -0
  120. package/src/components/Result/AssetPreview/index.ts +1 -0
  121. package/src/consts/asset.ts +16 -0
  122. package/src/consts/data.ts +17 -0
  123. package/src/index.tsx +305 -0
  124. package/src/page/Authenticate/Authenticate.tsx +232 -0
  125. package/src/page/Authenticate/ConnectingBackground.tsx +44 -0
  126. package/src/page/Authenticate/index.tsx +94 -0
  127. package/src/page/Home/Home.styled.ts +46 -0
  128. package/src/page/Home/Home.tsx +941 -0
  129. package/src/react-web-component.d.ts +4617 -0
  130. package/src/store/assets/assets.api.ts +167 -0
  131. package/src/store/assets/assets.service.ts +223 -0
  132. package/src/store/assets/assets.slice.ts +104 -0
  133. package/src/store/auth/auth.service.ts +71 -0
  134. package/src/store/auth/auth.slice.ts +295 -0
  135. package/src/store/index.ts +27 -0
  136. package/src/store/search/search.api.ts +319 -0
  137. package/src/store/search/search.slice.ts +28 -0
  138. package/src/store/user/user.api.ts +29 -0
  139. package/src/styles.css +42 -0
  140. package/src/types/assets.ts +71 -0
  141. package/src/types/auth.ts +42 -0
  142. package/src/types/common.ts +11 -0
  143. package/src/types/download.ts +8 -0
  144. package/src/types/navigation.ts +3 -0
  145. package/src/types/search.ts +116 -0
  146. package/{build/types/storage.d.ts → src/types/storage.ts} +1 -1
  147. package/src/types/user.ts +6 -0
  148. package/src/utils/api.ts +186 -0
  149. package/src/utils/array.ts +25 -0
  150. package/src/utils/constants.ts +12 -0
  151. package/src/utils/fetch.ts +116 -0
  152. package/src/utils/getRequestUrl.ts +15 -0
  153. package/src/utils/hooks.ts +36 -0
  154. package/src/utils/icon.ts +22 -0
  155. package/src/utils/image.ts +157 -0
  156. package/src/utils/number.ts +11 -0
  157. package/src/utils/rotate.ts +23 -0
  158. package/src/utils/storage.ts +184 -0
  159. package/src/utils/string.ts +24 -0
  160. package/src/view/AssetsPicker.tsx +24 -0
  161. package/src/web-component.d.ts +8151 -0
  162. package/tsconfig.eslint.json +10 -0
  163. package/tsconfig.json +37 -0
  164. package/build/ApiService.d.ts +0 -15
  165. package/build/App.d.ts +0 -62
  166. package/build/AppContext.d.ts +0 -18
  167. package/build/GlobalConfigContext.d.ts +0 -32
  168. package/build/OrangeDAMContentBrowserSDK.min.css +0 -2
  169. package/build/OrangeDAMContentBrowserSDK.min.css.map +0 -1
  170. package/build/OrangeDAMContentBrowserSDK.min.js +0 -11468
  171. package/build/OrangeDAMContentBrowserSDK.min.js.map +0 -1
  172. package/build/asset-manifest.json +0 -13
  173. package/build/components/ArrayClamp/ArrayClamp.d.ts +0 -10
  174. package/build/components/ArrayClamp/ArrayClamp.styled.d.ts +0 -1
  175. package/build/components/ArrayClamp/index.d.ts +0 -1
  176. package/build/components/Browser/Browser.constants.d.ts +0 -3
  177. package/build/components/Browser/Browser.d.ts +0 -21
  178. package/build/components/Browser/Browser.styled.d.ts +0 -2
  179. package/build/components/Browser/BrowserItem.d.ts +0 -13
  180. package/build/components/Browser/LoadMoreButton.d.ts +0 -9
  181. package/build/components/ControlBar/ControlBar.constants.d.ts +0 -10
  182. package/build/components/ControlBar/ControlBar.d.ts +0 -23
  183. package/build/components/ControlBar/ControlBar.styled.d.ts +0 -1
  184. package/build/components/ControlBar/Facet/Facet.d.ts +0 -14
  185. package/build/components/ControlBar/Facet/index.d.ts +0 -1
  186. package/build/components/FormatDialog/CropPreviewer/CropPreviewer.d.ts +0 -41
  187. package/build/components/FormatDialog/CustomRendition/CustomRendition.constants.d.ts +0 -5
  188. package/build/components/FormatDialog/CustomRendition/CustomRendition.d.ts +0 -56
  189. package/build/components/FormatDialog/CustomRendition/CustomRendition.styled.d.ts +0 -1
  190. package/build/components/FormatDialog/CustomRendition/index.d.ts +0 -1
  191. package/build/components/FormatDialog/CustomRendition/transformations/Crop.d.ts +0 -26
  192. package/build/components/FormatDialog/CustomRendition/transformations/Extension.d.ts +0 -11
  193. package/build/components/FormatDialog/CustomRendition/transformations/Format.d.ts +0 -10
  194. package/build/components/FormatDialog/CustomRendition/transformations/Metadata.d.ts +0 -7
  195. package/build/components/FormatDialog/CustomRendition/transformations/Quality.d.ts +0 -7
  196. package/build/components/FormatDialog/CustomRendition/transformations/Resize.d.ts +0 -18
  197. package/build/components/FormatDialog/CustomRendition/transformations/Rotate.d.ts +0 -8
  198. package/build/components/FormatDialog/FormatDialog.d.ts +0 -49
  199. package/build/components/FormatDialog/FormatDialog.styled.d.ts +0 -3
  200. package/build/components/FormatDialog/Previewer/Previewer.d.ts +0 -17
  201. package/build/components/FormatDialog/Previewer/Previewer.styled.d.ts +0 -1
  202. package/build/components/FormatDialog/Previewer/index.d.ts +0 -1
  203. package/build/components/FormatDialog/ProxyMenu/ProxyMenu.d.ts +0 -20
  204. package/build/components/FormatDialog/ProxyMenu/ProxyMenu.styled.d.ts +0 -2
  205. package/build/components/FormatDialog/ProxyMenu/index.d.ts +0 -1
  206. package/build/components/FormatDialog/TrackingParameters/TrackingParameters.d.ts +0 -13
  207. package/build/components/FormatDialog/TrackingParameters/index.d.ts +0 -1
  208. package/build/components/FormatDialog/VersionHistory/VersionHistory.d.ts +0 -6
  209. package/build/components/FormatDialog/VersionHistory/VersionHistory.styled.d.ts +0 -1
  210. package/build/components/FormatDialog/VersionHistory/index.d.ts +0 -1
  211. package/build/components/FormatDialog/index.d.ts +0 -1
  212. package/build/components/Header/Header.d.ts +0 -15
  213. package/build/components/Header/Header.styled.d.ts +0 -5
  214. package/build/components/Loader/Loader.d.ts +0 -7
  215. package/build/components/Loader/index.d.ts +0 -1
  216. package/build/components/NoResult/NoResult.d.ts +0 -7
  217. package/build/components/NoResult/index.d.ts +0 -1
  218. package/build/components/Result/AssetCard/AssetCard.d.ts +0 -15
  219. package/build/components/Result/AssetCard/AssetCard.styled.d.ts +0 -2
  220. package/build/components/Result/AssetCard/AssetCardWrapper.d.ts +0 -18
  221. package/build/components/Result/AssetCard/AssetCardWrapper.styled.d.ts +0 -1
  222. package/build/components/Result/AssetCard/index.d.ts +0 -1
  223. package/build/components/Result/AssetPreview/AssetPreview.d.ts +0 -11
  224. package/build/components/Result/AssetPreview/AssetPreview.styled.d.ts +0 -1
  225. package/build/components/Result/AssetPreview/ImagePreview/ImagePreview.d.ts +0 -11
  226. package/build/components/Result/AssetPreview/ImagePreview/index.d.ts +0 -1
  227. package/build/components/Result/AssetPreview/OtherPreview/OtherPreview.d.ts +0 -9
  228. package/build/components/Result/AssetPreview/OtherPreview/OtherPreview.styled.d.ts +0 -1
  229. package/build/components/Result/AssetPreview/OtherPreview/index.d.ts +0 -1
  230. package/build/components/Result/AssetPreview/VideoPreview/VideoPreview.d.ts +0 -11
  231. package/build/components/Result/AssetPreview/VideoPreview/index.d.ts +0 -1
  232. package/build/components/Result/AssetPreview/index.d.ts +0 -1
  233. package/build/consts/asset.d.ts +0 -14
  234. package/build/consts/auth.d.ts +0 -4
  235. package/build/consts/data.d.ts +0 -21
  236. package/build/index.d.ts +0 -225
  237. package/build/index.html +0 -1
  238. package/build/page/Authenticate/Authenticate.d.ts +0 -2
  239. package/build/page/Authenticate/ConnectingBackground.d.ts +0 -8
  240. package/build/page/Authenticate/index.d.ts +0 -2
  241. package/build/page/Home/Home.d.ts +0 -6
  242. package/build/page/Home/Home.styled.d.ts +0 -2
  243. package/build/setupTests.d.ts +0 -1
  244. package/build/store/assets/assets.api.d.ts +0 -66
  245. package/build/store/assets/assets.service.d.ts +0 -23
  246. package/build/store/assets/assets.slice.d.ts +0 -65
  247. package/build/store/auth/auth.service.d.ts +0 -10
  248. package/build/store/auth/auth.slice.d.ts +0 -76
  249. package/build/store/index.d.ts +0 -368
  250. package/build/store/search/search.api.d.ts +0 -39
  251. package/build/store/search/search.slice.d.ts +0 -12
  252. package/build/store/user/user.api.d.ts +0 -5
  253. package/build/types/assets.d.ts +0 -68
  254. package/build/types/auth.d.ts +0 -35
  255. package/build/types/common.d.ts +0 -11
  256. package/build/types/download.d.ts +0 -8
  257. package/build/types/navigation.d.ts +0 -3
  258. package/build/types/search.d.ts +0 -148
  259. package/build/types/user.d.ts +0 -7
  260. package/build/utils/api.d.ts +0 -27
  261. package/build/utils/array.d.ts +0 -13
  262. package/build/utils/constants.d.ts +0 -11
  263. package/build/utils/function.d.ts +0 -1
  264. package/build/utils/getRequestUrl.d.ts +0 -1
  265. package/build/utils/hooks.d.ts +0 -1
  266. package/build/utils/icon.d.ts +0 -3
  267. package/build/utils/image.d.ts +0 -24
  268. package/build/utils/number.d.ts +0 -4
  269. package/build/utils/rotate.d.ts +0 -4
  270. package/build/utils/storage.d.ts +0 -23
  271. package/build/utils/string.d.ts +0 -12
  272. package/build/view/AssetsPicker.d.ts +0 -6
  273. /package/{build → public}/favicon.ico +0 -0
  274. /package/{build → public}/logo192.png +0 -0
  275. /package/{build → public}/logo512.png +0 -0
  276. /package/{build → public}/manifest.json +0 -0
  277. /package/{build → public}/robots.txt +0 -0
  278. /package/{build/components/Browser/index.d.ts → src/components/Browser/index.ts} +0 -0
  279. /package/{build/components/ControlBar/index.d.ts → src/components/ControlBar/index.ts} +0 -0
  280. /package/{build/components/Header/index.d.ts → src/components/Header/index.ts} +0 -0
  281. /package/{build/page/Home/index.d.ts → src/page/Home/index.ts} +0 -0
@@ -0,0 +1,249 @@
1
+ import _debounce from 'lodash-es/debounce';
2
+ import { FC, FormEvent, useEffect, useMemo, useRef, useState } from 'react';
3
+
4
+ import { Unit } from '@/types/assets';
5
+ import { calculateAspectRatioFit } from '@/utils/image';
6
+ import { CxChangeEvent, CxInput, CxSelect } from '@/web-component';
7
+
8
+ import { cropModes, INPUT_DEBOUNCE_DELAY } from '../CustomRendition.constants';
9
+ type Props = {
10
+ open: boolean;
11
+ width: number;
12
+ height: number;
13
+ disabledCropApply: boolean;
14
+ lastAppliedSetting: Record<Unit, {
15
+ width: number;
16
+ height: number;
17
+ percentageWidth: number;
18
+ percentageHeight: number;
19
+ x: number;
20
+ y: number;
21
+ unit: Unit;
22
+ }>;
23
+ maxWidth: number;
24
+ maxHeight: number;
25
+ percentageWidth: number;
26
+ percentageHeight: number;
27
+ unit: Unit;
28
+ onChange: (
29
+ width: number,
30
+ height: number,
31
+ unit: Unit,
32
+ ) => void;
33
+ onApply: () => void;
34
+ };
35
+
36
+ const Crop: FC<Props> = ({
37
+ open,
38
+ width,
39
+ height,
40
+ disabledCropApply,
41
+ maxWidth,
42
+ maxHeight,
43
+ percentageHeight,
44
+ percentageWidth,
45
+ unit,
46
+ lastAppliedSetting,
47
+ onChange,
48
+ onApply,
49
+ }) => {
50
+ const [isDefined, setIsDefined] = useState(false);
51
+ const [mode, setMode] = useState<string>('free');
52
+ const [keepAspectRatio, setKeepAspectRatio] = useState(true);
53
+ const [invalidHeight, setInvalidHeight] = useState(false);
54
+ const [invalidWidth, setInvalidWidth] = useState(false);
55
+
56
+ const unitSelectRef = useRef<CxSelect>(null);
57
+ const formatSelectRef = useRef<CxSelect>(null);
58
+ const heightInputRef = useRef<CxInput>(null);
59
+ const widthInputRef = useRef<CxInput>(null);
60
+
61
+ useEffect(() => {
62
+ setMode('free');
63
+ }, [open]);
64
+
65
+ useEffect(() => {
66
+ if (!open) {
67
+ if (heightInputRef.current) {
68
+ heightInputRef.current.value = height.toString();
69
+ }
70
+ if (widthInputRef.current) {
71
+ widthInputRef.current.value = width.toString();
72
+ }
73
+ }
74
+ }, [height, open, width]);
75
+
76
+ useEffect(() => {
77
+ Promise.all([
78
+ customElements.whenDefined('cx-input'),
79
+ customElements.whenDefined('cx-select'),
80
+ ]).then(() => {
81
+ setIsDefined(true);
82
+ });
83
+ }, []);
84
+
85
+ useEffect(() => {
86
+ const unitSelect = unitSelectRef.current;
87
+ if (!unitSelect || !isDefined) {
88
+ return;
89
+ }
90
+ const onUnitChange = (e: CxChangeEvent) => {
91
+ if ((e.target as HTMLOptionElement).value === Unit.AspectRatio) {
92
+ onChange(lastAppliedSetting[Unit.AspectRatio].width, lastAppliedSetting[Unit.AspectRatio].height, Unit.AspectRatio);
93
+ } else {
94
+ onChange(lastAppliedSetting[Unit.Pixel].width, lastAppliedSetting[Unit.Pixel].height, Unit.Pixel);
95
+ }
96
+ setMode('free');
97
+ };
98
+ unitSelect.addEventListener('cx-change', onUnitChange);
99
+
100
+ return () => {
101
+ unitSelect.removeEventListener('cx-change', onUnitChange);
102
+ };
103
+ }, [isDefined, width, height, onChange, maxWidth, maxHeight, percentageWidth, percentageHeight, lastAppliedSetting]);
104
+
105
+ useEffect(() => {
106
+ const formatSelect = formatSelectRef.current;
107
+ if (!formatSelect || !isDefined) {
108
+ return;
109
+ }
110
+ const onModeChange = (e: CxChangeEvent) => {
111
+ const value = (e.target as HTMLOptionElement).value;
112
+ if (value === 'free') {
113
+ setKeepAspectRatio(false);
114
+ } else {
115
+ setKeepAspectRatio(true);
116
+ const [widthRatio, heightRatio] = value.split(':').map(Number);
117
+ if (unit === Unit.Pixel) {
118
+ // If image size is 1024x1024 and user selects 16:9, the new size should be 1024x576
119
+ const { width: newWidth, height: newHeight } = calculateAspectRatioFit(maxWidth, maxHeight, widthRatio, heightRatio);
120
+ onChange(newWidth, newHeight, unit);
121
+ } else {
122
+ onChange(widthRatio, heightRatio, unit);
123
+ }
124
+ }
125
+ setMode((e.target as HTMLOptionElement).value);
126
+ };
127
+ formatSelect.addEventListener('cx-change', onModeChange);
128
+
129
+ return () => {
130
+ formatSelect.removeEventListener('cx-change', onModeChange);
131
+ };
132
+ }, [isDefined, maxWidth, maxHeight, unit, onChange]);
133
+
134
+ const aspectRatio = useMemo(() => {
135
+ return maxWidth / maxHeight;
136
+ }, [maxWidth, maxHeight]);
137
+
138
+
139
+ const handleWidthChange = _debounce((e: FormEvent<CxInput>) => {
140
+ if (!(e.target as HTMLInputElement).value) {
141
+ setInvalidWidth(true);
142
+ return;
143
+ }
144
+ setInvalidWidth(false);
145
+ const newWidth = Math.max(Math.min(Number((e.target as HTMLInputElement).value), maxWidth), 1);
146
+ (e.target as HTMLInputElement).value = newWidth.toString();
147
+ let newHeight = height;
148
+ if (keepAspectRatio) {
149
+ newHeight = Math.min(Math.round(newWidth / aspectRatio), maxHeight);
150
+ setInvalidHeight(false);
151
+ }
152
+ onChange(newWidth, newHeight, unit);
153
+ }, INPUT_DEBOUNCE_DELAY);
154
+
155
+ const handleHeightChange = _debounce((e: FormEvent<CxInput>) => {
156
+ if (!(e.target as HTMLInputElement).value) {
157
+ setInvalidHeight(true);
158
+ return;
159
+ }
160
+ setInvalidHeight(false);
161
+ const newHeight = Math.max(Math.min(Number((e.target as HTMLInputElement).value), maxHeight), 1);
162
+ (e.target as HTMLInputElement).value = newHeight.toString();
163
+ let newWidth = width;
164
+ if (keepAspectRatio) {
165
+ newWidth = Math.min(Math.round(newHeight * aspectRatio), maxWidth);
166
+ setInvalidWidth(false);
167
+ }
168
+ onChange(newWidth, newHeight, unit);
169
+ }, INPUT_DEBOUNCE_DELAY);
170
+
171
+ return (
172
+ <cx-details open={open} data-value="crop">
173
+ <cx-space slot="summary" align-items='center'>
174
+ <div className="details__summary__icon">
175
+ <cx-icon name="crop"></cx-icon>
176
+ </div>
177
+ <cx-typography variant="body2">Crop</cx-typography>
178
+ </cx-space>
179
+ <cx-space direction="vertical" spacing="small">
180
+ <cx-select
181
+ ref={formatSelectRef}
182
+ value={isDefined ? mode : ''}
183
+ hoist
184
+ style={{
185
+ width: '100%',
186
+ }}
187
+ >
188
+ {cropModes.map(({ value, label }) => (
189
+ <cx-option key={value} value={value}>{label}</cx-option>
190
+ ))}
191
+ </cx-select>
192
+ <cx-space spacing="small">
193
+ <div className="resize__input-group">
194
+ <cx-input
195
+ ref={widthInputRef}
196
+ placeholder="Width"
197
+ type="number"
198
+ step="1"
199
+ value={isDefined ? width.toString() : ''}
200
+ onInput={handleWidthChange}
201
+ required
202
+ >
203
+ <cx-typography slot="prefix" variant="body3" className="details__summary__input-label">W</cx-typography>
204
+ </cx-input>
205
+ <cx-icon-button
206
+ name={keepAspectRatio ? 'insert_link' : 'link_off'}
207
+ onClick={() => {
208
+ if (keepAspectRatio) {
209
+ setMode('free');
210
+ }
211
+ setKeepAspectRatio(!keepAspectRatio);
212
+ }}
213
+ style={{
214
+ color: keepAspectRatio ? 'var(--cx-color-primary)' : undefined,
215
+ }}
216
+ ></cx-icon-button>
217
+ <cx-input
218
+ ref={heightInputRef}
219
+ placeholder="Height"
220
+ type="number"
221
+ step="1"
222
+ value={isDefined ? height.toString() : ''}
223
+ onInput={handleHeightChange}
224
+ required
225
+ >
226
+ <cx-typography slot="prefix" variant="body3" className="details__summary__input-label">H</cx-typography>
227
+ </cx-input>
228
+ </div>
229
+ <cx-select value={isDefined ? unit : ''} ref={unitSelectRef} hoist className="resize__unit-select">
230
+ <cx-option value="pixels">Pixels</cx-option>
231
+ <cx-option value="aspect-ratio">Aspect ratio</cx-option>
232
+ </cx-select>
233
+ </cx-space>
234
+ <cx-button
235
+ variant="primary"
236
+ disabled={disabledCropApply || invalidHeight || invalidWidth}
237
+ style={{
238
+ marginLeft: 'auto',
239
+ }}
240
+ onClick={onApply}
241
+ >
242
+ Apply
243
+ </cx-button>
244
+ </cx-space>
245
+ </cx-details>
246
+ );
247
+ };
248
+
249
+ export default Crop;
@@ -0,0 +1,54 @@
1
+ import { CxSelect, CxChangeEvent } from '@/web-component';
2
+ import { useState, useRef, useEffect, FC } from 'react';
3
+
4
+ type Props = {
5
+ extension: string,
6
+ extensions: { displayName: string; value: string }[],
7
+ onChange: (extension: string) => void;
8
+ };
9
+
10
+ const Extension: FC<Props> = ({
11
+ extension,
12
+ extensions,
13
+ onChange,
14
+ }) => {
15
+ const [isDefined, setIsDefined] = useState(false);
16
+ const extensionSelectRef = useRef<CxSelect>(null);
17
+
18
+ useEffect(() => {
19
+ Promise.all([
20
+ customElements.whenDefined('cx-select'),
21
+ ]).then(() => {
22
+ setIsDefined(true);
23
+ });
24
+ }, []);
25
+
26
+ useEffect(() => {
27
+ const extensionSelect = extensionSelectRef.current;
28
+ if (!extensionSelect || !isDefined) {
29
+ return;
30
+ }
31
+ const onExtensionChange = (e: CxChangeEvent) => {
32
+ const newExtension = (e.target as HTMLOptionElement).value;
33
+ onChange(newExtension);
34
+ };
35
+
36
+ extensionSelect.addEventListener('cx-change', onExtensionChange);
37
+ return () => {
38
+ extensionSelect.removeEventListener('cx-change', onExtensionChange);
39
+ };
40
+ }, [isDefined, onChange]);
41
+
42
+ return (
43
+ <cx-space direction="vertical" spacing="small" className="extension">
44
+ <cx-typography variant="body2">Extension</cx-typography>
45
+ <cx-select value={isDefined ? extension : ''} ref={extensionSelectRef} hoist>
46
+ {extensions.map((item) => (
47
+ <cx-option key={item.value} value={item.value}>{item.displayName}</cx-option>
48
+ ))}
49
+ </cx-select>
50
+ </cx-space>
51
+ );
52
+ };
53
+
54
+ export default Extension;
@@ -0,0 +1,86 @@
1
+ import { CxSelect, CxChangeEvent } from '@/web-component';
2
+ import { useState, useRef, useEffect, FC } from 'react';
3
+ import { Proxy } from '@/types/search';
4
+
5
+ type Props = {
6
+ format: string;
7
+ formats: Proxy[];
8
+ open: boolean;
9
+ onApply: (format: Proxy) => void;
10
+ };
11
+
12
+ const Extension: FC<Props> = ({ format, formats, open, onApply }) => {
13
+ const [value, setValue] = useState(format);
14
+ const [isDefined, setIsDefined] = useState(false);
15
+ const extensionSelectRef = useRef<CxSelect>(null);
16
+
17
+ useEffect(() => {
18
+ Promise.all([customElements.whenDefined('cx-select')]).then(() => {
19
+ setIsDefined(true);
20
+ });
21
+ }, []);
22
+
23
+ useEffect(() => {
24
+ const extensionSelect = extensionSelectRef.current;
25
+ if (!extensionSelect || !isDefined) {
26
+ return;
27
+ }
28
+ const onExtensionChange = (e: CxChangeEvent) => {
29
+ const newFormatId = (e.target as HTMLOptionElement).value;
30
+ setValue(newFormatId);
31
+ };
32
+
33
+ extensionSelect.addEventListener('cx-change', onExtensionChange);
34
+ return () => {
35
+ extensionSelect.removeEventListener('cx-change', onExtensionChange);
36
+ };
37
+ }, [formats, isDefined]);
38
+
39
+ useEffect(( ) => {
40
+ if (open) {
41
+ setValue(format);
42
+ }
43
+ }, [format, open]);
44
+
45
+ return (
46
+ <cx-details open={open} data-value="format" className="format">
47
+ <cx-space slot="summary" align-items="center">
48
+ <div className="details__summary__icon">
49
+ <cx-icon name="aspect_ratio"></cx-icon>
50
+ </div>
51
+ <cx-typography variant="body2">Format</cx-typography>
52
+ </cx-space>
53
+ <cx-space direction="vertical" spacing="small" className="format">
54
+ <cx-typography variant="body2">Format</cx-typography>
55
+ <cx-select
56
+ value={isDefined ? value : ''}
57
+ ref={extensionSelectRef}
58
+ hoist
59
+ >
60
+ {formats.map((item) => (
61
+ <cx-option key={item.id} value={item.id}>
62
+ {item.proxyLabel}
63
+ </cx-option>
64
+ ))}
65
+ </cx-select>
66
+ <cx-button
67
+ variant="primary"
68
+ style={{
69
+ marginLeft: 'auto',
70
+ }}
71
+ onClick={() => {
72
+ const selectedProxy = formats.find((item) => item.id === value);
73
+ if (selectedProxy) {
74
+ onApply(selectedProxy);
75
+ }
76
+ }}
77
+ disabled={value === format}
78
+ >
79
+ Apply
80
+ </cx-button>
81
+ </cx-space>
82
+ </cx-details>
83
+ );
84
+ };
85
+
86
+ export default Extension;
@@ -0,0 +1,176 @@
1
+ import _debounce from 'lodash-es/debounce';
2
+ import { FC, FormEvent, useEffect, useMemo, useRef, useState } from 'react';
3
+
4
+ import { Unit } from '@/types/assets';
5
+ import { CxChangeEvent, CxInput, CxSelect } from '@/web-component';
6
+ import { INPUT_DEBOUNCE_DELAY } from '../CustomRendition.constants';
7
+
8
+ type Props = {
9
+ open: boolean;
10
+ width: number;
11
+ height: number;
12
+ lastAppliedSetting: Record<Unit, {
13
+ width: number;
14
+ height: number;
15
+ }>;
16
+ maxWidth: number;
17
+ maxHeight: number;
18
+ unit: Unit;
19
+ onChange: (
20
+ width: number,
21
+ height: number,
22
+ unit: Unit
23
+ ) => void;
24
+ onApply: () => void;
25
+ };
26
+
27
+ const Resize: FC<Props> = ({ open, width, height, lastAppliedSetting, maxWidth, maxHeight, unit, onChange, onApply }) => {
28
+ const [isDefined, setIsDefined] = useState(false);
29
+ const [invalidHeight, setInvalidHeight] = useState(false);
30
+ const [invalidWidth, setInvalidWidth] = useState(false);
31
+ const [keepAspectRatio, setKeepAspectRatio] = useState(true);
32
+ const unitSelectRef = useRef<CxSelect>(null);
33
+ const heightInputRef = useRef<CxInput>(null);
34
+ const widthInputRef = useRef<CxInput>(null);
35
+
36
+ useEffect(() => {
37
+ if (!open) {
38
+ if (heightInputRef.current) {
39
+ heightInputRef.current.value = height.toString();
40
+ }
41
+ if (widthInputRef.current) {
42
+ widthInputRef.current.value = width.toString();
43
+ }
44
+ }
45
+ }, [height, open, width]);
46
+
47
+ useEffect(() => {
48
+ Promise.all([
49
+ customElements.whenDefined('cx-input'),
50
+ customElements.whenDefined('cx-select'),
51
+ ]).then(() => {
52
+ setIsDefined(true);
53
+ });
54
+ }, []);
55
+
56
+ useEffect(() => {
57
+ const unitSelect = unitSelectRef.current;
58
+ if (!unitSelect || !isDefined) {
59
+ return;
60
+ }
61
+ const onUnitChange = (e: CxChangeEvent) => {
62
+ if ((e.target as HTMLOptionElement).value === Unit.AspectRatio) {
63
+ onChange(lastAppliedSetting[Unit.AspectRatio].width, lastAppliedSetting[Unit.AspectRatio].height, Unit.AspectRatio);
64
+ } else {
65
+ onChange(lastAppliedSetting[Unit.Pixel].width, lastAppliedSetting[Unit.Pixel].height, Unit.Pixel);
66
+ }
67
+ };
68
+ unitSelect.addEventListener('cx-change', onUnitChange);
69
+
70
+ return () => {
71
+ unitSelect.removeEventListener('cx-change', onUnitChange);
72
+ };
73
+ }, [isDefined, width, height, onChange, lastAppliedSetting, unit]);
74
+
75
+ const aspectRatio = useMemo(() => {
76
+ return maxWidth / maxHeight;
77
+ }, [maxWidth, maxHeight]);
78
+
79
+ const disabledApplyButton = useMemo(() => {
80
+ return (lastAppliedSetting[unit].width === width && lastAppliedSetting[unit].height === height);
81
+ }, [lastAppliedSetting, unit, width, height]);
82
+
83
+ const handleWidthChange = _debounce((e: FormEvent<CxInput>) => {
84
+ if (!(e.target as HTMLInputElement).value) {
85
+ setInvalidWidth(true);
86
+ return;
87
+ }
88
+ setInvalidWidth(false);
89
+ const newWidth = Math.max(Number((e.target as HTMLInputElement).value), 1);
90
+ (e.target as HTMLInputElement).value = newWidth.toString();
91
+ let newHeight = height;
92
+ if (keepAspectRatio) {
93
+ newHeight = Math.round(newWidth / aspectRatio);
94
+ setInvalidHeight(false);
95
+ }
96
+ onChange(newWidth, newHeight, unit);
97
+ }, INPUT_DEBOUNCE_DELAY);
98
+
99
+ const handleHeightChange = _debounce((e: FormEvent<CxInput>) => {
100
+ if (!(e.target as HTMLInputElement).value) {
101
+ setInvalidHeight(true);
102
+ return;
103
+ }
104
+ setInvalidHeight(false);
105
+ const newHeight = Math.max(Number((e.target as HTMLInputElement).value), 1);
106
+ (e.target as HTMLInputElement).value = newHeight.toString();
107
+ let newWidth = width;
108
+ if (keepAspectRatio) {
109
+ newWidth = Math.round(newHeight * aspectRatio);
110
+ setInvalidWidth(false);
111
+ }
112
+ onChange(newWidth, newHeight, unit);
113
+ }, INPUT_DEBOUNCE_DELAY);
114
+
115
+ return (
116
+ <cx-details open={open} data-value="resize" className="resize">
117
+ <cx-space slot="summary" align-items='center'>
118
+ <div className="details__summary__icon">
119
+ <cx-icon name="aspect_ratio"></cx-icon>
120
+ </div>
121
+ <cx-typography variant="body2">Resize</cx-typography>
122
+ </cx-space>
123
+ <cx-space direction="vertical" spacing="small">
124
+ <cx-space spacing="small">
125
+ <div className="resize__input-group">
126
+ <cx-input
127
+ ref={widthInputRef}
128
+ placeholder="Width"
129
+ type="number"
130
+ step="1"
131
+ value={isDefined ? width.toString() : ''}
132
+ onInput={handleWidthChange}
133
+ required
134
+ >
135
+ <cx-typography slot="prefix" variant="body3" className="details__summary__input-label">W</cx-typography>
136
+ </cx-input>
137
+ <cx-icon-button
138
+ name={keepAspectRatio ? 'insert_link' : 'link_off'}
139
+ onClick={() => setKeepAspectRatio(prevState => !prevState)}
140
+ style={{
141
+ color: keepAspectRatio ? 'var(--cx-color-primary)' : undefined,
142
+ }}
143
+ ></cx-icon-button>
144
+ <cx-input
145
+ ref={heightInputRef}
146
+ placeholder="Height"
147
+ type="number"
148
+ step="1"
149
+ value={isDefined ? height.toString() : ''}
150
+ onInput={handleHeightChange}
151
+ required
152
+ >
153
+ <cx-typography slot="prefix" variant="body3" className="details__summary__input-label">H</cx-typography>
154
+ </cx-input>
155
+ </div>
156
+ <cx-select value={isDefined ? unit : ''} ref={unitSelectRef} hoist className="resize__unit-select">
157
+ <cx-option value="pixels">Pixels</cx-option>
158
+ <cx-option value="aspect-ratio">Aspect ratio</cx-option>
159
+ </cx-select>
160
+ </cx-space>
161
+ <cx-button
162
+ variant="primary"
163
+ disabled={disabledApplyButton || invalidHeight || invalidWidth}
164
+ style={{
165
+ marginLeft: 'auto',
166
+ }}
167
+ onClick={onApply}
168
+ >
169
+ Apply
170
+ </cx-button>
171
+ </cx-space>
172
+ </cx-details>
173
+ );
174
+ };
175
+
176
+ export default Resize;
@@ -0,0 +1,101 @@
1
+ import _debounce from 'lodash-es/debounce';
2
+ import { FormEvent, useEffect, useState } from 'react';
3
+
4
+ import { CxInput } from '@/web-component';
5
+ import { INPUT_DEBOUNCE_DELAY } from '../CustomRendition.constants';
6
+
7
+ type Props = {
8
+ open: boolean;
9
+ rotation: number;
10
+ onChange: (rotation: number) => void;
11
+ onApply: () => void;
12
+ };
13
+
14
+ const sanitizeRotation = (rotation: number) => {
15
+ if (rotation > 360) {
16
+ return 360;
17
+ } else if (rotation < 0) {
18
+ return 0;
19
+ }
20
+ return rotation;
21
+ };
22
+
23
+ const Rotate = ({ open, rotation, onChange, onApply }: Props) => {
24
+ const [isDefined, setIsDefined] = useState(false);
25
+ const [invalidRotation, setInvalidRotation] = useState(false);
26
+
27
+ useEffect(() => {
28
+ Promise.all([
29
+ customElements.whenDefined('cx-input'),
30
+ ]).then(() => {
31
+ setIsDefined(true);
32
+ });
33
+ }, []);
34
+
35
+ const handleRotationChange = _debounce((e: FormEvent<CxInput>) => {
36
+ const value = (e.target as HTMLInputElement).value;
37
+ const newRotation = Number(value);
38
+ if (!value) {
39
+ setInvalidRotation(true);
40
+ } else {
41
+ setInvalidRotation(false);
42
+ }
43
+
44
+ // When the user change the value to a number >= 360 for the second time in a row,
45
+ // The input won't update the value back to 359, so we need to do it manually
46
+ const sanitizedRotation = sanitizeRotation(newRotation);
47
+ if (newRotation > 360 || newRotation < 0) {
48
+ (e.target as HTMLInputElement).value = sanitizedRotation.toString();
49
+ }
50
+ onChange(sanitizedRotation);
51
+ }, INPUT_DEBOUNCE_DELAY);
52
+
53
+ return (
54
+ <cx-details open={open} data-value="rotate">
55
+ <cx-space slot="summary" align-items='center'>
56
+ <div className="details__summary__icon">
57
+ <cx-icon name="rotate_90_degrees_cw"></cx-icon>
58
+ </div>
59
+ <cx-typography variant="body2">Rotate</cx-typography>
60
+ </cx-space>
61
+ <cx-space spacing="small">
62
+ <cx-button-group label="History">
63
+ <cx-button
64
+ outline
65
+ onClick={() => onChange(sanitizeRotation(rotation - 90))}
66
+ >
67
+ <cx-icon name="rotate_90_degrees_ccw" label="Undo"></cx-icon>
68
+ </cx-button>
69
+ <cx-button
70
+ outline
71
+ onClick={() => onChange(sanitizeRotation(rotation + 90))}
72
+ >
73
+ <cx-icon name="rotate_90_degrees_cw" label="Redo"></cx-icon>
74
+ </cx-button>
75
+ </cx-button-group>
76
+ <cx-input
77
+ value={isDefined && !invalidRotation ? rotation.toString() : ''}
78
+ placeholder="0"
79
+ type="number"
80
+ min="0"
81
+ max="360"
82
+ style={{
83
+ width: '80px',
84
+ flex: 'none',
85
+ }}
86
+ onInput={handleRotationChange}
87
+ step='1'
88
+ ></cx-input>
89
+ <cx-button
90
+ variant="primary"
91
+ disabled={rotation === 0 || rotation === 360 || invalidRotation}
92
+ onClick={onApply}
93
+ >
94
+ Apply
95
+ </cx-button>
96
+ </cx-space>
97
+ </cx-details>
98
+ );
99
+ };
100
+
101
+ export default Rotate;
@@ -2,6 +2,4 @@ export { default as Crop } from './Crop';
2
2
  export { default as Extension } from './Extension';
3
3
  export { default as Resize } from './Resize';
4
4
  export { default as Rotate } from './Rotate';
5
- export { default as Format } from './Format';
6
- export { default as Quality } from './Quality';
7
- export { default as Metadata } from './Metadata';
5
+ export { default as Format } from './Format';