Skip to content

Commit

Permalink
feat: Pico v2 customized design system
Browse files Browse the repository at this point in the history
  • Loading branch information
lucaslarroche committed Jan 21, 2024
1 parent 1a50fa6 commit 845f87e
Show file tree
Hide file tree
Showing 20 changed files with 3,643 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ A pure HTML example, without dependencies.
- **[Class-less preview](https://codesandbox.io/s/github/picocss/examples/tree/master/v2-html-classless)**
A class-less example, without dependencies.

- **[Customized design system](https://codesandbox.io/s/github/picocss/examples/tree/master/v2-sass-customized-design-system)**
An example to customize Pico CSS with SASS.

- **[React Class-less login](https://codesandbox.io/s/github/picocss/examples/tree/master/v2-react-classless-login)**
A minimal, class-less login page in React, with a custom primary color.
</details>
Expand Down
12 changes: 12 additions & 0 deletions v2-sass-customized-design-system/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
node_modules/

# Build folder
/css/

# Logs
*.log

# System files
.DS_Store
Thumbs.db

12 changes: 12 additions & 0 deletions v2-sass-customized-design-system/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<a href="https://picocss.com/">
<img src="https://picocss.com/img/logo.svg" width="64" height="64">
</a>

# Customized design system
| Pico version | Tech stack |
| ----- | ----- |
| 2 | HTML, Sass |

An example to customize Pico CSS with SASS.

[![Open in CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/picocss/examples/tree/master/v2-sass-customized-design-system)
Binary file added v2-sass-customized-design-system/favicon.ico
Binary file not shown.
96 changes: 96 additions & 0 deletions v2-sass-customized-design-system/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="color-scheme" content="light dark" />
<title>Customized design system • Pico CSS</title>
<meta name="description" content="A pure HTML example, without dependencies." />
<link rel="stylesheet" href="css/main.css" />
</head>

<body>
<main>
<svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M63.04 39.741c-4.275 17.143-21.638 27.576-38.783 23.301C7.12 58.768-3.313 41.404.962 24.262 5.234 7.117 22.597-3.317 39.737.957c17.144 4.274 27.576 21.64 23.302 38.784Z"
fill="#F7931A"
/>
<path
d="M46.11 27.441c.636-4.258-2.606-6.547-7.039-8.074l1.438-5.768-3.51-.875-1.4 5.616c-.924-.23-1.872-.447-2.814-.662l1.41-5.653-3.509-.875-1.439 5.766c-.764-.174-1.514-.346-2.242-.527l.004-.018-4.842-1.209-.934 3.75s2.605.597 2.55.634c1.422.355 1.68 1.296 1.636 2.042l-1.638 6.571c.098.025.225.061.365.117l-.37-.092-2.297 9.205c-.174.432-.615 1.08-1.609.834.035.051-2.552-.637-2.552-.637l-1.743 4.019 4.57 1.139c.85.213 1.682.436 2.502.646l-1.453 5.834 3.507.875 1.44-5.772c.957.26 1.887.5 2.797.726l-1.434 5.745 3.511.875 1.453-5.823c5.987 1.133 10.49.676 12.384-4.739 1.527-4.36-.076-6.875-3.226-8.515 2.294-.529 4.022-2.038 4.483-5.155ZM38.086 38.69c-1.085 4.36-8.426 2.003-10.806 1.412l1.928-7.729c2.38.594 10.012 1.77 8.878 6.317Zm1.086-11.312c-.99 3.966-7.1 1.951-9.082 1.457l1.748-7.01c1.982.494 8.365 1.416 7.334 5.553Z"
fill="#fff"
/>
</svg>
<form>
<label for="amount">Amount to Send in Bitcoin</label>
<input
id="amount"
name="amount"
type="number"
min="0.001"
value="0.01"
step="0.001"
placeholder="0.01"
required
/>
<small data-type="amount"><span data-type="usd" id="amount-usd"></span></small>
<label for="address">Recipient's Bitcoin Address </label>
<input
id="address"
name="address"
type="text"
placeholder="Enter Bitcoin address"
autocomplete="off"
required
/>
<fieldset>
<label for="priority">Network Priority</label>
<input
id="priority"
name="priority"
list="priorities"
type="range"
min="1"
max="5"
step="1"
value="3"
list="priority"
/>
<datalist id="priorities">
<option value="1">Min</option>
<option value="2">Low</option>
<option value="3">Medium</option>
<option value="4">High</option>
<option value="5">Max</option>
</datalist>
</fieldset>
<table>
<tbody>
<tr>
<td>Transaction Fees</td>
<td>
<div data-type="amount">
<span id="transaction-fees-btc" data-type="btc"></span>
<span id="transaction-fees-usd" data-type="usd"></span>
</div>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Total Received</td>
<td>
<div data-type="amount">
<span id="total-received-btc" data-type="btc"></span>
<span id="total-received-usd" data-type="usd"></span>
</div>
</td>
</tr>
</tfoot>
</table>
<button type="submit">Send</button>
</form>
</main>
<script src="js/main.js"></script>
</body>
</html>
127 changes: 127 additions & 0 deletions v2-sass-customized-design-system/js/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Initialize
let bitcoinPrice = 0;
let recommendedFees = {
minimumFee: 20,
economyFee: 40,
hourFee: 60,
halfHourFee: 70,
fastestFee: 80,
};
const transactionSizeInBytes = 400;

// Form targets
const form = document.querySelector("form");
const addressInput = form.querySelector("#address");
const amountInput = form.querySelector("#amount");
const priorityInput = form.querySelector("#priority");
const priorityOptions= form.querySelectorAll("#priorities option");

// Amounts targets
const table = form.querySelector("table");
const amountUsd = form.querySelector("#amount-usd");
const transactionFeesBtc = table.querySelector("#transaction-fees-btc");
const transactionFeesUsd = table.querySelector("#transaction-fees-usd");
const totalReceivedBtc = table.querySelector("#total-received-btc");
const totalReceivedUsd = table.querySelector("#total-received-usd");

// Fetch Data
const fetchData = async (url) => {
const response = await fetch(url);
return await response.json();
};

// Calculate Transaction
const calculateTransaction = () => {
const amount = amountInput.value;
const priority = priorityInput.value;
const feesInSats = calculateFeesInSats(priority);
const feeInBtc = feesInSats / 100_000_000;
updateUI(amount, feeInBtc);
};

// Calculate Fees in Sats
const calculateFeesInSats = (priority) => {
const fees = ["minimumFee", "economyFee", "hourFee", "halfHourFee", "fastestFee"];
return transactionSizeInBytes * recommendedFees[fees[priority - 1]];
};

// Format Amount
const formatAmount = (num, maximumFractionDigits = 2) => {
const formatter = new Intl.NumberFormat("en-US", {
notation: "compact",
compactDisplay: "short",
maximumFractionDigits,
});
return formatter.format(num);
};

// Update UI
const updateUI = (amount, feeInBtc) => {
transactionFeesBtc.textContent = `-${formatAmount(feeInBtc, 8)} BTC`;
totalReceivedBtc.textContent = `${formatAmount(amount - feeInBtc, 8)} BTC`;
if (bitcoinPrice !== 0) {
const feeInUsd = feeInBtc * bitcoinPrice;
amountUsd.textContent = `${formatAmount(amount * bitcoinPrice)} USD`;
transactionFeesUsd.textContent = `-${formatAmount(feeInUsd)} USD`;
totalReceivedUsd.textContent = `${formatAmount(amount * bitcoinPrice - feeInUsd)} USD`;
}
};

// Set the priority style
const setPriorityStyle = () => {
const { value, min, max } = priorityInput;
const percent = ((value - min) / (max - min)) * 100;
priorityInput.style.setProperty("--pico-selected-ratio", `${percent}%`);
};

// Handle Priority
const handlePriority = () => {
setPriorityStyle();
calculateTransaction();
};

// Handle Amount
const handleAmount = () => {
calculateTransaction();
};

// Handle Priority Option
const handlePriorityOption = (event) => {
priorityInput.value = event.target.value;
setPriorityStyle();
calculateTransaction();
};

// Listens for input changes
amountInput.addEventListener("input", handleAmount);
priorityInput.addEventListener("input", handlePriority);

// Fetch data and calculate transaction on load
(async () => {
const prices = await fetchData("https://mempool.space/api/v1/prices");
bitcoinPrice = prices.USD;
recommendedFees = await fetchData("https://mempool.space/api/v1/fees/recommended");
calculateTransaction();
})();

// Listen clicks on priority options
priorityOptions.forEach((option) => {
console.log(option);
option.addEventListener("click", handlePriorityOption);
});

// Set the priority style on load
setPriorityStyle();

// Prevent form submission
form.addEventListener("submit", (event) => {
event.preventDefault();
});

// Focus and move cursor to the end of the input on load
(function focusAndMoveCursorToEnd(input) {
input.focus();
const value = input.value;
input.value = "";
input.value = value;
})(amountInput);
36 changes: 36 additions & 0 deletions v2-sass-customized-design-system/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "v2-sass-customized-design-system",
"version": "1.0.0",
"license": "MIT",
"private": true,
"main": "index.html",
"scripts": {
"build": "npm-run-all sort-scss css",
"sort-scss": "postcss --config scss ./scss/**/*.scss --replace",
"css": "npm-run-all css-compile css-prefix",
"css-compile": "sass --style compressed --source-map --embed-sources --no-error-css --load-path=node_modules/@picocss/pico/scss/ scss/:css/",
"css-prefix": "postcss --replace css/main.css --use autoprefixer --map",
"dev": "npm-run-all --parallel watch browser-sync",
"watch": "nodemon -e html,scss -x \"npm run build\"",
"browser-sync": "browser-sync --no-ui --no-notify start --server --files='*.html, css/*.css'",
"serve": "serve"
},
"devDependencies": {
"@picocss/pico": "2.0.0-rc2",
"autoprefixer": "^10.4.17",
"browser-sync": "^3.0.2",
"caniuse-lite": "1.0.30001579",
"css-declaration-sorter": "^7.1.1",
"nodemon": "^3.0.3",
"npm-run-all": "^4.1.5",
"postcss": "^8.4.33",
"postcss-cli": "^11.0.0",
"postcss-scss": "^4.0.9",
"prettier": "^3.2.4",
"sass": "^1.70.0",
"serve": "^14.2.1"
},
"browserslist": [
"defaults"
]
}
8 changes: 8 additions & 0 deletions v2-sass-customized-design-system/sandbox.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"hardReloadOnChange": true,
"template": "node",
"startScript": "serve",
"container": {
"node": "18"
}
}
53 changes: 53 additions & 0 deletions v2-sass-customized-design-system/scss/components/_amount.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
@use "sass:map";
@use "settings" as *;

[data-type="amount"] {
display: flex;
flex-direction: column;
align-items: flex-end;
font-variant-numeric: tabular-nums;

@media (min-width: map.get(map.get($breakpoints, "sm"), "breakpoint")) {
flex-direction: row-reverse;
align-items: center;

[data-type="usd"] {
margin-right: var(#{$css-var-prefix}spacing);
}
}

[data-type="usd"] {
color: var(#{$css-var-prefix}muted-color);
}

// Loading
[data-type="btc"],
[data-type="usd"] {
&:empty {
display: inline-block;
height: calc(1em * var(#{$css-var-prefix}line-height));
opacity: 0.25;

&:after {
display: inline-block;
width: 4rem;
height: 50%;
transform: translateY(50%);
border-radius: 0.25rem;
background-color: currentColor;
content: "\00a0 ";
animation-duration: 2s;
animation-iteration-count: infinite;
animation-fill-mode: both;
animation-name: opacity-pulse;
opacity: 1;
}
}

@keyframes opacity-pulse {
50% {
opacity: 0.5;
}
}
}
}
Loading

0 comments on commit 845f87e

Please sign in to comment.