@squiz/resource-browser 3.1.0-rc.3 → 3.1.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/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # Change Log
2
2
 
3
+ ## 3.1.0
4
+
5
+ ### Patch Changes
6
+
7
+ - a89fb2d: Updated the peer dependencies and dependencies so that we use the deps published by Matrix'
8
+ - a89fb2d: Updated title for modal to be sentence case when displayed
9
+ - a89fb2d: Changed background colour of hovered source on source selector
10
+ - a89fb2d: Updated modal to use sds button, removed scroll bar from search panel
11
+ - 6503eba: clean selected mode on modal close
12
+ - a89fb2d: Version control via changesets added
13
+ - Updated dependencies [70ed1a8]
14
+ - Updated dependencies [9bcc4d2]
15
+ - Updated dependencies [a89fb2d]
16
+ - Updated dependencies [a065ca7]
17
+ - Updated dependencies [7a6a6fc]
18
+ - Updated dependencies [a89fb2d]
19
+ - @squiz/resource-browser-ui-lib@1.0.0
20
+
21
+ ## 3.1.0-rc.4
22
+
23
+ ### Patch Changes
24
+
25
+ - 6503eba: clean selected mode on modal close
26
+
3
27
  ## 3.1.0-rc.3
4
28
 
5
29
  ### Patch Changes
@@ -13,7 +13,7 @@ const SelectedState = ({ resource, showThumbnail, icon, label, description, isDi
13
13
  isOpen: isModalOpen,
14
14
  onOpenChange: onModalStateChange,
15
15
  };
16
- const replaceAsset = (react_1.default.createElement(resource_browser_ui_lib_1.ModalTrigger, { overlayTriggerState: isModalOpen && onModalStateChange ? modalController : undefined, showLabel: false, label: "Replace selection", containerClasses: "text-gray-500 hover:text-gray-800 focus:text-gray-800 disabled:text-gray-500 disabled:cursor-not-allowed", icon: react_1.default.createElement(CircledLoopIcon_1.CircledLoopIcon, { "aria-hidden": true, className: "m-1" }), isDisabled: isDisabled, scope: "squiz-rb-scope" }, resourcePickerContainer));
16
+ const replaceAsset = (react_1.default.createElement(resource_browser_ui_lib_1.ModalTrigger, { overlayTriggerState: modalController, showLabel: false, label: "Replace selection", containerClasses: "text-gray-500 hover:text-gray-800 focus:text-gray-800 disabled:text-gray-500 disabled:cursor-not-allowed", icon: react_1.default.createElement(CircledLoopIcon_1.CircledLoopIcon, { "aria-hidden": true, className: "m-1" }), isDisabled: isDisabled, scope: "squiz-rb-scope" }, resourcePickerContainer));
17
17
  return (react_1.default.createElement(react_1.default.Fragment, null,
18
18
  showThumbnail && resource.squizImage ? (react_1.default.createElement("div", { className: "checkered-bg w-[56px] h-[56px] overflow-hidden flex justify-center items-center rounded" },
19
19
  react_1.default.createElement("img", { src: resource.squizImage.imageVariations.original.url || resource.url, className: "w-full h-full object-cover object-center", alt: resource.squizImage.name || resource.name }))) : (react_1.default.createElement("div", { className: "w-4 h-4 mt-1 flex self-start overflow-hidden" }, icon)),
package/lib/index.css CHANGED
@@ -5724,7 +5724,7 @@
5724
5724
  }
5725
5725
  .squiz-rb-scope .selection-list__item:not(.squiz-rb-plugin *) {
5726
5726
  display: flex;
5727
- margin: 0.5rem;
5727
+ margin: 0.25rem 0.5rem;
5728
5728
  border-bottom: 1px solid #e0e0e0;
5729
5729
  }
5730
5730
  .squiz-rb-scope .selection-list__item:last-child:not(.squiz-rb-plugin *) {
@@ -5732,6 +5732,7 @@
5732
5732
  }
5733
5733
  .squiz-rb-scope .selection-list__item-button:not(.squiz-rb-plugin *) {
5734
5734
  width: 100%;
5735
+ margin-bottom: 0.25rem;
5735
5736
  padding: 0.25rem 0.5rem;
5736
5737
  border: none;
5737
5738
  background: none;
@@ -5744,6 +5745,12 @@
5744
5745
  .squiz-rb-scope .selection-list__item-button:focus:not(.squiz-rb-plugin *) {
5745
5746
  background-color: #f5f5f5;
5746
5747
  }
5748
+ .squiz-rb-scope .selection-list__item--selected path:not(.squiz-rb-plugin *) {
5749
+ fill: #044985 !important;
5750
+ }
5751
+ .squiz-rb-scope .selection-list__item--selected .sds-text:not(.squiz-rb-plugin *) {
5752
+ color: #044985 !important;
5753
+ }
5747
5754
  .squiz-rb-scope .selection-list__item--selected .selection-list__item-button:not(.squiz-rb-plugin *) {
5748
5755
  background-color: #e6f1fa;
5749
5756
  }
@@ -5963,7 +5970,10 @@
5963
5970
  fill: #4f4f4f;
5964
5971
  }
5965
5972
  .squiz-rb-scope .searchListing:not(.squiz-rb-plugin *) {
5966
- padding: 1.25rem 1rem;
5973
+ padding: 1.25rem 0 1.25rem 1rem;
5974
+ }
5975
+ .squiz-rb-scope .searchListing__header:not(.squiz-rb-plugin *) {
5976
+ padding-right: 16px;
5967
5977
  }
5968
5978
  .squiz-rb-scope .searchListing__title-group:not(.squiz-rb-plugin *) {
5969
5979
  padding-bottom: 1rem;
@@ -6106,6 +6116,143 @@
6106
6116
  justify-content: center;
6107
6117
  align-items: center;
6108
6118
  }
6119
+ .squiz-rb-scope .image-info:not(.squiz-rb-plugin *) {
6120
+ align-items: center;
6121
+ border-top: 1px solid #e0e0e0;
6122
+ color: #707070;
6123
+ display: flex;
6124
+ flex-direction: column;
6125
+ height: calc(50vh - 60px);
6126
+ overflow-y: auto;
6127
+ }
6128
+ .squiz-rb-scope .image-info__image-container:not(.squiz-rb-plugin *) {
6129
+ position: relative;
6130
+ width: 250px;
6131
+ height: 150px;
6132
+ margin: 1.25rem;
6133
+ background-color: #ededed;
6134
+ }
6135
+ .squiz-rb-scope .checkered-bg:not(.squiz-rb-plugin *) {
6136
+ --tw-bg-opacity: 1;
6137
+ background-color: rgb(255 255 255 / var(--tw-bg-opacity));
6138
+ background-size: 24px 24px;
6139
+ background-position: 0 0, 12px 12px;
6140
+ background-image:
6141
+ linear-gradient(
6142
+ 45deg,
6143
+ #e0e0e0 25%,
6144
+ transparent 25%,
6145
+ transparent 75%,
6146
+ #e0e0e0 75%,
6147
+ #e0e0e0),
6148
+ linear-gradient(
6149
+ 45deg,
6150
+ #e0e0e0 25%,
6151
+ transparent 25%,
6152
+ transparent 75%,
6153
+ #e0e0e0 75%,
6154
+ #e0e0e0);
6155
+ }
6156
+ .squiz-rb-scope .image-info__image-container img:not(.squiz-rb-plugin *) {
6157
+ position: absolute;
6158
+ top: 0;
6159
+ right: 0;
6160
+ bottom: 0;
6161
+ left: 0;
6162
+ max-width: 100%;
6163
+ max-height: 100%;
6164
+ margin: auto;
6165
+ }
6166
+ .squiz-rb-scope .image-info__title:not(.squiz-rb-plugin *) {
6167
+ margin: 1rem 0;
6168
+ color: #3d3d3d;
6169
+ }
6170
+ .squiz-rb-scope .image-info__details:not(.squiz-rb-plugin *) {
6171
+ margin: 1rem 0;
6172
+ color: #707070;
6173
+ }
6174
+ .squiz-rb-scope .image-info__details-list:not(.squiz-rb-plugin *) {
6175
+ display: flex;
6176
+ flex-direction: column;
6177
+ margin: 1rem 0;
6178
+ }
6179
+ .squiz-rb-scope .image-info__details-item:not(.squiz-rb-plugin *) {
6180
+ display: flex;
6181
+ margin-bottom: 0.5rem;
6182
+ }
6183
+ .squiz-rb-scope .image-info__details-label:not(.squiz-rb-plugin *) {
6184
+ color: #707070;
6185
+ width: 60px;
6186
+ display: flex;
6187
+ }
6188
+ .squiz-rb-scope .image-info__details-value:not(.squiz-rb-plugin *) {
6189
+ color: #3d3d3d;
6190
+ }
6191
+ .squiz-rb-scope .image-variant__list:not(.squiz-rb-plugin *) {
6192
+ width: 250px;
6193
+ margin-bottom: 1rem;
6194
+ }
6195
+ .squiz-rb-scope .image-variant__item:not(.squiz-rb-plugin *) {
6196
+ display: flex;
6197
+ flex-direction: row;
6198
+ align-items: center;
6199
+ width: 100%;
6200
+ justify-content: space-between;
6201
+ }
6202
+ .squiz-rb-scope .selection-list__item--selected .image-variant__checkmark:not(.squiz-rb-plugin *) {
6203
+ visibility: visible;
6204
+ }
6205
+ .squiz-rb-scope .image-variant__checkmark:not(.squiz-rb-plugin *) {
6206
+ visibility: hidden;
6207
+ margin-left: 0.5rem;
6208
+ }
6209
+ .squiz-rb-scope .image-variant__checkmark path:not(.squiz-rb-plugin *) {
6210
+ fill: #044985;
6211
+ }
6212
+ .squiz-rb-scope .image-variant__info:not(.squiz-rb-plugin *) {
6213
+ display: flex;
6214
+ align-items: center;
6215
+ color: #3d3d3d;
6216
+ }
6217
+ .squiz-rb-scope .image-info__footer:not(.squiz-rb-plugin *) {
6218
+ margin-top: auto;
6219
+ align-self: stretch;
6220
+ display: flex;
6221
+ flex-direction: column;
6222
+ align-items: flex-end;
6223
+ }
6224
+ .squiz-rb-scope .image-info__select-button:not(.squiz-rb-plugin *) {
6225
+ margin: 1.25rem;
6226
+ }
6227
+ .squiz-rb-scope .image-info__select:not(.squiz-rb-plugin *) {
6228
+ padding-top: 1.5rem;
6229
+ padding-bottom: 1rem;
6230
+ }
6231
+ .squiz-rb-scope .image-info__select svg:not(.squiz-rb-plugin *) {
6232
+ height: 72px;
6233
+ width: 72px;
6234
+ }
6235
+ .squiz-rb-scope .image-info__select svg path:not(.squiz-rb-plugin *) {
6236
+ fill: #bababa;
6237
+ }
6238
+ .squiz-rb-scope .image-info__empty-text:not(.squiz-rb-plugin *) {
6239
+ padding-left: 1.25rem;
6240
+ padding-right: 1.25rem;
6241
+ }
6242
+ .squiz-rb-scope .image-info__loading:not(.squiz-rb-plugin *) {
6243
+ margin-top: 80px;
6244
+ }
6245
+ @media (min-width: 768px) {
6246
+ .squiz-rb-scope .image-info:not(.squiz-rb-plugin *) {
6247
+ height: calc(100vh - 60px);
6248
+ }
6249
+ }
6250
+ @media (min-width: 1024px) {
6251
+ .squiz-rb-scope .image-info:not(.squiz-rb-plugin *) {
6252
+ height: calc(100vh - 14rem);
6253
+ overflow-y: auto;
6254
+ }
6255
+ }
6109
6256
  .squiz-rb-scope .resource-picker:not(.squiz-rb-plugin *) {
6110
6257
  display: grid;
6111
6258
  grid-template-columns: 24px 1fr;
package/lib/index.js CHANGED
@@ -102,6 +102,9 @@ const ResourceBrowser = (props) => {
102
102
  setSource(null);
103
103
  setMode(null);
104
104
  }
105
+ else if (!isModalOpen) {
106
+ setMode(null);
107
+ }
105
108
  }, [sources, isModalOpen]);
106
109
  // Reset function to allow user manual reload if sources fail in inline usage
107
110
  const handleReset = (0, react_1.useCallback)(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squiz/resource-browser",
3
- "version": "3.1.0-rc.3",
3
+ "version": "3.1.0",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "private": false,
@@ -28,7 +28,7 @@
28
28
  "@react-types/shared": "^3.23.1",
29
29
  "@squiz/dx-json-schema-lib": "^1.67.0",
30
30
  "@squiz/generic-browser-lib": "1.67.2",
31
- "@squiz/resource-browser-ui-lib": "^1.0.0-rc.8",
31
+ "@squiz/resource-browser-ui-lib": "^1.0.0",
32
32
  "clsx": "^2.1.0",
33
33
  "expiry-map": "^2.0.0",
34
34
  "p-memoize": "^4.0.4",
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
  import { render, act, fireEvent, screen, waitFor } from '@testing-library/react';
3
3
  import { ResourceBrowserInput, ResourceBrowserInputProps } from './ResourceBrowserInput';
4
4
  import { mockSource, mockResource } from '../__mocks__/MockModels';
@@ -18,7 +18,7 @@ describe('Resource browser input', () => {
18
18
  const mockSetSource = jest.fn();
19
19
  const mockOnModalStateChange = jest.fn();
20
20
  const renderComponent = (props: Partial<ResourceBrowserInputProps> = {}) => {
21
- render(
21
+ return render(
22
22
  <ResourceBrowserInput
23
23
  modalTitle="Asset picker"
24
24
  value={null}
@@ -158,11 +158,16 @@ describe('Resource browser input', () => {
158
158
  },
159
159
  };
160
160
 
161
- renderComponent({ value: { sourceId: source.id, resourceId: '100' }, plugin: plugin as ResourceBrowserPlugin });
161
+ renderComponent({
162
+ value: { sourceId: source.id, resourceId: '100' },
163
+ plugin: plugin as ResourceBrowserPlugin,
164
+ });
162
165
 
163
166
  await waitFor(() => expect(screen.queryByLabelText('Loading selection')).not.toBeInTheDocument());
164
167
  await act(() => fireEvent.click(screen.getByRole('button', { name: 'Replace selection' })));
165
- expect(screen.getByRole('button', { name: 'Close Asset picker dialog' })).toBeInTheDocument();
168
+
169
+ // Modal index state change handler was instructed to open
170
+ expect(mockOnModalStateChange).toHaveBeenCalledWith(true);
166
171
  });
167
172
 
168
173
  it.each([
@@ -36,7 +36,7 @@ export const SelectedState = ({
36
36
  };
37
37
  const replaceAsset = (
38
38
  <ModalTrigger
39
- overlayTriggerState={isModalOpen && onModalStateChange ? modalController : undefined}
39
+ overlayTriggerState={modalController}
40
40
  showLabel={false}
41
41
  label="Replace selection"
42
42
  containerClasses="text-gray-500 hover:text-gray-800 focus:text-gray-800 disabled:text-gray-500 disabled:cursor-not-allowed"
@@ -8,6 +8,20 @@ import { ResourceBrowserPlugin, ResourceBrowserSource, ResourceBrowserSourceWith
8
8
  import * as RBI from './ResourceBrowserInput/ResourceBrowserInput';
9
9
  jest.spyOn(RBI, 'ResourceBrowserInput');
10
10
 
11
+ var useSourceReloadMock = jest.fn();
12
+ jest.mock('./Hooks/useSources', () => {
13
+ const actual = jest.requireActual('./Hooks/useSources');
14
+ return {
15
+ useSources: jest.fn((...args) => {
16
+ const actualResult = actual.useSources(...args);
17
+ return {
18
+ ...actualResult,
19
+ reload: useSourceReloadMock,
20
+ };
21
+ }),
22
+ };
23
+ });
24
+
11
25
  describe('Resource browser input', () => {
12
26
  const mockChange = jest.fn();
13
27
  const mockOnClear = jest.fn();
@@ -366,7 +380,7 @@ describe('Resource browser input', () => {
366
380
  });
367
381
 
368
382
  await waitFor(() => {
369
- expect(RBI.ResourceBrowserInput).toHaveBeenCalledWith(
383
+ expect(RBI.ResourceBrowserInput).toHaveBeenLastCalledWith(
370
384
  expect.objectContaining({
371
385
  source: calculatedSources[0],
372
386
  plugin: mockDamPlugin,
@@ -375,4 +389,59 @@ describe('Resource browser input', () => {
375
389
  );
376
390
  });
377
391
  });
392
+
393
+ it('onModalStateChange called with false will reset the Mode', async () => {
394
+ const sourcesInput = [mockSource({ type: 'dam' }), mockSource()];
395
+ mockRequestSources.mockResolvedValueOnce(sourcesInput);
396
+
397
+ renderComponent({ value: { sourceId: sourcesInput[0].id, resourceId: '123456' } });
398
+
399
+ // Select a component and plugin mode
400
+ (RBI.ResourceBrowserInput as unknown as jest.SpyInstance).mock.calls[0][0].setSource(sourcesInput[0], { type: 'browse' });
401
+ await waitFor(() => {
402
+ expect(RBI.ResourceBrowserInput).toHaveBeenCalledWith(
403
+ expect.objectContaining({
404
+ pluginMode: {
405
+ type: 'browse',
406
+ },
407
+ }),
408
+ {},
409
+ );
410
+ });
411
+
412
+ // Invoke modal close callback
413
+ const { onModalStateChange } = (RBI.ResourceBrowserInput as unknown as jest.SpyInstance).mock.calls[0][0];
414
+ act(() => {
415
+ onModalStateChange(false);
416
+ });
417
+
418
+ // Expect the mode to be reset
419
+ await waitFor(() => {
420
+ expect(RBI.ResourceBrowserInput).toHaveBeenLastCalledWith(
421
+ expect.objectContaining({
422
+ pluginMode: null,
423
+ }),
424
+ {},
425
+ );
426
+ });
427
+ });
428
+
429
+ it('onRetry reloads sources', async () => {
430
+ const sourcesInput = [mockSource({ type: 'dam' }), mockSource()];
431
+ mockRequestSources.mockResolvedValueOnce(sourcesInput);
432
+
433
+ renderComponent({ value: { sourceId: sourcesInput[0].id, resourceId: '123456' } });
434
+ await waitFor(() => {
435
+ expect(RBI.ResourceBrowserInput).toHaveBeenCalled();
436
+ });
437
+
438
+ const { onRetry } = (RBI.ResourceBrowserInput as unknown as jest.SpyInstance).mock.calls[0][0];
439
+ act(() => {
440
+ onRetry();
441
+ });
442
+
443
+ await waitFor(() => {
444
+ expect(useSourceReloadMock).toHaveBeenCalled();
445
+ });
446
+ });
378
447
  });
package/src/index.tsx CHANGED
@@ -106,6 +106,8 @@ export const ResourceBrowser = (props: ResourceBrowserProps) => {
106
106
  if (!isModalOpen && !value && (sources?.length > 1 || searchEnabled)) {
107
107
  setSource(null);
108
108
  setMode(null);
109
+ } else if (!isModalOpen) {
110
+ setMode(null);
109
111
  }
110
112
  }, [sources, isModalOpen]);
111
113