Skip to content

Commit 3707db7

Browse files
authored
feat(accordion): new component (#378)
* chore:update * chore:update * chore:update * chore:update * chore:update * fix: css * refactor: css name * fix: some corrections * refactor: selection-type to type * fix: test * chore: slots update * fix: default slots * fix: --radix * fix: collapsiblecontent * chore: fix ref * fix: type * fix: package name * fix: lock
1 parent 17a1270 commit 3707db7

37 files changed

+3413
-444
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ Website: [Oku Website](https://oku-ui.com)
1818

1919
Please read our [contributing guide](https://github.com/oku-ui/primitives/blob/master/CONTRIBUTING.md)
2020

21-
# TODO Components - 19/28
21+
# TODO Components - 22/28
2222

2323
Enter the component you want most in the components, leave the emojis and follow.
2424

2525
**Developers can work on unclaimed components**.
2626

2727
| Component | Description | Status | Docs |
2828
| --- | --- | --- | --- |
29-
| [Accordion](https://github.com/oku-ui/primitives/issues/3) | A group of collapsible panels | 🚧 In Progress | - |
29+
| [Accordion](https://oku-ui.com/primitives/components/accordion) | <span><a href="https://www.npmjs.com/package/@oku-ui/accordion "><img src="https://img.shields.io/npm/v/@oku-ui/accordion.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="Version"></a> </span> | <span> <a href="https://www.npmjs.com/package/@oku-ui/accordion"><img src="https://img.shields.io/npm/dm/@oku-ui/accordion.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="Downloads"></a> </span> | <span> <a href="https://oku-ui.com/primitives/components/accordion"><img src="https://img.shields.io/badge/Open%20Documentation-18181B" alt="Website"></a> </span> |
3030
| [Alert Dialog](https://oku-ui.com/primitives/components/alert-dialog) | <span><a href="https://www.npmjs.com/package/@oku-ui/alert-dialog "><img src="https://img.shields.io/npm/v/@oku-ui/alert-dialog.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="Version"></a> </span> | <span> <a href="https://www.npmjs.com/package/@oku-ui/alert-dialog"><img src="https://img.shields.io/npm/dm/@oku-ui/alert-dialog.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="Downloads"></a> </span> | <span> <a href="https://oku-ui.com/primitives/components/alert-dialog"><img src="https://img.shields.io/badge/Open%20Documentation-18181B" alt="Website"></a> </span> |
3131
| [Aspect Ratio](https://oku-ui.com/primitives/components/aspect-ratio) | <span><a href="https://www.npmjs.com/package/@oku-ui/aspect-ratio "><img src="https://img.shields.io/npm/v/@oku-ui/aspect-ratio.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="Version"></a> </span> | <span> <a href="https://www.npmjs.com/package/@oku-ui/aspect-ratio"><img src="https://img.shields.io/npm/dm/@oku-ui/aspect-ratio.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="Downloads"></a> </span> | <span> <a href="https://oku-ui.com/primitives/components/aspect-ratio"><img src="https://img.shields.io/badge/Open%20Documentation-18181B" alt="Website"></a> </span> |
3232
| [Avatar](https://oku-ui.com/primitives/components/avatar) | <span><a href="https://www.npmjs.com/package/@oku-ui/avatar "><img src="https://img.shields.io/npm/v/@oku-ui/avatar?style=flat&colorA=18181B&colorB=28CF8D" alt="Version"></a> </span> | <span> <a href="https://www.npmjs.com/package/@oku-ui/avatar"><img src="https://img.shields.io/npm/dm/@oku-ui/avatar?style=flat&colorA=18181B&colorB=28CF8D" alt="Downloads"></a></span> | <span> <a href="https://oku-ui.com/primitives/components/avatar"><img src="https://img.shields.io/badge/Open%20Documentation-18181B" alt="Website"></a> |

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"@clack/prompts": "^0.7.0",
4242
"@egoist/tailwindcss-icons": "^1.1.0",
4343
"@iconify-json/ph": "^1.1.6",
44+
"@oku-ui/accordion": "workspace:^",
4445
"@oku-ui/alert-dialog": "workspace:^",
4546
"@oku-ui/arrow": "workspace:^",
4647
"@oku-ui/aspect-ratio": "workspace:^",
@@ -124,6 +125,7 @@
124125
},
125126
"pnpm": {
126127
"overrides": {
128+
"@oku-ui/accordion": "workspace:^",
127129
"@oku-ui/alert-dialog": "workspace:^",
128130
"@oku-ui/arrow": "workspace:^",
129131
"@oku-ui/aspect-ratio": "workspace:^",
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Accordion
2+
A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.
3+
4+
![@oku-ui/accordion](./../../../.github/assets/og/oku-accordion.jpg)
5+
6+
<span><a href="https://www.npmjs.com/package/@oku-ui/accordion "><img src="https://img.shields.io/npm/v/@oku-ui/accordion?style=flat&colorA=18181B&colorB=28CF8D" alt="Version"></a> </span> | <span> <a href="https://www.npmjs.com/package/@oku-ui/accordion"> <img src="https://img.shields.io/npm/dm/@oku-ui/accordion?style=flat&colorA=18181B&colorB=28CF8D" alt="Downloads"> </a> </span> | <span> <a href="https://oku-ui.com/primitives/components/accordion"><img src="https://img.shields.io/badge/Open%20Documentation-18181B" alt="Website"></a> </span>
7+
8+
## Installation
9+
10+
```sh
11+
$ pnpm add @oku-ui/accordion
12+
```
13+
14+
[Documentation](https://oku-ui.com/primitives/components/accordion)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { defineBuildConfig } from 'unbuild'
2+
3+
const isClean = (process.env.CLEAN || 'false') === 'true'
4+
export default defineBuildConfig({
5+
declaration: true,
6+
clean: isClean,
7+
})
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"name": "@oku-ui/accordion",
3+
"type": "module",
4+
"version": "0.0.0",
5+
"license": "MIT",
6+
"source": "src/index.ts",
7+
"funding": "https://github.com/sponsors/productdevbook",
8+
"homepage": "https://oku-ui.com/primitives",
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/oku-ui/primitives.git",
12+
"directory": "packages/components/label"
13+
},
14+
"bugs": {
15+
"url": "https://github.com/oku-ui/primitives/issues"
16+
},
17+
"exports": {
18+
".": {
19+
"types": "./dist/index.d.ts",
20+
"import": "./dist/index.mjs"
21+
}
22+
},
23+
"module": "./dist/index.mjs",
24+
"types": "./dist/index.d.ts",
25+
"files": [
26+
"dist"
27+
],
28+
"engines": {
29+
"node": ">=18"
30+
},
31+
"scripts": {
32+
"build": "unbuild",
33+
"dev": "unbuild --stub",
34+
"clean": "rimraf ./dist && rimraf ./node_modules"
35+
},
36+
"peerDependencies": {
37+
"vue": "^3.3.0"
38+
},
39+
"dependencies": {
40+
"@oku-ui/collapsible": "latest",
41+
"@oku-ui/collection": "latest",
42+
"@oku-ui/direction": "latest",
43+
"@oku-ui/primitive": "latest",
44+
"@oku-ui/provide": "latest",
45+
"@oku-ui/roving-focus": "latest",
46+
"@oku-ui/use-composable": "latest",
47+
"@oku-ui/utils": "latest"
48+
},
49+
"devDependencies": {
50+
"tsconfig": "workspace:^"
51+
},
52+
"publishConfig": {
53+
"access": "public"
54+
}
55+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { defineComponent, h, mergeProps, reactive, toRefs } from 'vue'
2+
import { reactiveOmit, useForwardRef } from '@oku-ui/use-composable'
3+
import { OkuAccordionImplSingle } from './accordionImplSingle'
4+
import { OkuAccordionImplMultiple } from './accordionImplMultiple'
5+
import { ACCORDION_NAME, CollectionProvider, accordionProps, scopeAccordionProps } from './props'
6+
import type { AccordionImplSingleProps, AccordionNativeElement } from './props'
7+
8+
const accordion = defineComponent({
9+
name: ACCORDION_NAME,
10+
inheritAttrs: false,
11+
props: {
12+
...accordionProps.props,
13+
...scopeAccordionProps,
14+
},
15+
setup(props, { attrs, slots }) {
16+
const {
17+
type, ...accordionPropsRefs
18+
} = toRefs(props)
19+
const forwardRef = useForwardRef
20+
21+
const _reactiveProps = reactive(accordionPropsRefs) as AccordionImplSingleProps
22+
const reactiveProps = reactiveOmit(_reactiveProps, (key, _value) => key === undefined)
23+
24+
return () => {
25+
if (props.type) {
26+
const value = props.value || props.defaultValue
27+
if (props.type && !['single', 'multiple'].includes(props.type)) {
28+
return new Error(
29+
'Invalid prop `type` supplied to `Accordion`. Expected one of `single | multiple`.',
30+
)
31+
}
32+
if (props.type === 'multiple' && typeof value === 'string') {
33+
return new Error(
34+
'Invalid prop `type` supplied to `Accordion`. Expected `single` when `defaultValue` or `value` is type `string`.',
35+
)
36+
}
37+
if (props.type === 'single' && Array.isArray(value)) {
38+
return new Error(
39+
'Invalid prop `type` supplied to `Accordion`. Expected `multiple` when `defaultValue` or `value` is type `string[]`.',
40+
)
41+
}
42+
}
43+
44+
return h(CollectionProvider, {
45+
scope: props.scopeOkuAccordion,
46+
},
47+
{
48+
default: () => type.value === 'multiple'
49+
? h(OkuAccordionImplMultiple, {
50+
...mergeProps(attrs, reactiveProps),
51+
ref: forwardRef,
52+
}, slots)
53+
: h(OkuAccordionImplSingle, {
54+
...mergeProps(attrs, reactiveProps),
55+
ref: forwardRef,
56+
}, slots),
57+
},
58+
)
59+
}
60+
},
61+
})
62+
63+
// TODO: https://github.com/vuejs/core/pull/7444 after delete
64+
export const OkuAccordion = accordion as typeof accordion
65+
&
66+
(new () => {
67+
$props: AccordionNativeElement
68+
})
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { OkuCollapsibleContent } from '@oku-ui/collapsible'
2+
import { primitiveProps } from '@oku-ui/primitive'
3+
import { defineComponent, h, mergeProps, reactive, toRefs } from 'vue'
4+
import { reactiveOmit, useForwardRef } from '@oku-ui/use-composable'
5+
import { ACCORDION_NAME, type AccordionContentNativeElement, CONTENT_NAME, accordionContentProps, scopeAccordionProps, useAccordionInject, useAccordionItemInject, useCollapsibleScope } from './props'
6+
7+
/**
8+
* `AccordionContent` contains the collapsible content for an `AccordionItem`.
9+
*/
10+
const accordionContent = defineComponent({
11+
name: CONTENT_NAME,
12+
inheritAttrs: false,
13+
props: {
14+
...primitiveProps,
15+
...accordionContentProps.props,
16+
...scopeAccordionProps,
17+
},
18+
setup(props, { slots, attrs }) {
19+
const {
20+
scopeOkuAccordion,
21+
...contentProps
22+
} = toRefs(props)
23+
24+
const accordionInject = useAccordionInject(ACCORDION_NAME, scopeOkuAccordion.value)
25+
const itemInject = useAccordionItemInject(CONTENT_NAME, scopeOkuAccordion.value)
26+
const collapsibleScope = useCollapsibleScope(scopeOkuAccordion.value)
27+
28+
const _reactive = reactive(contentProps)
29+
const _contentProps = reactiveOmit(_reactive, (key, _value) => key === undefined)
30+
31+
const forwardRef = useForwardRef()
32+
33+
return () => h(OkuCollapsibleContent, {
34+
'role': 'region',
35+
'aria-labelledby': itemInject.triggerId.value,
36+
'data-orientation': accordionInject.orientation.value,
37+
...collapsibleScope,
38+
...mergeProps(attrs, _contentProps),
39+
'ref': forwardRef,
40+
'style': {
41+
'--oku-accordion-content-height': 'var(--oku-collapsible-content-height)',
42+
'--oku-accordion-content-width': 'var(--oku-collapsible-content-width)',
43+
...attrs.style as any,
44+
},
45+
}, slots)
46+
},
47+
})
48+
49+
// TODO: https://github.com/vuejs/core/pull/7444 after delete
50+
export const OkuAccordionContent = accordionContent as typeof accordionContent
51+
&
52+
(new () => {
53+
$props: AccordionContentNativeElement
54+
})
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { defineComponent, h, mergeProps, reactive, toRefs } from 'vue'
2+
import { Primitive, primitiveProps } from '@oku-ui/primitive'
3+
import { reactiveOmit, useForwardRef } from '@oku-ui/use-composable'
4+
import { ACCORDION_NAME, type AccordionHeaderNativeElement, HEADER_NAME, accordionHeaderProps, scopeAccordionProps, useAccordionInject, useAccordionItemInject } from './props'
5+
import { getState } from './utils'
6+
7+
/**
8+
* `AccordionHeader` contains the content for the parts of an `AccordionItem` that will be visible
9+
* whether or not its content is collapsed.
10+
*/
11+
const accordionHeader = defineComponent({
12+
name: HEADER_NAME,
13+
inheritAttrs: false,
14+
props: {
15+
...primitiveProps,
16+
...accordionHeaderProps.props,
17+
...scopeAccordionProps,
18+
},
19+
emits: accordionHeaderProps.emits,
20+
setup(props, { slots, attrs }) {
21+
const {
22+
scopeOkuAccordion, ...headerProps
23+
} = toRefs(props)
24+
25+
const accordionInject = useAccordionInject(ACCORDION_NAME, scopeOkuAccordion.value)
26+
27+
const itemInject = useAccordionItemInject(HEADER_NAME, scopeOkuAccordion.value)
28+
29+
const _reactive = reactive(headerProps)
30+
const _headerProps = reactiveOmit(_reactive, (key, _value) => key === undefined)
31+
32+
const forwardRef = useForwardRef()
33+
34+
return () => h(Primitive.h3, {
35+
'data-orientation': accordionInject.orientation.value,
36+
'data-state': getState(itemInject.open?.value),
37+
'data-disabled': itemInject.disabled?.value ? '' : undefined,
38+
...mergeProps(attrs, _headerProps),
39+
'ref': forwardRef,
40+
41+
}, { default: () => slots.default?.() })
42+
},
43+
})
44+
45+
// TODO: https://github.com/vuejs/core/pull/7444 after delete
46+
export const OkuAccordionHeader = accordionHeader as typeof accordionHeader
47+
&
48+
(new () => {
49+
$props: AccordionHeaderNativeElement
50+
})

0 commit comments

Comments
 (0)