Skip to content

Commit

Permalink
Update UI design (#441)
Browse files Browse the repository at this point in the history
Co-authored-by: makiopen <[email protected]>
  • Loading branch information
ericglau and makiopen authored Feb 13, 2025
1 parent 8ba4b75 commit 09049ef
Show file tree
Hide file tree
Showing 26 changed files with 301 additions and 160 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ Contracts Wizard is a web application to interactively build a contract out of c

Install dependencies with `yarn install`.

`packages/core` contains the code generation logic for Solidity and Cairo under separately named subfolders.
`packages/core` contains the code generation logic for each language under separately named subfolders.

`packages/ui` is the interface built in Svelte. `yarn dev` spins up a local server to develop the UI.
`packages/ui` is the interface built in Svelte. From the `packages/ui` directory, run `yarn dev` to spin up a local server to develop the UI.

You'll need to supply your own environment variables if you want to enable Wizard AI Assistant (OPENAI_API_KEY) and/or logging (REDIS_URL, REDIS_TOKEN).

Expand All @@ -30,7 +30,7 @@ Then place `<oz-wizard></oz-wizard>` in the body where you want Contracts Wizard

Optionally focus on specific tab with the `data-tab` attribute as in `<oz-wizard data-tab="ERC721"></oz-wizard>`.

For Cairo, use the `data-lang` attribute: `<oz-wizard data-lang="cairo"></oz-wizard>`.
For languages other than Solidity, use the `data-lang` attribute, for example: `<oz-wizard data-lang="cairo"></oz-wizard>`.

## API

Expand Down
11 changes: 11 additions & 0 deletions packages/core/cairo/src/contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,14 @@ test('contract with standalone import', t => {
t.snapshot(printContract(Foo));
});

test('contract with sorted use clauses', t => {
const Foo = new ContractBuilder('Foo');
Foo.addComponent(
FOO_COMPONENT,
);
Foo.addUseClause('some::library', 'SomeLibrary');
Foo.addUseClause('another::library', 'AnotherLibrary');
Foo.addUseClause('another::library', 'Foo', { alias: 'Custom2' });
Foo.addUseClause('another::library', 'Foo', { alias: 'Custom1' });
t.snapshot(printContract(Foo));
});
42 changes: 42 additions & 0 deletions packages/core/cairo/src/contract.test.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,45 @@ Generated by [AVA](https://avajs.dev).
}␊
}␊
`

## contract with sorted use clauses

> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^0.20.0␊
#[starknet::contract]␊
mod Foo {␊
use another::library::{AnotherLibrary, Foo as Custom1, Foo as Custom2};␊
use some::library::SomeLibrary;␊
use some::path::FooComponent;␊
component!(path: FooComponent, storage: foo, event: FooEvent);␊
// External␊
#[abi(embed_v0)]␊
impl FooImpl = FooComponent::FooImpl<ContractState>;␊
// Internal␊
impl FooInternalImpl = FooComponent::InternalImpl<ContractState>;␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
foo: FooComponent::Storage,␊
}␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
FooEvent: FooComponent::Event,␊
}␊
#[constructor]␊
fn constructor(ref self: ContractState) {␊
self.foo.initializer();␊
}␊
}␊
`
Binary file modified packages/core/cairo/src/contract.test.ts.snap
Binary file not shown.
37 changes: 10 additions & 27 deletions packages/core/cairo/src/print.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,40 +67,23 @@ function getLinesFromUseClausesGroup(group: UseClause[], groupName: string): Lin
const lines = [];
if (groupName === STANDALONE_IMPORTS_GROUP) {
for (const useClause of group) {
const alias = useClause.alias ?? '';
if (alias.length > 0) {
lines.push(`use ${useClause.containerPath}::${useClause.name} as ${alias};`);
} else {
lines.push(`use ${useClause.containerPath}::${useClause.name};`);
}
lines.push(`use ${useClause.containerPath}::${nameWithAlias(useClause)};`);
}
} else {
if (group.length == 1) {
const alias = group[0]!.alias ?? '';
if (alias.length > 0) {
lines.push(`use ${groupName}::${group[0]!.name} as ${alias};`);
} else {
lines.push(`use ${groupName}::${group[0]!.name};`);
}

lines.push(`use ${groupName}::${nameWithAlias(group[0]!)};`);
} else if (group.length > 1) {
let clauses = group.reduce((clauses, useClause) => {
const alias = useClause.alias ?? '';
if (alias.length > 0) {
clauses += `${useClause.name} as ${useClause.alias}, `;
} else {
clauses += `${useClause.name}, `;
}
return clauses;
}, '');
clauses = clauses.slice(0, -2);

lines.push(`use ${groupName}::{${clauses}};`);
let names = group.map((useClause) => nameWithAlias(useClause)).join(', ');
lines.push(`use ${groupName}::{${names}};`);
}
}
return lines;
}

function nameWithAlias(useClause: UseClause): string {
return useClause.alias ? `${useClause.name} as ${useClause.alias}` : useClause.name;
}

// TODO: remove this when we can use a formatting js library
function splitLongUseClauseLine(line: string): Lines[] {
const lines = [];
Expand Down Expand Up @@ -136,8 +119,8 @@ function splitLongLineInner(line: string): Lines[] {

function sortUseClauses(contract: Contract): UseClause[] {
return contract.useClauses.sort((a, b) => {
const aFullPath = `${a.containerPath}::${a.name}`;
const bFullPath = `${b.containerPath}::${b.name}`;
const aFullPath = `${a.containerPath}::${nameWithAlias(a)}`;
const bFullPath = `${b.containerPath}::${nameWithAlias(b)}`;
return aFullPath.localeCompare(bFullPath);
});
}
Expand Down
42 changes: 27 additions & 15 deletions packages/ui/public/cairo.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>OpenZeppelin Contracts Wizard for Cairo</title>
<title>OpenZeppelin Contracts Wizard</title>

<!-- Twitter card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:creator" content="@OpenZeppelin">
<meta name="twitter:title" content="OpenZeppelin Contracts Wizard for Cairo">
<meta name="twitter:description" content="An interactive smart contract generator based on OpenZeppelin Contracts for Cairo.">
<meta name="twitter:title" content="OpenZeppelin Contracts Wizard">
<meta name="twitter:description" content="An interactive smart contract generator based on OpenZeppelin Contracts.">
<meta name="twitter:image" content="https://wizard.openzeppelin.com/tw-card.png">

<!-- Favicons -->
Expand All @@ -32,37 +32,49 @@
<meta name="theme-color" content="#ffffff">

<!-- Scripts and CSS -->
<link rel="preload" href="/fonts/silka-regular-webfont.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/fonts/silka-semibold-webfont.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/fonts/Inter-VariableFont_opsz,wght.ttf" as="font" type="font/woff2" crossorigin>
<link rel='stylesheet' href='/build/standalone.css'>
<script async src='/build/embed.js'></script>
</head>
<body>

<div class="header container flex flex-row justify-between overflow-auto">
<div class="flex flex-row">
<img src="/logo.svg" alt="OpenZeppelin" width="300px">
<a class="switch switch-solidity switch-off" href="/">Solidity Wizard</a>
<a class="switch switch-cairo" href="#">Cairo Wizard</a>
<div class="header container flex flex-row justify-between items-center overflow-auto">
<div class="flex flex-row items-center">
<a href="https://www.openzeppelin.com/" target="_blank" rel="noopener noreferrer"><img src="/logo.svg" alt="OpenZeppelin" class="logo" width="160"></a>
</div>
<div class="flex flex-row">
<div class="flex flex-row items-center">
<a class="link" href="https://forum.openzeppelin.com/" target="_blank" rel="noopener noreferrer">Forum</a>
<a class="link" href="https://docs.openzeppelin.com/" target="_blank" rel="noopener noreferrer">Docs</a>
<a class="link" href="https://github.com/OpenZeppelin/cairo-contracts" target="_blank" rel="noopener noreferrer">GitHub</a>
<a class="link" href="https://twitter.com/OpenZeppelin" target="_blank" rel="noopener noreferrer">Twitter</a>
<a class="link" href="https://github.com/OpenZeppelin/" target="_blank" rel="noopener noreferrer"><img src="/icons/github-mark.svg" width="20" alt="GitHub OpenZeppelin"></a>
<a class="link" href="https://x.com/OpenZeppelin" target="_blank" rel="noopener noreferrer"><img src="/icons/x-logo.svg" width="20" alt="Twitter/X"></a>
</div>
</div>

<div class="nav">
<a class="switch switch-solidity" href="/"><img src="/icons/solidity.svg" alt="solidity">Solidity</a>
<a class="switch switch-cairo active" href="#"><img src="/icons/cairo.svg" alt="cairo">Cairo</a>
</div>
<div class="wizard-container">

<oz-wizard class="wizard" data-sync-url="fragment" data-lang="cairo"></oz-wizard>
</div>

<footer>
<p>© <a href="https://openzeppelin.com" target="_blank" rel="noopener noreferrer">OpenZeppelin</a> 2022-2025 |&nbsp;<a href="https://openzeppelin.com/privacy" target="_blank" rel="noopener noreferrer">Privacy</a> |&nbsp;<a href="https://openzeppelin.com/tos" target="_blank" rel="noopener noreferrer">Terms of Service</a></p>
<p>© <a href="https://openzeppelin.com" target="_blank" rel="noopener noreferrer">OpenZeppelin</a> 2017-2025 |&nbsp;<a href="https://openzeppelin.com/privacy" target="_blank" rel="noopener noreferrer">Privacy</a> |&nbsp;<a href="https://openzeppelin.com/tos" target="_blank" rel="noopener noreferrer">Terms of Service</a></p>
</footer>

<!-- Start of HubSpot Embed Code -->
<script type="text/javascript" id="hs-script-loader" async defer src="//js.hs-scripts.com/7795250.js"></script>
<!-- End of HubSpot Embed Code -->
<!-- Hotjar Tracking Code for OpenZeppelinWizard -->
<script>
(function(h,o,t,j,a,r){
h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
h._hjSettings={hjid:5302135,hjsv:6};
a=o.getElementsByTagName('head')[0];
r=o.createElement('script');r.async=1;
r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
a.appendChild(r);
})(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');
</script>
</body>
</html>
Binary file not shown.
3 changes: 3 additions & 0 deletions packages/ui/public/icons/cairo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/ui/public/icons/github-mark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions packages/ui/public/icons/solidity.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions packages/ui/public/icons/stellar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions packages/ui/public/icons/stylus.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 09049ef

Please sign in to comment.