Skip to content

Commit 75a4afd

Browse files
committed
[add] Side Navigator menu
[add] DropMenu document
1 parent 435b5df commit 75a4afd

9 files changed

Lines changed: 230 additions & 19 deletions

File tree

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ install:
1313
- npm install
1414
script:
1515
- npm run build
16-
- echo '' > docs/.nojekyll
1716
deploy:
1817
provider: pages
1918
on:

document/source/components/BreadCrumb.mdx

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,39 @@
22
layout: docs
33
title: BreadCrumb
44
description: Indicate the current page's location within a navigational hierarchy that automatically adds separators via CSS.
5-
group: components
5+
group: Components
66
---
77

88
import { BreadCrumb } from 'boot-cell/source/Navigator/BreadCrumb';
9+
import { Example } from '../../../source/component/Example';
910

1011
## Example
1112

12-
<BreadCrumb path={[{ title: 'Home' }]} />
13+
<Example>
14+
<BreadCrumb path={[{ title: 'Home' }]} />
15+
</Example>
1316

1417
```javascript
1518
<BreadCrumb path={[{ title: 'Home' }]} />
1619
```
1720

18-
<BreadCrumb path={[{ href: '#', title: 'Home' }, { title: 'Library' }]} />
21+
<Example>
22+
<BreadCrumb path={[{ href: '#', title: 'Home' }, { title: 'Library' }]} />
23+
</Example>
1924

2025
```javascript
2126
<BreadCrumb path={[{ href: '#', title: 'Home' }, { title: 'Library' }]} />
2227
```
2328

24-
<BreadCrumb
25-
path={[
26-
{ href: '#', title: 'Home' },
27-
{ href: '#', title: 'Library' },
28-
{ title: 'Data' }
29-
]}
30-
/>
29+
<Example>
30+
<BreadCrumb
31+
path={[
32+
{ href: '#', title: 'Home' },
33+
{ href: '#', title: 'Library' },
34+
{ title: 'Data' }
35+
]}
36+
/>
37+
</Example>
3138

3239
```javascript
3340
<BreadCrumb
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
---
2+
layout: docs
3+
title: DropMenu
4+
description: Toggle contextual overlays for displaying lists of links and more with the Bootstrap dropdown plugin.
5+
group: Components
6+
toc: true
7+
---
8+
9+
import { DropMenu } from 'boot-cell/source/Navigator/DropMenu';
10+
import { Example } from '../../../source/component/Example';
11+
12+
## Overview
13+
14+
DropMenu are toggleable, contextual overlays for displaying lists of links and more. They're toggled by clicking, not by hovering; this is [an intentional design decision](http://markdotto.com/2012/02/27/bootstrap-explained-dropdowns/).
15+
16+
## Accessibility
17+
18+
The [<abbr title="Web Accessibility Initiative">WAI</abbr> <abbr title="Accessible Rich Internet Applications">ARIA</abbr>](https://www.w3.org/TR/wai-aria/) standard defines an actual [`role="menu"` widget](https://www.w3.org/WAI/PF/aria/roles#menu), but this is specific to application-like menus which trigger actions or functions. <abbr title="Accessible Rich Internet Applications">ARIA</abbr> menus can only contain menu items, checkbox menu items, radio button menu items, radio button groups, and sub-menus.
19+
20+
Bootstrap's dropdowns, on the other hand, are designed to be generic and applicable to a variety of situations and markup structures. For instance, it is possible to create dropdowns that contain additional inputs and form controls, such as search fields or login forms. For this reason, Bootstrap does not expect (nor automatically add) any of the `role` and `aria-` attributes required for true <abbr title="Accessible Rich Internet Applications">ARIA</abbr> menus. Authors will have to include these more specific attributes themselves.
21+
22+
However, Bootstrap does add built-in support for most standard keyboard menu interactions, such as the ability to move through individual `.dropdown-item` elements using the cursor keys and close the menu with the <kbd>ESC</kbd> key.
23+
24+
## Examples
25+
26+
Wrap the dropdown's toggle (your button or link) and the dropdown menu within `.dropdown`, or another element that declares `position: relative;`. DropMenu can be triggered from `<a>` or `<button>` elements to better fit your potential needs. The examples shown here use semantic `<ul>` elements where appropriate, but custom markup is supported.
27+
28+
### Single button
29+
30+
Any single `.btn` can be turned into a dropdown toggle with some markup changes. Here's how you can put them to work with either `<button>` elements:
31+
32+
<Example>
33+
<DropMenu
34+
title="Dropdown button"
35+
list={[
36+
{ href: '#', title: 'Action' },
37+
{ href: '#', title: 'Another action' },
38+
{ href: '#', title: 'Something else here' }
39+
]}
40+
/>
41+
</Example>
42+
43+
```javascript
44+
<DropMenu
45+
title="Dropdown button"
46+
list={[
47+
{ href: '#', title: 'Action' },
48+
{ href: '#', title: 'Another action' },
49+
{ href: '#', title: 'Something else here' }
50+
]}
51+
/>
52+
```
53+
54+
The best part is you can do this with any button variant, too:
55+
56+
<Example>
57+
<DropMenu
58+
buttonKind="danger"
59+
title="Danger"
60+
list={[
61+
{ href: '#', title: 'Action' },
62+
{ href: '#', title: 'Another action' },
63+
{ href: '#', title: 'Something else here' },
64+
{},
65+
{ href: '#', title: 'Separated link' }
66+
]}
67+
/>
68+
</Example>
69+
70+
```javascript
71+
<DropMenu
72+
buttonKind="danger"
73+
title="Danger"
74+
list={[
75+
{ href: '#', title: 'Action' },
76+
{ href: '#', title: 'Another action' },
77+
{ href: '#', title: 'Something else here' },
78+
{},
79+
{ href: '#', title: 'Separated link' }
80+
]}
81+
/>
82+
```
83+
84+
### Split button
85+
86+
<Example>
87+
<DropMenu
88+
buttonKind="danger"
89+
title="Action"
90+
href="https://web-cell.dev/BootCell/"
91+
list={[
92+
{ href: '#', title: 'Action' },
93+
{ href: '#', title: 'Another action' },
94+
{ href: '#', title: 'Something else here' },
95+
{},
96+
{ href: '#', title: 'Separated link' }
97+
]}
98+
/>
99+
</Example>
100+
101+
```javascript
102+
<DropMenu
103+
buttonKind="danger"
104+
title="Action"
105+
href="https://web-cell.dev/BootCell/"
106+
list={[
107+
{ href: '#', title: 'Action' },
108+
{ href: '#', title: 'Another action' },
109+
{ href: '#', title: 'Something else here' },
110+
{},
111+
{ href: '#', title: 'Separated link' }
112+
]}
113+
/>
114+
```

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
{
22
"name": "bootcell-document",
3-
"version": "0.2.0",
3+
"version": "0.3.0",
44
"description": "Re-implemented Official Web-site of BootStrap based on WebCell, BootCell & MarkCell",
55
"dependencies": {
66
"boot-cell": "^0.23.2",
77
"cell-router": "^2.0.0-rc.6",
88
"classnames": "^2.2.6",
9+
"lodash.groupby": "^4.6.0",
910
"mobx": "^5.15.2",
1011
"mobx-web-cell": "^0.2.5",
1112
"web-cell": "^2.0.0-rc.15"
1213
},
1314
"devDependencies": {
15+
"@types/lodash.groupby": "^4.6.6",
1416
"husky": "^4.2.0",
17+
"less": "^3.10.3",
1518
"lint-staged": "^9.5.0",
1619
"mark-cell": "^0.2.1",
1720
"parcel": "^1.12.4",
@@ -23,7 +26,7 @@
2326
"tabWidth": 4
2427
},
2528
"lint-staged": {
26-
"*.{html,md,mdx,json,yml,ts,tsx}": [
29+
"*.{html,md,mdx,less,json,yml,ts,tsx}": [
2730
"prettier --write",
2831
"git add"
2932
]

source/component/Example.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { createCell } from 'web-cell';
2+
import { WebCellProps } from 'boot-cell/source/utility/type';
3+
4+
export function Example({ defaultSlot }: WebCellProps) {
5+
return <div className="border border-light p-4">{defaultSlot}</div>;
6+
}

source/index.html

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,12 @@
44
rel="stylesheet"
55
href="https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/css/bootstrap.min.css"
66
/>
7-
<link
8-
rel="stylesheet"
9-
href="https://cdn.jsdelivr.net/npm/github-markdown-css@3.0.1/github-markdown.min.css"
10-
/>
117
<link
128
rel="stylesheet"
139
href="https://cdn.jsdelivr.net/npm/highlight.js@9.18.0/styles/atom-one-dark.css"
1410
/>
11+
<link rel="stylesheet" href="index.less" />
12+
1513
<script src="https://polyfill.io/v3/polyfill.min.js?flags=gated&features=Object.fromEntries%2CArray.prototype.flat"></script>
1614
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2.4.0/webcomponents-bundle.min.js"></script>
1715
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2.4.0/custom-elements-es5-adapter.js"></script>

source/index.less

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
p > strong,
2+
p > abbr,
3+
p > code,
4+
p > kbd,
5+
p > a {
6+
margin: auto 0.25rem;
7+
}
8+
pre > code {
9+
display: block;
10+
background: #f8f9fa;
11+
padding: 1.5rem;
12+
13+
[class^='hljs-'] {
14+
padding-left: 0.5rem;
15+
}
16+
position: relative;
17+
&::before {
18+
position: absolute;
19+
top: 0.25rem;
20+
right: 0.5rem;
21+
content: 'Copy';
22+
color: gray;
23+
cursor: pointer;
24+
}
25+
}

source/page/index.tsx

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
1-
import { component, createCell, Fragment } from 'web-cell';
1+
import groupBy from 'lodash.groupby';
2+
import { component, createCell, Fragment, on } from 'web-cell';
23
import { observer } from 'mobx-web-cell';
34
import { HTMLRouter } from 'cell-router/source';
5+
import { HTMLHyperLinkProps } from 'boot-cell/source/utility/type';
46
import { NavBar } from 'boot-cell/source/Navigator/NavBar';
57

68
import { history } from '../model';
79
import routes from '../../document/dist';
810

11+
const documents = Promise.all(
12+
routes.map(async ({ paths: [href], meta }) => {
13+
const { title, group } = await meta();
14+
15+
return { title, href, group };
16+
})
17+
).then(list => groupBy(list, 'group'));
18+
919
@observer
1020
@component({
1121
tagName: 'page-router',
@@ -29,11 +39,59 @@ export class PageRouter extends HTMLRouter {
2939
}
3040
}));
3141

42+
state = { sideMenu: {} };
43+
44+
async connectedCallback() {
45+
super.connectedCallback();
46+
47+
const sideMenu = await documents;
48+
49+
this.setState({ sideMenu });
50+
}
51+
52+
@on('click', 'pre > code')
53+
autoCopy({ target }: MouseEvent) {
54+
self.getSelection()
55+
.getRangeAt(0)
56+
.selectNode(target as Node);
57+
58+
document.execCommand('copy');
59+
}
60+
61+
renderSideMenu() {
62+
const map = this.state.sideMenu as {
63+
[key: string]: HTMLHyperLinkProps[];
64+
};
65+
66+
return (
67+
<ul className="list-unstyled">
68+
{Object.entries(map).map(([group, list]) => (
69+
<li>
70+
<h5>{group}</h5>
71+
72+
<ul className="list-unstyled">
73+
{list.map(({ href, title }) => (
74+
<li>
75+
<a href={href}>{title}</a>
76+
</li>
77+
))}
78+
</ul>
79+
</li>
80+
))}
81+
</ul>
82+
);
83+
}
84+
3285
render() {
3386
return (
3487
<Fragment>
3588
<NavBar title="BootCell" />
36-
<main className="mt-5 p-3 markdown-body">{super.render()}</main>
89+
90+
<div className="mt-5 d-flex">
91+
<nav className="p-3">{this.renderSideMenu()}</nav>
92+
93+
<main className="p-3">{super.render()}</main>
94+
</div>
3795
</Fragment>
3896
);
3997
}

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"target": "ES5",
44
"module": "ESNext",
55
"moduleResolution": "Node",
6+
"allowSyntheticDefaultImports": true,
67
"experimentalDecorators": true,
78
"jsx": "react",
89
"jsxFactory": "createCell"

0 commit comments

Comments
 (0)