Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for theme customization using CSS variables #60

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions packages/tail-kit/src/components/button/button.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ test('render icon after label when iconPlacement is afterText', () => {
test('render default disabled button correctly', () => {
render(<Button disabled>Click Me</Button>)
expect(screen.getByRole('button')).toHaveClass(
'border-gray-400 text-gray-400',
'border-disabled text-disabled',
)
})

Expand All @@ -115,7 +115,9 @@ test('render primary disabled button correctly', () => {
Click Me
</Button>,
)
expect(screen.getByRole('button')).toHaveClass('bg-gray-400 text-white')
expect(screen.getByRole('button')).toHaveClass(
'bg-disabled text-text-inverse',
)
})

test('render danger disabled button correctly', () => {
Expand All @@ -125,7 +127,7 @@ test('render danger disabled button correctly', () => {
</Button>,
)
expect(screen.getByRole('button')).toHaveClass(
'border-gray-400 text-gray-400',
'border-disabled text-disabled',
)
})

Expand All @@ -135,5 +137,5 @@ test('render link disabled button correctly', () => {
Click Me
</Button>,
)
expect(screen.getByRole('button')).toHaveClass('text-gray-400')
expect(screen.getByRole('button')).toHaveClass('text-disabled')
})
18 changes: 9 additions & 9 deletions packages/tail-kit/src/components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,32 +65,32 @@ export const Button = forwardRef(
const buttonClassNames = useMemo(() => {
if (buttonType === 'default') {
if (disabled) {
return 'border-gray-400 text-gray-400 default'
return 'border-disabled text-disabled default'
}
return 'border-blue-600 text-blue-600 hover:bg-blue-600 hover:text-white default'
return 'border-primary text-primary hover:bg-primary hover:text-text-inverse default'
}

if (buttonType === 'primary') {
if (disabled) {
return 'bg-gray-400 text-white border-transparent primary'
return 'bg-disabled text-text-inverse border-transparent primary'
}

return 'bg-blue-600 text-white border-transparent primary'
return 'bg-primary text-text-inverse border-transparent primary'
}

if (buttonType === 'danger') {
if (disabled) {
return 'border-gray-400 text-gray-400 danger'
return 'border-disabled text-disabled danger'
}

return 'border-red-500 text-red-500 hover:bg-red-500 hover:text-white danger'
return 'border-error text-error hover:bg-error hover:text-text-inverse danger'
}

// if none of the above branches are satisfied, then the button is of type link
if (disabled) {
return 'border-transparent text-gray-400 link'
return 'border-transparent text-disabled link'
}
return 'border-transparent text-blue-600 link'
return 'border-transparent text-primary link'
}, [buttonType, disabled])

const iconComponent = loading ? (
Expand All @@ -103,7 +103,7 @@ export const Button = forwardRef(
<button
aria-label={children || restProps['aria-label']}
className={clsx(
'py-2 rounded-md focus:outline-none focus:ring-2 border text-sm font-medium flex items-center justify-center space-x-2 transition-colors duration-300',
'py-2 rounded-default focus:outline-none focus:ring-2 border text-sm font-medium flex items-center justify-center space-x-2 transition-colors duration-300',
iconOnlyButton ? 'px-2' : 'px-3',
buttonClassNames,
disabled || loading ? 'cursor-not-allowed' : 'cursor-pointer',
Expand Down
4 changes: 2 additions & 2 deletions packages/tail-kit/src/components/form/form.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,10 @@ test('children as function works correctly with form', async () => {
)}
</Form>,
)
expect(screen.getByText('Submit').parentElement).toHaveClass('bg-gray-400')
expect(screen.getByText('Submit').parentElement).toHaveClass('bg-disabled')
userEvent.type(screen.getByRole('textbox'), 'test@example.com')
await waitFor(() => {
expect(screen.getByText('Submit').parentElement).toHaveClass('bg-blue-600')
expect(screen.getByText('Submit').parentElement).toHaveClass('bg-primary')
})
})

Expand Down
24 changes: 12 additions & 12 deletions packages/tail-kit/src/components/pagination/pagination.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,23 @@ test('pagination component working correctly', () => {

test('Next button of pagination component working correctly', () => {
render(<Pagination total={50} />)
expect(screen.getByText('1').parentElement).toHaveClass('bg-blue-600')
expect(screen.getByText('1').parentElement).toHaveClass('bg-primary')
fireEvent.click(screen.getByText('Next'))
expect(screen.getByText('2').parentElement).toHaveClass('bg-blue-600')
expect(screen.getByText('2').parentElement).toHaveClass('bg-primary')
})

test('Previous button of pagination component working correctly', () => {
render(<Pagination total={50} defaultCurrent={3} />)
expect(screen.getByText('3').parentElement).toHaveClass('bg-blue-600')
expect(screen.getByText('3').parentElement).toHaveClass('bg-primary')
fireEvent.click(screen.getByText('Previous'))
expect(screen.getByText('2').parentElement).toHaveClass('bg-blue-600')
expect(screen.getByText('2').parentElement).toHaveClass('bg-primary')
})

test('Page buttons of pagination component working correctly', () => {
render(<Pagination total={50} />)
expect(screen.getByText('1').parentElement).toHaveClass('bg-blue-600')
expect(screen.getByText('1').parentElement).toHaveClass('bg-primary')
fireEvent.click(screen.getByText('3'))
expect(screen.getByText('3').parentElement).toHaveClass('bg-blue-600')
expect(screen.getByText('3').parentElement).toHaveClass('bg-primary')
})

/** Tests for page size changer in pagination component */
Expand All @@ -43,42 +43,42 @@ test('Change selected page when value of total number of pages changes', () => {
render(<Pagination total={100} showSizeChanger defaultCurrent={10} />)
fireEvent.click(screen.getByText('10 / page'))
fireEvent.click(screen.getByText('20 / page'))
expect(screen.getByText('5').parentElement).toHaveClass('bg-blue-600')
expect(screen.getByText('5').parentElement).toHaveClass('bg-primary')
})

/** Tests for page jumper */
test('Page jumper of pagination component working correctly', () => {
render(<Pagination total={50} showQuickJumper />)
userEvent.type(screen.getByRole('textbox'), '3')
fireEvent.blur(screen.getByDisplayValue('3'))
expect(screen.getByText('3').parentElement).toHaveClass('bg-blue-600')
expect(screen.getByText('3').parentElement).toHaveClass('bg-primary')
})

test('Out of range value in page jumper working correctly', () => {
render(<Pagination total={50} defaultCurrent={3} showQuickJumper />)
userEvent.type(screen.getByRole('textbox'), '-1')
fireEvent.blur(screen.getByDisplayValue('-1'))
expect(screen.getByText('1').parentElement).toHaveClass('bg-blue-600')
expect(screen.getByText('1').parentElement).toHaveClass('bg-primary')

userEvent.type(screen.getByRole('textbox'), '10')
fireEvent.blur(screen.getByDisplayValue('10'))
expect(screen.getByText('5').parentElement).toHaveClass('bg-blue-600')
expect(screen.getByText('5').parentElement).toHaveClass('bg-primary')
})

test('Enter key shortcut for page jumper working correctly', () => {
render(<Pagination total={100} showQuickJumper />)
const input = screen.getByRole('textbox')
userEvent.type(input, '5')
fireEvent.keyDown(input, { key: 'Enter', code: 13 })
expect(screen.getByText('5').parentElement).toHaveClass('bg-blue-600')
expect(screen.getByText('5').parentElement).toHaveClass('bg-primary')
})

test('invalid entries in page jumper working correctly', () => {
render(<Pagination total={100} defaultCurrent={5} showQuickJumper />)
const input = screen.getByRole('textbox')
userEvent.type(input, 'abc')
fireEvent.keyDown(input, { key: 'Enter', code: 13 })
expect(screen.getByText('5').parentElement).toHaveClass('bg-blue-600')
expect(screen.getByText('5').parentElement).toHaveClass('bg-primary')
})

/** Test cases for page wrap in pagination component */
Expand Down
20 changes: 19 additions & 1 deletion packages/tail-kit/src/styles/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,26 @@

@tailwind components;

@layer base {
:root {
--font-family: 'Inter var', ui-sans-serif, system-ui, -apple-system,
BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
'Segoe UI Symbol', 'Noto Color Emoji';

/* Color Palette */
--primary-color: theme('colors.blue.600');
--error-color: theme('colors.red.500');
--disabled-color: theme('colors.gray.400');

--text-primary-color: theme('colors.gray.800');
--text-inverse-color: theme('colors.white');
--border-radius-default: theme('borderRadius.md');
}
}

body {
@apply font-sans antialiased;
@apply antialiased font-default;
}

.checkbox:focus-within > .checkbox-icon-container {
Expand Down
23 changes: 23 additions & 0 deletions packages/tail-kit/tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,27 @@
module.exports = {
presets: [require('../../tailwind.config')],
purge: ['./src/**/*.tsx', './src/**/*.ts', './src/styles/safelist.txt'],
theme: {
extend: {
fontFamily: {
default: 'var(--font-family)',
},
colors: {
primary: 'var(--primary-color)',
error: 'var(--error-color)',
disabled: 'var(--disabled-color)',
text: {
primary: 'var(--text-primary-color)',
inverse: 'var(--text-inverse-color)',
},
},
borderRadius: {
default: 'var(--border-radius-default)',
},
},
},
variants: {
extend: {},
},
plugins: [],
}