fix(ui): add asChild support to Button and update theme styles
This commit is contained in:
parent
6a0fcf5343
commit
a96222cc28
186
src/App.css
186
src/App.css
@ -1,186 +0,0 @@
|
||||
.counter {
|
||||
font-size: 16px;
|
||||
padding: 5px 10px;
|
||||
border-radius: 5px;
|
||||
color: var(--accent);
|
||||
background: var(--accent-bg);
|
||||
border: 2px solid transparent;
|
||||
transition: border-color 0.3s;
|
||||
margin-bottom: 24px;
|
||||
|
||||
&:hover {
|
||||
border-color: var(--accent-border);
|
||||
}
|
||||
&:focus-visible {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.hero {
|
||||
position: relative;
|
||||
|
||||
.base,
|
||||
.framework,
|
||||
.vite {
|
||||
inset-inline: 0;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.base {
|
||||
width: 170px;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.framework,
|
||||
.vite {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.framework {
|
||||
z-index: 1;
|
||||
top: 34px;
|
||||
height: 28px;
|
||||
transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg)
|
||||
scale(1.4);
|
||||
}
|
||||
|
||||
.vite {
|
||||
z-index: 0;
|
||||
top: 107px;
|
||||
height: 26px;
|
||||
width: auto;
|
||||
transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg)
|
||||
scale(0.8);
|
||||
}
|
||||
}
|
||||
|
||||
#center {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 25px;
|
||||
place-content: center;
|
||||
place-items: center;
|
||||
flex-grow: 1;
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
padding: 32px 20px 24px;
|
||||
gap: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
#next-steps {
|
||||
display: flex;
|
||||
border-top: 1px solid var(--border);
|
||||
text-align: left;
|
||||
|
||||
& > div {
|
||||
flex: 1 1 0;
|
||||
padding: 32px;
|
||||
@media (max-width: 1024px) {
|
||||
padding: 24px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-bottom: 16px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
#docs {
|
||||
border-right: 1px solid var(--border);
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
border-right: none;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
}
|
||||
|
||||
#next-steps ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin: 32px 0 0;
|
||||
|
||||
.logo {
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--text-h);
|
||||
font-size: 16px;
|
||||
border-radius: 6px;
|
||||
background: var(--social-bg);
|
||||
display: flex;
|
||||
padding: 6px 12px;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
text-decoration: none;
|
||||
transition: box-shadow 0.3s;
|
||||
|
||||
&:hover {
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
.button-icon {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
margin-top: 20px;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
|
||||
li {
|
||||
flex: 1 1 calc(50% - 8px);
|
||||
}
|
||||
|
||||
a {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#spacer {
|
||||
height: 88px;
|
||||
border-top: 1px solid var(--border);
|
||||
@media (max-width: 1024px) {
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
.ticks {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -4.5px;
|
||||
border: 5px solid transparent;
|
||||
}
|
||||
|
||||
&::before {
|
||||
left: 0;
|
||||
border-left-color: var(--border);
|
||||
}
|
||||
&::after {
|
||||
right: 0;
|
||||
border-right-color: var(--border);
|
||||
}
|
||||
}
|
||||
27
src/App.tsx
27
src/App.tsx
@ -1,4 +1,3 @@
|
||||
import './App.css'
|
||||
import { useEffect } from "react";
|
||||
import { Navigate, createBrowserRouter, useParams } from "react-router";
|
||||
import { RouterProvider } from "react-router/dom";
|
||||
@ -46,6 +45,11 @@ import SettingsAccessibilityPage from "@/page/settings/accessibility";
|
||||
import SettingsSecurityPage from "@/page/settings/security";
|
||||
import SettingsTokensPage from "@/page/settings/tokens";
|
||||
import SettingsSshKeysPage from "@/page/settings/ssh-keys";
|
||||
import LandingLayout from "@/page/landing/layout";
|
||||
import LandingHome from "@/page/landing/home";
|
||||
import FeaturesPage from "@/page/landing/features";
|
||||
import WorkflowPage from "@/page/landing/workflow";
|
||||
import PricingPage from "@/page/landing/pricing";
|
||||
|
||||
function WorkspaceCompatRedirect() {
|
||||
const { projectName = "" } = useParams();
|
||||
@ -65,8 +69,25 @@ function App() {
|
||||
element: <RootLayout />,
|
||||
children: [
|
||||
{
|
||||
path: "/",
|
||||
element: <Navigate replace to="/me" />,
|
||||
element: <LandingLayout />,
|
||||
children: [
|
||||
{
|
||||
index: true,
|
||||
element: <LandingHome />,
|
||||
},
|
||||
{
|
||||
path: "features",
|
||||
element: <FeaturesPage />,
|
||||
},
|
||||
{
|
||||
path: "workflow",
|
||||
element: <WorkflowPage />,
|
||||
},
|
||||
{
|
||||
path: "pricing",
|
||||
element: <PricingPage />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/workspace/:projectName/*",
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import React from "react"
|
||||
import { Button as ButtonPrimitive } from "@base-ui/react/button"
|
||||
import { cva, type VariantProps } from "class-variance-authority"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const buttonVariants = cva(
|
||||
"group/button inline-flex shrink-0 items-center justify-center rounded-xl border border-transparent bg-clip-padding text-[13px] font-semibold whitespace-nowrap transition-all outline-none select-none focus-visible:ring-2 focus-visible:ring-ring/30 active:not-aria-[haspopup]:scale-[0.97] disabled:pointer-events-none disabled:opacity-40 aria-invalid:border-destructive aria-invalid:ring-2 aria-invalid:ring-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 shadow-sm",
|
||||
"group/button inline-flex shrink-0 items-center justify-center rounded-xl border border-transparent bg-clip-padding text-[13px] font-semibold whitespace-nowrap transition-[background-color,border-color,color,box-shadow,transform] outline-none select-none focus-visible:ring-2 focus-visible:ring-ring/30 active:not-aria-[haspopup]:scale-[0.97] disabled:pointer-events-none disabled:opacity-40 aria-invalid:border-destructive aria-invalid:ring-2 aria-invalid:ring-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 shadow-sm",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
@ -42,14 +43,30 @@ function Button({
|
||||
className,
|
||||
variant = "default",
|
||||
size = "default",
|
||||
asChild,
|
||||
children,
|
||||
render,
|
||||
...props
|
||||
}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {
|
||||
}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants> & { asChild?: boolean }) {
|
||||
const classes = cn(buttonVariants({ variant, size, className }))
|
||||
|
||||
let finalRender = render
|
||||
let finalChildren = children
|
||||
|
||||
if (asChild && !finalRender) {
|
||||
finalRender = React.Children.only(children) as React.ReactElement
|
||||
finalChildren = undefined
|
||||
}
|
||||
|
||||
return (
|
||||
<ButtonPrimitive
|
||||
data-slot="button"
|
||||
className={cn(buttonVariants({ variant, size, className }))}
|
||||
render={finalRender}
|
||||
className={classes}
|
||||
{...props}
|
||||
/>
|
||||
>
|
||||
{finalChildren}
|
||||
</ButtonPrimitive>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
@import "tailwindcss";
|
||||
@plugin "@tailwindcss/typography";
|
||||
@import "tw-animate-css";
|
||||
@import "shadcn/tailwind.css";
|
||||
@import "@fontsource-variable/space-grotesk";
|
||||
@ -29,6 +30,12 @@
|
||||
--color-input: var(--input);
|
||||
--color-border: var(--border);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-success: var(--success);
|
||||
--color-success-foreground: var(--success-foreground);
|
||||
--color-warning: var(--warning);
|
||||
--color-warning-foreground: var(--warning-foreground);
|
||||
--color-info: var(--info);
|
||||
--color-info-foreground: var(--info-foreground);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
@ -68,6 +75,12 @@
|
||||
--accent: #f5f5f5;
|
||||
--accent-foreground: #111111;
|
||||
--destructive: #ef4444;
|
||||
--success: #16a34a;
|
||||
--success-foreground: #ffffff;
|
||||
--warning: #d97706;
|
||||
--warning-foreground: #ffffff;
|
||||
--info: #2563eb;
|
||||
--info-foreground: #ffffff;
|
||||
--border: #e8e8e8;
|
||||
--input: #e8e8e8;
|
||||
--ring: #111111;
|
||||
@ -103,6 +116,12 @@
|
||||
--accent: #1f2128;
|
||||
--accent-foreground: #ececf1;
|
||||
--destructive: #EF4444;
|
||||
--success: #22c55e;
|
||||
--success-foreground: #052e16;
|
||||
--warning: #f59e0b;
|
||||
--warning-foreground: #451a03;
|
||||
--info: #60a5fa;
|
||||
--info-foreground: #082f49;
|
||||
--border: rgba(255, 255, 255, 0.08);
|
||||
--input: rgba(255, 255, 255, 0.08);
|
||||
--ring: #5E6AD2;
|
||||
@ -120,12 +139,29 @@
|
||||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
}
|
||||
html {
|
||||
@apply font-sans;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground antialiased;
|
||||
font-feature-settings: "cv02", "cv03", "cv04", "cv11";
|
||||
}
|
||||
html {
|
||||
@apply font-sans;
|
||||
button,
|
||||
a,
|
||||
input,
|
||||
textarea,
|
||||
select {
|
||||
touch-action: manipulation;
|
||||
}
|
||||
h1,
|
||||
h2,
|
||||
h3 {
|
||||
text-wrap: balance;
|
||||
}
|
||||
p,
|
||||
li {
|
||||
text-wrap: pretty;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -348,6 +348,11 @@ export function applyTheme(preset: ThemePreset) {
|
||||
root.style.setProperty("--chart-4", preset.isDark ? "#6e7681" : "#374151");
|
||||
root.style.setProperty("--chart-5", preset.isDark ? "#4b5563" : "#1f2937");
|
||||
|
||||
root.style.setProperty("color-scheme", preset.isDark ? "dark" : "light");
|
||||
|
||||
const themeColorMeta = document.querySelector<HTMLMetaElement>('meta[name="theme-color"]');
|
||||
themeColorMeta?.setAttribute("content", c.background);
|
||||
|
||||
// Toggle dark class for any tailwind dark: variants still in use
|
||||
if (preset.isDark) {
|
||||
root.classList.add("dark");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user