-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create new chip component to represent grade status (#6658)
- Loading branch information
Showing
5 changed files
with
221 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
lms/static/scripts/frontend_apps/components/dashboard/GradeStatusChip.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import classnames from 'classnames'; | ||
|
||
export type GradeStatusChipProps = { | ||
/** | ||
* A grade, from 0 to 100, that will be used to render the corresponding | ||
* color combination. | ||
*/ | ||
grade: number; | ||
}; | ||
|
||
/** | ||
* A badge where the corresponding color combination is calculated from a grade | ||
* from 0 to 100, following the next table: | ||
* | ||
* 100 - bright green | ||
* 80-99 - light green | ||
* 50-79 - yellow | ||
* 1-49 - light red | ||
* 0 - bright red | ||
* other - grey | ||
*/ | ||
export default function GradeStatusChip({ grade }: GradeStatusChipProps) { | ||
const gradeIsInvalid = grade < 0 || grade > 100; | ||
|
||
return ( | ||
<div | ||
className={classnames('rounded font-bold inline-block px-2 py-0.5', { | ||
// We would usually use our standard `green-success` and `red-error` | ||
// colors here, but they don't have enough contrast when used with | ||
// white text and a small font. | ||
// Instead, we use slightly darker shades of green and red. | ||
'bg-[#008558] text-white': grade === 100, | ||
'bg-[#D7373A] text-white': grade === 0, | ||
'bg-green-200 text-green-900': grade >= 80 && grade < 100, | ||
'bg-amber-100 text-amber-900': grade >= 50 && grade < 80, | ||
'bg-red-200 text-red-900': grade >= 1 && grade < 50, | ||
'bg-grey-3 text-grey-7': gradeIsInvalid, | ||
})} | ||
> | ||
{grade} | ||
{!gradeIsInvalid && '%'} | ||
</div> | ||
); | ||
} |
58 changes: 58 additions & 0 deletions
58
lms/static/scripts/frontend_apps/components/dashboard/test/GradeStatusChip-test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { checkAccessibility } from '@hypothesis/frontend-testing'; | ||
import { mount } from 'enzyme'; | ||
|
||
import GradeStatusChip from '../GradeStatusChip'; | ||
|
||
describe('GradeStatusChip', () => { | ||
function renderComponent(grade) { | ||
return mount(<GradeStatusChip grade={grade} />); | ||
} | ||
|
||
[0, 20, 48, 77, 92, 100].forEach(grade => { | ||
it('renders valid grades as percentage', () => { | ||
const wrapper = renderComponent(grade); | ||
assert.equal(wrapper.text(), `${grade}%`); | ||
}); | ||
}); | ||
|
||
[-20, 150].forEach(grade => { | ||
it('renders invalid grades verbatim', () => { | ||
const wrapper = renderComponent(grade); | ||
assert.equal(wrapper.text(), `${grade}`); | ||
}); | ||
}); | ||
|
||
it( | ||
'should pass a11y checks', | ||
checkAccessibility([ | ||
{ | ||
name: '100', | ||
content: () => renderComponent(100), | ||
}, | ||
{ | ||
name: '80', | ||
content: () => renderComponent(80), | ||
}, | ||
{ | ||
name: '68', | ||
content: () => renderComponent(68), | ||
}, | ||
{ | ||
name: '38', | ||
content: () => renderComponent(38), | ||
}, | ||
{ | ||
name: '0', | ||
content: () => renderComponent(0), | ||
}, | ||
{ | ||
name: '-20', | ||
content: () => renderComponent(-20), | ||
}, | ||
{ | ||
name: '150', | ||
content: () => renderComponent(150), | ||
}, | ||
]), | ||
); | ||
}); |
103 changes: 103 additions & 0 deletions
103
lms/static/scripts/ui-playground/components/GradeStatusChipPage.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import { DataTable } from '@hypothesis/frontend-shared'; | ||
import Library from '@hypothesis/frontend-shared/lib/pattern-library/components/Library'; | ||
|
||
import GradeStatusChip from '../../frontend_apps/components/dashboard/GradeStatusChip'; | ||
|
||
export default function GradeStatusChipPage() { | ||
return ( | ||
<Library.Page title="Grade status chip"> | ||
<Library.Section title="GradeStatusChip"> | ||
<p> | ||
It renders a badge with an automatically calculating color | ||
combination, based on a grade from 0 to 100. | ||
</p> | ||
<Library.Demo withSource> | ||
<GradeStatusChip grade={100} /> | ||
<GradeStatusChip grade={80} /> | ||
<GradeStatusChip grade={68} /> | ||
<GradeStatusChip grade={38} /> | ||
<GradeStatusChip grade={0} /> | ||
<GradeStatusChip grade={120} /> | ||
<GradeStatusChip grade={-25} /> | ||
</Library.Demo> | ||
</Library.Section> | ||
|
||
<Library.Section title="GradeStatusChip in DataTable"> | ||
<p> | ||
We plan to use the <code>GradeStatusChip</code> inside the dashboard | ||
metrics tables. This is how it will look like. | ||
</p> | ||
<Library.Demo withSource> | ||
<DataTable | ||
grid | ||
striped={false} | ||
rows={[ | ||
{ | ||
name: 'Bethany VonRueden', | ||
grade: 100, | ||
annotations: 4, | ||
replies: 1, | ||
}, | ||
{ | ||
name: 'Grace Feet', | ||
grade: 92, | ||
annotations: 2, | ||
replies: 1, | ||
}, | ||
{ | ||
name: 'Hannah Rohan', | ||
grade: 0, | ||
annotations: 0, | ||
replies: 0, | ||
}, | ||
{ | ||
name: 'Jeremiah Kassuke', | ||
grade: 68, | ||
annotations: 1, | ||
replies: 2, | ||
}, | ||
{ | ||
name: 'Julio Mertz', | ||
grade: 75, | ||
annotations: 2, | ||
replies: 1, | ||
}, | ||
{ | ||
name: 'Martha Russel', | ||
grade: 48, | ||
annotations: 1, | ||
replies: 0, | ||
}, | ||
]} | ||
columns={[ | ||
{ | ||
field: 'name', | ||
label: 'Student', | ||
}, | ||
{ | ||
field: 'grade', | ||
label: 'Grade', | ||
}, | ||
{ | ||
field: 'annotations', | ||
label: 'Annotations', | ||
}, | ||
{ | ||
field: 'replies', | ||
label: 'Replies', | ||
}, | ||
]} | ||
title="Students" | ||
renderItem={(row, field) => { | ||
if (field === 'grade') { | ||
return <GradeStatusChip grade={row.grade} />; | ||
} | ||
|
||
return row[field]; | ||
}} | ||
/> | ||
</Library.Demo> | ||
</Library.Section> | ||
</Library.Page> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters