Skip to content

Commit bb01d79

Browse files
Added Angular 13 components and samples
Removed AngularJS Directive sample
1 parent 9535943 commit bb01d79

File tree

16 files changed

+520
-9
lines changed

16 files changed

+520
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import React, { useEffect } from 'react';
2+
import Helmet from 'react-helmet';
3+
import { useSelector, useDispatch } from 'react-redux';
4+
import { makeStyles } from '@material-ui/core/styles';
5+
import Container from '@material-ui/core/Container';
6+
import TryMe from './TryMe';
7+
import { load, setCode } from 'redux/modules/angularhowtouse';
8+
import MDReactComponent from 'markdown-react-js';
9+
import { Light as SyntaxHighlighter } from 'react-syntax-highlighter';
10+
import js from 'react-syntax-highlighter/dist/esm/languages/hljs/javascript';
11+
import docco from 'react-syntax-highlighter/dist/esm/styles/hljs/docco';
12+
13+
SyntaxHighlighter.registerLanguage('javascript', js);
14+
15+
const useStyles = makeStyles(() => ({
16+
placeholder: {
17+
width: "100%",
18+
height: "520px",
19+
"border-left-width": "0px",
20+
"border-right-width": "0px",
21+
22+
"border-top-width": "1px",
23+
"border-top-style": "solid",
24+
"border-bottom-width": "1px",
25+
"border-bottom-style": "solid"
26+
}
27+
}));
28+
29+
function AngularHowToUse(props) {
30+
const classes = useStyles();
31+
const { fileName } = props;
32+
const loaded = useSelector(state => state.angularhowtouse.files[fileName] && state.angularhowtouse.files[fileName].loaded);
33+
const markdown = useSelector(state => state.angularhowtouse.files[fileName] && state.angularhowtouse.files[fileName].markdown);
34+
const groups = useSelector(state => state.angularhowtouse.files[fileName] != null ? state.angularhowtouse.files[fileName].groups : {});
35+
const dispatch = useDispatch()
36+
37+
useEffect(() => {
38+
if (!loaded) {
39+
dispatch(load(fileName));
40+
}
41+
// eslint-disable-next-line react-hooks/exhaustive-deps
42+
}, [fileName]/* run only once on fileName change */);
43+
44+
let key = 0;
45+
function handleIterate(Tag, props, children, level) {
46+
if (level === 1) {
47+
props = {
48+
...props,
49+
className: 'first-level-class'
50+
};
51+
}
52+
key++;
53+
if (Tag === 'p') {
54+
if (children.filter(child => child.props != null && child.props.samples != null).length > 0) {
55+
return <div key={key}>{children}</div>;
56+
}
57+
}
58+
key++;
59+
if (Tag === 'a') {
60+
const [caption] = children;
61+
const groupKey = props.href;
62+
const group = groups[groupKey];
63+
if (caption === 'group' && group != null) {
64+
const { activeKey, samples } = group;
65+
props = {
66+
...props,
67+
className: classes.placeholder,
68+
name: `group${groupKey}`,
69+
samples,
70+
activeKey,
71+
tagKey: key
72+
};
73+
return <TryMe key={key} {...props} onCodeChange={(sampleKey, text) => dispatch(setCode(fileName, props.href, sampleKey, text))} />;
74+
}
75+
}
76+
if(props.hasOwnProperty("data-language")) {
77+
key +=1;
78+
return <SyntaxHighlighter language="javascript" style={docco} key={key}>{children}</SyntaxHighlighter>;
79+
}
80+
key++;
81+
return <Tag key={key} {...props}>{children}</Tag>;
82+
}
83+
84+
let title = "";
85+
if(typeof markdown === "string") {
86+
[, title] = markdown.match(/^# (.+)$/m) || [];
87+
}
88+
return (markdown ?
89+
<>
90+
<Helmet>
91+
<title>{` for Angular - ${title}`}</title>
92+
<meta name="description" content="Angular Product Samples." />
93+
</Helmet>
94+
<Container fixed>
95+
<MDReactComponent text={markdown} onIterate={handleIterate} />
96+
</Container>
97+
</> :
98+
<></>
99+
);
100+
}
101+
102+
export default AngularHowToUse;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React, { Component } from 'react';
2+
3+
class AngularUseCases extends Component {
4+
render() {
5+
const { children } = this.props;
6+
return <>
7+
{children}
8+
</>
9+
}
10+
}
11+
12+
export default AngularUseCases;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import React, { Component } from 'react';
2+
import PropTypes from 'prop-types';
3+
import {Controlled as CodeMirror} from 'react-codemirror2'
4+
import 'codemirror/lib/codemirror.css';
5+
import 'codemirror/theme/material.css';
6+
import 'codemirror/mode/javascript/javascript';
7+
8+
class Editor extends Component {
9+
static propTypes = {
10+
onCodeChange: PropTypes.func.isRequired,
11+
content: PropTypes.string.isRequired
12+
};
13+
14+
render() {
15+
const { content, onCodeChange } = this.props;
16+
return <div style={{
17+
height: "300px",
18+
maxHeight: "350px",
19+
overflow: "auto",
20+
background: '#1D1F27',
21+
// color: '#f8f8f2',
22+
// whiteSpace: "pre-wrap",
23+
// textAlign: "left",
24+
// fontSize: "0.9em",
25+
// fontFamily: "Source Code Pro, monospace",
26+
marginBottom: "10px"
27+
}}>
28+
<CodeMirror
29+
value={content}
30+
options={{
31+
mode: 'javascript',
32+
theme: 'material',
33+
lineNumbers: true,
34+
preserveScrollPosition: true
35+
}}
36+
onBeforeChange={(editor, data, value) => {
37+
onCodeChange(value);
38+
}}
39+
onChange={(editor, data, value) => {
40+
41+
}}
42+
/>
43+
</div>
44+
}
45+
}
46+
47+
export default Editor;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React, { Suspense } from "react"
2+
const AngularHowToUse = React.lazy(() => import('./AngularHowToUse'));
3+
4+
export default function Loadable(props) {
5+
return (
6+
<div>
7+
<Suspense fallback={<div>Loading...</div>}>
8+
<AngularHowToUse {...props} />
9+
</Suspense>
10+
</div>
11+
);
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import React, { Component } from 'react';
2+
import PropTypes from 'prop-types';
3+
import Button from '@material-ui/core/Button';
4+
import Paper from '@material-ui/core/Paper';
5+
import Tabs from '@material-ui/core/Tabs';
6+
import Tab from '@material-ui/core/Tab';
7+
import Editor from './Editor';
8+
9+
class TryMe extends Component {
10+
static propTypes = {
11+
name: PropTypes.string.isRequired,
12+
onCodeChange: PropTypes.func.isRequired,
13+
activeKey: PropTypes.number.isRequired,
14+
tagKey: PropTypes.number.isRequired,
15+
samples: PropTypes.arrayOf(
16+
PropTypes.shape({
17+
caption: PropTypes.string.isRequired,
18+
url: PropTypes.string.isRequired,
19+
content: PropTypes.string.isRequired,
20+
defaultUrl: PropTypes.string.isRequired,
21+
defaultContent: PropTypes.string.isRequired
22+
})
23+
).isRequired,
24+
classes: PropTypes.any
25+
};
26+
27+
constructor(props) {
28+
super(props);
29+
this.setActiveSample = this.setActiveSample.bind(this);
30+
this.tryIt = this.tryIt.bind(this);
31+
this.resetSample = this.resetSample.bind(this);
32+
this.onEditorValueChange = this.onEditorValueChange.bind(this);
33+
34+
const { samples, activeKey } = props;
35+
this.state = {
36+
samples,
37+
activeKey
38+
};
39+
}
40+
41+
componentWillReceiveProps({ onCodeChange, samples, activeKey }) {
42+
this.setState({
43+
onCodeChange, // eslint-disable-line react/no-unused-state
44+
samples,
45+
activeKey
46+
});
47+
}
48+
49+
onEditorValueChange(text) {
50+
const { samples, activeKey } = this.state;
51+
this.setState({
52+
samples: samples.map((sample, index) => {
53+
if (index === activeKey) {
54+
const newSample = { ...sample };
55+
newSample.content = text;
56+
return newSample;
57+
}
58+
return sample;
59+
})
60+
});
61+
}
62+
63+
setActiveSample(activeKey) {
64+
this.setState({
65+
activeKey
66+
});
67+
}
68+
69+
tryIt() {
70+
const { onCodeChange } = this.props;
71+
const { activeKey, samples } = this.state;
72+
const { content } = samples[activeKey];
73+
onCodeChange(activeKey, content);
74+
}
75+
76+
resetSample() {
77+
const { activeKey, samples } = this.state;
78+
this.setState({
79+
samples: samples.map((sample, index) => {
80+
if (index === activeKey) {
81+
const newSample = { ...sample };
82+
newSample.url = sample.defaultUrl;
83+
newSample.content = sample.defaultContent;
84+
return newSample;
85+
}
86+
return sample;
87+
})
88+
});
89+
}
90+
91+
render() {
92+
const { name, tagKey } = this.props;
93+
const { samples, activeKey } = this.state;
94+
const { url, content } = samples[activeKey];
95+
return (
96+
<div key={tagKey}>
97+
<Paper square>
98+
<Tabs
99+
id={name}
100+
value={activeKey}
101+
onChange={(event, key) => this.setActiveSample(key)}
102+
aria-label="Samples"
103+
indicatorColor="primary"
104+
textColor="primary"
105+
>
106+
{samples.map(({ caption }, index) => (
107+
<Tab value={index} key={`tab${index}`} label={caption} />
108+
))}
109+
</Tabs>
110+
</Paper>
111+
<Editor content={content} onCodeChange={this.onEditorValueChange} />
112+
<div style={{width: "100%", border: "none", padding: "10px"}}>
113+
<Button variant="contained" color="primary" onClick={() => this.resetSample()}>Reset code value</Button>
114+
&nbsp;
115+
<Button variant="contained" color="primary" onClick={() => this.tryIt()}>Try it >></Button>
116+
</div>
117+
<Paper square>
118+
<iframe title="placeholder" src={url} style={{width: "100%", height: "540px", border: "none"}} />
119+
</Paper>
120+
</div>
121+
);
122+
}
123+
}
124+
125+
export default TryMe;

client/src/containers/AngularUseCases/railscasts.css

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/src/containers/index.js

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import useCases from './UseCases/UseCases';
2121
import howToUse from './UseCases/Loadable';
2222
import reactUseCases from './ReactUseCases/ReactUseCases';
2323
import reactHowToUse from './ReactUseCases/Loadable';
24+
import angularUseCases from './AngularUseCases/AngularUseCases';
25+
import angularHowToUse from './AngularUseCases/Loadable';
2426
import reference from './Reference/Loadable';
2527
import apiReference from './Reference/ApiReference';
2628
import changelog from './Changelog/Changelog';
@@ -50,8 +52,10 @@ export const TechTree = techTree;
5052
export const Partners = partners;
5153
export const ReactUseCases = reactUseCases;
5254
export const UseCases = useCases;
55+
export const AngularUseCases = angularUseCases;
5356
export const ReactHowToUse = reactHowToUse;
5457
export const HowToUse = howToUse;
58+
export const AngularHowToUse = angularHowToUse;
5559
export const ApiReference = apiReference;
5660
export const Reference = reference;
5761
export const Changelog = changelog;

0 commit comments

Comments
 (0)