tangled
alpha
login
or
join now
mary.my.id
/
danaus
4
fork
atom
work-in-progress atproto PDS
typescript
atproto
pds
atcute
4
fork
atom
overview
issues
pulls
pipelines
feat: accordion components
mary.my.id
2 months ago
5481d484
2b86afc1
verified
This commit was signed with the committer's
known signature
.
mary.my.id
SSH Key Fingerprint:
SHA256:ZlTP/auFSGpGnaoDg4mCTG1g9OZvXp62jWR4c6H4O3c=
+150
4 changed files
expand all
collapse all
unified
split
packages
danaus
src
web
primitives
accordion-header.tsx
accordion-item.tsx
accordion-panel.tsx
accordion.tsx
+86
packages/danaus/src/web/primitives/accordion-header.tsx
···
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
···
1
+
import { cva } from 'cva';
2
+
import type { Child } from 'hono/jsx';
3
+
4
+
import ChevronDownSmallOutlined from '../icons/central/chevron-down-small-outlined.tsx';
5
+
6
+
const root = cva({
7
+
base: [
8
+
'flex w-full cursor-pointer list-none items-center',
9
+
'm-0 rounded-md border-0',
10
+
'bg-transparent text-neutral-foreground-1',
11
+
'outline-2 -outline-offset-2 outline-transparent',
12
+
'focus-visible:outline-stroke-focus-2',
13
+
// hide default marker
14
+
'[&::-webkit-details-marker]:hidden',
15
+
],
16
+
variants: {
17
+
size: {
18
+
small: 'min-h-8 text-base-200',
19
+
medium: 'min-h-11 text-base-300',
20
+
large: 'min-h-11 text-base-400',
21
+
'extra-large': 'min-h-11 text-base-500',
22
+
},
23
+
expandIconPosition: {
24
+
// padding: 0 12px 0 10px
25
+
start: 'pr-3 pl-2.5',
26
+
// padding: 0 10px 0 12px (reversed)
27
+
end: 'pr-2.5 pl-3',
28
+
},
29
+
},
30
+
defaultVariants: {
31
+
size: 'medium',
32
+
expandIconPosition: 'start',
33
+
},
34
+
});
35
+
36
+
const expandIconStyle = cva({
37
+
base: ['flex shrink-0 items-center', 'text-base-500 leading-base-500'],
38
+
variants: {
39
+
position: {
40
+
start: 'pr-2',
41
+
end: 'grow shrink basis-0 justify-end pl-2',
42
+
},
43
+
},
44
+
});
45
+
46
+
const iconStyle = cva({
47
+
base: 'flex shrink-0 items-center pr-2 text-base-500 leading-base-500',
48
+
});
49
+
50
+
export interface AccordionHeaderProps {
51
+
size?: 'small' | 'medium' | 'large' | 'extra-large';
52
+
expandIconPosition?: 'start' | 'end';
53
+
/** slot for custom icon before the text */
54
+
icon?: Child;
55
+
class?: string;
56
+
children?: Child;
57
+
}
58
+
59
+
/**
60
+
* accordion header component using native `<summary>` element
61
+
*/
62
+
const AccordionHeader = (props: AccordionHeaderProps) => {
63
+
const { size = 'medium', expandIconPosition = 'start', icon, class: className, children } = props;
64
+
65
+
return (
66
+
<summary class={root({ size, expandIconPosition, className })}>
67
+
{expandIconPosition === 'start' && (
68
+
<span class={expandIconStyle({ position: 'start' })}>
69
+
<ChevronDownSmallOutlined size={20} />
70
+
</span>
71
+
)}
72
+
73
+
{icon && <span class={iconStyle()}>{icon}</span>}
74
+
75
+
{children}
76
+
77
+
{expandIconPosition === 'end' && (
78
+
<span class={expandIconStyle({ position: 'end' })}>
79
+
<ChevronDownSmallOutlined size={20} />
80
+
</span>
81
+
)}
82
+
</summary>
83
+
);
84
+
};
85
+
86
+
export default AccordionHeader;
+25
packages/danaus/src/web/primitives/accordion-item.tsx
···
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
···
1
+
import type { Child } from 'hono/jsx';
2
+
3
+
export interface AccordionItemProps {
4
+
/** whether the accordion item is open by default */
5
+
open?: boolean;
6
+
/** group name for exclusive accordion behavior (only one open at a time) */
7
+
name?: string;
8
+
class?: string;
9
+
children?: Child;
10
+
}
11
+
12
+
/**
13
+
* accordion item component using native `<details>` element
14
+
*/
15
+
const AccordionItem = (props: AccordionItemProps) => {
16
+
const { open = false, name, class: className, children } = props;
17
+
18
+
return (
19
+
<details open={open} name={name} class={`group/accordion-item${className ? ` ${className}` : ''}`}>
20
+
{children}
21
+
</details>
22
+
);
23
+
};
24
+
25
+
export default AccordionItem;
+22
packages/danaus/src/web/primitives/accordion-panel.tsx
···
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
···
1
+
import { cva } from 'cva';
2
+
import type { Child } from 'hono/jsx';
3
+
4
+
const root = cva({
5
+
base: 'px-3 pb-3',
6
+
});
7
+
8
+
export interface AccordionPanelProps {
9
+
class?: string;
10
+
children?: Child;
11
+
}
12
+
13
+
/**
14
+
* accordion panel component for content within accordion item
15
+
*/
16
+
const AccordionPanel = (props: AccordionPanelProps) => {
17
+
const { class: className, children } = props;
18
+
19
+
return <div class={root({ className })}>{children}</div>;
20
+
};
21
+
22
+
export default AccordionPanel;
+17
packages/danaus/src/web/primitives/accordion.tsx
···
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
···
1
+
import type { Child } from 'hono/jsx';
2
+
3
+
export interface AccordionProps {
4
+
class?: string;
5
+
children?: Child;
6
+
}
7
+
8
+
/**
9
+
* accordion container component
10
+
*/
11
+
const Accordion = (props: AccordionProps) => {
12
+
const { class: className, children } = props;
13
+
14
+
return <div class={className}>{children}</div>;
15
+
};
16
+
17
+
export default Accordion;