Skip to content

Commit cd221d0

Browse files
author
onesine
committed
Default select implementation in progress
1 parent ea2e505 commit cd221d0

File tree

6 files changed

+84
-37
lines changed

6 files changed

+84
-37
lines changed

src/App.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ const App = () => {
1111
<span className="ml-2">{children}</span>
1212
);
1313

14-
const Header = ({children}) => (
15-
<AccordionHeader className="w-full flex items-center text-gray-600 border-b p-4">
14+
const Header = ({children, onClick = null}) => (
15+
<AccordionHeader className="w-full flex items-center text-gray-600 border-b p-4" href={"/toto"} as={"a"} onClick={onClick}>
1616
{children}
1717
</AccordionHeader>
1818
);
1919

2020
switch (item.type) {
2121
case "group":
2222
return (
23-
<AccordionItem key={index}>
23+
<AccordionItem key={index} isActive={"isActive" in item ? item.isActive : false}>
2424
<Header>
2525
{({open}) => (
2626
<>

src/constants/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ export const menu = [
22
{
33
type: "group",
44
title: "Group 1",
5+
isActive: true,
56
submenu: [
67
{
78
type: "group",
89
title: "Sub Group 1",
10+
isActive: true,
911
submenu: [
1012
{
1113
type: "image",

src/packages/accordion/AccordionBody.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import {useContext, useMemo} from "react";
1+
import {useContext, useLayoutEffect, useMemo} from "react";
22
import {AccordionItemContext} from "./AccordionItemProvider";
33

44
const AccordionBody = ({children, as}) => {
5-
const {hash, transition} = useContext(AccordionItemContext);
5+
const {hash, transition, show} = useContext(AccordionItemContext);
66

77
const TagName = useMemo(() => {
88
if(["div", "ul"].includes(as)) {
@@ -32,7 +32,7 @@ const AccordionBody = ({children, as}) => {
3232
aria-labelledby={`button-${hash}`}
3333
style={
3434
{
35-
maxHeight: "0px",
35+
maxHeight: show ? "none" : "0px",
3636
transitionProperty: "max-height",
3737
overflow: "hidden",
3838
transitionDuration: transitionData.duration,

src/packages/accordion/AccordionHeader.jsx

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
1-
import {useLayoutEffect, useRef, useContext, useMemo} from "react";
1+
import {useRef, useContext, useMemo, useEffect} from "react";
22
import {AccordionItemContext} from "./AccordionItemProvider";
33

4-
const AccordionHeader = ({children, as = "button", className = ""}) => {
5-
const {hash, active, toggle, items, alwaysOpen} = useContext(AccordionItemContext);
4+
const AccordionHeader = ({children, as = "button", className = "", href = "", onClick = null}) => {
5+
const {hash, active, toggle, items, alwaysOpen, show, disabledShow} = useContext(AccordionItemContext);
66
const ref = useRef();
77

8-
useLayoutEffect(() => {
8+
const TagName = useMemo(() => {
9+
if(["button", "div", "li", "ol", "a"].includes(as)) {
10+
return as;
11+
}
12+
return "button";
13+
}, [as]);
14+
15+
useEffect(() => {
916
if (ref && ref.current) {
1017
const toggleButton = (button) => {
1118
let ariaExpanded = button.getAttribute('aria-expanded');
@@ -43,16 +50,24 @@ const AccordionHeader = ({children, as = "button", className = ""}) => {
4350
}
4451
}
4552

46-
const showAccordion = () => {
53+
const showAccordion = (e) => {
54+
disabledShow();
55+
disabledShow();
56+
57+
// Pervent default
58+
if (TagName === "a") {
59+
e.preventDefault();
60+
}
61+
4762
toggle()
4863

4964
if (!alwaysOpen) {
5065
// Close content already open
51-
const buttons = ref.current.parentNode.querySelectorAll(":scope > button[aria-expanded='true']");
66+
const buttons = ref.current.parentNode.querySelectorAll(`:scope > ${TagName}[aria-expanded='true']`);
5267
buttons.forEach(button => {
5368
if (button && button !== ref.current) {
5469
const id = button.id.split("-")[1];
55-
items[id].setActive(false);
70+
items[id](false);
5671
toggleButton(button);
5772
toggleContent(document.querySelector(`#${button.getAttribute('aria-controls')}`));
5873
}
@@ -64,29 +79,46 @@ const AccordionHeader = ({children, as = "button", className = ""}) => {
6479

6580
// Toggle Content
6681
toggleContent(document.querySelector(`#${ref.current.getAttribute('aria-controls')}`));
82+
83+
if (onClick) {
84+
onClick(e);
85+
}
6786
};
6887

6988
ref.current.addEventListener('click', showAccordion);
7089

90+
if (show) {
91+
ref.current.setAttribute("aria-expanded", "true")
92+
}
93+
7194
return () => {
72-
ref.current.removeEventListener('click', showAccordion);
95+
if (ref && ref.current) {
96+
ref?.current?.removeEventListener('click', showAccordion);
97+
}
7398
};
7499
}
75100

76-
}, [items, toggle]);
77-
78-
const TagName = useMemo(() => {
79-
if(["button", "div", "li", "ol"].includes(as)) {
80-
return as;
81-
}
82-
return "button";
83-
}, [as]);
101+
}, [TagName, alwaysOpen, items, onClick, show, disabledShow, toggle]);
102+
103+
if (TagName === "a") {
104+
return (
105+
<TagName
106+
ref={ref}
107+
id={`button-${hash}`}
108+
href={href}
109+
aria-expanded="false"
110+
className={className}
111+
aria-controls={`content-${hash}`}
112+
>
113+
{typeof children === "function" ? children({open: active}) : children}
114+
</TagName>
115+
);
116+
}
84117

85118
return (
86119
<TagName
87120
ref={ref}
88121
id={`button-${hash}`}
89-
type="button"
90122
aria-expanded="false"
91123
className={className}
92124
aria-controls={`content-${hash}`}

src/packages/accordion/AccordionItem.jsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
import {AccordionItemProvider} from "./AccordionItemProvider";
2-
import {useLayoutEffect} from "react";
3-
4-
const AccordionItem = ({children}) => {
5-
useLayoutEffect(() => {
6-
7-
}, []);
82

3+
const AccordionItem = ({children, isActive = false}) => {
94
return (
10-
<AccordionItemProvider>
5+
<AccordionItemProvider isActive={isActive}>
116
{children}
127
</AccordionItemProvider>
138
)

src/packages/accordion/AccordionItemProvider.jsx

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,31 @@
1-
import {createContext, useContext, useEffect, useLayoutEffect, useMemo, useState} from "react";
1+
import {createContext, useContext, useEffect, useMemo, useState} from "react";
22
import {AccordionContext} from "./AccordionProvider";
33

4-
export const AccordionItemContext = createContext({});
4+
export const AccordionItemContext = createContext({
5+
accordionRef: null,
6+
active: false,
7+
items: [],
8+
hash: "",
9+
transition: null,
10+
alwaysOpen: false,
11+
toggle: () => {},
12+
show: false,
13+
setShow: () => {}
14+
});
515

616

7-
export const AccordionItemProvider = ({children}) => {
17+
export const AccordionItemProvider = ({children, isActive = false}) => {
818
const {accordionRef, items, setItems, transition, alwaysOpen} = useContext(AccordionContext);
9-
const [active, setActive] = useState(false);
19+
const [active, setActive] = useState(isActive);
20+
const [show, setShow] = useState(isActive);
1021

1122
const hash = useMemo(() => {
1223
return Math.random().toString(36).substring(2, 9);
1324
}, []);
1425

1526
useEffect(() => {
1627
if (!(hash in items)) {
17-
setItems({...items, [hash]: {active, setActive}});
28+
setItems({...items, [hash]: setActive});
1829
}
1930
}, [active, hash, items, setItems]);
2031

@@ -26,9 +37,16 @@ export const AccordionItemProvider = ({children}) => {
2637
items,
2738
hash,
2839
transition,
29-
alwaysOpen
40+
alwaysOpen,
41+
show,
42+
disabledShow: () => {
43+
console.log("exec")
44+
setShow(false)
45+
}
3046
}
31-
}, [accordionRef, active, hash, items, transition, alwaysOpen]);
47+
}, [accordionRef, active, alwaysOpen, hash, items, show, setShow, transition]);
48+
49+
console.log(`${hash}:`, isActive)
3250

3351
return (
3452
<AccordionItemContext.Provider value={value}>

0 commit comments

Comments
 (0)