-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0726ea1
commit 6b3361c
Showing
4 changed files
with
248 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@codeui/kit": patch | ||
--- | ||
|
||
add text area |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { createTheme, style } from "@vanilla-extract/css"; | ||
import { themeTokens } from "../../foundation"; | ||
import { tokens } from "../../foundation/contract.css"; | ||
import { componentStateStyles } from "@kobalte/vanilla-extract"; | ||
|
||
export const [tabsTheme, tabsVars] = createTheme({ | ||
tabListIndicatorColor: tokens.accent5, | ||
tabHeaderHoverBackgroundColor: tokens.brandSecondaryAccentHover, | ||
tabHeaderHoverColor: tokens.accent7, | ||
tabHeaderSelectedColor: tokens.brandAccentActive, | ||
tabIndicatorColor: tokens.brandAccentActive, | ||
}); | ||
|
||
export const tabsList = style({ | ||
display: "flex", | ||
position: "relative", | ||
borderBottom: `1px solid ${tabsVars.tabListIndicatorColor}`, | ||
|
||
selectors: { | ||
"&[data-orientation=vertical]": { | ||
alignItems: "stretch", | ||
flexDirection: "column", | ||
}, | ||
}, | ||
}); | ||
|
||
export const tabsHeader = style([ | ||
{ | ||
display: "inline-block", | ||
position: "relative", | ||
outline: "none", | ||
padding: `${themeTokens.spacing["2"]} ${themeTokens.spacing["4"]}`, | ||
fontSize: themeTokens.fontSize.sm, | ||
fontWeight: themeTokens.fontWeight.semibold, | ||
transition: "color 250ms ease-in-out", | ||
":hover": { | ||
color: tabsVars.tabHeaderHoverColor, | ||
}, | ||
}, | ||
componentStateStyles({ | ||
selected: { | ||
color: tabsVars.tabHeaderSelectedColor, | ||
}, | ||
}), | ||
]); | ||
|
||
export const tabsContent = style({ | ||
padding: themeTokens.spacing["2"], | ||
}); | ||
|
||
export const indicator = style({ | ||
position: "absolute", | ||
transition: "all .25s", | ||
backgroundColor: tabsVars.tabIndicatorColor, | ||
selectors: { | ||
"&[data-orientation=horizontal]": { | ||
bottom: "-2px", | ||
height: "3px", | ||
}, | ||
"&[data-orientation=vertical]": { | ||
right: "-1px", | ||
width: "2px", | ||
}, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { Tabs as KTabs } from "@kobalte/core"; | ||
import { mergeClasses } from "../../utils/css"; | ||
import * as styles from "./Tabs.css"; | ||
import { createContext, Show, splitProps, useContext } from "solid-js"; | ||
|
||
type TabsProps = KTabs.TabsRootProps & { | ||
theme?: "inline" | "default"; | ||
}; | ||
|
||
const TabsContext = createContext<{ | ||
theme: TabsProps["theme"]; | ||
}>({ | ||
theme: "default", | ||
}); | ||
|
||
export function Tabs(props: TabsProps) { | ||
const [local, others] = splitProps(props, ["class", "theme"]); | ||
const classes = () => mergeClasses(styles.tabsTheme, local.class); | ||
|
||
return ( | ||
<TabsContext.Provider | ||
value={{ | ||
theme: local.theme, | ||
}} | ||
> | ||
<KTabs.Root | ||
data-cui={"tabs"} | ||
data-tabs-theme={local.theme} | ||
{...others} | ||
class={classes()} | ||
/> | ||
</TabsContext.Provider> | ||
); | ||
} | ||
|
||
type TabsListProps = KTabs.TabsListProps; | ||
|
||
export function TabsList(props: TabsListProps) { | ||
const context = useContext(TabsContext); | ||
const [local, others] = splitProps(props, ["class", "children"]); | ||
const classes = () => mergeClasses(styles.tabsList, local.class); | ||
|
||
return ( | ||
<KTabs.List {...others} class={classes()}> | ||
{local.children} | ||
<Show when={context.theme === "inline"}> | ||
<TabsIndicator /> | ||
</Show> | ||
</KTabs.List> | ||
); | ||
} | ||
|
||
type TabsTriggerProps = KTabs.TabsTriggerProps; | ||
|
||
export function TabsHeader(props: TabsTriggerProps) { | ||
const [local, others] = splitProps(props, ["class"]); | ||
const classes = () => mergeClasses(styles.tabsHeader, local.class); | ||
|
||
return <KTabs.Trigger {...others} class={classes()} />; | ||
} | ||
|
||
type TabsContentProps = KTabs.TabsContentProps; | ||
|
||
export function TabsContent(props: TabsContentProps) { | ||
const [local, others] = splitProps(props, ["class"]); | ||
const classes = () => mergeClasses(styles.tabsContent, local.class); | ||
|
||
return <KTabs.Content {...others} class={classes()} />; | ||
} | ||
|
||
type TabsIndicatorProps = KTabs.TabsIndicatorProps; | ||
|
||
export function TabsIndicator(props: TabsIndicatorProps) { | ||
const [local, others] = splitProps(props, ["class"]); | ||
return ( | ||
<KTabs.Indicator {...props} class={mergeClasses(styles.indicator, local.class)} /> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import { createSignal, For } from "solid-js"; | ||
import { Button, Tabs, TabsContent, TabsHeader, TabsList } from "@codeui/kit"; | ||
import { DemoSectionRow } from "~/components/ui/DemoSection"; | ||
|
||
export default function TabsDemo() { | ||
const [tabs, setTabs] = createSignal([ | ||
{ id: "1", title: "Tab 1", content: "Tab body 1" }, | ||
{ id: "2", title: "Tab 2", content: "Tab body 2" }, | ||
{ id: "3", title: "Tab 3", content: "Tab body 3" }, | ||
]); | ||
const addTab = () => { | ||
setTabs(prev => [ | ||
...prev, | ||
{ | ||
id: String(prev.length + 1), | ||
title: `Tab ${prev.length + 1}`, | ||
content: `Tab Body ${prev.length + 1}`, | ||
}, | ||
]); | ||
}; | ||
const removeTab = () => { | ||
if (tabs().length > 1) { | ||
setTabs(prev => prev.slice(0, -1)); | ||
} | ||
}; | ||
return ( | ||
<> | ||
<h1 class={"title"}>Tabs</h1> | ||
|
||
<div style={{ display: "flex", gap: "2rem" }}> | ||
<Button theme={"primary"} onClick={addTab}> | ||
Add tab | ||
</Button> | ||
<Button theme={"primary"} onClick={removeTab}> | ||
Remove tab | ||
</Button> | ||
</div> | ||
|
||
<h2>Dynamic default style</h2> | ||
|
||
<DemoSectionRow> | ||
<Tabs theme={"default"}> | ||
<TabsList> | ||
<For each={tabs()}> | ||
{tab => <TabsHeader value={tab.id}>{tab.title}</TabsHeader>} | ||
</For> | ||
</TabsList> | ||
<For each={tabs()}> | ||
{tab => <TabsContent value={tab.id}>{tab.content}</TabsContent>} | ||
</For> | ||
</Tabs> | ||
</DemoSectionRow> | ||
|
||
<h2>Dynamic default style - Vertical</h2> | ||
|
||
<DemoSectionRow> | ||
<Tabs theme={"default"} orientation={"vertical"}> | ||
<TabsList> | ||
<For each={tabs()}> | ||
{tab => <TabsHeader value={tab.id}>{tab.title}</TabsHeader>} | ||
</For> | ||
</TabsList> | ||
<For each={tabs()}> | ||
{tab => <TabsContent value={tab.id}>{tab.content}</TabsContent>} | ||
</For> | ||
</Tabs> | ||
</DemoSectionRow> | ||
|
||
<h2>Inline style</h2> | ||
|
||
<DemoSectionRow> | ||
<Tabs theme={"inline"}> | ||
<TabsList> | ||
<For each={tabs()}> | ||
{tab => <TabsHeader value={tab.id}>{tab.title}</TabsHeader>} | ||
</For> | ||
</TabsList> | ||
<For each={tabs()}> | ||
{tab => <TabsContent value={tab.id}>{tab.content}</TabsContent>} | ||
</For> | ||
</Tabs> | ||
</DemoSectionRow> | ||
|
||
<h2>Dynamic inline style - Vertical</h2> | ||
|
||
<DemoSectionRow> | ||
<Tabs theme={"inline"} orientation={"vertical"}> | ||
<TabsList> | ||
<For each={tabs()}> | ||
{tab => <TabsHeader value={tab.id}>{tab.title}</TabsHeader>} | ||
</For> | ||
</TabsList> | ||
<For each={tabs()}> | ||
{tab => <TabsContent value={tab.id}>{tab.content}</TabsContent>} | ||
</For> | ||
</Tabs> | ||
</DemoSectionRow> | ||
</> | ||
); | ||
} |