Skip to content

Commit e349892

Browse files
authored
Add <Checklist> component (#2883)
* Create check-list component * Use new Checklist component in SSO configuration guide * Alternate design, version A * Alternate design, version B * Use alternate design B with fill effect from design C * Adjust checkbox design * Replace SSO guide content with new component * Increase vertical padding for the list
1 parent 61bdd18 commit e349892

File tree

6 files changed

+239
-8
lines changed

6 files changed

+239
-8
lines changed

docusaurus/docs/cms/configurations/guides/configure-sso.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,16 @@ export default ({ env }) => ({
7171

7272
## Setting up provider configuration
7373

74-
:::strapi End-to-end SSO setup checklist
7574
Parts of the documentation below assume that some one-time preparation steps have been done both in Strapi and in your identity provider (IdP). If these steps are skipped, the login button might appear on the Strapi login page but the flow will fail with a redirect or "invalid client" error. Make sure to follow all these steps:
7675

77-
<Icon name="check-square" /> Enable SSO in Strapi: Go to *Global settings > Single Sign-On* in the admin panel and set up the feature (e.g. toggle auto-registration and choose the default role). <br/>
78-
<Icon name="check-square" /> Register Strapi in your IdP: In the provider's dashboard (e.g. Azure AD, Okta, Google, GitHub), create a new OAuth/OIDC application for Strapi. Copy the client ID and client secret that the provider generates. <br/>
79-
<Icon name="check-square" /> Add the Strapi callback URL to the provider: Set the redirect/callback URL in the provider configuration to the value generated by `strapi.admin.services.passport.getStrategyCallbackURL('<provider_uid>')` (e.g. `/admin/connect/google` if the UID is `google`). The provider must accept this URL or the login will be blocked. <br/>
80-
<Icon name="check-square" /> Provide credentials to Strapi: Add the client ID and client secret as environment variables (e.g. `GOOGLE_CLIENT_ID`/`GOOGLE_CLIENT_SECRET`) so they can be read in `/config/admin.{js,ts}`. <br/>
81-
<Icon name="check-square" /> Configure the provider in code: Import the provider's Passport strategy and add it to `auth.providers`. <br/>
82-
<Icon name="check-square" /> Rebuild and restart Strapi: Run `yarn build && yarn develop` or `npm run build && npm run develop` so the new provider appears on the login page. If the admin panel is hosted separately, also ensure the [`url` setting](/cms/admin-panel-customization/host-port-path) matches the deployed admin URL.
83-
:::
76+
<Checklist title="End-to-end SSO setup checklist">
77+
<ChecklistItem>Enable SSO in Strapi: Go to <em>Global settings > Single Sign-On</em> in the admin panel and set up the feature (e.g. toggle auto-registration and choose the default role).</ChecklistItem>
78+
<ChecklistItem>Register Strapi in your IdP: In the provider's dashboard (e.g. Azure AD, Okta, Google, GitHub), create a new OAuth/OIDC application for Strapi. Copy the client ID and client secret that the provider generates.</ChecklistItem>
79+
<ChecklistItem>Add the Strapi callback URL to the provider: Set the redirect/callback URL in the provider configuration to the value generated by <code>{"strapi.admin.services.passport.getStrategyCallbackURL('<provider_uid>')"}</code> (e.g. <code>/admin/connect/google</code> if the UID is <code>google</code>). The provider must accept this URL or the login will be blocked.</ChecklistItem>
80+
<ChecklistItem>Provide credentials to Strapi: Add the client ID and client secret as environment variables (e.g. <code>GOOGLE_CLIENT_ID</code>/<code>GOOGLE_CLIENT_SECRET</code>) so they can be read in <code>{"/config/admin.{js,ts}"}</code>.</ChecklistItem>
81+
<ChecklistItem>Configure the provider in code: Import the provider's Passport strategy and add it to <code>auth.providers</code>.</ChecklistItem>
82+
<ChecklistItem>Rebuild and restart Strapi: Run <code>yarn build && yarn develop</code> or <code>npm run build && npm run develop</code> so the new provider appears on the login page. If the admin panel is hosted separately, also ensure the <a href="/cms/admin-panel-customization/host-port-path"><code>url</code> setting</a> matches the deployed admin URL.</ChecklistItem>
83+
</Checklist>
8484

8585
A provider's configuration is a JavaScript object built with the following properties:
8686

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React, { useState, useId } from 'react';
2+
import clsx from 'clsx';
3+
4+
export function ChecklistItem({ children }) {
5+
const id = useId();
6+
const [checked, setChecked] = useState(false);
7+
8+
return (
9+
<li className="checklist__item">
10+
<label className="checklist__label" htmlFor={id}>
11+
<input
12+
type="checkbox"
13+
id={id}
14+
className="checklist__input"
15+
checked={checked}
16+
onChange={() => setChecked(!checked)}
17+
/>
18+
<span className="checklist__checkbox" aria-hidden="true" />
19+
<span className="checklist__text">{children}</span>
20+
</label>
21+
</li>
22+
);
23+
}
24+
25+
export default function Checklist({
26+
title = 'Checklist',
27+
children,
28+
className,
29+
...rest
30+
}) {
31+
return (
32+
<div className={clsx('checklist', className)} {...rest}>
33+
<div className="checklist__header">{title}</div>
34+
<ul className="checklist__list" role="list">
35+
{children}
36+
</ul>
37+
</div>
38+
);
39+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import Checklist, { ChecklistItem } from './Checklist';
2+
3+
export { ChecklistItem };
4+
export default Checklist;

docusaurus/src/scss/__index.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
@use 'breadcrumbs.scss';
2424
@use 'breaking-change-id-card.scss';
2525
@use 'card.scss';
26+
@use 'checklist.scss';
2627
@use 'code.scss';
2728
@use 'code-block.scss';
2829
@use 'columns.scss';

docusaurus/src/scss/checklist.scss

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/** Component: Checklist */
2+
@use 'mixins' as *;
3+
4+
.checklist {
5+
--checklist-header-font-size: 11px;
6+
--checklist-header-line-height: 16px;
7+
--checklist-header-font-weight: 600;
8+
--checklist-content-font-size: 14px;
9+
--checklist-content-line-height: 20px;
10+
11+
border: 1px solid var(--strapi-neutral-150);
12+
border-radius: 4px;
13+
background-color: var(--strapi-neutral-0);
14+
overflow: hidden;
15+
margin-bottom: 40px;
16+
17+
&__header {
18+
background-color: var(--strapi-neutral-100);
19+
color: var(--strapi-neutral-600);
20+
text-transform: uppercase;
21+
font-size: var(--checklist-header-font-size) !important;
22+
line-height: var(--checklist-header-line-height);
23+
font-weight: var(--checklist-header-font-weight);
24+
padding: 8px 16px 6px;
25+
letter-spacing: 0.4px;
26+
border-bottom: 1px solid var(--strapi-neutral-150);
27+
}
28+
29+
&__list {
30+
list-style: none;
31+
margin: 0;
32+
padding: 12px 0;
33+
}
34+
35+
&__item {
36+
padding: 0;
37+
38+
&::before {
39+
display: none;
40+
}
41+
}
42+
43+
&__label {
44+
display: flex;
45+
align-items: flex-start;
46+
padding: 8px 16px;
47+
cursor: pointer;
48+
gap: 12px;
49+
}
50+
51+
&__input {
52+
position: absolute;
53+
opacity: 0;
54+
width: 0;
55+
height: 0;
56+
pointer-events: none;
57+
}
58+
59+
&__checkbox {
60+
flex-shrink: 0;
61+
width: 16px;
62+
height: 16px;
63+
border: 1.5px solid var(--strapi-neutral-300);
64+
border-radius: 50%;
65+
background-color: transparent;
66+
position: relative;
67+
top: 3px;
68+
transition: all 0.2s ease;
69+
70+
&::before {
71+
content: '';
72+
position: absolute;
73+
inset: -1.5px;
74+
background-color: var(--strapi-primary-600);
75+
transform: scale(0);
76+
transition: transform 0.15s ease;
77+
border-radius: 50%;
78+
z-index: 1;
79+
}
80+
81+
&::after {
82+
content: '';
83+
position: absolute;
84+
left: 4px;
85+
top: 2px;
86+
width: 3px;
87+
height: 6px;
88+
border: solid white;
89+
border-width: 0 2px 2px 0;
90+
transform: rotate(45deg);
91+
opacity: 0;
92+
transition: opacity 0.1s ease 0.05s;
93+
z-index: 2;
94+
}
95+
}
96+
97+
&__input:checked + &__checkbox {
98+
border-color: transparent;
99+
100+
&::before {
101+
transform: scale(1);
102+
}
103+
104+
&::after {
105+
opacity: 1;
106+
}
107+
}
108+
109+
&__input:focus-visible + &__checkbox {
110+
outline: 2px solid var(--strapi-primary-500);
111+
outline-offset: 2px;
112+
}
113+
114+
&__text {
115+
flex: 1;
116+
color: var(--strapi-neutral-800);
117+
font-size: var(--checklist-content-font-size);
118+
line-height: var(--checklist-content-line-height);
119+
word-break: break-word;
120+
121+
code {
122+
background-color: var(--strapi-neutral-100);
123+
color: var(--strapi-neutral-700);
124+
border: 1px solid var(--strapi-neutral-200);
125+
border-radius: 3px;
126+
padding: 1px 4px;
127+
font-size: 13px;
128+
word-break: break-all;
129+
}
130+
131+
a {
132+
color: var(--strapi-primary-600);
133+
text-decoration: none;
134+
135+
&:hover {
136+
text-decoration: underline;
137+
}
138+
}
139+
}
140+
}
141+
142+
@include dark {
143+
.checklist {
144+
background-color: #212134;
145+
border-color: #4a4a6a;
146+
147+
&__header {
148+
background-color: var(--strapi-neutral-150);
149+
color: var(--strapi-neutral-400);
150+
border-color: #4a4a6a;
151+
}
152+
153+
&__checkbox {
154+
background-color: transparent;
155+
border-color: #6a6a8a;
156+
157+
&::before {
158+
background-color: var(--strapi-primary-500);
159+
}
160+
}
161+
162+
&__label:hover .checklist__checkbox {
163+
border-color: var(--strapi-primary-400);
164+
}
165+
166+
&__input:checked + .checklist__checkbox {
167+
border-color: var(--strapi-primary-500);
168+
}
169+
170+
&__text {
171+
color: #DCDCE4;
172+
173+
code {
174+
background-color: var(--strapi-neutral-150);
175+
color: #DCDCE4;
176+
border-color: #4a4a6a;
177+
}
178+
179+
a {
180+
color: var(--strapi-primary-500);
181+
}
182+
}
183+
}
184+
}

docusaurus/src/theme/MDXComponents.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import { ExternalLink } from '../components/ExternalLink';
3838
import BreakingChangeIdCard from '../components/BreakingChangeIdCard';
3939
import MermaidWithFallback from '../components/MermaidWithFallback.js';
4040
import IdentityCard, { IdentityCardItem } from '../components/IdentityCard';
41+
import Checklist, { ChecklistItem } from '../components/Checklist';
4142
// Debug component for testing, for instance the AIToolbar configuration
4243
import DebugComponent from '../components/DebugComponent';
4344

@@ -91,6 +92,8 @@ export default {
9192
Icon,
9293
ExternalLink,
9394
BreakingChangeIdCard,
95+
Checklist,
96+
ChecklistItem,
9497
IdentityCard,
9598
IdentityCardItem,
9699
Tldr,

0 commit comments

Comments
 (0)