on master help sign in
Merge pull request #225 from urbit/fix/mobile-styling

mobile related fixes to forms, hardware login, text wrapping, + more

commiteb9c739fc39f3d7e1ef126bf06128ead3c41160e authorMatt Condon <mattgcondon@gmail.com> dateMon 19 Aug 2019, 19:16 (7 years ago) parent6738c1464aee13
20 files changed+141−64
package.json+1−1 src/components/Accordion.js+17−3 src/components/Passport.js+1−1 src/components/Sigil.js+2−1 src/components/Tabs.js+27−26 src/components/View.js+1−1 src/indigo-react/components/Input.js+3−3 src/store/network.js+1−1 src/style/bridge.scss+4−18 src/style/form-reset.scss+47 src/style/index.scss+3 src/style/indigo-proposals.scss+8 src/views/AcceptTransfer.js+1−1 src/views/Admin/AdminCancelTransfer.js+1−1 src/views/Admin/AdminTransfer.js+1−1 src/views/CreateGalaxy.js+1−1 src/views/IssueChild.js+1−1 src/views/Login/Hardware.js+17−2 src/views/Party/PartySetPoolSize.js+1−1 src/views/Points.js+3−1
package.json+1−1
@@ -78,7 +78,7 @@
7878 "checksum": "cd build && find . -exec shasum -a256 {} ';' > ../checksums.txt && cd ..",
7979 "zip": "zip -ur bridge-$npm_package_version.zip README.md bridge-https.py checksums.txt && cd build && zip -ur ../bridge-$npm_package_version.zip ./* && cd ..",
8080 "release": "npm install && npm run build && npm run checksum && npm run zip",
81− "pilot:ganache": "ganache-cli --blockTime 1 --networkId 1 -m 'benefit crew supreme gesture quantum web media hazard theory mercy wing kitten' > /dev/null &",
81+ "pilot:ganache": "ganache-cli --blockTime 1 --networkId 1 --host '0.0.0.0' -m 'benefit crew supreme gesture quantum web media hazard theory mercy wing kitten' > /dev/null &",
8282 "pilot:deploy": "cd node_modules/azimuth-solidity && truffle deploy",
8383 "pilot:setup": "npm run pilot:ganache && npm run pilot:deploy",
8484 "pilot": "HTTPS=true npm-run-all pilot:setup start pilot:cleanup --continue-on-error",
src/components/Accordion.js+17−3
@@ -1,4 +1,5 @@
11import React from 'react';
2+import cn from 'classnames';
23import { Grid, AccessoryIcon } from 'indigo-react';
34
45export default function Accordion({
@@ -22,9 +23,19 @@ export default function Accordion({
2223 <React.Fragment key={option.value}>
2324 <Grid.Item
2425 full
25− className="f5 pv3 rel clickable"
26− onClick={() => onTabChange(isActive ? undefined : option.value)}>
26+ className={cn('f5 pv3 rel', {
27+ clickable: !option.disabled,
28+ gray3: option.disabled,
29+ })}
30+ onClick={
31+ option.disabled
32+ ? null
33+ : () => onTabChange(isActive ? undefined : option.value)
34+ }>
2735 {option.text}
36+ {option.disabled && (
37+ <sup className="f6 lowercase">{option.disabled}</sup>
38+ )}
2839 <div
2940 className="abs"
3041 style={{
@@ -34,7 +45,10 @@ export default function Accordion({
3445 width: '44px',
3546 overflow: 'hidden',
3647 }}>
37− <AccessoryIcon className="black">
48+ <AccessoryIcon
49+ className={cn({
50+ black: !option.disabled,
51+ })}>
3852 {isActive ? '▲' : '▼'}
3953 </AccessoryIcon>
4054 </div>
src/components/Passport.js+1−1
@@ -78,7 +78,7 @@ function Passport({ point, className, ticket = null, address = Nothing() }) {
7878 <MaybeSigil patp={name} size={64} />
7979 </Grid.Item>
8080 <Grid.Item as={Flex} cols={[4, 13]} col justify="between">
81− <Flex.Item className="mono white f5">{visualName}</Flex.Item>
81+ <Flex.Item className="mono white f5 pb2">{visualName}</Flex.Item>
8282 <Flex.Item as={Flex} col>
8383 <Flex.Item as={Text} className="mono f6 f5-ns gray4 uppercase">
8484 Birth Time
src/components/Sigil.js+2−1
@@ -4,8 +4,9 @@ export default function Sigil({ patp, size, colors, ...rest }) {
44 return sigil({
55 patp,
66 renderer: reactRenderer,
7− style: { width: '100%', height: '100%' }, //NOTE scale to container
7+ style: { width: '100%', height: '100%' }, // NOTE: scale to container
88 size,
9+ margin: size / 8,
910 colors,
1011 ...rest,
1112 });
src/components/Tabs.js+27−26
@@ -14,33 +14,34 @@ export default function Tabs({
1414
1515 return (
1616 <Grid className={className}>
17− <Grid.Item full as={Flex} wrap className="b-gray3 bb1">
18− {options.map((option, i) => {
19− const isActive = option.value === currentTab;
20− const isFirst = i === 0;
17+ <Grid.Item full as={Flex} className="b-gray3 bb1 scroll-x hidden-y">
18+ <Flex.Item as={Flex}>
19+ {options.map((option, i) => {
20+ const isActive = option.value === currentTab;
21+ const isFirst = i === 0;
2122
22− return (
23− <Flex.Item
24− key={option.value}
25− onClick={() => onTabChange(option.value)}
26− className={cn(
27− 'f5 pv3 clickable',
28− {
29− 'black b-black bb1': isActive,
30− gray3: !isActive,
31− },
32− {
33− // all items have right margin/padding
34− 'mr2 pr2': true,
35− // the first one is flush to the left
36− 'ml2 pl2': !isFirst,
37− }
38− )}
39− style={{ marginBottom: '-1px' }}>
40− {option.text}
41− </Flex.Item>
42− );
43− })}
23+ return (
24+ <Flex.Item
25+ key={option.value}
26+ onClick={() => onTabChange(option.value)}
27+ className={cn(
28+ 'f5 pv3 clickable nowrap',
29+ {
30+ 'black b-black bb1': isActive,
31+ gray3: !isActive,
32+ },
33+ {
34+ // all items have right margin/padding
35+ 'mr2 pr2': true,
36+ // the first one is flush to the left
37+ 'ml2 pl2': !isFirst,
38+ }
39+ )}>
40+ {option.text}
41+ </Flex.Item>
42+ );
43+ })}
44+ </Flex.Item>
4445 </Grid.Item>
4546 <Grid.Item full as={Tab} {...rest} />
4647 </Grid>
src/components/View.js+1−1
@@ -62,7 +62,7 @@ function View({
6262 <Flex.Item as={Footer.Target} />
6363 </Flex.Item>
6464
65− <Flex.Item style={{ width: '48px' }} className={cn(insetPadding)} />
65+ <Flex.Item style={{ width: '48px' }} />
6666 </Flex>
6767 );
6868}
src/indigo-react/components/Input.js+3−3
@@ -78,8 +78,8 @@ export default function Input({
7878 flex
7979 as={BaseComponent}
8080 {...rest}
81− // NOTE: 24px = 12px * 2 (from p3 styling)
82− style={type === 'textarea' ? { minHeight: 'calc(1rem + 24px)' } : {}}
81+ // NOTE: 1.15 from input line-height, 24px = 12px * 2 (from p3 styling)
82+ style={type === 'textarea' ? { minHeight: 'calc(1.5rem * 3)' } : {}}
8383 className={cn(
8484 'b b1 p3 outline-none bs-none',
8585 { mono },
@@ -110,7 +110,7 @@ export default function Input({
110110 top: 0,
111111 right: 0,
112112 height: '100%',
113− width: '44px',
113+ width: 'calc(1.5em + 24px)',
114114 overflow: 'hidden',
115115 }}>
116116 {accessory}
src/store/network.js+1−1
@@ -41,7 +41,7 @@ function _useNetwork(initialNetworkType = null) {
4141 switch (networkType) {
4242 case NETWORK_TYPES.LOCAL: {
4343 const protocol = isDevelopment ? 'ws' : 'wss';
44− const endpoint = `${protocol}://localhost:8545`;
44+ const endpoint = `${protocol}://${document.location.hostname}:8545`;
4545
4646 return initWeb3(
4747 new Web3.providers.WebsocketProvider(endpoint),
src/style/bridge.scss+4−18
@@ -1,18 +1,4 @@
1−@keyframes autofill {
2− to {
3− color: #000;
4− background: transparent;
5− }
6−}
7−
8−/* avoid yellow autofill highlight on browsers that respect this attribute */
9−input:-webkit-autofill {
10− animation-name: autofill;
11− animation-fill-mode: both;
12−
13− -webkit-animation-name: autofill;
14− -webkit-animation-fill-mode: both;
15−}
1+$handle-extent: 24px; // $lh-regular
162
173// min-height the top elements so footer behavior works correctly
184html {
@@ -36,7 +22,7 @@ input[type='range'] {
3622
3723 /* Chrome */
3824 &::-webkit-slider-runnable-track {
39− height: 24px;
25+ height: $handle-extent;
4026 -webkit-appearance: none;
4127 background-color: #e6e6e6;
4228 margin-top: -1px;
@@ -44,7 +30,7 @@ input[type='range'] {
4430
4531 &::-webkit-slider-thumb {
4632 -webkit-appearance: none;
47− width: 24px;
33+ width: $handle-extent;
4834 height: 100%;
4935 background-color: #000;
5036 border: none;
@@ -63,7 +49,7 @@ input[type='range'] {
6349 }
6450
6551 &::-moz-range-thumb {
66− width: 24px;
52+ width: $handle-extent;
6753 height: 100%;
6854 background-color: #000;
6955 border: none;
src/style/form-reset.scssnew file+47
@@ -0,0 +1,47 @@
1+$form-padding: 24px; // indigo pv3
2+$form-line-height: 1.5rem; // $lh-regular
3+
4+@keyframes autofill {
5+ to {
6+ color: #000;
7+ background: transparent;
8+ }
9+}
10+
11+input,
12+button,
13+textarea,
14+select {
15+ padding: 0;
16+ margin: 0;
17+ border-radius: 0;
18+ -webkit-appearance: none;
19+
20+ &:focus,
21+ &:hover,
22+ &:active {
23+ outline: 0;
24+ }
25+
26+ &::-moz-focus-inner {
27+ border: 0;
28+ }
29+}
30+
31+input {
32+ // enforce border-box
33+ box-sizing: border-box;
34+
35+ // enforce height & line-height for accessories
36+ height: calc(#{$form-line-height} + #{$form-padding});
37+ line-height: $form-line-height;
38+
39+ // avoid yellow autofill highlight on browsers that respect this attribute
40+ &:-webkit-autofill {
41+ animation-name: autofill;
42+ animation-fill-mode: both;
43+
44+ -webkit-animation-name: autofill;
45+ -webkit-animation-fill-mode: both;
46+ }
47+}
src/style/index.scss+3
@@ -1,3 +1,6 @@
1+/* Form Reset */
2+@import './form-reset.scss';
3+
14/* Indigo */
25@import '../indigo-react/indigo.css';
36@import './indigo-proposals.scss';
src/style/indigo-proposals.scss+8
@@ -52,3 +52,11 @@
5252.arial {
5353 font-family: Arial, monospace;
5454}
55+
56+.scroll-x {
57+ overflow-x: auto;
58+}
59+
60+.hidden-y {
61+ overflow-y: hidden;
62+}
src/views/AcceptTransfer.js+1−1
@@ -73,7 +73,7 @@ export default function AcceptTransfer() {
7373 <Grid.Item
7474 full
7575 as={Text}
76− className={cn('f5', {
76+ className={cn('f5 wrap', {
7777 green3: completed,
7878 })}>
7979 {completed
src/views/Admin/AdminCancelTransfer.js+1−1
@@ -65,7 +65,7 @@ export default function AdminCancelTransfer() {
6565 <Grid.Item
6666 full
6767 as={Text}
68− className={cn('f5', {
68+ className={cn('f5 wrap', {
6969 green3: completed,
7070 })}>
7171 {completed
src/views/Admin/AdminTransfer.js+1−1
@@ -78,7 +78,7 @@ export default function AdminTransfer() {
7878 <Grid.Item
7979 full
8080 as={Text}
81− className={cn('f5', {
81+ className={cn('f5 wrap', {
8282 green3: completed,
8383 })}>
8484 {completed
src/views/CreateGalaxy.js+1−1
@@ -123,7 +123,7 @@ export default function CreateGalaxy() {
123123 <Grid.Item
124124 full
125125 as={Text}
126− className={cn('f5', {
126+ className={cn('f5 wrap', {
127127 green3: completed,
128128 })}>
129129 {values.galaxyName} has been created and can be claimed by{' '}
src/views/IssueChild.js+1−1
@@ -149,7 +149,7 @@ export default function IssueChild() {
149149 <Grid.Item
150150 full
151151 as={Text}
152− className={cn('f5', {
152+ className={cn('f5 wrap', {
153153 green3: completed,
154154 })}>
155155 {values.point} has been spawned and can be claimed by{' '}
src/views/Login/Hardware.js+17−2
@@ -1,4 +1,6 @@
1−import React, { useState } from 'react';
1+import React, { useMemo, useState } from 'react';
2+
3+import useBreakpoints from 'lib/useBreakpoints';
24
35import Accordion from 'components/Accordion';
46
@@ -23,11 +25,24 @@ const OPTIONS = [
2325export default function Hardware({ className, ...rest }) {
2426 const [currentTab, setCurrentTab] = useState(undefined);
2527
28+ // using breakpoint to decide if we're on mobile or not
29+ // see ActivateCode for more details on this approach
30+ const hardwareAllowed = useBreakpoints([false, true, true]);
31+
32+ const options = useMemo(
33+ () =>
34+ OPTIONS.map(option => ({
35+ ...option,
36+ disabled: !hardwareAllowed && ' not availble on mobile',
37+ })),
38+ [hardwareAllowed]
39+ );
40+
2641 return (
2742 <Accordion
2843 className={className}
2944 views={VIEWS}
30− options={OPTIONS}
45+ options={options}
3146 currentTab={currentTab}
3247 onTabChange={setCurrentTab}
3348 //
src/views/Party/PartySetPoolSize.js+1−1
@@ -116,7 +116,7 @@ export default function PartySetPoolSize() {
116116 <Grid.Item
117117 full
118118 as={Text}
119− className={cn('f5', {
119+ className={cn('f5 wrap', {
120120 green3: completed,
121121 })}>
122122 {completed
src/views/Points.js+3−1
@@ -40,7 +40,9 @@ const PointList = function({ points, className, actions, ...rest }) {
4040 return (
4141 <Grid gap={3} className={className}>
4242 {points.map((point, i) => (
43− <Grid.Item half={(i % 2) + 1} key={point}>
43+ <Grid.Item
44+ key={point}
45+ className={`full half-${(i % 2) + 1}-md half-${(i % 2) + 1}-lg`}>
4446 <Flex col>
4547 <Passport.Mini
4648 point={point}