Skip to content

Commit 85814e3

Browse files
committed
Implement Design UI
1 parent c9f3d65 commit 85814e3

61 files changed

Lines changed: 8802 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
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 type {JSX, ReactNode} from 'react';
20+
import {Button, Paper, Stack, Typography} from '@mui/material';
21+
22+
/**
23+
* Configuration for a bulk action button.
24+
*/
25+
export interface BulkAction {
26+
/** Button label */
27+
label: string;
28+
/** Icon to display before label */
29+
icon: ReactNode;
30+
/** Click handler */
31+
onClick: () => void;
32+
/** Whether the button is disabled */
33+
disabled?: boolean;
34+
/** Button color */
35+
color?: 'primary' | 'error' | 'secondary';
36+
}
37+
38+
/**
39+
* Props for the BulkActionBar component.
40+
*/
41+
export interface BulkActionBarProps {
42+
/** Number of selected items */
43+
selectedCount: number;
44+
/** Callback to clear all selections */
45+
onClearSelection: () => void;
46+
/** Array of action buttons to display */
47+
actions: BulkAction[];
48+
}
49+
50+
/**
51+
* Sticky action bar that appears when items are selected.
52+
* Shows selected count and action buttons for bulk operations.
53+
*
54+
* @param props - Component props
55+
* @returns BulkActionBar component
56+
*
57+
* @example
58+
* ```tsx
59+
* const { selectedIds, clearSelection } = useMultiSelect();
60+
*
61+
* {selectedIds.size > 0 && (
62+
* <BulkActionBar
63+
* selectedCount={selectedIds.size}
64+
* onClearSelection={clearSelection}
65+
* actions={[
66+
* {
67+
* label: 'Delete',
68+
* icon: <Trash2 size={20} />,
69+
* onClick: handleBulkDelete,
70+
* color: 'error'
71+
* },
72+
* {
73+
* label: 'Duplicate',
74+
* icon: <Copy size={20} />,
75+
* onClick: handleBulkDuplicate,
76+
* }
77+
* ]}
78+
* />
79+
* )}
80+
* ```
81+
*/
82+
export default function BulkActionBar({selectedCount, onClearSelection, actions}: BulkActionBarProps): JSX.Element {
83+
return (
84+
<Paper
85+
elevation={8}
86+
sx={{
87+
position: 'fixed',
88+
bottom: 24,
89+
left: '50%',
90+
transform: 'translateX(-50%)',
91+
zIndex: 1000,
92+
px: 3,
93+
py: 2,
94+
minWidth: 400,
95+
animation: 'slideUp 0.3s ease-out',
96+
'@keyframes slideUp': {
97+
from: {
98+
opacity: 0,
99+
transform: 'translate(-50%, 20px)',
100+
},
101+
to: {
102+
opacity: 1,
103+
transform: 'translate(-50%, 0)',
104+
},
105+
},
106+
}}
107+
>
108+
<Stack direction="row" alignItems="center" spacing={3}>
109+
{/* Selected count */}
110+
<Typography variant="body1" fontWeight={600} color="text.primary">
111+
{selectedCount} selected
112+
</Typography>
113+
114+
{/* Action buttons */}
115+
<Stack direction="row" spacing={1} flex={1} justifyContent="flex-end">
116+
{actions.map((action, index) => (
117+
<Button
118+
key={index}
119+
variant={action.color === 'error' ? 'outlined' : 'text'}
120+
color={action.color || 'primary'}
121+
startIcon={action.icon}
122+
onClick={action.onClick}
123+
disabled={action.disabled}
124+
size="small"
125+
>
126+
{action.label}
127+
</Button>
128+
))}
129+
</Stack>
130+
131+
{/* Clear selection button */}
132+
<Button variant="outlined" onClick={onClearSelection} size="small">
133+
Clear
134+
</Button>
135+
</Stack>
136+
</Paper>
137+
);
138+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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 type {JSX} from 'react';
20+
import {Card, CardContent, Grid, Skeleton, Stack} from '@mui/material';
21+
22+
/**
23+
* Props for the CardSkeleton component.
24+
*/
25+
export interface CardSkeletonProps {
26+
/** Number of skeleton cards to render */
27+
count?: number;
28+
/** Height of each skeleton card in pixels */
29+
height?: number;
30+
}
31+
32+
/**
33+
* Loading skeleton component that matches the card grid layout.
34+
* Shows animated placeholder cards while content is loading.
35+
*
36+
* @param props - Component props
37+
* @returns CardSkeleton component
38+
*
39+
* @example
40+
* ```tsx
41+
* {isLoading ? (
42+
* <CardSkeleton count={8} height={280} />
43+
* ) : (
44+
* <Grid container spacing={3}>
45+
* {items.map(item => <Card key={item.id}>...</Card>)}
46+
* </Grid>
47+
* )}
48+
* ```
49+
*/
50+
export default function CardSkeleton({count = 8, height = 280}: CardSkeletonProps): JSX.Element {
51+
return (
52+
<Grid container spacing={3}>
53+
{Array.from({length: count}).map((_, index) => (
54+
<Grid item xs={12} sm={6} md={4} lg={3} key={index}>
55+
<Card sx={{height}}>
56+
<CardContent>
57+
<Stack spacing={2}>
58+
{/* Preview area */}
59+
<Skeleton variant="rectangular" height={height * 0.6} sx={{borderRadius: 2}} />
60+
61+
{/* Title */}
62+
<Skeleton variant="text" width="80%" height={24} />
63+
64+
{/* Metadata */}
65+
<Stack direction="row" spacing={1}>
66+
<Skeleton variant="rectangular" width={60} height={24} sx={{borderRadius: 1}} />
67+
<Skeleton variant="text" width={100} height={20} />
68+
</Stack>
69+
</Stack>
70+
</CardContent>
71+
</Card>
72+
</Grid>
73+
))}
74+
</Grid>
75+
);
76+
}

0 commit comments

Comments
 (0)