Skip to content

Commit

Permalink
feat(divider): ✨ finish divider component
Browse files Browse the repository at this point in the history
  • Loading branch information
navin-moorthy committed Jun 16, 2022
1 parent bd7067b commit 64342e3
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 21 deletions.
31 changes: 23 additions & 8 deletions src/divider/Divider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,41 @@ import {
import { As, Props } from "ariakit-utils/types";

import { useTheme } from "../theme";
import { cx, RenderProp, runIfFn } from "../utils";
import { cx, RenderProp, runRenderFn } from "../utils";

export const useDivider = createHook<DividerOptions>(
({ label, orientation = "horizontal", ...props }) => {
({
orientation = "horizontal",
label,
labelPosition = "center",
...props
}) => {
const theme = useTheme("divider");
const className = cx(
theme.base,
orientation === "horizontal" ? theme.horizontal : theme.vertical,
theme.orientation[orientation],
props.className,
);
const labelClassName = theme.label;

props = useWrapElement(
props,
element => {
if (label) {
const labelClassName = cx(theme.label[orientation]?.[labelPosition]);

return (
<div className="relative h-full w-full">
{element}
<span className={labelClassName}>
{runIfFn(label as React.ReactNode, { orientation })}
{runRenderFn(label, { orientation, label, labelPosition })}
</span>
</div>
);
}

return element;
},
[label, labelClassName, orientation],
[label, orientation, labelPosition],
);

props = { ...props, className };
Expand All @@ -53,11 +59,20 @@ export const Divider = createComponent<DividerOptions>(props => {
return createElement("hr", htmlProps);
});

export type DividerOptions<T extends As = "hr"> = SeparatorOptions<T> & {
export type DividerState = {
orientation: SeparatorOptions["orientation"];
/**
* Provide a label to name the divider at the center to mark it as a section.
*/
label?: RenderProp<SeparatorOptions>;
label?: RenderProp<DividerState>;

/**
* Position of the given label.
*/
labelPosition?: "start" | "center" | "end";
};

export type DividerOptions<T extends As = "hr"> = SeparatorOptions<T> &
Partial<DividerState>;

export type DividerProps<T extends As = "hr"> = Props<DividerOptions<T>>;
14 changes: 14 additions & 0 deletions src/divider/__tests__/Divider.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { render } from "../../utils/testUtils";
import { Divider } from "../Divider";

describe("Divider", () => {
it("should render properly", () => {
const { asFragment } = render(
<div className="w-80">
<Divider />
</div>,
);

expect(asFragment()).toMatchSnapshot();
});
});
32 changes: 28 additions & 4 deletions src/divider/stories/DividerBasic.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ComponentMeta, ComponentStoryObj } from "@storybook/react";

import { createPreviewTabs } from "../../../.storybook/utils";
import { createControls, createPreviewTabs } from "../../../.storybook/utils";
import { Button } from "../../button";

import js from "./templates/DividerBasicJsx";
Expand All @@ -18,10 +18,34 @@ export default {
options: { showPanel: true },
preview: createPreviewTabs({ js, ts }),
},
argTypes: createControls("divider", {
ignore: ["wrapElement", "as", "ref"],
}),
} as Meta;

export const Default: Story = {};
export const Default: Story = {
args: { orientation: "horizontal", labelPosition: "center" },
};

export const LabelCenter: Story = {
...Default,
args: { ...Default.args, label: <Button variant="outline">Continue</Button> },
};

export const Label: Story = {
args: { label: <Button variant="outline">Continue</Button> },
export const LabelStart: Story = {
...Default,
args: {
...Default.args,
label: <Button variant="outline">Continue</Button>,
labelPosition: "start",
},
};

export const LabelEnd: Story = {
...Default,
args: {
...Default.args,
label: <Button variant="outline">Continue</Button>,
labelPosition: "end",
},
};
2 changes: 1 addition & 1 deletion src/divider/stories/DividerVertical.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export type DividerVerticalProps = DividerProps & {};
export const DividerVertical: React.FC<DividerVerticalProps> = props => {
return (
<div className="flex h-80 items-center justify-center">
<Divider orientation="vertical" {...props} />
<Divider {...props} />
</div>
);
};
Expand Down
32 changes: 28 additions & 4 deletions src/divider/stories/DividerVertical.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ComponentMeta, ComponentStoryObj } from "@storybook/react";

import { createPreviewTabs } from "../../../.storybook/utils";
import { createControls, createPreviewTabs } from "../../../.storybook/utils";
import { Button } from "../../button";

import js from "./templates/DividerVerticalJsx";
Expand All @@ -18,10 +18,34 @@ export default {
options: { showPanel: true },
preview: createPreviewTabs({ js, ts }),
},
argTypes: createControls("divider", {
ignore: ["wrapElement", "as", "ref"],
}),
} as Meta;

export const Default: Story = {};
export const Default: Story = {
args: { orientation: "vertical", labelPosition: "center" },
};

export const LabelCenter: Story = {
...Default,
args: { ...Default.args, label: <Button variant="outline">Continue</Button> },
};

export const Label: Story = {
args: { label: <Button variant="outline">Continue</Button> },
export const LabelStart: Story = {
...Default,
args: {
...Default.args,
label: <Button variant="outline">Continue</Button>,
labelPosition: "start",
},
};

export const LabelEnd: Story = {
...Default,
args: {
...Default.args,
label: <Button variant="outline">Continue</Button>,
labelPosition: "end",
},
};
21 changes: 17 additions & 4 deletions src/theme/defaultTheme/divider.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
export const divider = {
base: " border-grey-300",
horizontal: "w-full",
vertical: "border-l border-t-0 h-full",
label: "absolute -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2",
base: "border-gray-300",
orientation: {
horizontal: "w-full",
vertical: "border-l border-t-0 h-full",
},
label: {
horizontal: {
start: "absolute -translate-y-1/2 top-1/2 left-4",
center: "absolute -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2",
end: "absolute -translate-y-1/2 top-1/2 right-4",
},
vertical: {
start: "absolute -translate-x-1/2 left-1/2 top-4",
center: "absolute -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2",
end: "absolute -translate-x-1/2 left-1/2 bottom-4",
},
},
};

0 comments on commit 64342e3

Please sign in to comment.