pxt-core 7.5.19 → 7.5.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/built/pxt.js +37 -0
  2. package/built/pxtcompiler.d.ts +1 -0
  3. package/built/pxtcompiler.js +21 -0
  4. package/built/pxteditor.d.ts +1 -0
  5. package/built/pxtlib.d.ts +17 -0
  6. package/built/pxtlib.js +16 -0
  7. package/built/target.js +1 -1
  8. package/built/web/blockly.css +1 -1
  9. package/built/web/main.js +1 -1
  10. package/built/web/pxtapp.js +1 -1
  11. package/built/web/pxtasseteditor.js +1 -1
  12. package/built/web/pxtcompiler.js +1 -1
  13. package/built/web/pxtembed.js +1 -1
  14. package/built/web/pxtlib.js +1 -1
  15. package/built/web/pxtworker.js +1 -1
  16. package/built/web/react-common-authcode.css +168 -10
  17. package/built/web/react-common-skillmap.css +1 -1
  18. package/built/web/rtlblockly.css +1 -1
  19. package/built/web/rtlreact-common-skillmap.css +1 -1
  20. package/built/web/rtlsemantic.css +1 -1
  21. package/built/web/semantic.css +1 -1
  22. package/built/web/skillmap/css/main.c5811548.chunk.css +1 -0
  23. package/built/web/skillmap/js/2.26b9a6f6.chunk.js +2 -0
  24. package/built/web/skillmap/js/main.27185090.chunk.js +1 -0
  25. package/built/web/skillmap/js/{runtime-main.85a3c371.js → runtime-main.37bd2885.js} +0 -0
  26. package/localtypings/pxtarget.d.ts +16 -0
  27. package/localtypings/pxtpackage.d.ts +1 -0
  28. package/package.json +1 -1
  29. package/react-common/components/controls/Button.tsx +3 -0
  30. package/react-common/components/extensions/DeleteConfirmationModal.tsx +18 -0
  31. package/react-common/components/extensions/ExtensionCard.tsx +32 -0
  32. package/react-common/components/extensions/ImportModal.tsx +29 -0
  33. package/react-common/components/share/ShareInfo.tsx +98 -46
  34. package/react-common/components/share/SocialButton.tsx +1 -1
  35. package/react-common/styles/controls/Button.less +62 -14
  36. package/react-common/styles/controls/EditorToggle.less +3 -3
  37. package/react-common/styles/controls/Input.less +26 -0
  38. package/react-common/styles/extensions/ExtensionCard.less +56 -0
  39. package/react-common/styles/react-common-variables.less +15 -7
  40. package/react-common/styles/react-common.less +1 -0
  41. package/react-common/styles/share/share.less +56 -6
  42. package/theme/blockly-core.less +13 -0
  43. package/theme/common.less +152 -0
  44. package/theme/themes/pxt/globals/site.variables +7 -1
  45. package/webapp/public/skillmap.html +2 -2
  46. package/built/web/skillmap/css/main.73b22966.chunk.css +0 -1
  47. package/built/web/skillmap/js/2.3e47a285.chunk.js +0 -2
  48. package/built/web/skillmap/js/main.e30f6be4.chunk.js +0 -1
@@ -4,6 +4,7 @@ import { EditorToggle } from "../controls/EditorToggle";
4
4
  import { Input } from "../controls/Input";
5
5
  import { MenuDropdown } from "../controls/MenuDropdown";
6
6
  import { Textarea } from "../controls/Textarea";
7
+ import { Modal } from "../controls/Modal";
7
8
 
8
9
  import { ShareData } from "./Share";
9
10
  import { GifInfo } from "./GifInfo";
@@ -29,12 +30,15 @@ export const ShareInfo = (props: ShareInfoProps) => {
29
30
  gifRenderAsync, gifAddFrame, publishAsync, registerSimulatorMsgHandler, unregisterSimulatorMsgHandler } = props;
30
31
  const [ name, setName ] = React.useState(projectName);
31
32
  const [ thumbnailUri, setThumbnailUri ] = React.useState(screenshotUri);
32
- const [ shareState, setShareState ] = React.useState<"share" | "gifrecord" | "publish">("share");
33
+ const [ shareState, setShareState ] = React.useState<"share" | "gifrecord" | "publish" | "publishing">("share");
33
34
  const [ shareData, setShareData ] = React.useState<ShareData>();
34
35
  const [ embedState, setEmbedState ] = React.useState<"none" | "code" | "editor" | "simulator">("none");
35
36
  const [ showQRCode, setShowQRCode ] = React.useState(false);
37
+ const [ copySuccessful, setCopySuccessful ] = React.useState(false);
36
38
 
37
39
  const showSimulator = !!screenshotAsync || !!gifRecordAsync;
40
+ const showDescription = shareState !== "publish";
41
+ let qrCodeButtonRef: HTMLButtonElement;
38
42
 
39
43
  React.useEffect(() => {
40
44
  setThumbnailUri(screenshotUri)
@@ -50,13 +54,20 @@ export const ShareInfo = (props: ShareInfoProps) => {
50
54
  }
51
55
 
52
56
  const handlePublishClick = async (forceAnonymous?: boolean) => {
57
+ setShareState("publishing");
53
58
  let publishedShareData = await publishAsync(name, thumbnailUri, forceAnonymous);
54
59
  setShareData(publishedShareData);
55
60
  if (!publishedShareData?.error) setShareState("publish");
61
+ else setShareState("share")
56
62
  }
57
63
 
58
64
  const handleCopyClick = () => {
59
65
  navigator.clipboard.writeText(shareData.url);
66
+ setCopySuccessful(true);
67
+ }
68
+
69
+ const handleCopyBlur = () => {
70
+ setCopySuccessful(false);
60
71
  }
61
72
 
62
73
  const handleEmbedClick = () => {
@@ -104,30 +115,42 @@ export const ShareInfo = (props: ShareInfoProps) => {
104
115
  title: lf("Create snapshot"),
105
116
  label: lf("Create snapshot"),
106
117
  onClick: () => handlePublishClick(true)
107
- }]
118
+ }];
119
+
120
+ const handleQRCodeButtonRef = (ref: HTMLButtonElement) => {
121
+ if (ref) qrCodeButtonRef = ref;
122
+ }
123
+
124
+ const handleQRCodeModalClose = () => {
125
+ setShowQRCode(false);
126
+ if (qrCodeButtonRef) qrCodeButtonRef.focus();
127
+ }
128
+
129
+ const prePublish = shareState === "share" || shareState === "publishing";
108
130
 
109
131
  return <>
110
132
  <div className="project-share-info">
111
- {(shareState === "share" || shareState === "publish") && <>
133
+ {(prePublish|| shareState === "publish") && <>
112
134
  {showSimulator && <div className="project-share-title">
113
135
  <h2>{lf("About your project")}</h2>
114
- {showShareDropdown && shareState === "share" && <MenuDropdown id="project-share-dropdown"
136
+ {showShareDropdown && prePublish && <MenuDropdown id="project-share-dropdown"
115
137
  icon="fas fa-ellipsis-h"
116
138
  title={lf("More share options")}
117
139
  items={dropdownOptions}
118
140
  />}
119
141
  </div>}
120
- <Input label={lf("Project Name")}
121
- initialValue={name}
122
- placeholder={lf("Name your project")}
123
- readOnly={shareState === "publish"}
124
- onChange={setName} />
125
- <Textarea label={lf("Description")}
126
- initialValue={description}
127
- placeholder={lf("Tell others about your game")}
128
- readOnly={shareState === "publish"}
129
- rows={5} />
130
- {shareState === "share" && <>
142
+ {showDescription && <>
143
+ <Input label={lf("Project Name")}
144
+ initialValue={name}
145
+ placeholder={lf("Name your project")}
146
+ onChange={setName} />
147
+ <Textarea label={lf("Description")}
148
+ initialValue={description}
149
+ placeholder={lf("Tell others about your game")}
150
+ rows={5} />
151
+ </>
152
+ }
153
+ {prePublish && <>
131
154
  {showSimulator && <div className="project-share-thumbnail">
132
155
  {thumbnailUri
133
156
  ? <img src={thumbnailUri} />
@@ -137,41 +160,65 @@ export const ShareInfo = (props: ShareInfoProps) => {
137
160
  label={lf("Update project thumbnail")}
138
161
  onClick={() => setShareState("gifrecord")} />
139
162
  </div>}
140
- <div>{lf("By publishing you agree that you are allowed to share this game.")}</div>
163
+ <div>{lf("You need to publish your project to share it or embed it in other web pages. You acknowledge having consent to publish this project.")}</div>
141
164
  {shareData?.error && <div className="project-share-error">
142
165
  {(shareData.error.statusCode === 413
143
166
  && pxt.appTarget?.cloud?.cloudProviders?.github)
144
167
  ? lf("Oops! Your project is too big. You can create a GitHub repository to share it.")
145
168
  : lf("Oops! There was an error. Please ensure you are connected to the Internet and try again.")}
146
169
  </div>}
147
- <Button className="primary"
148
- title={lf("Publish to share")}
149
- label={lf("Publish to share")}
150
- onClick={handlePublishClick} />
170
+ {shareState === "share" ?
171
+ <Button className="primary share-publish-button"
172
+ title={lf("Publish to share")}
173
+ label={lf("Publish to share")}
174
+ onClick={handlePublishClick} /> :
175
+ <Button className="primary share-publish-button"
176
+ title={lf("Publishing...")}
177
+ label={ <div className="common-spinner" />}
178
+ onClick={() => {}} />
179
+ }
151
180
  </>}
152
- {shareState === "publish" && <div className="project-share-actions">
153
- <Button className="teal"
154
- title={lf("Copy link")}
155
- label={lf("Copy link")}
156
- leftIcon="fas fa-link"
157
- onClick={handleCopyClick} />
158
- <Button className="share-button"
159
- title={lf("Show QR code")}
160
- leftIcon="fas fa-qrcode"
161
- onClick={handleQRCodeClick} />
162
- <Button className="share-button"
163
- title={lf("Show embed code")}
164
- leftIcon="fas fa-code"
165
- onClick={handleEmbedClick} />
166
- <SocialButton className="share-button"
167
- url={shareData?.url}
168
- type='facebook'
169
- heading={lf("Share on Facebook")} />
170
- <SocialButton className="share-button"
171
- url={shareData?.url}
172
- type='twitter'
173
- heading={lf("Share on Twitter")} />
174
- </div>}
181
+
182
+ {shareState === "publish" &&
183
+ <div className="project-share-data">
184
+ <div className="project-share-text">
185
+ {lf("Your project is ready! Use the address below to share your projects.")}
186
+ </div>
187
+ <div className="common-input-attached-button">
188
+ <Input
189
+ initialValue={shareData.url}
190
+ readOnly={true}
191
+ onChange={setName} />
192
+ <Button className={copySuccessful ? "green" : "primary"}
193
+ title={lf("Copy link")}
194
+ label={copySuccessful ? lf("Copied!") : lf("Copy link")}
195
+ leftIcon="fas fa-link"
196
+ onClick={handleCopyClick}
197
+ onBlur={handleCopyBlur} />
198
+ </div>
199
+ <div className="project-share-actions">
200
+ <Button className="circle-button gray"
201
+ title={lf("Show embed code")}
202
+ leftIcon="fas fa-code"
203
+ onClick={handleEmbedClick} />
204
+ <SocialButton className="circle-button facebook"
205
+ url={shareData?.url}
206
+ type='facebook'
207
+ heading={lf("Share on Facebook")} />
208
+ <SocialButton className="circle-button twitter"
209
+ url={shareData?.url}
210
+ type='twitter'
211
+ heading={lf("Share on Twitter")} />
212
+ <Button
213
+ className="menu-button project-qrcode"
214
+ buttonRef={handleQRCodeButtonRef}
215
+ title={lf("Show QR Code")}
216
+ label={<img className="qrcode-image" src={shareData?.qr} />}
217
+ onClick={handleQRCodeClick}
218
+ />
219
+ </div>
220
+ </div>
221
+ }
175
222
  {embedState !== "none" && <div className="project-embed">
176
223
  <EditorToggle id="project-embed-toggle"
177
224
  className="slim tablet-compact"
@@ -181,9 +228,6 @@ export const ShareInfo = (props: ShareInfoProps) => {
181
228
  rows={5}
182
229
  initialValue={shareData?.embed[embedState]} />
183
230
  </div>}
184
- {showQRCode && <div className="project-qrcode">
185
- <img src={shareData?.qr} />
186
- </div>}
187
231
  </>}
188
232
  {shareState === "gifrecord" && <GifInfo
189
233
  initialUri={thumbnailUri}
@@ -195,6 +239,14 @@ export const ShareInfo = (props: ShareInfoProps) => {
195
239
  gifAddFrame={gifAddFrame}
196
240
  registerSimulatorMsgHandler={registerSimulatorMsgHandler}
197
241
  unregisterSimulatorMsgHandler={unregisterSimulatorMsgHandler} />}
242
+
243
+ {showQRCode &&
244
+ <Modal title={lf("QR Code")} onClose={handleQRCodeModalClose}>
245
+ <div className="qrcode-modal-body">
246
+ <img className="qrcode-image" src={shareData?.qr} />
247
+ </div>
248
+ </Modal>
249
+ }
198
250
  </div>
199
251
  </>
200
252
  }
@@ -47,7 +47,7 @@ export const SocialButton = (props: SocialButtonProps) => {
47
47
 
48
48
  return <Button className={className}
49
49
  ariaLabel={type}
50
- title={type}
50
+ title={heading}
51
51
  leftIcon={`icon ${type}`}
52
52
  onClick={handleClick} />
53
53
  }
@@ -6,7 +6,7 @@
6
6
  outline: none;
7
7
  border: none;
8
8
  vertical-align: middle;
9
- color: @buttonTextColor;
9
+ color: @buttonTextColorLightBackground;
10
10
  background: @buttonBackgroundColor;
11
11
  font-family: @pageFont;
12
12
  margin: 0 0.25rem 0 0;
@@ -42,62 +42,68 @@
42
42
 
43
43
  .common-button.primary {
44
44
  background: @primaryColor;
45
- color: @buttonTextColorInverted;
45
+ color: @buttonTextColorDarkBackground;
46
46
  border: 1px solid @primaryColor;
47
47
  }
48
48
 
49
49
  .common-button.secondary {
50
50
  background: @secondaryColor;
51
- color: @buttonTextColorInverted;
51
+ color: @buttonTextColorDarkBackground;
52
52
  border: 1px solid @secondaryColor;
53
53
  }
54
54
 
55
55
  .common-button.teal {
56
56
  background: @teal;
57
- color: @buttonTextColorInverted;
57
+ color: @buttonTextColorDarkBackground;
58
58
  border: 1px solid @teal;
59
59
  }
60
60
 
61
61
  .common-button.orange {
62
62
  background: @orange;
63
- color: @buttonTextColorInverted;
63
+ color: @buttonTextColorDarkBackground;
64
64
  border: 1px solid @orange;
65
65
  }
66
66
 
67
67
  .common-button.red {
68
68
  background: @red;
69
- color: @buttonTextColorInverted;
69
+ color: @buttonTextColorDarkBackground;
70
70
  border: 1px solid @red;
71
71
  }
72
72
 
73
73
  .common-button.green {
74
74
  background: @green;
75
- color: @buttonTextColorInverted;
75
+ color: @buttonTextColorDarkBackground;
76
76
  border: 1px solid @green;
77
77
  }
78
78
 
79
+ .common-button.gray, .common-button.grey {
80
+ background: @buttonGrayColor;
81
+ color: @buttonTextColorLightBackground;
82
+ border: 1px solid @buttonGrayColor;
83
+ }
84
+
79
85
  .common-button.primary.inverted {
80
- background: @buttonTextColorInverted;
86
+ background: @buttonTextColorDarkBackground;
81
87
  color: @primaryColor;
82
88
  }
83
89
 
84
90
  .common-button.teal.inverted {
85
- background: @buttonTextColorInverted;
91
+ background: @buttonTextColorDarkBackground;
86
92
  color: @teal;
87
93
  }
88
94
 
89
95
  .common-button.orange.inverted {
90
- background: @buttonTextColorInverted;
96
+ background: @buttonTextColorDarkBackground;
91
97
  color: @orange;
92
98
  }
93
99
 
94
100
  .common-button.red.inverted {
95
- background: @buttonTextColorInverted;
101
+ background: @buttonTextColorDarkBackground;
96
102
  color: @red;
97
103
  }
98
104
 
99
105
  .common-button.green.inverted {
100
- background: @buttonTextColorInverted;
106
+ background: @buttonTextColorDarkBackground;
101
107
  color: @green;
102
108
  }
103
109
 
@@ -126,7 +132,7 @@
126
132
  {
127
133
  cursor: default;
128
134
  background-color: @buttonBackgroundColorDisabled;
129
- color: @buttonTextColor;
135
+ color: @buttonTextColorLightBackground;
130
136
  border: @buttonBackgroundColorDisabled;
131
137
  }
132
138
 
@@ -150,7 +156,10 @@
150
156
  .common-button.teal:focus::after,
151
157
  .common-button.orange:focus::after,
152
158
  .common-button.red:focus::after,
153
- .common-button.green:focus::after {
159
+ .common-button.green:focus::after,
160
+ .common-button.facebook:focus::after,
161
+ .common-button.twitter:focus::after,
162
+ .common-button.discourse:focus::after {
154
163
  outline: @buttonFocusOutlineDarkBackground;
155
164
  }
156
165
 
@@ -213,6 +222,45 @@
213
222
  text-decoration: underline;
214
223
  }
215
224
 
225
+ /****************************************************
226
+ * Circle Buttons *
227
+ ****************************************************/
228
+
229
+ .common-button.circle-button {
230
+ width: 3rem;
231
+ height: 3rem;
232
+ overflow: hidden;
233
+ padding: 0;
234
+ border-radius: 2rem;
235
+
236
+ i, i.fas, i.far {
237
+ margin: 0;
238
+ }
239
+ }
240
+
241
+ .common-button.circle-button:focus::after {
242
+ border-radius: 2rem;
243
+ }
244
+
245
+ /****************************************************
246
+ * Social Buttons *
247
+ ****************************************************/
248
+
249
+ .common-button.facebook {
250
+ background: #4267B2;
251
+ color: @buttonTextColorDarkBackground;
252
+ }
253
+
254
+ .common-button.twitter {
255
+ background: #1DA1F2;
256
+ color: @buttonTextColorDarkBackground;
257
+ }
258
+
259
+ .common-button.discourse {
260
+ background: #333333;
261
+ color: @buttonTextColorDarkBackground;
262
+ }
263
+
216
264
  /****************************************************
217
265
  * High Contrast *
218
266
  ****************************************************/
@@ -37,7 +37,7 @@
37
37
 
38
38
  & > .common-button {
39
39
  background: none;
40
- color: @buttonTextColorInverted;
40
+ color: @buttonTextColorDarkBackground;
41
41
  transition: color .25s;
42
42
  margin: 0;
43
43
  width: 100%;
@@ -60,12 +60,12 @@
60
60
 
61
61
  & > .common-button {
62
62
  border-right: none;
63
- color: @buttonTextColor;
63
+ color: @buttonTextColorLightBackground;
64
64
  }
65
65
  }
66
66
 
67
67
  & > .common-button {
68
- color: @buttonTextColor;
68
+ color: @buttonTextColorLightBackground;
69
69
  }
70
70
  }
71
71
 
@@ -94,6 +94,32 @@
94
94
  }
95
95
  }
96
96
 
97
+
98
+ /****************************************************
99
+ * Attached Button *
100
+ ****************************************************/
101
+
102
+ .common-input-attached-button {
103
+ display: flex;
104
+ flex-direction: row;
105
+
106
+ .common-input-wrapper {
107
+ flex-grow: 1;
108
+
109
+ .common-input-group {
110
+ border-top-right-radius: 0;
111
+ border-bottom-right-radius: 0;
112
+ border-right: none;
113
+ height: 3rem;
114
+ }
115
+ }
116
+
117
+ .common-button {
118
+ border-top-left-radius: 0;
119
+ border-bottom-left-radius: 0;
120
+ }
121
+ }
122
+
97
123
  /****************************************************
98
124
  * High Contrast *
99
125
  ****************************************************/
@@ -0,0 +1,56 @@
1
+ .extensionCard.loading {
2
+ background: @loadingAnimation;
3
+ background-size: 400% 400%;
4
+ animation: gradient 3s infinite alternate;
5
+ }
6
+
7
+ @keyframes gradient {
8
+ 0% {
9
+ background-position: 0% 50%;
10
+ }
11
+ 50% {
12
+ background-position: 100% 50%;
13
+ }
14
+ 100% {
15
+ background-position: 0% 50%;
16
+ }
17
+ }
18
+
19
+ .extensionCard.ui.card {
20
+ height: 19rem;
21
+ display: flex;
22
+ justify-content: space-between;
23
+ margin: 0;
24
+ overflow: hidden;
25
+
26
+ img {
27
+ height: 11rem;
28
+ }
29
+
30
+ .content {
31
+ justify-content: flex-start;
32
+ display: flex;
33
+ flex-direction: column;
34
+ padding: 0.2em 1em;
35
+ }
36
+
37
+ .name {
38
+ font-family: @defaultFont;
39
+ font-weight: 600;
40
+ font-size: 1.5rem;
41
+ line-height: 1.6rem;
42
+ padding-top: .5rem;
43
+ }
44
+
45
+ .description {
46
+ font-weight: 400;
47
+ text-overflow: ellipsis;
48
+ padding-top: .8rem;
49
+ font-size: 1rem;
50
+ }
51
+
52
+ .learnmore {
53
+ font-size: 1rem;
54
+ align-self: flex-end;
55
+ }
56
+ }
@@ -19,19 +19,22 @@
19
19
  @largeMonitorAndBelow: ~"only screen and (max-width: @{largestLargeMonitor})";
20
20
 
21
21
 
22
+ @defaultFont: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
23
+
22
24
  /****************************************************
23
25
  * Buttons *
24
26
  ****************************************************/
25
27
 
26
- @buttonTextColor: @commonTextColor;
27
- @buttonTextColorInverted: @white;
28
+ @buttonTextColorLightBackground: @commonTextColor;
29
+ @buttonTextColorDarkBackground: @white;
28
30
  @buttonBackgroundColor: @white;
29
31
  @buttonBackgroundColorDisabled: @commonBackgroundDisabledColor;
32
+ @buttonGrayColor: #e0e1e2;
30
33
 
31
34
  @buttonMenuTextColor: #ffffff;
32
35
  @buttonMenuTextColorInverted: @primaryColor;
33
36
  @buttonMenuBackgroundColorInverted: @buttonMenuTextColor;
34
- @buttonFocusOutlineDarkBackground: @buttonTextColorInverted solid 1px;;
37
+ @buttonFocusOutlineDarkBackground: @buttonTextColorDarkBackground solid 1px;;
35
38
  @buttonFocusOutlineLightBackground: @commonBorderColor solid 1px;
36
39
  @buttonMenuBackgroundHoverColor: rgba(0,0,0,.1);
37
40
  @buttonMenuBackgroundActiveColor: rgba(0,0,0,.15);
@@ -96,19 +99,19 @@
96
99
 
97
100
  @inputTextColor: @commonTextColor;
98
101
  @inputTextColorDisabled: rgb(161, 159, 157);
99
- @inputBorderColor: @commonBorderColor;
102
+ @inputBorderColor: rgba(34,36,38,.15);
100
103
  @inputBorderColorFocus: rgb(0, 120, 212);
101
104
  @inputBackgroundColor: #ffffff;
102
105
  @inputBackgroundColorDisabled: @commonBackgroundDisabledColor;
103
106
  @inputButtonColor: rgb(0, 120, 212);
104
- @inputButtonColorHover: rgb(16, 110, 190);
107
+ @inputButtonColorHover: rgb(3, 33, 60);
105
108
 
106
109
  /****************************************************
107
110
  * Textarea *
108
111
  ****************************************************/
109
112
 
110
113
  @textareaTextColor: @commonTextColor;
111
- @textareaBorderColor: @commonBorderColor;
114
+ @textareaBorderColor: @inputBorderColor;
112
115
  @textareaBorderColorFocus: rgb(0, 120, 212);
113
116
  @textareaBackgroundColor: #ffffff;
114
117
  @textareaBackgroundColorDisabled: @commonBackgroundDisabledColor;
@@ -139,4 +142,9 @@
139
142
  @highContrastBackgroundColor: #000000;
140
143
  @highContrastHighlightColor: #ffff00;
141
144
  @highContrastFocusOutline: 2px solid @highContrastHighlightColor;
142
- @highContrastFocusZIndex: 1;
145
+ @highContrastFocusZIndex: 1;
146
+
147
+ /****************************************************
148
+ * Extension Card *
149
+ ****************************************************/
150
+ @loadingAnimation: linear-gradient(-45deg, #ffffff46, #f3f3f350, #dee2ff6e, #f1f1f149);
@@ -11,6 +11,7 @@
11
11
  @import "controls/Modal.less";
12
12
  @import "controls/RadioButtonGroup.less";
13
13
  @import "controls/Spinner.less";
14
+ @import "extensions/ExtensionCard.less";
14
15
  @import "controls/Textarea.less";
15
16
  @import "./react-common-variables.less";
16
17
 
@@ -72,23 +72,73 @@
72
72
  }
73
73
  }
74
74
 
75
+ .share-publish-button {
76
+ height: 3rem;
77
+
78
+ .common-spinner {
79
+ display: inline-block;
80
+ }
81
+ }
82
+
75
83
  /////////////////////////////////////////
76
84
  // Embed //
77
85
  /////////////////////////////////////////
78
86
 
79
87
  .project-share-actions {
80
88
  display: flex;
89
+ margin-top: 1rem;
90
+ position: relative;
91
+ margin-bottom: 2rem;
92
+
93
+ .common-button {
94
+ margin-right: 1rem;
95
+ }
96
+ }
97
+
98
+ .project-share-text {
99
+ margin-bottom: 1rem;
100
+ }
81
101
 
82
- .share-button {
83
- width: 3rem;
84
- padding: 1rem 0.75rem;
102
+ .common-button.menu-button.project-qrcode {
103
+ position: absolute;
104
+ right: 0;
105
+ height: 6rem;
106
+ padding: 0.5rem;
107
+ top: -0.5rem;
85
108
 
86
- i {
87
- margin: 0;
88
- }
109
+ img {
110
+ height: 5rem;
89
111
  }
90
112
  }
91
113
 
114
+ .common-button.menu-button.project-qrcode:focus::after {
115
+ outline: @buttonFocusOutlineLightBackground;
116
+ }
117
+
118
+ .project-share-data .common-input-attached-button .common-button {
119
+ width: 10rem;
120
+ padding: .8rem 1rem .95rem;
121
+ }
122
+
123
+ .qrcode-image {
124
+ image-rendering: optimizeSpeed;
125
+ image-rendering: -moz-crisp-edges;
126
+ image-rendering: -webkit-optimize-contrast;
127
+ image-rendering: optimize-contrast;
128
+ image-rendering: pixelated;
129
+ -ms-interpolation-mode: nearest-neighbor;
130
+ }
131
+
132
+
133
+ .qrcode-modal-body {
134
+ display: flex;
135
+ align-items: center;
136
+ justify-content: center;
137
+
138
+ .qrcode-image {
139
+ height: 20rem;
140
+ }
141
+ }
92
142
 
93
143
  /////////////////////////////////////////
94
144
  // Gif Recorder //
@@ -115,6 +115,19 @@ body.blocklyMinimalBody {
115
115
  visibility: visible;
116
116
  }
117
117
 
118
+ i.icon.blocklyTreeButton {
119
+ float: right;
120
+ line-height: 40px;
121
+ color: grey;
122
+ opacity: 0;
123
+ transition-property: opacity;
124
+ transition-duration: .5s;
125
+ }
126
+
127
+ .blocklyTreeRow:hover i.icon.blocklyTreeButton {
128
+ opacity: 1;
129
+ }
130
+
118
131
  /*******************************
119
132
  Blockly Flyout
120
133
  *******************************/