Extract SVGs to files (#7076)
* Extract SVGs to individual files Probably not working for cloud frontend (`watch-dashboard`, `build-dashboard`) yet Dynamic SVGs were not extracted out * Make file SVGs work for `watch-dashboard` and `build-dashboard` * Document SVG loaders * Address QA issues
@ -28,7 +28,7 @@ const NAME = 'enso'
|
||||
* `yargs` and `react-hot-toast` are modules we explicitly want the default imports of.
|
||||
* `node:process` is here because `process.on` does not exist on the namespace import. */
|
||||
const DEFAULT_IMPORT_ONLY_MODULES =
|
||||
'node:process|chalk|string-length|yargs|yargs\\u002Fyargs|sharp|to-ico|connect|morgan|serve-static|create-servers|electron-is-dev|fast-glob|esbuild-plugin-.+|opener|tailwindcss.*'
|
||||
'node:process|chalk|string-length|yargs|yargs\\u002Fyargs|sharp|to-ico|connect|morgan|serve-static|create-servers|electron-is-dev|fast-glob|esbuild-plugin-.+|opener|tailwindcss.*|enso-assets.*'
|
||||
const ALLOWED_DEFAULT_IMPORT_MODULES = `${DEFAULT_IMPORT_ONLY_MODULES}|postcss|react-hot-toast`
|
||||
const OUR_MODULES = 'enso-content-config|enso-common|enso-common\\u002Fsrc\\u002Fdetect'
|
||||
const RELATIVE_MODULES =
|
||||
|
4
app/ide-desktop/lib/assets/arrow_right.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg height="24" width="24" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
viewBox="0 0 24 24" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
After Width: | Height: | Size: 267 B |
3
app/ide-desktop/lib/assets/arrow_right_small.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="8" height="8" viewBox="-1 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m0 0 6 4-6 4V0Z" fill="#3e515fe5" fill-opacity="0.7" />
|
||||
</svg>
|
After Width: | Height: | Size: 168 B |
6
app/ide-desktop/lib/assets/arrow_up.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="21" height="21" x="1.5" y="1.5" rx="10.5" stroke="#3e515fe5" stroke-opacity="0.1" stroke-width="3" />
|
||||
<path d="M12 17a1.5 1.5 0 0 1-1.5-1.5V12h3v3.5A1.5 1.5 0 0 1 12 17Z" fill="#3e515fe5" />
|
||||
<path d="M8.943 12a1 1 0 0 1-.814-1.581l3.057-4.28a1 1 0 0 1 1.628 0l3.056 4.28A1 1 0 0 1 15.057 12H8.943Z"
|
||||
fill="#3e515fe5" />
|
||||
</svg>
|
After Width: | Height: | Size: 454 B |
5
app/ide-desktop/lib/assets/at.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg height="24" width="24" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
viewBox="0 0 24 24" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M16 12a4 4 0 10-8 0 4 4 0 008 0zm0 0v1.5a2.5 2.5 0 005 0V12a9 9 0 10-9 9m4.5-1.206a8.959 8.959 0 01-4.5 1.207" />
|
||||
</svg>
|
After Width: | Height: | Size: 327 B |
5
app/ide-desktop/lib/assets/bars.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="2" y="1" width="12" height="3" fill="#767676" />
|
||||
<rect x="2" y="6" width="12" height="3" fill="#767676" />
|
||||
<rect x="2" y="11" width="12" height="3" fill="#767676" />
|
||||
</svg>
|
After Width: | Height: | Size: 289 B |
7
app/ide-desktop/lib/assets/close.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="12" fill="#3e515fe5" fill-opacity="0.1" />
|
||||
<g opacity="0.66" transform="rotate(45 12 12)">
|
||||
<rect x="11" y="6" width="2" height="12" fill="#3e515fe5" />
|
||||
<rect x="6" y="11" width="12" height="2" fill="#3e515fe5" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 375 B |
4
app/ide-desktop/lib/assets/cloud.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.5 16A2.9 2.9 0 1 1 8 10.5 4 4 0 0 1 15.5 11 2 2 0 0 1 17.5 12 1.9 1.9 0 1 1 18.5 16"
|
||||
fill="#3e515fe5" />
|
||||
</svg>
|
After Width: | Height: | Size: 231 B |
5
app/ide-desktop/lib/assets/computer.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M3.5 18.5a1 1 0 0 1 0-2h3.5v-1.5h-3.5a1 1 0 0 1-1-1v-7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7a1 1 0 0 1-1 1h-3.5v1.5h3.5a1 1 0 0 1 0 2ZM4 14a.5.5 0 0 1-.5-.5v-6a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-.5.5ZM17.3 18.5a1 1 0 0 1-1-1v-10.5a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v10.5a1 1 0 0 1-1 1ZM17.3 9a.3.3 0 1 1 0-.6h3a.3.3 0 1 1 0 .6ZM18.8 16a.7.7 0 1 1 0-1.4.7.7 0 1 1 0 1.4Z"
|
||||
fill="#3e515fe5" fill-rule="evenodd" />
|
||||
</svg>
|
After Width: | Height: | Size: 545 B |
4
app/ide-desktop/lib/assets/create_account.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg height="24" width="24" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
viewBox="0 0 24 24" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z" />
|
||||
</svg>
|
After Width: | Height: | Size: 294 B |
4
app/ide-desktop/lib/assets/dashed_border.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="100%" height="100%" fill="none" rx="16" ry="16" stroke="#3e515f" stroke-width="4"
|
||||
stroke-dasharray="11 11" stroke-linecap="butt" />
|
||||
</svg>
|
After Width: | Height: | Size: 231 B |
5
app/ide-desktop/lib/assets/default_user.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg height="32" width="32" viewBox="2 2 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M6 20a10 10 0 0 1 6 -18 10 10 0 0 1 6 18 6 6 0 0 0 -4 -5 4.3 4.3 0 0 0 -2 -8 4.3 4.3 0 0 0 -2 8 6 6 0 0 0 -4 5"
|
||||
fill="#888888" />
|
||||
</svg>
|
After Width: | Height: | Size: 249 B |
5
app/ide-desktop/lib/assets/directory.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="-2 -2 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M0 7h16v6a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V7Zm0-4h14a2 2 0 0 1 2 2v1H0V3Zm0 0c0-1.1.9-2 2-2h4a2 2 0 0 1 2 2H0Z"
|
||||
fill="#3e515fe5" fill-opacity="0.4" />
|
||||
</svg>
|
After Width: | Height: | Size: 269 B |
3
app/ide-desktop/lib/assets/down_caret.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg height="16" width="16" viewBox="-1-1 12 12" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1 3l4 4 4-4" fill="transparent" stroke="#3e515fe5" stroke-linecap="round" />
|
||||
</svg>
|
After Width: | Height: | Size: 182 B |
6
app/ide-desktop/lib/assets/download.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="3" y="12" width="10" height="18" rx="2" transform="rotate(-90 3 12)" fill="#3e515fe5"
|
||||
fill-opacity="0.2" />
|
||||
<path d="M11.5 7C12.33 7 13 7.67 13 8.5L13 15L10 15L10 8.5C10 7.67 10.67 7 11.5 7Z" fill="#3e515fe5" />
|
||||
<path d="M16 15L11.5 21L7.00003 15L16 15Z" fill="#3e515fe5" />
|
||||
</svg>
|
After Width: | Height: | Size: 406 B |
4
app/ide-desktop/lib/assets/exclamation.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="#f9fafb" fill-opacity="0.7" fill-rule="evenodd"
|
||||
d="M9 0A9 9 0 1 1 9 18 9 9 0 1 1 9 0M7.5 3.5H10.5L10 10.5H8L7.5 3.5ZM8 12L10 12 10 14 8 14" />
|
||||
</svg>
|
After Width: | Height: | Size: 269 B |
5
app/ide-desktop/lib/assets/file.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M6.5 3h8v2a2 2 0 0 0 2 2h2v13a1 1 0 0 1 -1 1h-11a1 1 0 0 1 -1 -1v-16a1 1 0 0 1 1 -1ZM15 3v2a1.5 1.5 0 0 0 1.5 1.5h2"
|
||||
fill="#3e515fe5" />
|
||||
</svg>
|
After Width: | Height: | Size: 256 B |
4
app/ide-desktop/lib/assets/go_back.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg height="24" width="24" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
viewBox="0 0 24 24" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11 16l-4-4m0 0l4-4m-4 4h14m-5 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h7a3 3 0 013 3v1" />
|
||||
</svg>
|
After Width: | Height: | Size: 302 B |
4
app/ide-desktop/lib/assets/lock.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg height="24" width="24" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
viewBox="0 0 24 24" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
|
||||
</svg>
|
After Width: | Height: | Size: 310 B |
6
app/ide-desktop/lib/assets/magnifying_glass.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g opacity="0.5">
|
||||
<path d="M11.4142 10L15.6569 14.2426L14.2426 15.6569L10 11.4142L11.4142 10Z" fill="#3e515fe5" />
|
||||
<circle cx="7" cy="7" r="5" stroke="#3e515fe5" stroke-width="2" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 313 B |
17
app/ide-desktop/lib/assets/package.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "enso-assets",
|
||||
"type": "module",
|
||||
"version": "1.0.0",
|
||||
"author": {
|
||||
"name": "Enso Team",
|
||||
"email": "contact@enso.org"
|
||||
},
|
||||
"homepage": "https://github.com/enso-org/enso/tree/develop/app/ide-desktop/lib/assets",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:enso-org/enso.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/enso-org/enso/issues"
|
||||
}
|
||||
}
|
5
app/ide-desktop/lib/assets/play.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m10.04 7.34 6 3.85a1 1 0 0 1 0 1.68l-6 3.85a1 1 0 0 1-1.54-.84v-7.7a1 1 0 0 1 1.54-.84Z"
|
||||
fill="#3e515fe5" />
|
||||
<rect x="1.5" y="1.5" width="21" height="21" rx="10.5" stroke="#3e515fe5" stroke-opacity="0.1" stroke-width="3" />
|
||||
</svg>
|
After Width: | Height: | Size: 351 B |
7
app/ide-desktop/lib/assets/plus.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="12" fill="#3e515fe5" fill-opacity="0.1" />
|
||||
<g opacity="0.66">
|
||||
<rect x="11" y="6" width="2" height="12" fill="#3e515fe5" />
|
||||
<rect x="6" y="11" width="12" height="2" fill="#3e515fe5" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 346 B |
4
app/ide-desktop/lib/assets/plus_circled.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="80" height="80" viewBox="0 0 24 24" fill="none" stroke-width="0.5" stroke="#3e515fe5"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v6m3-3H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
After Width: | Height: | Size: 255 B |
5
app/ide-desktop/lib/assets/secret.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M10.3 13a4 4 0 1 1 0-2h10a1 1 0 0 1 1 1v3a1 1 0 0 1-2 0v-2h-2v2a1 1 0 0 1-2 0v-2ZM3.5 12a1 1 0 1 1 2 0a1 1 0 1 1-2 0"
|
||||
fill="#3e515fe5" fill-rule="evenodd" />
|
||||
</svg>
|
After Width: | Height: | Size: 277 B |
4
app/ide-desktop/lib/assets/speech_bubble.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<ellipse cx="8" cy="8" rx="8" ry="7.5" fill="white" />
|
||||
<path d="M4.17269e-05 16.5L2 10.5L5.50006 14L4.17269e-05 16.5Z" fill="white" />
|
||||
</svg>
|
After Width: | Height: | Size: 245 B |
7
app/ide-desktop/lib/assets/upload.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="3" y="14" width="12" height="17" rx="2" transform="rotate(-90 3 14)" fill="#3e515fe5"
|
||||
fill-opacity="0.2" />
|
||||
<path d="M11.5 21C10.6716 21 10 20.3284 10 19.5L10 11L13 11L13 19.5C13 20.33 12.33 21 11.5 21Z"
|
||||
fill="#3e515fe5" />
|
||||
<path d="M7 11L11.5 5L16 11L7 11Z" fill="#3e515fe5" />
|
||||
</svg>
|
After Width: | Height: | Size: 418 B |
@ -106,7 +106,8 @@ export function bundlerOptions(args: Arguments) {
|
||||
'.css': 'copy',
|
||||
'.map': 'copy',
|
||||
'.wasm': 'copy',
|
||||
'.svg': 'copy',
|
||||
// The `file` loader copies the file, and replaces the import with the path to the file.
|
||||
'.svg': 'file',
|
||||
'.png': 'copy',
|
||||
'.ttf': 'copy',
|
||||
},
|
||||
|
@ -33,8 +33,7 @@ async function bundle() {
|
||||
path.resolve(THIS_PATH, 'src', 'index.html'),
|
||||
path.resolve(THIS_PATH, 'src', 'index.tsx')
|
||||
)
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
opts.loader = { '.html': 'copy' }
|
||||
opts.loader['.html'] = 'copy'
|
||||
await esbuild.build(opts)
|
||||
return
|
||||
} catch (error) {
|
||||
|
@ -112,6 +112,16 @@ export function bundlerOptions(args: Arguments) {
|
||||
entryPoints: [path.resolve(THIS_PATH, 'src', 'tailwind.css')],
|
||||
outdir: outputPath,
|
||||
outbase: 'src',
|
||||
loader: {
|
||||
// The CSS file needs to import a single SVG as a data URL.
|
||||
// For `bundle.ts` and `watch.ts`, `index.js` also includes various SVG icons
|
||||
// which need to be bundled.
|
||||
// The `dataurl` loader replaces the import with the file, as a data URL. Using the
|
||||
// `file` loader, which copies the file and replaces the import with the path,
|
||||
// is an option, however this loader avoids adding extra files to the bundle.
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
'.svg': 'dataurl',
|
||||
},
|
||||
plugins: [
|
||||
esbuildPluginNodeModules.NodeModulesPolyfillPlugin(),
|
||||
esbuildPluginTime(),
|
||||
|
@ -3,6 +3,10 @@
|
||||
import * as react from 'react'
|
||||
import * as router from 'react-router-dom'
|
||||
|
||||
import ArrowRightIcon from 'enso-assets/arrow_right.svg'
|
||||
import AtIcon from 'enso-assets/at.svg'
|
||||
import GoBackIcon from 'enso-assets/go_back.svg'
|
||||
|
||||
import * as app from '../../components/app'
|
||||
import * as auth from '../providers/auth'
|
||||
import * as svg from '../../components/svg'
|
||||
@ -46,8 +50,9 @@ function ForgotPassword() {
|
||||
E-Mail Address:
|
||||
</label>
|
||||
<div className="relative">
|
||||
<SvgIcon svg={svg.AT} />
|
||||
|
||||
<SvgIcon>
|
||||
<svg.SvgMask src={AtIcon} />
|
||||
</SvgIcon>
|
||||
<Input
|
||||
id="email"
|
||||
type="email"
|
||||
@ -68,7 +73,9 @@ function ForgotPassword() {
|
||||
}
|
||||
>
|
||||
<span className="mr-2 uppercase">Send link</span>
|
||||
<span>{svg.RIGHT_ARROW}</span>
|
||||
<span>
|
||||
<svg.SvgMask src={ArrowRightIcon} />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@ -81,7 +88,9 @@ function ForgotPassword() {
|
||||
'text-center'
|
||||
}
|
||||
>
|
||||
<span>{svg.GO_BACK}</span>
|
||||
<span>
|
||||
<svg.SvgMask src={GoBackIcon} />
|
||||
</span>
|
||||
<span className="ml-2">Go back to login</span>
|
||||
</router.Link>
|
||||
</div>
|
||||
|
@ -2,6 +2,11 @@
|
||||
import * as react from 'react'
|
||||
import * as router from 'react-router-dom'
|
||||
|
||||
import ArrowRightIcon from 'enso-assets/arrow_right.svg'
|
||||
import AtIcon from 'enso-assets/at.svg'
|
||||
import CreateAccountIcon from 'enso-assets/create_account.svg'
|
||||
import LockIcon from 'enso-assets/lock.svg'
|
||||
|
||||
import * as fontawesomeIcons from '@fortawesome/free-brands-svg-icons'
|
||||
|
||||
import * as app from '../../components/app'
|
||||
@ -52,7 +57,7 @@ function Login() {
|
||||
}}
|
||||
className="relative mt-6 border rounded-md py-2 text-sm text-gray-800 bg-gray-100 hover:bg-gray-200"
|
||||
>
|
||||
<FontAwesomeIcon icon={fontawesomeIcons.faGithub} />
|
||||
<FontAwesomeIcon icon={fontawesomeIcons.faGoogle} />
|
||||
<span>Login with Google</span>
|
||||
</button>
|
||||
<button
|
||||
@ -87,8 +92,9 @@ function Login() {
|
||||
E-Mail Address:
|
||||
</label>
|
||||
<div className="relative">
|
||||
<SvgIcon svg={svg.AT} />
|
||||
|
||||
<SvgIcon>
|
||||
<svg.SvgMask src={AtIcon} />
|
||||
</SvgIcon>
|
||||
<Input
|
||||
required
|
||||
id="email"
|
||||
@ -108,8 +114,9 @@ function Login() {
|
||||
Password:
|
||||
</label>
|
||||
<div className="relative">
|
||||
<SvgIcon svg={svg.LOCK} />
|
||||
|
||||
<SvgIcon>
|
||||
<svg.SvgMask src={LockIcon} />
|
||||
</SvgIcon>
|
||||
<Input
|
||||
required={true}
|
||||
id="password"
|
||||
@ -143,7 +150,9 @@ function Login() {
|
||||
}
|
||||
>
|
||||
<span className="mr-2 uppercase">Login</span>
|
||||
<span>{svg.RIGHT_ARROW}</span>
|
||||
<span>
|
||||
<svg.SvgMask src={ArrowRightIcon} />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@ -156,7 +165,9 @@ function Login() {
|
||||
'text-xs text-center'
|
||||
}
|
||||
>
|
||||
<span>{svg.CREATE_ACCOUNT}</span>
|
||||
<span>
|
||||
<svg.SvgMask src={CreateAccountIcon} />
|
||||
</span>
|
||||
<span className="ml-2">You don't have an account?</span>
|
||||
</router.Link>
|
||||
</div>
|
||||
|
@ -3,6 +3,11 @@ import * as react from 'react'
|
||||
import * as router from 'react-router-dom'
|
||||
import toast from 'react-hot-toast'
|
||||
|
||||
import AtIcon from 'enso-assets/at.svg'
|
||||
import CreateAccountIcon from 'enso-assets/create_account.svg'
|
||||
import GoBackIcon from 'enso-assets/go_back.svg'
|
||||
import LockIcon from 'enso-assets/lock.svg'
|
||||
|
||||
import * as app from '../../components/app'
|
||||
import * as auth from '../providers/auth'
|
||||
import * as svg from '../../components/svg'
|
||||
@ -58,8 +63,9 @@ function Registration() {
|
||||
E-Mail Address:
|
||||
</label>
|
||||
<div className="relative">
|
||||
<SvgIcon svg={svg.AT} />
|
||||
|
||||
<SvgIcon>
|
||||
<svg.SvgMask src={AtIcon} />
|
||||
</SvgIcon>
|
||||
<Input
|
||||
id="email"
|
||||
type="email"
|
||||
@ -78,8 +84,9 @@ function Registration() {
|
||||
Password:
|
||||
</label>
|
||||
<div className="relative">
|
||||
<SvgIcon svg={svg.LOCK} />
|
||||
|
||||
<SvgIcon>
|
||||
<svg.SvgMask src={LockIcon} />
|
||||
</SvgIcon>
|
||||
<Input
|
||||
required
|
||||
id="password"
|
||||
@ -101,8 +108,9 @@ function Registration() {
|
||||
Confirm Password:
|
||||
</label>
|
||||
<div className="relative">
|
||||
<SvgIcon svg={svg.LOCK} />
|
||||
|
||||
<SvgIcon>
|
||||
<svg.SvgMask src={LockIcon} />
|
||||
</SvgIcon>
|
||||
<Input
|
||||
required
|
||||
id="password_confirmation"
|
||||
@ -125,7 +133,9 @@ function Registration() {
|
||||
}
|
||||
>
|
||||
<span className="mr-2 uppercase">Register</span>
|
||||
<span>{svg.CREATE_ACCOUNT}</span>
|
||||
<span>
|
||||
<svg.SvgMask src={CreateAccountIcon} />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@ -138,7 +148,9 @@ function Registration() {
|
||||
'text-sm text-center'
|
||||
}
|
||||
>
|
||||
<span>{svg.GO_BACK}</span>
|
||||
<span>
|
||||
<svg.SvgMask src={GoBackIcon} />
|
||||
</span>
|
||||
<span className="ml-2">Already have an account?</span>
|
||||
</router.Link>
|
||||
</div>
|
||||
|
@ -4,6 +4,11 @@ import * as react from 'react'
|
||||
import * as router from 'react-router-dom'
|
||||
import toast from 'react-hot-toast'
|
||||
|
||||
import ArrowRightIcon from 'enso-assets/arrow_right.svg'
|
||||
import AtIcon from 'enso-assets/at.svg'
|
||||
import GoBackIcon from 'enso-assets/go_back.svg'
|
||||
import LockIcon from 'enso-assets/lock.svg'
|
||||
|
||||
import * as app from '../../components/app'
|
||||
import * as auth from '../providers/auth'
|
||||
import * as svg from '../../components/svg'
|
||||
@ -72,8 +77,9 @@ function ResetPassword() {
|
||||
E-Mail Address:
|
||||
</label>
|
||||
<div className="relative">
|
||||
<SvgIcon svg={svg.AT} />
|
||||
|
||||
<SvgIcon>
|
||||
<svg.SvgMask src={AtIcon} />
|
||||
</SvgIcon>
|
||||
<Input
|
||||
id="email"
|
||||
type="email"
|
||||
@ -92,8 +98,9 @@ function ResetPassword() {
|
||||
Confirmation Code:
|
||||
</label>
|
||||
<div className="relative">
|
||||
<SvgIcon svg={svg.LOCK} />
|
||||
|
||||
<SvgIcon>
|
||||
<svg.SvgMask src={LockIcon} />
|
||||
</SvgIcon>
|
||||
<Input
|
||||
id="code"
|
||||
type="text"
|
||||
@ -112,8 +119,9 @@ function ResetPassword() {
|
||||
New Password:
|
||||
</label>
|
||||
<div className="relative">
|
||||
<SvgIcon svg={svg.LOCK} />
|
||||
|
||||
<SvgIcon>
|
||||
<svg.SvgMask src={LockIcon} />
|
||||
</SvgIcon>
|
||||
<Input
|
||||
id="new_password"
|
||||
type="password"
|
||||
@ -134,8 +142,9 @@ function ResetPassword() {
|
||||
Confirm New Password:
|
||||
</label>
|
||||
<div className="relative">
|
||||
<SvgIcon svg={svg.LOCK} />
|
||||
|
||||
<SvgIcon>
|
||||
<svg.SvgMask src={LockIcon} />
|
||||
</SvgIcon>
|
||||
<Input
|
||||
id="new_password_confirm"
|
||||
type="password"
|
||||
@ -156,7 +165,9 @@ function ResetPassword() {
|
||||
}
|
||||
>
|
||||
<span className="mr-2 uppercase">Reset</span>
|
||||
<span>{svg.RIGHT_ARROW}</span>
|
||||
<span>
|
||||
<svg.SvgMask src={ArrowRightIcon} />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@ -169,7 +180,9 @@ function ResetPassword() {
|
||||
'text-center'
|
||||
}
|
||||
>
|
||||
<span>{svg.GO_BACK}</span>
|
||||
<span>
|
||||
<svg.SvgMask src={GoBackIcon} />
|
||||
</span>
|
||||
<span className="ml-2">Go back to login</span>
|
||||
</router.Link>
|
||||
</div>
|
||||
|
@ -2,6 +2,9 @@
|
||||
* registration. */
|
||||
import * as react from 'react'
|
||||
|
||||
import ArrowRightIcon from 'enso-assets/arrow_right.svg'
|
||||
import AtIcon from 'enso-assets/at.svg'
|
||||
|
||||
import * as auth from '../providers/auth'
|
||||
import * as backendProvider from '../../providers/backend'
|
||||
import * as svg from '../../components/svg'
|
||||
@ -41,7 +44,9 @@ function SetUsername() {
|
||||
>
|
||||
<div className="flex flex-col mb-6">
|
||||
<div className="relative">
|
||||
<SvgIcon svg={svg.AT} />
|
||||
<SvgIcon>
|
||||
<svg.SvgMask src={AtIcon} />
|
||||
</SvgIcon>
|
||||
|
||||
<Input
|
||||
id="username"
|
||||
@ -63,7 +68,9 @@ function SetUsername() {
|
||||
}
|
||||
>
|
||||
<span className="mr-2 uppercase">Set username</span>
|
||||
<span>{svg.RIGHT_ARROW}</span>
|
||||
<span>
|
||||
<svg.SvgMask src={ArrowRightIcon} />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -1,24 +1,20 @@
|
||||
/** @file Styled wrapper around SVG images. */
|
||||
import * as React from 'react'
|
||||
|
||||
// ===============
|
||||
// === SvgIcon ===
|
||||
// ===============
|
||||
|
||||
/** Props for a {@link SvgIcon}. */
|
||||
export interface SvgIconProps {
|
||||
svg: JSX.Element
|
||||
}
|
||||
export interface SvgIconProps extends React.PropsWithChildren {}
|
||||
|
||||
/** A fixed-size container for a SVG image. */
|
||||
function SvgIcon(props: SvgIconProps) {
|
||||
const { children } = props
|
||||
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
'inline-flex items-center justify-center absolute left-0 top-0 h-full w-10 ' +
|
||||
'text-gray-400'
|
||||
}
|
||||
>
|
||||
<span>{props.svg}</span>
|
||||
<div className="inline-flex items-center justify-center absolute left-0 top-0 h-full w-10 text-gray-400">
|
||||
<span>{children}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -4,273 +4,10 @@
|
||||
* the `svg` files when building for Electron. Once the build scripts have been adapted to allow for
|
||||
* for this, the contents of this file should be moved back to standalone SVG files. */
|
||||
|
||||
// =================
|
||||
// === Constants ===
|
||||
// =================
|
||||
|
||||
export const AT = (
|
||||
<Svg path="M16 12a4 4 0 10-8 0 4 4 0 008 0zm0 0v1.5a2.5 2.5 0 005 0V12a9 9 0 10-9 9m4.5-1.206a8.959 8.959 0 01-4.5 1.207" />
|
||||
)
|
||||
|
||||
export const LOCK = (
|
||||
<Svg path="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
|
||||
)
|
||||
|
||||
export const RIGHT_ARROW = <Svg path="M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
|
||||
export const CREATE_ACCOUNT = (
|
||||
<Svg path="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z" />
|
||||
)
|
||||
|
||||
export const GO_BACK = (
|
||||
<Svg path="M11 16l-4-4m0 0l4-4m-4 4h14m-5 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h7a3 3 0 013 3v1" />
|
||||
)
|
||||
|
||||
// ===================================
|
||||
// === SVGs with custom formatting ===
|
||||
// ===================================
|
||||
|
||||
/** Icon used to indicate a warning. */
|
||||
export const EXCLAMATION_ICON = (
|
||||
<svg width={18} height={18} viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
fill="#f9fafb"
|
||||
fillOpacity={0.7}
|
||||
fillRule="evenodd"
|
||||
d="M9 0A9 9 0 1 1 9 18 9 9 0 1 1 9 0M7.5 3.5H10.5L10 10.5H8L7.5 3.5ZM8 12L10 12 10 14 8 14"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** Icon representing a file being uploaded. */
|
||||
export const UPLOAD_ICON = (
|
||||
<svg width={24} height={24} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
x={3}
|
||||
y={14}
|
||||
width={12}
|
||||
height={17}
|
||||
rx={2}
|
||||
transform="rotate(-90 3 14)"
|
||||
fill="currentColor"
|
||||
fillOpacity={0.2}
|
||||
/>
|
||||
<path
|
||||
d="M11.5 21C10.6716 21 10 20.3284 10 19.5L10 11L13 11L13 19.5C13 20.33 12.33 21 11.5 21Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path d="M7 11L11.5 5L16 11L7 11Z" fill="currentColor" />
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** Icon representing a file being downloaded. */
|
||||
export const DOWNLOAD_ICON = (
|
||||
<svg width={24} height={24} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
x={3}
|
||||
y={12}
|
||||
width={10}
|
||||
height={18}
|
||||
rx={2}
|
||||
transform="rotate(-90 3 12)"
|
||||
fill="currentColor"
|
||||
fillOpacity={0.2}
|
||||
/>
|
||||
<path
|
||||
d="M11.5 7C12.33 7 13 7.67 13 8.5L13 15L10 15L10 8.5C10 7.67 10.67 7 11.5 7Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path d="M16 15L11.5 21L7.00003 15L16 15Z" fill="currentColor" />
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** Icon representing a directory. */
|
||||
export const DIRECTORY_ICON = (
|
||||
<svg width={24} height={24} viewBox="-2 -2 20 20">
|
||||
<path
|
||||
d="M0 7h16v6a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V7Zm0-4h14a2 2 0 0 1 2 2v1H0V3Zm0 0c0-1.1.9-2 2-2h4a2 2 0 0 1 2 2H0Z"
|
||||
fill="currentColor"
|
||||
fillOpacity={0.4}
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** Icon representing a secret. */
|
||||
export const SECRET_ICON = (
|
||||
<svg width={24} height={24} viewBox="0 0 24 24">
|
||||
<path
|
||||
d="M10.3 13a4 4 0 1 1 0-2h10a1 1 0 0 1 1 1v3a1 1 0 0 1-2 0v-2h-2v2a1 1 0 0 1-2 0v-2ZM3.5 12a1 1 0 1 1 2 0a1 1 0 1 1-2 0"
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** Icon representing a file whose filetype does not have an associated icon. */
|
||||
export const FILE_ICON = (
|
||||
<svg width={24} height={24} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M6.5 3h8v2a2 2 0 0 0 2 2h2v13a1 1 0 0 1 -1 1h-11a1 1 0 0 1 -1 -1v-16a1 1 0 0 1 1 -1ZM15 3v2a1.5 1.5 0 0 0 1.5 1.5h2"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** Icon typically indicating that the item on the right is a child of the item on the left. */
|
||||
export const SMALL_RIGHT_ARROW_ICON = (
|
||||
<svg width={8} height={8} viewBox="-1 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m0 0 6 4-6 4V0Z" fill="currentColor" fillOpacity={0.7} />
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** Displayed when a project is ready to start. */
|
||||
export const PLAY_ICON = (
|
||||
<svg width={24} height={24} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="m10.04 7.34 6 3.85a1 1 0 0 1 0 1.68l-6 3.85a1 1 0 0 1-1.54-.84v-7.7a1 1 0 0 1 1.54-.84Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<rect
|
||||
x={1.5}
|
||||
y={1.5}
|
||||
width={21}
|
||||
height={21}
|
||||
rx={10.5}
|
||||
stroke="currentColor"
|
||||
strokeOpacity={0.1}
|
||||
strokeWidth={3}
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** Displayed when a project is ready for opening an IDE. */
|
||||
export const ARROW_UP_ICON = (
|
||||
<svg width={24} height={24} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
width={21}
|
||||
height={21}
|
||||
x={1.5}
|
||||
y={1.5}
|
||||
rx={10.5}
|
||||
stroke="currentColor"
|
||||
strokeOpacity={0.1}
|
||||
strokeWidth={3}
|
||||
/>
|
||||
<path d="M12 17a1.5 1.5 0 0 1-1.5-1.5V12h3v3.5A1.5 1.5 0 0 1 12 17Z" fill="currentColor" />
|
||||
<path
|
||||
d="M8.943 12a1 1 0 0 1-.814-1.581l3.057-4.28a1 1 0 0 1 1.628 0l3.056 4.28A1 1 0 0 1 15.057 12H8.943Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** `+`-shaped icon representing creation of an item. */
|
||||
export const ADD_ICON = (
|
||||
<svg width={18} height={18} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx={12} cy={12} r={12} fill="currentColor" fillOpacity={0.1} />
|
||||
<g opacity={0.66}>
|
||||
<rect x={11} y={6} width={2} height={12} fill="currentColor" />
|
||||
<rect x={6} y={11} width={12} height={2} fill="currentColor" />
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** An icon representing creation of an item. */
|
||||
export const CIRCLED_PLUS_ICON = (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={80}
|
||||
height={80}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
strokeWidth={0.5}
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M12 9v6m3-3H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** Icon with three bars. */
|
||||
export const BARS_ICON = (
|
||||
<svg width={16} height={16} viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x={2} y={1} width={12} height={3} fill="#767676" />
|
||||
<rect x={2} y={6} width={12} height={3} fill="#767676" />
|
||||
<rect x={2} y={11} width={12} height={3} fill="#767676" />
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** Icon indicating a search input. */
|
||||
export const MAGNIFYING_GLASS_ICON = (
|
||||
<svg width={16} height={16} viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g opacity={0.5}>
|
||||
<path
|
||||
d="M11.4142 10L15.6569 14.2426L14.2426 15.6569L10 11.4142L11.4142 10Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<circle cx={7} cy={7} r={5} stroke="currentColor" strokeWidth={2} />
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** Icon indicating a chat dialog. */
|
||||
export const SPEECH_BUBBLE_ICON = (
|
||||
<svg width={16} height={17} viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<ellipse cx={8} cy={8} rx={8} ry={7.5} fill="white" />
|
||||
<path d="M4.17269e-05 16.5L2 10.5L5.50006 14L4.17269e-05 16.5Z" fill="white" />
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** `x`-shaped icon representing the closing of a window. */
|
||||
export const CLOSE_ICON = (
|
||||
<svg width={18} height={18} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx={12} cy={12} r={12} fill="currentColor" fillOpacity={0.1} />
|
||||
<g opacity={0.66} transform="rotate(45 12 12)">
|
||||
<rect x={11} y={6} width={2} height={12} fill="currentColor" />
|
||||
<rect x={6} y={11} width={12} height={2} fill="currentColor" />
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const CLOUD_ICON = (
|
||||
<svg width={18} height={18} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M6.5 16A2.9 2.9 0 1 1 8 10.5 4 4 0 0 1 15.5 11 2 2 0 0 1 17.5 12 1.9 1.9 0 1 1 18.5 16"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const COMPUTER_ICON = (
|
||||
<svg width={18} height={18} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M3.5 18.5a1 1 0 0 1 0-2h3.5v-1.5h-3.5a1 1 0 0 1-1-1v-7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7a1 1 0 0 1-1 1h-3.5v1.5h3.5a1 1 0 0 1 0 2ZM4 14a.5.5 0 0 1-.5-.5v-6a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-.5.5ZM17.3 18.5a1 1 0 0 1-1-1v-10.5a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v10.5a1 1 0 0 1-1 1ZM17.3 9a.3.3 0 1 1 0-.6h3a.3.3 0 1 1 0 .6ZM18.8 16a.7.7 0 1 1 0-1.4.7.7 0 1 1 0 1.4Z"
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** An icon representing a user without a profile picture. */
|
||||
export const DEFAULT_USER_ICON = (
|
||||
<svg height={32} width={32} viewBox="2 2 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M6 20a10 10 0 0 1 6 -18 10 10 0 0 1 6 18 6 6 0 0 0 -4 -5 4.3 4.3 0 0 0 -2 -8 4.3 4.3 0 0 0 -2 8 6 6 0 0 0 -4 5"
|
||||
fill="#888888"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** An icon representing a menu that can be expanded downwards. */
|
||||
export const DOWN_CARET_ICON = (
|
||||
<svg height={16} width={16} viewBox="-1-1 12 12" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1 3l4 4 4-4" fill="transparent" stroke="currentColor" strokeLinecap="round" />
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** Props for a {@link Spinner}. */
|
||||
export interface SpinnerProps {
|
||||
size: number
|
||||
@ -352,31 +89,33 @@ export function StopIcon(props: StopIconProps) {
|
||||
)
|
||||
}
|
||||
|
||||
// ===========
|
||||
// === Svg ===
|
||||
// ===========
|
||||
// ===============
|
||||
// === SvgMask ===
|
||||
// ===============
|
||||
|
||||
/** Props for a {@link Svg}. */
|
||||
export interface SvgProps {
|
||||
path: string
|
||||
/** Props for a {@link SvgMask}. */
|
||||
export interface SvgMaskProps {
|
||||
/** The URL of the SVG to use as the mask. */
|
||||
src: string
|
||||
}
|
||||
|
||||
/** Component for rendering SVG icons.
|
||||
*
|
||||
* @param props - Extra props for the SVG path. The `props.data` field in particular contains the
|
||||
* SVG path data. */
|
||||
function Svg(props: SvgProps) {
|
||||
/** Use an SVG as a mask. This lets the SVG use the text color (`currentColor`). */
|
||||
export function SvgMask(props: SvgMaskProps) {
|
||||
const { src } = props
|
||||
const urlSrc = `url(${JSON.stringify(src)})`
|
||||
|
||||
return (
|
||||
<svg
|
||||
className="h-6 w-6"
|
||||
fill="none"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: 'currentcolor',
|
||||
mask: urlSrc,
|
||||
// The names come from a third-party API and cannot be changed.
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
WebkitMask: urlSrc,
|
||||
}}
|
||||
>
|
||||
<path d={props.path} />
|
||||
</svg>
|
||||
{/* This is required for this component to have the right size. */}
|
||||
<img src={src} className="opacity-0" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
/** @file Managing the logic and displaying the UI for the password change function. */
|
||||
import * as react from 'react'
|
||||
|
||||
import toast from 'react-hot-toast'
|
||||
|
||||
import ArrowRightIcon from 'enso-assets/arrow_right.svg'
|
||||
import LockIcon from 'enso-assets/lock.svg'
|
||||
|
||||
import * as auth from '../../authentication/providers/auth'
|
||||
import * as modalProvider from '../../providers/modal'
|
||||
import * as svg from '../../components/svg'
|
||||
@ -10,6 +12,7 @@ import * as validation from '../validation'
|
||||
|
||||
import Input from './input'
|
||||
import Modal from './modal'
|
||||
import SvgIcon from './svgIcon'
|
||||
|
||||
// ==========================
|
||||
// === ResetPasswordModal ===
|
||||
@ -61,10 +64,9 @@ function ChangePasswordModal() {
|
||||
Old Password:
|
||||
</label>
|
||||
<div className="relative">
|
||||
<div className="inline-flex items-center justify-center absolute left-0 top-0 h-full w-10 text-gray-400">
|
||||
{svg.LOCK}
|
||||
</div>
|
||||
|
||||
<SvgIcon>
|
||||
<svg.SvgMask src={LockIcon} />
|
||||
</SvgIcon>
|
||||
<Input
|
||||
autoFocus
|
||||
required
|
||||
@ -88,10 +90,9 @@ function ChangePasswordModal() {
|
||||
New Password:
|
||||
</label>
|
||||
<div className="relative">
|
||||
<div className="inline-flex items-center justify-center absolute left-0 top-0 h-full w-10 text-gray-400">
|
||||
{svg.LOCK}
|
||||
</div>
|
||||
|
||||
<SvgIcon>
|
||||
<svg.SvgMask src={LockIcon} />
|
||||
</SvgIcon>
|
||||
<Input
|
||||
required
|
||||
id="new_password"
|
||||
@ -114,10 +115,9 @@ function ChangePasswordModal() {
|
||||
Confirm New Password:
|
||||
</label>
|
||||
<div className="relative">
|
||||
<div className="inline-flex items-center justify-center absolute left-0 top-0 h-full w-10 text-gray-400">
|
||||
{svg.LOCK}
|
||||
</div>
|
||||
|
||||
<SvgIcon>
|
||||
<svg.SvgMask src={LockIcon} />
|
||||
</SvgIcon>
|
||||
<Input
|
||||
required
|
||||
id="confirm_new_password"
|
||||
@ -136,7 +136,9 @@ function ChangePasswordModal() {
|
||||
className="flex items-center justify-center focus:outline-none text-white text-sm sm:text-base bg-blue-600 hover:bg-blue-700 rounded py-2 w-full transition duration-150 ease-in"
|
||||
>
|
||||
<span className="mr-2 uppercase">Reset</span>
|
||||
<span>{svg.RIGHT_ARROW}</span>
|
||||
<span>
|
||||
<svg.SvgMask src={ArrowRightIcon} />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -2,8 +2,9 @@
|
||||
import * as react from 'react'
|
||||
import toast from 'react-hot-toast'
|
||||
|
||||
import CloseIcon from 'enso-assets/close.svg'
|
||||
|
||||
import * as modalProvider from '../../providers/modal'
|
||||
import * as svg from '../../components/svg'
|
||||
|
||||
import Modal from './modal'
|
||||
|
||||
@ -58,7 +59,7 @@ function ConfirmDeleteModal(props: ConfirmDeleteModalProps) {
|
||||
className="relative bg-white shadow-soft rounded-lg w-96 p-2"
|
||||
>
|
||||
<button type="button" className="absolute right-0 top-0 m-2" onClick={unsetModal}>
|
||||
{svg.CLOSE_ICON}
|
||||
<img src={CloseIcon} />
|
||||
</button>
|
||||
Are you sure you want to delete the {assetType} '{name}'?
|
||||
<div className="m-1">
|
||||
|
@ -4,8 +4,9 @@
|
||||
|
||||
import * as react from 'react'
|
||||
|
||||
import CloseIcon from 'enso-assets/close.svg'
|
||||
|
||||
import * as modalProvider from '../../providers/modal'
|
||||
import * as svg from '../../components/svg'
|
||||
|
||||
import Modal from './modal'
|
||||
|
||||
@ -46,7 +47,7 @@ function CreateForm(props: CreateFormProps) {
|
||||
}}
|
||||
>
|
||||
<button type="button" className="absolute right-0 m-2" onClick={unsetModal}>
|
||||
{svg.CLOSE_ICON}
|
||||
<img src={CloseIcon} />
|
||||
</button>
|
||||
<h2 className="inline-block font-semibold m-2">{title}</h2>
|
||||
{children}
|
||||
|
@ -3,6 +3,14 @@
|
||||
import * as react from 'react'
|
||||
import toast from 'react-hot-toast'
|
||||
|
||||
import ArrowRightSmallIcon from 'enso-assets/arrow_right_small.svg'
|
||||
import DefaultUserIcon from 'enso-assets/default_user.svg'
|
||||
import DirectoryIcon from 'enso-assets/directory.svg'
|
||||
import DownloadIcon from 'enso-assets/download.svg'
|
||||
import PlusIcon from 'enso-assets/plus.svg'
|
||||
import SecretIcon from 'enso-assets/secret.svg'
|
||||
import UploadIcon from 'enso-assets/upload.svg'
|
||||
|
||||
import * as common from 'enso-common'
|
||||
|
||||
import * as backendModule from '../backend'
|
||||
@ -14,7 +22,6 @@ import * as localBackend from '../localBackend'
|
||||
import * as newtype from '../../newtype'
|
||||
import * as projectManager from '../projectManager'
|
||||
import * as remoteBackendModule from '../remoteBackend'
|
||||
import * as svg from '../../components/svg'
|
||||
import * as uploadMultipleFiles from '../../uploadMultipleFiles'
|
||||
|
||||
import * as authProvider from '../../authentication/providers/auth'
|
||||
@ -602,7 +609,7 @@ function Dashboard(props: DashboardProps) {
|
||||
enterDirectory(directoryAsset)
|
||||
}}
|
||||
>
|
||||
{svg.DIRECTORY_ICON} <span className="px-2">{directoryAsset.title}</span>
|
||||
<img src={DirectoryIcon} /> <span className="px-2">{directoryAsset.title}</span>
|
||||
</div>
|
||||
),
|
||||
[backendModule.AssetType.secret]: secret => (
|
||||
@ -622,7 +629,7 @@ function Dashboard(props: DashboardProps) {
|
||||
}
|
||||
}}
|
||||
>
|
||||
{svg.SECRET_ICON} <span className="px-2">{secret.title}</span>
|
||||
<img src={SecretIcon} /> <span className="px-2">{secret.title}</span>
|
||||
</div>
|
||||
),
|
||||
[backendModule.AssetType.file]: file => (
|
||||
@ -642,7 +649,7 @@ function Dashboard(props: DashboardProps) {
|
||||
}
|
||||
}}
|
||||
>
|
||||
{fileInfo.fileIcon()} <span className="px-2">{file.title}</span>
|
||||
<img src={fileInfo.fileIcon()} /> <span className="px-2">{file.title}</span>
|
||||
</div>
|
||||
),
|
||||
}
|
||||
@ -663,7 +670,7 @@ function Dashboard(props: DashboardProps) {
|
||||
key={user.user.organization_id}
|
||||
permissions={PERMISSION[user.permission]}
|
||||
>
|
||||
{svg.DEFAULT_USER_ICON}
|
||||
<img src={DefaultUserIcon} />
|
||||
</PermissionDisplay>
|
||||
))}
|
||||
</>
|
||||
@ -756,7 +763,7 @@ function Dashboard(props: DashboardProps) {
|
||||
}
|
||||
}}
|
||||
>
|
||||
{svg.ADD_ICON}
|
||||
<img src={PlusIcon} />
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
@ -995,7 +1002,7 @@ function Dashboard(props: DashboardProps) {
|
||||
<button className="mx-2" onClick={exitDirectory}>
|
||||
{parentDirectory?.title ?? '/'}
|
||||
</button>
|
||||
{svg.SMALL_RIGHT_ARROW_ICON}
|
||||
<img src={ArrowRightSmallIcon} />
|
||||
</>
|
||||
)}
|
||||
<span className="mx-2">{directory?.title ?? '/'}</span>
|
||||
@ -1027,7 +1034,7 @@ function Dashboard(props: DashboardProps) {
|
||||
))
|
||||
}}
|
||||
>
|
||||
{svg.UPLOAD_ICON}
|
||||
<img src={UploadIcon} />
|
||||
</button>
|
||||
<button
|
||||
className={`mx-1 opacity-50`}
|
||||
@ -1038,7 +1045,7 @@ function Dashboard(props: DashboardProps) {
|
||||
/* TODO */
|
||||
}}
|
||||
>
|
||||
{svg.DOWNLOAD_ICON}
|
||||
<img src={DownloadIcon} />
|
||||
</button>
|
||||
</div>
|
||||
{EXPERIMENTAL.columnModeSwitcher && (
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file A label, which may be either user-defined, or a system warning message. */
|
||||
import * as react from 'react'
|
||||
|
||||
import * as svg from '../../components/svg'
|
||||
import ExclamationIcon from 'enso-assets/exclamation.svg'
|
||||
|
||||
// =============
|
||||
// === Types ===
|
||||
@ -28,8 +28,16 @@ const CSS_CLASS: Record<Status, string> = {
|
||||
/** A mapping of label type to its corresponding icon. */
|
||||
const STATUS_ICON: Record<Status, JSX.Element | null> = {
|
||||
[Status.none]: null,
|
||||
[Status.warning]: <div className="m-1">{svg.EXCLAMATION_ICON}</div>,
|
||||
[Status.severeWarning]: <div className="m-1">{svg.EXCLAMATION_ICON}</div>,
|
||||
[Status.warning]: (
|
||||
<div className="m-1">
|
||||
<img src={ExclamationIcon} />
|
||||
</div>
|
||||
),
|
||||
[Status.severeWarning]: (
|
||||
<div className="m-1">
|
||||
<img src={ExclamationIcon} />
|
||||
</div>
|
||||
),
|
||||
}
|
||||
|
||||
// =================
|
||||
|
@ -2,6 +2,9 @@
|
||||
import * as react from 'react'
|
||||
import toast from 'react-hot-toast'
|
||||
|
||||
import ArrowUpIcon from 'enso-assets/arrow_up.svg'
|
||||
import PlayIcon from 'enso-assets/play.svg'
|
||||
|
||||
import * as backendModule from '../backend'
|
||||
import * as backendProvider from '../../providers/backend'
|
||||
import * as localBackend from '../localBackend'
|
||||
@ -347,7 +350,7 @@ function ProjectActionButton(props: ProjectActionButtonProps) {
|
||||
doOpenManually()
|
||||
}}
|
||||
>
|
||||
{svg.PLAY_ICON}
|
||||
<img src={PlayIcon} />
|
||||
</button>
|
||||
)
|
||||
case backendModule.ProjectState.openInProgress:
|
||||
@ -381,7 +384,7 @@ function ProjectActionButton(props: ProjectActionButtonProps) {
|
||||
openIde()
|
||||
}}
|
||||
>
|
||||
{svg.ARROW_UP_ICON}
|
||||
<img src={ArrowUpIcon} />
|
||||
</button>
|
||||
</>
|
||||
)
|
||||
|
@ -2,8 +2,9 @@
|
||||
import * as react from 'react'
|
||||
import toast from 'react-hot-toast'
|
||||
|
||||
import CloseIcon from 'enso-assets/close.svg'
|
||||
|
||||
import * as modalProvider from '../../providers/modal'
|
||||
import * as svg from '../../components/svg'
|
||||
|
||||
import Input from './input'
|
||||
import Modal from './modal'
|
||||
@ -62,7 +63,7 @@ function RenameModal(props: RenameModalProps) {
|
||||
className="relative bg-white shadow-soft rounded-lg w-96 p-2"
|
||||
>
|
||||
<button type="button" className="absolute right-0 top-0 m-2" onClick={unsetModal}>
|
||||
{svg.CLOSE_ICON}
|
||||
<img src={CloseIcon} />
|
||||
</button>
|
||||
What do you want to rename the {assetType} '{name}' to?
|
||||
<div className="m-2">
|
||||
|
@ -0,0 +1,22 @@
|
||||
/** @file Styled wrapper around SVG images. */
|
||||
import * as React from 'react'
|
||||
|
||||
// ===============
|
||||
// === SvgIcon ===
|
||||
// ===============
|
||||
|
||||
/** Props for a {@link SvgIcon}. */
|
||||
export interface SvgIconProps extends React.PropsWithChildren {}
|
||||
|
||||
/** A fixed-size container for a SVG image. */
|
||||
function SvgIcon(props: SvgIconProps) {
|
||||
const { children } = props
|
||||
|
||||
return (
|
||||
<div className="inline-flex items-center justify-center absolute left-0 top-0 h-full w-10 text-gray-400">
|
||||
<span>{children}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SvgIcon
|
@ -1,5 +1,5 @@
|
||||
/** @file Renders the list of templates from which a project can be created. */
|
||||
import * as svg from '../../components/svg'
|
||||
import PlusCircledIcon from 'enso-assets/plus_circled.svg'
|
||||
|
||||
// =================
|
||||
// === Templates ===
|
||||
@ -78,7 +78,9 @@ function TemplatesRender(props: TemplatesRenderProps) {
|
||||
>
|
||||
<div className="flex h-full w-full border-dashed-custom rounded-2xl text-primary">
|
||||
<div className="m-auto text-center">
|
||||
<button>{svg.CIRCLED_PLUS_ICON}</button>
|
||||
<button>
|
||||
<img src={PlusCircledIcon} />
|
||||
</button>
|
||||
<p className="font-semibold text-sm">New empty project</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,9 +1,15 @@
|
||||
/** @file The top-bar of dashboard. */
|
||||
import * as react from 'react'
|
||||
|
||||
import BarsIcon from 'enso-assets/bars.svg'
|
||||
import CloudIcon from 'enso-assets/cloud.svg'
|
||||
import ComputerIcon from 'enso-assets/computer.svg'
|
||||
import DefaultUserIcon from 'enso-assets/default_user.svg'
|
||||
import MagnifyingGlassIcon from 'enso-assets/magnifying_glass.svg'
|
||||
import SpeechBubbleIcon from 'enso-assets/speech_bubble.svg'
|
||||
|
||||
import * as backendModule from '../backend'
|
||||
import * as dashboard from './dashboard'
|
||||
import * as svg from '../../components/svg'
|
||||
|
||||
import * as backendProvider from '../../providers/backend'
|
||||
import * as modalProvider from '../../providers/modal'
|
||||
@ -63,7 +69,7 @@ function TopBar(props: TopBarProps) {
|
||||
: 'opacity-50'
|
||||
} rounded-full px-1.5 py-1`}
|
||||
>
|
||||
{svg.COMPUTER_ICON}
|
||||
<img src={ComputerIcon} />
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
@ -75,7 +81,7 @@ function TopBar(props: TopBarProps) {
|
||||
: 'opacity-50'
|
||||
} rounded-full px-1.5 py-1`}
|
||||
>
|
||||
{svg.CLOUD_ICON}
|
||||
<img src={CloudIcon} />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
@ -91,7 +97,9 @@ function TopBar(props: TopBarProps) {
|
||||
>
|
||||
{projectName ?? 'Dashboard'}
|
||||
</span>
|
||||
<div className="bg-white shadow-soft rounded-full px-1.5 py-1">{svg.BARS_ICON}</div>
|
||||
<div className="bg-white shadow-soft rounded-full px-1.5 py-1">
|
||||
<img src={BarsIcon} />
|
||||
</div>
|
||||
<span
|
||||
className={`opacity-50 overflow-hidden transition-width nowrap ${
|
||||
tab === dashboard.Tab.ide ? 'm-2 w-16' : 'w-0'
|
||||
@ -101,7 +109,9 @@ function TopBar(props: TopBarProps) {
|
||||
</span>
|
||||
</div>
|
||||
<div className="grow flex items-center bg-label rounded-full px-2">
|
||||
<div>{svg.MAGNIFYING_GLASS_ICON}</div>
|
||||
<div>
|
||||
<img src={MagnifyingGlassIcon} />
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
size={1}
|
||||
@ -119,7 +129,9 @@ function TopBar(props: TopBarProps) {
|
||||
className="flex items-center bg-help rounded-full px-2.5 text-white mx-2"
|
||||
>
|
||||
<span className="whitespace-nowrap">help chat</span>
|
||||
<div className="ml-2">{svg.SPEECH_BUBBLE_ICON}</div>
|
||||
<div className="ml-2">
|
||||
<img src={SpeechBubbleIcon} />
|
||||
</div>
|
||||
</a>
|
||||
{/* User profile and menu. */}
|
||||
<div className="transform w-8">
|
||||
@ -130,7 +142,7 @@ function TopBar(props: TopBarProps) {
|
||||
}}
|
||||
className="rounded-full w-8 h-8 bg-cover cursor-pointer"
|
||||
>
|
||||
{svg.DEFAULT_USER_ICON}
|
||||
<img src={DefaultUserIcon} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,11 +2,12 @@
|
||||
import * as react from 'react'
|
||||
import toast from 'react-hot-toast'
|
||||
|
||||
import CloseIcon from 'enso-assets/close.svg'
|
||||
|
||||
import * as backendModule from '../backend'
|
||||
import * as backendProvider from '../../providers/backend'
|
||||
import * as fileInfo from '../../fileInfo'
|
||||
import * as modalProvider from '../../providers/modal'
|
||||
import * as svg from '../../components/svg'
|
||||
|
||||
import Modal from './modal'
|
||||
|
||||
@ -67,7 +68,7 @@ function UploadFileModal(props: UploadFileModalProps) {
|
||||
className="absolute right-0 top-0 m-2"
|
||||
onClick={unsetModal}
|
||||
>
|
||||
{svg.CLOSE_ICON}
|
||||
<img src={CloseIcon} />
|
||||
</button>
|
||||
<div className="m-2">
|
||||
<label className="w-1/3" htmlFor="uploaded_file_name">
|
||||
|
@ -1,5 +1,5 @@
|
||||
/** @file Utility functions for extracting and manipulating file information. */
|
||||
import * as svg from './components/svg'
|
||||
import FileIcon from 'enso-assets/file.svg'
|
||||
|
||||
// ================================
|
||||
// === Extract file information ===
|
||||
@ -12,7 +12,7 @@ export function fileExtension(fileName: string) {
|
||||
|
||||
/** Returns the appropriate icon for a specific file extension. */
|
||||
export function fileIcon() {
|
||||
return svg.FILE_ICON
|
||||
return FileIcon
|
||||
}
|
||||
|
||||
// ===================================
|
||||
|
@ -104,7 +104,7 @@ body {
|
||||
}
|
||||
|
||||
.border-dashed-custom {
|
||||
background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='16' ry='16' stroke='%233e515f' stroke-width='4' stroke-dasharray='11 11' stroke-linecap='butt'/%3e%3c/svg%3e");
|
||||
background-image: url("enso-assets/dashed_border.svg");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,8 +29,7 @@ OPTS.entryPoints.push(
|
||||
)
|
||||
OPTS.minify = false
|
||||
OPTS.write = false
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
OPTS.loader = { '.html': 'copy' }
|
||||
OPTS.loader['.html'] = 'copy'
|
||||
OPTS.pure.splice(OPTS.pure.indexOf('assert'), 1)
|
||||
;(OPTS.inject = OPTS.inject ?? []).push(path.resolve(THIS_PATH, '..', '..', 'debugGlobals.ts'))
|
||||
OPTS.plugins.push({
|
||||
|
@ -5,13 +5,13 @@
|
||||
"name": "Enso Team",
|
||||
"email": "contact@enso.org"
|
||||
},
|
||||
"homepage": "https://github.com/enso-org/ide",
|
||||
"homepage": "https://github.com/enso-org/enso/tree/develop/app/ide-desktop/lib/icons",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:enso-org/ide.git"
|
||||
"url": "git@github.com:enso-org/enso.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/enso-org/ide/issues"
|
||||
"url": "https://github.com/enso-org/enso/issues"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node src/index.js"
|
||||
|
5
app/ide-desktop/lib/types/modules.d.ts
vendored
@ -6,6 +6,11 @@
|
||||
// === Module declarations ===
|
||||
// ===========================
|
||||
|
||||
declare module '*.svg' {
|
||||
const PATH: string
|
||||
export default PATH
|
||||
}
|
||||
|
||||
// Required because this is a build artifact, which does not exist on a clean repository.
|
||||
declare module '*/build.json' {
|
||||
/** Build metadata generated by the build CLI. */
|
||||
|
14
app/ide-desktop/package-lock.json
generated
@ -8,12 +8,13 @@
|
||||
"name": "root",
|
||||
"version": "1.0.0",
|
||||
"workspaces": [
|
||||
"lib/assets",
|
||||
"lib/client",
|
||||
"lib/common",
|
||||
"lib/content",
|
||||
"lib/content-config",
|
||||
"lib/dashboard",
|
||||
"lib/dashboard/src/authentication",
|
||||
"lib/content-config",
|
||||
"lib/esbuild-plugin-copy-directories",
|
||||
"lib/icons"
|
||||
],
|
||||
@ -25,6 +26,10 @@
|
||||
"eslint-plugin-jsdoc": "^40.0.2"
|
||||
}
|
||||
},
|
||||
"lib/assets": {
|
||||
"name": "enso-assets",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"lib/client": {
|
||||
"name": "enso",
|
||||
"version": "0.0.0-dev",
|
||||
@ -7447,6 +7452,10 @@
|
||||
"resolved": "lib/client",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/enso-assets": {
|
||||
"resolved": "lib/assets",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/enso-authentication": {
|
||||
"resolved": "lib/dashboard/src/authentication",
|
||||
"link": true
|
||||
@ -20897,6 +20906,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"enso-assets": {
|
||||
"version": "file:lib/assets"
|
||||
},
|
||||
"enso-authentication": {
|
||||
"version": "file:lib/dashboard/src/authentication",
|
||||
"requires": {
|
||||
|
@ -16,12 +16,13 @@
|
||||
"name": "root",
|
||||
"private": true,
|
||||
"workspaces": [
|
||||
"lib/assets",
|
||||
"lib/client",
|
||||
"lib/common",
|
||||
"lib/content",
|
||||
"lib/content-config",
|
||||
"lib/dashboard",
|
||||
"lib/dashboard/src/authentication",
|
||||
"lib/content-config",
|
||||
"lib/esbuild-plugin-copy-directories",
|
||||
"lib/icons"
|
||||
],
|
||||
|