Skip to content

Commit

Permalink
feat: chip tabs brand weak
Browse files Browse the repository at this point in the history
  • Loading branch information
junghyeonsu committed Oct 4, 2024
1 parent 90b463b commit 08312c6
Show file tree
Hide file tree
Showing 27 changed files with 470 additions and 85 deletions.
19 changes: 13 additions & 6 deletions component-docs/public/mdx/component/chip-tabs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {
useLazyContents,
type UseLazyContentsProps,
} from "@seed-design/react-tabs";
import { chipTabs } from "@seed-design/recipe/chipTabs";
import { chipTab } from "@seed-design/recipe/chipTab";
import { chipTabs, ChipTabsVariant } from "@seed-design/recipe/chipTabs";
import { chipTab, ChipTabVariant } from "@seed-design/recipe/chipTab";

import "@seed-design/stylesheet/chipTab.css";
import "@seed-design/stylesheet/chipTabs.css";
Expand All @@ -23,6 +23,7 @@ interface ChipTabsContextValue {
api: ReturnType<typeof useTabs>;
classNames: ReturnType<typeof chipTabs>;
shouldRender: (value: string) => boolean;
variant: ChipTabsVariant["variant"];
}

const ChipTabsContext = React.createContext<ChipTabsContextValue | null>(null);
Expand All @@ -37,12 +38,15 @@ const useChipTabsContext = () => {

export interface ChipTabsProps
extends Assign<React.HTMLAttributes<HTMLDivElement>, Omit<UseTabsProps, "layout">>,
ChipTabsVariant,
Omit<UseLazyContentsProps, "currentValue"> {}

export const ChipTabs = React.forwardRef<HTMLDivElement, ChipTabsProps>((props, ref) => {
const { className, lazyMode, isLazy } = props;
const { className, lazyMode, isLazy, variant } = props;
const api = useTabs(props);
const classNames = chipTabs();
const classNames = chipTabs({
variant,
});
const { rootProps, value, restProps } = api;
const { shouldRender } = useLazyContents({ currentValue: value, lazyMode, isLazy });

Expand All @@ -53,6 +57,7 @@ export const ChipTabs = React.forwardRef<HTMLDivElement, ChipTabsProps>((props,
api,
classNames,
shouldRender,
variant,
}}
>
{props.children}
Expand Down Expand Up @@ -102,9 +107,11 @@ export interface ChipTabTriggerProps

export const ChipTabTrigger = React.forwardRef<HTMLButtonElement, ChipTabTriggerProps>(
({ className, children, value, ...otherProps }, ref) => {
const { api } = useChipTabsContext();
const { api, variant } = useChipTabsContext();
const { getTabTriggerProps } = api;
const { label, root } = chipTab();
const { label, root } = chipTab({
variant,
});
const { rootProps, labelProps } = getTabTriggerProps({ value });

return (
Expand Down
7 changes: 6 additions & 1 deletion component-docs/public/mdx/react/chip-tabs-preview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ export default function ChipTabsPreview() {
const [value, setValue] = React.useState("1");
return (
<>
<ChipTabs defaultValue="1" value={value} onValueChange={(value) => setValue(value)}>
<ChipTabs
variant="neutralSolid"
defaultValue="1"
value={value}
onValueChange={(value) => setValue(value)}
>
<ChipTabTriggerList>
<ChipTabTrigger value="1">라벨1</ChipTabTrigger>
<ChipTabTrigger value="2">라벨2</ChipTabTrigger>
Expand Down
28 changes: 28 additions & 0 deletions component-docs/public/mdx/react/chip-tabs-variant-brand-weak.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
```tsx copy
import * as React from "react";
import { ChipTabs, ChipTabTrigger, ChipTabTriggerList } from "seed-design/ui/chip-tabs";

export default function ChipTabsVariantBrandWeak() {
const [value, setValue] = React.useState("1");
return (
<>
<ChipTabs
variant="brandWeak"
defaultValue="1"
value={value}
onValueChange={(value) => setValue(value)}
>
<ChipTabTriggerList>
<ChipTabTrigger value="1">라벨1</ChipTabTrigger>
<ChipTabTrigger value="2">라벨2</ChipTabTrigger>
<ChipTabTrigger value="3">라벨3</ChipTabTrigger>
</ChipTabTriggerList>
</ChipTabs>
{value === "1" && <div>content 1</div>}
{value === "2" && <div>content 2</div>}
{value === "3" && <div>content 3</div>}
</>
);
}

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
```tsx copy
import * as React from "react";
import { ChipTabs, ChipTabTrigger, ChipTabTriggerList } from "seed-design/ui/chip-tabs";

export default function ChipTabsVariantNeutralSolid() {
const [value, setValue] = React.useState("1");
return (
<>
<ChipTabs
variant="neutralSolid"
defaultValue="1"
value={value}
onValueChange={(value) => setValue(value)}
>
<ChipTabTriggerList>
<ChipTabTrigger value="1">라벨1</ChipTabTrigger>
<ChipTabTrigger value="2">라벨2</ChipTabTrigger>
<ChipTabTrigger value="3">라벨3</ChipTabTrigger>
</ChipTabTriggerList>
</ChipTabs>
{value === "1" && <div>content 1</div>}
{value === "2" && <div>content 2</div>}
{value === "3" && <div>content 3</div>}
</>
);
}

```
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ const ChipTabsBasicActivity: ActivityComponentType<"ChipTabsBasic"> = () => {

return (
<AppScreen>
<ChipTabs defaultValue="1" value={value} onValueChange={(value) => setValue(value)}>
<ChipTabs
variant="neutralSolid"
defaultValue="1"
value={value}
onValueChange={(value) => setValue(value)}
>
<ChipTabTriggerList>
<ChipTabTrigger value="1">라벨1</ChipTabTrigger>
<ChipTabTrigger value="2">라벨2</ChipTabTrigger>
Expand Down
2 changes: 1 addition & 1 deletion component-docs/public/registry/component/chip-tabs.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"registries": [
{
"name": "chip-tabs.tsx",
"content": "\"use client\";\n\nimport clsx from \"clsx\";\nimport * as React from \"react\";\nimport {\n useTabs,\n type UseTabsProps,\n type TriggerProps,\n type ContentProps,\n useLazyContents,\n type UseLazyContentsProps,\n} from \"@seed-design/react-tabs\";\nimport { chipTabs } from \"@seed-design/recipe/chipTabs\";\nimport { chipTab } from \"@seed-design/recipe/chipTab\";\n\nimport \"@seed-design/stylesheet/chipTab.css\";\nimport \"@seed-design/stylesheet/chipTabs.css\";\n\ntype Assign<T, U> = Omit<T, keyof U> & U;\n\ninterface ChipTabsContextValue {\n api: ReturnType<typeof useTabs>;\n classNames: ReturnType<typeof chipTabs>;\n shouldRender: (value: string) => boolean;\n}\n\nconst ChipTabsContext = React.createContext<ChipTabsContextValue | null>(null);\n\nconst useChipTabsContext = () => {\n const context = React.useContext(ChipTabsContext);\n if (!context) {\n throw new Error(\"Tabs cannot be rendered outside the Tabs\");\n }\n return context;\n};\n\nexport interface ChipTabsProps\n extends Assign<React.HTMLAttributes<HTMLDivElement>, Omit<UseTabsProps, \"layout\">>,\n Omit<UseLazyContentsProps, \"currentValue\"> {}\n\nexport const ChipTabs = React.forwardRef<HTMLDivElement, ChipTabsProps>((props, ref) => {\n const { className, lazyMode, isLazy } = props;\n const api = useTabs(props);\n const classNames = chipTabs();\n const { rootProps, value, restProps } = api;\n const { shouldRender } = useLazyContents({ currentValue: value, lazyMode, isLazy });\n\n return (\n <div ref={ref} {...rootProps} {...restProps} className={clsx(classNames.root, className)}>\n <ChipTabsContext.Provider\n value={{\n api,\n classNames,\n shouldRender,\n }}\n >\n {props.children}\n </ChipTabsContext.Provider>\n </div>\n );\n});\nChipTabs.displayName = \"ChipTabs\";\n\nexport const ChipTabTriggerList = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, children, ...otherProps }, ref) => {\n const { api, classNames } = useChipTabsContext();\n const { tabTriggerListProps, triggerSize } = api;\n const { left } = triggerSize;\n const { triggerList } = classNames;\n\n const containerRef = React.useRef<HTMLDivElement>(null);\n React.useImperativeHandle(ref, () => containerRef.current as HTMLDivElement);\n\n React.useEffect(() => {\n if (containerRef.current) {\n containerRef.current?.scrollTo({\n // NOTE: 27px is half of tab's min-width\n left: left - 27,\n behavior: \"smooth\",\n });\n }\n }, [left]);\n\n return (\n <div\n ref={containerRef}\n {...tabTriggerListProps}\n className={clsx(triggerList, className)}\n {...otherProps}\n >\n {children}\n </div>\n );\n});\nChipTabTriggerList.displayName = \"ChipTabTriggerList\";\n\nexport interface ChipTabTriggerProps\n extends Assign<React.HTMLAttributes<HTMLButtonElement>, Omit<TriggerProps, \"isDisabled\">> {}\n\nexport const ChipTabTrigger = React.forwardRef<HTMLButtonElement, ChipTabTriggerProps>(\n ({ className, children, value, ...otherProps }, ref) => {\n const { api } = useChipTabsContext();\n const { getTabTriggerProps } = api;\n const { label, root } = chipTab();\n const { rootProps, labelProps } = getTabTriggerProps({ value });\n\n return (\n <button ref={ref} {...rootProps} className={clsx(root, className)} {...otherProps}>\n <span className={label} {...labelProps}>\n {children}\n </span>\n </button>\n );\n },\n);\nChipTabTrigger.displayName = \"ChipTabTrigger\";\n\nexport const ChipTabContent = React.forwardRef<\n HTMLDivElement,\n Assign<React.HTMLAttributes<HTMLDivElement>, ContentProps>\n>(({ className, children, value, ...otherProps }, ref) => {\n const { api, classNames, shouldRender } = useChipTabsContext();\n const { getTabContentProps } = api;\n const { content } = classNames;\n const tabContentProps = getTabContentProps({ value });\n const isRender = shouldRender(value);\n\n return (\n <div ref={ref} {...tabContentProps} className={clsx(content, className)} {...otherProps}>\n {isRender && children}\n </div>\n );\n});\nChipTabContent.displayName = \"ChipTabContent\";\n"
"content": "\"use client\";\n\nimport clsx from \"clsx\";\nimport * as React from \"react\";\nimport {\n useTabs,\n type UseTabsProps,\n type TriggerProps,\n type ContentProps,\n useLazyContents,\n type UseLazyContentsProps,\n} from \"@seed-design/react-tabs\";\nimport { chipTabs, ChipTabsVariant } from \"@seed-design/recipe/chipTabs\";\nimport { chipTab, ChipTabVariant } from \"@seed-design/recipe/chipTab\";\n\nimport \"@seed-design/stylesheet/chipTab.css\";\nimport \"@seed-design/stylesheet/chipTabs.css\";\n\ntype Assign<T, U> = Omit<T, keyof U> & U;\n\ninterface ChipTabsContextValue {\n api: ReturnType<typeof useTabs>;\n classNames: ReturnType<typeof chipTabs>;\n shouldRender: (value: string) => boolean;\n variant: ChipTabsVariant[\"variant\"];\n}\n\nconst ChipTabsContext = React.createContext<ChipTabsContextValue | null>(null);\n\nconst useChipTabsContext = () => {\n const context = React.useContext(ChipTabsContext);\n if (!context) {\n throw new Error(\"Tabs cannot be rendered outside the Tabs\");\n }\n return context;\n};\n\nexport interface ChipTabsProps\n extends Assign<React.HTMLAttributes<HTMLDivElement>, Omit<UseTabsProps, \"layout\">>,\n ChipTabsVariant,\n Omit<UseLazyContentsProps, \"currentValue\"> {}\n\nexport const ChipTabs = React.forwardRef<HTMLDivElement, ChipTabsProps>((props, ref) => {\n const { className, lazyMode, isLazy, variant } = props;\n const api = useTabs(props);\n const classNames = chipTabs({\n variant,\n });\n const { rootProps, value, restProps } = api;\n const { shouldRender } = useLazyContents({ currentValue: value, lazyMode, isLazy });\n\n return (\n <div ref={ref} {...rootProps} {...restProps} className={clsx(classNames.root, className)}>\n <ChipTabsContext.Provider\n value={{\n api,\n classNames,\n shouldRender,\n variant,\n }}\n >\n {props.children}\n </ChipTabsContext.Provider>\n </div>\n );\n});\nChipTabs.displayName = \"ChipTabs\";\n\nexport const ChipTabTriggerList = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, children, ...otherProps }, ref) => {\n const { api, classNames } = useChipTabsContext();\n const { tabTriggerListProps, triggerSize } = api;\n const { left } = triggerSize;\n const { triggerList } = classNames;\n\n const containerRef = React.useRef<HTMLDivElement>(null);\n React.useImperativeHandle(ref, () => containerRef.current as HTMLDivElement);\n\n React.useEffect(() => {\n if (containerRef.current) {\n containerRef.current?.scrollTo({\n // NOTE: 27px is half of tab's min-width\n left: left - 27,\n behavior: \"smooth\",\n });\n }\n }, [left]);\n\n return (\n <div\n ref={containerRef}\n {...tabTriggerListProps}\n className={clsx(triggerList, className)}\n {...otherProps}\n >\n {children}\n </div>\n );\n});\nChipTabTriggerList.displayName = \"ChipTabTriggerList\";\n\nexport interface ChipTabTriggerProps\n extends Assign<React.HTMLAttributes<HTMLButtonElement>, Omit<TriggerProps, \"isDisabled\">> {}\n\nexport const ChipTabTrigger = React.forwardRef<HTMLButtonElement, ChipTabTriggerProps>(\n ({ className, children, value, ...otherProps }, ref) => {\n const { api, variant } = useChipTabsContext();\n const { getTabTriggerProps } = api;\n const { label, root } = chipTab({\n variant,\n });\n const { rootProps, labelProps } = getTabTriggerProps({ value });\n\n return (\n <button ref={ref} {...rootProps} className={clsx(root, className)} {...otherProps}>\n <span className={label} {...labelProps}>\n {children}\n </span>\n </button>\n );\n },\n);\nChipTabTrigger.displayName = \"ChipTabTrigger\";\n\nexport const ChipTabContent = React.forwardRef<\n HTMLDivElement,\n Assign<React.HTMLAttributes<HTMLDivElement>, ContentProps>\n>(({ className, children, value, ...otherProps }, ref) => {\n const { api, classNames, shouldRender } = useChipTabsContext();\n const { getTabContentProps } = api;\n const { content } = classNames;\n const tabContentProps = getTabContentProps({ value });\n const isRender = shouldRender(value);\n\n return (\n <div ref={ref} {...tabContentProps} className={clsx(content, className)} {...otherProps}>\n {isRender && children}\n </div>\n );\n});\nChipTabContent.displayName = \"ChipTabContent\";\n"
}
],
"type": "component"
Expand Down
30 changes: 17 additions & 13 deletions component-docs/seed-design/ui/chip-tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
import {
useLazyContents,
useTabs,
type ContentProps,
type TriggerProps,
type UseLazyContentsProps,
type UseTabsProps,
type ContentProps,
} from "@seed-design/react-tabs";
import { chipTab } from "@seed-design/recipe/chipTab";
import { chipTabs } from "@seed-design/recipe/chipTabs";
import { ChipTabsVariant, chipTabs } from "@seed-design/recipe/chipTabs";
import clsx from "clsx";
import * as React from "react";

Expand All @@ -22,6 +22,7 @@ interface ChipTabsContextValue {
api: ReturnType<typeof useTabs>;
classNames: ReturnType<typeof chipTabs>;
shouldRender: (value: string) => boolean;
variant: ChipTabsVariant["variant"];
}

const ChipTabsContext = React.createContext<ChipTabsContextValue | null>(null);
Expand All @@ -36,12 +37,15 @@ const useChipTabsContext = () => {

export interface ChipTabsProps
extends Assign<React.HTMLAttributes<HTMLDivElement>, Omit<UseTabsProps, "layout">>,
ChipTabsVariant,
Omit<UseLazyContentsProps, "currentValue"> {}

export const ChipTabs = React.forwardRef<HTMLDivElement, ChipTabsProps>((props, ref) => {
const { className, lazyMode, isLazy } = props;
const { className, lazyMode, isLazy, variant } = props;
const api = useTabs(props);
const classNames = chipTabs();
const classNames = chipTabs({
variant,
});
const { rootProps, value, restProps } = api;
const { shouldRender } = useLazyContents({ currentValue: value, lazyMode, isLazy });

Expand All @@ -52,6 +56,7 @@ export const ChipTabs = React.forwardRef<HTMLDivElement, ChipTabsProps>((props,
api,
classNames,
shouldRender,
variant,
}}
>
{props.children}
Expand Down Expand Up @@ -97,14 +102,16 @@ export const ChipTabTriggerList = React.forwardRef<
ChipTabTriggerList.displayName = "ChipTabTriggerList";

export interface ChipTabTriggerProps
extends Assign<React.HTMLAttributes<HTMLButtonElement>, TriggerProps> {}
extends Assign<React.HTMLAttributes<HTMLButtonElement>, Omit<TriggerProps, "isDisabled">> {}

export const ChipTabTrigger = React.forwardRef<HTMLButtonElement, ChipTabTriggerProps>(
({ className, children, value, isDisabled, ...otherProps }, ref) => {
const { api } = useChipTabsContext();
({ className, children, value, ...otherProps }, ref) => {
const { api, variant } = useChipTabsContext();
const { getTabTriggerProps } = api;
const { label, root } = chipTab();
const { rootProps, labelProps } = getTabTriggerProps({ value, isDisabled });
const { label, root } = chipTab({
variant,
});
const { rootProps, labelProps } = getTabTriggerProps({ value });

return (
<button ref={ref} {...rootProps} className={clsx(root, className)} {...otherProps}>
Expand All @@ -124,10 +131,7 @@ export const ChipTabContent = React.forwardRef<
const { api, classNames, shouldRender } = useChipTabsContext();
const { getTabContentProps } = api;
const { content } = classNames;
const tabContentProps = getTabContentProps({
value,
visibilityMode: "hidden",
});
const tabContentProps = getTabContentProps({ value });
const isRender = shouldRender(value);

return (
Expand Down
19 changes: 13 additions & 6 deletions component-docs/snippets/component/chip-tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
useLazyContents,
type UseLazyContentsProps,
} from "@seed-design/react-tabs";
import { chipTabs } from "@seed-design/recipe/chipTabs";
import { chipTab } from "@seed-design/recipe/chipTab";
import { chipTabs, ChipTabsVariant } from "@seed-design/recipe/chipTabs";
import { chipTab, ChipTabVariant } from "@seed-design/recipe/chipTab";

import "@seed-design/stylesheet/chipTab.css";
import "@seed-design/stylesheet/chipTabs.css";
Expand All @@ -22,6 +22,7 @@ interface ChipTabsContextValue {
api: ReturnType<typeof useTabs>;
classNames: ReturnType<typeof chipTabs>;
shouldRender: (value: string) => boolean;
variant: ChipTabsVariant["variant"];
}

const ChipTabsContext = React.createContext<ChipTabsContextValue | null>(null);
Expand All @@ -36,12 +37,15 @@ const useChipTabsContext = () => {

export interface ChipTabsProps
extends Assign<React.HTMLAttributes<HTMLDivElement>, Omit<UseTabsProps, "layout">>,
ChipTabsVariant,
Omit<UseLazyContentsProps, "currentValue"> {}

export const ChipTabs = React.forwardRef<HTMLDivElement, ChipTabsProps>((props, ref) => {
const { className, lazyMode, isLazy } = props;
const { className, lazyMode, isLazy, variant } = props;
const api = useTabs(props);
const classNames = chipTabs();
const classNames = chipTabs({
variant,
});
const { rootProps, value, restProps } = api;
const { shouldRender } = useLazyContents({ currentValue: value, lazyMode, isLazy });

Expand All @@ -52,6 +56,7 @@ export const ChipTabs = React.forwardRef<HTMLDivElement, ChipTabsProps>((props,
api,
classNames,
shouldRender,
variant,
}}
>
{props.children}
Expand Down Expand Up @@ -101,9 +106,11 @@ export interface ChipTabTriggerProps

export const ChipTabTrigger = React.forwardRef<HTMLButtonElement, ChipTabTriggerProps>(
({ className, children, value, ...otherProps }, ref) => {
const { api } = useChipTabsContext();
const { api, variant } = useChipTabsContext();
const { getTabTriggerProps } = api;
const { label, root } = chipTab();
const { label, root } = chipTab({
variant,
});
const { rootProps, labelProps } = getTabTriggerProps({ value });

return (
Expand Down
7 changes: 6 additions & 1 deletion component-docs/snippets/example/react/chip-tabs-preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ export default function ChipTabsPreview() {
const [value, setValue] = React.useState("1");
return (
<>
<ChipTabs defaultValue="1" value={value} onValueChange={(value) => setValue(value)}>
<ChipTabs
variant="neutralSolid"
defaultValue="1"
value={value}
onValueChange={(value) => setValue(value)}
>
<ChipTabTriggerList>
<ChipTabTrigger value="1">라벨1</ChipTabTrigger>
<ChipTabTrigger value="2">라벨2</ChipTabTrigger>
Expand Down
Loading

0 comments on commit 08312c6

Please sign in to comment.