React-Router-SPA-Netlify
Reactは最終的にbundle.jsに全てを襲爵するSingle Page App, SPAである
しかしRouteを使うことによってRequestが来た時に擬似的に複数ページを ユーザーに見せることができる.やってみる
why
職場のコーポレートサイト制作での複数ページ導入に.
code
$ npm install -S react-router-dom
参考にしてindex.jsで
import { BrowserRouter as Router, Route, Switch, } from 'react-router-dom'; import App from './App'; import Works from './components/Works'; ......... ReactDOM.render( <Router> <div> <Route exact path='/' component={App} /> <Route path='/works' component={Works} /> </div> </Router>, document.getElementById('root') );
を埋め込む
そしてWorksを作成し,一部書き換え
<Col className='py-3 bg-secondary' xs={9} > 電球,蛍光灯,電池交換,テレビ,エアコン, </Col>
urlで /works/にアクセスすると表示された!
しかしdeployしたnetlifyではダメだった
tried
とりあえずマッチしなければAppに返すようにSwitchで挟む
そういうわけにはいかない,exactにしてみた.効果はない
大文字にした,効果はない
componentでそのまま渡してるんだから,src/components/Works
からAppと並列のsrc/Worksにする
<Route exact path='/App' component={App} />
これを追加して,deploy先でRouterが読まれているかのテストとする
動いていない
[https://reacttraining.com/react-router/web/guides/quick-start:embed:cite]
この例を見るとRouteの中にComponentを入れているので こっちらで試してみる
<Switch> <Route path="/about"> <About /> </Route> <Route path="/users"> <Users /> </Route> <Route path="/"> <Home /> </Route> </Switch>
このやり方ではErrorになったのでぼつ
https://codeburst.io/getting-started-with-react-router-5c978f70df91codeburst.io
このページのやり方
<Router> <div> <Route exact path="/" component={App} /> <Route path="/users" component={Users} /> <Route path="/contact" component={Contact} /> </div> </Router>
https://codeburst.io/getting-started-with-react-router-5c978f70df91
もerrorになる
Netlifyがredirectを弾いてるのが原因らしい?
/static/_redirects に以下の内容を記載。
/* /index.html 200
なのでdefaultのauto-deployからcliでのdeployにする必要が出てくる
npm でcli をinstall
netlify linkでcurrent github projectにset
そしてstatic/ にさっきの_redirect fileをさくせい
... しかしこれをやってもRouteはできなかった....
とにかくNetlifyの問題なのか,firebase hosting している2chの
projectの方で見てみよう
2chにappそのままでrouterを追加
npm run build , firebase deploy
ダメだった,defaultのpageにredirectされてしまう...
exactにしたらいった!!!
firebase hostingでのrouting完了!!!!!ヨシ!!!!
いろいろ調べたところ、netlify のデフォルトの設定だと、/build の直下に _redirect ファイルを置くべきでした。
— りょう@WEB エンジニア (@ryocoding) May 14, 2020
神が教えてくださった.....
static/ ではなくbulid/に直接おいたらできた!!!!
netlify public document にあったそうだ,そうかhostのredirectのページか....
なのでNetlifyでReact-routerを使う場合は
npm install netlify-cli -g
npm run build
cp _redirect builld/
netlify deploy
をする必要がある.
Hugo
Hogeの仲間の無意味語ではない!
そもそもSPAではrouteをする手間がかかる.
しかしhtml cssだけでかくと変更があったときに全身から血が吹き出して死ぬ.
それを防ぐための静的ジェネレーターにHugoがあるとたふみさんから
教えていただいた.
未検証.dataからhtmlを生成できるようだ.
Excel 実践の授業 感想
## why 2020.05
Twitterのbloggerは感想を書くことを条件に本がもらえるキャンペーンで,linkからformにblogのurlを入れて申し込んだら当選した
「当選は発想を持って変えさえていただきます」
なので連絡などは一切なかった
https://nihonzuno.co.jp/books-present-campaign/
how
職場に置いたが,まず紐とじなので開きやすくて好評だった
またさらっとauto fillから書かれていて使いやすい
文字も,職場での重複日報の検知作業に役立ち,MATCH()を使って
重複を見抜く式が書け,実務で役に立った
今後も更新していきます
またindirectなども分かりやすく例文を用いて書かれていて、ググる前のインデックスとしてパラパラ捲るのに重宝しています。
CSS Sidebar by React bootstrap Grid
why
HP Builderで作成された電気屋のHPの改修をやっている
非推奨であるiFrameのSideBarのNavigationをなるべく近いデザインで置き換える際に,Bootstrap Gridを採用したのでここに記す.
これがBootstrap Grid
なおRowとColを包括するタグは,Containerになる.
import {Container, Row, Col} from 'react-bootstrap'; ...... return ( <Container> <Row> <Col>1 of 2</Col> <Col>2 of 2</Col> </Row> <Row> <Col>1 of 3</Col> <Col>2 of 3</Col> <Col>3 of 3</Col> </Row> </Container> );
簡単なGrid ならこれで組める
html css にクラスをつけるよりかなりわかりやすい.
この公式サンプルの通りに配置すると,上の1/2が下の1/3と同じ位置
上の2/2 が2/3と3/3の間の位置になる
Bootstrap4と言えど流石に最初から水色のいい感じのレイアウト は付いていないので,(Tableではない)
これをみながらclassをつけて修飾する
MUIの方がPaperなどがあるのが魅力的に見える.
基本的に12分割で設定されている.
上のmarginを開けるのは
<Container className='my-4'>
であいた
これで
3 col 分の広さで横は揃った,あとは縦
paddingをつけたいが,Rowだけじゃ駄目で,Col一つ一つにつけない
先頭のColだけでもこうなる
[f:id:kei_s_lifehack:20200510112347p:plain]
<Container className='my-5'> <Row> <Col className='py-5 bg-danger' xs={3}>1 to 3, top-logo </Col> <Col className='py-5 bg-secondary' xs={2}>4 to 5, big-logo</Col> <Col className='py-5 bg-danger' xs={7}>6 to 13, text... </Col> </Row> <Row> <Col className='py-3 bg-info' xs={3}>HOME BTN</Col> <Col className='py-3 bg-danger' xs={2}>BLANK</Col> <Col className='py-3 bg-secondary' xs={7}>BLANK</Col> </Row> <Row> <Col className='py-3 bg-info' xs={3}>NEW INFO</Col> <Col className='py-3 bg-secondary' xs={2}>SHOP 1 NAME</Col> <Col className='py-3 bg-danger' xs={7}>SHOP 1 TEL</Col> </Row> <Row> <Col className='py-3 bg-info' xs={3}>ABOUT WORK</Col> <Col className='py-3 bg-danger' xs={2}>BLANK</Col> <Col className='py-3 bg-secondary' xs={7}>BLANK</Col> </Row>
ついでに色もつけた
両サイドが空いているのはcontainerだからで
マックスにするにはcontainer-fluidにする必要がある
縦の結合
だが縦の結合ができなかった
素のCSSで書いていた時はclassごとにrow 1/2 col 3/2とかやっていたから,
start とendで合わせるか?
そして公式ドキュメントにはgird colは12がdefltとある
どうやらこのサイトによると
これで列の改行ができて
このHTMLのtableのサイトだと
<Col md={{span: 4}}>1 </Col>
のspanもxs={4}も変わらない
だがRowにSpanやxsをつけても盾が広がらない!!
offsetで隙間を開ければ!
<Row> <Col className='py-3 bg-primary' xs={3} offset={9} >HOME BTN</Col> </Row>
隙間が空いた!が,入らない!
入れ子でcontainerと分ければ作れる!!!
ようやくProgressだ....
Col md 4の中にsidemenuを入れる
Col md 8の中にCardcontainerを入れる
logoの真ん中寄はd-blockでやった
sidebarはmapを駆使してわかりやすく書くことができた
const SideMenu = () => { const navText = [ 'NEW INFO', 'ABOUT WORKS', 'PARTS ORDER', 'AIRCON CLEAN', 'LINKS', ]; const navItems = navText.map((item, key) => <Row> <Col className='py-3 bg-info ' > <h5 key={item}>{item}</h5> </Col> </Row> ); return ( <div> {navItems} </div> ); }; export default SideMenu;
これでmenuが増えた時も簡単に描ける
最終的に
<Container className='my-5'> <Header /> <Row> <Col className='py-3 bg-primary' xs={3} > <SideMenu /> </Col> <Col className='py-3 bg-secondary' xs={9} > <Body /> </Col> </Row>
2/12, 10/12, でSideMenuとBodyを分割し
import NavData from '../NavDataList' const SideMenu = () => { const navItems = NavData.map((item, key) => <Row key={item} className=''> <Col className='py-1 my-1 ' > <Button variant="light" href={item.link} size='lg' className='w-100' >{item.name}</Button> </Col> </Row> ); return ( <div> {navItems} </div> ); };
py-3で下にpaddingをつけながら,一つのColで出力することで
入れ子構造にして,SideMenuが実装できた.
そもそもSideMenuはGridで実装すべきではない?
中央揃えにしたlogoとずれるし,ただでさえ.containerで
サイドカットしてるのでSideMenuで2/12はとるとやばい
Make-2ch-log
まずAppの中身をCLEAR
Bootstrap4をnpmで食わせる
npm i bootstrap
4.4.1が入った
npm i react-bootstrap
これも必要?1.01が入った
import 'bootstrap/dist/css/bootstrap.min.css';
これをimportして
import Button from 'react-bootstrap/Button';
btnで試してみる
<Button variant="primary">Primary</Button>{' '}
Appのrenderにこれを書いたら読み込まれた!
[f:id:kei_s_lifehack:20200507051109p:plain]
[https://react-bootstrap.github.io/components/table/:embed:cite]
Reactだとかなりsimpleにbootstrapがかける
[f:id:kei_s_lifehack:20200507051254p:plain]
しかし2chのUIはこれ
[f:id:kei_s_lifehack:20200507052547p:plain]
tableのUIはこれ
[f:id:kei_s_lifehack:20200507052610p:plain]
次の行にcontentsかけないし,columnの幅も調整できん
grid三つ書くしかないか?
[f:id:kei_s_lifehack:20200507120627p:plain]
思ったよりいい感じになった
import React from 'react'; import Writing from './components/Writing'; function App() { return ( <div> <Writing/ > </div> ); } export default App;
App側を簡単にかけるの便利だ
Database
まずはconsoleでfirestoreで
Add Firebase to Your AppのところでNick Name
firestoreを書いていく まずは src/Config/config.jsに
Add Firebase to Your AppのところでNick Name
npm i firebase
import firebase from 'firebase/app'; const firebaseConfig = ... { apiKey = xxxxxx; const firebaseApp = firebase.initializeApp(config); export const firestore = firebaseApp.firestore(); ..... }
これをfirestoreとしてWritingでimport
refにuseStateを使ってみよう!!
constructor直下に
this.ref = firebase.firestore().collection('notes');
で書いていたのを
const [ref, setRef] = useState[ firebase.firestore().collection('writings')];
に置き換える
useEffectがわからんが,どうやらcomponentWillMountに近いものらしい
[https://qiita.com/keiya01/items/fc5c725fed1ec53c24c5#%E8%89%AF%E3%81%84%E4%BE%8B-3:embed:cite]
この記事によると
useEffect( () => { const time = setInterval(() => { dispatch({ type: "ADD_COUNT" }); }, state.tick); return () => clearInterval(time); }, [ state.tick ] );
これでstate.tickが変化するたびに「副作用」として処理を追加できるらしい
function Example() { const [count, setCount] = useState(0); // Similar to componentDidMount and componentDidUpdate: useEffect(() => { // Update the document title using the browser API document.title = `You clicked ${count} times`; }); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
公式にはこのような記載がある.htmlのtitleも変更できるようだ
このコードでは[]に最後に入れてないから,何も入れてなければbrowser APIで何か 変数が更新されたのを検知してuseEffectをうごかすのだろうか.
TypeError: storeRef.onShapshot is not a function (anonymous function) src/components/Writing.jsx:37 34 | 35 | useEffect( 36 | () => {
37 | let unsub = storeRef.onShapshot( | ^ 38 | update 39 | ); 40 | }
storeRef.onShapShotがuseEffectではとれない....
storeRefの中身は確認してある.hooksでclassのやり方はできないようだ
全部はわからんがここのコードを使ってみる
export const createWrintings = (writings) => { return storeRef.add({ created: firebase.firestore.FieldValue.serverTimestamp(), content: writings, }); };
create, addは簡単に作れた.stateは使わないようだ
SHOWができないから
これを使ってみる
react-firebase-hooks というツールを使う
npm install --save react-firebase-hooks
Writing.jsxにはいつもの
import firebase from 'firebase/app'; import { firestore } from '../Config/config';
の他に
import {useCollectionData} from 'react-firebase-hooks/firestore';
をしてさっきnpm i したのを読んで
const [values, loading, error,] = useCollectionData( ref, {idField: 'id'});
で設定する
if(loading) { return <div>Loading...</div> } if(error) { return <div>{`Error: ${error.message}`}</div> }
loading, errorではこれらを返し
return ( <ul> {values.map(value => ( <li key = {value.id}>{value.content}</li> ))} </ul> )
return ではvalueをmapするだけ doc...とか一切必要がない
これだけでfirestore collectionからDOMに書き込めた
valuesをcllすると
(2) [{…}, {…}] 0: {created_at: t, content: "俺みたいな中3でグロ見てる腐れ野郎、他に、いますかっていねーか、はは", id: "KwONQGM2AyLohkGOTF3u"} 1: {created_at: t, content: "初カキコ,ども...", id: "LIGRzMJJdxM1pJAo5R3L"} length: 2 __proto__: Array(0)
ちゃんと入っている!!!これをcreated_atでsortすれば行けそうだ.
idFieldでidを取得するところがポイントです。
と書いてある通りに,doc.idがdoc.data()と並列で入っている!!
また,記事のNewTodoの通りに
const Add = () => { const [content, setContent] = useState(''); const [pending, setPending] = useState(false); const add = async () => { setContent(''); setPending(true); try { await ref.add({ content, created_at: firebase.firestore.FieldValue.serverTimestamp(), }); } finally { setPending(false); } }
useStateを使ってcontentを空のstr, pendingをfalseでstateとして初期化
そして追加btnが押された時のaddの処理を書く.
asyncを噛ませてcontentを空にし,実行中ということでpendingをtrueに
tryではawaitが使われるのでこちらが先になるのか?
setContent('')が行われていないのでcontentは残っている.これが先に refにcreated_atとともに追加される
そしてtryが終わった後にpendingをfalse, NOに書きかえる
その後async前半が処理されてinput valueのcontentが空になり pendingがfalseになる.
このaddを
return ( <div> <input value = {content} onChange={e => setContent(e.target.value)} /> <button onClick={add} > Add </button> {pending && 'Pending...'} </div>
returnでinputを作り,valueには常にcontentを置き, onChangeにsetContentをしてe.target.valueをおく.
btnのonClickでaddがfireするように仕込み,
その下にはpendingがtrueの時のみ出るようにする
このComponentをAppで読み込むことによって
追加機能のあるinputとbtnが配備された.
Wesのよりかなりシンプルだ
どのcomponentでもrefは使っているので,Appで呼び出してpropsで渡そうか
しかしありえんほど簡単に
毎回firestoreをconsolelogで使用しているのもおかしいので改善策を感がてみた
config のままexportして,各自のcomponentでinitする作戦は
objのconfigをうまくconfigとしてexportできずにerror
import config from '../Config/config';
firebase.initializeApp(config);
これでうまくいきそうだが,これでもno -usedになってしまう
App側で済ますのも無理だった
これは仕方ないのかもしれない
export const firestore = firebase.initializeApp(config);
をconfig.jsに書いて
import {firestore} from '../Config/config';
をfirestore使う全てのcomponentに書くのは避けられないようだ;;;;;;
timestamp 出ないけど大まかなレイアウトは下
sort
timestampの値でsortがしたい
[1, 2,3, ] ならarr.sortで簡単だがarrのobjが必要
created_atの中身は
created_at: t nanoseconds: 964000000 seconds: 1589391378
である
これを普通に出そうとしたらめっちゃ詰まった
まぁ2020.05.21に解決して,例外処理挟んで出せるようになった, UIも書いた
ここで
React使っててなぜXSSが防げてるのかなんもわからん
dangerouslySetInnerHTMLを使うとXSSできるようになりますよ!() やれるもんならやってみて下さいよ! Add関数壊れてるわよ
おもちゃかコレェ!!!!!!!(言いたかっただけ)
動かしてなぜ動かないかわからん...
短くかける!!!と思ってここのsetTitleのところを流用してadd関数を作った
import React, { useState } from "react"; import {Col, Row,} from 'react-bootstrap'; import {Form} from 'react-bootstrap'; import {Button} from 'react-bootstrap'; import firebase from 'firebase/app'; import { firestore } from '../Config/config'; const ref = firebase.firestore().collection('writings'); const Add = () => { const [content, setContent] = useState(''); const [pending, setPending] = useState(false); const add = async () => { setContent(''); setPending(true); try { await ref.add({ content: content, created_at: firebase.firestore.FieldValue.serverTimestamp, }); } finally { setPending(false); } } return ( <div> <Form> <Row> <Col md = {7}> <Form.Control placeholder='write here' value = {content} onChange={e => setContent(e.target.value)} /> </Col> <Col md = {5}> <Button variant="primary" type="submit" onClick={add} > Submit </Button> </Col> </Row> </Form> {pending && 'Pending...'} </div> ) }; export default Add;
これを自分のちんちんで...じゃなくて自分で入れてbuttton押すと, 動いているように見えるが中身が入らない
エラーも出ないしわからない....
最初は動いてたもん,自分で自分のちんちん舐めたいって入れないし...
そんなに身体が柔らかくないので...(そういう問題?)
firestore追加されない問題
2020.05.30. 解決を図る.
const ref = firebase.firestore().collection('writings'); const Add = () => { const [content, setContent] = useState(''); const [pending, setPending] = useState(false); const add = async () => { setContent(''); setPending(true); try { console.log('adding'); await ref.add({ content: content, created_at: firebase.firestore.FieldValue.serverTimestamp, }); } finally { setPending(false); } }
こうしてconsole.log addingは一瞬見える.
追加中に画面が切り替わっているのだろうか?
ちんちんが追加された時はそういえばBootstrapは使っていなかった
このBtnが何か悪いのだろうか
Firebase CLI で React App を Hosting する
Firebase + ReactのHosting やり方
なぜ?
よく忘れるからドキュメンテーション!
Console of Firebase ( Browser )
Firebase consoleでcreate project
そして真っ先にdatabaseからcloud firestoreを作成する
ここでlocationの選択が出てくる, asia-northeastを選択
また消して作り直す場合は、trash から消えるのを待つ必要があるので
30日同じ名前を使えないので注意。
Terminal
ターミナルで適当なディレクトリを作成して
npm install -g firebase-tools
firebase-tools を install する
npm i firebase ではない
firebase login
これで Chrome が開いてログイン処理できる。
firebase init
TUI設定開始
Firestore, Hositing を選択
use an existing projectを選択
使うプロジェクトを選択する
? What do you want to use as your public directory? public ? Configure as a single-page app (rewrite all urls to /index.html)? Yes ✔ Wrote public/index.html i Writing configuration info to firebase.json... i Writing project information to .firebaserc... i Writing gitignore file to .gitignore... ✔ Firebase initialization complete!
これで init が終わった。
firebase deploy
これでデプロイできる
ソースを見てみる
生成されたソースを見ると、app, auth, database, message, storage,
そして init がローカルな処理?
<script src="/__/firebase/7.14.2/firebase-app.js"></script> <script src="/__/firebase/7.14.2/firebase-auth.js"></script> <script src="/__/firebase/7.14.2/firebase-database.js"></script> <script src="/__/firebase/7.14.2/firebase-messaging.js"></script> <script src="/__/firebase/7.14.2/firebase-storage.js"></script> <!-- initialize the SDK after all desired features are loaded --> <script src="/__/firebase/init.js"></script>
webで見れる.拡張子はnetlifyと同じ.app
ソースを書き換えると反応した
React
これを参考にする
portfolioと言う名のprojectならまずfirebase設定するときに作った
code/portofolio/で npx create react app portfolio
cd portfolio/
親dirにあるpublic/ はindex.htmlしかないからrm -rf
残りを全てmv * ..で持ってくる
package.jsonはfirebaseの方にはないからNO CONFLICT
中の方の node_modules/ は放棄
とりあえずportfolio/ でnpm i (package.jsonのdataからreact動かすため?)
そしてnpm startでlocalでreactが動作する
firebase.jsonのpublic: publicをbuild/に書き換える
そしてnpm run build, firebase deploy
これでbuild先で動く.(https://portfolio0902.web.app/)
Database crud
別の記事に書く
懸念点
spark(free)planでは作成数に上限がある……
PRJを作る度にLimitに近づいているカウントがされていく。
これは既存の適当に乱立したPRJを全て削除してもリセットされない。
削除したprojectが30days立つまで減るのを待つ必要がある.
FTP SoftでのHPのupload
why, なぜFTP?
職場のhogedenki.comが消滅した.どのサービスを使っていたかも不明だ.
そこでサブで使われていたHP builderで94年とかに作られたwin96らしいカラフルなサイトを更新することになり,いにしえの書類が発掘されて最終的に接続に成功した.
職場のHPがFTPというソフトを使った方式だった.
site name, id, passなどでloginするとGUIで,右半分がServer, 左がlocalのdirになる.
これで適当にVScodeとかで開いてpushすると反映される.
git を使いなれている私にはFTPソフトでのpushは非常に面倒だ,
まず私がMacで開発したものをgithubにあげて後輩くんにDLさせてFTPさせる方式では,個人情報のあるサイトデータをpublicにするわけには行かないので面倒
またNetlifyみたいにauto buildしてくれなく,bulidしたもののエントリーポイントをどうするかも難しい
フォロワーにCUIでやれる方法もあると教えてもらった
passwordを私のpcにも打ち込んでいいならこれで実装しよう...
npm build
buildしたreact-appはopen index.htmlで開いても動かない.
localhostでnpm startするか,NetlifyやFirebaseのserverに上げれば
動いた.
しかしFTPの静的環境ではそんなことはやってくれないだろう.
なのでbuild/index.htmlを開いてreact-appが正常に動いてる状況で
File Trasportする必要が出てきた
こちらに書いてあるように
package.jsonに
"homepage": "."
を追加してもだめだった.
React Material-UIを使ってみた
why
職場のサイトを作ることになって,headerを作るのに採択した
mediumを参考にする
npm install @material-ui/core --save
npm i contentful --save
import React from 'react' import AppBar from '@material-ui/core/AppBar' import Toolbar from '@material-ui/core/Toolbar' import Typography from '@material-ui/core/Typography' const NavBar = () => { return( <div> <AppBar position="static"> <Toolbar> <Typography variant="title" color="inherit"> React & Material-UI Sample Application </Typography> </Toolbar> </AppBar> </div> ) } export default NavBar;
NavBarのコードをコピペ
dependenciesのpackage.jsonも含めてpushするとできた
だが公式ドキュメントを読んでも複雑で,自分で組み合わせられそうにない
これはこのまま使えるらしい?
これならそのままcopyして使えるらしいが,Starbarがresolveできなかった..消したら動いた.
Androidの情報が多い
ここからパーツのまとまりをみていく
material-ui/Pricing.js at master · mui-org/material-ui · GitHub
Appbarを見ると
<AppBar position="static" color="default" elevation={0} className={classes.appBar}> <Toolbar className={classes.toolbar}> <Typography variant="h6" color="inherit" noWrap className={classes.toolbarTitle}> Company name </Typography> <nav> <Link variant="button" color="textPrimary" href="#" className={classes.link}> Features </Link> <Link variant="button" color="textPrimary" href="#" className={classes.link}> Enterprise </Link> <Link variant="button" color="textPrimary" href="#" className={classes.link}> Support </Link> </nav> <Button href="#" color="primary" variant="outlined" className={classes.link}> Login </Button> </Toolbar> </AppBar>
になっていて
AppBar, Toolbar, Typography, Link, Button,
が使われている,全てimportする
classNameが必要,useStylesでかなり定義されているからその
import { makeStyles } from '@material-ui/core/styles';
も入れて先に変数で宣言しておく必要がある
const useStyles = makeStyles((theme) => ({ '@global': { ul: { margin: 0, padding: 0, listStyle: 'none', }, }, appBar: { borderBottom: `1px solid ${theme.palette.divider}`, }, .......
そしてfunction App()のなかに
const classes = useStyles();
これを宣言
もちろんこれも必要
npm install @material-ui/core
これでこのコードだけで
const useStyles = makeStyles((theme) => ({ '@global': { ul: { margin: 0, padding: 0, listStyle: 'none', }, }, appBar: { borderBottom: `1px solid ${theme.palette.divider}`, }, toolbar: { flexWrap: 'wrap', }, toolbarTitle: { flexGrow: 1, }, link: { margin: theme.spacing(1, 1.5), }, })); function App() { const classes = useStyles(); return (
このheaderが実装できた
ではこのUIを動かしてみよう.サンプルテンプレを見せて言われたのはheaderが小さい,文字が小さいだったからそれを変えてみる
下記では全て変化がない.
appBar: { padding: '100px', }, minHeight: 300, paddingTop: theme.spacing(5), <AppBar position="static" color="default" elevation={0} height='201%' >
ul globalのpaddingを消してもダメだ
この数値を変えたら動いた!
link: { margin: theme.spacing(1, 1.5), },
だが,Appbarに適用しても変化がない
defaultの大きさはこれだ
そもそもAppbar, Toolbar, ToolbarTitle, linkの関係性ってなんだ?
とりあえずlink全てにmgnを渡すことによってくっつくことをpreventしている
toolbarでspacingの2nd argを増やすと左に寄る (mgn rightか?)
margin: theme.spacing(0, 20),
この時tool titleのいちは変わらないから,この二つは独立している.
当然1st argを増やすと下に膨らむ.
margin: theme.spacing(20, 0),
[f:id:kei_s_lifehack:20200504170731p:plain]
よってこれでheader barの大きさを調整できる.
次は左側にlogoを仕込みたい.
なぜCompany nameが真ん中になっているのかは
TypograhyとLinkの違いだ
[http://yucatio.hatenablog.com/entry/2018/12/20/090547:embed:cite]
このサイトを見るとLinkにlogоを入れて
<Link to='/'> <img src={logo} alt="TODODO(トドド)" height="36" width="auto"/> </Link>
inlineで大きさを調整している
このサイトを見ると
import AppBar from "@material-ui/core/AppBar"; import Grid from "@material-ui/core/Grid"; import { makeStyles } from "@material-ui/core/styles"; import Toolbar from "@material-ui/core/Toolbar"; import React from "react"; import { Tabs } from "@material-ui/core"; import Tab from "@material-ui/core/Tab"; const useStyles = makeStyles({ root: { flexGrow: 1 }, logo: { width: 135, height: 43.54 } }); const Header = () => { const classes = useStyles(); const [value, setValue] = React.useState(0); return ( <nav className={classes.root}> <AppBar position="static" color="default"> <Toolbar> <Grid justify={"space-between"} container> <Grid xs={1} item> <img className={classes.logo} src={ "https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg" } alt="Bosch Logo" /> </Grid> <Grid xs={4} item> <Grid container justify={"center"}> <Tabs onChange={(e, v) => setValue(v)} value={value} aria-label="Navigation Tabs" > <Tab label={"page 1"} /> <Tab label={"page 2"} /> </Tabs> </Grid> </Grid> <Grid item xs={1} /> </Grid> </Toolbar> </AppBar> </nav> ); }; export default Header;
Grid xs 1, 4, で割合を調節してるっぽい?
をコンテナとして
にimgのlogoをuseStylesでwidth: 135,height: 43.54, で入れて
それの後に
のなかに
を入れて
その後に
で空間調整している.
だからこの調節コードを消すと
右にずらされる
よし!!と思ったが
自動でresponsiveにしてくれるわけではなかった....
このままではCorp Siteには採用できない
media queryごとにgiridで書くか???
Grid
この記事もわかりやすい
とりあえずGridはわかりやすい.
ここを見るとflex-start, center, flex-endがよくわかる
headerで左右に分ける時はこれを分ければいいわけだ.
さっきのredditのcodeはspace-between でlogoを左において
距離をとって,flex-endでTabを右ヅメにしたわけだ.
また,paddingはtheme.spacing(2)
で取るのが一般的らしい.
普通に入れるカードはPaper, 文字を入れるのはTypography.
自動でmedia queryをやってくれるGridは見つからなかったが
Containerで幅をsm, smallに制限して
きゃりーさんの新作のように
元から狭い幅で作ってしまえば一つのlayoutですむかもしれない.
いや,流石にCorp Siteでこれは狭すぎるか....
Reactでmedia queryごとにcssを分けて書くのはどうやるんだろうか?
設計としてはこの記事がわかりやすい
table
Validateがうまくいっていればスマフォでもいい感じになるはずの
moneylogのこれは, bootstrap4のtable-responsiveで作ったが
Table React component - Material-UI
MUIには相当するものはなかった.
ただSortなど,使いこなせれば相当richだと思う.