Skip to content

feat: Setup tailwindcss. #239

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

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
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
6 changes: 4 additions & 2 deletions .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
"tabWidth": 2,
"semi": false,
"singleQuote": true,
"jsxBracketSameLine": true
}
"jsxBracketSameLine": true,
"plugins": ["prettier-plugin-tailwindcss"],
"tailwindStylesheet": "./src/assets/index.css"
}
8 changes: 4 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
<meta name="theme-color" content="#000000" />
<link rel="apple-touch-icon" href="/logo192.png" />
<link rel="preconnect" href="https://hackertab.dev" />
<link href="/src/styles.css" rel="stylesheet" />
<script src="/startup.js"></script>

<% if (isWebBuild) { %>
<title>Hackertab</title>
<link rel="manifest" href="/web_manifest.json" />
<title>Hackertab</title>
<link rel="manifest" href="/web_manifest.json" />
<% } else { %>
<title>New Tab</title>
<title>New Tab</title>
<%}%>
</head>
<body class="preload">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>

</body>
</html>
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"private": false,
"dependencies": {
"@amplitude/analytics-browser": "^1.5.5",
"@tailwindcss/vite": "^4.1.5",
"@tanstack/query-async-storage-persister": "^5.8.3",
"@tanstack/react-query": "^4.13.0",
"@tanstack/react-query-persist-client": "^5.8.4",
Expand Down Expand Up @@ -33,6 +34,7 @@
"react-spring-bottom-sheet": "^3.4.1",
"react-toggle": "^4.1.1",
"react-tooltip": "^4.2.21",
"tailwindcss": "^4.1.5",
"timeago.js": "^4.0.2",
"type-fest": "^1.2.0",
"vite-plugin-ejs": "^1.6.4",
Expand Down Expand Up @@ -87,7 +89,8 @@
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-hooks": "^4.3.0",
"prettier": "^2.7.1",
"prettier": "^3.5.3",
"prettier-plugin-tailwindcss": "^0.6.11",
"terser": "^5.19.2",
"typescript": "^5.1.6",
"vite": "^6.2.4",
Expand Down
15 changes: 11 additions & 4 deletions src/assets/App.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import 'variables.css';
@import './variables.css';

html {
background: var(--background-color);
Expand Down Expand Up @@ -371,7 +371,9 @@ a {
padding: 0;
pointer-events: all;
text-align: center;
transition: opacity 0.3s ease, right 0.3s ease;
transition:
opacity 0.3s ease,
right 0.3s ease;
width: 28px;
margin-bottom: 6px;
margin-right: 6px;
Expand Down Expand Up @@ -556,7 +558,9 @@ a {
flex-wrap: wrap;
gap: 8px;
order: 4;
transition: opacity 0.3s ease-out 0.1s, transform 0.3s ease-out 0.1s,
transition:
opacity 0.3s ease-out 0.1s,
transform 0.3s ease-out 0.1s,
visibility 0.3s ease-out 0.1s;
width: 100%;
}
Expand Down Expand Up @@ -872,7 +876,10 @@ Producthunt item

.searchBar {
order: 3;
transition: opacity 0.3s ease-out, transform 0.3s ease-out, visibility 0.3s ease-out;
transition:
opacity 0.3s ease-out,
transform 0.3s ease-out,
visibility 0.3s ease-out;
width: 100%;
display: flex;
align-items: center;
Expand Down
24 changes: 21 additions & 3 deletions src/assets/index.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
@import 'variables.css';
@import 'tailwindcss';
@import './variables.css';

body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',
'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
font-family:
-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell',
'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
Expand All @@ -19,3 +21,19 @@ code {
width: 100vw;
display: flex;
}

@custom-variant dark (&:where(.dark, .dark *));

@theme {
--color-ht-100: oklch(0.9 0.0221 250.23);
--color-ht-200: oklch(0.83 0.0314 249.73);
--color-ht-900: oklch(0.453 0.0179 251.34);
}

@layer base {
@variant dark {
--color-ht-100: oklch(0.2421 0.0129 258.37);
--color-ht-200: oklch(0.2245 0.0115 254.07);
--color-ht-900: oklch(1 0 0);
}
}
13 changes: 9 additions & 4 deletions src/components/DropDownMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Item, Menu, MenuId, animation, useContextMenu } from 'react-contexify'
import { RiArrowDownSFill } from 'react-icons/ri'
import { Button } from './Elements'

type Option = {
label: string
Expand Down Expand Up @@ -29,10 +30,14 @@ export const DropDownMenu = ({

return (
<>
<button onClick={displayMenu} className="headerSelect" data-target-id={tagId}>
{label}
<RiArrowDownSFill className="headerSelectIcon" />
</button>
<Button
type="text"
onClick={(e) => displayMenu(e)}
className="inline-flex items-center justify-center gap-2 text-center"
tagId={tagId}>
<span>{label}</span>
<RiArrowDownSFill />
</Button>
<Menu id={tagId} animation={animation.fade}>
{data &&
data.map((tag) => {
Expand Down
37 changes: 26 additions & 11 deletions src/components/Elements/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,56 @@
import clsx from 'clsx'
import React from 'react'
import { Spinner } from '../Spinner'
import './Button.css'

const sizes = {
small: 'small',
medium: 'medium',
large: 'large',
sm: 'py-1 px-2 text-xs',
md: 'py-3 px-4 text-base',
lg: 'py-4 px-8 text-xl',
}
type ButtonProps = {

const types = {
primary: 'bg-blue-500 text-white hover:bg-blue-600',
secondary: 'bg-ht-100 text-ht-900 hover:bg-ht-200',
danger: 'bg-danger text-on-danger ',
success: 'bg-green-500 text-white hover:bg-green-600',
warning: 'bg-yellow-400 text-white hover:bg-yellow-500',
text: 'bg-transparent text-ht-900',
}

interface ButtonProps {
children: React.ReactNode
onClick: () => void
onClick: (e: React.MouseEvent<HTMLSpanElement>) => void
className?: string
type?: keyof typeof types
size?: keyof typeof sizes
startIcon?: React.ReactNode
endIcon?: React.ReactNode
isLoading?: boolean
tagId?: string
}
export const Button = ({
size = 'medium',
onClick,
type = 'secondary',
className,
size = 'md',
startIcon,
endIcon,
children,
isLoading = false,
tagId,
}: ButtonProps) => {
return (
<button
className={clsx(
'button',
isLoading && 'loading',
'inline-flex items-center justify-center gap-2 rounded-full text-center',
types[type],
sizes[size],
className,
isLoading && 'disabled'
isLoading ? 'pointer-events-none cursor-not-allowed' : 'cursor-pointer'
)}
onClick={onClick}
disabled={isLoading}>
disabled={isLoading}
data-target-id={tagId}>
{isLoading ? <Spinner size="small" /> : startIcon}
{children}
{endIcon}
Expand Down
21 changes: 12 additions & 9 deletions src/components/Elements/Button/CircleButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ import clsx from 'clsx'
import { Spinner } from '../Spinner'

const sizes = {
small: 'small',
medium: 'medium',
large: 'large',
sm: 'size-[30px]',
md: 'size-[40px]',
lg: 'size-[50px]',
}

const variants = {
primary: 'primary',
darkfocus: 'dark-focus',
primary: 'bg-blue-500 text-white hover:bg-blue-600',
secondary: 'bg-ht-100 text-ht-900 hover:bg-ht-200',
outlined: 'bg-ht-100 text-ht-900 hover:bg-ht-100',
text: 'bg-transparent ttext-ht-900',
darkfocus: 'bg-blue-900 text-yellow-400 hover:opacity-80',
}

type CircleButtonProps = {
Expand All @@ -22,8 +25,8 @@ type CircleButtonProps = {
}

export const CircleButton = ({
size = 'medium',
variant = 'primary',
size = 'md',
variant = 'secondary',
onClick,
isLoading,
className,
Expand All @@ -33,11 +36,11 @@ export const CircleButton = ({
<button
disabled={isLoading}
className={clsx(
'circle-button',
'pointer-events-auto inline-flex cursor-pointer items-center justify-center rounded-full text-center',
sizes[size],
variants[variant],
className,
isLoading && 'disabled'
isLoading ? 'pointer-events-none cursor-not-allowed' : 'cursor-pointer'
)}
onClick={onClick}>
{isLoading ? <Spinner size="small" /> : children}
Expand Down
7 changes: 4 additions & 3 deletions src/components/Elements/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useRemoteConfigStore } from 'src/features/remoteConfig'
import { DesktopBreakpoint } from 'src/providers/DesktopBreakpoint'
import { useUserPreferences } from 'src/stores/preferences'
import { SupportedCardType } from 'src/types'
import { CircleButton } from '../Button'

type CardProps = {
children: React.ReactNode
Expand Down Expand Up @@ -61,9 +62,9 @@ export const Card = ({
<div className="blockHeader">
<DesktopBreakpoint>
<SortableKnob>
<button className="blockHeaderDragButton">
<MdOutlineDragIndicator />
</button>
<CircleButton onClick={() => {}} variant="text">
<MdOutlineDragIndicator size={24} />
</CircleButton>
</SortableKnob>
</DesktopBreakpoint>
<span className="blockHeaderIcon">{icon}</span> {titleComponent || label}{' '}
Expand Down
23 changes: 14 additions & 9 deletions src/components/Elements/CardWithActions/CardItemWithActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Attributes, trackLinkBookmark, trackLinkUnBookmark } from 'src/lib/anal
import { useBookmarks } from 'src/stores/bookmarks'
import { useUserPreferences } from 'src/stores/preferences'
import { BaseEntry } from 'src/types'
import { CircleButton } from '../Button'

type CardItemWithActionsProps = {
item: BaseEntry
Expand Down Expand Up @@ -80,27 +81,31 @@ export const CardItemWithActions = ({
shareData={shareModalData}
/>
{cardItem}
<div className={`blockActions ${isBookmarked ? 'active' : ''} `}>
<div className={`flex items-end justify-end gap-1 ${isBookmarked ? 'active' : ''}`}>
{source === 'ai' && (
<button
className={`blockActionButton `}
<CircleButton
size="sm"
className={`blockActionButton`}
onClick={onReportClicked}
aria-label="Report item">
<MdBugReport />
</button>
</CircleButton>
)}
<button
className={`blockActionButton `}
<CircleButton
size="sm"
className={`blockActionButton`}
onClick={onShareModalClicked}
aria-label="Open share modal">
<BiShareAlt />
</button>
<button
</CircleButton>
<CircleButton
size="sm"
variant={isBookmarked ? 'darkfocus' : 'secondary'}
className={`blockActionButton ${isBookmarked ? 'active' : ''}`}
onClick={onBookmarkClick}
aria-label="Bookmark item">
{!isBookmarked ? <BiBookmarkPlus /> : <BiBookmarkMinus />}
</button>
</CircleButton>
</div>
</div>
)
Expand Down
34 changes: 23 additions & 11 deletions src/components/Elements/ChipsSet/ChipsSet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import clsx from 'clsx'
import { useState } from 'react'
import { IoIosClose } from 'react-icons/io'
import { Option } from 'src/types'
import { Button } from '../Button'
import './chipset.css'
type ChipProps = {
option: Option
Expand All @@ -12,17 +13,28 @@ type ChipProps = {

const Chip = ({ option, onSelect, onRemove, active = false }: ChipProps) => {
return (
<div className={'chip ' + (active && 'active')}>
<button onClick={() => onSelect(option)}>
{option.icon && <span className="chipIcon">{option.icon}</span>}
{option.label}
</button>
{option.removeable && onRemove && (
<button className="deleteButton" onClick={() => onRemove(option)}>
<IoIosClose className="icon" />
</button>
)}
</div>
<Button
onClick={() => onSelect(option)}
type={`${active ? 'primary' : 'secondary'}`}
size="md"
startIcon={
// TODO we should search find svg icons for sources.
option.icon && (
<span className="h-[20px] w-[20px] rounded-full bg-white p-[2px] text-black dark:bg-transparent">
{option.icon}
</span>
)
}
endIcon={
option.removeable &&
onRemove && (
<button onClick={() => onRemove(option)}>
<IoIosClose size={24} />
</button>
)
}>
{option.label}
</Button>
)
}
type ChangeAction = {
Expand Down
Loading