Skip to content

Commit

Permalink
chore: progress with accordion
Browse files Browse the repository at this point in the history
  • Loading branch information
segunadebayo committed Jan 3, 2020
1 parent f027d2b commit 7b96a84
Show file tree
Hide file tree
Showing 23 changed files with 142 additions and 103 deletions.
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/indent": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/array-callback-return": "off",
"@typescript-eslint/array-type": "off",
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn"
Expand Down
2 changes: 1 addition & 1 deletion .storybook/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { configure } from "@storybook/react";
// ../packages/hooks/src/useCheckbox

const req = require.context(
"../packages/system/src/",
"../packages/core/src/",
true,
/.stories\.(ts|tsx)$/,
);
Expand Down
9 changes: 8 additions & 1 deletion packages/core/src/Accordion/Accordion.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,21 @@ import {
AccordionItem,
AccordionButton,
AccordionPanel,
AccordionIcon,
} from "./Accordion";
import { chakra } from "@chakra-ui/system";

const stories = storiesOf("Accordion", module).addDecorator(setup);

stories.add("default", () => (
<Accordion allowToggle>
<AccordionItem>
<AccordionButton>Toggle 1</AccordionButton>
<AccordionButton>
<chakra.div flex="1" textAlign="left">
Section 1 title
</chakra.div>
<AccordionIcon />
</AccordionButton>
<AccordionPanel>Panel 1</AccordionPanel>
</AccordionItem>

Expand Down
46 changes: 34 additions & 12 deletions packages/core/src/Accordion/Accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@ import {
useAccordionButton,
useAccordionPanel,
AccordionItemProviderProps,
useAccordionItemState,
} from "@chakra-ui/hooks";
import { createChakra, chakra, PropsOf } from "@chakra-ui/system";
import { Omit } from "@chakra-ui/utils";
import { Icon } from "../Icon";

const AccordionButton = createChakra("button", {
hook: useAccordionButton,
themeKey: "AccordionButton",
});

AccordionButton.defaultProps = {
sx: {
baseStyles: {
display: "flex",
alignItems: "center",
width: "100%",
Expand All @@ -27,20 +26,19 @@ AccordionButton.defaultProps = {
paddingX: 4,
paddingY: 2,
},
};
});

const AccordionPanel = createChakra("div", {
hook: useAccordionPanel,
themeKey: "AccordionPanel",
dataAttr: "accordion-panel",
baseStyles: {
paddingTop: 2,
paddingX: 4,
paddingBottom: 5,
},
});

AccordionPanel.defaultProps = {
paddingTop: 2,
paddingX: 4,
paddingBottom: 5,
};

export type AccordionItemProps = AccordionItemProviderProps &
Omit<PropsOf<typeof chakra.div>, "onChange">;

Expand All @@ -65,4 +63,28 @@ const AccordionItem = React.forwardRef(
),
);

export { Accordion, AccordionItem, AccordionPanel, AccordionButton };
const AccordionIcon = (props: PropsOf<typeof Icon>) => {
const { isOpen, isDisabled } = useAccordionItemState();
return (
<Icon
aria-hidden
focusable="false"
size="1.25em"
name="chevron-down"
opacity={isDisabled ? 0.4 : 1}
transform={isOpen ? "rotate(-180deg)" : undefined}
transition="transform 0.2s"
transformOrigin="center"
{...props}
/>
);
};

export {
Accordion,
useAccordionItemState,
AccordionItem,
AccordionIcon,
AccordionPanel,
AccordionButton,
};
1 change: 1 addition & 0 deletions packages/core/src/Accordion/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./Accordion";
14 changes: 6 additions & 8 deletions packages/core/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
{
"extends": "../../tsconfig-base.json",
"include": ["src", "types"],
"exclude": [
"**/*.spec.ts",
"**/*.spec.tsx",
"**/*.test.ts",
"**/*.test.tsx",
"**/*.stories.tsx",
"**/*/examples.tsx"
]
"exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.test.ts", "**/*.test.tsx"],
"compilerOptions": {
"noImplicitAny": true,
"rootDir": "./",
"typeRoots": ["../../node_modules/@types", "@types"]
}
}
20 changes: 8 additions & 12 deletions packages/hooks/src/useAccordion/useAccordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import {
composeEventHandlers,
createContext,
createOnKeyDown,
createHookContext,
} from "@chakra-ui/utils";
import constate from "constate";
import * as React from "react";
import useControllableProp from "../useControllableProp";
import {
Expand Down Expand Up @@ -229,19 +229,15 @@ export function useAccordionItem(props: AccordionItemProviderProps) {

// To manage communication between the accordion item's children,
// let's create a context and a hook to read from context
const [
AccordionItemProvider,
useAccordionItemContext,
useAccordionItemState,
] = constate(
const [AccordionItemProvider, useAccordionItemContext] = createHookContext(
useAccordionItem,
context => context,
context => ({
isOpen: context.isOpen,
onClose: context.onClose,
isDisabled: context.isDisabled,
}),
);

const useAccordionItemState = () => {
const { isOpen, onClose, isDisabled } = useAccordionItemContext();
return { isOpen, onClose, isDisabled };
};

export { AccordionItemProvider, useAccordionItemState };

//////////////////////////////////////////////////////////////////////
Expand Down
4 changes: 2 additions & 2 deletions packages/hooks/src/useModal/utils/ModalManager.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react";
import constate from "constate";
import { createHookContext } from "@chakra-ui/utils";

type ElementRef = React.RefObject<HTMLElement>;

Expand All @@ -23,6 +23,6 @@ function useModalManager() {
};
}

const [ModalManager, useManager] = constate(useModalManager);
const [ModalManager, useManager] = createHookContext(useModalManager);
export { useManager };
export default ModalManager;
11 changes: 7 additions & 4 deletions packages/hooks/src/useTabs/useTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
* - https://inclusive-components.design/tabbed-interfaces/
*/

import { composeEventHandlers, createOnKeyDown } from "@chakra-ui/utils";
import constate from "constate";
import {
composeEventHandlers,
createOnKeyDown,
createHookContext,
} from "@chakra-ui/utils";
import * as React from "react";
import useControllableProp from "../useControllableProp";
import useMergeRefs from "../useMergeRefs";
Expand Down Expand Up @@ -123,7 +126,7 @@ export function useTabs(props: UseTabsOptions) {

////////////////////////////////////////////////////////////////////////

const [TabsProvider, useTabsContext] = constate(useTabs);
const [TabsProvider, useTabsContext] = createHookContext(useTabs);
export { TabsProvider };

////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -225,7 +228,7 @@ export function useTabList(props: UseTabListOptions) {

// Enhance the children by passing some props to them
const children = React.Children.map(props.children, (child: any, index) => {
let isSelected = index === tabs.selectedIndex;
const isSelected = index === tabs.selectedIndex;

const onClick = () => {
tabs.onFocus(index);
Expand Down
2 changes: 1 addition & 1 deletion packages/system/src/chakra/stories/component.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from "react";
import { storiesOf } from "@storybook/react";
import { forwardRef } from "../../forward-ref";
import { forwardRef } from "@chakra-ui/system";
import chakra from "../chakra";
import { ChakraComponent, PropsOf } from "../types";
import setup from "./setup";
Expand Down
2 changes: 1 addition & 1 deletion packages/system/src/chakra/styled.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ThemeContext } from "@emotion/core";
import * as React from "react";
import { forwardRef, memo } from "../forward-ref";
import { isPropValid, jsx } from "../system";
import { As, ChakraComponent } from "./types";
import { isFunction, isString } from "@chakra-ui/utils";
import { forwardRef, memo } from "../forward-ref";

/**
* @desc Check if we should forward props
Expand Down
8 changes: 4 additions & 4 deletions packages/system/src/create-theme-context.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { ThemeContext } from "@emotion/core";
import * as React from "react";

function createThemeContext<T extends object>(theme: T) {
export function createThemeContext<T extends object>(theme: T) {
const ThemeProvider = ({ children }: { children: React.ReactNode }) => (
<ThemeContext.Provider value={theme} children={children} />
);

function useTheme() {
const theme = React.useContext((ThemeContext as unknown) as React.Context<
T | undefined
>);
const theme = React.useContext(
(ThemeContext as unknown) as React.Context<T | undefined>,
);
if (!theme)
throw new Error("useTheme must be within a ThemeProvider with a value");
return theme;
Expand Down
44 changes: 44 additions & 0 deletions packages/system/src/createChakra/component-style.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Dict, isFunction } from "@chakra-ui/utils";
import { get } from "@styled-system/css";
import css from "../css";
import { CreateChakraOptions } from "./types";

const themableProps = ["variant", "variantSize", "variantColor"] as const;

function getComponentStyles<H>(props: any, options?: CreateChakraOptions<H>) {
const componentStyle: Dict = {};

const themeKey = options?.themeKey;
if (!themeKey) return {};

const commonStyleObject = get(props.theme, `components.${themeKey}.common`);

if (commonStyleObject) {
const commonStyle = css(commonStyleObject)(props.theme);
Object.assign(componentStyle, commonStyle);
}

for (const prop of themableProps) {
if (themableProps.includes(prop)) {
const styleObjectOrFunc = get(
props.theme,
`components.${themeKey}.${prop}.${props[prop]}`,
);

if (!styleObjectOrFunc) continue;

const systemObject = isFunction(styleObjectOrFunc)
? styleObjectOrFunc(props)
: styleObjectOrFunc;

const style = css(systemObject)(props.theme);

// Add style to component style
Object.assign(componentStyle, style);
}
}

return componentStyle;
}

export default getComponentStyles;
42 changes: 2 additions & 40 deletions packages/system/src/createChakra/styled.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,13 @@
import { isFunction, Dict } from "@chakra-ui/utils";
import { get } from "@styled-system/css";
import { Dict, isFunction } from "@chakra-ui/utils";
import * as React from "react";
import { filterProps, getShouldForwardProps } from "../chakra/styled";
import { useChakra } from "../color-mode";
import { css } from "../css";
import { forwardRef } from "../forward-ref";
import { jsx } from "../system";
import getComponentStyles from "./component-style";
import { As, CreateChakraComponent, CreateChakraOptions } from "./types";

const themableProps = ["variant", "variantSize", "variantColor"] as const;

function getComponentStyles<H>(props: any, options?: CreateChakraOptions<H>) {
const componentStyle: Dict = {};

const themeKey = options?.themeKey;
if (!themeKey) return {};

const commonStyleObject = get(props.theme, `components.${themeKey}.common`);

if (commonStyleObject) {
const commonStyle = css(commonStyleObject)(props.theme);
Object.assign(componentStyle, commonStyle);
}

for (const prop of themableProps) {
if (themableProps.includes(prop)) {
const styleObjectOrFunc = get(
props.theme,
`components.${themeKey}.${prop}.${props[prop]}`,
);

if (!styleObjectOrFunc) continue;

const systemObject = isFunction(styleObjectOrFunc)
? styleObjectOrFunc(props)
: styleObjectOrFunc;

const style = css(systemObject)(props.theme);

// Add style to component style
Object.assign(componentStyle, style);
}
}

return componentStyle;
}

export const styled = <T extends As, H = {}>(
tag: T,
options?: CreateChakraOptions<H>,
Expand Down
2 changes: 2 additions & 0 deletions packages/system/src/css.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ import { replacePseudo } from "./system/jsx";

export const css = (styles: object): any =>
_css(transformProps(replacePseudo(styles)));

export default css;
6 changes: 3 additions & 3 deletions packages/system/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
export * from "./chakra";
export * from "./createChakra";
export * from "./system";
export * from "./forward-ref";
export * from "./create-theme-context";
export { default as createThemeContext } from "./create-theme-context";
export * from "./create-theme-context";
export { ResponsiveValue, get } from "styled-system";
export { default as isPropValid } from "./system/is-prop-valid";
export * from "./system/is-prop-valid";
export * from "./css";
export { default as CSSReset } from "./css-reset";
export * from "./color-mode";
export * from "./forward-ref";
2 changes: 1 addition & 1 deletion packages/system/src/system/is-prop-valid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const shouldForwardProp = SS.createShouldForwardProp([
*/
const nativeHTMLPropAlias = ["htmlWidth", "htmlHeight"];

function isPropValid(prop: string): boolean {
export function isPropValid(prop: string): boolean {
if (nativeHTMLPropAlias.includes(prop)) {
return true;
} else {
Expand Down
2 changes: 0 additions & 2 deletions packages/system/src/system/system-props-interface.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import * as SS from "styled-system";
import { CustomProps } from "./custom-props-interface";
import { PseudoProps } from "./pseudo-props-interface";

// All system props
// Write a TS Generic that'll take the custom theme and provider autocompletion
export type SystemProps = SS.ColorProps &
SS.LayoutProps &
SS.SpaceProps &
Expand Down
Loading

0 comments on commit 7b96a84

Please sign in to comment.