Skip to content

Commit cc47616

Browse files
authored
fix: improve focus/selected style on library authoring (#1918)
Improves the focus and selected styles from the LibraryPage and UnitPage.
1 parent e8463f7 commit cc47616

8 files changed

Lines changed: 93 additions & 23 deletions

File tree

src/generic/DraggableList/SortableItem.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const SortableItem = ({
1818
isClickable,
1919
onClick,
2020
disabled,
21+
cardClassName = '',
2122
// injected
2223
intl,
2324
}) => {
@@ -52,7 +53,7 @@ const SortableItem = ({
5253
>
5354
<Card
5455
style={style}
55-
className="mx-0"
56+
className={`mx-0 ${cardClassName}`}
5657
isClickable={isClickable}
5758
>
5859
<ActionRow style={actionStyle}>
@@ -94,6 +95,7 @@ SortableItem.propTypes = {
9495
isClickable: PropTypes.bool,
9596
onClick: PropTypes.func,
9697
disabled: PropTypes.bool,
98+
cardClassName: PropTypes.string,
9799
// injected
98100
intl: intlShape.isRequired,
99101
};

src/library-authoring/components/BaseCard.scss

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,56 @@
22
.pgn__card {
33
height: 100%;
44
min-width: 15rem;
5-
}
65

7-
.library-item-header {
8-
border-top-left-radius: .375rem;
9-
border-top-right-radius: .375rem;
10-
padding: 0 .5rem 0 1.25rem;
6+
&::before {
7+
border: none !important; // Remove default focus
8+
}
9+
10+
&.selected:not(:focus) {
11+
border: 2px $gray-700 solid;
12+
13+
.library-item-header {
14+
border-top-left-radius: calc(.375rem - 2px);
15+
border-top-right-radius: calc(.375rem - 2px);
16+
}
17+
}
18+
19+
&.selected:focus {
20+
border: 3px $gray-700 solid;
1121

12-
.library-item-header-icon {
13-
width: 2.3rem;
14-
height: 2.3rem;
22+
.library-item-header {
23+
border-top-left-radius: calc(.375rem - 3px);
24+
border-top-right-radius: calc(.375rem - 3px);
25+
}
1526
}
1627

17-
.pgn__card-header-content {
18-
margin-top: .55rem;
28+
&:not(.selected):focus {
29+
outline: 1px $gray-200 solid;
30+
outline-offset: 2px;
1931
}
2032

21-
.pgn__card-header-actions {
22-
margin: .25rem 0 .25rem 1rem;
33+
&:not(.selected) {
34+
.library-item-header {
35+
border-top-left-radius: .375rem;
36+
border-top-right-radius: .375rem;
37+
}
38+
}
39+
40+
.library-item-header {
41+
padding: 0 .5rem 0 1.25rem;
42+
43+
.library-item-header-icon {
44+
width: 2.3rem;
45+
height: 2.3rem;
46+
}
47+
48+
.pgn__card-header-content {
49+
margin-top: .55rem;
50+
}
51+
52+
.pgn__card-header-actions {
53+
margin: .25rem 0 .25rem 1rem;
54+
}
2355
}
2456
}
2557

src/library-authoring/components/BaseCard.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ type BaseCardProps = {
2222
tags: ContentHitTags;
2323
actions: React.ReactNode;
2424
hasUnpublishedChanges?: boolean;
25-
onSelect: () => void
25+
onSelect: () => void;
26+
selected?: boolean;
2627
};
2728

2829
const BaseCard = ({
@@ -33,6 +34,7 @@ const BaseCard = ({
3334
tags,
3435
actions,
3536
onSelect,
37+
selected = false,
3638
...props
3739
} : BaseCardProps) => {
3840
const tagCount = useMemo(() => {
@@ -47,7 +49,7 @@ const BaseCard = ({
4749
const intl = useIntl();
4850

4951
return (
50-
<Container className="library-item-card">
52+
<Container className="library-item-card selected">
5153
<Card
5254
isClickable
5355
onClick={onSelect}
@@ -56,6 +58,7 @@ const BaseCard = ({
5658
onSelect();
5759
}
5860
}}
61+
className={selected ? 'selected' : undefined}
5962
>
6063
<Card.Header
6164
className={`library-item-header ${getComponentStyleColor(itemType)}`}

src/library-authoring/components/CollectionCard.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { Link } from 'react-router-dom';
1313
import { type CollectionHit } from '../../search-manager';
1414
import { useComponentPickerContext } from '../common/context/ComponentPickerContext';
1515
import { useLibraryContext } from '../common/context/LibraryContext';
16-
import { useSidebarContext } from '../common/context/SidebarContext';
16+
import { SidebarBodyComponentId, useSidebarContext } from '../common/context/SidebarContext';
1717
import { useLibraryRoutes } from '../routes';
1818
import BaseCard from './BaseCard';
1919
import { ToastContext } from '../../generic/toast-context';
@@ -115,7 +115,7 @@ type CollectionCardProps = {
115115
const CollectionCard = ({ hit } : CollectionCardProps) => {
116116
const { componentPickerMode } = useComponentPickerContext();
117117
const { showOnlyPublished } = useLibraryContext();
118-
const { openCollectionInfoSidebar } = useSidebarContext();
118+
const { openCollectionInfoSidebar, sidebarComponentInfo } = useSidebarContext();
119119

120120
const {
121121
type: itemType,
@@ -132,6 +132,9 @@ const CollectionCard = ({ hit } : CollectionCardProps) => {
132132

133133
const { displayName = '', description = '' } = formatted;
134134

135+
const selected = sidebarComponentInfo?.type === SidebarBodyComponentId.CollectionInfo
136+
&& sidebarComponentInfo.id === collectionId;
137+
135138
const { navigateTo } = useLibraryRoutes();
136139
const openCollection = useCallback(() => {
137140
openCollectionInfoSidebar(collectionId);
@@ -154,6 +157,7 @@ const CollectionCard = ({ hit } : CollectionCardProps) => {
154157
</ActionRow>
155158
)}
156159
onSelect={openCollection}
160+
selected={selected}
157161
/>
158162
);
159163
};

src/library-authoring/components/ComponentCard.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
import { type ContentHit, PublishStatus } from '../../search-manager';
77
import { useComponentPickerContext } from '../common/context/ComponentPickerContext';
88
import { useLibraryContext } from '../common/context/LibraryContext';
9-
import { useSidebarContext } from '../common/context/SidebarContext';
9+
import { SidebarBodyComponentId, useSidebarContext } from '../common/context/SidebarContext';
1010
import { useLibraryRoutes } from '../routes';
1111
import AddComponentWidget from './AddComponentWidget';
1212
import BaseCard from './BaseCard';
@@ -18,7 +18,7 @@ type ComponentCardProps = {
1818

1919
const ComponentCard = ({ hit }: ComponentCardProps) => {
2020
const { showOnlyPublished } = useLibraryContext();
21-
const { openComponentInfoSidebar } = useSidebarContext();
21+
const { openComponentInfoSidebar, sidebarComponentInfo } = useSidebarContext();
2222
const { componentPickerMode } = useComponentPickerContext();
2323

2424
const {
@@ -44,6 +44,9 @@ const ComponentCard = ({ hit }: ComponentCardProps) => {
4444
}
4545
}, [usageKey, navigateTo, openComponentInfoSidebar]);
4646

47+
const selected = sidebarComponentInfo?.type === SidebarBodyComponentId.ComponentInfo
48+
&& sidebarComponentInfo.id === usageKey;
49+
4750
return (
4851
<BaseCard
4952
itemType={blockType}
@@ -61,6 +64,7 @@ const ComponentCard = ({ hit }: ComponentCardProps) => {
6164
)}
6265
hasUnpublishedChanges={publishStatus !== PublishStatus.Published}
6366
onSelect={openComponent}
67+
selected={selected}
6468
/>
6569
);
6670
};

src/library-authoring/components/ContainerCard.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { ToastContext } from '../../generic/toast-context';
1717
import { type ContainerHit, PublishStatus } from '../../search-manager';
1818
import { useComponentPickerContext } from '../common/context/ComponentPickerContext';
1919
import { useLibraryContext } from '../common/context/LibraryContext';
20-
import { SidebarActions, useSidebarContext } from '../common/context/SidebarContext';
20+
import { SidebarActions, SidebarBodyComponentId, useSidebarContext } from '../common/context/SidebarContext';
2121
import { useRemoveItemsFromCollection } from '../data/apiHooks';
2222
import { useLibraryRoutes } from '../routes';
2323
import AddComponentWidget from './AddComponentWidget';
@@ -174,7 +174,7 @@ type ContainerCardProps = {
174174
const ContainerCard = ({ hit } : ContainerCardProps) => {
175175
const { componentPickerMode } = useComponentPickerContext();
176176
const { setUnitId, showOnlyPublished } = useLibraryContext();
177-
const { openUnitInfoSidebar } = useSidebarContext();
177+
const { openUnitInfoSidebar, sidebarComponentInfo } = useSidebarContext();
178178

179179
const {
180180
blockType: itemType,
@@ -199,6 +199,9 @@ const ContainerCard = ({ hit } : ContainerCardProps) => {
199199
showOnlyPublished ? published?.content?.childUsageKeys : content?.childUsageKeys
200200
) ?? [];
201201

202+
const selected = sidebarComponentInfo?.type === SidebarBodyComponentId.UnitInfo
203+
&& sidebarComponentInfo.id === unitId;
204+
202205
const { navigateTo } = useLibraryRoutes();
203206

204207
const openContainer = useCallback(() => {
@@ -227,6 +230,7 @@ const ContainerCard = ({ hit } : ContainerCardProps) => {
227230
)}
228231
hasUnpublishedChanges={publishStatus !== PublishStatus.Published}
229232
onSelect={openContainer}
233+
selected={selected}
230234
/>
231235
);
232236
};

src/library-authoring/units/LibraryUnitBlocks.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import {
2929
import { LibraryBlock } from '../LibraryBlock';
3030
import { useLibraryRoutes, ContentType } from '../routes';
3131
import messages from './messages';
32-
import { SidebarActions, useSidebarContext } from '../common/context/SidebarContext';
32+
import { SidebarActions, SidebarBodyComponentId, useSidebarContext } from '../common/context/SidebarContext';
3333
import { ToastContext } from '../../generic/toast-context';
3434
import { canEditComponent } from '../components/ComponentEditorModal';
3535
import { useRunOnNextRender } from '../../utils';
@@ -139,7 +139,7 @@ const ComponentBlock = ({ block, preview, isDragging }: ComponentBlockProps) =>
139139
unitId, collectionId, componentId, openComponentEditor,
140140
} = useLibraryContext();
141141

142-
const { openInfoSidebar } = useSidebarContext();
142+
const { openInfoSidebar, sidebarComponentInfo } = useSidebarContext();
143143

144144
const handleComponentSelection = useCallback((numberOfClicks: number) => {
145145
navigateTo({ componentId: block.originalId });
@@ -182,6 +182,9 @@ const ComponentBlock = ({ block, preview, isDragging }: ComponentBlockProps) =>
182182
return {};
183183
}, [isDragging, componentId, block]);
184184

185+
const selected = sidebarComponentInfo?.type === SidebarBodyComponentId.ComponentInfo
186+
&& sidebarComponentInfo?.id === block.id;
187+
185188
return (
186189
<IframeProvider>
187190
<SortableItem
@@ -197,6 +200,7 @@ const ComponentBlock = ({ block, preview, isDragging }: ComponentBlockProps) =>
197200
isClickable
198201
onClick={(e: { detail: number; }) => handleComponentSelection(e.detail)}
199202
disabled={preview}
203+
cardClassName={selected ? 'selected' : undefined}
200204
>
201205
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
202206
<div

src/library-authoring/units/index.scss

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,23 @@
44
padding: 0;
55
margin-bottom: 1rem;
66
border: solid 1px $light-500;
7+
8+
&::before {
9+
border: none !important; // Remove default focus
10+
}
11+
12+
&.selected:not(:focus) {
13+
border: 2px $gray-700 solid;
14+
}
15+
16+
&.selected:focus {
17+
border: 3px $gray-700 solid;
18+
}
19+
20+
&:not(.selected):focus {
21+
outline: 1px $gray-200 solid;
22+
outline-offset: 2px;
23+
}
724
}
825

926
.pgn__card.clickable {

0 commit comments

Comments
 (0)