Skip to content

Commit 47c3bf4

Browse files
committed
Re-designed neobrutalism theme; Fixed shadows
1 parent 6cd3f29 commit 47c3bf4

File tree

10 files changed

+200
-81
lines changed

10 files changed

+200
-81
lines changed

apps/web/components/admin/page-editor/theme-editor/interactive-selector.tsx

Lines changed: 92 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
} from "@/components/ui/select";
99
import { Input } from "@/components/ui/input";
1010
import { Label } from "@/components/ui/label";
11-
import { cn } from "@/lib/shadcn-utils";
1211
import { Info } from "lucide-react";
1312
import { Border, ThemeStyle } from "@courselit/page-models";
1413
import {
@@ -25,6 +24,8 @@ import {
2524
PageCard,
2625
PageCardContent,
2726
PageCardHeader,
27+
Input as PageInput,
28+
Link as PageLink,
2829
} from "@courselit/page-primitives";
2930
import {
3031
Dialog,
@@ -72,9 +73,7 @@ function InteractiveSelector({
7273
<Label className="text-xs text-muted-foreground">
7374
Preview
7475
</Label>
75-
<a href="#" className={cn(value?.hover || "")}>
76-
Demo Link
77-
</a>
76+
<PageLink theme={theme}>Demo Link</PageLink>
7877
</div>
7978
);
8079
case "card":
@@ -99,17 +98,10 @@ function InteractiveSelector({
9998
<Label className="text-xs text-muted-foreground">
10099
Preview
101100
</Label>
102-
<Input
101+
<PageInput
102+
theme={theme}
103103
type="text"
104104
placeholder="Demo Input"
105-
className={cn(
106-
value?.padding?.x || "",
107-
value?.padding?.y || "",
108-
value?.borderRadius || "",
109-
value?.border?.style || "",
110-
value?.shadow || "",
111-
value?.hover || "",
112-
)}
113105
/>
114106
</div>
115107
);
@@ -549,12 +541,71 @@ function InteractiveSelector({
549541
</div>
550542
);
551543

544+
const renderBoxShadowConfig = () => (
545+
<div className="space-y-2">
546+
<div className="space-y-2">
547+
<Label>Shadow</Label>
548+
<Select
549+
value={value?.shadow || ""}
550+
onValueChange={(newValue) => {
551+
onChange({
552+
...theme,
553+
interactives: {
554+
...theme.interactives,
555+
[type]: {
556+
...value,
557+
shadow: newValue,
558+
},
559+
},
560+
});
561+
}}
562+
>
563+
<SelectTrigger>
564+
<SelectValue placeholder="Select shadow" />
565+
</SelectTrigger>
566+
<SelectContent>
567+
{shadowOptions.map((option) => (
568+
<SelectItem
569+
key={option.value}
570+
value={option.value}
571+
>
572+
{option.label}
573+
</SelectItem>
574+
))}
575+
</SelectContent>
576+
</Select>
577+
</div>
578+
{value?.shadow === "shadow-custom" && (
579+
<div className="space-y-2">
580+
<Label>Custom Shadow</Label>
581+
<Input
582+
value={value?.customShadow || ""}
583+
placeholder="0px 0px 0px 0px rgba(0, 0, 0, 0.1)"
584+
onChange={(e) =>
585+
onChange({
586+
...theme,
587+
interactives: {
588+
...theme.interactives,
589+
[type]: {
590+
...value,
591+
customShadow: e.target.value,
592+
},
593+
},
594+
})
595+
}
596+
/>
597+
</div>
598+
)}
599+
</div>
600+
);
601+
552602
switch (type) {
553603
case "button":
554604
return (
555605
<div className="space-y-6">
556606
{renderPaddingConfig()}
557607
{renderBorderConfig()}
608+
{renderBoxShadowConfig()}
558609
<div className="grid grid-cols-2 gap-4">
559610
<div className="space-y-2">
560611
<Label>Border Radius</Label>
@@ -602,7 +653,7 @@ function InteractiveSelector({
602653
...theme.interactives,
603654
[type]: {
604655
...value,
605-
shadow: newValue,
656+
shadow: newValue as ThemeStyle["interactives"]["button"]["shadow"],
606657
},
607658
},
608659
});
@@ -628,11 +679,36 @@ function InteractiveSelector({
628679
</div>
629680
);
630681
case "link":
631-
return <div className="space-y-6">{renderHoverInput()}</div>;
682+
return (
683+
<div className="space-y-6">
684+
{renderHoverInput()}
685+
<div className="space-y-2">
686+
<Label>Text Shadow</Label>
687+
<Input
688+
value={value?.textShadow || ""}
689+
placeholder="0px 0px 0px 0px rgba(0, 0, 0, 0.1)"
690+
onChange={(e) =>
691+
onChange({
692+
...theme,
693+
interactives: {
694+
...theme.interactives,
695+
[type]: {
696+
...value,
697+
textShadow: e.target
698+
.value as ThemeStyle["interactives"]["link"]["textShadow"],
699+
},
700+
},
701+
})
702+
}
703+
/>
704+
</div>
705+
</div>
706+
);
632707
case "card":
633708
return (
634709
<div className="space-y-6">
635710
{renderPaddingConfig()}
711+
{renderBoxShadowConfig()}
636712
<div className="grid grid-cols-2 gap-4">
637713
<div className="space-y-2">
638714
<Label>Border Radius</Label>
@@ -781,6 +857,7 @@ function InteractiveSelector({
781857
return (
782858
<div className="space-y-6">
783859
{renderPaddingConfig()}
860+
{renderBoxShadowConfig()}
784861
<div className="grid grid-cols-2 gap-4">
785862
<div className="space-y-2">
786863
<Label>Border Radius</Label>

apps/web/components/admin/page-editor/theme-editor/tailwind-to-human-readable.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,20 @@ export const shadowOptions: TailwindOption[] = [
7676
{ label: "Extra Large", value: "shadow-xl" },
7777
{ label: "2X Large", value: "shadow-2xl" },
7878
{ label: "Inner", value: "shadow-inner" },
79+
{ label: "Neo", value: "shadow-neo" },
80+
{ label: "Neo Small", value: "shadow-neo-sm" },
81+
{ label: "Neo Large", value: "shadow-neo-lg" },
82+
{ label: "Custom", value: "shadow-custom" },
83+
];
84+
85+
export const textShadowOptions: TailwindOption[] = [
86+
{ label: "None", value: "text-shadow-none" },
87+
{ label: "Extra Small", value: "text-shadow-2xs" },
88+
{ label: "Small", value: "text-shadow-xs" },
89+
{ label: "Default", value: "text-shadow-sm" },
90+
{ label: "Medium", value: "text-shadow-md" },
91+
{ label: "Large", value: "text-shadow-lg" },
92+
{ label: "Custom", value: "text-shadow-custom" },
7993
];
8094

8195
export const opacityOptions: TailwindOption[] = [

packages/page-models/src/theme-style.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ type Shadow =
6060
| "shadow-none"
6161
| "shadow-neo"
6262
| "shadow-neo-sm"
63-
| "shadow-neo-lg";
63+
| "shadow-neo-lg"
64+
| "shadow-custom";
6465
type Cursor = "cursor-not-allowed" | "cursor-default" | "cursor-pointer";
6566

6667
export interface Typography {
@@ -173,11 +174,12 @@ export interface ThemeStyle {
173174
shadow?: Shadow;
174175
hover?: HoverStyle;
175176
disabled?: DisabledStyle;
177+
customShadow?: string;
176178
};
177179
link: {
178180
padding?: Padding;
179181
border?: Border;
180-
shadow?: Shadow;
182+
textShadow?: string;
181183
hover?: HoverStyle;
182184
disabled?: DisabledStyle;
183185
};
@@ -186,6 +188,7 @@ export interface ThemeStyle {
186188
border?: Border;
187189
shadow?: Shadow;
188190
hover?: HoverStyle;
191+
customShadow?: string;
189192
};
190193
input: {
191194
borderRadius?: BorderRadius;
@@ -194,6 +197,7 @@ export interface ThemeStyle {
194197
shadow?: Shadow;
195198
hover?: HoverStyle;
196199
disabled?: DisabledStyle;
200+
customShadow?: string;
197201
};
198202
};
199203
structure: {

packages/page-primitives/src/button.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export const Button: React.FC<ButtonProps> = ({
4343
buttonStyles?.border?.radius,
4444
buttonStyles?.border?.style,
4545
// buttonStyles?.border?.color,
46-
buttonStyles?.shadow,
46+
buttonStyles?.shadow === "shadow-custom" ? "" : buttonStyles?.shadow,
4747
// Theme hover states
4848
buttonStyles?.hover,
4949
// Theme disabled states
@@ -67,6 +67,10 @@ export const Button: React.FC<ButtonProps> = ({
6767
style.backgroundColor || theme?.colors?.primary,
6868
color: style.color || theme?.colors?.buttonText,
6969
borderColor: theme?.colors?.border,
70+
boxShadow:
71+
buttonStyles?.shadow === "shadow-custom"
72+
? buttonStyles?.customShadow
73+
: undefined,
7074
}}
7175
{...props}
7276
>

packages/page-primitives/src/card.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,15 @@ export interface PageCardHeaderProps
3030
children: React.ReactNode;
3131
className?: string;
3232
theme?: ThemeStyle;
33+
style?: React.CSSProperties;
3334
}
3435

3536
export const PageCard: React.FC<PageCardProps> = ({
3637
isLink,
3738
children,
3839
className = "",
3940
theme,
41+
style,
4042
...props
4143
}) => {
4244
const cardStyles = theme?.interactives?.card;
@@ -47,7 +49,7 @@ export const PageCard: React.FC<PageCardProps> = ({
4749
cardStyles?.border?.width,
4850
cardStyles?.border?.radius,
4951
cardStyles?.border?.style,
50-
cardStyles?.shadow,
52+
cardStyles?.shadow === "shadow-custom" ? "" : cardStyles?.shadow,
5153
// Theme hover states
5254
isLink ? `cursor-pointer ${cardStyles?.hover}` : "",
5355
className,
@@ -56,8 +58,16 @@ export const PageCard: React.FC<PageCardProps> = ({
5658
return (
5759
<div
5860
style={{
59-
borderColor: theme?.colors?.border,
60-
backgroundColor: theme?.colors?.background || undefined,
61+
...style,
62+
borderColor: style?.borderColor || theme?.colors?.border,
63+
backgroundColor:
64+
style?.backgroundColor ||
65+
theme?.colors?.background ||
66+
undefined,
67+
boxShadow:
68+
cardStyles?.shadow === "shadow-custom"
69+
? cardStyles?.customShadow
70+
: undefined,
6171
}}
6272
className={classes}
6373
{...props}

packages/page-primitives/src/input.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(
3434
inputStyles?.border?.width,
3535
inputStyles?.border?.style,
3636
// inputStyles?.border?.color,
37-
inputStyles?.shadow,
37+
inputStyles?.shadow === "shadow-custom" ? "" : inputStyles?.shadow,
3838
// Theme hover states
3939
inputStyles?.hover,
4040
// Theme disabled states
@@ -55,6 +55,10 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(
5555
style={{
5656
...style,
5757
borderColor: theme?.colors?.border,
58+
boxShadow:
59+
inputStyles?.shadow === "shadow-custom"
60+
? inputStyles?.customShadow
61+
: undefined,
5862
}}
5963
{...props}
6064
/>

packages/page-primitives/src/link.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ export interface LinkProps
88
className?: string;
99
theme?: ThemeStyle;
1010
disabled?: boolean;
11+
style?: React.CSSProperties;
1112
}
1213

1314
export const Link: React.FC<LinkProps> = ({
1415
children,
1516
className = "",
1617
theme,
1718
disabled = false,
19+
style,
1820
...props
1921
}) => {
2022
const typographyStyles = theme?.typography?.link;
@@ -37,7 +39,6 @@ export const Link: React.FC<LinkProps> = ({
3739
linkStyles?.border?.width,
3840
linkStyles?.border?.radius,
3941
linkStyles?.border?.style,
40-
linkStyles?.shadow,
4142
// Theme hover states
4243
linkStyles?.hover,
4344
// Theme disabled states
@@ -50,7 +51,14 @@ export const Link: React.FC<LinkProps> = ({
5051
);
5152

5253
return (
53-
<span className={classes} {...props}>
54+
<span
55+
className={classes}
56+
style={{
57+
...style,
58+
textShadow: linkStyles?.textShadow || undefined,
59+
}}
60+
{...props}
61+
>
5462
{children}
5563
</span>
5664
);

0 commit comments

Comments
 (0)