Стили попутного ветра не применяются к компонентам внутри Shadcn Sheet

При создании проекта в Nextjs 14 с использованием компонентов Tailwind и shadcn я столкнулся с неловкой проблемой, особенно с компонентом Sheet из shadcn, из-за которой невозможно стилизовать компоненты внутри него. Например, при установке цвета фона на Button в Form внутри компонента Sheet, фон Button становится полностью прозрачным/белым.

По сути, любой стиль Tailwind внутри Sheet игнорируется. Интересное поведение: если вы установите для bg-colorbutton цвет, например bg-yellow-300, button потеряет любой цвет и станет «скрытым», но если за пределами этого Sheet вы используете тот же цвет, цвет фона будет правильно применять к button. Очень странное поведение, как будто внутри Sheet свойство Tailwind не компилируется (?).

Кодекс Form

запись-form.tsx

import {useFieldArray, useForm} from "react-hook-form";
import {zodResolver} from "@hookform/resolvers/zod";
import {z} from "zod";
import {Form, FormControl, FormField, FormItem, FormLabel} from "@/components/ui/form";
import {Input} from "@/components/ui/input";
import {Button} from "@/components/ui/button";
import {Select} from "@/components/select";
import {Plus} from "lucide-react";


const dynamicFieldSchema = z.object({
    name: z.string(),
    type: z.string(),
})

const propertiesSchema = z.array(dynamicFieldSchema)

const formSchema = z.object({
    name: z.string(),
    url: z.string(),
    properties: propertiesSchema
})

type FormValues = z.input<typeof formSchema>
type Props = {
    id?: string;
    defaultValues?: FormValues;
    onSubmit: (values: FormValues) => void;
    onDelete?: () => void;
    disabled?: boolean;
}
export const EntryForm = (
    {
        id,
        defaultValues,
        onSubmit,
        onDelete,
        disabled
    }: Props
) => {
    const form = useForm<FormValues>({
        resolver: zodResolver(formSchema),
        defaultValues: {
            name: "",
            url: "",
            properties: []
        }
    })

    const {control, handleSubmit} = form
    const {fields, append, remove} = useFieldArray({
        control,
        name: "properties"
    })

    const typeOptions = [
        {label: "STRING", value: "string"},
        {label: "NUMBER", value: "number"},
        {label: "BOOLEAN", value: "boolean"},
        {label: "DOUBLE", value: "double"},
    ]

    const submit = (values: FormValues) => {
        console.info({values})
        onSubmit(values)
    }

    const handleDelete = () => {
        onDelete?.()
    }

    return (
        <Form {...form}>
            <form onSubmit = {form.handleSubmit(submit)} className = "space-y-4">
                <FormField
                    name = {"name"}
                    control = {form.control}
                    render = {({field}) => (
                        <FormItem>
                            <FormLabel>
                                Name of set
                            </FormLabel>
                            <FormControl>
                                <Input
                                    disabled = {disabled}
                                    placeholder = {"Posts..."}
                                    {...field}
                                />
                            </FormControl>
                        </FormItem>
                    )}
                />
                <FormField
                    name = {"url"}
                    control = {form.control}
                    render = {({field}) => (
                        <FormItem>
                            <FormLabel>
                                URL of set
                            </FormLabel>
                            <FormControl>
                                <Input
                                    disabled = {disabled}
                                    placeholder = {"https://myweb.com/user?=1/posts..."}
                                    {...field}
                                />
                            </FormControl>
                        </FormItem>
                    )}
                />
                {fields.map((item, index) => (
                    <div key = {item.id} className = "flex flex-col space-y-4">
                        <div className = "flex flex-row gap-x-2">
                            <FormField
                                name = {`properties.${index}.name`}
                                control = {form.control}
                                render = {({field}) => (
                                    <FormItem>
                                        <FormLabel>
                                            Name
                                        </FormLabel>
                                        <FormControl>
                                            <Input
                                                disabled = {disabled}
                                                placeholder = {"name"}
                                                {...field}
                                            />
                                        </FormControl>
                                    </FormItem>
                                )}
                            />
                            <FormField
                                name = {`properties.${index}.type`}
                                control = {form.control}
                                render = {({field}) => (
                                    <FormItem>
                                        <FormLabel>
                                            Type
                                        </FormLabel>
                                        <FormControl>
                                            <Select
                                                placeholder = {"STRING"}
                                                options = {typeOptions}
                                                disabled = {disabled}
                                                onCreate = {(name) => {
                                                    console.info("Creating", name)
                                                }}
                                                value = {field.value}
                                                onChange = {field.onChange}
                                            />
                                        </FormControl>
                                    </FormItem>
                                )}
                            />
                        </div>
                        <Button
                            type = {"button"}
                            onClick = {() => remove(index)}
                        >
                            Remove property
                        </Button>
                    </div>
                ))}
                {/* this className is not applied, not a single attribute */}
                <div className = "flex flex-col space-y-4 border-2 border-sky-700 rounded-md">
                    <p className = "text-sm font-medium">
                        Define your object response type
                    </p>
                    {/* this className is not applied, no way to set any styling to the button*/}
                    <Button
                        type = {"button"}
                        onClick = {() => append({name: "", type: ""})}
                        className = "w-fit bg-zinc-600"
                    >
                        <Plus className = "size-4 mr-2"/>
                        Add property
                    </Button>
                </div>
                <Button className = "w-full" disabled = {disabled}>
                    {id ? "Save changes" : "Create set"}
                </Button>
            </form>
        </Form>
    )
}

Кодекс Sheet

новый-запись-sheet.tsx

import {insertEntrySchema} from "@/db/schema";
import {z} from "zod";
import {useNewEntry} from "@/features/entry/hooks/use-new-entry";
import {useCreateEntry} from "@/features/entry/api/use-create-entry";
import {Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle} from "@/components/ui/sheet";
import {EntryForm} from "@/features/entry/components/entry-form";


const formSchema = insertEntrySchema.omit({
    userId: true
})
type FormValues = z.input<typeof formSchema>
export const NewEntrySheet = () => {
    const { isOpen, onClose } = useNewEntry()
    const mutation = useCreateEntry()

    const onSubmit = (values: FormValues) => {
        mutation.mutate(values, {
            onSuccess: () => {
                onClose();
            }
        })
    }

    return (
        <Sheet open = {isOpen} onOpenChange = {onClose}>
            <SheetContent className = "space-y-4">
                <SheetHeader>
                    <SheetTitle>
                        New Data Set
                    </SheetTitle>
                    <SheetDescription className = {"text-yellow-600"}>
                        Create a new data set to track your data and manage your data.
                    </SheetDescription>
                </SheetHeader>
                <EntryForm onSubmit = {onSubmit} disabled = {mutation.isPending}  />
            </SheetContent>
        </Sheet>
    )

}

Tailwind работает корректно в остальной части проекта, а в остальных компонентах shadcn стили можно применять к кнопкам за пределами Sheet.

Я пробовал:

  • Проверяю, правильный ли мой tailwind.config.ts.
  • Проверяю, правильный ли мой components.json.
  • Проверяю, правильный ли мой globals.css.

Любая помощь приветствуется, дайте мне знать, что еще мне следует приложить. Заранее спасибо.

Вы не поделились своим кодом внутри компонента листа!

Pinal Tilva 16.08.2024 06:29

@PinalTilva, мне очень жаль, вы правы, я указал неправильный код new-entry-form.tsx, теперь указан правильный код :D

MACROSystems 16.08.2024 10:24

Я только что попытался воспроизвести то же самое, запустив ваш код локально, но не смог найти ту же проблему. Не могли бы вы поделиться содержимым своего tailwind config file?

Pinal Tilva 18.08.2024 10:41

@PinalTilva действительно была проблема, я опубликовал ответ с решением... в любом случае спасибо!

MACROSystems 19.08.2024 14:36
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Решение найдено, и это была очень стандартная конфигурация.

Функционал приложения я разделил в папке features. Как вы понимаете, путь features не был включен в массив content объекта tailwind.config.ts.

добавление пути features к content файла tailwind.config.ts решило проблему.

Вот как это выглядит сейчас:

content: [
    './pages/**/*.{ts,tsx}',
    './components/**/*.{ts,tsx}',
    './app/**/*.{ts,tsx}',
    './features/**/*.{js,ts,jsx,tsx}'
  ]

Другие вопросы по теме