2
0
mirror of https://github.com/iconify/iconify.git synced 2024-12-13 14:13:06 +00:00

Refactoring React: redo demo for offline component

This commit is contained in:
Vjacheslav Trushkin 2021-04-24 12:05:35 +03:00
parent 9fb87b1e61
commit 93856ba889
7 changed files with 378 additions and 154 deletions

View File

@ -21,17 +21,43 @@ section:after {
display: table;
clear: both;
}
h1 {
h1,
h2 {
margin: 0 0 16px;
padding: 0;
font-size: 24px;
font-weight: normal;
}
h2 {
margin: 16px 0;
font-size: 20px;
}
h1 + h2 {
margin-top: -8px;
}
p {
margin: 12px 0 4px;
padding: 0;
}
/* Tests */
.test-row {
font-size: 16px;
line-height: 1.5;
}
.test-row > svg {
color: #afafaf;
}
.test-row > svg.success {
color: #327335;
}
.test-row > svg.fail {
color: #ba3329;
}
.test-row > span {
padding-left: 4px;
}
/* 24px icon */
.icon-24 svg {
font-size: 24px;

View File

@ -5,15 +5,15 @@ import {
addIcon,
addCollection,
} from '@iconify/react/dist/offline';
import accountIcon from '@iconify-icons/mdi-light/account';
import alertIcon from '@iconify-icons/mdi-light/alert';
import homeIcon from '@iconify-icons/mdi-light/home';
import presentationPlay from '@iconify-icons/mdi-light/presentation-play';
import checkedIcon from '@iconify-icons/uil/check-circle';
import uncheckedIcon from '@iconify-icons/uil/circle';
import { Checkbox } from './components/Checkbox';
import { InlineDemo } from './components/Inline';
import { OfflineUsageDemo } from './components/UsageOffline';
import { TestsOffline } from './components/TestsOffline';
import './App.css';
@ -53,66 +53,10 @@ addCollection({
height: 24,
});
// Component
class CheckboxIcon extends React.Component {
constructor(props) {
super();
this.state = {
checked: props.checked,
};
this._check = this._check.bind(this);
}
render() {
const checked = this.state.checked;
const icon = checked ? checkedIcon : uncheckedIcon;
const color = checked ? 'green' : 'red';
return (
<InlineIcon
icon={icon}
onClick={this._check}
style={{ cursor: 'pointer', color }}
/>
);
}
_check(event) {
event.preventDefault();
this.setState({
checked: !this.state.checked,
});
}
}
function App() {
// Debug logging for testing references, which cannot be reliably tested with unit tests
console.log('References that should be logged: valid icon');
console.log('References that might be logged: missing icon');
console.log('References that should not be logged: missing text icon');
return (
<div className="App">
<section className="icon-24">
<h1>Usage</h1>
<div>
Empty icon: <Icon />
</div>
<div>
Icon referenced by name: <Icon icon="demo" />
</div>
<div>
Icon referenced by object: <Icon icon={accountIcon} />
</div>
<div>
2 icons imported from icon set:{' '}
<Icon icon="mdi-light:account-alert" />
<Icon icon="mdi-light:link" />
</div>
<div className="alert">
<Icon icon={alertIcon} />
Important notice with alert icon!
</div>
</section>
<OfflineUsageDemo />
<section>
<h1>Checkbox</h1>
@ -132,97 +76,7 @@ function App() {
<InlineDemo />
<section>
<h1>Tests</h1>
<p>
<Icon
icon={homeIcon}
style={{
color: '#1769aa',
fontSize: '24px',
lineHeight: '1em',
verticalAlign: '-0.25em',
}}
/>
Home icon! 24px icon in 16px text with 24px line height,
aligned using inline style.
</p>
<p>
Empty icon (span): <Icon />
<br />
Empty icon (emoji): <Icon>😀</Icon>
<br />
Empty icon (em and emoji):
<Icon>
<em> empty</em>😀
</Icon>
</p>
<p>
Clickable icon (testing events and style): <CheckboxIcon />
</p>
<p>
Colored icons (block, inline, block):
<InlineIcon
icon={alertIcon}
style={{
fontSize: '1.5em',
verticalAlign: 0,
marginLeft: '8px',
}}
color="green"
/>
<InlineIcon
icon={alertIcon}
style={{
fontSize: '1.5em',
color: 'red',
marginLeft: '8px',
}}
/>
<Icon
icon={alertIcon}
style={{
fontSize: '1.5em',
color: 'purple',
marginLeft: '8px',
}}
/>
</p>
<p>
Testing reference by adding border to icon:{' '}
<Icon
icon="demo"
ref={(element) => {
console.log('Ref: valid icon');
element.style.border = '1px solid red';
}}
/>
<br />
Reference to missing icon:{' '}
<Icon
ref={(element) => {
console.log('Ref: missing icon');
element.style.border = '1px solid red';
}}
/>
<br />
Reference to missing icon with fallback text:{' '}
<Icon
ref={(element) => {
console.log('Ref: missing text icon');
element.style.border = '1px solid red';
}}
>
😀
</Icon>
</p>
<p>
Testing replacing ids in icons: <Icon icon="noto-robot" />{' '}
<Icon icon="noto-robot" /> (default handler)
<Icon icon="noto-robot" id="test1" />{' '}
<Icon icon="noto-robot" id="test2" /> (string)
</p>
</section>
<TestsOffline />
</div>
);
}

View File

@ -1,7 +1,7 @@
import React from 'react';
import { Icon } from '@iconify/react/dist/offline';
import checkedIcon from '@iconify-icons/uil/check-circle';
import uncheckedIcon from '@iconify-icons/uil/circle';
import checkedIcon from '@iconify-icons/uil/check-square';
import uncheckedIcon from '@iconify-icons/uil/square';
export class Checkbox extends React.Component {
constructor(props) {

View File

@ -4,7 +4,7 @@ import { Icon } from '@iconify/react/dist/offline';
export function InlineDemo() {
return (
<section className="inline-demo">
<h1>Inline (components/Inline.jsx)</h1>
<h1>Inline demo</h1>
<div>
Block icon (behaving like image):
<Icon icon="experiment2" />

View File

@ -0,0 +1,29 @@
import React from 'react';
import { InlineIcon } from '@iconify/react/dist/offline';
import successIcon from '@iconify-icons/uil/check-circle';
import pendingIcon from '@iconify-icons/uil/question-circle';
import failedIcon from '@iconify-icons/uil/times-circle';
export function TestIcon(props) {
let icon = pendingIcon;
let className = '';
switch (props.status) {
case 'success':
case 'default-success':
case true:
icon = successIcon;
className = 'success';
break;
case 'fail':
case false:
icon = failedIcon;
className = 'fail';
break;
default:
}
return <InlineIcon icon={icon} className={className} />;
}

View File

@ -0,0 +1,285 @@
import React from 'react';
import { InlineIcon } from '@iconify/react/dist/offline';
import { TestIcon } from './TestIcon';
export class TestsOffline extends React.Component {
constructor(props) {
super();
const state = {
ref_missing: 'default-success',
};
this.state = state;
}
render() {
const state = this.state;
const success = this._toggle.bind(this, 'success');
const fail = this._toggle.bind(this, 'fail');
return (
<section className="tests">
<h1>Tests (offline module)</h1>
<h2>References</h2>
<div className="test-row">
<TestIcon status={state.ref} />
<span>
Getting reference
<InlineIcon
icon="demo"
ref={(element) => {
const key = 'ref';
if (element && element.tagName === 'svg') {
success(key);
} else {
fail(key);
}
}}
/>
</span>
</div>
<div className="test-row">
<TestIcon status={state.ref_missing} />
<span>
Getting reference for empty icon
<InlineIcon
ref={(element) => {
// Cannot be called because there is no SVG to render!
fail('ref_missing');
}}
/>
</span>
</div>
<div className="test-row">
<TestIcon status={state.ref_missing} />
<span>
Getting reference for missing icon with fallback text{' '}
<InlineIcon
ref={(element) => {
// Cannot be called because there is no SVG to render!
fail('ref_missing');
}}
>
😀
</InlineIcon>
</span>
</div>
<h2>Style</h2>
<div className="test-row">
<TestIcon status={state.style} />
<span>
Inline style for icon
<InlineIcon
icon="demo"
style={{
color: '#1769aa',
fontSize: '24px',
lineHeight: '1em',
verticalAlign: '-0.25em',
}}
ref={(element) => {
const key = 'style';
if (element && element.tagName === 'svg') {
let errors = false;
// Get style
const style = element.style;
switch (style.color.toLowerCase()) {
case 'rgb(23, 105, 170)':
case '#1769aa':
break;
default:
console.log(
'Invalid color:',
style.color
);
errors = true;
}
if (style.fontSize !== '24px') {
console.log(
'Invalid font-size:',
style.fontSize
);
errors = true;
}
if (style.verticalAlign !== '-0.25em') {
console.log(
'Invalid vertical-align:',
style.verticalAlign
);
errors = true;
}
if (errors) {
fail(key);
} else {
success(key);
}
} else {
fail(key);
}
}}
/>
</span>
</div>
<div className="test-row">
<TestIcon status={state.color1} />
<span>
Green color from attribute:{' '}
<InlineIcon
icon="demo"
color="green"
ref={(element) => {
const key = 'color1';
if (element && element.tagName === 'svg') {
let errors = false;
// Get style
const style = element.style;
switch (style.color.toLowerCase()) {
case 'rgb(0, 128, 0)':
case '#008000':
case 'green':
break;
default:
console.log(
'Invalid color:',
style.color
);
errors = true;
}
if (errors) {
fail(key);
} else {
success(key);
}
} else {
fail(key);
}
}}
/>
</span>
</div>
<div className="test-row">
<TestIcon status={state.color2} />
<span>
Green color from style:{' '}
<InlineIcon
icon="demo"
style={{
color: 'green',
}}
ref={(element) => {
const key = 'color2';
if (element && element.tagName === 'svg') {
let errors = false;
// Get style
const style = element.style;
switch (style.color.toLowerCase()) {
case 'rgb(0, 128, 0)':
case '#008000':
case 'green':
break;
default:
console.log(
'Invalid color:',
style.color
);
errors = true;
}
if (errors) {
fail(key);
} else {
success(key);
}
} else {
fail(key);
}
}}
/>
</span>
</div>
<div className="test-row">
<TestIcon status={state.color3} />
<span>
Green color from attribute (overrides style) + red from
style:{' '}
<InlineIcon
icon="demo"
color="green"
style={{
color: 'red',
}}
ref={(element) => {
const key = 'color3';
if (element && element.tagName === 'svg') {
let errors = false;
// Get style
const style = element.style;
switch (style.color.toLowerCase()) {
case 'rgb(0, 128, 0)':
case '#008000':
case 'green':
break;
default:
console.log(
'Invalid color:',
style.color
);
errors = true;
}
if (errors) {
fail(key);
} else {
success(key);
}
} else {
fail(key);
}
}}
/>
</span>
</div>
</section>
);
}
_toggle(value, key) {
setTimeout(() => {
const oldValue = this.state[key];
if (
oldValue === value ||
oldValue === 'success' ||
oldValue === 'fail'
) {
return;
}
this.setState({
[key]: value,
});
});
}
}

View File

@ -0,0 +1,30 @@
import React from 'react';
import { Icon } from '@iconify/react/dist/offline';
import accountIcon from '@iconify-icons/mdi-light/account';
import alertIcon from '@iconify-icons/mdi-light/alert';
export function OfflineUsageDemo() {
return (
<section className="icon-24">
<h1>Usage (offline module)</h1>
<div>
Empty icon: <Icon />
</div>
<div>
Icon referenced by name: <Icon icon="demo" />
</div>
<div>
Icon referenced by object: <Icon icon={accountIcon} />
</div>
<div>
2 icons imported from icon set:{' '}
<Icon icon="mdi-light:account-alert" />
<Icon icon="mdi-light:link" />
</div>
<div className="alert">
<Icon icon={alertIcon} />
Important notice with alert icon!
</div>
</section>
);
}