Skip to content

Commit

Permalink
Merge pull request #7 from bleu-fi/joao/click-565-update-bleu-ui-tail…
Browse files Browse the repository at this point in the history
…wind-configuration

Joao/click 565 update bleu UI tailwind configuration
  • Loading branch information
devjoaov authored Jan 23, 2024
2 parents 0f86ef6 + 4454a5e commit 9c14986
Show file tree
Hide file tree
Showing 9 changed files with 155 additions and 59 deletions.
9 changes: 8 additions & 1 deletion src/components/DataTable/SWRDataTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from "@tanstack/react-table";
import { useNavigate } from "react-router-dom";
import useSWR from "swr";
import { CheckIcon, Cross2Icon } from "@radix-ui/react-icons";
import {
Badge,
Table,
Expand Down Expand Up @@ -57,7 +58,13 @@ const renderCell = ({ filters, column, row }) => {

switch (column.columnDef.type) {
case "text":
return <div>{value}</div>;
return <div className="max-w-[400px] truncate">{value}</div>;
case "boolean":
return value ? (
<CheckIcon className="size-4 bg-primary text-primary-foreground rounded-full" />
) : (
<Cross2Icon className="size-4 text-muted-foreground" />
);
case "badge":
// TODO: needs to be refactored
switch (value) {
Expand Down
161 changes: 122 additions & 39 deletions src/components/FormBuilder/fields/RadioGroupField.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import React from "react";
import { cva } from "class-variance-authority";
import { cn } from "@/lib/utils";
import {
FormControl,
FormDescription,
Expand All @@ -9,7 +11,7 @@ import {
} from "@/components/ui/Form";
import { Label } from "@/components/ui/Label";
import { RadioGroup, RadioGroupItem } from "@/components/ui/RadioGroup";

import { Button } from "@/components/ui/Button";
import { BaseField, withConditional } from "../fields";

export interface RadioGroupFieldProps extends BaseField {
Expand All @@ -23,56 +25,137 @@ export interface RadioGroupFieldProps extends BaseField {
}>;
}

export const RadioGroupField = withConditional<RadioGroupFieldProps>(
({ form, field }) => (
// TODO: handle this case
// const hasSections = field.sections.length > 0;
// if (!hasSections) return;
const radioGroupVariants = cva("w-full", {
variants: {
layout: {
stack: "flex flex-col justify-between items-start",
inline: "flex flex-row justify-start items-center space-x-4",
},
gap: {
small: "gap-1",
medium: "gap-2",
large: "gap-4",
},
},
defaultVariants: {
layout: "inline",
gap: "medium",
},
});

const RadioGroupWithoutSection = ({ form, field }) => {
const hasClearButton = field.show_clear_button;
const [selectedValue, setSelectedValue] = React.useState(
form.getValues(field.name)
);

React.useEffect(() => {
setSelectedValue(form.getValues(field.name));
}, [form, field.name]);

const handleChange = (value) => {
setSelectedValue(value);
form.setValue(field.name, value);
};

const clearSelection = () => {
setSelectedValue(null);
form.setValue(field.name, null);
};

return (
<FormField
control={form.control}
name={field.name}
rules={field.required ? { required: true } : undefined}
render={({ field: formField }) => (
<FormItem className="space-y-0">
rules={field.required ? { required: true } : {}}
render={() => (
<FormItem className="space-y-0 w-full">
<FormLabel>{field.label}</FormLabel>
<FormDescription className="">{field.description}</FormDescription>
<FormDescription>{field.description}</FormDescription>
<FormControl>
<RadioGroup
onValueChange={formField.onChange}
defaultValue={formField.value}
className="py-2"
onValueChange={handleChange}
value={selectedValue}
className={cn(radioGroupVariants(field), "py-2")}
>
<div className="grid grid-cols-2 gap-4">
{field.sections.map((section) => (
<div key={section.label} className="space-y-2">
<Label>{section.label}</Label>
<p className="text-muted-foreground text-sm">
{section.description}
</p>
<div className="flex flex-col gap-1 rounded-md border-red-800 p-2">
{section.options.map((option) => (
<FormItem
key={option.value}
className="flex items-center space-x-3 space-y-0"
>
<FormControl>
<RadioGroupItem value={option.value} />
</FormControl>
<FormLabel className="font-normal">
{option.label}
</FormLabel>
</FormItem>
))}
</div>
</div>
))}
</div>
{field.options.map((option, optionIdx) => (
<FormItem
// eslint-disable-next-line react/no-array-index-key
key={optionIdx}
className="flex items-center space-x-1 space-y-0"
>
<FormControl>
<RadioGroupItem value={option.value} />
</FormControl>
<FormLabel className="font-normal">{option.label}</FormLabel>
</FormItem>
))}
</RadioGroup>
</FormControl>
<FormMessage />

{hasClearButton && (
<Button type="button" onClick={clearSelection}>
Clear
</Button>
)}
</FormItem>
)}
/>
)
);
};

export const RadioGroupField = withConditional<RadioGroupFieldProps>(
({ form, field }) => {
const hasSections = field.sections?.length > 0;
if (!hasSections) return <RadioGroupWithoutSection {...{ form, field }} />;

return (
<FormField
control={form.control}
name={field.name}
rules={field.required ? { required: true } : undefined}
render={({ field: formField }) => (
<FormItem className="space-y-0">
<FormLabel>{field.label}</FormLabel>
<FormDescription className="">{field.description}</FormDescription>
<FormControl>
<RadioGroup
onValueChange={formField.onChange}
defaultValue={formField.value}
className="py-2"
>
<div className="grid grid-cols-2 gap-4">
{field.sections.map((section) => (
<div key={section.label} className="space-y-2">
<Label>{section.label}</Label>
<p className="text-muted-foreground text-sm">
{section.description}
</p>
<div className="flex flex-col gap-1 rounded-md border-red-800 p-2">
{section.options.map((option) => (
<FormItem
key={option.value}
className="flex items-center space-x-3 space-y-0"
>
<FormControl>
<RadioGroupItem value={option.value} />
</FormControl>
<FormLabel className="font-normal">
{option.label}
</FormLabel>
</FormItem>
))}
</div>
</div>
))}
</div>
</RadioGroup>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
);
}
);
11 changes: 11 additions & 0 deletions src/components/RailsApp/context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React, { createContext, useContext } from "react";

export const RailsAppContext = createContext("");

export const RailsAppProvider = ({ children, csrfToken }) => (
<RailsAppContext.Provider value={csrfToken}>
{children}
</RailsAppContext.Provider>
);

export const useRailsApp = () => useContext(RailsAppContext);
1 change: 1 addition & 0 deletions src/components/RailsApp/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./context";
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from "./ThemeToggle";
export * from "./DataTable";
export * from "./FormBuilder";
export * from "./ui";
export * from "./RailsApp";
21 changes: 8 additions & 13 deletions src/components/ui/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from "react-hook-form";
import { cn } from "@/lib/utils";
import { Label } from "@/components/ui/Label";
import { useRailsApp } from "@/components/RailsApp/context";

type FormFieldContextValue<
TFieldValues extends FieldValues = FieldValues,
Expand All @@ -25,17 +26,15 @@ const Form = ({
action,
method,
encType = "application/x-www-form-urlencoded",
csrfToken,
...props
}: React.ComponentProps<typeof FormProvider> & {
action: string;
children: React.ReactNode;
className?: string;
csrfToken?: string;
encType?: string;
method?: "post" | "get";
}) => {
// const csrfToken = ReactOnRails.authenticityToken();
const csrfToken = useRailsApp();

if (!csrfToken) {
throw new Error("Missing authenticity_token");
Expand All @@ -55,7 +54,6 @@ const Form = ({
</FormProvider>
);
};

const FormFieldContext = React.createContext<FormFieldContextValue>(
{} as FormFieldContextValue
);
Expand Down Expand Up @@ -112,15 +110,12 @@ const FormItemContext = React.createContext<FormItemContextValue>(
const FormItem = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => {
const id = React.useMemo(() => ({ id: React.useId() }), []);

return (
<FormItemContext.Provider value={id}>
<div ref={ref} className={cn("space-y-2", className)} {...props} />
</FormItemContext.Provider>
);
});
>(({ className, ...props }, ref) => (
// eslint-disable-next-line react/jsx-no-constructed-context-values
<FormItemContext.Provider value={{ id: React.useId() }}>
<div ref={ref} className={cn("space-y-2", className)} {...props} />
</FormItemContext.Provider>
));
FormItem.displayName = "FormItem";

const FormLabel = React.forwardRef<
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const TooltipContent = React.forwardRef<
ref={ref}
sideOffset={sideOffset}
className={cn(
"bleu-ui-z-50 bleu-ui-overflow-hidden bleu-ui-rounded-md bleu-ui-bg-primary bleu-ui-px-3 bleu-ui-py-1.5 bleu-ui-text-xs bleu-ui-text-primary-foreground bleu-ui-animate-in bleu-ui-fade-in-0 bleu-ui-zoom-in-95 data-[state=closed]:bleu-ui-animate-out data-[state=closed]:bleu-ui-fade-out-0 data-[state=closed]:bleu-ui-zoom-out-95 data-[side=bottom]:bleu-ui-slide-in-from-top-2 data-[side=left]:bleu-ui-slide-in-from-right-2 data-[side=right]:bleu-ui-slide-in-from-left-2 data-[side=top]:bleu-ui-slide-in-from-bottom-2",
"z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
{...props}
Expand Down
4 changes: 2 additions & 2 deletions src/tailwind.css
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@

@layer base {
* {
@apply bleu-ui-border-border;
@apply border-border;
}
body {
@apply bleu-ui-bg-background bleu-ui-text-foreground;
@apply bg-background text-foreground;
font-feature-settings:
"rlig" 1,
"calt" 1;
Expand Down
4 changes: 1 addition & 3 deletions tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
const { fontFamily } = require("tailwindcss/defaultTheme");

const CLASSES_PREFIX = "bleu-ui-";

/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ["class"],
prefix: CLASSES_PREFIX,
prefix: "",
// important: "#bleu-ui",
content: ["src/**/*.{ts,tsx}"],
corePlugins: {
Expand Down

0 comments on commit 9c14986

Please sign in to comment.