From 0753d0794de2b2bffeba89a08bf47032f8154ada Mon Sep 17 00:00:00 2001 From: Paul Kaplan <pkaplan@media.mit.edu> Date: Tue, 3 Apr 2018 15:36:25 -0400 Subject: [PATCH] Update design for editor tabs with icons, changing blocks to code. Resolves https://github.com/LLK/scratch-gui/issues/1713 --- src/components/gui/gui.css | 51 +++++++++++++++++++++++--- src/components/gui/gui.jsx | 41 +++++++++++++++++++-- src/components/gui/icon--code.svg | Bin 0 -> 1571 bytes src/components/gui/icon--costumes.svg | Bin 0 -> 2120 bytes src/components/gui/icon--sounds.svg | Bin 0 -> 2015 bytes test/integration/blocks.test.js | 4 +- test/integration/localization.test.js | 2 +- 7 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 src/components/gui/icon--code.svg create mode 100644 src/components/gui/icon--costumes.svg create mode 100644 src/components/gui/icon--sounds.svg diff --git a/src/components/gui/gui.css b/src/components/gui/gui.css index 5132af685..fa6c4ce1a 100644 --- a/src/components/gui/gui.css +++ b/src/components/gui/gui.css @@ -57,10 +57,13 @@ .tab { flex-grow: 1; height: 80%; - margin-left: 1px; + margin-left: -0.5rem; - border-radius: $space $space 0 0; - border: none; + border-radius: 1rem 1rem 0 0; + border: $ui-pane-border 1px solid; + + padding: 0.125rem 1rem 0; + font-size: 0.7rem; background-color: #F6F8FA; color: #9AA1B5; @@ -72,13 +75,49 @@ user-select: none; } -.tab.is-selected { +/* Use z-indices to force left-on-top for tabs */ +.tab:nth-of-type(1) { + margin-left: 0; + z-index: 3; +} +.tab:nth-of-type(2) { + z-index: 2; +} +.tab:nth-of-type(3) { z-index: 1; - color: #40B9F5; +} + +.tab.is-selected { + color: $motion-primary; background-color: #FFFFFF; - border-bottom: $ui-background-blue 1px solid; + z-index: 4; /* Make sure selected is always above */ +} + +.tab img { + margin-right: 0.125rem; + filter: grayscale(100%); +} + +.tab.is-selected img { + filter: none; +} + +/* Tab style overrides from react-tabs */ +.tab.is-selected:after { + display: none; +} + +.tab.is-selected:focus { + outline: none; + box-shadow: none; + border-color: $ui-pane-border; +} + +.tab.is-selected:focus:after { + display: none; } +/* Body of the tabs */ .tabs { position: relative; flex-grow: 1; diff --git a/src/components/gui/gui.jsx b/src/components/gui/gui.jsx index 2ec53402b..37a66c308 100644 --- a/src/components/gui/gui.jsx +++ b/src/components/gui/gui.jsx @@ -1,7 +1,7 @@ import classNames from 'classnames'; import PropTypes from 'prop-types'; import React from 'react'; -import {defineMessages, injectIntl, intlShape} from 'react-intl'; +import {defineMessages, FormattedMessage, injectIntl, intlShape} from 'react-intl'; import {Tab, Tabs, TabList, TabPanel} from 'react-tabs'; import MediaQuery from 'react-responsive'; import tabStyles from 'react-tabs/style/react-tabs.css'; @@ -25,6 +25,9 @@ import WebGlModal from '../../containers/webgl-modal.jsx'; import layout from '../../lib/layout-constants.js'; import styles from './gui.css'; import addExtensionIcon from './icon--extensions.svg'; +import codeIcon from './icon--code.svg'; +import costumesIcon from './icon--costumes.svg'; +import soundsIcon from './icon--sounds.svg'; const messages = defineMessages({ addExtension: { @@ -110,9 +113,39 @@ const GUIComponent = props => { onSelect={onActivateTab} > <TabList className={tabClassNames.tabList}> - <Tab className={tabClassNames.tab}>Blocks</Tab> - <Tab className={tabClassNames.tab}>Costumes</Tab> - <Tab className={tabClassNames.tab}>Sounds</Tab> + <Tab className={tabClassNames.tab}> + <img + draggable={false} + src={codeIcon} + /> + <FormattedMessage + defaultMessage="Code" + description="Button to get to the code panel" + id="gui.gui.codeTab" + /> + </Tab> + <Tab className={tabClassNames.tab}> + <img + draggable={false} + src={costumesIcon} + /> + <FormattedMessage + defaultMessage="Costumes" + description="Button to get to the costumes panel" + id="gui.gui.costumesTab" + /> + </Tab> + <Tab className={tabClassNames.tab}> + <img + draggable={false} + src={soundsIcon} + /> + <FormattedMessage + defaultMessage="Sounds" + description="Button to get to the sounds panel" + id="gui.gui.soundsTab" + /> + </Tab> </TabList> <TabPanel className={tabClassNames.tabPanel}> <Box className={styles.blocksWrapper}> diff --git a/src/components/gui/icon--code.svg b/src/components/gui/icon--code.svg new file mode 100644 index 0000000000000000000000000000000000000000..390e683b16da01b13bbe8a2df0a0ac0711d9451e GIT binary patch literal 1571 zcmcDqugJ|&C`&CW&dkrVRWj5wP*O<EOU_Tp%uBab3Jr17wNSFR<FY9(OIIk*Oex8* zRWdRts8CYKNX<;oD1q_HGE>W)@+)kW3=|9$j6g^U*-%3zg^Jvqykc9WjFOT9D}DX) z@^Za$W4-*MbbTWO0|WiyvUI2ttBRb=yliX=4J|D#^}(`Ac3cVy3JNxgy1EMPsd=eI zi6!|(Rtmw{sU^u73MQ6%MhY6HhK6PanhLrKNH!+rXQbw4CPKZZmz<xgUkuTss|z)< zB(o$Z)y_FTB~>BJ$VMN+h1iyoTAXa>T$GwvlA5AWo>`IswNTGSA1nn^l~!yA5=kqD z8kw$;nPRI1GEz6pNJ*i%q$oc-)mAAlKQ9%=(}f1Dp^`#cW=;-F62#UmD$Pl?RZ1;O z&C5?of%+Wm`+~%h422Y1C0|2R9YYg6Q$q!32+Q2UOu^7Z&)nQh$Iw*Iz!1bSg))6C z^$ab|p&VyRJp(fnD91w2(ikFPW~5-DXJG=CFf=t&@UhS{Gy$7sVQQk_Y@ughY7Ek3 zX=1Kmu4idvrekQPV6JCwX$)fcnCTfAn1fi(W_kwZCLorno}~%cY>*aHJquH?*&x$= zO!W*+!DfSOayHd7Ff#&~ZD3}kV4`Pf43;u5R4~!AFaTR>V5s0@tOxUsv$39$5!f&T zLj_|{Fn~M{W|)E$>KGd8nJPFNgJ>fo69uSpLj|xAh6+9=5N8`IIGaFxVyIvW@t+}x zQZR*h-4H}6_&}X*2=ak~Gt^gxAkQg4{c5BD^}dmU4>U-O6r7=<1PWJh*g>>FgB4<$ zj|Iq3kUI@c%s_z*4l#%$EFs}&s9*^RT0;dNP=xCkf}$K6(S{13$TtK92b5*1-~$o@ zr;I2CUqf>pOGqLCF+jm&Xa-3m2H-Se1`1R#6P8B699S9wbD(L&02E8GG-3dXKzJH4 z0Qmyse6T+az(E7`y&)`(7%IThh@k>3jevq3>|=-)Xh1_ugQXFOO|UcqaRfAtfL#Yo zBVaZpjewc3Gy>)r>sac6{0^caDZ~ttK+M1)2T31h;N)QjOC4sg#9;<a8)isJ!wflP zm_d9GNf>5e&qLCMIW$?A!%~GgEK!&%K=KnrH6%$ujDe;Ihy~6TAk%apHbc^b88kVV zDfk$IBF{|085*Nz3Wnx75D$SFpp*cLbW=lxC?$Al1S@NlO`I*w-Q1MyZ1h1z3bfSH MPq*W;0hP;k0MfH&O#lD@ literal 0 HcmV?d00001 diff --git a/src/components/gui/icon--costumes.svg b/src/components/gui/icon--costumes.svg new file mode 100644 index 0000000000000000000000000000000000000000..de50ce39b013b123e5c94364aad49b80e6a14d32 GIT binary patch literal 2120 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 UHu|7?23n=*r`vJafGTf00CJhzIRF3v literal 0 HcmV?d00001 diff --git a/src/components/gui/icon--sounds.svg b/src/components/gui/icon--sounds.svg new file mode 100644 index 0000000000000000000000000000000000000000..0de67c53780e9305d76d09363d349146222c0a87 GIT binary patch literal 2015 zcmcDqugJ|&C`&CW&dkrVRWj5wP*O<EOU_Tp%uBab3Jr17wNSFR<FY9(OIIk*Oex8* zRWdRts8CYKNX<;oD1q_HGE>W)@+)kW3=|9$j6g^U*-%3zg^Jvqykc9WjFOT9D}DX) z@^Za$W4-*MbbTWO0|WiyvUI2ttBRb=yliX=4J|D#^}(`Ac3cVy3JNxgy1EMPsd=eI zi6!|(Rtmw{sU^u73MQ6%MhY6HhK6PanhLrKNH!+rXQbw4CPKZZmz<xgUkuTss|z)< zB(o$Z)h;-{G%uxCA<WQ5A0hy;FD11&+0MBrHL)Z$MWH;iBm-)to{c_O3Z^Qp*bXF; zRtz;XT_H2YRtaLLZkVBxLUBn^es-#@QeJ*uDvYNK4PHYfg|y6^9GE1Cty@%@lWMD! zT9%rZpOOOgJvamk5=$}^Qf!rc4UP27j19~!3=DM)jrGio%?(YA6r2r>^h_)aj4Vu$ z1PzV!jEzi9%^-rNmgc4==H?29MtX)8CYFZg79gdjh9-uFW|j)hhK73PX6A+#re+{v zBQsMYV+&ISLqk0?BXdg=Lo*#iBRz8?V>1&|Bao<txv7bT8CcZVz}U>p80-XN6EicA zprM|rfq{vci5bW?n4p24sey^5sUeDfOFeS~V?#4DOGB^|V3t|x8Ce*bn;V!~f-HkM z%tFuH#K6$p+}IdoF3cAedM1{JMwS+qW?(m%8JJm^S(@rt=oy)q8kty_n<*F?>lvDu z7@C@x>saU+TNqmyK}C%%EG#U{K%y1~M#h$AmY|R{(KEC#Gd4Fh(J?g8Gc>idG&D6< zFhmkH)Uz-#H8n5*8w@kT&{)sNz}Udh0u+|UdPYX3=Eg>#pfs^CHZU+Z1i9GK*wEbE z$QUFFjW?{38KvNBXsTyqYG!6^W~^gqs%KzoYHVa;qTp<3s%L0mW@utyge+`mqGxGp zU|?tg7Bn<9H#RT?IoQI`z}(zK2PAE5WMpXxiX#&}V@qQL6OdXHJu?eq6C<!vBU58@ zOLKFOT0;{<3nNfEG0`(MFf=wXG6%WW+{h5*X|NMaEX<7!K%O(wGcYkRH!(3+Ff`SJ ziCXGeni&{dSQwju+yFDeLeI#;#N5Ep4CD(FJ(zvwdKP9T=7yFgAhj@;nd=!F8JZg! zfdbe>59$kZJp*$i3u9w&S~b-J`Nz=6Ovg;m!pOqV(%cm622et=G`G+()3Y=)H8wLg zu~aZL(=#wMF*h-?&@l(ay`{0CnW=)aA;=O76GKZw9ZNkkLsMf@Pyi!|f-;YVrMU&j z5eOp;P4vu+42=v7LEbRcvoJL<v;gG|6Fo}<LqiKoQ&32lnwpy#S(t)j0~&MK;}aCo z271Qk7N$lPAg`F2TbNpyo0};37$SrXP4$e83=B*RK(0m-Hq$dUF}5%^HB+$EGc-3e zH!(9e(=jyDvj9b;k*R`(o{6EQk(rs12}sn?!qVKpz+Az{OwZiX#N5;flnhPu%q-0< zOiauaoXzx%3@uG84NZ)|X~5jT*wV;Q!Bo%0%+kWh*b-dUSeToenVTCcfV3Hy8G-`Z z&{z*9>SLm3Vqj)!U}^>~gJ8nWpfbw9(9pybobF-5V2+WAsi}pLg@Q4ta4|76HnlW0 zQ}8j?vD7m)H88a>H&t*p*0IntH#aaaG%+z%Kr+fg&(IiTnT4eSlD$ZxJ|=o*=B9=w z7Dh%oNW#vhdM2hO#->Kbpb`RZhMAs`fr){krG=S}xt@iIvALyzrKN(Ip1HZDk%fU7 zNYvQS%-Gn%)KtL-DP&DS$<x@x5LEslMT4oHp^<@+nWcpSQbd~SnVFgy8JL+HBa52p z!DBs230!+P=jSG6=B1|S24^G|q{8Y5WfNyhb2m37I~#paRRFDT^waIQY(RCY9ROtt B#*qL3 literal 0 HcmV?d00001 diff --git a/test/integration/blocks.test.js b/test/integration/blocks.test.js index 9f0736488..4f3411d55 100644 --- a/test/integration/blocks.test.js +++ b/test/integration/blocks.test.js @@ -29,7 +29,7 @@ describe('Working with the blocks', () => { test('Blocks report when clicked in the toolbox', async () => { await loadUri(uri); await clickXpath('//button[@title="tryit"]'); - await clickText('Blocks'); + await clickText('Code'); await clickText('Operators', scope.blocksTab); await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation await clickText('join', scope.blocksTab); // Click "join <hello> <world>" block @@ -58,7 +58,7 @@ describe('Working with the blocks', () => { test('Creating variables', async () => { await loadUri(uri); await clickXpath('//button[@title="tryit"]'); - await clickText('Blocks'); + await clickText('Code'); await clickText('Variables', scope.blocksTab); await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation diff --git a/test/integration/localization.test.js b/test/integration/localization.test.js index 7c90b3221..deaf1a788 100644 --- a/test/integration/localization.test.js +++ b/test/integration/localization.test.js @@ -29,7 +29,7 @@ describe('Localization', () => { test.skip('Localization', async () => { await loadUri(uri); await clickXpath('//button[@title="tryit"]'); - await clickText('Blocks'); + await clickText('Code'); await clickXpath('//button[@title="Add Extension"]'); await clickText('Pen', scope.modal); // Modal closes await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation -- GitLab