Skip to content

Commit cbc242f

Browse files
committed
chore(react): implement BEM-style styling for OrganizationList and BaseOrganizationList components
1 parent 364dcba commit cbc242f

File tree

4 files changed

+564
-218
lines changed

4 files changed

+564
-218
lines changed
Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
/**
2+
* Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
3+
*
4+
* WSO2 LLC. licenses this file to you under the Apache License,
5+
* Version 2.0 (the "License"); you may not use this file except
6+
* in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing,
12+
* software distributed under the License is distributed on an
13+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
* KIND, either express or implied. See the License for the
15+
* specific language governing permissions and limitations
16+
* under the License.
17+
*/
18+
19+
import {css} from '@emotion/css';
20+
import {useMemo} from 'react';
21+
import {bem, Theme} from '@asgardeo/browser';
22+
23+
/**
24+
* Creates styles for the BaseOrganizationList component using BEM methodology
25+
* @param theme - The theme object containing design tokens
26+
* @param colorScheme - The current color scheme (used for memoization)
27+
* @returns Object containing CSS class names for component styling
28+
*/
29+
const useStyles = (theme: Theme, colorScheme: string) => {
30+
return useMemo(() => {
31+
const cssOrganizationList = css`
32+
padding: calc(${theme.vars.spacing.unit} * 4);
33+
min-width: 600px;
34+
margin: 0 auto;
35+
background: ${theme.vars.colors.background.surface};
36+
border-radius: ${theme.vars.borderRadius.large};
37+
38+
&__header {
39+
display: flex;
40+
align-items: center;
41+
justify-content: space-between;
42+
margin-bottom: calc(${theme.vars.spacing.unit} * 3);
43+
padding-bottom: calc(${theme.vars.spacing.unit} * 2);
44+
border-bottom: 1px solid ${theme.vars.colors.border};
45+
}
46+
47+
&__header-info {
48+
flex: 1;
49+
}
50+
51+
&__title {
52+
font-size: 1.5rem;
53+
font-weight: 600;
54+
margin: 0 0 8px 0;
55+
color: ${theme.vars.colors.text.primary};
56+
}
57+
58+
&__subtitle {
59+
color: ${theme.vars.colors.text.secondary};
60+
font-size: 0.875rem;
61+
margin: 0;
62+
}
63+
64+
&__refresh-button {
65+
background-color: ${theme.vars.colors.background.surface};
66+
border: 1px solid ${theme.vars.colors.border};
67+
border-radius: ${theme.vars.borderRadius.small};
68+
color: ${theme.vars.colors.text.primary};
69+
cursor: pointer;
70+
font-size: 0.875rem;
71+
padding: ${theme.vars.spacing.unit} calc(${theme.vars.spacing.unit} * 2);
72+
transition: all 0.2s;
73+
74+
&:hover {
75+
background-color: ${theme.vars.colors.background.surface};
76+
border-color: ${theme.vars.colors.primary.main};
77+
}
78+
}
79+
80+
&__list-container {
81+
display: flex;
82+
flex-direction: column;
83+
gap: calc(${theme.vars.spacing.unit} * 1.5);
84+
}
85+
86+
&__organization-item {
87+
border: 1px solid ${theme.vars.colors.border};
88+
border-radius: ${theme.vars.borderRadius.medium};
89+
display: flex;
90+
justify-content: space-between;
91+
padding: calc(${theme.vars.spacing.unit} * 2);
92+
transition: all 0.2s;
93+
background-color: ${theme.vars.colors.background.surface};
94+
95+
&:hover {
96+
border-color: ${theme.vars.colors.primary.main};
97+
box-shadow: 0 2px 8px ${theme.vars.colors.primary.main}20;
98+
}
99+
}
100+
101+
&__organization-content {
102+
display: flex;
103+
align-items: center;
104+
gap: calc(${theme.vars.spacing.unit} * 2);
105+
flex: 1;
106+
}
107+
108+
&__organization-info {
109+
flex: 1;
110+
}
111+
112+
&__organization-name {
113+
font-size: 1.125rem;
114+
font-weight: 600;
115+
margin: 0 0 4px 0;
116+
color: ${theme.vars.colors.text.primary};
117+
}
118+
119+
&__organization-handle {
120+
color: ${theme.vars.colors.text.secondary};
121+
font-size: 0.875rem;
122+
margin: 0 0 4px 0;
123+
font-family: monospace;
124+
}
125+
126+
&__organization-status {
127+
color: ${theme.vars.colors.text.secondary};
128+
font-size: 0.875rem;
129+
margin: 0;
130+
}
131+
132+
&__status-text {
133+
font-weight: 500;
134+
135+
&--active {
136+
color: ${theme.vars.colors.success.main};
137+
}
138+
139+
&--inactive {
140+
color: ${theme.vars.colors.error.main};
141+
}
142+
}
143+
144+
&__organization-actions {
145+
display: flex;
146+
align-items: center;
147+
}
148+
149+
&__badge {
150+
border-radius: ${theme.vars.borderRadius.large};
151+
font-size: 0.75rem;
152+
font-weight: 500;
153+
padding: calc(${theme.vars.spacing.unit} / 2) calc(${theme.vars.spacing.unit} * 1.5);
154+
text-transform: uppercase;
155+
letter-spacing: 0.5px;
156+
157+
&--success {
158+
background-color: color-mix(in srgb, ${theme.vars.colors.success.main} 20%, transparent);
159+
color: ${theme.vars.colors.success.main};
160+
}
161+
162+
&--error {
163+
background-color: color-mix(in srgb, ${theme.vars.colors.error.main} 20%, transparent);
164+
color: ${theme.vars.colors.error.main};
165+
}
166+
}
167+
168+
&__loading-container {
169+
padding: calc(${theme.vars.spacing.unit} * 4);
170+
text-align: center;
171+
display: flex;
172+
flex-direction: column;
173+
align-items: center;
174+
gap: calc(${theme.vars.spacing.unit} * 2);
175+
}
176+
177+
&__loading-text {
178+
margin-top: ${theme.vars.spacing.unit};
179+
}
180+
181+
&__error-container {
182+
background-color: color-mix(in srgb, ${theme.vars.colors.error.main} 20%, transparent);
183+
border: 1px solid ${theme.vars.colors.error.main};
184+
border-radius: ${theme.vars.borderRadius.medium};
185+
color: ${theme.vars.colors.error.main};
186+
padding: calc(${theme.vars.spacing.unit} * 2);
187+
}
188+
189+
&__empty-container {
190+
padding: calc(${theme.vars.spacing.unit} * 4);
191+
text-align: center;
192+
}
193+
194+
&__empty-text {
195+
color: ${theme.vars.colors.text.secondary};
196+
font-size: 1rem;
197+
}
198+
199+
&__load-more-button {
200+
background-color: ${theme.vars.colors.primary.main};
201+
border: none;
202+
border-radius: ${theme.vars.borderRadius.medium};
203+
color: ${theme.vars.colors.primary.contrastText};
204+
cursor: pointer;
205+
font-size: 0.875rem;
206+
font-weight: 500;
207+
padding: calc(${theme.vars.spacing.unit} * 1.5) calc(${theme.vars.spacing.unit} * 3);
208+
width: 100%;
209+
transition: all 0.2s;
210+
211+
&:hover:not(:disabled) {
212+
background-color: ${theme.vars.colors.primary.main};
213+
opacity: 0.9;
214+
}
215+
216+
&:disabled {
217+
background-color: ${theme.vars.colors.text.secondary};
218+
cursor: not-allowed;
219+
opacity: 0.6;
220+
}
221+
}
222+
223+
&__error-margin {
224+
margin-top: calc(${theme.vars.spacing.unit} * 2);
225+
}
226+
227+
&__load-more-margin {
228+
margin-top: calc(${theme.vars.spacing.unit} * 3);
229+
}
230+
231+
&__popup-content {
232+
padding: ${theme.vars.spacing.unit};
233+
}
234+
`;
235+
236+
return {
237+
organizationList: cssOrganizationList,
238+
organizationList__header: bem(cssOrganizationList, 'header'),
239+
organizationList__headerInfo: bem(cssOrganizationList, 'header-info'),
240+
organizationList__title: bem(cssOrganizationList, 'title'),
241+
organizationList__subtitle: bem(cssOrganizationList, 'subtitle'),
242+
organizationList__refreshButton: bem(cssOrganizationList, 'refresh-button'),
243+
organizationList__listContainer: bem(cssOrganizationList, 'list-container'),
244+
organizationList__organizationItem: bem(cssOrganizationList, 'organization-item'),
245+
organizationList__organizationContent: bem(cssOrganizationList, 'organization-content'),
246+
organizationList__organizationInfo: bem(cssOrganizationList, 'organization-info'),
247+
organizationList__organizationName: bem(cssOrganizationList, 'organization-name'),
248+
organizationList__organizationHandle: bem(cssOrganizationList, 'organization-handle'),
249+
organizationList__organizationStatus: bem(cssOrganizationList, 'organization-status'),
250+
organizationList__statusText: bem(cssOrganizationList, 'status-text'),
251+
'organizationList__statusText--active': bem(cssOrganizationList, 'status-text', 'active'),
252+
'organizationList__statusText--inactive': bem(cssOrganizationList, 'status-text', 'inactive'),
253+
organizationList__organizationActions: bem(cssOrganizationList, 'organization-actions'),
254+
organizationList__badge: bem(cssOrganizationList, 'badge'),
255+
'organizationList__badge--success': bem(cssOrganizationList, 'badge', 'success'),
256+
'organizationList__badge--error': bem(cssOrganizationList, 'badge', 'error'),
257+
organizationList__loadingContainer: bem(cssOrganizationList, 'loading-container'),
258+
organizationList__loadingText: bem(cssOrganizationList, 'loading-text'),
259+
organizationList__errorContainer: bem(cssOrganizationList, 'error-container'),
260+
organizationList__emptyContainer: bem(cssOrganizationList, 'empty-container'),
261+
organizationList__emptyText: bem(cssOrganizationList, 'empty-text'),
262+
organizationList__loadMoreButton: bem(cssOrganizationList, 'load-more-button'),
263+
organizationList__errorMargin: bem(cssOrganizationList, 'error-margin'),
264+
organizationList__loadMoreMargin: bem(cssOrganizationList, 'load-more-margin'),
265+
organizationList__popupContent: bem(cssOrganizationList, 'popup-content'),
266+
};
267+
}, [theme, colorScheme]);
268+
};
269+
270+
export default useStyles;

0 commit comments

Comments
 (0)