Skip to content

Commit cad1906

Browse files
feat: extends Button and extracts ListHeader components (#7777)
1 parent 988c884 commit cad1906

File tree

12 files changed

+276
-107
lines changed

12 files changed

+276
-107
lines changed

packages/next/src/views/List/Default/index.scss

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,13 @@
1111
}
1212
}
1313

14-
&__header {
15-
display: flex;
16-
align-items: flex-end;
17-
flex-wrap: wrap;
18-
gap: base(0.8);
19-
20-
h1 {
21-
margin: 0;
22-
}
23-
14+
.list-header {
2415
a {
2516
text-decoration: none;
2617
}
2718

28-
.pill {
19+
.btn--withoutPopup,
20+
.btn--withPopup {
2921
position: relative;
3022
margin: 0 0 base(0.2);
3123
}

packages/next/src/views/List/Default/index.tsx

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ import {
99
EditMany,
1010
Gutter,
1111
ListControls,
12+
ListHeader,
1213
ListSelection,
1314
Pagination,
1415
PerPage,
15-
Pill,
16+
PopupList,
1617
PublishMany,
1718
RelationshipProvider,
1819
RenderComponent,
@@ -104,35 +105,36 @@ export const DefaultListView: React.FC = () => {
104105
<RenderComponent mappedComponent={beforeList} />
105106
<SelectionProvider docs={data.docs} totalDocs={data.totalDocs}>
106107
<Gutter className={`${baseClass}__wrap`}>
107-
<header className={`${baseClass}__header`}>
108-
{Header || (
109-
<Fragment>
110-
<h1>{getTranslation(labels?.plural, i18n)}</h1>
111-
{hasCreatePermission && (
112-
<Pill
113-
aria-label={i18n.t('general:createNewLabel', {
114-
label: getTranslation(labels?.singular, i18n),
115-
})}
116-
to={newDocumentURL}
117-
>
118-
{i18n.t('general:createNew')}
119-
</Pill>
120-
)}
121-
{!smallBreak && (
122-
<ListSelection label={getTranslation(collectionConfig.labels.plural, i18n)} />
123-
)}
124-
{description && (
125-
<div className={`${baseClass}__sub-header`}>
126-
<RenderComponent
127-
Component={ViewDescription}
128-
clientProps={{ description }}
129-
mappedComponent={Description}
130-
/>
131-
</div>
132-
)}
133-
</Fragment>
134-
)}
135-
</header>
108+
{Header || (
109+
<ListHeader heading={getTranslation(labels?.plural, i18n)}>
110+
{hasCreatePermission && (
111+
<Button
112+
Link={Link}
113+
aria-label={i18n.t('general:createNewLabel', {
114+
label: getTranslation(labels?.singular, i18n),
115+
})}
116+
buttonStyle="pill"
117+
el="link"
118+
size="small"
119+
to={newDocumentURL}
120+
>
121+
{i18n.t('general:createNew')}
122+
</Button>
123+
)}
124+
{!smallBreak && (
125+
<ListSelection label={getTranslation(collectionConfig.labels.plural, i18n)} />
126+
)}
127+
{description && (
128+
<div className={`${baseClass}__sub-header`}>
129+
<RenderComponent
130+
Component={ViewDescription}
131+
clientProps={{ description }}
132+
mappedComponent={Description}
133+
/>
134+
</div>
135+
)}
136+
</ListHeader>
137+
)}
136138
<ListControls collectionConfig={collectionConfig} fields={fields} />
137139
<RenderComponent mappedComponent={beforeListTable} />
138140
{!data.docs && (
@@ -174,7 +176,7 @@ export const DefaultListView: React.FC = () => {
174176
limit={data.limit}
175177
nextPage={data.nextPage}
176178
numberOfNeighbors={1}
177-
onChange={handlePageChange}
179+
onChange={(page) => void handlePageChange(page)}
178180
page={data.page}
179181
prevPage={data.prevPage}
180182
totalPages={data.totalPages}
@@ -189,7 +191,7 @@ export const DefaultListView: React.FC = () => {
189191
{i18n.t('general:of')} {data.totalDocs}
190192
</div>
191193
<PerPage
192-
handleChange={handlePerPageChange}
194+
handleChange={(limit) => void handlePerPageChange(limit)}
193195
limit={
194196
isNumber(searchParams?.limit) ? Number(searchParams.limit) : defaultLimit
195197
}

packages/ui/src/elements/Button/index.scss

Lines changed: 107 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,99 @@ a.btn {
44
display: inline-block;
55
}
66

7+
.btn--withPopup {
8+
margin-block: 24px;
9+
.btn {
10+
margin: 0;
11+
}
12+
}
13+
14+
.btn {
15+
// colors
16+
&--style-primary {
17+
--color: var(--theme-elevation-0);
18+
--bg-color: var(--theme-elevation-800);
19+
--box-shadow: none;
20+
--hover-bg: var(--theme-elevation-600);
21+
--hover-color: var(--color);
22+
23+
&.btn--disabled {
24+
--bg-color: var(--theme-elevation-200);
25+
--color: var(--theme-elevation-800);
26+
--hover-bg: var(--bg-color);
27+
--hover-color: var(--color);
28+
}
29+
}
30+
31+
&--style-secondary {
32+
--color: var(--theme-text);
33+
--bg-color: transparent;
34+
--box-shadow: inset 0 0 0 1px var(--theme-elevation-800);
35+
--hover-color: var(--theme-elevation-600);
36+
--hover-box-shadow: inset 0 0 0 1px var(--theme-elevation-400);
37+
38+
&.btn--disabled {
39+
--color: var(--theme-elevation-200);
40+
--box-shadow: inset 0 0 0 1px var(--theme-elevation-200);
41+
--hover-box-shadow: inset 0 0 0 1px var(--theme-elevation-200);
42+
--hover-color: var(--color);
43+
}
44+
}
45+
46+
&--style-pill {
47+
--bg-color: var(--theme-elevation-150);
48+
--color: var(--theme-elevation-800);
49+
--hover-color: var(--color);
50+
--hover-bg: var(--theme-elevation-100);
51+
52+
&.btn--disabled {
53+
--color: var(--theme-elevation-600);
54+
--hover-bg: var(--bg-color);
55+
--hover-color: var(--color);
56+
}
57+
}
58+
}
59+
60+
.btn--withPopup {
61+
.popup-button {
62+
color: var(--color, inherit);
63+
background-color: var(--bg-color);
64+
box-shadow: var(--box-shadow);
65+
border-radius: $style-radius-m;
66+
border-left: 1px solid var(--theme-bg);
67+
border-top-left-radius: 0;
68+
border-bottom-left-radius: 0;
69+
align-items: center;
70+
71+
&:hover,
72+
&:focus-visible,
73+
&:focus,
74+
&:active {
75+
background-color: var(--hover-bg);
76+
color: var(--hover-color);
77+
box-shadow: var(--hover-box-shadow);
78+
}
79+
}
80+
}
81+
82+
.btn,
83+
.btn--withPopup .btn {
84+
&:hover,
85+
&:focus-visible,
86+
&:focus,
87+
&:active {
88+
color: var(--hover-color);
89+
box-shadow: var(--hover-box-shadow);
90+
background-color: var(--hover-bg);
91+
}
92+
}
93+
94+
.btn--disabled,
95+
.btn--disabled .btn {
96+
cursor: not-allowed;
97+
}
98+
799
.btn {
8-
background: transparent;
9100
border-radius: $style-radius-s;
10101
font-size: var(--base-body-size);
11102
margin-block: base(1.2);
@@ -14,11 +105,18 @@ a.btn {
14105
cursor: pointer;
15106
font-weight: normal;
16107
text-decoration: none;
17-
color: inherit;
18108
transition-property: border, color, box-shadow, background;
19109
transition-duration: 100ms;
20110
transition-timing-function: cubic-bezier(0, 0.2, 0.2, 1);
21111

112+
color: var(--color, inherit);
113+
background-color: var(--bg-color, transparent);
114+
box-shadow: var(--box-shadow, none);
115+
116+
.icon {
117+
@include color-svg(var(--color));
118+
}
119+
22120
&__content {
23121
display: flex;
24122
align-items: center;
@@ -47,6 +145,10 @@ a.btn {
47145
}
48146
}
49147

148+
&--withPopup {
149+
display: flex;
150+
}
151+
50152
&--has-tooltip {
51153
position: relative;
52154
}
@@ -127,46 +229,9 @@ a.btn {
127229
}
128230
}
129231

130-
&--style-primary {
131-
background: var(--theme-elevation-800);
132-
color: var(--theme-elevation-0);
133-
134-
&.btn--disabled {
135-
background: var(--theme-elevation-200);
136-
}
137-
138-
&:not(.btn--disabled) {
139-
&:hover,
140-
&:focus-visible,
141-
&:focus,
142-
&:active {
143-
background: var(--theme-elevation-600);
144-
}
145-
}
146-
147-
.icon {
148-
@include color-svg(var(--theme-elevation-0));
149-
}
150-
}
151-
152-
&--style-secondary {
153-
box-shadow: inset 0 0 0 1px var(--theme-elevation-800);
154-
color: var(--theme-text);
155-
156-
&.btn--disabled {
157-
color: var(--theme-elevation-200);
158-
box-shadow: inset 0 0 0 1px var(--theme-elevation-200);
159-
}
160-
161-
&:not(.btn--disabled) {
162-
&:hover,
163-
&:focus-visible,
164-
&:focus,
165-
&:active {
166-
color: var(--theme-elevation-600);
167-
box-shadow: inset 0 0 0 1px var(--theme-elevation-400);
168-
}
169-
}
232+
&--withPopup .btn {
233+
border-top-right-radius: 0;
234+
border-bottom-right-radius: 0;
170235
}
171236

172237
&--style-icon-label,

0 commit comments

Comments
 (0)