mirror of https://github.com/sylv/micro.git
chore: switch classnames for clsx
This commit is contained in:
parent
d8d10f908e
commit
aac4a2d14c
|
@ -15,7 +15,7 @@
|
|||
".microrc.development": "jsonc"
|
||||
},
|
||||
"tailwindCSS.experimental.classRegex": [
|
||||
["classNames\\(([^)]*)\\)", "'([^']*)'", "\"([^']*)\""],
|
||||
["clsx\\(([^)]*)\\)", "'([^']*)'", "\"([^']*)\""],
|
||||
[":\\s*?[\"'`]([^\"'`]*).*?,"],
|
||||
["baseStyle.=.[\"'`]([^\"'`]*)"],
|
||||
// Enum = 'value'
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
"@ryanke/pandora": "^0.0.9",
|
||||
"@tailwindcss/typography": "^0.5.9",
|
||||
"autoprefixer": "^10.4.15",
|
||||
"classnames": "^2.3.2",
|
||||
"clsx": "^2.0.0",
|
||||
"concurrently": "^8.2.1",
|
||||
"copy-to-clipboard": "^3.3.3",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-disable react/no-danger */
|
||||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import * as avatar from 'generate-avatar';
|
||||
import type { FC } from 'react';
|
||||
import { useEffect, useMemo, useRef } from 'react';
|
||||
|
@ -10,7 +10,7 @@ export interface AvatarProps {
|
|||
}
|
||||
|
||||
export const Avatar: FC<AvatarProps> = (props) => {
|
||||
const classes = classNames('overflow-hidden rounded-full select-none', props.className);
|
||||
const classes = clsx('overflow-hidden rounded-full select-none', props.className);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const svg = useMemo(() => {
|
||||
return avatar.generateFromString(props.userId);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Menu } from '@headlessui/react';
|
||||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import type { FC, ReactNode } from 'react';
|
||||
import { Fragment } from 'react';
|
||||
import { Link } from '../link';
|
||||
|
@ -13,12 +13,12 @@ export interface DropdownTabProps {
|
|||
|
||||
export const DropdownTab: FC<DropdownTabProps> = ({ href, className, children, onClick }) => {
|
||||
const props = href ? { as: Link, href: href } : { as: Fragment };
|
||||
const base = classNames('px-3 py-2 my-1 text-gray-400 transition ease-in-out border-none cursor-pointer', className);
|
||||
const base = clsx('px-3 py-2 my-1 text-gray-400 transition ease-in-out border-none cursor-pointer', className);
|
||||
|
||||
return (
|
||||
<Menu.Item {...(props as any)}>
|
||||
{({ active }) => (
|
||||
<div className={classNames(base, active && 'text-white bg-dark-800')} onClick={onClick}>
|
||||
<div className={clsx(base, active && 'text-white bg-dark-800')} onClick={onClick}>
|
||||
{children}
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Menu, Transition } from '@headlessui/react';
|
||||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import type { FC, ReactNode } from 'react';
|
||||
import React, { Fragment } from 'react';
|
||||
|
||||
|
@ -10,7 +10,7 @@ export interface DropdownProps {
|
|||
}
|
||||
|
||||
export const Dropdown: FC<DropdownProps> = ({ trigger, children, className }) => {
|
||||
const itemsClasses = classNames(
|
||||
const itemsClasses = clsx(
|
||||
'absolute right-0 mt-2 overflow-y-auto rounded-md shadow-2xl bg-dark-300 focus:outline-none max-h-56 min-w-[10em]',
|
||||
className
|
||||
);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import { BASE_EMBED_CLASSES, MAX_HEIGHT } from '../embed';
|
||||
import type { Embeddable } from '../embeddable';
|
||||
|
||||
export const EmbedDefault = ({ data }: { data: Embeddable }) => {
|
||||
const classes = classNames(
|
||||
const classes = clsx(
|
||||
'flex flex-col items-center justify-center w-full select-none h-44',
|
||||
BASE_EMBED_CLASSES,
|
||||
MAX_HEIGHT
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import Head from 'next/head';
|
||||
import { Fragment } from 'react';
|
||||
import { BASE_EMBED_CLASSES, MAX_HEIGHT } from '../embed';
|
||||
import type { Embeddable } from '../embeddable';
|
||||
|
||||
export const EmbedImage = ({ data }: { data: Embeddable }) => {
|
||||
const imageClasses = classNames(`object-contain`, MAX_HEIGHT);
|
||||
const containerClasses = classNames(
|
||||
const imageClasses = clsx(`object-contain`, MAX_HEIGHT);
|
||||
const containerClasses = clsx(
|
||||
'flex items-center justify-center relative overflow-hidden',
|
||||
BASE_EMBED_CLASSES,
|
||||
MAX_HEIGHT
|
||||
|
|
|
@ -4,13 +4,13 @@ import { PageLoader } from '../../page-loader';
|
|||
import { EmbedDefault } from './embed-default';
|
||||
import type { Embeddable } from '../embeddable';
|
||||
import { textFetcher } from '../text-fetcher';
|
||||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import { BASE_EMBED_CLASSES } from '../embed';
|
||||
|
||||
export const EmbedMarkdown = ({ data }: { data: Embeddable }) => {
|
||||
const swrContent = useSWR<string>(data.content ? null : data.paths.direct, { fetcher: textFetcher });
|
||||
const content = data.content ?? swrContent;
|
||||
const classes = classNames('p-4', BASE_EMBED_CLASSES);
|
||||
const classes = clsx('p-4', BASE_EMBED_CLASSES);
|
||||
|
||||
if (content.error) {
|
||||
return <EmbedDefault data={data} />;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import { BASE_EMBED_CLASSES, MAX_HEIGHT } from '../embed';
|
||||
import type { Embeddable } from '../embeddable';
|
||||
|
||||
export const EmbedVideo = ({ file }: { file: Embeddable }) => {
|
||||
const classes = classNames('outline-none', BASE_EMBED_CLASSES, MAX_HEIGHT);
|
||||
const classes = clsx('outline-none', BASE_EMBED_CLASSES, MAX_HEIGHT);
|
||||
return (
|
||||
<video
|
||||
controls
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Button, ButtonStyle, Container, useAsync, useOnClickOutside, useToasts } from '@ryanke/pandora';
|
||||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import { Fragment, memo, useRef, useState } from 'react';
|
||||
import { Crop } from 'react-feather';
|
||||
import { useResendVerificationEmailMutation } from '../../generated/graphql';
|
||||
|
@ -19,7 +19,7 @@ export const Header = memo(() => {
|
|||
const [email, setEmail] = useState('');
|
||||
const createToast = useToasts();
|
||||
const [resent, setResent] = useState(false);
|
||||
const classes = classNames(
|
||||
const classes = clsx(
|
||||
'relative z-20 flex items-center justify-between h-16 my-auto transition',
|
||||
paths.loading && 'pointer-events-none invisible'
|
||||
);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import type { FormikContextType } from 'formik';
|
||||
import { FormikContext } from 'formik';
|
||||
import type { ReactNode } from 'react';
|
||||
|
@ -41,7 +41,7 @@ export function InputContainer<T extends InputChildPropsBase>({
|
|||
const formik = useContext<FormikContextType<any>>(FormikContext);
|
||||
const errorMessage = !!(formik && id && formik.touched[id]) && (formik.errors[id] as string);
|
||||
if (errorMessage) style = InputStyle.Error;
|
||||
const childClasses = classNames(
|
||||
const childClasses = clsx(
|
||||
'w-full h-full px-3 py-2 rounded outline-none border transition duration-75',
|
||||
maxHeight && 'max-h-[calc(2.65em-2px)]',
|
||||
style,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import type { SelectHTMLAttributes } from 'react';
|
||||
import React from 'react';
|
||||
import { ChevronDown } from 'react-feather';
|
||||
|
@ -11,7 +11,7 @@ export const Select = React.forwardRef<HTMLSelectElement, SelectProps>(({ classN
|
|||
return (
|
||||
<InputContainer className={className} childProps={delegated}>
|
||||
{({ childClasses, ...rest }) => {
|
||||
const classes = classNames(className, childClasses, 'appearance-none pr-8');
|
||||
const classes = clsx(className, childClasses, 'appearance-none pr-8');
|
||||
return (
|
||||
<div className="relative select-none">
|
||||
<select className={classes} ref={ref} {...rest}>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import type { TextareaHTMLAttributes } from 'react';
|
||||
import React from 'react';
|
||||
import type { InputChildProps } from './container';
|
||||
|
@ -10,7 +10,7 @@ export const TextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps>(({
|
|||
return (
|
||||
<InputContainer className={className} maxHeight={false} childProps={delegated}>
|
||||
{({ childClasses, ...rest }) => {
|
||||
const classes = classNames(childClasses, 'h-[50vh]');
|
||||
const classes = clsx(childClasses, 'h-[50vh]');
|
||||
return <textarea {...rest} className={classes} ref={ref} />;
|
||||
}}
|
||||
</InputContainer>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import type { Language } from 'prism-react-renderer';
|
||||
import { Fragment, memo } from 'react';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
|
@ -8,7 +8,7 @@ import { SyntaxHighlighter } from './syntax-highlighter/syntax-highlighter';
|
|||
const LANGUAGE_REGEX = /(^| )language-(?<language>.+)$/u;
|
||||
|
||||
export const Markdown = memo<{ children: string; className?: string }>(({ children, className }) => {
|
||||
const classes = classNames(
|
||||
const classes = clsx(
|
||||
'prose prose-invert max-w-none',
|
||||
// remove "" quotes from blockquotes
|
||||
'prose-p:before:content-none prose-p:after:content-none',
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import type { FC } from 'react';
|
||||
import { Fragment } from 'react';
|
||||
import { Ping } from './ping';
|
||||
|
@ -18,7 +18,7 @@ export const Steps: FC<StepsProps> = ({ steps, stepIndex }) => {
|
|||
{index !== 0 && <div className="h-px w-8 mx-4 bg-gray-800" />}
|
||||
<div className="flex items-center gap-2">
|
||||
<Ping active={isActive} />
|
||||
<div className={classNames(!isActive && 'text-gray-400')}>{step}</div>
|
||||
<div className={clsx(!isActive && 'text-gray-400')}>{step}</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import type { Language } from 'prism-react-renderer';
|
||||
import { Highlight } from 'prism-react-renderer';
|
||||
import type { HTMLProps } from 'react';
|
||||
|
@ -21,7 +21,7 @@ export const SyntaxHighlighter = memo<SyntaxHighlighterProps>(
|
|||
<Highlight theme={theme} code={trimmed} language={language}>
|
||||
{({ className: highlighterClasses, style, tokens, getLineProps, getTokenProps }) => {
|
||||
console.log(highlighterClasses);
|
||||
const containerClasses = classNames(
|
||||
const containerClasses = clsx(
|
||||
'text-left overflow-x-auto h-full relative',
|
||||
highlighterClasses,
|
||||
additionalClasses
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
|
||||
export interface ToggleOption<T = unknown> {
|
||||
label: string;
|
||||
|
@ -22,7 +22,7 @@ export function Toggle<T extends string | number | boolean>({
|
|||
<div className="inline-flex items-center overflow-hidden select-none bg-black text-gray-400 rounded-full">
|
||||
{options.map((item) => {
|
||||
const active = item.value === selected;
|
||||
const classes = classNames(
|
||||
const classes = clsx(
|
||||
'rounded-full px-4 py-1 text-sm cursor-pointer h-full',
|
||||
active ? 'text-white' : 'hover:bg-dark-200',
|
||||
active && backgroundColour
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import type { HTMLAttributes } from 'react';
|
||||
import { forwardRef } from 'react';
|
||||
import { Avatar } from './avatar';
|
||||
|
@ -10,7 +10,7 @@ export interface UserPillProps extends HTMLAttributes<HTMLDivElement> {
|
|||
|
||||
export const UserPill = forwardRef<HTMLDivElement, UserPillProps>(
|
||||
({ userId: id, username, className, ...rest }, ref) => {
|
||||
const classes = classNames(
|
||||
const classes = clsx(
|
||||
'flex items-center px-2 py-1 transition rounded-full shadow-lg cursor-pointer select-none align-center bg-dark-600 hover:bg-dark-900 hover:text-white',
|
||||
className
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Container, Spinner } from '@ryanke/pandora';
|
||||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import { Fragment, useState } from 'react';
|
||||
import { Download } from 'react-feather';
|
||||
import { Section } from '../../components/section';
|
||||
|
@ -93,7 +93,7 @@ export const ConfigGenerator = () => {
|
|||
<div className="grid grid-cols-2 md:grid-cols-3 gap-2 mt-2">
|
||||
{config.data.hosts.map((host) => {
|
||||
const isSelected = selectedHosts.includes(host.normalised);
|
||||
const classes = classNames(
|
||||
const classes = clsx(
|
||||
'rounded px-2 py-1 truncate transition border border-transparent',
|
||||
isSelected && 'bg-purple-600 text-white',
|
||||
!isSelected && 'text-gray-400 bg-dark-100 hover:bg-dark-200 hover:text-white'
|
||||
|
@ -124,7 +124,7 @@ export const ConfigGenerator = () => {
|
|||
<button
|
||||
type="submit"
|
||||
onClick={download}
|
||||
className={classNames(
|
||||
className={clsx(
|
||||
'mt-8 ml-auto flex items-center gap-1',
|
||||
downloadable ? 'text-purple-400 hover:underline' : 'text-gray-700 cursor-not-allowed'
|
||||
)}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import { memo } from 'react';
|
||||
import { Link } from '../../../components/link';
|
||||
import { Time } from '../../../components/time';
|
||||
|
@ -13,7 +13,7 @@ export const PasteCard = memo<PasteCardProps>(({ paste }) => {
|
|||
const user = useUser();
|
||||
const showUrl = !paste.encrypted && user.data;
|
||||
const url = showUrl ? (paste.burn ? `${paste.urls.view}?burn_unless=${user.data.id}` : paste.urls.view) : '#';
|
||||
const containerClasses = classNames(!showUrl && 'cursor-not-allowed');
|
||||
const containerClasses = clsx(!showUrl && 'cursor-not-allowed');
|
||||
const modifiers: string[] = [paste.type];
|
||||
if (paste.burn) modifiers.push('burn');
|
||||
if (paste.encrypted) modifiers.push('encrypted');
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useAsync } from '@ryanke/pandora';
|
||||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import { Form, Formik } from 'formik';
|
||||
import { useRouter } from 'next/router';
|
||||
import type { FC } from 'react';
|
||||
|
@ -59,7 +59,7 @@ export const LoginForm: FC = () => {
|
|||
login({ ...loginInfo, otp });
|
||||
}}
|
||||
/>
|
||||
<span className={classNames(`text-xs text-center`, invalidOTP ? 'text-red-400' : 'text-gray-600')}>
|
||||
<span className={clsx(`text-xs text-center`, invalidOTP ? 'text-red-400' : 'text-gray-600')}>
|
||||
{invalidOTP ? 'Invalid OTP code' : 'Enter the OTP code from your authenticator app'}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Button, ButtonStyle, Container, useAsync, useToasts } from '@ryanke/pandora';
|
||||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import { useRouter } from 'next/router';
|
||||
import { QRCodeSVG } from 'qrcode.react';
|
||||
import { Fragment, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
|
@ -146,7 +146,7 @@ export default function Generate() {
|
|||
type="button"
|
||||
onClick={() => setCurrentStep((prev) => prev - 1)}
|
||||
disabled={currentStep === 0}
|
||||
className={classNames(
|
||||
className={clsx(
|
||||
`text-gray-400 flex items-center gap-1 hover:underline`,
|
||||
currentStep === 0 && 'opacity-0 pointer-events-none'
|
||||
)}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Container, Spinner, useAsync, useToasts } from '@ryanke/pandora';
|
||||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import copyToClipboard from 'copy-to-clipboard';
|
||||
import type { GetServerSidePropsContext } from 'next';
|
||||
import { useRouter } from 'next/router';
|
||||
|
@ -20,7 +20,7 @@ const FileOption: FC<{ children: ReactNode; className?: string; onClick: () => v
|
|||
className,
|
||||
onClick,
|
||||
}) => {
|
||||
const classes = classNames(
|
||||
const classes = clsx(
|
||||
'flex items-center gap-2 shrink-0 transition-colors duration-100 hover:text-gray-300',
|
||||
className
|
||||
);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import classNames from 'classnames';
|
||||
import clsx from 'clsx';
|
||||
import { type FC, type ReactNode } from 'react';
|
||||
import { Info } from 'react-feather';
|
||||
|
||||
export const Warning: FC<{ children: ReactNode; className?: string }> = ({ children, className }) => {
|
||||
const classes = classNames(
|
||||
const classes = clsx(
|
||||
'bg-purple-400 bg-opacity-40 border border-purple-400 px-2 py-1 rounded text-sm flex items-center gap-2',
|
||||
className
|
||||
);
|
||||
|
|
|
@ -222,9 +222,6 @@ importers:
|
|||
autoprefixer:
|
||||
specifier: ^10.4.15
|
||||
version: 10.4.15(postcss@8.4.29)
|
||||
classnames:
|
||||
specifier: ^2.3.2
|
||||
version: 2.3.2
|
||||
clsx:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
|
@ -4766,10 +4763,6 @@ packages:
|
|||
validator: 13.9.0
|
||||
dev: false
|
||||
|
||||
/classnames@2.3.2:
|
||||
resolution: {integrity: sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==}
|
||||
dev: false
|
||||
|
||||
/clean-regexp@1.0.0:
|
||||
resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==}
|
||||
engines: {node: '>=4'}
|
||||
|
|
Loading…
Reference in New Issue