Primitive Components
Relevant source files
The following files were used as context for generating this wiki page:
Primitive components are the foundational, reusable UI building blocks of the Grapevine website. Located in the components/primitives/ directory, they provide a consistent and standardized set of elements for constructing more complex components and page layouts. These components are built using React with TypeScript and styled with Tailwind CSS.
The system leverages clsx and tailwind-merge (via a cn utility function) to enable robust and predictable style composition, allowing developers to combine base styles, variants, and custom classes without conflicts. The primitives cover layout, form elements, and interactive controls, ensuring a cohesive look and feel across the application.
Sources: README.md:29-32, components/contact-form.tsx:7
Core Concepts
Styling and Variants
Styling for primitive components heavily relies on a combination of Tailwind CSS and utility libraries. While the exact implementation of cva (class-variance-authority) is not present in the provided files, the pattern of defining variants (e.g., variant, size) is evident in components like Button. These variants are combined with custom className props using a cn utility function, which merges Tailwind classes intelligently.
The diagram below illustrates the flow of how styles are resolved for a primitive component.
This diagram shows how component props are used to resolve variants and combine them with custom classes, which are then processed by tailwind-merge to produce the final CSS class string.
Sources: components/contact-form.tsx:8, components/primitives/button.tsx
Layout Primitives
Layout primitives form the basic structure of pages. They manage spacing, width, and content flow.
Section
The Section component is a top-level container used to create distinct vertical blocks on a page. It controls the background color and vertical padding.
| Prop | Type | Description |
|---|---|---|
variant | 'white', 'light', 'navy' | Sets the background color of the section. |
spacing | 'sm', 'md', 'lg' | Defines the vertical padding (top and bottom) of the section. |
as | ElementType | The HTML tag to render, defaults to section. |
className | string | Additional CSS classes to apply. |
children | React.ReactNode | The content to be rendered inside the section. |
Sources: components/primitives/section.tsx, components/contact-form.tsx:142
Container
The Container component is typically nested inside a Section to provide a centered, max-width content area. It ensures that content is aligned and readable on large screens.
| Prop | Type | Description |
|---|---|---|
as | ElementType | The HTML tag to render, defaults to div. |
className | string | Additional CSS classes to apply. |
children | React.ReactNode | The content to be rendered inside the container. |
Sources: components/primitives/section.tsx, components/contact-form.tsx:143
The following diagram shows the typical nesting structure of layout components.
This shows a page using a Section to define a background and padding, with a Container inside to constrain the width of the main content.
Sources: app/contact/page.tsx:28, components/contact-form.tsx:142-143
Form Primitives
These components are used to build forms, such as the one for booking a discovery call. They include built-in support for displaying error states and helper text.
Sources: components/contact-form.tsx:7, 142-243
Input
A standard text input field that can be configured for various types like text, email, etc. It integrates error handling by changing its border color and displaying a helper message when the error prop is true.
| Prop | Type | Description |
|---|---|---|
type | string | The type attribute of the input element. |
error | boolean | If true, applies error styling. |
helperText | string | A message to display below the input, often for errors. |
...props | InputHTMLAttributes | Standard HTML input attributes. |
Sources: components/primitives/input.tsx, components/contact-form.tsx:162-168
Select
A wrapper around the native select element. It shares the same error handling and styling mechanism as the Input component.
| Prop | Type | Description |
|---|---|---|
error | boolean | If true, applies error styling. |
helperText | string | A message to display below the select, often for errors. |
...props | SelectHTMLAttributes | Standard HTML select attributes. |
Sources: components/contact-form.tsx:219-237
Textarea
A multi-line text input field. It also supports error styling and helper text, consistent with other form primitives.
| Prop | Type | Description |
|---|---|---|
rows | number | The visible number of text lines. |
error | boolean | If true, applies error styling. |
helperText | string | A message to display below the textarea. |
...props | TextareaHTMLAttributes | Standard HTML textarea attributes. |
Sources: components/contact-form.tsx:243-249
Form Interaction Flow
The contact-form.tsx component demonstrates how these primitives are used together with React state to handle user input, validation, and submission.
This sequence diagram illustrates how a user interaction with an Input primitive triggers a state update in the parent ContactForm component, which is later used for validation.
Sources: components/contact-form.tsx:106-112, 164
Interactive Primitives
Button
The Button component is a versatile, polymorphic control that can render as either a standard HTML <button> or a Next.js <Link> component. This is controlled by the as prop. It uses a variance-aware styling approach to support different visual treatments and sizes.
| Prop | Type | Description |
|---|---|---|
as | 'button', 'link' | Determines whether to render a <button> or a Next.js <Link>. Defaults to 'button'. |
href | string | The URL to navigate to when as is 'link'. |
variant | 'primary', 'secondary', 'ghost' | The visual style of the button. |
size | 'sm', 'md', 'lg' | The size of the button, affecting padding and font size. |
...props | ButtonHTMLAttributes or LinkProps | Other props are passed down to the underlying <button> or <Link> element. |
Sources: components/primitives/button.tsx
The following diagram shows the logic for rendering the Button component.
This demonstrates the polymorphic behavior of the Button component based on its as prop.
Sources: components/primitives/button.tsx
Summary
The primitive components in grapevine_website establish a robust and consistent design system foundation. By providing a set of pre-styled, reusable, and composable elements for layout, forms, and interactions, they accelerate development and ensure UI/UX consistency. The use of TypeScript, Tailwind CSS, and class-merging utilities makes them both flexible and type-safe, forming the essential toolkit for building any feature within the application.
Sources: README.md:29-32, components/contact-form.tsx