feat: add tailwind version of Button component
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hello-pangea/dnd": "^16.5.0",
|
"@hello-pangea/dnd": "^16.5.0",
|
||||||
"@types/sql.js": "^1.4.9",
|
"@types/sql.js": "^1.4.9",
|
||||||
|
"@unocss/reset": "^0.58.5",
|
||||||
"@vitejs/plugin-react": "^4.2.1",
|
"@vitejs/plugin-react": "^4.2.1",
|
||||||
"chrome-extension-toolkit": "^0.0.51",
|
"chrome-extension-toolkit": "^0.0.51",
|
||||||
"clsx": "^2.1.0",
|
"clsx": "^2.1.0",
|
||||||
|
|||||||
11
pnpm-lock.yaml
generated
11
pnpm-lock.yaml
generated
@@ -19,6 +19,9 @@ dependencies:
|
|||||||
'@types/sql.js':
|
'@types/sql.js':
|
||||||
specifier: ^1.4.9
|
specifier: ^1.4.9
|
||||||
version: 1.4.9
|
version: 1.4.9
|
||||||
|
'@unocss/reset':
|
||||||
|
specifier: ^0.58.5
|
||||||
|
version: 0.58.5
|
||||||
'@vitejs/plugin-react':
|
'@vitejs/plugin-react':
|
||||||
specifier: ^4.2.1
|
specifier: ^4.2.1
|
||||||
version: 4.2.1(vite@5.1.2)
|
version: 4.2.1(vite@5.1.2)
|
||||||
@@ -5427,8 +5430,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-2wMrkCj3SSb5hrx9TKs5jZa34QIRkHv9FotbJutAPo7o8hx+XXn56ogzdoUrcFPJZJUx2R2nyOVbSlGMIjtFtw==}
|
resolution: {integrity: sha512-2wMrkCj3SSb5hrx9TKs5jZa34QIRkHv9FotbJutAPo7o8hx+XXn56ogzdoUrcFPJZJUx2R2nyOVbSlGMIjtFtw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@unocss/rule-utils@0.58.5:
|
/@unocss/reset@0.58.5:
|
||||||
resolution: {integrity: sha512-w0sGJoeUGwMWLVFLEE9PDiv/fQcQqZnTIIQLYNCjTdqXDRlwTp9ACW0h47x/hAAIXdOtEOOBuTfjGD79GznUmA==}
|
resolution: {integrity: sha512-2wMrkCj3SSb5hrx9TKs5jZa34QIRkHv9FotbJutAPo7o8hx+XXn56ogzdoUrcFPJZJUx2R2nyOVbSlGMIjtFtw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@unocss/rule-utils@0.58.4:
|
||||||
|
resolution: {integrity: sha512-52Jp4I+joGTaDm7ehB/7uZ2kJL+9BZcYRDUVk4IDacDH5W9yxf1F75LzYT8jJVWXD/HIhiS0r9V6qhcBq2OWZw==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@unocss/core': 0.58.5
|
'@unocss/core': 0.58.5
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Button } from 'src/views/components/common/Button/Button';
|
import { Button } from 'src/views/components/common/Button/Button';
|
||||||
import type { Meta, StoryObj } from '@storybook/react';
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import ImagePlaceholderIcon from '~icons/material-symbols/image';
|
||||||
|
|
||||||
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
|
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
|
||||||
const meta = {
|
const meta = {
|
||||||
@@ -39,15 +40,37 @@ export const Grid: Story = {
|
|||||||
render: props => (
|
render: props => (
|
||||||
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
||||||
<div style={{ display: 'flex' }}>
|
<div style={{ display: 'flex' }}>
|
||||||
<Button {...props} type='filled' />
|
<Button {...props} variant='filled' className='bg-ut-black' />
|
||||||
<Button {...props} type='outline' />
|
<Button {...props} variant='outline' className='text-ut-black' />
|
||||||
<Button {...props} type='single' />
|
<Button {...props} variant='single' className='text-ut-black' />
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: 'flex' }}>
|
<div style={{ display: 'flex' }}>
|
||||||
<Button {...props} type='filled' disabled />
|
<Button {...props} variant='filled' className='bg-ut-black' useScss />
|
||||||
<Button {...props} type='outline' disabled />
|
<Button {...props} variant='outline' className='text-ut-black' useScss />
|
||||||
<Button {...props} type='single' disabled />
|
<Button {...props} variant='single' className='text-ut-black' useScss />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<div style={{ display: 'flex' }}>
|
||||||
|
<Button {...props} variant='filled' className='bg-ut-black' disabled />
|
||||||
|
<Button {...props} variant='outline' className='text-ut-black' disabled />
|
||||||
|
<Button {...props} variant='single' className='text-ut-black' disabled />
|
||||||
|
</div>
|
||||||
|
<div style={{ display: 'flex' }}>
|
||||||
|
<Button {...props} variant='filled' className='bg-ut-black' disabled useScss />
|
||||||
|
<Button {...props} variant='outline' className='text-ut-black' disabled useScss />
|
||||||
|
<Button {...props} variant='single' className='text-ut-black' disabled useScss />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Icons: Story = {
|
||||||
|
render: props => (
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
||||||
|
<Button {...props} variant='filled' icon={ImagePlaceholderIcon} />
|
||||||
|
<Button {...props} variant='outline' icon={ImagePlaceholderIcon} />
|
||||||
|
<Button {...props} variant='single' icon={ImagePlaceholderIcon} />
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@@ -60,14 +83,14 @@ export const CourseButtons: Story = {
|
|||||||
render: props => (
|
render: props => (
|
||||||
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
||||||
<div style={{ display: 'flex' }}>
|
<div style={{ display: 'flex' }}>
|
||||||
<Button {...props} type='filled' />
|
<Button {...props} variant='filled' />
|
||||||
<Button {...props} type='outline' />
|
<Button {...props} variant='outline' />
|
||||||
<Button {...props} type='single' />
|
<Button {...props} variant='single' />
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: 'flex' }}>
|
<div style={{ display: 'flex' }}>
|
||||||
<Button {...props} type='filled' disabled />
|
<Button {...props} variant='filled' disabled />
|
||||||
<Button {...props} type='outline' disabled />
|
<Button {...props} variant='outline' disabled />
|
||||||
<Button {...props} type='single' disabled />
|
<Button {...props} variant='single' disabled />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -5,18 +5,18 @@ import styles from './Button.module.scss';
|
|||||||
interface Props {
|
interface Props {
|
||||||
className?: string;
|
className?: string;
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
type?: 'filled' | 'outline' | 'single';
|
variant?: 'filled' | 'outline' | 'single';
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
iconOnly?: boolean;
|
icon?: React.ReactNode;
|
||||||
showSymbol?: boolean;
|
|
||||||
symbol?: React.ReactNode;
|
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
title?: string;
|
title?: string;
|
||||||
testId?: string;
|
testId?: string;
|
||||||
primaryColor?: string;
|
useScss?: boolean;
|
||||||
secondaryColor?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BUTTON_BASE_CLASS =
|
||||||
|
'm-2.5 h-10 w-auto flex cursor-pointer content-center items-center gap-2 rounded-1 px-4 py-0 text-4.5 font-500 leading-normal font-sans btn-transition';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reusable button component that follows the design system of the extension.
|
* A reusable button component that follows the design system of the extension.
|
||||||
* @returns
|
* @returns
|
||||||
@@ -24,25 +24,22 @@ interface Props {
|
|||||||
export function Button({
|
export function Button({
|
||||||
className,
|
className,
|
||||||
style,
|
style,
|
||||||
type,
|
variant,
|
||||||
onClick,
|
onClick,
|
||||||
iconOnly,
|
icon,
|
||||||
showSymbol,
|
|
||||||
symbol,
|
|
||||||
disabled,
|
disabled,
|
||||||
title,
|
title,
|
||||||
testId,
|
testId,
|
||||||
primaryColor,
|
|
||||||
secondaryColor,
|
|
||||||
children,
|
children,
|
||||||
|
useScss = false,
|
||||||
}: React.PropsWithChildren<Props>): JSX.Element {
|
}: React.PropsWithChildren<Props>): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
style={
|
style={
|
||||||
{
|
{
|
||||||
...style,
|
...style,
|
||||||
'--color-primary': primaryColor ?? '#333F48',
|
'--color-primary': '#333F48',
|
||||||
'--color-secondary': secondaryColor ?? '#FFFFFF',
|
'--color-secondary': '#FFFFFF',
|
||||||
} as React.CSSProperties
|
} as React.CSSProperties
|
||||||
}
|
}
|
||||||
data-testid={testId}
|
data-testid={testId}
|
||||||
@@ -50,9 +47,11 @@ export function Button({
|
|||||||
[styles.disabled]: disabled,
|
[styles.disabled]: disabled,
|
||||||
})}
|
})}
|
||||||
title={title}
|
title={title}
|
||||||
|
disabled={disabled}
|
||||||
onClick={disabled ? undefined : onClick}
|
onClick={disabled ? undefined : onClick}
|
||||||
>
|
>
|
||||||
{!iconOnly && children}
|
{icon}
|
||||||
|
{children}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import styles from './ExtensionRoot.module.scss';
|
|||||||
|
|
||||||
import '@unocss/reset/tailwind-compat.css';
|
import '@unocss/reset/tailwind-compat.css';
|
||||||
import 'uno.css';
|
import 'uno.css';
|
||||||
|
import '@unocss/reset/tailwind-compat.css';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
testId?: string;
|
testId?: string;
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ export default function CourseButtons({ course, activeSchedule }: Props) {
|
|||||||
<Button
|
<Button
|
||||||
onClick={openRateMyProfessorURL}
|
onClick={openRateMyProfessorURL}
|
||||||
disabled={!course.instructors.length}
|
disabled={!course.instructors.length}
|
||||||
type='primary'
|
variant='primary'
|
||||||
className={styles.button}
|
className={styles.button}
|
||||||
title='Search for this professor on RateMyProfessor'
|
title='Search for this professor on RateMyProfessor'
|
||||||
>
|
>
|
||||||
@@ -94,7 +94,7 @@ export default function CourseButtons({ course, activeSchedule }: Props) {
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={openSyllabiURL}
|
onClick={openSyllabiURL}
|
||||||
type='secondary'
|
variant='secondary'
|
||||||
className={styles.button}
|
className={styles.button}
|
||||||
title='Search for syllabi for this course'
|
title='Search for syllabi for this course'
|
||||||
>
|
>
|
||||||
@@ -105,7 +105,7 @@ export default function CourseButtons({ course, activeSchedule }: Props) {
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={openTextbookURL}
|
onClick={openTextbookURL}
|
||||||
type='tertiary'
|
variant='tertiary'
|
||||||
className={styles.button}
|
className={styles.button}
|
||||||
title='Search for textbooks for this course'
|
title='Search for textbooks for this course'
|
||||||
>
|
>
|
||||||
@@ -118,7 +118,7 @@ export default function CourseButtons({ course, activeSchedule }: Props) {
|
|||||||
disabled={!activeSchedule}
|
disabled={!activeSchedule}
|
||||||
onClick={isCourseSaved ? handleRemoveCourse : handleSaveCourse}
|
onClick={isCourseSaved ? handleRemoveCourse : handleSaveCourse}
|
||||||
title={isCourseSaved ? 'Remove this course from your schedule' : 'Add this course to your schedule'}
|
title={isCourseSaved ? 'Remove this course from your schedule' : 'Add this course to your schedule'}
|
||||||
type={isCourseSaved ? 'danger' : 'success'}
|
variant={isCourseSaved ? 'danger' : 'success'}
|
||||||
className={styles.button}
|
className={styles.button}
|
||||||
>
|
>
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ export default function TableRow({ row, isSelected, activeSchedule, onClick }: P
|
|||||||
|
|
||||||
return ReactDOM.createPortal(
|
return ReactDOM.createPortal(
|
||||||
<>
|
<>
|
||||||
<Button className={styles.rowButton} onClick={onClick} type='secondary'>
|
<Button className={styles.rowButton} onClick={onClick} variant='secondary'>
|
||||||
<Icon name='bar_chart' color='white' size='medium' />
|
<Icon name='bar_chart' color='white' size='medium' />
|
||||||
</Button>
|
</Button>
|
||||||
{conflicts.length > 0 && (
|
{conflicts.length > 0 && (
|
||||||
|
|||||||
Reference in New Issue
Block a user