Skip to content
This repository was archived by the owner on Sep 20, 2024. It is now read-only.

Commit 5364346

Browse files
committed
feat: create bradcrumb component
1 parent a27f72f commit 5364346

File tree

17 files changed

+426
-29
lines changed

17 files changed

+426
-29
lines changed

components.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* This is a generated file. Do not edit it's contents.
88
*
9-
* This file was generated on 2021-07-16T10:09:49.527Z
9+
* This file was generated on 2021-07-27T08:11:47.550Z
1010
*/
1111

1212
import { ChakraProps } from '@chakra-ui/vue-system'
@@ -42,6 +42,7 @@ declare module 'vue' {
4242
CAlertTitle: typeof import('@chakra-ui/vue-next')['CAlertTitle']
4343
CAlertDescription: typeof import('@chakra-ui/vue-next')['CAlertDescription']
4444
CAlertIcon: typeof import('@chakra-ui/vue-next')['CAlertIcon']
45+
CBreadcrumb: typeof import('@chakra-ui/vue-next')['CBreadcrumb']
4546
CButton: typeof import('@chakra-ui/vue-next')['CButton']
4647
CButtonGroup: typeof import('@chakra-ui/vue-next')['CButtonGroup']
4748
CIconButton: typeof import('@chakra-ui/vue-next')['CIconButton']

packages/c-breadcrumb/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# @chakra-ui/c-breadcrumb
2+
3+
Breadcrumbs help users visualize their current location in relation to the rest of the website or application by showing the hierarchy of pages
4+
5+
## Installation
6+
7+
```sh
8+
yarn add @chakra-ui/c-breadcrumb
9+
# or
10+
npm i @chakra-ui/c-breadcrumb
11+
```
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<template>
2+
<c-breadcrumb>
3+
<template v-slot:separator>
4+
<c-icon name="chevron-right" />
5+
</template>
6+
<c-breadcrumb-item>
7+
<c-breadcrumb-link as="router-link" to="/">Home</c-breadcrumb-link>
8+
</c-breadcrumb-item>
9+
<c-breadcrumb-item>
10+
<c-breadcrumb-link href="#">Docs</c-breadcrumb-link>
11+
</c-breadcrumb-item>
12+
<c-breadcrumb-item is-current-page>
13+
<c-breadcrumb-link href="#">About</c-breadcrumb-link>
14+
</c-breadcrumb-item>
15+
</c-breadcrumb>
16+
</template>
17+
18+
<script lang="ts" setup>
19+
import { useRoute } from 'vue-router'
20+
21+
const route = useRoute()
22+
</script>

packages/c-breadcrumb/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './src'

packages/c-breadcrumb/package.json

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"name": "@chakra-ui/c-breadcrumb",
3+
"description": "Chakra UI Vue | Breadcrumbs help users visualize their current location in relation to the rest of the website or application by showing the hierarchy of pages component",
4+
"version": "1.0.0-alpha.4",
5+
"main": "dist/cjs/index.js",
6+
"module": "dist/esm/index.js",
7+
"types": "dist/types/index.d.ts",
8+
"typings": "dist/types/index.d.ts",
9+
"author": "Jonathan Bakebwa <[email protected]>",
10+
"homepage": "https://github.com/chakra-ui/chakra-ui-vue-next#readme",
11+
"license": "MIT",
12+
"files": [
13+
"dist"
14+
],
15+
"exports": {
16+
".": {
17+
"require": "./dist/cjs/index.js",
18+
"default": "./dist/esm/index.js"
19+
}
20+
},
21+
"publishConfig": {
22+
"access": "public"
23+
},
24+
"repository": "https://github.com/chakra-ui/chakra-ui-vue-next/tree/master/packages/c-breadcrumb",
25+
"bugs": {
26+
"url": "https://github.com/chakra-ui/chakra-ui-vue-next/issues"
27+
},
28+
"sideEffects": false,
29+
"scripts": {
30+
"build": "rimraf ./dist && concurrently yarn:build:*",
31+
"build:esm": "cross-env BABEL_ENV=esm babel src --root-mode upward --extensions .ts,.tsx -d dist/esm --source-maps",
32+
"build:cjs": "cross-env BABEL_ENV=cjs babel src --root-mode upward --extensions .ts,.tsx -d dist/cjs --source-maps",
33+
"build:types": "cross-env tsc --emitDeclarationOnly --declaration --declarationDir dist/types",
34+
"watch": "concurrently yarn:watch:*",
35+
"watch:esm": "cross-env BABEL_ENV=esm babel src --root-mode upward --extensions .ts,.tsx -d dist/esm --source-maps --watch",
36+
"watch:cjs": "cross-env BABEL_ENV=cjs babel src --root-mode upward --extensions .ts,.tsx -d dist/cjs --source-maps --watch",
37+
"watch:types": "cross-env tsc --emitDeclarationOnly --declaration --declarationDir dist/types --watch --incremental"
38+
},
39+
"dependencies": {
40+
"@chakra-ui/styled-system": "^1.10.0",
41+
"@chakra-ui/vue-system": "0.1.0-alpha.4",
42+
"@chakra-ui/vue-utils": "0.1.0-alpha.4"
43+
},
44+
"peerDependencies": {
45+
"vue": "^3.1.4"
46+
},
47+
"devDependencies": {
48+
"vue": "^3.1.4"
49+
}
50+
}
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
/**
2+
* Hey! Welcome to @chakra-ui/vue-next CBreadcrumb
3+
*
4+
* Breadcrumbs help users visualize their current location in relation to the rest of the website or application by showing the hierarchy of pages
5+
*
6+
* @see Docs https://next.vue.chakra-ui.com/breadcrumb
7+
* @see Source https://github.com/chakra-ui/chakra-ui-vue-next/blob/master/packages/c-breadcrumb/src/c-breadcrumb/c-breadcrumb.ts
8+
* @see WAI-ARIA https://www.w3.org/TR/wai-aria-practices-1.2
9+
*/
10+
11+
import { h, defineComponent, PropType, ConcreteComponent, Component, computed, cloneVNode, VNode, VNodeProps, mergeProps } from 'vue'
12+
import {
13+
chakra,
14+
HTMLChakraProps,
15+
SystemProps,
16+
ThemingProps,
17+
StylesProvider,
18+
useMultiStyleConfig,
19+
useStyles,
20+
SystemStyleObject
21+
} from '@chakra-ui/vue-system'
22+
import { filterUndefined } from '@chakra-ui/utils'
23+
import { getValidChildren, SNA, SNAO } from '@chakra-ui/vue-utils'
24+
25+
/**
26+
* CBreadcrumb (root)
27+
*/
28+
29+
30+
export interface BreadcrumbOptions {
31+
/**
32+
* The visual separator between each breadcrumb item
33+
* @type string | ConcreteComponent | Component
34+
*/
35+
separator?: string | ConcreteComponent | Component
36+
/**
37+
* The left and right margin applied to the separator
38+
* @type SystemProps["mx"]
39+
*/
40+
spacing?: SystemProps['mx']
41+
}
42+
43+
export interface BreadcrumbProps
44+
extends HTMLChakraProps<'nav'>,
45+
BreadcrumbOptions,
46+
ThemingProps<'Breadcrumb'> {}
47+
48+
49+
/**
50+
* CBreadcrumb is used to render a breadcrumb navigation landmark.
51+
* It renders a `nav` element with `aria-label` set to `breadcrumb`
52+
*
53+
* @see Docs https://next.vue.chakra-ui.com/breadcrumb
54+
*/
55+
export const CBreadcrumb = defineComponent(
56+
(props: BreadcrumbProps, { attrs, slots }) => {
57+
const themingProps = computed<ThemingProps>(() =>
58+
filterUndefined({
59+
colorScheme: props.colorScheme,
60+
variant: props.variant,
61+
size: props.size,
62+
styleConfig: props.styleConfig,
63+
})
64+
)
65+
66+
const styles = useMultiStyleConfig('Breadcrumb', themingProps.value)
67+
StylesProvider(styles)
68+
69+
const separator = computed(() => slots?.separator?.() || props.separator)
70+
71+
return () => {
72+
const validChildren = getValidChildren(slots)
73+
const count = validChildren.length
74+
75+
const children = validChildren.map((vnode: VNode<unknown, unknown, BreadcrumbOptions>, index: number) => cloneVNode(vnode, {
76+
separator: separator.value,
77+
spacing: props.spacing,
78+
isLastChild: count === index + 1,
79+
}))
80+
81+
return (
82+
<chakra.nav
83+
as={props.as}
84+
aria-label="breadcrumb"
85+
__css={styles.value.container}
86+
{...attrs}
87+
>
88+
<chakra.ol __label="chakra-breadcrumb__list">
89+
{() => children}
90+
</chakra.ol>
91+
</chakra.nav>
92+
)
93+
}
94+
}
95+
)
96+
97+
// @ts-ignore "name" property is typically read-only for functional components
98+
CBreadcrumb.name = 'CBreadcrumb'
99+
CBreadcrumb.props = {
100+
separator: {
101+
type: SNAO as PropType<BreadcrumbOptions['separator']>,
102+
default: '/'
103+
},
104+
spacing: {
105+
type: SNA as PropType<BreadcrumbOptions['spacing']>,
106+
default: '0.5rem'
107+
},
108+
as: {
109+
type: [String, Object] as PropType<DOMElements | Component | string>,
110+
default: 'nav',
111+
},
112+
}
113+
114+
115+
/**
116+
* CBreadcrumbSeparator
117+
*/
118+
119+
export interface BreadcrumbSeparatorProps extends HTMLChakraProps<"div"> {
120+
/**
121+
* @type SystemProps["mx"]
122+
*/
123+
spacing?: SystemProps["mx"]
124+
}
125+
126+
/**
127+
* The `CBreadcrumbSeparator` component is the separator for
128+
* each breacrumb item.
129+
*/
130+
export const CBreadcrumbSeparator = defineComponent((props: BreadcrumbSeparatorProps, { attrs, slots }) => {
131+
const styles = useStyles()
132+
const separatorStyles = computed<SystemStyleObject>(() => ({
133+
display: 'flex',
134+
mx: props.spacing,
135+
...styles.value.separator,
136+
}))
137+
138+
return () => (
139+
<chakra.span
140+
role="presentation"
141+
__label="chakra-breadcrumb__separator"
142+
{...attrs}
143+
__css={separatorStyles.value}
144+
>
145+
{slots}
146+
</chakra.span>
147+
)
148+
})
149+
150+
CBreadcrumbSeparator.props = {
151+
spacing: CBreadcrumb.props.spacing,
152+
}
153+
154+
155+
// @ts-ignore "name" property is typically read-only for functional components
156+
CBreadcrumbSeparator.name = 'CBreadcrumbSeparator'
157+
158+
159+
/**
160+
* CBreadcrumbItem
161+
*/
162+
163+
interface BreadcrumbItemOptions extends BreadcrumbOptions {
164+
isCurrentPage?: boolean
165+
isLastChild?: boolean
166+
}
167+
168+
export interface BreadcrumbItemProps
169+
extends BreadcrumbItemOptions,
170+
HTMLChakraProps<"li"> {}
171+
172+
export const CBreadcrumbItem = defineComponent((props: BreadcrumbItemProps, { attrs, slots }) => {
173+
const styles = useStyles()
174+
const itemStyles = computed<SystemStyleObject>(() => ({
175+
display: "inline-flex",
176+
alignItems: "center",
177+
...styles.value.item,
178+
}))
179+
180+
return () => {
181+
const validChildren = getValidChildren(slots)
182+
const children = validChildren.map((vnode: VNode<unknown, unknown, BreadcrumbItemOptions>) => {
183+
// @ts-expect-error The "name" property is not typed on `VNodeTypes` but we need to access it during runtime
184+
if (vnode.type.name === 'CBreadcrumbLink') {
185+
return cloneVNode(vnode, {
186+
isCurrentPage: props.isCurrentPage,
187+
})
188+
}
189+
190+
// @ts-expect-error The "name" property is not typed on `VNodeTypes` but we need to access it during runtime
191+
if (vnode.type.name === 'CBreadcrumbSeparator') {
192+
return cloneVNode(vnode, {
193+
spacing: props.spacing,
194+
children: vnode.children || { default: () => props.separator },
195+
})
196+
}
197+
198+
return vnode
199+
})
200+
201+
return (
202+
<chakra.li __label="chakra-breadcrumb__list-it" __css={itemStyles.value}>
203+
{children}
204+
{!props.isLastChild && (
205+
// @ts-expect-error
206+
<CBreadcrumbSeparator spacing={props.spacing}>
207+
{() => props.separator}
208+
</CBreadcrumbSeparator>
209+
)}
210+
</chakra.li>
211+
)
212+
}
213+
})
214+
215+
// @ts-ignore "name" property is typically read-only for functional components
216+
CBreadcrumbItem.name = 'CBreadcrumbItem'
217+
CBreadcrumbItem.props = {
218+
...CBreadcrumb.props,
219+
isLastChild: Boolean as PropType<boolean>,
220+
isCurrentPage: Boolean as PropType<boolean>,
221+
}
222+
223+
/**
224+
* CBreadcrumbLink
225+
*/
226+
227+
export interface BreadcrumbLinkProps extends HTMLChakraProps<"a"> {
228+
isCurrentPage?: boolean
229+
}
230+
231+
/**
232+
* BreadcrumbLink link.
233+
*
234+
* It renders a `span` when it matches the current link. Otherwise,
235+
* it renders an anchor tag.
236+
*/
237+
export const CBreadcrumbLink = defineComponent((props: BreadcrumbLinkProps, { attrs, slots }) => {
238+
const styles = useStyles()
239+
240+
return () => {
241+
if (props.isCurrentPage) {
242+
return (
243+
<chakra.span __label="chakra-breadcrumb__link" aria-current="page" __css={styles.value.link} as={props.as} {...attrs}>
244+
{slots}
245+
</chakra.span>
246+
)
247+
}
248+
249+
return (
250+
<chakra.a __label="chakra-breadcrumb__link" as={props.as} __css={styles.value.link} {...attrs}>
251+
{slots}
252+
</chakra.a>
253+
)
254+
}
255+
})
256+
257+
// @ts-ignore "name" property is typically read-only for functional components
258+
CBreadcrumbLink.name = 'CBreadcrumbLink'
259+
CBreadcrumbLink.props = {
260+
isCurrentPage: Boolean as PropType<boolean>,
261+
}

packages/c-breadcrumb/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './c-breadcrumb'
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`should render properly 1`] = `
4+
<DocumentFragment>
5+
<nav
6+
aria-label="breadcrumb"
7+
class="css-0"
8+
>
9+
<ol
10+
class="chakra-chakra-breadcrumb__list css-0"
11+
/>
12+
</nav>
13+
</DocumentFragment>
14+
`;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { render } from '../../test-utils/src'
2+
import { CBreadcrumb } from '../src'
3+
4+
it('should render properly', () => {
5+
const { asFragment } = render(CBreadcrumb)
6+
expect(asFragment()).toMatchSnapshot()
7+
})

0 commit comments

Comments
 (0)