mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2026-01-13 19:25:17 +00:00
Compare commits
94 Commits
go/feat/pa
...
tutorials-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4bafb3502a | ||
|
|
f9a9ae9ca8 | ||
|
|
b3b40a8eff | ||
|
|
00fb447a76 | ||
|
|
1e9e2ba43b | ||
|
|
2dde2a7f60 | ||
|
|
374e81ef60 | ||
|
|
d5e64a6100 | ||
|
|
d48698531c | ||
|
|
fd33614c97 | ||
|
|
6dce88c4f8 | ||
|
|
724c61c9e3 | ||
|
|
50f2f35b0b | ||
|
|
d4cfcee8ea | ||
|
|
e9709335a9 | ||
|
|
45f25acc3e | ||
|
|
61bc24b7dc | ||
|
|
7cf6dccdd2 | ||
|
|
f44370009c | ||
|
|
3a1bb9a70b | ||
|
|
78fc4f49e6 | ||
|
|
adb09928cc | ||
|
|
36cd69821b | ||
|
|
1e91335f83 | ||
|
|
1ff667bb21 | ||
|
|
d1969d3919 | ||
|
|
92230d702c | ||
|
|
30c6a42519 | ||
|
|
24a374e2bf | ||
|
|
cac56c37f6 | ||
|
|
bd06feb49c | ||
|
|
815df642e0 | ||
|
|
46ed7fc569 | ||
|
|
f99277b841 | ||
|
|
6c64a1e449 | ||
|
|
9e343558cc | ||
|
|
fb33561a98 | ||
|
|
567d980713 | ||
|
|
7f16532b07 | ||
|
|
62759ec261 | ||
|
|
003927517f | ||
|
|
9c8c231900 | ||
|
|
382a10bda9 | ||
|
|
d2cf306ec6 | ||
|
|
3e41224ef0 | ||
|
|
01ed3055ec | ||
|
|
eb174b8700 | ||
|
|
9e96d40799 | ||
|
|
d6b55ab177 | ||
|
|
d8b216bdd7 | ||
|
|
e3ee7bf32f | ||
|
|
1e095599fd | ||
|
|
d27888182c | ||
|
|
7dd37e6b19 | ||
|
|
3347fc965d | ||
|
|
30c8e22eeb | ||
|
|
8d2d3850ec | ||
|
|
c7961f692e | ||
|
|
dbcdb508aa | ||
|
|
982386d0f6 | ||
|
|
9dde1114ca | ||
|
|
4ee47a63dc | ||
|
|
41b07a458e | ||
|
|
e6765094a9 | ||
|
|
fdcbc6c747 | ||
|
|
5f3dc85e5b | ||
|
|
ea0c186fa0 | ||
|
|
31ff09c093 | ||
|
|
3fa6394b09 | ||
|
|
4319594cf1 | ||
|
|
7d9b9f7c17 | ||
|
|
483c7c55e2 | ||
|
|
0d73d6d851 | ||
|
|
408c0f27e8 | ||
|
|
e7cb03a88d | ||
|
|
18985ad7e5 | ||
|
|
09708e58de | ||
|
|
6e6247952f | ||
|
|
d7ca624269 | ||
|
|
d07d6dae6d | ||
|
|
bc0c698692 | ||
|
|
878f1ba77c | ||
|
|
a2e5c3a613 | ||
|
|
bc5e48a0ba | ||
|
|
588da44a2e | ||
|
|
26fb8775a0 | ||
|
|
10c974249f | ||
|
|
5d45562fc6 | ||
|
|
904761dc51 | ||
|
|
b2f345edd5 | ||
|
|
b1c8a33de9 | ||
|
|
755b15383b | ||
|
|
9e40756dd1 | ||
|
|
b2aa96e283 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -8,8 +8,6 @@ yarn-error.log
|
||||
*.iml
|
||||
.venv/
|
||||
_code-samples/*/js/package-lock.json
|
||||
*.css.map
|
||||
|
||||
# PHP
|
||||
composer.lock
|
||||
.cursor/
|
||||
@@ -74,8 +74,8 @@ Si una dirección de reserva se ve comprometida, las consecuencias son similares
|
||||
- [Cuentas](index.md)
|
||||
- [Claves criptográficas](cryptographic-keys.md)
|
||||
- **Tutoriales:**
|
||||
- [Asignar par de claves regulares](../../tutorials/how-tos/manage-account-settings/assign-a-regular-key-pair.md)
|
||||
- [Cambiar o eliminar par de claves regulares](../../tutorials/how-tos/manage-account-settings/change-or-remove-a-regular-key-pair.md)
|
||||
- [Asignar par de claves regulares](/docs/tutorials/best-practices/key-management/assign-a-regular-key-pair.md)
|
||||
- [Cambiar o eliminar par de claves regulares](/docs/tutorials/best-practices/key-management/change-or-remove-a-regular-key-pair.md)
|
||||
- **Referencias:**
|
||||
- [metodo account_info][]
|
||||
- [Transacción SetRegularKey][]
|
||||
|
||||
@@ -88,7 +88,7 @@ El [metodo wallet_propose][] es una forma de generar el par de claves maestras.
|
||||
|
||||
**Atención:** Si un actor malicioso conoce tu clave privada maestra (o semilla), tendrá control completo sobre tu cuenta, a no ser que tu par de claves maestras se inhabilite. Puedes tomar todo tu dinero de la cuenta posee y causar un daño irreparable. ¡Trata tus valores secretos con cuidado!
|
||||
|
||||
Dado que cambiar el par de claves maestras es imposible, debes cuidarlo en proporción al valor de lo que posea. Una buena práctica es [guardar tu par de claves maestras offline](../../tutorials/how-tos/manage-account-settings/offline-account-setup.md) y configurar un par de claves normales para firmar transacciones en tu cuenta. Al mantener el par de claves maestras activadas pero offline, puedes estar razonablemente seguro de que nadie puede acceder a él a través de Internet, pero aun así deberías encontrarlo en caso de una emergencia.
|
||||
Dado que cambiar el par de claves maestras es imposible, debes cuidarlo en proporción al valor de lo que posea. Una buena práctica es [guardar tu par de claves maestras offline](/docs/tutorials/best-practices/key-management/offline-account-setup.md) y configurar un par de claves normales para firmar transacciones en tu cuenta. Al mantener el par de claves maestras activadas pero offline, puedes estar razonablemente seguro de que nadie puede acceder a él a través de Internet, pero aun así deberías encontrarlo en caso de una emergencia.
|
||||
|
||||
Mantener tu par de claves maestras offline significa no colocar tu información secreta (passphrase, semilla, or clave privada) en cualquier sitio en que los actores maliciosos puedan tener acceso a él. En general, esto quiere decir que no está al alcance de un programa inofrmático que interactúe con Internet. Por ejemplo, puedes guardarlo en un equipo que no se conecta nunca a Internet, en un trozo de papel guardado en una caja fuerte, o tenerla completamente memorizada. (Memorizarla tiene algunos puntos inconvenientes, incluido ser imposible pasar la clave una vez muerto.)
|
||||
|
||||
@@ -119,7 +119,7 @@ Una buena práctica de seguridad es guardar tu clave privada maestra en algun si
|
||||
|
||||
El par de claves normales tiene el mismo formato que el par de claves maestras. Las generas de la misma forma (por ejemplo, usando el [método wallet_propose][]). La única diferencia es que el par de claves normales es que el par no está intrínsicamente vinculado a la cuenta para la que firma transacciones. Es posible (pero no es buena idea) utilizar el par de claves maestras de una cuenta como lel par de claves normales para otra cuenta.
|
||||
|
||||
La [transacción SetRegularKey][] asigna o cambia el par de claves normales de una cuenta. Para un tutorial de asignación o cambio de un par de claves normales, ver [Asignar par de claves normales](../../tutorials/how-tos/manage-account-settings/assign-a-regular-key-pair.md).
|
||||
La [transacción SetRegularKey][] asigna o cambia el par de claves normales de una cuenta. Para un tutorial de asignación o cambio de un par de claves normales, ver [Asignar par de claves normales](/docs/tutorials/best-practices/key-management/assign-a-regular-key-pair.md).
|
||||
|
||||
|
||||
## Algorítmos de firma
|
||||
@@ -248,8 +248,8 @@ Los pasos para derivar par de claves de cuenta XRP Ledger secp256k1 desde un val
|
||||
- **Conceptos:**
|
||||
- [Direcciones de emisión y operacionales](account-types.md)
|
||||
- **Tutoriales:**
|
||||
- [Asignación de par de claves normales](../../tutorials/how-tos/manage-account-settings/assign-a-regular-key-pair.md)
|
||||
- [Cambiar o eliminar par de claves normales](../../tutorials/how-tos/manage-account-settings/change-or-remove-a-regular-key-pair.md)
|
||||
- [Asignación de par de claves normales](/docs/tutorials/best-practices/key-management/assign-a-regular-key-pair.md)
|
||||
- [Cambiar o eliminar par de claves normales](/docs/tutorials/best-practices/key-management/change-or-remove-a-regular-key-pair.md)
|
||||
- **Referencias:**
|
||||
- [Transacción SetRegularKey][]
|
||||
- [Objeto de ledger AccountRoot](../../references/protocol/ledger-data/ledger-entry-types/accountroot.md)
|
||||
|
||||
@@ -63,7 +63,7 @@ La forma típica de obtener una cuenta en el XRP Ledger es la siguiente:
|
||||
- [Transacción Payment][]
|
||||
- [Objeto AccountRoot](../../references/protocol/ledger-data/ledger-entry-types/accountroot.md)
|
||||
- **Tutoriales:**
|
||||
- [Administrar configuración de la cuenta (Categoría)](../../tutorials/how-tos/manage-account-settings/index.md)
|
||||
- [Monitorizar pagos entrantes con WebSocket](../../tutorials/http-websocket-apis/build-apps/monitor-incoming-payments-with-websocket.md)
|
||||
- [Administrar configuración de la cuenta (Categoría)](/docs/tutorials/best-practices/key-management/assign-a-regular-key-pair.md)
|
||||
- [Monitorizar pagos entrantes con WebSocket](/docs/tutorials/advanced-developer-topics/client-library-development/monitor-incoming-payments-with-websocket.md)
|
||||
|
||||
{% raw-partial file="/docs/_snippets/common-links.md" /%}
|
||||
|
||||
@@ -60,7 +60,7 @@ Podría darse el caso donde crees una lista de multi firma como "plan de respald
|
||||
|
||||
Para enviar transacciones multi-signed de forma satisfactoria, debes de hacer todo lo siguiente:
|
||||
|
||||
* La dirección que envía la transacción (especificada en el campo `Account`) debe tener un [objeto `SignerList` en el ledger ](../../references/protocol/ledger-data/ledger-entry-types/signerlist.md). Para instrucciones de cómo hacer esto, ver [Set Up Multi-Signing](../../tutorials/how-tos/manage-account-settings/set-up-multi-signing.md).
|
||||
* La dirección que envía la transacción (especificada en el campo `Account`) debe tener un [objeto `SignerList` en el ledger ](../../references/protocol/ledger-data/ledger-entry-types/signerlist.md). Para instrucciones de cómo hacer esto, ver [Set Up Multi-Signing](/docs/tutorials/best-practices/key-management/set-up-multi-signing.md).
|
||||
* La transacción debe incluir el campo `SigningPubKey` como un valor vacío.
|
||||
* La transacción debe incluir el [campo `Signers`](../../references/protocol/transactions/common-fields.md#signers-field) conteniendo un array de firmas.
|
||||
* Las firmas presentadas en el array `Signers` debe coincidir con los firmantes definidos en la `SignerList`.
|
||||
@@ -72,8 +72,8 @@ Para enviar transacciones multi-signed de forma satisfactoria, debes de hacer to
|
||||
## Ver también
|
||||
|
||||
- **Tutoriales:**
|
||||
- [Configurar Multi-Signing](../../tutorials/how-tos/manage-account-settings/set-up-multi-signing.md)
|
||||
- [Envíar una transacción Multi-Signed](../../tutorials/how-tos/manage-account-settings/send-a-multi-signed-transaction.md)
|
||||
- [Configurar Multi-Signing](/docs/tutorials/best-practices/key-management/set-up-multi-signing.md)
|
||||
- [Envíar una transacción Multi-Signed](/docs/tutorials/best-practices/key-management/send-a-multi-signed-transaction.md)
|
||||
- **Conceptos:**
|
||||
- [Claves criptográficas](cryptographic-keys.md)
|
||||
- [Coste de transacción especial para transacciones Multi-signed](../transactions/transaction-cost.md#special-transaction-costs)
|
||||
|
||||
@@ -54,7 +54,7 @@ Las aplicaciones pueden buscar los valores de las reservas base e incremental ac
|
||||
|
||||
Para determinar las reservas de propietario de una cuenta, hay que multiplicar la reserva incremental por el número de objetos que la cuenta posee. Para mirar el número de objetos que una cuenta posee, llama al [método account_info][] y toma `account_data.OwnerCount`.
|
||||
|
||||
Para calcular el requisito total de direcciones, multiplica `OwnerCount` por `reserve_inc_xrp`, y luego suma `reserve_base_xrp`. [Aquí tienes una demostración](../../tutorials/python/build-apps/build-a-desktop-wallet-in-python.md#codeblock-17) del cálculo en Python.
|
||||
Para calcular el requisito total de direcciones, multiplica `OwnerCount` por `reserve_inc_xrp`, y luego suma `reserve_base_xrp`. [Aquí tienes una demostración](/docs/tutorials/sample-apps/build-a-desktop-wallet-in-python.md#codeblock-17) del cálculo en Python.
|
||||
|
||||
|
||||
## Quedarse por debajo del requisito de reserva
|
||||
@@ -76,6 +76,6 @@ El XRP Ledger tiene un mecanismo para ajustar los requisitos de reserva. Estos a
|
||||
- [Objeto AccountRoot][]
|
||||
- [Votación de Fee](../consensus-protocol/fee-voting.md)
|
||||
- [Pseudo-transacción SetFee][]
|
||||
- [Tutorial: Calcular y mostrar los requisitos de reserva (Python)](../../tutorials/python/build-apps/build-a-desktop-wallet-in-python.md#3-display-an-account)
|
||||
- [Tutorial: Calcular y mostrar los requisitos de reserva (Python)](/docs/tutorials/sample-apps/build-a-desktop-wallet-in-python.md#3-display-an-account)
|
||||
|
||||
{% raw-partial file="/docs/_snippets/common-links.md" /%}
|
||||
|
||||
@@ -63,7 +63,7 @@ Cualquier cuenta puede crear y utilizar Tickets en cualquier tipo de transaccion
|
||||
- **Conceptos:**
|
||||
- [Multi-Signing](multi-signing.md)
|
||||
- **Tutoriales:**
|
||||
- [Usar Tickets](../../tutorials/how-tos/manage-account-settings/use-tickets.md)
|
||||
- [Usar Tickets](/docs/tutorials/best-practices/transaction-sending/use-tickets.md)
|
||||
- **Referencias:**
|
||||
- [Transacción TicketCreate][]
|
||||
- [Campos comunes de una transacción](../../references/protocol/transactions/common-fields.md)
|
||||
|
||||
@@ -27,7 +27,7 @@ Necesitas confiar en el servidor que utilizas. Si te conectas a un servidor mali
|
||||
* Podría selectivamente mostrar u ocultar los caminos (o paths) de pago y las foertas de intercambio de divisas para garantizar su propio beneficio mientras no te ofrece la mejor oferta.
|
||||
* Si le enviaste la clave secreta de tu dirección, esto podría generar transacciones arbitrarias en tu nombre e incluso transferir o destruir todo el dinero que la dirección posee.
|
||||
|
||||
Adicionalmente, ejecutar tu propio servidor te da [acceso de administrador](../../tutorials/http-websocket-apis/build-apps/get-started.md#admin-access), lo que te permite ejecutar comandos exclusivos de administrador y de carga intensa. Si utilizas un servidor compartido, debes preocuparte por los otros usuarios del mismo servidor compitiendo contra ti por el poder de computación del servidor. Muchos de los comandos en el API WebSocket puede poner mucha presión sobre el servidor, por lo que el servidor tiene la opción de reducir sus respuestas cuando lo necesite. Si compartes un servidor con otros, puede que no siempre consigas los mejores resultados posibles.
|
||||
Adicionalmente, ejecutar tu propio servidor te da [acceso de administrador](/docs/tutorials/get-started/get-started-http-websocket-apis.md#admin-access), lo que te permite ejecutar comandos exclusivos de administrador y de carga intensa. Si utilizas un servidor compartido, debes preocuparte por los otros usuarios del mismo servidor compitiendo contra ti por el poder de computación del servidor. Muchos de los comandos en el API WebSocket puede poner mucha presión sobre el servidor, por lo que el servidor tiene la opción de reducir sus respuestas cuando lo necesite. Si compartes un servidor con otros, puede que no siempre consigas los mejores resultados posibles.
|
||||
|
||||
Finalmente, si ejecutas un servidor de validación, puedes utilizar un servidor común como proxy a la red pública mientras mantienes tu servidor de vaalidación en una red privada la cual es solo accesible desde el mundo exterior desde tu servidor común. Esto hace más difícil comprometer la integridad de tu servidor de validación.
|
||||
|
||||
|
||||
@@ -17,8 +17,6 @@ Para ayudar a miembros de la comunidad del XRP Ledger a interactuar con la tecno
|
||||
| Mainnet | Lanzamientos estables | _El_ [XRP Ledger](/about/), un libro contable criptográfico descentralizado impulsado por una red de servidores peer-to-peer y el hogar de [XRP](../../introduction/what-is-xrp.md). |
|
||||
| Testnet | Lanzamientos estables | Una red de "universo alternativo" que actua como un campo de pruebas para el software construido en el XRP Ledger, sin impactar a los usuarios del XRP Ledger de producción y sin arriesgar dinero real. El [estado de enmienda](/resources/known-amendments.md) de Testnet está destinado a reflejar de cerca el de la Mainnet, aunque pueden ocurrir ligeras variaciones en el tiempo debido a la naturaleza impredecible de los sistemas descentralizados. |
|
||||
| Devnet | Lanzamientos Beta | Una vista previa de las próximas atracciones, donde cambios inestables en el software principal de XRP Ledger se pueden probar. Los desarrolladores pueden utilizar esta altnet para interactuar y aprender sobre funcionalidades nuevas planficiadas para el XRP Ledger y enmiendas que no están habilitadas en la Mainnet. |
|
||||
| [Hooks V3 Testnet](https://hooks-testnet-v3.xrpl-labs.com/) | [Servidor Hooks](https://github.com/XRPL-Labs/xrpld-hooks) | Una vista previa de la funcionalidad de smart contract en la cadena utilizando [hooks](https://xrpl-hooks.readme.io/). |
|
||||
| Sidechain-Devnet | Lanzamientos Beta | Una sidechain para probar funcionalidades en puentes cross-chain. Devnet se trata como la cadena de bloqueo y esta sidechain es la cadena de emisión.<br>Soporte a la librería:<br>- [xrpl.js 2.12.0](https://www.npmjs.com/package/xrpl/v/2.12.0)<br>- [xrpl-py 2.4.0](https://pypi.org/project/xrpl-py/2.4.0/)<br>**Nota**: También puedes usar la herramienta de línea de comandos [`xbridge-cli`](https://github.com/XRPLF/xbridge-cli) para configurar un puente entre cadenas en tu máquina local. |
|
||||
|
||||
Cada altnet tiene su propia distribución separada de XRP de prueba, que se [regala gratis](/resources/dev-tools/xrp-faucets) a partes interesadas en experimentar con el XRP Ledger y desarrollar aplicaciones e integraciones. El XRP test no tiene valor en el mundo real y se pierde cuando la red se reinicia.
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ El software del servidor `rippled` puede ejecutarse en varios modos dependiendo
|
||||
|
||||
- [**Modo P2P**](#modo-p2p) - Este es el modo principal del servidor: sigue la red peer-to-peer, procesa transacciones, y mantiene cierta cantidad de [histórico del ledger](ledger-history.md). Este modo se puede configurar para alguno o todos los siguientes roles:
|
||||
- [**Validador**](#validadores) - Ayuda a asegurar la red participando en el consenso.
|
||||
- [**Servidor API**](#servidores-api) - Proporciona [acceso API](../../tutorials/http-websocket-apis/build-apps/get-started.md) para leer datos del ledger compartido, enviar transacciones, y mirar la actividad en el ledger. Opcionalmente, puede ser un [**servidor full history**](#servidores-full-history), el cual guarda un registro completo de transacciones y el histórico del ledger.
|
||||
- [**Servidor API**](#servidores-api) - Proporciona [acceso API](/docs/tutorials/get-started/get-started-http-websocket-apis.md) para leer datos del ledger compartido, enviar transacciones, y mirar la actividad en el ledger. Opcionalmente, puede ser un [**servidor full history**](#servidores-full-history), el cual guarda un registro completo de transacciones y el histórico del ledger.
|
||||
- [**Servidor hub**](#hubs-públicos) - Transmite mensajes entre muchos otros miembros de la red peer-to-peer.
|
||||
- [**Modo solitario**](#modo-solitario) - Un modo offline para pruebas. No se conecta a la red peer-to-peer ni usa consenso.
|
||||
|
||||
|
||||
@@ -50,11 +50,11 @@ Para más información sobre Cheques en el XRP Ledger, ver:
|
||||
- [CheckCash][]
|
||||
- [CheckCancel][]
|
||||
- [Tutoriales de cheques](../../tutorials/how-tos/use-specialized-payment-types/use-checks/index.md)
|
||||
- [Enviar un cheque](../../tutorials/how-tos/use-specialized-payment-types/use-checks/send-a-check.md)
|
||||
- [Buscar cheques](../../tutorials/how-tos/use-specialized-payment-types/use-checks/look-up-checks.md)
|
||||
- [Canjear un cheque por la cantidad exacta](../../tutorials/how-tos/use-specialized-payment-types/use-checks/cash-a-check-for-an-exact-amount.md)
|
||||
- [Canjear un cheque por una cantidad flexible](../../tutorials/how-tos/use-specialized-payment-types/use-checks/cash-a-check-for-a-flexible-amount.md)
|
||||
- [Cancelar un cheque](../../tutorials/how-tos/use-specialized-payment-types/use-checks/cancel-a-check.md)
|
||||
- [Enviar un cheque](/docs/tutorials/payments/send-a-check.md)
|
||||
- [Buscar cheques](/docs/tutorials/ /how-tos/use-specialized-payment-types/use-checks/look-up-checks.md)
|
||||
- [Canjear un cheque por la cantidad exacta](/docs/tutorials/payments/cash-a-check-for-an-exact-amount.md)
|
||||
- [Canjear un cheque por una cantidad flexible](/docs/tutorials/payments/cash-a-check-for-a-flexible-amount.md)
|
||||
- [Cancelar un cheque](/docs/tutorials/payments/cancel-a-check.md)
|
||||
- [Enmienda Cheques][]
|
||||
|
||||
Para más información sobre funciones relacionadas, ver:
|
||||
|
||||
@@ -39,8 +39,8 @@ La base de cualquier sistema financiero es la transferencia de valor. El método
|
||||
## Ver también
|
||||
|
||||
- **Tutoriales:**
|
||||
- [Enviar XRP (Tutorial interactivo)](../../tutorials/how-tos/send-xrp.md)
|
||||
- [Monitorizar pagos entrantes con WebSocket](../../tutorials/http-websocket-apis/build-apps/monitor-incoming-payments-with-websocket.md)
|
||||
- [Enviar XRP (Tutorial interactivo)](/docs/tutorials/payments/send-xrp.md)
|
||||
- [Monitorizar pagos entrantes con WebSocket](/docs/tutorials/advanced-developer-topics/client-library-development/monitor-incoming-payments-with-websocket.md)
|
||||
- **Referencias:**
|
||||
- [Transacción Payment][]
|
||||
- [Resultados de Transaction](../../references/protocol/transactions/transaction-results/index.md)
|
||||
|
||||
@@ -128,7 +128,7 @@ Utilizar [el campo `delivered_amount`](#the-delivered_amount-field) al procesar
|
||||
- [Transacciones](../transactions/index.md)
|
||||
- **Tutoriales:**
|
||||
- [Buscar resultados de transacciones](../transactions/finality-of-results/look-up-transaction-results.md)
|
||||
- [Monitorear pagos recibidos con WebSocket](../../tutorials/http-websocket-apis/build-apps/monitor-incoming-payments-with-websocket.md)
|
||||
- [Monitorear pagos recibidos con WebSocket](/docs/tutorials/advanced-developer-topics/client-library-development/monitor-incoming-payments-with-websocket.md)
|
||||
- [Usar tipos de pagos especializados](../../tutorials/how-tos/use-specialized-payment-types/index.md)
|
||||
- [Listar XRP en un Exchange](../../use-cases/defi/list-xrp-as-an-exchange.md)
|
||||
- **Referencias:**
|
||||
|
||||
@@ -6,4 +6,4 @@ Checkを換金するための前提条件は、正確な金額を換金する場
|
||||
- 発行済み通貨用のCheckの場合は、ご自身(受取人)にイシュアーに対するトラストラインがある必要があります。このトラストライン上のご自身の限度額は、受け取る金額を追加するための残高より十分高くなければなりません。
|
||||
- トラストラインと限度額について詳しくは、[トークン](../concepts/tokens/index.md)および[トラストラインと発行](../concepts/tokens/fungible-tokens/index.md)をご覧ください。
|
||||
- [トランザクションに安全に署名できる手段](../concepts/transactions/secure-signing.md)。
|
||||
- XRP Ledgerに接続できる[クライアントライブラリ](../references/client-libraries.md)か、それとも[HTTPライブラリ、WebSocketライブラリなど](../tutorials/http-websocket-apis/build-apps/get-started.md)。
|
||||
- XRP Ledgerに接続できる[クライアントライブラリ](../references/client-libraries.md)か、それとも[HTTPライブラリ、WebSocketライブラリなど](../tutorials/http-websocket-apis/get-started.md)。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
`rippled`ログメッセージの詳細は、[ログメッセージについて](../infrastructure/troubleshooting/understanding-log-messages.md)をご覧ください。
|
||||
|
||||
`rippled`が残りのネットワークと同期されたら、ストック`rippled`サーバが完全に機能するようになります。このサーバを、ローカル署名やXRP LedgerへのAPIアクセスに使用できます。`rippled`サーバがネットワークと同期されているかどうかを判別するには、[`rippled`サーバの状況](../references/http-websocket-apis/api-conventions/rippled-server-states.md)を使用します。[`rippled`のコマンドラインインターフェイス](../tutorials/http-websocket-apis/build-apps/get-started.md#コマンドライン)を使用すれば、これを迅速にテストできます。
|
||||
`rippled`が残りのネットワークと同期されたら、ストック`rippled`サーバが完全に機能するようになります。このサーバを、ローカル署名やXRP LedgerへのAPIアクセスに使用できます。`rippled`サーバがネットワークと同期されているかどうかを判別するには、[`rippled`サーバの状況](../references/http-websocket-apis/api-conventions/rippled-server-states.md)を使用します。[`rippled`のコマンドラインインターフェイス](../tutorials/http-websocket-apis/get-started.md#コマンドライン)を使用すれば、これを迅速にテストできます。
|
||||
|
||||
```sh
|
||||
rippled server_info
|
||||
|
||||
@@ -54,7 +54,7 @@ XRP Ledgerでは、スパムや悪意のある使用によって、共有グロ
|
||||
|
||||
アカウントの所有者準備金を決定するには、増分準備金にアカウントが所有するオブジェクトの数を掛けます。アカウントが所有しているオブジェクトの数を調べるには、[account_infoメソッド][]を呼び出し、`account_data.OwnerCount`を取得します。
|
||||
|
||||
アドレスの必要となる合計準備金を計算するには、`OwnerCount`に`reserve_inc_xrp`を掛け、次に`reserve_base_xrp`を加えます。[この計算をPythonで行うデモ](../../tutorials/python/build-apps/build-a-desktop-wallet-in-python.md#codeblock-17)があります。
|
||||
アドレスの必要となる合計準備金を計算するには、`OwnerCount`に`reserve_inc_xrp`を掛け、次に`reserve_base_xrp`を加えます。[この計算をPythonで行うデモ](/docs/tutorials/sample-apps/build-a-desktop-wallet-in-python.md#codeblock-17)があります。
|
||||
|
||||
|
||||
## 必要準備金を下回る
|
||||
@@ -76,6 +76,6 @@ XRP Ledgerには、準備金要件を調整する仕組みがあります。こ
|
||||
- [AccountRootオブジェクト][]
|
||||
- [手数料の投票](../consensus-protocol/fee-voting.md)
|
||||
- [SetFee疑似トランザクション][]疑似トランザクション
|
||||
- [チュートリアル: 必要準備金の計算と表示(Python)](../../tutorials/python/build-apps/build-a-desktop-wallet-in-python.md#3-display-an-account)
|
||||
- [チュートリアル: 必要準備金の計算と表示(Python)](/docs/tutorials/sample-apps/build-a-desktop-wallet-in-python.md#3-display-an-account)
|
||||
|
||||
{% raw-partial file="/@l10n/ja/docs/_snippets/common-links.md" /%}
|
||||
|
||||
@@ -27,7 +27,7 @@ XRP Ledgerを動かすサーバソフトウェアは、主に2種類あります
|
||||
* 選択的に支払いパスや通貨交換のオファーを表示または非表示にすることができ、最良の取引を提供せず、彼ら自身の利益を確保する可能性があります。
|
||||
* もし、アドレスの秘密鍵を送信してしまった場合、サーバの管理者はあなたに代わって任意のトランザクションを実行し、アドレスが保有するすべての資金を転送または破棄する可能性があります。
|
||||
|
||||
さらに、独自のサーバを運営することで、[管理者アクセス権限](../../tutorials/http-websocket-apis/build-apps/get-started.md#管理者アクセス権限)が与えられ、重要な管理者専用コマンドや負荷の高いコマンドを実行することができます。共有サーバを使用する場合、同じサーバの他のユーザとサーバの計算能力を共有することを考慮しなければいけません。WebSocket APIのコマンドの多くはサーバに大きな負担をかけるので、サーバには必要なときにレスポンスを縮小するオプションがあります。サーバを他人と共有する場合、常に最良の結果を得られるとは限りません。
|
||||
さらに、独自のサーバを運営することで、[管理者アクセス権限](/docs/tutorials/get-started/get-started-http-websocket-apis.md#管理者アクセス権限)が与えられ、重要な管理者専用コマンドや負荷の高いコマンドを実行することができます。共有サーバを使用する場合、同じサーバの他のユーザとサーバの計算能力を共有することを考慮しなければいけません。WebSocket APIのコマンドの多くはサーバに大きな負担をかけるので、サーバには必要なときにレスポンスを縮小するオプションがあります。サーバを他人と共有する場合、常に最良の結果を得られるとは限りません。
|
||||
|
||||
最後に、バリデーションサーバを運用する場合、パブリックネットワークへのプロキシとしてストックサーバを使用し、バリデーションサーバをプライベートネットワークに置いて、ストックサーバを通してのみ外部にアクセスできるようにすることができます。これにより、バリデーションサーバに侵入することがより困難になります。
|
||||
|
||||
|
||||
@@ -17,8 +17,6 @@ XRP Ledgerコミュニティのメンバーが、メインネットに影響を
|
||||
| Mainnet | 安定版リリース | ピアツーピアサーバのネットワーク機能を備えた分散型の暗号台帳であり、[XRP](../../introduction/what-is-xrp.md)の土台となる[XRP Ledger](/about/)です。 |
|
||||
| Testnet | 安定版リリース | XRP Ledger上に構築したソフトウェアのテスト環境として動作する「代替環境」のネットワークです。本番環境のXRP Ledgerユーザに影響を及ぼすことも、本物の通貨をリスクにさらすこともありません。Testnetの[Amendmentのステータス](/resources/known-amendments.md)は、Mainnetを厳密に反映するようになっていますが、分散型システムが持つ予測不可能な性質により、タイミングにわずかな違いが生じることがあります。 |
|
||||
| Devnet | ベータ版リリース | 次期リリースのプレビューネットワークです。XRP Ledgerのコアソフトウェアへの不安定な変更がテストされます。このAltNetを使用すると、開発者はまだMainnetで有効になっていないXRPLの計画段階の新機能やAmendmentを操作したり学習したりすることができます。 |
|
||||
| [Hooks V3 Testnet](https://hooks-testnet-v3.xrpl-labs.com/) | [Hooksサーバ](https://github.com/XRPL-Labs/xrpld-hooks) | [Hooks](https://xrpl-hooks.readme.io/)を使用したオンチェーン・スマートコントラクト機能のプレビューネットワークです。 |
|
||||
| Sidechain-Devnet | ベータ版リリース | クロスチェーンブリッジ機能をテストするためのサイドチェーンです。<br>ライブラリのサポート:<br>- [xrpl.js 2.12.0](https://www.npmjs.com/package/xrpl/v/2.12.0)<br>- [xrpl-py 2.4.0](https://pypi.org/project/xrpl-py/2.4.0/)<br>**注記**: また、[`xbridge-cli`](https://github.com/XRPLF/xbridge-cli)コマンドラインツールを使用して、ローカルマシンにクロスチェーンブリッジをセットアップすることもできます。 |
|
||||
|
||||
テスト用XRPは、XRP Ledgerの実験やアプリケーションの開発、統合に興味のある人々に[無償で提供](/resources/dev-tools/xrp-faucets)されています。テスト用のXRPは実際には価値を持たず、ネットワークがリセットされると失われます。
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ labels:
|
||||
|
||||
- [**P2Pモード**](#p2pモード) - ピアツーピアネットワークをフォローし、トランザクションを処理し、ある程度の[レジャー履歴](ledger-history.md)を維持します。このモードは、以下の役割のいずれか、またはすべてを行うように設定することができます。
|
||||
- [**バリデータ**](#バリデータ) - コンセンサスに参加することで、ネットワークの安全確保に貢献します。
|
||||
- [**APIサーバ**](#apiサーバ) - 共有レジャーからデータを読み込んだり、トランザクションを送信したり、レジャーのアクティビティを監視するための[APIアクセス](../../tutorials/http-websocket-apis/build-apps/get-started.md)を提供します。オプションとして、トランザクションやレジャーの履歴を完全に記録する [**全履歴サーバ**](#全履歴サーバ) とすることができます。
|
||||
- [**APIサーバ**](#apiサーバ) - 共有レジャーからデータを読み込んだり、トランザクションを送信したり、レジャーのアクティビティを監視するための[APIアクセス](/docs/tutorials/get-started/get-started-http-websocket-apis.md)を提供します。オプションとして、トランザクションやレジャーの履歴を完全に記録する [**全履歴サーバ**](#全履歴サーバ) とすることができます。
|
||||
- [**ハブサーバ**](#公開ハブ) - ピアツーピアネットワークの他の多くのメンバー間のメッセージを中継します。
|
||||
- [**レポートモード**](#レポートモード) - リレーショナルデータベースからのAPIリクエストに対応するための専用モードです。ピアツーピアネットワークには参加しないため、P2Pモードサーバを実行し、信頼できるgRPC接続を使用してレポートモードサーバに接続する必要があります。 {% badge href="https://github.com/XRPLF/rippled/releases/tag/1.7.0" %}新規: rippled 1.7.0{% /badge %}
|
||||
- [**スタンドアロンモード**](#スタンドアロンモード) - テスト用のオフラインモードです。ピアツーピアネットワークに接続せず、コンセンサスも使用しません。
|
||||
|
||||
@@ -97,12 +97,12 @@ XRP LedgerのChecksの詳細は、以下をご覧ください。
|
||||
- [CheckCreate][]
|
||||
- [CheckCash][]
|
||||
- [CheckCancel][]
|
||||
- [Checksのチュートリアル](../../tutorials/how-tos/use-specialized-payment-types/use-checks/index.md)
|
||||
- [Checkの送信](../../tutorials/how-tos/use-specialized-payment-types/use-checks/send-a-check.md)
|
||||
- [Checksの検索](../../tutorials/how-tos/use-specialized-payment-types/use-checks/look-up-checks.md)
|
||||
- [Checkの指定された金額での換金](../../tutorials/how-tos/use-specialized-payment-types/use-checks/cash-a-check-for-an-exact-amount.md)
|
||||
- [Checkの変動金額での換金](../../tutorials/how-tos/use-specialized-payment-types/use-checks/cash-a-check-for-a-flexible-amount.md)
|
||||
- [Checkの取消し](../../tutorials/how-tos/use-specialized-payment-types/use-checks/cancel-a-check.md)
|
||||
- Checksのチュートリアル
|
||||
- [Checkの送信](/docs/tutorials/payments/send-a-check.md)
|
||||
- [Checksの検索](/docs/tutorials/payments/look-up-checks.md)
|
||||
- [Checkの指定された金額での換金](/docs/tutorials/payments/cash-a-check-for-an-exact-amount.md)
|
||||
- [Checkの変動金額での換金](/docs/tutorials/payments/cash-a-check-for-a-flexible-amount.md)
|
||||
- [Checkの取消し](/docs/tutorials/payments/cancel-a-check.md)
|
||||
- [Checks Amendment][]
|
||||
|
||||
関連機能の詳細については、以下をご覧ください。
|
||||
|
||||
@@ -207,7 +207,7 @@ XRP Ledgerは、トランザクションオブジェクトが送信元アドレ
|
||||
- [安全な署名の設定](secure-signing.md)
|
||||
- [XRPの送金](../../tutorials/how-tos/send-xrp.md)
|
||||
- [トランザクションの結果の確認](finality-of-results/look-up-transaction-results.md)
|
||||
- [WebSocketを使用した着信ペイメントの監視](../../tutorials/http-websocket-apis/build-apps/monitor-incoming-payments-with-websocket.md)
|
||||
- [WebSocketを使用した着信ペイメントの監視](/docs/tutorials/advanced-developer-topics/client-library-development/monitor-incoming-payments-with-websocket.md)
|
||||
- [トランザクションの取り消しまたはスキップ](finality-of-results/canceling-a-transaction.md)
|
||||
- [信頼できるトランザクションの送信](reliable-transaction-submission.md)
|
||||
- **リファレンス:**
|
||||
|
||||
@@ -48,7 +48,7 @@ labels:
|
||||
|
||||
[構成ファイルの例](https://github.com/XRPLF/rippled/blob/8429dd67e60ba360da591bfa905b58a35638fda1/cfg/rippled-example.cfg#L1050-L1073)では、ローカルループバックネットワーク上(127.0.0.1)のポート5005でJSON-RPC(HTTP)、ポート6006でWebSocket(WS)の接続をリッスンし、接続されるすべてのクライアントを管理者として扱っています。
|
||||
|
||||
{% admonition type="warning" name="注意" %}署名に[コマンドラインAPI](../../references/http-websocket-apis/api-conventions/request-formatting.md#コマンドライン形式)を使用する場合は、コマンドラインでないクライアントで[Websocket APIやJSON-RPC APIを使用](../../tutorials/http-websocket-apis/build-apps/get-started.md)する場合よりもセキュリティが弱くなります。コマンドライン構文を使用すると、秘密鍵がシステムのプロセスリストで他のユーザに見える可能性があり、シェル履歴にプレーンテキスト形式でキーが保存される可能性があります。{% /admonition %}
|
||||
{% admonition type="warning" name="注意" %}署名に[コマンドラインAPI](../../references/http-websocket-apis/api-conventions/request-formatting.md#コマンドライン形式)を使用する場合は、コマンドラインでないクライアントで[Websocket APIやJSON-RPC APIを使用](/docs/tutorials/get-started/get-started-http-websocket-apis.md)する場合よりもセキュリティが弱くなります。コマンドライン構文を使用すると、秘密鍵がシステムのプロセスリストで他のユーザに見える可能性があり、シェル履歴にプレーンテキスト形式でキーが保存される可能性があります。{% /admonition %}
|
||||
|
||||
3. サーバの使用中は、稼働状態と最新状態を維持して、ネットワークと同期されるようにしておく必要があります。
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ labels:
|
||||
---
|
||||
# Amendment投票機能の設定
|
||||
|
||||
バリデータとして設定されたサーバは、[featureメソッド][]を使ってXRP Ledgerプロトコルの[Amendment](../../concepts/networks-and-servers/amendments.md)に投票することができます。(この方法には[管理者アクセス](../../tutorials/http-websocket-apis/build-apps/get-started.md#管理者アクセス権限)が必要です).
|
||||
バリデータとして設定されたサーバは、[featureメソッド][]を使ってXRP Ledgerプロトコルの[Amendment](../../concepts/networks-and-servers/amendments.md)に投票することができます。(この方法には[管理者アクセス](/docs/tutorials/get-started/get-started-http-websocket-apis.md#管理者アクセス権限)が必要です).
|
||||
|
||||
例えば、「SHAMapV2」Amendmentに反対票を投じるには、以下のコマンドを実行します。
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ gRPCを有効にするには、次の前提条件を満たす必要がありま
|
||||
- [XRP Ledgerの概要](/about/)
|
||||
- [`rippled`サーバのモード](../../concepts/networks-and-servers/rippled-server-modes.md)
|
||||
- **チュートリアル:**
|
||||
- [HTTP / WebSocketAPIを使ってみる](../../tutorials/http-websocket-apis/build-apps/get-started.md)
|
||||
- [HTTP / WebSocketAPIを使ってみる](/docs/tutorials/get-started/get-started-http-websocket-apis.md)
|
||||
- [信頼できるトランザクションの送信](../../concepts/transactions/reliable-transaction-submission.md)
|
||||
- [rippledサーバの管理](../installation/install-rippled-on-ubuntu.md)
|
||||
- **リファレンス:**
|
||||
|
||||
@@ -43,11 +43,6 @@ labels:
|
||||
# No [ips] stanza. Use the default hubs to connect to Mainnet.
|
||||
```
|
||||
|
||||
```{% label="Sidechain-Devnet" %}
|
||||
[ips]
|
||||
sidechain-net2.devnet.rippletest.net 51235
|
||||
```
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
2. 以前の `[ips]`があれば、コメントアウトしてください。
|
||||
@@ -78,11 +73,6 @@ labels:
|
||||
main
|
||||
```
|
||||
|
||||
```{% label="Sidechain-Devnet" %}
|
||||
[network_id]
|
||||
262
|
||||
```
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
カスタムネットワークの場合、そのネットワークに接続する全員が、そのネットワークに固有の値を使用する必要があります。新しいネットワークを作成するときは、ネットワークIDを11から4,294,967,295までの整数からランダムに選択します。
|
||||
@@ -121,14 +111,6 @@ labels:
|
||||
ED2677ABFFD1B33AC6FBC3062B71F1E8397C1505E1C42C64D11AD1B28FF73F4734
|
||||
```
|
||||
|
||||
```{% label="Sidechain-Devnet" %}
|
||||
[validator_list_sites]
|
||||
https://vlsidechain-net2.devnet.rippletest.net
|
||||
|
||||
[validator_list_keys]
|
||||
EDA5504C7133743FADA46342229B4E9CBBE1CF9BCA19D16633574F7CBB72F79569
|
||||
```
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
{% admonition type="success" name="ヒント" %}プレビュー版パッケージには必要な項目があらかじめ設定されている場合がありますが、念のため確認してください。{% /admonition %}
|
||||
@@ -182,13 +164,6 @@ labels:
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Sidechain-Devnet" %}
|
||||
```
|
||||
[features]
|
||||
XChainBridge
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
{% admonition type="danger" name="警告" %}メインネットまたはテストネットに接続するときは、`[features]`を使用しないでください。他のネットワークと異なる機能を強制的に有効にすると、サーバがネットワークから分断される可能性があります。{% /admonition %}
|
||||
|
||||
@@ -57,7 +57,7 @@ labels:
|
||||
|
||||
2. サーバに対してオンライン削除を指示する[can_deleteメソッド][]の実行をテストします。
|
||||
|
||||
このコマンドの実行には[`rippled`コマンドラインインターフェイス](../../../tutorials/http-websocket-apis/build-apps/get-started.md#コマンドライン)を使用できます。例:
|
||||
このコマンドの実行には[`rippled`コマンドラインインターフェイス](/docs/tutorials/get-started/get-started-http-websocket-apis.md#コマンドライン)を使用できます。例:
|
||||
|
||||
```
|
||||
$ rippled --conf=/etc/opt/ripple/rippled.cfg can_delete now
|
||||
|
||||
@@ -11,7 +11,7 @@ labels:
|
||||
|
||||
{% badge href="https://github.com/XRPLF/rippled/releases/tag/1.1.0" %}新規: rippled 1.1.0{% /badge %}デフォルトでは、`rippled`の署名メソッドは管理者接続に限定されています。v1.1.0以前のバージョンの`rippled`のように、署名メソッドをパブリックAPIメソッドとして使用できるようにするには、構成を変更することで、これを使用できるようにします。
|
||||
|
||||
これにより、サーバが「パブリック」[JSON-RPC接続およびWebSocket接続](../../tutorials/http-websocket-apis/build-apps/get-started.md)を受け入れる場合は、これらのパブリック接続で以下のメソッドが使用できるようになります。
|
||||
これにより、サーバが「パブリック」[JSON-RPC接続およびWebSocket接続](/docs/tutorials/get-started/get-started-http-websocket-apis.md)を受け入れる場合は、これらのパブリック接続で以下のメソッドが使用できるようになります。
|
||||
|
||||
- [sign][signメソッド]
|
||||
- [sign_for][sign_forメソッド]
|
||||
|
||||
@@ -80,7 +80,7 @@ labels:
|
||||
- **チュートリアル:**
|
||||
- [rippledの構成](../configuration/index.md)
|
||||
- [rippledのトラブルシューティング](../troubleshooting/index.md)
|
||||
- [rippled APIの使用開始](../../tutorials/http-websocket-apis/build-apps/get-started.md)
|
||||
- [rippled APIの使用開始](/docs/tutorials/get-started/get-started-http-websocket-apis.md)
|
||||
- **リファレンス:**
|
||||
- [rippled APIリファレンス](../../references/http-websocket-apis/index.md)
|
||||
- [`rippled`コマンドラインの使用](../commandline-usage.md)
|
||||
|
||||
@@ -182,7 +182,7 @@ Terminating thread doJob:AcquisitionDone: unhandled
|
||||
|
||||
11. `rippled`サービスが正常に起動したかどうかを確認します。
|
||||
|
||||
[コマンドラインインターフェイス](../../tutorials/http-websocket-apis/build-apps/get-started.md#コマンドライン)を使用してサーバの状況を確認できます(サーバがJSON-RPCリクエストを受け入れないように設定している場合を除く)。次に例を示します。
|
||||
[コマンドラインインターフェイス](/docs/tutorials/get-started/get-started-http-websocket-apis.md#コマンドライン)を使用してサーバの状況を確認できます(サーバがJSON-RPCリクエストを受け入れないように設定している場合を除く)。次に例を示します。
|
||||
|
||||
```
|
||||
/opt/ripple/bin/rippled server_info
|
||||
|
||||
@@ -12,10 +12,10 @@ seo:
|
||||
|
||||
| 言語 | ライブラリ名 | Get Started | APIリファレンス | ソースコード |
|
||||
|---------------------------------|------------------------|--------------|---------------|-------------|
|
||||
| **Python** | `xrpl-py` | [Pythonを使ってみよう](../tutorials/python/build-apps/get-started.md) | [API リファレンス](https://xrpl-py.readthedocs.io/) | [リポジトリ](https://github.com/XRPLF/xrpl-py) |
|
||||
| **JavaScript** / **TypeScript** | `xrpl.js` | [JavaScriptを使ってみよう](../tutorials/javascript/build-apps/get-started.md) | [API リファレンス](https://js.xrpl.org/) | [リポジトリ](https://github.com/XRPLF/xrpl.js) |
|
||||
| **Python** | `xrpl-py` | [Pythonを使ってみよう](/docs/tutorials/get-started/get-started-python.md) | [API リファレンス](https://xrpl-py.readthedocs.io/) | [リポジトリ](https://github.com/XRPLF/xrpl-py) |
|
||||
| **JavaScript** / **TypeScript** | `xrpl.js` | [JavaScriptを使ってみよう](/docs/tutorials/get-started/get-started-javascript.md) | [API リファレンス](https://js.xrpl.org/) | [リポジトリ](https://github.com/XRPLF/xrpl.js) |
|
||||
| **JavaScript** / **TypeScript** | `xrpl-client` | [触ってみる](https://jsfiddle.net/WietseWind/35az6p1b/) | [NPM リファレンス](https://www.npmjs.com/package/xrpl-client) | [リポジトリ](https://github.com/XRPL-Labs/xrpl-client) |
|
||||
| **JavaScript** / **TypeScript** | `xrpl-accountlib` | [触ってみる](https://jsfiddle.net/WietseWind/gkefpnu0/) | [NPM リファレンス](https://www.npmjs.com/package/xrpl-accountlib) | [リポジトリ](https://github.com/WietseWind/xrpl-accountlib) |
|
||||
| **C++** | `rippled` 署名ライブラリ | [署名ライブラリを使ってみよう](https://github.com/XRPLF/rippled/tree/develop/Builds/linux#signing-library) | | ([`rippled`](https://github.com/XRPLF/rippled/))の一部 |
|
||||
| **Java** | `xrpl4j` | [Javaを使ってみよう](../tutorials/java/build-apps/get-started.md) | [API リファレンス](https://javadoc.io/doc/org.xrpl/) | [リポジトリ](https://github.com/XRPLF/xrpl4j) |
|
||||
| **PHP** | `XRPL_PHP` | [PHPを使ってみよう](../tutorials/php/build-apps/get-started.md) | [XRPL_PHP ドキュメント](https://alexanderbuzz.github.io/xrpl-php-docs/) | [リポジトリ](https://github.com/AlexanderBuzz/xrpl-php) |
|
||||
| **Java** | `xrpl4j` | [Javaを使ってみよう](/docs/tutorials/get-started/get-started-java.md) | [API リファレンス](https://javadoc.io/doc/org.xrpl/) | [リポジトリ](https://github.com/XRPLF/xrpl4j) |
|
||||
| **PHP** | `XRPL_PHP` | [PHPを使ってみよう](/docs/tutorials/get-started/get-started-php.md) | [XRPL_PHP ドキュメント](https://alexanderbuzz.github.io/xrpl-php-docs/) | [リポジトリ](https://github.com/AlexanderBuzz/xrpl-php) |
|
||||
|
||||
@@ -14,6 +14,6 @@ nav_omit: true
|
||||
|
||||
## Alternatives
|
||||
|
||||
アカウント残高や取引履歴のリクエストなど、ほとんどの一般的な操作では、[WebSocket接続](../tutorials/http-websocket-apis/get-started.md#websocket-api)または[JSON-RPC(HTTP POST)](../tutorials/http-websocket-apis/build-apps/get-started.md#json-rpc)を使用して、セルフホストまたは[公開XRP Ledgerサーバ](../tutorials/public-servers.md)にリクエストすることとができます。
|
||||
アカウント残高や取引履歴のリクエストなど、ほとんどの一般的な操作では、[WebSocket接続](/docs/tutorials/get-started/get-started-http-websocket-apis.md#websocket-api)または[JSON-RPC(HTTP POST)](/docs/tutorials/get-started/get-started-http-websocket-apis.md#json-rpc)を使用して、セルフホストまたは[公開XRP Ledgerサーバ](../tutorials/public-servers.md)にリクエストすることとができます。
|
||||
|
||||
詳細については、[HTTP / WebSocket APIsの使用を開始する](../tutorials/http-websocket-apis/build-apps/get-started.md)ページをご覧ください。
|
||||
詳細については、[HTTP / WebSocket APIsの使用を開始する](/docs/tutorials/get-started/get-started-http-websocket-apis.md)ページをご覧ください。
|
||||
|
||||
@@ -10,7 +10,7 @@ labels:
|
||||
|
||||
`rippled`サーバと直接通信する際には管理APIメソッドを使用します。管理メソッドは、信頼できるサーバ運用担当者のみを対象としています。管理メソッドには、サーバの管理、監視、デバッグのためのコマンドが含まれています。
|
||||
|
||||
管理コマンドを使用できるのは、管理者として、`rippled.cfg`ファイルに指定されているホストとポートで`rippled`サーバに接続している場合に限られます。デフォルトでは、コマンドラインクライアントが管理接続を使用します。`rippled`への接続についての詳細は、[rippled API入門](../../../tutorials/http-websocket-apis/build-apps/get-started.md)をご覧ください。
|
||||
管理コマンドを使用できるのは、管理者として、`rippled.cfg`ファイルに指定されているホストとポートで`rippled`サーバに接続している場合に限られます。デフォルトでは、コマンドラインクライアントが管理接続を使用します。`rippled`への接続についての詳細は、[rippled API入門](/docs/tutorials/get-started/get-started-http-websocket-apis.md)をご覧ください。
|
||||
|
||||
|
||||
## [キー生成メソッド](key-generation-methods/index.md)
|
||||
|
||||
@@ -10,7 +10,7 @@ labels:
|
||||
|
||||
`rippled`サーバはAPIクライアントが公開APIにリクエストできるレートを制限できます。レート制限はクライアントのIPアドレスに基づいて行われるため、[ネットワークアドレス変換](https://ja.wikipedia.org/wiki/ネットワークアドレス変換)の背後にいるクライアントは公開IPアドレスに基づく制限を共有します。
|
||||
|
||||
{% admonition type="success" name="ヒント" %}レート制限は、クライアントが[管理者](../../../tutorials/http-websocket-apis/build-apps/get-started.md#管理者アクセス権限)として接続されているときには適用されません{% /admonition %}
|
||||
{% admonition type="success" name="ヒント" %}レート制限は、クライアントが[管理者](/docs/tutorials/get-started/get-started-http-websocket-apis.md#管理者アクセス権限)として接続されているときには適用されません{% /admonition %}
|
||||
|
||||
クライアントがレート制限に近づいている場合、サーバは[APIレスポンス](response-formatting.md)のトップレベルにフィールド`"warning": "load"`というフィールドを[APIレスポンス](response-formatting.md)のトップレベルに追加します。この警告はすべてのレスポンスに追加されるわけではありませんが、サーバはクライアントを切断する前に何度かこのような警告を送ることがあります。
|
||||
|
||||
@@ -58,7 +58,7 @@ Server is overloaded
|
||||
- [`rippled`サーバ](../../../concepts/networks-and-servers/index.md)
|
||||
- [ソフトウェアエコシステム](../../../introduction/software-ecosystem.md)
|
||||
- **チュートリアル:**
|
||||
- [XRP Ledger APIの使用開始](../../../tutorials/http-websocket-apis/build-apps/get-started.md)
|
||||
- [XRP Ledger APIの使用開始](/docs/tutorials/get-started/get-started-http-websocket-apis.md)
|
||||
- [rippledのトラブルシューティング](../../../infrastructure/troubleshooting/index.md)
|
||||
- **リファレンス:**
|
||||
- [rippled APIリファレンス](../index.md)
|
||||
|
||||
@@ -130,7 +130,7 @@ HTTP Status: 200 OK
|
||||
|
||||
この警告は、XRP Ledgerプロトコルの1つ以上の[Amendment](../../../concepts/networks-and-servers/amendments.md)が有効になる予定であるが、現在のサーバにはそれらのAmendmentの実装がないことを示しています。これらのAmendmentが有効になると、現在のサーバは[Amendmentブロック](../../../concepts/networks-and-servers/amendments.md#amendment-blocked-servers)されるため、できるだけ早く[最新の`rippled`バージョンにアップグレード](../../../infrastructure/installation/index.md)する必要があります。
|
||||
|
||||
サーバは、この警告を送信するのは、クライアントが[管理者として接続している](../../../tutorials/http-websocket-apis/build-apps/get-started.md#admin-access)場合のみです。
|
||||
サーバは、この警告を送信するのは、クライアントが[管理者として接続している](/docs/tutorials/get-started/get-started-http-websocket-apis.md#admin-access)場合のみです。
|
||||
|
||||
この警告には、以下のフィールドを含む`details`フィールドが含まれます。
|
||||
|
||||
@@ -189,7 +189,7 @@ HTTP Status: 200 OK
|
||||
- [Amendment](../../../concepts/networks-and-servers/amendments.md)
|
||||
- [既知のAmendment](/resources/known-amendments.md)
|
||||
- **チュートリアル:**
|
||||
- [XRP LedgerのAPIを触ってみよう](../../../tutorials/http-websocket-apis/build-apps/get-started.md)
|
||||
- [XRP LedgerのAPIを触ってみよう](/docs/tutorials/get-started/get-started-http-websocket-apis.md)
|
||||
- [`rippled`のインストールと更新](../../../infrastructure/installation/index.md)
|
||||
- **リファレンス:**
|
||||
- [featureメソッド][]
|
||||
|
||||
@@ -20,7 +20,7 @@ steps: ['Generate', 'Connect', 'Check Sequence', 'Prepare & Sign', 'Submit', 'Wa
|
||||
<script type="application/javascript" src="/js/interactive-tutorial.js"></script>
|
||||
<script type="application/javascript" src="/js/tutorials/use-tickets.js"></script>
|
||||
|
||||
このページでは、[xrpl.js](https://js.xrpl.org/)ライブラリを使用したJavaScriptのサンプルを提供しています。設定方法は、[JavaScriptを使ってみよう](../../javascript/build-apps/get-started.md)をご覧ください。
|
||||
このページでは、[xrpl.js](https://js.xrpl.org/)ライブラリを使用したJavaScriptのサンプルを提供しています。設定方法は、[JavaScriptを使ってみよう](/docs/tutorials/get-started/get-started-javascript.md)をご覧ください。
|
||||
|
||||
JavaScriptはWebブラウザ上で動作するため、セットアップなしで読み進められ、インタラクティブな手順を利用することができます。
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ steps: ['Generate', 'Connect', 'Prepare', 'Sign', 'Submit', 'Wait', 'Check']
|
||||
<script type="application/javascript" src="/js/interactive-tutorial.js"></script>
|
||||
<script type="application/javascript" src="/js/tutorials/send-xrp.js"></script>
|
||||
|
||||
- このページでは、xrpl.jsライブラリーを使用するJavaScriptの例を紹介します。[xrpl.js入門ガイド](../javascript/build-apps/get-started.md)に、xrpl.jsを使用してJavaScriptからXRP Ledgerデータにアクセスする方法の説明があります。
|
||||
- このページでは、xrpl.jsライブラリーを使用するJavaScriptの例を紹介します。[xrpl.js入門ガイド](/docs/tutorials/get-started/get-started-javascript.md)に、xrpl.jsを使用してJavaScriptからXRP Ledgerデータにアクセスする方法の説明があります。
|
||||
|
||||
- XRP Ledgerでトランザクションを送信するには、まずアドレスと秘密鍵、そしていくらかのXRPが必要となります。次のインターフェイスを使用して、XRP Test NetにあるアドレスとTestnet XRPを入手できます。
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ labels:
|
||||
| Ripple[¹][] | Testnet (Clio) | `https://clio.altnet.rippletest.net:51234/` | `wss://clio.altnet.rippletest.net:51233/` | Clioを使用したTestnet公開サーバ |
|
||||
| Ripple[¹][] | Devnet | `https://s.devnet.rippletest.net:51234/` | `wss://s.devnet.rippletest.net:51233/` | Devnet 公開サーバ |
|
||||
| Ripple[¹][] | Devnet (Clio) | `https://clio.devnet.rippletest.net:51234/` | `wss://clio.devnet.rippletest.net:51233/` | Clioを使用したDevnet公開サーバ |
|
||||
| Ripple[¹][] | Sidechain-Devnet | `https://sidechain-net2.devnet.rippletest.net:51234/` | `wss://sidechain-net2.devnet.rippletest.net:51233/` | クロスチェーンブリッジ機能をテストするためのサイドチェーンDevnet。Devnetはロックチェーンとして機能し、このサイドチェーンは発行チェーンとして機能します。 |
|
||||
| XRPL Labs | Xahau Testnet | `https://xahau-test.net/` | `wss://xahau-test.net/` | [Hooksが有効](https://hooks.xrpl.org/)なXahau Testnet |
|
||||
|
||||
[ネットワーク]: ../concepts/networks-and-servers/parallel-networks.md
|
||||
|
||||
@@ -72,7 +72,7 @@ XRP Ledgerの分散型取引所(DEX)には、「アルゴリズムトレード
|
||||
|
||||
### トレードの発注
|
||||
|
||||
XRP Ledgerの分散型取引所で _代替可能_ トークンとXRPを売買するには、通常[OfferCreateトランザクション](../../references/protocol/transactions/types/offercreate.md)を送信します。この方法でトレードを行うためのコードと技術的ステップの詳細なウォークスルーについては、[分散型取引所でのトレード](../../tutorials/how-tos/use-tokens/trade-in-the-decentralized-exchange.md)をご覧ください。[Paymentトランザクション](../../references/protocol/transactions/types/payment.md)を使用して通貨を両替することも可能です。[クロスカレンしー支払い](../../concepts/payment-types/cross-currency-payments.md)を他のユーザに送ったり、長い[パス](../../concepts/tokens/fungible-tokens/paths.md)を使って裁定取引の機会を1つの操作にまとめることで、自分自身に送り返すこともできます。
|
||||
XRP Ledgerの分散型取引所で _代替可能_ トークンとXRPを売買するには、通常[OfferCreateトランザクション](../../references/protocol/transactions/types/offercreate.md)を送信します。この方法でトレードを行うためのコードと技術的ステップの詳細なウォークスルーについては、[分散型取引所でのトレード](/docs/tutorials/dex/trade-in-the-decentralized-exchange.md)をご覧ください。[Paymentトランザクション](../../references/protocol/transactions/types/payment.md)を使用して通貨を両替することも可能です。[クロスカレンしー支払い](../../concepts/payment-types/cross-currency-payments.md)を他のユーザに送ったり、長い[パス](../../concepts/tokens/fungible-tokens/paths.md)を使って裁定取引の機会を1つの操作にまとめることで、自分自身に送り返すこともできます。
|
||||
|
||||
NFTをトレードするためのコードと技術的な手順については、[JavaScriptを使用したNFTokenの送信](../../tutorials/javascript/nfts/transfer-nfts.md)をご覧ください。
|
||||
|
||||
@@ -89,7 +89,7 @@ XRP Ledgerのトレード活動に関する情報源は数多くあります。
|
||||
XRP Ledgerは既存の中央指値注文ベース(CLOB)の分散型取引所と連携するネイティブな自動マーケットメーカー(AMM)の機能をネイティブサポートしています。AMMはXRP Ledger上のトレードにおいて重要な要素となっています。詳しくは以下のリンクをご覧ください。
|
||||
|
||||
- [自動マーケットメーカー](../../concepts/tokens/decentralized-exchange/automated-market-makers.md)
|
||||
- [AMMのオークションスロットを利用して低い取引手数料でトレードする](../../tutorials/javascript/amm/add-assets-to-amm.md)
|
||||
- [AMMのオークションスロットを利用して低い取引手数料でトレードする](/docs/tutorials/dex/add-assets-to-amm-in-javascript.md)
|
||||
- [XLS-30 標準規格](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0030-automated-market-maker#readme)
|
||||
|
||||
## さらに詳しく
|
||||
|
||||
@@ -67,7 +67,7 @@ NFTをオークション形式で販売することができます。[NFTオー
|
||||
|
||||
XRPL NFTの最もシンプルな支払い方法はXRPです。XRPを使ったNFTの売り買いの例については、[NFTokenの取引](../../tutorials/javascript/nfts/transfer-nfts.md)をご覧ください。
|
||||
|
||||
他の通貨での取引は、DEXを活用してあらゆる種類の発行通貨を受け入れ、取引することができます。[分散型取引所での取引](../../tutorials/how-tos/use-tokens/trade-in-the-decentralized-exchange.md#trade-in-the-decentralized-exchange)をご覧ください。
|
||||
他の通貨での取引は、DEXを活用してあらゆる種類の発行通貨を受け入れ、取引することができます。[分散型取引所での取引](/docs/tutorials/dex/trade-in-the-decentralized-exchange.md#trade-in-the-decentralized-exchange)をご覧ください。
|
||||
|
||||
## NFTのインデックス
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ NFTをオークション形式で販売することができます。[NFTオー
|
||||
|
||||
XRPL NFTの最もシンプルな支払い方法はXRPです。XRPを使ったNFTの売り買いの例については、[NFTokenの取引](../../tutorials/javascript/nfts/transfer-nfts.md))をご覧ください。
|
||||
|
||||
他の通貨での取引は、DEXを活用してあらゆる種類の発行通貨を受け入れ、取引することができます。[分散型取引所での取引](../../tutorials/how-tos/use-tokens/trade-in-the-decentralized-exchange.md#trade-in-the-decentralized-exchange)をご覧ください。
|
||||
他の通貨での取引は、DEXを活用してあらゆる種類の発行通貨を受け入れ、取引することができます。[分散型取引所での取引](/docs/tutorials/dex/trade-in-the-decentralized-exchange.md#trade-in-the-decentralized-exchange)をご覧ください。
|
||||
|
||||
## NFTのインデックス化
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ NFTをオークション形式で販売することができます。[NFTオー
|
||||
|
||||
XRPL NFTの最もシンプルな支払い方法はXRPです。XRPを使ったNFTの売り買いの例については、[NFTokenの取引](../../tutorials/javascript/nfts/transfer-nfts.md)をご覧ください。
|
||||
|
||||
他の通貨での取引は、DEXを活用してあらゆる種類の発行通貨を受け入れ、取引することができます。[分散型取引所での取引](../../tutorials/how-tos/use-tokens/trade-in-the-decentralized-exchange.md#trade-in-the-decentralized-exchange)をご覧ください。
|
||||
他の通貨での取引は、DEXを活用してあらゆる種類の発行通貨を受け入れ、取引することができます。[分散型取引所での取引](/docs/tutorials/dex/trade-in-the-decentralized-exchange.md#trade-in-the-decentralized-exchange)をご覧ください。
|
||||
|
||||
<!--
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ NFTをオークション形式で販売することができます。[NFTオー
|
||||
|
||||
XRPL NFTの最もシンプルな支払い方法はXRPです。XRPを使ったNFTの売り買いの例については、[NFTokenの取引](../../tutorials/javascript/nfts/transfer-nfts.md)をご覧ください。
|
||||
|
||||
他の通貨での取引は、DEXを活用してあらゆる種類の発行通貨を受け入れ、取引することができます。[分散型取引所での取引](../../tutorials/how-tos/use-tokens/trade-in-the-decentralized-exchange.md#trade-in-the-decentralized-exchange)をご覧ください。
|
||||
他の通貨での取引は、DEXを活用してあらゆる種類の発行通貨を受け入れ、取引することができます。[分散型取引所での取引](/docs/tutorials/dex/trade-in-the-decentralized-exchange.md#trade-in-the-decentralized-exchange)をご覧ください。
|
||||
|
||||
## NFTのインデックス化
|
||||
|
||||
|
||||
@@ -128,31 +128,22 @@ export function Navbar(props) {
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
// Bootstrap 5 uses vanilla JavaScript API instead of jQuery
|
||||
// These events set classes so that the search bar and other
|
||||
// Turns out jQuery is necessary for firing events on Bootstrap v4
|
||||
// dropdowns. These events set classes so that the search bar and other
|
||||
// submenus collapse on mobile when you expand one submenu.
|
||||
const dropdowns = document.querySelectorAll("#topnav-pages .dropdown");
|
||||
const dds = $("#topnav-pages .dropdown");
|
||||
const top_main_nav = document.querySelector("#top-main-nav");
|
||||
|
||||
const handleDropdownShow = () => {
|
||||
top_main_nav?.classList.add("submenu-expanded");
|
||||
};
|
||||
|
||||
const handleDropdownHidden = () => {
|
||||
top_main_nav?.classList.remove("submenu-expanded");
|
||||
};
|
||||
|
||||
// Attach Bootstrap 5 dropdown events
|
||||
dropdowns.forEach((dropdown) => {
|
||||
dropdown.addEventListener("show.bs.dropdown", handleDropdownShow);
|
||||
dropdown.addEventListener("hidden.bs.dropdown", handleDropdownHidden);
|
||||
dds.on("show.bs.dropdown", (evt) => {
|
||||
top_main_nav.classList.add("submenu-expanded");
|
||||
});
|
||||
dds.on("hidden.bs.dropdown", (evt) => {
|
||||
top_main_nav.classList.remove("submenu-expanded");
|
||||
});
|
||||
|
||||
// Close navbar on .dropdown-item click
|
||||
const toggleNavbar = () => {
|
||||
const navbarToggler = document.querySelector(".navbar-toggler");
|
||||
const isNavbarCollapsed =
|
||||
navbarToggler?.getAttribute("aria-expanded") === "true";
|
||||
navbarToggler.getAttribute("aria-expanded") === "true";
|
||||
if (isNavbarCollapsed) {
|
||||
navbarToggler?.click(); // Simulate click to toggle navbar
|
||||
}
|
||||
@@ -165,10 +156,6 @@ export function Navbar(props) {
|
||||
|
||||
// Cleanup function to remove event listeners
|
||||
return () => {
|
||||
dropdowns.forEach((dropdown) => {
|
||||
dropdown.removeEventListener("show.bs.dropdown", handleDropdownShow);
|
||||
dropdown.removeEventListener("hidden.bs.dropdown", handleDropdownHidden);
|
||||
});
|
||||
dropdownItems.forEach((item) => {
|
||||
item.removeEventListener("click", toggleNavbar);
|
||||
});
|
||||
@@ -313,7 +300,7 @@ export function NavDropdown(props) {
|
||||
href="#"
|
||||
id={toggler_id}
|
||||
role="button"
|
||||
data-bs-toggle="dropdown"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
@@ -342,8 +329,8 @@ export function NavControls(props) {
|
||||
<button
|
||||
className="navbar-toggler collapsed"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#top-main-nav"
|
||||
data-toggle="collapse"
|
||||
data-target="#top-main-nav"
|
||||
aria-controls="navbarHolder"
|
||||
aria-expanded="false"
|
||||
aria-label="Toggle navigation"
|
||||
@@ -435,19 +422,19 @@ export class ThemeToggle extends React.Component {
|
||||
<div className="nav-item" id="topnav-theme">
|
||||
<form className="form-inline">
|
||||
<div
|
||||
className="form-check form-check-inline form-switch custom-theme-toggle"
|
||||
className="custom-control custom-theme-toggle form-inline-item"
|
||||
title=""
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="left"
|
||||
data-toggle="tooltip"
|
||||
data-placement="left"
|
||||
data-original-title="Toggle Dark Mode"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
className="form-check-input"
|
||||
className="custom-control-input"
|
||||
id="css-toggle-btn"
|
||||
onClick={this.user_choose_theme}
|
||||
/>
|
||||
<label className="form-check-label" htmlFor="css-toggle-btn">
|
||||
<label className="custom-control-label" htmlFor="css-toggle-btn">
|
||||
<span className="d-lg-none">Light/Dark Theme</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -25,7 +25,7 @@ export function XRPLCard(props: XRPLCardProps) {
|
||||
<p className="card-text">{props.body}</p>
|
||||
)}
|
||||
</div>
|
||||
{/* <div className="card-footer"> </div> */}
|
||||
<div className="card-footer"> </div>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// @ts-check
|
||||
|
||||
import { getInnerText } from '@redocly/realm/dist/shared/markdoc.js';
|
||||
import { getInnerText } from '@redocly/realm/dist/server/plugins/markdown/markdoc/helpers/get-inner-text.js';
|
||||
|
||||
import { dirname, relative, join as joinPath } from 'path';
|
||||
import markdoc from '@markdoc/markdoc';
|
||||
@@ -47,6 +47,7 @@ export function blogPosts() {
|
||||
actions.createSharedData('blog-posts', { blogPosts: sortedPosts });
|
||||
actions.addRouteSharedData('/blog/', 'blog-posts', 'blog-posts');
|
||||
actions.addRouteSharedData('/ja/blog/', 'blog-posts', 'blog-posts');
|
||||
actions.addRouteSharedData('/es-es/blog/', 'blog-posts', 'blog-posts');
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// @ts-check
|
||||
|
||||
import { getInnerText } from '@redocly/realm/dist/shared/markdoc.js';
|
||||
import { getInnerText } from '@redocly/realm/dist/server/plugins/markdown/markdoc/helpers/get-inner-text.js';
|
||||
|
||||
import { dirname, relative, join as joinPath } from 'path';
|
||||
|
||||
@@ -44,6 +44,7 @@ export function codeSamples() {
|
||||
});
|
||||
actions.addRouteSharedData('/resources/code-samples/', 'code-samples', 'code-samples');
|
||||
actions.addRouteSharedData('/ja/resources/code-samples/', 'code-samples', 'code-samples');
|
||||
actions.addRouteSharedData('/es-es/resources/code-samples/', 'code-samples', 'code-samples');
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
@@ -1,178 +0,0 @@
|
||||
# Color System Migration Summary
|
||||
|
||||
**Date:** October 21, 2025
|
||||
**Source:** [XRPL.org Design Tokens - Figma](https://figma.com/design/zRyhXG4hRP3Lk3B6Owr3eo/XRPL.org-Design-Tokens)
|
||||
|
||||
## Migration Strategy: Clean Migration
|
||||
|
||||
The old 10-level color scale (100-1000) has been completely migrated to a new 5-level scale (100-500). All references in the codebase have been updated, and backward compatibility aliases have been removed for a clean implementation.
|
||||
|
||||
**Mapping Applied:**
|
||||
```
|
||||
Old System → New System
|
||||
100 → 100 (lightest)
|
||||
200 → 100
|
||||
300 → 200
|
||||
400 → 200
|
||||
500 → 300 (mid-tone, default)
|
||||
600 → 300
|
||||
700 → 400
|
||||
800 → 400
|
||||
900 → 500 (darkest)
|
||||
1000 → 500
|
||||
```
|
||||
|
||||
**Migration Approach:**
|
||||
1. All color usages (600-1000) were found and replaced with their new equivalents (300-500)
|
||||
2. Backward compatibility aliases were removed from `_colors.scss`
|
||||
3. Only 100-500 design tokens remain for each color family
|
||||
|
||||
## Color Families Updated
|
||||
|
||||
### Primary Colors
|
||||
|
||||
#### Gray (Neutral) ⏸️ NOT UPDATED
|
||||
- **Status:** Original values retained - design tokens not ready
|
||||
- **Current values:** #FCFCFD, #F5F5F7, #E0E0E1, #C1C1C2, #A2A2A4, #838386, #454549, #343437, #232325, #111112
|
||||
- **Note:** Gray/Neutral design tokens will be migrated in a future update
|
||||
|
||||
#### Green ✅
|
||||
- **New Design Tokens:** #EAFCF1, #70EE97, #21E46B, #0DAA3E, #078139
|
||||
- **Variables:** `$green-100` through `$green-500` only
|
||||
- **Migrated:** 14 file references updated
|
||||
- **Special:** `$apex-2023-green` (#00FF76) retained
|
||||
|
||||
#### Lilac (Primary) ✅ *replaces blue-purple*
|
||||
- **New Design Tokens:** #F2EDFF, #D9CAFF, #C0A7FF, #7649E3, #5429A1
|
||||
- **Variables:** `$lilac-100` through `$lilac-500` only
|
||||
- **Legacy aliases:** `$blue-purple-100` through `$blue-purple-500` map to lilac (600-900 removed)
|
||||
- **Migrated:** 16 file references updated
|
||||
- **Note:** This is a new color name in the design system
|
||||
|
||||
### Secondary Colors
|
||||
|
||||
#### Red ✅ *NEW*
|
||||
- **New Design Tokens:** #FDECE7, #F27A66, #F0643A, #DA4518, #A22514
|
||||
- **Variables:** `$red-100` through `$red-500` only
|
||||
- **Note:** This is a completely new color family added to the design system
|
||||
|
||||
#### Pink ✅ *replaces magenta*
|
||||
- **New Design Tokens:** #FDF1F4, #F2B5C3, #F18DA5, #FF577F, #DC466F
|
||||
- **Variables:** `$pink-100` through `$pink-500` only
|
||||
- **Legacy aliases:** `$magenta-100` through `$magenta-500` map to pink (600-900 removed)
|
||||
- **Migrated:** 7 file references updated
|
||||
|
||||
#### Blue ✅
|
||||
- **New Design Tokens:** #EDF4FF, #93BFF1, #428CFF, #0179E7, #0A4DC0
|
||||
- **Variables:** `$blue-100` through `$blue-500` only
|
||||
- **Migrated:** 8 file references updated
|
||||
- **Special:** `$accent-blue-90` (#001133) retained
|
||||
|
||||
#### Yellow ✅
|
||||
- **New Design Tokens:** #F3F1EB, #E6F1A7, #DBF15E, #E1DB26, #D4C02D
|
||||
- **Variables:** `$yellow-100` through `$yellow-500` only
|
||||
- **Migrated:** 11 file references updated
|
||||
|
||||
## Colors Retained (No Design Token Replacement)
|
||||
|
||||
### Orange
|
||||
- **Status:** Legacy values retained
|
||||
- **Values:** #FFEEE5, #FFCCB2, #FFAA80, #FF884B, #FF6719, #E54D00, #B23C00, #802B00, #4C1A00
|
||||
- **Reason:** No corresponding design token in new system
|
||||
|
||||
### Red-purple
|
||||
- **Status:** Legacy values retained
|
||||
- **Values:** #FBE5FF, #F2B2FF, #EA80FF, #E24CFF, #D919FF, #C000E5, #9500B2, #6B0080, #40004C
|
||||
- **Reason:** No corresponding design token in new system
|
||||
|
||||
### Special Event Colors
|
||||
- `$apex-2023-green: #00FF76`
|
||||
- `$token-2049-purple: #410bb9`
|
||||
- `$accent-blue-90: #001133`
|
||||
|
||||
## Bootstrap & Component Colors
|
||||
|
||||
All Bootstrap theme variables remain functional:
|
||||
- `$primary` → `$purple` (now `$lilac-400`)
|
||||
- `$secondary` → `$gray-200`
|
||||
- `$success` → `$green-500`
|
||||
- `$info` → `$blue-500`
|
||||
- `$warning` → `$yellow-500`
|
||||
- `$danger` → `$magenta-500` (now `$pink-500`)
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
**Removed Variables:**
|
||||
- All color variables from 600-1000 have been removed for: Green, Blue, Lilac, Pink, Red, Yellow
|
||||
- `$blue-purple-600` through `$blue-purple-900` removed (use 100-500)
|
||||
- `$magenta-600` through `$magenta-900` removed (use 100-500)
|
||||
|
||||
**No Impact:**
|
||||
- All usages in the codebase have been updated
|
||||
- Legacy color name aliases maintained (100-500 only):
|
||||
- `$blue-purple-100` through `$blue-purple-500` → maps to `$lilac-*`
|
||||
- `$magenta-100` through `$magenta-500` → maps to `$pink-*`
|
||||
|
||||
## Color Name Changes
|
||||
|
||||
| Old Name | New Name | Reason |
|
||||
|----------|----------|--------|
|
||||
| `blue-purple-*` | `lilac-*` | Design system rebranding |
|
||||
| `magenta-*` | `pink-*` | Design system rebranding |
|
||||
| N/A | `red-*` | New color family added |
|
||||
|
||||
## Usage Recommendations
|
||||
|
||||
### Current Best Practices
|
||||
Use the new 5-level design tokens (100-500):
|
||||
```scss
|
||||
// Primary colors
|
||||
color: $gray-300; // Gray (not yet migrated - still uses old values)
|
||||
color: $green-300; // Default green
|
||||
color: $lilac-400; // Primary purple
|
||||
|
||||
// Secondary colors
|
||||
color: $red-300; // Default red
|
||||
color: $pink-300; // Default pink
|
||||
color: $blue-300; // Default blue
|
||||
color: $yellow-300; // Default yellow
|
||||
```
|
||||
|
||||
### Legacy Aliases Still Available
|
||||
```scss
|
||||
// These legacy names work (100-500 only)
|
||||
color: $blue-purple-400; // Same as $lilac-400
|
||||
color: $magenta-300; // Same as $pink-300
|
||||
```
|
||||
|
||||
## Files Modified
|
||||
|
||||
- `styles/_colors.scss` - Complete color system update
|
||||
|
||||
## Validation Status
|
||||
|
||||
✅ All SCSS variables resolve correctly
|
||||
✅ No linter errors
|
||||
✅ Bootstrap theme colors functional
|
||||
✅ All old color references (600-1000) removed from codebase
|
||||
✅ Special event colors preserved
|
||||
⏸️ Gray/Neutral colors - pending future update
|
||||
|
||||
## Migration Statistics
|
||||
|
||||
**Files Updated:** 11 SCSS files
|
||||
- `styles/_colors.scss` - Color definitions cleaned up
|
||||
- `styles/light/_light-theme.scss` - 11 color references updated
|
||||
- `styles/_status-labels.scss` - 39 color references updated
|
||||
- `styles/_diagrams.scss` - 6 color references updated
|
||||
- `styles/_code-tabs.scss` - 2 color references updated
|
||||
- `styles/_content.scss` - 1 color reference updated
|
||||
- `styles/_buttons.scss` - 7 color references updated
|
||||
- `styles/_pages.scss` - 3 color references updated
|
||||
- `styles/_blog.scss` - 2 color references updated
|
||||
- `styles/_feedback.scss` - 2 color references updated
|
||||
- `styles/_rpc-tool.scss` - 1 color reference updated
|
||||
- `styles/_landings.scss` - 1 color reference updated
|
||||
|
||||
**Total Color References Updated:** 75+ instances
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
# CSS Optimization - Implementation Summary
|
||||
|
||||
## ✅ Successfully Completed
|
||||
|
||||
The CSS build pipeline has been modernized with industry-standard optimization tools, resulting in significant performance improvements.
|
||||
|
||||
## Results
|
||||
|
||||
### Bundle Size Improvements
|
||||
|
||||
\`\`\`
|
||||
=== CSS Bundle Comparison ===
|
||||
|
||||
Master (Bootstrap 4):
|
||||
Uncompressed: 405.09 KB
|
||||
Gzipped: 63.44 KB
|
||||
|
||||
This Branch BEFORE Optimization (Bootstrap 5):
|
||||
Uncompressed: 486.64 KB
|
||||
Gzipped: 71.14 KB
|
||||
|
||||
This Branch AFTER Optimization (Bootstrap 5 + PurgeCSS):
|
||||
Uncompressed: 280.92 KB ✅ 42% smaller
|
||||
Gzipped: 43.32 KB ✅ 39% smaller (network transfer)
|
||||
\`\`\`
|
||||
|
||||
### Key Improvements
|
||||
|
||||
| Metric | Before | After | Improvement |
|
||||
|--------|--------|-------|-------------|
|
||||
| **Network Transfer (Gzipped)** | 71.14 KB | 43.32 KB | **39% smaller** |
|
||||
| **Uncompressed Size** | 486.64 KB | 280.92 KB | **42% smaller** |
|
||||
| **CSS Selectors** | 5,423 | 2,681 | **51% fewer** |
|
||||
| **DevTools Filter Performance** | ~60 seconds | <1 second | **98% faster** |
|
||||
|
||||
### Real-World Impact
|
||||
|
||||
- **Page Load:** 40% faster CSS download on 3G connections
|
||||
- **Developer Experience:** DevTools CSS filtering is now instant (<1s vs 60s)
|
||||
- **Bandwidth Savings:** ~28 KB less per page load
|
||||
- **Maintainability:** Modern tooling with source maps in development
|
||||
|
||||
## What Was Implemented
|
||||
|
||||
### 1. Modern Build Pipeline
|
||||
|
||||
- **Upgraded Sass** from 1.26.10 (2020) → 1.93.2 (latest)
|
||||
- **Added PostCSS** with optimization plugins:
|
||||
- **PurgeCSS** - Removes unused CSS selectors
|
||||
- **Autoprefixer** - Browser compatibility
|
||||
- **cssnano** - Advanced minification
|
||||
|
||||
### 2. Build Scripts
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"build-css": "Production build with full optimization",
|
||||
"build-css-dev": "Development build with source maps",
|
||||
"build-css-watch": "Watch mode for continuous compilation",
|
||||
"analyze-css": "Bundle analysis tool"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. PurgeCSS Configuration
|
||||
|
||||
- Scans all `.tsx`, `.md`, `.yaml`, `.html` files for class names
|
||||
- Intelligent safelist for dynamically-added classes
|
||||
- Preserves Bootstrap JS components, CodeMirror, custom tools
|
||||
- Only runs in production (dev builds are fast)
|
||||
|
||||
### 4. CSS Analysis Tool
|
||||
|
||||
Created `scripts/analyze-css.js` to monitor:
|
||||
- Bundle size and composition
|
||||
- Bootstrap component usage
|
||||
- Optimization opportunities
|
||||
- Before/after comparisons
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
### New Files
|
||||
- `postcss.config.cjs` - PostCSS and PurgeCSS configuration
|
||||
- `scripts/analyze-css.js` - CSS bundle analysis tool
|
||||
- `CSS-OPTIMIZATION.md` - Comprehensive optimization guide
|
||||
- `CSS-OPTIMIZATION-SUMMARY.md` - This summary
|
||||
|
||||
### Modified Files
|
||||
- `package.json` - Updated dependencies and build scripts
|
||||
- `styles/README.md` - Updated build documentation
|
||||
|
||||
### Configuration Files
|
||||
All configuration files include extensive inline documentation explaining decisions and patterns.
|
||||
|
||||
## Usage
|
||||
|
||||
### For Production
|
||||
```bash
|
||||
npm run build-css # Full optimization
|
||||
npm run analyze-css # Check results
|
||||
```
|
||||
|
||||
### For Development
|
||||
```bash
|
||||
npm run build-css:dev # Fast build with source maps
|
||||
npm run build-css:watch # Auto-rebuild on changes
|
||||
```
|
||||
|
||||
## Backward Compatibility
|
||||
|
||||
✅ **No breaking changes** - All existing styles are preserved
|
||||
✅ Visual appearance is identical
|
||||
✅ All Bootstrap components still work
|
||||
✅ Dynamic classes are safelisted
|
||||
|
||||
## Documentation
|
||||
|
||||
- **`styles/README.md`** - Build process and troubleshooting
|
||||
- **`CSS-OPTIMIZATION.md`** - Detailed implementation guide
|
||||
- **`postcss.config.cjs`** - Inline configuration documentation
|
||||
|
||||
## Maintenance
|
||||
|
||||
### Adding New Styles
|
||||
|
||||
1. Create `_component.scss` file
|
||||
2. Import in `xrpl.scss`
|
||||
3. Add dynamic classes to safelist if needed
|
||||
4. Test: `npm run build-css:dev` and `npm run build-css`
|
||||
5. Analyze: `npm run analyze-css`
|
||||
|
||||
### Troubleshooting Missing Styles
|
||||
|
||||
If styles are missing in production:
|
||||
1. Check if class is added dynamically
|
||||
2. Add pattern to safelist in `postcss.config.cjs`
|
||||
3. Rebuild with `npm run build-css`
|
||||
|
||||
## Next Steps (Optional Future Optimizations)
|
||||
|
||||
1. **Code Splitting** - Separate vendor CSS from custom styles
|
||||
2. **Critical CSS** - Extract above-the-fold styles
|
||||
3. **Bootstrap Customization** - Import only needed components
|
||||
4. **CSS Modules** - Component-scoped styles for React pages
|
||||
|
||||
## Conclusion
|
||||
|
||||
The CSS optimization is complete and working perfectly. The bundle size has been reduced by 42% (uncompressed) and 39% (gzipped), resulting in faster page loads and dramatically improved developer experience.
|
||||
|
||||
**Status: ✅ Ready for Production**
|
||||
|
||||
---
|
||||
*Last Updated: October 2025*
|
||||
@@ -1,381 +0,0 @@
|
||||
# CSS Optimization Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes the CSS optimization implementation for the XRPL Dev Portal, including the rationale, implementation details, performance improvements, and maintenance guidelines.
|
||||
|
||||
## The Problem
|
||||
|
||||
### Before Optimization
|
||||
|
||||
The dev portal was serving a **486 KB** minified CSS bundle that included:
|
||||
|
||||
- **Entire Bootstrap 5.3.8 framework** (~200+ KB)
|
||||
- Thousands of unused CSS selectors
|
||||
- No tree-shaking or dead code elimination
|
||||
- All styles loaded on every page, regardless of usage
|
||||
- **1-minute lag** in Chrome DevTools when filtering CSS
|
||||
|
||||
#### Impact
|
||||
|
||||
- **Developer Experience:** DevTools filter took 60+ seconds to respond
|
||||
- **Page Performance:** 486 KB CSS downloaded on every page load
|
||||
- **Build Process:** Outdated Sass 1.26.10 (from 2020)
|
||||
- **Debugging:** No source maps, even in development
|
||||
|
||||
### Analysis Results
|
||||
|
||||
Initial analysis showed:
|
||||
|
||||
```
|
||||
Bundle Size: 486.64 KB
|
||||
Total Selectors: 5,423
|
||||
Unique Selectors: 4,678
|
||||
|
||||
Bootstrap Component Usage:
|
||||
- Pagination: 998 usages
|
||||
- Cards: 428 usages
|
||||
- Grid System: 253 usages
|
||||
- ...but also...
|
||||
- Toast: 8 usages
|
||||
- Spinner: 8 usages
|
||||
- Accordion: 0 usages (unused!)
|
||||
```
|
||||
|
||||
## The Solution
|
||||
|
||||
### Modern Build Pipeline
|
||||
|
||||
Implemented a three-stage optimization pipeline:
|
||||
|
||||
```
|
||||
SCSS → Sass Compiler → PostCSS → Optimized CSS
|
||||
│
|
||||
├─ PurgeCSS (removes unused)
|
||||
├─ Autoprefixer (adds vendor prefixes)
|
||||
└─ cssnano (minifies)
|
||||
```
|
||||
|
||||
### Key Technologies
|
||||
|
||||
1. **Sass (latest)** - Modern SCSS compilation with better performance
|
||||
2. **PostCSS** - Industry-standard CSS processing
|
||||
3. **PurgeCSS** - Intelligent unused CSS removal
|
||||
4. **Autoprefixer** - Browser compatibility
|
||||
5. **cssnano** - Advanced minification
|
||||
|
||||
## Implementation
|
||||
|
||||
### 1. Dependency Upgrades
|
||||
|
||||
```json
|
||||
{
|
||||
"devDependencies": {
|
||||
"sass": "^1.93.2", // was 1.26.10
|
||||
"postcss": "^8.5.6",
|
||||
"postcss-cli": "^11.0.1",
|
||||
"@fullhuman/postcss-purgecss": "^7.0.2",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"cssnano": "^7.1.1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Build Scripts
|
||||
|
||||
Created separate development and production builds:
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"build-css": "Production build with full optimization",
|
||||
"build-css:dev": "Development build with source maps",
|
||||
"build-css:watch": "Watch mode for continuous compilation",
|
||||
"analyze-css": "node scripts/analyze-css.js"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Production Build:**
|
||||
- ✅ Full PurgeCSS optimization
|
||||
- ✅ Minified and compressed
|
||||
- ✅ Autoprefixed
|
||||
- ❌ No source maps
|
||||
|
||||
**Development Build:**
|
||||
- ✅ Source maps for debugging
|
||||
- ✅ Autoprefixed
|
||||
- ❌ No PurgeCSS (faster builds)
|
||||
- ❌ Not minified (readable)
|
||||
|
||||
### 3. PurgeCSS Configuration
|
||||
|
||||
Created `postcss.config.cjs` with intelligent safelist:
|
||||
|
||||
```javascript
|
||||
// Content paths - scan these for class names
|
||||
content: [
|
||||
'./**/*.tsx',
|
||||
'./**/*.md',
|
||||
'./**/*.yaml',
|
||||
'./**/*.html',
|
||||
'./static/js/**/*.js',
|
||||
]
|
||||
|
||||
// Safelist - preserve these classes
|
||||
safelist: {
|
||||
standard: [
|
||||
'html', 'body', 'light', 'dark',
|
||||
/^show$/, /^active$/, /^disabled$/,
|
||||
],
|
||||
deep: [
|
||||
/dropdown-menu/, /modal-backdrop/,
|
||||
/cm-/, /CodeMirror/, // Third-party
|
||||
/rpc-tool/, /websocket/, // Custom components
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
**Safelist Strategy:**
|
||||
- **Standard:** State classes added by JavaScript
|
||||
- **Deep:** Component patterns (keeps parent and children)
|
||||
- **Greedy:** Attribute-based matching
|
||||
|
||||
### 4. Analysis Tool
|
||||
|
||||
Created `scripts/analyze-css.js` to track optimization:
|
||||
|
||||
- Bundle size metrics
|
||||
- Selector counts
|
||||
- Bootstrap component usage
|
||||
- Custom pattern detection
|
||||
- Optimization recommendations
|
||||
|
||||
## Results
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
| Metric | Before | After | Improvement |
|
||||
|--------|--------|-------|-------------|
|
||||
| **Bundle Size (Uncompressed)** | 486.64 KB | 280.92 KB | **42% smaller** |
|
||||
| **Bundle Size (Gzipped)** | 71.14 KB | 43.32 KB | **39% smaller** |
|
||||
| **Total Selectors** | 5,423 | 2,681 | **51% fewer** |
|
||||
| **Unique Selectors** | 4,678 | 2,167 | **54% fewer** |
|
||||
| **DevTools Filter** | ~60 seconds | <1 second | **98% faster** |
|
||||
| **Download Time (3G)** | ~2.0s | ~1.2s | **40% faster** |
|
||||
|
||||
**Note:** Gzipped size is what actually gets transmitted over the network, representing the real-world bandwidth savings.
|
||||
|
||||
### Bootstrap Component Optimization
|
||||
|
||||
| Component | Before | After | Reduction |
|
||||
|-----------|--------|-------|-----------|
|
||||
| Pagination | 998 | 831 | 17% |
|
||||
| Cards | 428 | 306 | 29% |
|
||||
| Grid System | 253 | 94 | 63% |
|
||||
| Badge | 253 | 0 | 100% (unused) |
|
||||
| Navbar | 171 | 78 | 54% |
|
||||
| Buttons | 145 | 77 | 47% |
|
||||
| Forms | 179 | 70 | 61% |
|
||||
|
||||
### Developer Experience
|
||||
|
||||
**Before:**
|
||||
```
|
||||
Build time: 5-10 seconds
|
||||
DevTools CSS filter: 60 seconds
|
||||
Debugging: No source maps
|
||||
```
|
||||
|
||||
**After:**
|
||||
```
|
||||
Production build: 8-12 seconds
|
||||
Development build: 3-5 seconds (no PurgeCSS)
|
||||
DevTools CSS filter: <1 second
|
||||
Debugging: Source maps in dev mode
|
||||
```
|
||||
|
||||
## Maintenance
|
||||
|
||||
### Adding New Styles
|
||||
|
||||
When adding new component styles:
|
||||
|
||||
1. **Create the SCSS file:**
|
||||
```scss
|
||||
// styles/_my-component.scss
|
||||
.my-component {
|
||||
// styles here
|
||||
}
|
||||
```
|
||||
|
||||
2. **Import in xrpl.scss:**
|
||||
```scss
|
||||
@import "_my-component.scss";
|
||||
```
|
||||
|
||||
3. **If using dynamic classes, update safelist:**
|
||||
```javascript
|
||||
// postcss.config.cjs
|
||||
deep: [
|
||||
/my-component/, // Keeps all .my-component-* classes
|
||||
]
|
||||
```
|
||||
|
||||
4. **Test both builds:**
|
||||
```bash
|
||||
npm run build-css:dev # Test development build
|
||||
npm run build-css # Test production build
|
||||
npm run analyze-css # Check bundle size impact
|
||||
```
|
||||
|
||||
### Troubleshooting Missing Styles
|
||||
|
||||
If styles are missing after a production build:
|
||||
|
||||
1. **Identify the missing class:**
|
||||
```bash
|
||||
# Search for class usage in codebase
|
||||
grep -r "missing-class" .
|
||||
```
|
||||
|
||||
2. **Check if it's dynamically added:**
|
||||
- Bootstrap JavaScript components
|
||||
- React state-based classes
|
||||
- Third-party library classes
|
||||
|
||||
3. **Add to PurgeCSS safelist:**
|
||||
```javascript
|
||||
// postcss.config.cjs
|
||||
safelist: {
|
||||
deep: [
|
||||
/missing-class/, // Preserve this pattern
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
4. **Rebuild and verify:**
|
||||
```bash
|
||||
npm run build-css
|
||||
npm run analyze-css
|
||||
```
|
||||
|
||||
### Monitoring Bundle Size
|
||||
|
||||
Run the analysis tool regularly:
|
||||
|
||||
```bash
|
||||
npm run analyze-css
|
||||
```
|
||||
|
||||
**Watch for:**
|
||||
- Bundle size > 350 KB (indicates regression)
|
||||
- Components with 0 usages (can be removed from Bootstrap import)
|
||||
- Significant selector count increases
|
||||
|
||||
### Future Optimizations
|
||||
|
||||
Potential next steps for further optimization:
|
||||
|
||||
1. **Code Splitting**
|
||||
- Split vendor CSS (Bootstrap) from custom styles
|
||||
- Lazy-load page-specific styles
|
||||
- Critical CSS extraction
|
||||
|
||||
2. **Bootstrap Customization**
|
||||
- Import only needed Bootstrap components
|
||||
- Remove unused variables and mixins
|
||||
- Custom Bootstrap build
|
||||
|
||||
3. **Component-Level CSS**
|
||||
- CSS Modules for page components
|
||||
- CSS-in-JS for dynamic styles
|
||||
- Scoped styles per route
|
||||
|
||||
4. **Advanced Compression**
|
||||
- Brotli compression (88% ratio vs 76% gzip)
|
||||
- CSS splitting by media queries
|
||||
- HTTP/2 server push for critical CSS
|
||||
|
||||
## Migration Notes
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
**None** - This optimization is backward-compatible. All existing classes and styles are preserved.
|
||||
|
||||
### Testing Checklist
|
||||
|
||||
When testing the optimization:
|
||||
|
||||
- [ ] Homepage loads correctly
|
||||
- [ ] Documentation pages display properly
|
||||
- [ ] Blog posts render correctly
|
||||
- [ ] Dev tools (RPC tool, WebSocket tool) function
|
||||
- [ ] Navigation menus work
|
||||
- [ ] Dropdowns and modals open correctly
|
||||
- [ ] Forms are styled properly
|
||||
- [ ] Code syntax highlighting works
|
||||
- [ ] Print styles work
|
||||
- [ ] Light/dark theme switching works
|
||||
|
||||
### Rollback Procedure
|
||||
|
||||
If issues are found:
|
||||
|
||||
1. **Temporarily revert to old build:**
|
||||
```bash
|
||||
# In package.json, change build-css to:
|
||||
"build-css": "sass --load-path styles/scss styles/xrpl.scss ./static/css/devportal2024-v1.css --style compressed --no-source-map"
|
||||
```
|
||||
|
||||
2. **Rebuild:**
|
||||
```bash
|
||||
npm run build-css
|
||||
```
|
||||
|
||||
3. **Report the issue** with:
|
||||
- Missing class names
|
||||
- Page where issue appears
|
||||
- Expected vs actual behavior
|
||||
|
||||
## Resources
|
||||
|
||||
### Documentation
|
||||
|
||||
- [PurgeCSS Documentation](https://purgecss.com/)
|
||||
- [PostCSS Documentation](https://postcss.org/)
|
||||
- [Sass Documentation](https://sass-lang.com/)
|
||||
- [Bootstrap Customization](https://getbootstrap.com/docs/5.3/customize/sass/)
|
||||
|
||||
### Tools
|
||||
|
||||
- `npm run build-css` - Production build
|
||||
- `npm run build-css:dev` - Development build
|
||||
- `npm run build-css:watch` - Watch mode
|
||||
- `npm run analyze-css` - Bundle analysis
|
||||
|
||||
### Files
|
||||
|
||||
- `styles/README.md` - Build process documentation
|
||||
- `postcss.config.cjs` - PostCSS and PurgeCSS configuration
|
||||
- `scripts/analyze-css.js` - Bundle analysis tool
|
||||
- `package.json` - Build scripts
|
||||
|
||||
## Conclusion
|
||||
|
||||
This optimization reduces the CSS bundle by 42% (486 KB → 281 KB), dramatically improving both developer experience and end-user performance. The implementation uses industry-standard tools and maintains full backward compatibility while providing a foundation for future optimizations.
|
||||
|
||||
**Key Takeaways:**
|
||||
- ✅ 42% smaller uncompressed CSS bundle (486 KB → 281 KB)
|
||||
- ✅ 39% smaller gzipped bundle (71 KB → 43 KB network transfer)
|
||||
- ✅ 98% faster DevTools filtering (60s → <1s)
|
||||
- ✅ Modern build tooling (Sass + PostCSS + PurgeCSS)
|
||||
- ✅ Source maps in development mode
|
||||
- ✅ Backward compatible - no breaking changes
|
||||
- ✅ Well documented and maintainable
|
||||
|
||||
---
|
||||
|
||||
*Last updated: October 2025*
|
||||
*Contributors: CSS Optimization Initiative*
|
||||
|
||||
15
_api-examples/path_find/create-followup.json
Normal file
15
_api-examples/path_find/create-followup.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"alternatives": [
|
||||
// ... paths omitted from this example; same format as the initial response ...
|
||||
],
|
||||
"destination_account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"destination_amount": {
|
||||
"currency": "USD",
|
||||
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
|
||||
"value": "0.001"
|
||||
},
|
||||
"full_reply": true,
|
||||
"id": 8,
|
||||
"source_account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"type": "path_find"
|
||||
}
|
||||
75
_api-examples/path_find/create-response.json
Normal file
75
_api-examples/path_find/create-response.json
Normal file
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"id": 8,
|
||||
"result": {
|
||||
"alternatives": [
|
||||
{
|
||||
"paths_computed": [
|
||||
[
|
||||
{
|
||||
"currency": "USD",
|
||||
"issuer": "rKiCet8SdvWxPXnAgYarFUXMh1zCPz432Y",
|
||||
"type": 48
|
||||
},
|
||||
{
|
||||
"account": "rKiCet8SdvWxPXnAgYarFUXMh1zCPz432Y",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"account": "rLzpfEnrB2Ro2LtaGd6Af7znRqGxULc4rW",
|
||||
"type": 1
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"currency": "USD",
|
||||
"issuer": "rKiCet8SdvWxPXnAgYarFUXMh1zCPz432Y",
|
||||
"type": 48
|
||||
},
|
||||
{
|
||||
"account": "rKiCet8SdvWxPXnAgYarFUXMh1zCPz432Y",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"account": "rQhbp2h133vD3TJGWkNY5zePHKQUq6vSVm",
|
||||
"type": 1
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"currency": "USD",
|
||||
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
|
||||
"type": 48
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"currency": "USD",
|
||||
"issuer": "rhub8VRN55s94qWKDv6jmDy1pUykJzF3wq",
|
||||
"type": 48
|
||||
},
|
||||
{
|
||||
"account": "rhub8VRN55s94qWKDv6jmDy1pUykJzF3wq",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"account": "r4cjaKtZqP2GDjwK3eT9qua4Hqk9Zk2kSy",
|
||||
"type": 1
|
||||
}
|
||||
]
|
||||
],
|
||||
"source_amount": "390"
|
||||
}
|
||||
],
|
||||
"destination_account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"destination_amount": {
|
||||
"currency": "USD",
|
||||
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
|
||||
"value": "0.001"
|
||||
},
|
||||
"full_reply": false,
|
||||
"id": 8,
|
||||
"source_account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59"
|
||||
},
|
||||
"status": "success",
|
||||
"type": "response"
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
# Batch
|
||||
|
||||
Code samples showing how to create and submit a [Batch transaction](../../docs/concepts/transactions/batch-transactions.md).
|
||||
Both for simple and multi account batch transactions.
|
||||
Code samples showing how to create and submit a [Batch transaction](https://xrpl.org/docs/concepts/transactions/batch-transactions).
|
||||
|
||||
Both for single and multi-account batch transactions.
|
||||
|
||||
301
_code-samples/batch/js/README.md
Normal file
301
_code-samples/batch/js/README.md
Normal file
@@ -0,0 +1,301 @@
|
||||
# Send a Batch Transaction
|
||||
|
||||
Code samples showing how to create and submit a [Batch transaction](https://xrpl.org/docs/concepts/transactions/batch-transactions) with Javascript.
|
||||
|
||||
Both for single and multi-account batch transactions.
|
||||
|
||||
## Single Account Batch Transaction
|
||||
|
||||
Quick setup and usage:
|
||||
|
||||
```sh
|
||||
npm install xrpl
|
||||
node singleAccountBatch.js
|
||||
```
|
||||
|
||||
The script should output the following:
|
||||
|
||||
```sh
|
||||
=== Funding new wallets from faucet... ===
|
||||
Sender: rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim, Balance: 100 XRP
|
||||
Wallet1: rGx6SACvYEvX8SRrvTPD91UhBmJ16pxL94, Balance: 100 XRP
|
||||
Wallet2: r3qetgSfAtyCpGc4rvKNz4LX3F3urMSJJy, Balance: 100 XRP
|
||||
|
||||
=== Creating Batch transaction... ===
|
||||
{
|
||||
"TransactionType": "Batch",
|
||||
"Account": "rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim",
|
||||
"Flags": 65536,
|
||||
"RawTransactions": [
|
||||
{
|
||||
"RawTransaction": {
|
||||
"TransactionType": "Payment",
|
||||
"Account": "rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim",
|
||||
"Destination": "rGx6SACvYEvX8SRrvTPD91UhBmJ16pxL94",
|
||||
"Amount": "2000000",
|
||||
"Flags": 1073741824
|
||||
}
|
||||
},
|
||||
{
|
||||
"RawTransaction": {
|
||||
"TransactionType": "Payment",
|
||||
"Account": "rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim",
|
||||
"Destination": "r3qetgSfAtyCpGc4rvKNz4LX3F3urMSJJy",
|
||||
"Amount": "5000000",
|
||||
"Flags": 1073741824
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
=== Submitting Batch transaction... ===
|
||||
|
||||
Batch transaction submitted successfully!
|
||||
Result:
|
||||
{
|
||||
"close_time_iso": "2025-11-17T12:04:50Z",
|
||||
"ctid": "C013313800030002",
|
||||
"hash": "AE118213B0A183528418ABC5F14E3BFD6524020C5DB1C060157A0D3FDE15B900",
|
||||
"ledger_hash": "621183809B68A794371C5EC6522105FF04E502C48EBDC8171B80224991E33394",
|
||||
"ledger_index": 1257784,
|
||||
"meta": {
|
||||
"AffectedNodes": [
|
||||
{
|
||||
"ModifiedNode": {
|
||||
"FinalFields": {
|
||||
"Account": "rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim",
|
||||
"Balance": "99999996",
|
||||
"Flags": 0,
|
||||
"OwnerCount": 0,
|
||||
"Sequence": 1257779
|
||||
},
|
||||
"LedgerEntryType": "AccountRoot",
|
||||
"LedgerIndex": "42CC98AF0A28EDDDC7E359B5622CC5748BDE2A93E124AF5C32647ECA8F68D480",
|
||||
"PreviousFields": {
|
||||
"Balance": "100000000",
|
||||
"Sequence": 1257778
|
||||
},
|
||||
"PreviousTxnID": "081C42DAE12001735AC4E9A7F027636DF612DB17B4BFA2333F4DB8EA0C9D1E9F",
|
||||
"PreviousTxnLgrSeq": 1257778
|
||||
}
|
||||
}
|
||||
],
|
||||
"TransactionIndex": 3,
|
||||
"TransactionResult": "tesSUCCESS"
|
||||
},
|
||||
"tx_json": {
|
||||
"Account": "rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim",
|
||||
"Fee": "4",
|
||||
"Flags": 65536,
|
||||
"LastLedgerSequence": 1257802,
|
||||
"RawTransactions": [
|
||||
{
|
||||
"RawTransaction": {
|
||||
"Account": "rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim",
|
||||
"Amount": "2000000",
|
||||
"Destination": "rGx6SACvYEvX8SRrvTPD91UhBmJ16pxL94",
|
||||
"Fee": "0",
|
||||
"Flags": 1073741824,
|
||||
"Sequence": 1257779,
|
||||
"SigningPubKey": "",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
},
|
||||
{
|
||||
"RawTransaction": {
|
||||
"Account": "rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim",
|
||||
"Amount": "5000000",
|
||||
"Destination": "r3qetgSfAtyCpGc4rvKNz4LX3F3urMSJJy",
|
||||
"Fee": "0",
|
||||
"Flags": 1073741824,
|
||||
"Sequence": 1257780,
|
||||
"SigningPubKey": "",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
}
|
||||
],
|
||||
"Sequence": 1257778,
|
||||
"SigningPubKey": "ED7031CA5BA4EC745610AB495F5053F318C119E87567BE485A494773AD8ED4FBCE",
|
||||
"TransactionType": "Batch",
|
||||
"TxnSignature": "0610A277086943BC462C1A5F85BEB667B62B4BDA59525138B6014101C08297897A73D3D2D247CB37A06E1EA36267C53A51C0FDF32F3D8E974029BEDC41105B07",
|
||||
"ctid": "C013313800030002",
|
||||
"date": 816696290,
|
||||
"ledger_index": 1257784
|
||||
},
|
||||
"validated": true
|
||||
}
|
||||
|
||||
Batch transaction URL:
|
||||
https://devnet.xrpl.org/transactions/AE118213B0A183528418ABC5F14E3BFD6524020C5DB1C060157A0D3FDE15B900
|
||||
|
||||
=== Verifying inner transactions... ===
|
||||
|
||||
Transaction 1 hash: D18EA54D5653BBB5C87F116978822EAB7A26EDFB1D6C41910F36D7484D4890E3
|
||||
- Status: tesSUCCESS (Ledger 1257784)
|
||||
- Transaction URL: https://devnet.xrpl.org/transactions/D18EA54D5653BBB5C87F116978822EAB7A26EDFB1D6C41910F36D7484D4890E3
|
||||
|
||||
Transaction 2 hash: 5660DB400F08EE5543C54D4D65824A2142F9D5AC17294A4ABF654260F129B44E
|
||||
- Status: tesSUCCESS (Ledger 1257784)
|
||||
- Transaction URL: https://devnet.xrpl.org/transactions/5660DB400F08EE5543C54D4D65824A2142F9D5AC17294A4ABF654260F129B44E
|
||||
|
||||
=== Final balances ===
|
||||
Sender: rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim, Balance: 92.999996 XRP
|
||||
Wallet1: rGx6SACvYEvX8SRrvTPD91UhBmJ16pxL94, Balance: 102 XRP
|
||||
Wallet2: r3qetgSfAtyCpGc4rvKNz4LX3F3urMSJJy, Balance: 105 XRP
|
||||
```
|
||||
|
||||
## Multi-Account Batch Transaction
|
||||
|
||||
```sh
|
||||
npm install xrpl
|
||||
node multiAccountBatch.js
|
||||
```
|
||||
|
||||
The script should output the following:
|
||||
|
||||
```sh
|
||||
=== Funding new wallets from faucet... ===
|
||||
Alice: rHpve1GL2ZXUs3NB5iU91BrXBSwb5PbBrG, Balance: 100 XRP
|
||||
Bob: r3ruQ92bqXwWxcR2w4cC1tW35og9h3UbBq, Balance: 100 XRP
|
||||
Charlie: rsi5D9bkczpbGykPxoGNBVVmFFFXGwm3QA, Balance: 100 XRP
|
||||
Third-party wallet: rfUpGXTzU3siTr4UovV6Wt86Vw3gQU4ttA, Balance: 100 XRP
|
||||
|
||||
=== Creating Batch transaction... ===
|
||||
{
|
||||
"TransactionType": "Batch",
|
||||
"Account": "rfUpGXTzU3siTr4UovV6Wt86Vw3gQU4ttA",
|
||||
"Flags": 65536,
|
||||
"RawTransactions": [
|
||||
{
|
||||
"RawTransaction": {
|
||||
"TransactionType": "Payment",
|
||||
"Account": "rsi5D9bkczpbGykPxoGNBVVmFFFXGwm3QA",
|
||||
"Destination": "rHpve1GL2ZXUs3NB5iU91BrXBSwb5PbBrG",
|
||||
"Amount": "50000000",
|
||||
"Flags": 1073741824
|
||||
}
|
||||
},
|
||||
{
|
||||
"RawTransaction": {
|
||||
"TransactionType": "Payment",
|
||||
"Account": "r3ruQ92bqXwWxcR2w4cC1tW35og9h3UbBq",
|
||||
"Destination": "rHpve1GL2ZXUs3NB5iU91BrXBSwb5PbBrG",
|
||||
"Amount": "50000000",
|
||||
"Flags": 1073741824
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
=== Submitting Batch transaction... ===
|
||||
|
||||
Batch transaction submitted successfully!
|
||||
Result:
|
||||
{
|
||||
"close_time_iso": "2025-11-17T12:08:31Z",
|
||||
"ctid": "C013317600000002",
|
||||
"hash": "1299D20C6B489DA5C632AE4DBE49475DBF42D9444C7E9C109CC9B8DD0FD55FEC",
|
||||
"ledger_hash": "E45ECF69057084CD02BA49A17E4D0C9154D33A98BB3C95A11B2EB9BE18F32C9B",
|
||||
"ledger_index": 1257846,
|
||||
"meta": {
|
||||
"AffectedNodes": [
|
||||
{
|
||||
"ModifiedNode": {
|
||||
"FinalFields": {
|
||||
"Account": "rfUpGXTzU3siTr4UovV6Wt86Vw3gQU4ttA",
|
||||
"Balance": "99999994",
|
||||
"Flags": 0,
|
||||
"OwnerCount": 0,
|
||||
"Sequence": 1257845
|
||||
},
|
||||
"LedgerEntryType": "AccountRoot",
|
||||
"LedgerIndex": "2D9E0A02007241C38A8DF679E7E62AA0B273E8B12A5430B7B9D99300424F0E1F",
|
||||
"PreviousFields": {
|
||||
"Balance": "100000000",
|
||||
"Sequence": 1257844
|
||||
},
|
||||
"PreviousTxnID": "3153DE8DE922538A6BE54AA8F783CAD4B848A321AFF028D3E6DD0E80C4B9C237",
|
||||
"PreviousTxnLgrSeq": 1257844
|
||||
}
|
||||
}
|
||||
],
|
||||
"TransactionIndex": 0,
|
||||
"TransactionResult": "tesSUCCESS"
|
||||
},
|
||||
"tx_json": {
|
||||
"Account": "rfUpGXTzU3siTr4UovV6Wt86Vw3gQU4ttA",
|
||||
"BatchSigners": [
|
||||
{
|
||||
"BatchSigner": {
|
||||
"Account": "rsi5D9bkczpbGykPxoGNBVVmFFFXGwm3QA",
|
||||
"SigningPubKey": "EDEB88C2868BD25BF03DB26050E16579FA6F8F9E3FF3172E0DC3DCBDA5408572EB",
|
||||
"TxnSignature": "9508568084596147CFDCFC18A62DC298A78AD1148BA4B0EB99BEE1CD37E5555FE3930810790D5708F9739B0E3F79772012C154CA33C2280BDD5B72473C17A607"
|
||||
}
|
||||
},
|
||||
{
|
||||
"BatchSigner": {
|
||||
"Account": "r3ruQ92bqXwWxcR2w4cC1tW35og9h3UbBq",
|
||||
"SigningPubKey": "ED82F98DA6A3FC3E88D2EE3A5469D92C7070513BEF4DEE75CAB0BDAA81E8AE378D",
|
||||
"TxnSignature": "A482C8747F79857530474F1677599766C0BE283CB7E2A05AACF76E61BECCA16DCE3802D2D8244FBF4546A1C0E5EB70691255E3EFD2F8AC80B55357BDAB9ACD05"
|
||||
}
|
||||
}
|
||||
],
|
||||
"Fee": "6",
|
||||
"Flags": 65536,
|
||||
"LastLedgerSequence": 1257864,
|
||||
"RawTransactions": [
|
||||
{
|
||||
"RawTransaction": {
|
||||
"Account": "rsi5D9bkczpbGykPxoGNBVVmFFFXGwm3QA",
|
||||
"Amount": "50000000",
|
||||
"Destination": "rHpve1GL2ZXUs3NB5iU91BrXBSwb5PbBrG",
|
||||
"Fee": "0",
|
||||
"Flags": 1073741824,
|
||||
"Sequence": 1257842,
|
||||
"SigningPubKey": "",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
},
|
||||
{
|
||||
"RawTransaction": {
|
||||
"Account": "r3ruQ92bqXwWxcR2w4cC1tW35og9h3UbBq",
|
||||
"Amount": "50000000",
|
||||
"Destination": "rHpve1GL2ZXUs3NB5iU91BrXBSwb5PbBrG",
|
||||
"Fee": "0",
|
||||
"Flags": 1073741824,
|
||||
"Sequence": 1257841,
|
||||
"SigningPubKey": "",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
}
|
||||
],
|
||||
"Sequence": 1257844,
|
||||
"SigningPubKey": "ED22A32B61EDF083315515831723BC18F8311F03886BBA375DFF46335BB7A75F0B",
|
||||
"TransactionType": "Batch",
|
||||
"TxnSignature": "156791D2DBFAEFC9B0AC29F2D8D0CDB25E13F92E70E6D5414FE31BD8573CA23D3F62F8B34FC1F117BD556B25E4F748095A24C4342108AB32F1B2BAFBF1443501",
|
||||
"ctid": "C013317600000002",
|
||||
"date": 816696511,
|
||||
"ledger_index": 1257846
|
||||
},
|
||||
"validated": true
|
||||
}
|
||||
|
||||
Batch transaction URL:
|
||||
https://devnet.xrpl.org/transactions/1299D20C6B489DA5C632AE4DBE49475DBF42D9444C7E9C109CC9B8DD0FD55FEC
|
||||
|
||||
=== Verifying inner transactions ===
|
||||
|
||||
Transaction 1 hash: 0F71979E3F641C980929F926640DCA886C30236ED0CD7C94B6CB36F0D42948AC
|
||||
- Status: tesSUCCESS (Ledger 1257846)
|
||||
- Transaction URL: https://devnet.xrpl.org/transactions/0F71979E3F641C980929F926640DCA886C30236ED0CD7C94B6CB36F0D42948AC
|
||||
|
||||
Transaction 2 hash: BC124CB29334AA1079139A9BE186B69A0AC467797F147754E2406714854D2A50
|
||||
- Status: tesSUCCESS (Ledger 1257846)
|
||||
- Transaction URL: https://devnet.xrpl.org/transactions/BC124CB29334AA1079139A9BE186B69A0AC467797F147754E2406714854D2A50
|
||||
|
||||
=== Final balances ===
|
||||
Alice: rHpve1GL2ZXUs3NB5iU91BrXBSwb5PbBrG, Balance: 200 XRP
|
||||
Bob: r3ruQ92bqXwWxcR2w4cC1tW35og9h3UbBq, Balance: 50 XRP
|
||||
Charlie: rsi5D9bkczpbGykPxoGNBVVmFFFXGwm3QA, Balance: 50 XRP
|
||||
Third-party wallet: rfUpGXTzU3siTr4UovV6Wt86Vw3gQU4ttA, Balance: 99.999994 XRP
|
||||
```
|
||||
143
_code-samples/batch/js/multiAccountBatch.js
Normal file
143
_code-samples/batch/js/multiAccountBatch.js
Normal file
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* XRP Ledger Batch Transactions Tutorial
|
||||
*
|
||||
* This tutorial demonstrates how to use the Batch transaction feature (XLS-56)
|
||||
* to perform a multi-account batch transaction.
|
||||
* Concept doc: https://xrpl.org/docs/concepts/transactions/batch-transactions
|
||||
* Reference doc: https://xrpl.org/docs/references/protocol/transactions/types/batch
|
||||
*/
|
||||
|
||||
import xrpl from "xrpl"
|
||||
|
||||
const client = new xrpl.Client("wss://s.devnet.rippletest.net:51233/")
|
||||
await client.connect()
|
||||
|
||||
// Create and fund wallets
|
||||
console.log("=== Funding new wallets from faucet... ===");
|
||||
const [
|
||||
{ wallet: alice },
|
||||
{ wallet: bob },
|
||||
{ wallet: charlie },
|
||||
{ wallet: thirdPartyWallet },
|
||||
] = await Promise.all([
|
||||
client.fundWallet(),
|
||||
client.fundWallet(),
|
||||
client.fundWallet(),
|
||||
client.fundWallet(),
|
||||
]);
|
||||
|
||||
console.log(`Alice: ${alice.address}, Balance: ${await client.getXrpBalance(alice.address)} XRP`)
|
||||
console.log(`Bob: ${bob.address}, Balance: ${await client.getXrpBalance(bob.address)} XRP`)
|
||||
console.log(`Charlie: ${charlie.address}, Balance: ${await client.getXrpBalance(charlie.address)} XRP`)
|
||||
console.log(`Third-party wallet: ${thirdPartyWallet.address}, Balance: ${await client.getXrpBalance(thirdPartyWallet.address)} XRP`)
|
||||
|
||||
// Create inner transactions --------------------------------------------
|
||||
// REQUIRED: Inner transactions MUST have the tfInnerBatchTxn flag (0x40000000).
|
||||
// This marks them as part of a batch (requires Fee: 0 and empty SigningPubKey).
|
||||
|
||||
// Transaction 1: Charlie pays Alice
|
||||
const charliePayment = {
|
||||
TransactionType: "Payment",
|
||||
Account: charlie.address,
|
||||
Destination: alice.address,
|
||||
Amount: xrpl.xrpToDrops(50),
|
||||
Flags: xrpl.GlobalFlags.tfInnerBatchTxn // THIS IS REQUIRED
|
||||
}
|
||||
|
||||
// Transaction 2: Bob pays Alice
|
||||
const bobPayment = {
|
||||
TransactionType: "Payment",
|
||||
Account: bob.address,
|
||||
Destination: alice.address,
|
||||
Amount: xrpl.xrpToDrops(50),
|
||||
Flags: xrpl.GlobalFlags.tfInnerBatchTxn // THIS IS REQUIRED
|
||||
}
|
||||
|
||||
// Send Batch transaction --------------------------------------------
|
||||
console.log("\n=== Creating Batch transaction... ===")
|
||||
const batchTx = {
|
||||
TransactionType: "Batch",
|
||||
Account: thirdPartyWallet.address,
|
||||
Flags: xrpl.BatchFlags.tfAllOrNothing, // tfAllOrNothing: All inner transactions must succeed
|
||||
// Must include a minimum of 2 transactions and a maximum of 8 transactions.
|
||||
RawTransactions: [
|
||||
{ RawTransaction: charliePayment },
|
||||
{ RawTransaction: bobPayment },
|
||||
]
|
||||
}
|
||||
console.log(JSON.stringify(batchTx, null, 2))
|
||||
|
||||
// Validate the transaction structure
|
||||
xrpl.validate(batchTx)
|
||||
|
||||
// Set the expected number of signers, which is 2 (Bob and Charlie) in this case, for this transaction.
|
||||
// "autofill" will automatically add Fee: "0" and SigningPubKey: "" to inner transactions.
|
||||
const autofilledBatchTx = await client.autofill(batchTx, 2)
|
||||
|
||||
// Gather batch signatures --------------------------------
|
||||
// Each signer needs their own tx copy because signMultiBatch modifies the object.
|
||||
// Charlie signs the Batch transaction
|
||||
const charlieBatch = { ...autofilledBatchTx }
|
||||
xrpl.signMultiBatch(charlie, charlieBatch)
|
||||
|
||||
// Bob signs the Batch transaction
|
||||
const bobBatch = { ...autofilledBatchTx }
|
||||
xrpl.signMultiBatch(bob, bobBatch)
|
||||
|
||||
// Combine inner transaction signatures.
|
||||
// This returns a signed transaction blob (hex string) ready for submission.
|
||||
const combinedSignedTx = xrpl.combineBatchSigners([charlieBatch, bobBatch])
|
||||
|
||||
// Submit the signed blob with the third-party's wallet
|
||||
console.log("\n=== Submitting Batch transaction... ===")
|
||||
const submitResponse = await client.submitAndWait(combinedSignedTx,
|
||||
{ wallet: thirdPartyWallet }
|
||||
)
|
||||
|
||||
// Check Batch transaction result --------------------------------
|
||||
if (submitResponse.result.meta.TransactionResult !== "tesSUCCESS") {
|
||||
const resultCode = submitResponse.result.meta.TransactionResult
|
||||
console.warn(`\nTransaction failed with result code ${resultCode}`)
|
||||
await client.disconnect()
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
console.log("\nBatch transaction submitted successfully!")
|
||||
console.log("Result:\n", JSON.stringify(submitResponse.result, null, 2))
|
||||
// View the transaction on the XRPL Explorer
|
||||
console.log(`\nBatch transaction URL:\nhttps://devnet.xrpl.org/transactions/${submitResponse.result.hash}`)
|
||||
|
||||
// Calculate and verify inner transaction hashes --------------------------------------------
|
||||
console.log("\n=== Verifying inner transactions ===")
|
||||
const rawTransactions = submitResponse.result.tx_json.RawTransactions
|
||||
let hasFailure = false
|
||||
|
||||
for (let i = 0; i < rawTransactions.length; i++) {
|
||||
const innerTx = rawTransactions[i].RawTransaction
|
||||
const hash = xrpl.hashes.hashSignedTx(innerTx)
|
||||
console.log(`\nTransaction ${i + 1} hash: ${hash}`)
|
||||
|
||||
try {
|
||||
const tx = await client.request({ command: 'tx', transaction: hash })
|
||||
const status = tx.result.meta?.TransactionResult
|
||||
console.log(` - Status: ${status} (Ledger ${tx.result.ledger_index})`)
|
||||
console.log(` - Transaction URL: https://devnet.xrpl.org/transactions/${hash}`)
|
||||
} catch (error) {
|
||||
hasFailure = true
|
||||
console.log(` - Transaction not found: ${error}`)
|
||||
}
|
||||
}
|
||||
if (hasFailure) {
|
||||
console.error("\n--- Error: One or more inner transactions failed. ---")
|
||||
await client.disconnect()
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Verify balances after transaction
|
||||
console.log("\n=== Final balances ===")
|
||||
console.log(`Alice: ${alice.address}, Balance: ${await client.getXrpBalance(alice.address)} XRP`)
|
||||
console.log(`Bob: ${bob.address}, Balance: ${await client.getXrpBalance(bob.address)} XRP`)
|
||||
console.log(`Charlie: ${charlie.address}, Balance: ${await client.getXrpBalance(charlie.address)} XRP`)
|
||||
console.log(`Third-party wallet: ${thirdPartyWallet.address}, Balance: ${await client.getXrpBalance(thirdPartyWallet.address)} XRP`)
|
||||
|
||||
await client.disconnect()
|
||||
6
_code-samples/batch/js/package.json
Normal file
6
_code-samples/batch/js/package.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"xrpl": "^4.4.3"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
120
_code-samples/batch/js/singleAccountBatch.js
Normal file
120
_code-samples/batch/js/singleAccountBatch.js
Normal file
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* Single Account Batch Transaction Example
|
||||
*
|
||||
* This example demonstrates how to use the Batch transactions feature (XLS-56)
|
||||
* to create a single-account batch transaction that sends payments
|
||||
* to multiple destinations in one atomic operation.
|
||||
* Concept doc: https://xrpl.org/docs/concepts/transactions/batch-transactions
|
||||
* Reference doc: https://xrpl.org/docs/references/protocol/transactions/types/batch
|
||||
*/
|
||||
|
||||
import xrpl from "xrpl"
|
||||
|
||||
const client = new xrpl.Client("wss://s.devnet.rippletest.net:51233/")
|
||||
await client.connect()
|
||||
|
||||
// Create and fund wallets
|
||||
console.log("=== Funding new wallets from faucet... ===");
|
||||
const [{ wallet: sender }, { wallet: wallet1 }, { wallet: wallet2 }] =
|
||||
await Promise.all([
|
||||
client.fundWallet(),
|
||||
client.fundWallet(),
|
||||
client.fundWallet(),
|
||||
]);
|
||||
|
||||
console.log(`Sender: ${sender.address}, Balance: ${await client.getXrpBalance(sender.address)} XRP`)
|
||||
console.log(`Wallet1: ${wallet1.address}, Balance: ${await client.getXrpBalance(wallet1.address)} XRP`)
|
||||
console.log(`Wallet2: ${wallet2.address}, Balance: ${await client.getXrpBalance(wallet2.address)} XRP`)
|
||||
|
||||
// Create inner transactions --------------------------------------------
|
||||
// REQUIRED: Inner transactions MUST have the tfInnerBatchTxn flag (0x40000000).
|
||||
// This marks them as part of a batch (requires Fee: 0 and empty SigningPubKey).
|
||||
|
||||
// Transaction 1
|
||||
const payment1 = {
|
||||
TransactionType: "Payment",
|
||||
Account: sender.address,
|
||||
Destination: wallet1.address,
|
||||
Amount: xrpl.xrpToDrops(2),
|
||||
Flags: xrpl.GlobalFlags.tfInnerBatchTxn // THIS IS REQUIRED
|
||||
}
|
||||
|
||||
// Transaction 2
|
||||
const payment2 = {
|
||||
TransactionType: "Payment",
|
||||
Account: sender.address,
|
||||
Destination: wallet2.address,
|
||||
Amount: xrpl.xrpToDrops(5),
|
||||
Flags: xrpl.GlobalFlags.tfInnerBatchTxn // THIS IS REQUIRED
|
||||
}
|
||||
|
||||
// Send Batch transaction --------------------------------------------
|
||||
console.log("\n=== Creating Batch transaction... ===")
|
||||
const batchTx = {
|
||||
TransactionType: "Batch",
|
||||
Account: sender.address,
|
||||
Flags: xrpl.BatchFlags.tfAllOrNothing, // tfAllOrNothing: All inner transactions must succeed
|
||||
// Must include a minimum of 2 transactions and a maximum of 8 transactions.
|
||||
RawTransactions: [
|
||||
{ RawTransaction: payment1 },
|
||||
{ RawTransaction: payment2 }
|
||||
]
|
||||
}
|
||||
console.log(JSON.stringify(batchTx, null, 2))
|
||||
|
||||
// Validate the transaction structure before submitting
|
||||
xrpl.validate(batchTx)
|
||||
|
||||
// Submit and wait for validation
|
||||
console.log("\n=== Submitting Batch transaction... ===")
|
||||
const submitResponse = await client.submitAndWait(batchTx, {
|
||||
wallet: sender,
|
||||
// "autofill" will automatically add Fee: "0" and SigningPubKey: "" to inner transactions.
|
||||
autofill: true
|
||||
})
|
||||
|
||||
// Check Batch transaction result --------------------------------
|
||||
if (submitResponse.result.meta.TransactionResult !== "tesSUCCESS") {
|
||||
const resultCode = submitResponse.result.meta.TransactionResult
|
||||
console.warn(`\nTransaction failed with result code ${resultCode}`)
|
||||
await client.disconnect()
|
||||
process.exit(1)
|
||||
}
|
||||
console.log("\nBatch transaction submitted successfully!")
|
||||
console.log("Result:\n", JSON.stringify(submitResponse.result, null, 2))
|
||||
// View the batch transaction on the XRPL Explorer
|
||||
console.log(`\nBatch transaction URL:\nhttps://devnet.xrpl.org/transactions/${submitResponse.result.hash}`)
|
||||
|
||||
// Calculate and verify inner transaction hashes --------------------------------------------
|
||||
console.log("\n=== Verifying inner transactions... ===")
|
||||
const rawTransactions = submitResponse.result.tx_json.RawTransactions
|
||||
let hasFailure = false
|
||||
|
||||
for (let i = 0; i < rawTransactions.length; i++) {
|
||||
const innerTx = rawTransactions[i].RawTransaction
|
||||
const hash = xrpl.hashes.hashSignedTx(innerTx)
|
||||
console.log(`\nTransaction ${i + 1} hash: ${hash}`)
|
||||
|
||||
try {
|
||||
const tx = await client.request({ command: 'tx', transaction: hash })
|
||||
const status = tx.result.meta?.TransactionResult
|
||||
console.log(` - Status: ${status} (Ledger ${tx.result.ledger_index})`)
|
||||
console.log(` - Transaction URL: https://devnet.xrpl.org/transactions/${hash}`)
|
||||
} catch (error) {
|
||||
hasFailure = true
|
||||
console.log(` - Transaction not found: ${error}`)
|
||||
}
|
||||
}
|
||||
if (hasFailure) {
|
||||
console.error("\n--- Error: One or more inner transactions failed. ---")
|
||||
await client.disconnect()
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Verify balances after transaction
|
||||
console.log("\n=== Final balances ===")
|
||||
console.log(`Sender: ${sender.address}, Balance: ${await client.getXrpBalance(sender.address)} XRP`)
|
||||
console.log(`Wallet1: ${wallet1.address}, Balance: ${await client.getXrpBalance(wallet1.address)} XRP`)
|
||||
console.log(`Wallet2: ${wallet2.address}, Balance: ${await client.getXrpBalance(wallet2.address)} XRP`)
|
||||
|
||||
await client.disconnect()
|
||||
@@ -92,7 +92,7 @@
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title subhead-sm-r" id="send-xrp-modal-label">Send XRP</h1>
|
||||
<h1 class="modal-title fs-5" id="send-xrp-modal-label">Send XRP</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title subhead-sm-r" id="send-xrp-modal-label">Send XRP</h1>
|
||||
<h1 class="modal-title fs-5" id="send-xrp-modal-label">Send XRP</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
module github.com/XRPLF
|
||||
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.10
|
||||
go 1.24.0
|
||||
|
||||
require github.com/Peersyst/xrpl-go v0.1.11
|
||||
|
||||
@@ -20,5 +18,5 @@ require (
|
||||
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
golang.org/x/crypto v0.35.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
)
|
||||
|
||||
@@ -46,8 +46,8 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ
|
||||
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Create AMM
|
||||
|
||||
Code samples for the [Create an Automated Market Maker tutorial](../../docs/tutorials/how-tos/use-tokens/create-an-automated-market-maker.md), showing how to make set up a new AMM.
|
||||
Code samples for the [Create an Automated Market Maker tutorial](../../docs/tutorials/dex/create-an-automated-market-maker.md), showing how to make set up a new AMM.
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
module github.com/XRPLF
|
||||
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.10
|
||||
go 1.24.0
|
||||
|
||||
require github.com/Peersyst/xrpl-go v0.1.11
|
||||
|
||||
@@ -20,5 +18,5 @@ require (
|
||||
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
golang.org/x/crypto v0.35.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
)
|
||||
|
||||
@@ -46,8 +46,8 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ
|
||||
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
module github.com/XRPLF
|
||||
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.10
|
||||
go 1.24.0
|
||||
|
||||
require github.com/Peersyst/xrpl-go v0.1.11
|
||||
|
||||
@@ -20,5 +18,5 @@ require (
|
||||
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
golang.org/x/crypto v0.35.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
)
|
||||
|
||||
@@ -46,8 +46,8 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ
|
||||
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
||||
62
_code-samples/get-started/py/README.md
Normal file
62
_code-samples/get-started/py/README.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Get Started Using Python Library
|
||||
|
||||
Connects to the XRP Ledger and gets account information using Python.
|
||||
|
||||
To download the source code, see [Get Started Using Python Library](http://xrpl.org/docs/tutorials/python/build-apps/get-started).
|
||||
|
||||
## Run the Code
|
||||
|
||||
Quick setup and usage:
|
||||
|
||||
```sh
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
python ./get-acct-info.py
|
||||
```
|
||||
|
||||
You should see output similar to the following:
|
||||
|
||||
```sh
|
||||
Creating a new wallet and funding it with Testnet XRP...
|
||||
Attempting to fund address ravbHNootpSNQkxyEFCWevSkHsFGDHfyop
|
||||
Faucet fund successful.
|
||||
Wallet: ravbHNootpSNQkxyEFCWevSkHsFGDHfyop
|
||||
Account Testnet Explorer URL:
|
||||
https://testnet.xrpl.org/accounts/ravbHNootpSNQkxyEFCWevSkHsFGDHfyop
|
||||
|
||||
Getting account info...
|
||||
Response Status: ResponseStatus.SUCCESS
|
||||
{
|
||||
"account_data": {
|
||||
"Account": "ravbHNootpSNQkxyEFCWevSkHsFGDHfyop",
|
||||
"Balance": "100000000",
|
||||
"Flags": 0,
|
||||
"LedgerEntryType": "AccountRoot",
|
||||
"OwnerCount": 0,
|
||||
"PreviousTxnID": "3DACF2438AD39F294C4EFF6132D5D88BCB65D2F2261C7650F40AC1F6A54C83EA",
|
||||
"PreviousTxnLgrSeq": 12039759,
|
||||
"Sequence": 12039759,
|
||||
"index": "148E6F4B8E4C14018D679A2526200C292BDBC5AB77611BC3AE0CB97CD2FB84E5"
|
||||
},
|
||||
"account_flags": {
|
||||
"allowTrustLineClawback": false,
|
||||
"defaultRipple": false,
|
||||
"depositAuth": false,
|
||||
"disableMasterKey": false,
|
||||
"disallowIncomingCheck": false,
|
||||
"disallowIncomingNFTokenOffer": false,
|
||||
"disallowIncomingPayChan": false,
|
||||
"disallowIncomingTrustline": false,
|
||||
"disallowIncomingXRP": false,
|
||||
"globalFreeze": false,
|
||||
"noFreeze": false,
|
||||
"passwordSpent": false,
|
||||
"requireAuthorization": false,
|
||||
"requireDestinationTag": false
|
||||
},
|
||||
"ledger_hash": "CA624D717C4FCDD03BAD8C193F374A77A14F7D2566354A4E9617A8DAD896DE71",
|
||||
"ledger_index": 12039759,
|
||||
"validated": true
|
||||
}
|
||||
```
|
||||
@@ -1,34 +1,39 @@
|
||||
# @chunk {"steps": ["connect-tag"]}
|
||||
# Define the network client
|
||||
from xrpl.clients import JsonRpcClient
|
||||
from xrpl.wallet import generate_faucet_wallet
|
||||
from xrpl.core import addresscodec
|
||||
from xrpl.models.requests.account_info import AccountInfo
|
||||
import json
|
||||
|
||||
JSON_RPC_URL = "https://s.altnet.rippletest.net:51234/"
|
||||
client = JsonRpcClient(JSON_RPC_URL)
|
||||
# @chunk-end
|
||||
|
||||
|
||||
# Create a wallet using the testnet faucet:
|
||||
# @chunk {"steps": ["get-account-create-wallet-tag"]}
|
||||
# Create a wallet using the Testnet faucet:
|
||||
# https://xrpl.org/xrp-testnet-faucet.html
|
||||
from xrpl.wallet import generate_faucet_wallet
|
||||
print("\nCreating a new wallet and funding it with Testnet XRP...")
|
||||
test_wallet = generate_faucet_wallet(client, debug=True)
|
||||
|
||||
# Create an account str from the wallet
|
||||
test_account = test_wallet.address
|
||||
|
||||
# Derive an x-address from the classic address:
|
||||
# https://xrpaddress.info/
|
||||
from xrpl.core import addresscodec
|
||||
test_xaddress = addresscodec.classic_address_to_xaddress(test_account, tag=12345, is_test_network=True)
|
||||
print("\nClassic address:\n\n", test_account)
|
||||
print("X-address:\n\n", test_xaddress)
|
||||
test_account = test_wallet.classic_address
|
||||
print(f"Wallet: {test_account}")
|
||||
print(f"Account Testnet Explorer URL: ")
|
||||
print(f" https://testnet.xrpl.org/accounts/{test_account}")
|
||||
# @chunk-end
|
||||
|
||||
|
||||
# @chunk {"steps": ["query-xrpl-tag"]}
|
||||
# Look up info about your account
|
||||
from xrpl.models.requests.account_info import AccountInfo
|
||||
print("\nGetting account info...")
|
||||
acct_info = AccountInfo(
|
||||
account=test_account,
|
||||
ledger_index="validated",
|
||||
strict=True,
|
||||
)
|
||||
|
||||
response = client.request(acct_info)
|
||||
result = response.result
|
||||
print("response.status: ", response.status)
|
||||
import json
|
||||
print("Response Status: ", response.status)
|
||||
print(json.dumps(response.result, indent=4, sort_keys=True))
|
||||
# @chunk-end
|
||||
|
||||
1
_code-samples/get-started/py/requirements.txt
Normal file
1
_code-samples/get-started/py/requirements.txt
Normal file
@@ -0,0 +1 @@
|
||||
xrpl-py==4.3.0
|
||||
@@ -1,8 +1,6 @@
|
||||
module github.com/XRPLF
|
||||
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.10
|
||||
go 1.24.0
|
||||
|
||||
require github.com/Peersyst/xrpl-go v0.1.11
|
||||
|
||||
@@ -20,5 +18,5 @@ require (
|
||||
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
golang.org/x/crypto v0.35.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
)
|
||||
|
||||
@@ -46,8 +46,8 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ
|
||||
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
||||
@@ -10,26 +10,26 @@ const { wallet } = await client.fundWallet()
|
||||
|
||||
// Define metadata as JSON
|
||||
const mpt_metadata = {
|
||||
ticker: 'TBILL',
|
||||
name: 'T-Bill Yield Token',
|
||||
desc: 'A yield-bearing stablecoin backed by short-term U.S. Treasuries and money market instruments.',
|
||||
icon: 'https://example.org/tbill-icon.png',
|
||||
asset_class: 'rwa',
|
||||
asset_subclass: 'treasury',
|
||||
issuer_name: 'Example Yield Co.',
|
||||
urls: [
|
||||
t: 'TBILL',
|
||||
n: 'T-Bill Yield Token',
|
||||
d: 'A yield-bearing stablecoin backed by short-term U.S. Treasuries and money market instruments.',
|
||||
i: 'https://example.org/tbill-icon.png',
|
||||
ac: 'rwa',
|
||||
as: 'treasury',
|
||||
in: 'Example Yield Co.',
|
||||
us: [
|
||||
{
|
||||
url: 'https://exampleyield.co/tbill',
|
||||
type: 'website',
|
||||
title: 'Product Page'
|
||||
u: 'https://exampleyield.co/tbill',
|
||||
c: 'website',
|
||||
t: 'Product Page'
|
||||
},
|
||||
{
|
||||
url: 'https://exampleyield.co/docs',
|
||||
type: 'docs',
|
||||
title: 'Yield Token Docs'
|
||||
u: 'https://exampleyield.co/docs',
|
||||
c: 'docs',
|
||||
t: 'Yield Token Docs'
|
||||
}
|
||||
],
|
||||
additional_info: {
|
||||
ai: {
|
||||
interest_rate: '5.00%',
|
||||
interest_type: 'variable',
|
||||
yield_source: 'U.S. Treasury Bills',
|
||||
|
||||
@@ -12,26 +12,26 @@ wallet = generate_faucet_wallet(client, debug=True)
|
||||
|
||||
# Define metadata as JSON
|
||||
mpt_metadata = {
|
||||
"ticker": "TBILL",
|
||||
"name": "T-Bill Yield Token",
|
||||
"desc": "A yield-bearing stablecoin backed by short-term U.S. Treasuries and money market instruments.",
|
||||
"icon": "https://example.org/tbill-icon.png",
|
||||
"asset_class": "rwa",
|
||||
"asset_subclass": "treasury",
|
||||
"issuer_name": "Example Yield Co.",
|
||||
"urls": [
|
||||
"t": "TBILL",
|
||||
"n": "T-Bill Yield Token",
|
||||
"d": "A yield-bearing stablecoin backed by short-term U.S. Treasuries and money market instruments.",
|
||||
"i": "example.org/tbill-icon.png",
|
||||
"ac": "rwa",
|
||||
"as": "treasury",
|
||||
"in": "Example Yield Co.",
|
||||
"us": [
|
||||
{
|
||||
"url": "https://exampleyield.co/tbill",
|
||||
"type": "website",
|
||||
"title": "Product Page"
|
||||
"u": "exampleyield.co/tbill",
|
||||
"c": "website",
|
||||
"t": "Product Page"
|
||||
},
|
||||
{
|
||||
"url": "https://exampleyield.co/docs",
|
||||
"type": "docs",
|
||||
"title": "Yield Token Docs"
|
||||
"u": "exampleyield.co/docs",
|
||||
"c": "docs",
|
||||
"t": "Yield Token Docs"
|
||||
}
|
||||
],
|
||||
"additional_info": {
|
||||
"ai": {
|
||||
"interest_rate": "5.00%",
|
||||
"interest_type": "variable",
|
||||
"yield_source": "U.S. Treasury Bills",
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
module github.com/XRPLF
|
||||
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.10
|
||||
go 1.24.0
|
||||
|
||||
require github.com/Peersyst/xrpl-go v0.1.11
|
||||
|
||||
@@ -20,5 +18,5 @@ require (
|
||||
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
golang.org/x/crypto v0.35.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
)
|
||||
|
||||
@@ -46,8 +46,8 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ
|
||||
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
module github.com/XRPLF
|
||||
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.10
|
||||
go 1.24.0
|
||||
|
||||
require github.com/Peersyst/xrpl-go v0.1.11
|
||||
|
||||
@@ -20,5 +18,5 @@ require (
|
||||
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
golang.org/x/crypto v0.35.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
)
|
||||
|
||||
@@ -46,8 +46,8 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ
|
||||
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
module github.com/XRPLF
|
||||
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.10
|
||||
go 1.24.0
|
||||
|
||||
require github.com/Peersyst/xrpl-go v0.1.11
|
||||
|
||||
@@ -20,5 +18,5 @@ require (
|
||||
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
golang.org/x/crypto v0.35.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
)
|
||||
|
||||
@@ -46,8 +46,8 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ
|
||||
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
module github.com/XRPLF
|
||||
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.10
|
||||
go 1.24.0
|
||||
|
||||
require github.com/Peersyst/xrpl-go v0.1.11
|
||||
|
||||
@@ -20,5 +18,5 @@ require (
|
||||
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
golang.org/x/crypto v0.35.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
)
|
||||
|
||||
@@ -46,8 +46,8 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ
|
||||
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
||||
@@ -1,488 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Button } from 'shared/components/Button';
|
||||
import { PageGrid, PageGridCol, PageGridRow } from 'shared/components/PageGrid/page-grid';
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
title: 'BDS Button Component Showcase',
|
||||
description: 'Interactive showcase of the Brand Design System Button component with all states and variants.',
|
||||
},
|
||||
};
|
||||
|
||||
export default function ButtonShowcase() {
|
||||
const [clickCount, setClickCount] = React.useState(0);
|
||||
|
||||
const handleClick = () => {
|
||||
setClickCount((prev) => prev + 1);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="landing">
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse col-lg-8 mx-auto">
|
||||
<h1 className="mb-0">BDS Button Component</h1>
|
||||
<h6 className="eyebrow mb-3">Brand Design System</h6>
|
||||
</div>
|
||||
<p className="col-lg-8 mx-auto mt-10">
|
||||
A scalable button component following the XRPL Brand Design System. This showcase demonstrates all states,
|
||||
responsive behavior, and accessibility features of the Primary button variant.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Basic Usage */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Basic Usage</h2>
|
||||
<h6 className="eyebrow mb-3">Primary Variant</h6>
|
||||
</div>
|
||||
<div className="d-flex flex-wrap align-items-center">
|
||||
<Button variant="primary" onClick={handleClick} className="me-4 mb-4">
|
||||
Get Started
|
||||
</Button>
|
||||
<Button variant="primary" onClick={handleClick} className="me-4 mb-4">
|
||||
Submit Form
|
||||
</Button>
|
||||
<Button variant="primary" onClick={handleClick} className="mb-4">
|
||||
Continue
|
||||
</Button>
|
||||
</div>
|
||||
{clickCount > 0 && (
|
||||
<p className="mt-4 text-muted">Button clicked {clickCount} time{clickCount !== 1 ? 's' : ''}</p>
|
||||
)}
|
||||
</section>
|
||||
|
||||
{/* States */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Button States</h2>
|
||||
<h6 className="eyebrow mb-3">Interactive States</h6>
|
||||
</div>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<h5 className="mb-4">Enabled State</h5>
|
||||
<p className="mb-4 text-muted">Default state when button is ready for interaction.</p>
|
||||
<Button variant="primary" onClick={handleClick}>
|
||||
Enabled Button
|
||||
</Button>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<h5 className="mb-4">Disabled State</h5>
|
||||
<p className="mb-4 text-muted">Button cannot be interacted with.</p>
|
||||
<Button variant="primary" disabled>
|
||||
Disabled Button
|
||||
</Button>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">Hover & Focus States</h5>
|
||||
<p className="mb-4 text-muted">
|
||||
Hover over the buttons below or use Tab to focus them. Notice the background color change and icon swap.
|
||||
</p>
|
||||
<div className="d-flex flex-wrap">
|
||||
<Button variant="primary" onClick={handleClick} className="me-4 mb-4">
|
||||
Hover Me
|
||||
</Button>
|
||||
<Button variant="primary" onClick={handleClick} className="mb-4">
|
||||
Focus Me (Tab)
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Black Color Variant */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Black Color Variant</h2>
|
||||
<h6 className="eyebrow mb-3">Color Theme</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">
|
||||
Primary buttons can use a black color theme for dark backgrounds or alternative styling needs.
|
||||
</p>
|
||||
<div className="d-flex flex-wrap align-items-center">
|
||||
<Button variant="primary" color="black" onClick={handleClick} className="me-4 mb-4">
|
||||
Black Primary
|
||||
</Button>
|
||||
<Button variant="primary" color="black" onClick={handleClick} className="me-4 mb-4">
|
||||
Dark Button
|
||||
</Button>
|
||||
<Button variant="primary" color="black" onClick={handleClick} className="mb-4">
|
||||
Get Started
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Black Variant States */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Black Variant States</h2>
|
||||
<h6 className="eyebrow mb-3">Interactive States</h6>
|
||||
</div>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<h5 className="mb-4">Enabled State</h5>
|
||||
<p className="mb-4 text-muted">Black background with white text.</p>
|
||||
<Button variant="primary" color="black" onClick={handleClick}>
|
||||
Enabled Button
|
||||
</Button>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<h5 className="mb-4">Disabled State</h5>
|
||||
<p className="mb-4 text-muted">Same disabled styling as green variant.</p>
|
||||
<Button variant="primary" color="black" disabled>
|
||||
Disabled Button
|
||||
</Button>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">Hover & Focus States</h5>
|
||||
<p className="mb-4 text-muted">
|
||||
Hover over the buttons or use Tab to focus them. Notice the background darkens slightly on hover.
|
||||
</p>
|
||||
<div className="d-flex flex-wrap">
|
||||
<Button variant="primary" color="black" onClick={handleClick} className="me-4 mb-4">
|
||||
Hover Me
|
||||
</Button>
|
||||
<Button variant="primary" color="black" onClick={handleClick} className="mb-4">
|
||||
Focus Me (Tab)
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Green vs Black Comparison */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Green vs Black Comparison</h2>
|
||||
<h6 className="eyebrow mb-3">Color Themes</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">Compare the green (default) and black color themes side by side.</p>
|
||||
<div className="d-flex flex-wrap align-items-center">
|
||||
<Button variant="primary" color="green" onClick={handleClick} className="me-4 mb-4">
|
||||
Green Primary
|
||||
</Button>
|
||||
<Button variant="primary" color="black" onClick={handleClick} className="mb-4">
|
||||
Black Primary
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Link Buttons */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Link Buttons</h2>
|
||||
<h6 className="eyebrow mb-3">Navigation</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">
|
||||
Buttons can function as links by passing an <code>href</code> prop. They render as anchor elements wrapped in a Redocly Link component for routing support.
|
||||
</p>
|
||||
<div className="d-flex flex-wrap align-items-center">
|
||||
<Button variant="primary" href="/docs" className="me-4 mb-4">
|
||||
View Documentation
|
||||
</Button>
|
||||
<Button variant="primary" href="https://xrpl.org" target="_blank" className="me-4 mb-4">
|
||||
Visit XRPL.org
|
||||
</Button>
|
||||
<Button variant="primary" color="black" href="/about" className="mb-4">
|
||||
About Us
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Without Icon */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Without Icon</h2>
|
||||
<h6 className="eyebrow mb-3">Icon Control</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">Buttons can be rendered without the arrow icon when needed.</p>
|
||||
<div className="d-flex flex-wrap">
|
||||
<Button variant="primary" showIcon={false} onClick={handleClick} className="me-4 mb-4">
|
||||
No Icon Button
|
||||
</Button>
|
||||
<Button variant="primary" showIcon={true} onClick={handleClick} className="mb-4">
|
||||
With Icon Button
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Button Types */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Button Types</h2>
|
||||
<h6 className="eyebrow mb-3">Form Integration</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">Different button types for form submission and actions.</p>
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
alert('Form submitted!');
|
||||
}}
|
||||
className="d-flex flex-wrap"
|
||||
>
|
||||
<Button variant="primary" type="submit" className="me-4 mb-4">
|
||||
Submit Button
|
||||
</Button>
|
||||
<Button variant="primary" type="reset" className="me-4 mb-4">
|
||||
Reset Button
|
||||
</Button>
|
||||
<Button variant="primary" type="button" onClick={handleClick} className="mb-4">
|
||||
Regular Button
|
||||
</Button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
{/* Responsive Behavior */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Responsive Behavior</h2>
|
||||
<h6 className="eyebrow mb-3">Breakpoint Adjustments</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">
|
||||
Button padding adjusts automatically across breakpoints. Resize your browser window to see the changes:
|
||||
</p>
|
||||
<ul className="mb-4">
|
||||
<li>
|
||||
<strong>Desktop (≥1024px):</strong> Padding: 8px 19px 8px 20px, Gap: 16px
|
||||
</li>
|
||||
<li>
|
||||
<strong>Tablet/Mobile (≤1023px):</strong> Padding: 8px 15px 8px 16px, Gap: 16px
|
||||
</li>
|
||||
<li>
|
||||
<strong>Hover/Focus:</strong> Gap increases (22px desktop, 21px mobile) with adjusted padding to maintain
|
||||
button width
|
||||
</li>
|
||||
</ul>
|
||||
<div className="d-flex flex-wrap">
|
||||
<Button variant="primary" onClick={handleClick} className="me-4 mb-4">
|
||||
Responsive Button
|
||||
</Button>
|
||||
<Button variant="primary" onClick={handleClick} className="mb-4">
|
||||
Long Button Label Example
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Accessibility */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Accessibility Features</h2>
|
||||
<h6 className="eyebrow mb-3">WCAG Compliance</h6>
|
||||
</div>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<h5 className="mb-4">Keyboard Navigation</h5>
|
||||
<ul>
|
||||
<li>Tab to focus buttons</li>
|
||||
<li>Enter or Space to activate</li>
|
||||
<li>Focus indicator: 2px black border</li>
|
||||
<li>Disabled buttons are not focusable</li>
|
||||
</ul>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<h5 className="mb-4">Screen Reader Support</h5>
|
||||
<ul>
|
||||
<li>Button labels are announced</li>
|
||||
<li>Disabled state communicated via aria-disabled</li>
|
||||
<li>Icons are hidden from screen readers (aria-hidden)</li>
|
||||
<li>Semantic button element used</li>
|
||||
</ul>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">Color Contrast</h5>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Enabled:</strong> Black text (#141414) on Green 300 (#21E46B) = 9.06:1 (AAA)
|
||||
</li>
|
||||
<li>
|
||||
<strong>Hover:</strong> Black text (#141414) on Green 200 (#70EE97) = 10.23:1 (AAA)
|
||||
</li>
|
||||
<li>
|
||||
<strong>Disabled:</strong> Gray 500 (#838386) on Gray 200 (#E0E0E1) = 2.12:1 (acceptable for disabled
|
||||
state)
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Code Examples */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Code Examples</h2>
|
||||
<h6 className="eyebrow mb-3">Implementation</h6>
|
||||
</div>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#1e1e1e', color: '#d4d4d4' }}>
|
||||
<pre style={{ margin: 0, overflow: 'auto' }}>
|
||||
<code>{`import { Button } from 'shared/components/Button';
|
||||
|
||||
// Basic usage (green theme - default)
|
||||
<Button variant="primary" onClick={handleClick}>
|
||||
Get Started
|
||||
</Button>
|
||||
|
||||
// Black color theme
|
||||
<Button variant="primary" color="black" onClick={handleClick}>
|
||||
Dark Button
|
||||
</Button>
|
||||
|
||||
// Disabled state
|
||||
<Button variant="primary" disabled>
|
||||
Submit
|
||||
</Button>
|
||||
|
||||
// Without icon
|
||||
<Button variant="primary" showIcon={false}>
|
||||
Continue
|
||||
</Button>
|
||||
|
||||
// Form integration
|
||||
<Button variant="primary" type="submit">
|
||||
Submit Form
|
||||
</Button>
|
||||
|
||||
// Link button (internal navigation)
|
||||
<Button variant="primary" href="/docs">
|
||||
View Documentation
|
||||
</Button>
|
||||
|
||||
// Link button (external, opens in new tab)
|
||||
<Button variant="primary" href="https://xrpl.org" target="_blank">
|
||||
Visit XRPL.org
|
||||
</Button>`}</code>
|
||||
</pre>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Design Specifications */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Design Specifications</h2>
|
||||
<h6 className="eyebrow mb-3">Visual Details</h6>
|
||||
</div>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<h5 className="mb-4">Typography</h5>
|
||||
<ul>
|
||||
<li>Font: Booton, sans-serif</li>
|
||||
<li>Size: 16px</li>
|
||||
<li>Weight: 400</li>
|
||||
<li>Line Height: 23.2px</li>
|
||||
<li>Letter Spacing: 0px</li>
|
||||
</ul>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<h5 className="mb-4">Spacing & Layout</h5>
|
||||
<ul>
|
||||
<li>Border Radius: 100px (fully rounded)</li>
|
||||
<li>Icon Size: 15px × 14px</li>
|
||||
<li>Icon Gap: 16px (default), 22px (hover/focus desktop), 21px (hover/focus mobile)</li>
|
||||
<li>Min Height: 40px (touch target)</li>
|
||||
</ul>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">State Colors - Green Theme</h5>
|
||||
<div style={{ width: '100%', backgroundColor: '#FFFFFF' }}>
|
||||
{/* Header */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '2px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>State</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Text Color</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Background Color</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Border</div>
|
||||
</div>
|
||||
{/* Rows */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Enabled</div>
|
||||
<div style={{ padding: '12px' }}>#141414 (Neutral Black)</div>
|
||||
<div style={{ padding: '12px' }}>#21E46B (Green 300)</div>
|
||||
<div style={{ padding: '12px' }}>None</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Hover</div>
|
||||
<div style={{ padding: '12px' }}>#141414 (Neutral Black)</div>
|
||||
<div style={{ padding: '12px' }}>#70EE97 (Green 200)</div>
|
||||
<div style={{ padding: '12px' }}>None</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Focus</div>
|
||||
<div style={{ padding: '12px' }}>#141414 (Neutral Black)</div>
|
||||
<div style={{ padding: '12px' }}>#70EE97 (Green 200)</div>
|
||||
<div style={{ padding: '12px' }}>2px solid #141414</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Active</div>
|
||||
<div style={{ padding: '12px' }}>#141414 (Neutral Black)</div>
|
||||
<div style={{ padding: '12px' }}>#21E46B (Green 300)</div>
|
||||
<div style={{ padding: '12px' }}>None</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr' }}>
|
||||
<div style={{ padding: '12px' }}>Disabled</div>
|
||||
<div style={{ padding: '12px' }}>#838386 (Gray 500)</div>
|
||||
<div style={{ padding: '12px' }}>#E0E0E1 (Gray 200)</div>
|
||||
<div style={{ padding: '12px' }}>None</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">State Colors - Black Theme</h5>
|
||||
<div style={{ width: '100%', backgroundColor: '#FFFFFF' }}>
|
||||
{/* Header */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '2px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>State</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Text Color</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Background Color</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Border</div>
|
||||
</div>
|
||||
{/* Rows */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Enabled</div>
|
||||
<div style={{ padding: '12px' }}>#FFFFFF (White)</div>
|
||||
<div style={{ padding: '12px' }}>#141414 (Neutral Black)</div>
|
||||
<div style={{ padding: '12px' }}>None</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Hover</div>
|
||||
<div style={{ padding: '12px' }}>#FFFFFF (White)</div>
|
||||
<div style={{ padding: '12px' }}>rgba(20, 20, 20, 0.8) (80% Black)</div>
|
||||
<div style={{ padding: '12px' }}>None</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Focus</div>
|
||||
<div style={{ padding: '12px' }}>#FFFFFF (White)</div>
|
||||
<div style={{ padding: '12px' }}>rgba(20, 20, 20, 0.8) (80% Black)</div>
|
||||
<div style={{ padding: '12px' }}>2px solid #141414</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Active</div>
|
||||
<div style={{ padding: '12px' }}>#FFFFFF (White)</div>
|
||||
<div style={{ padding: '12px' }}>#141414 (Neutral Black)</div>
|
||||
<div style={{ padding: '12px' }}>None</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr' }}>
|
||||
<div style={{ padding: '12px' }}>Disabled</div>
|
||||
<div style={{ padding: '12px' }}>#838386 (Gray 500)</div>
|
||||
<div style={{ padding: '12px' }}>#E0E0E1 (Gray 200)</div>
|
||||
<div style={{ padding: '12px' }}>None</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,528 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Button } from 'shared/components/Button';
|
||||
import { PageGrid, PageGridCol, PageGridRow } from 'shared/components/PageGrid/page-grid';
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
title: 'BDS Secondary Button Component Showcase',
|
||||
description: 'Interactive showcase of the Brand Design System Secondary Button component with all states and variants.',
|
||||
},
|
||||
};
|
||||
|
||||
export default function ButtonShowcaseSecondary() {
|
||||
const [clickCount, setClickCount] = React.useState(0);
|
||||
|
||||
const handleClick = () => {
|
||||
setClickCount((prev) => prev + 1);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="landing">
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse col-lg-8 mx-auto">
|
||||
<h1 className="mb-0">BDS Secondary Button</h1>
|
||||
<h6 className="eyebrow mb-3">Brand Design System</h6>
|
||||
</div>
|
||||
<p className="col-lg-8 mx-auto mt-10">
|
||||
The Secondary button is an outline-style button used for secondary actions. It features a transparent
|
||||
background with a green stroke/border, providing visual hierarchy below the Primary button while maintaining
|
||||
brand consistency.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Basic Usage */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Basic Usage</h2>
|
||||
<h6 className="eyebrow mb-3">Secondary Variant</h6>
|
||||
</div>
|
||||
<div className="d-flex flex-wrap align-items-center">
|
||||
<Button variant="secondary" onClick={handleClick} className="me-4 mb-4">
|
||||
Learn More
|
||||
</Button>
|
||||
<Button variant="secondary" onClick={handleClick} className="me-4 mb-4">
|
||||
View Details
|
||||
</Button>
|
||||
<Button variant="secondary" onClick={handleClick} className="mb-4">
|
||||
Explore
|
||||
</Button>
|
||||
</div>
|
||||
{clickCount > 0 && (
|
||||
<p className="mt-4 text-muted">
|
||||
Button clicked {clickCount} time{clickCount !== 1 ? 's' : ''}
|
||||
</p>
|
||||
)}
|
||||
</section>
|
||||
|
||||
{/* Primary vs Secondary Comparison */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Primary vs Secondary</h2>
|
||||
<h6 className="eyebrow mb-3">Visual Hierarchy</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">
|
||||
Use Primary for main actions and Secondary for supporting actions to create clear visual hierarchy.
|
||||
</p>
|
||||
<div className="d-flex flex-wrap align-items-center">
|
||||
<Button variant="primary" onClick={handleClick} className="me-4 mb-4">
|
||||
Get Started
|
||||
</Button>
|
||||
<Button variant="secondary" onClick={handleClick} className="mb-4">
|
||||
Learn More
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* States */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Button States</h2>
|
||||
<h6 className="eyebrow mb-3">Interactive States</h6>
|
||||
</div>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<h5 className="mb-4">Enabled State</h5>
|
||||
<p className="mb-4 text-muted">Default outline style with green border and text.</p>
|
||||
<Button variant="secondary" onClick={handleClick}>
|
||||
Enabled Button
|
||||
</Button>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<h5 className="mb-4">Disabled State</h5>
|
||||
<p className="mb-4 text-muted">Gray border and text indicate non-interactive state.</p>
|
||||
<Button variant="secondary" disabled>
|
||||
Disabled Button
|
||||
</Button>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">Hover & Focus States</h5>
|
||||
<p className="mb-4 text-muted">
|
||||
Hover over the buttons or use Tab to focus them. Notice the light green background fill and darker green
|
||||
border on hover/focus.
|
||||
</p>
|
||||
<div className="d-flex flex-wrap">
|
||||
<Button variant="secondary" onClick={handleClick} className="me-4 mb-4">
|
||||
Hover Me
|
||||
</Button>
|
||||
<Button variant="secondary" onClick={handleClick} className="mb-4">
|
||||
Focus Me (Tab)
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Black Color Variant */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Black Color Variant</h2>
|
||||
<h6 className="eyebrow mb-3">Color Theme</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">
|
||||
Secondary buttons can use a black color theme with black text and border instead of green.
|
||||
</p>
|
||||
<div className="d-flex flex-wrap align-items-center">
|
||||
<Button variant="secondary" color="black" onClick={handleClick} className="me-4 mb-4">
|
||||
Black Secondary
|
||||
</Button>
|
||||
<Button variant="secondary" color="black" onClick={handleClick} className="me-4 mb-4">
|
||||
Learn More
|
||||
</Button>
|
||||
<Button variant="secondary" color="black" onClick={handleClick} className="mb-4">
|
||||
View Details
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Black Variant States */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Black Variant States</h2>
|
||||
<h6 className="eyebrow mb-3">Interactive States</h6>
|
||||
</div>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<h5 className="mb-4">Enabled State</h5>
|
||||
<p className="mb-4 text-muted">Black border and text with transparent background.</p>
|
||||
<Button variant="secondary" color="black" onClick={handleClick}>
|
||||
Enabled Button
|
||||
</Button>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<h5 className="mb-4">Disabled State</h5>
|
||||
<p className="mb-4 text-muted">Same disabled styling as green variant.</p>
|
||||
<Button variant="secondary" color="black" disabled>
|
||||
Disabled Button
|
||||
</Button>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">Hover & Focus States</h5>
|
||||
<p className="mb-4 text-muted">
|
||||
Hover over the buttons or use Tab to focus them. Notice the subtle black background fill on hover.
|
||||
</p>
|
||||
<div className="d-flex flex-wrap">
|
||||
<Button variant="secondary" color="black" onClick={handleClick} className="me-4 mb-4">
|
||||
Hover Me
|
||||
</Button>
|
||||
<Button variant="secondary" color="black" onClick={handleClick} className="mb-4">
|
||||
Focus Me (Tab)
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Green vs Black Comparison */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Green vs Black Comparison</h2>
|
||||
<h6 className="eyebrow mb-3">Color Themes</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">Compare the green (default) and black color themes side by side.</p>
|
||||
<div className="d-flex flex-wrap align-items-center">
|
||||
<Button variant="secondary" color="green" onClick={handleClick} className="me-4 mb-4">
|
||||
Green Secondary
|
||||
</Button>
|
||||
<Button variant="secondary" color="black" onClick={handleClick} className="mb-4">
|
||||
Black Secondary
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Without Icon */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Without Icon</h2>
|
||||
<h6 className="eyebrow mb-3">Icon Control</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">Secondary buttons can also be rendered without the arrow icon.</p>
|
||||
<div className="d-flex flex-wrap">
|
||||
<Button variant="secondary" showIcon={false} onClick={handleClick} className="me-4 mb-4">
|
||||
No Icon Button
|
||||
</Button>
|
||||
<Button variant="secondary" showIcon={true} onClick={handleClick} className="mb-4">
|
||||
With Icon Button
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Button Types */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Button Types</h2>
|
||||
<h6 className="eyebrow mb-3">Form Integration</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">Secondary buttons can be used for form actions like cancel or reset.</p>
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
alert('Form submitted!');
|
||||
}}
|
||||
className="d-flex flex-wrap"
|
||||
>
|
||||
<Button variant="primary" type="submit" className="me-4 mb-4">
|
||||
Submit
|
||||
</Button>
|
||||
<Button variant="secondary" type="reset" className="me-4 mb-4">
|
||||
Reset
|
||||
</Button>
|
||||
<Button variant="secondary" type="button" onClick={() => alert('Cancelled!')} className="mb-4">
|
||||
Cancel
|
||||
</Button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
{/* Responsive Behavior */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Responsive Behavior</h2>
|
||||
<h6 className="eyebrow mb-3">Breakpoint Adjustments</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">
|
||||
Button padding adjusts automatically across breakpoints. Resize your browser window to see the changes:
|
||||
</p>
|
||||
<ul className="mb-4">
|
||||
<li>
|
||||
<strong>Desktop (≥1024px):</strong> Padding: 6px 17px 6px 18px (compensates for 2px border)
|
||||
</li>
|
||||
<li>
|
||||
<strong>Tablet/Mobile (≤1023px):</strong> Padding: 6px 13px 6px 14px
|
||||
</li>
|
||||
<li>
|
||||
<strong>Hover/Focus:</strong> Gap increases (22px desktop, 21px mobile) with adjusted padding
|
||||
</li>
|
||||
</ul>
|
||||
<div className="d-flex flex-wrap">
|
||||
<Button variant="secondary" onClick={handleClick} className="me-4 mb-4">
|
||||
Responsive Button
|
||||
</Button>
|
||||
<Button variant="secondary" onClick={handleClick} className="mb-4">
|
||||
Long Button Label Example
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Accessibility */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Accessibility Features</h2>
|
||||
<h6 className="eyebrow mb-3">WCAG Compliance</h6>
|
||||
</div>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<h5 className="mb-4">Keyboard Navigation</h5>
|
||||
<ul>
|
||||
<li>Tab to focus buttons</li>
|
||||
<li>Enter or Space to activate</li>
|
||||
<li>Focus indicator: 2px black outline (additional to green border)</li>
|
||||
<li>Disabled buttons are not focusable</li>
|
||||
</ul>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<h5 className="mb-4">Screen Reader Support</h5>
|
||||
<ul>
|
||||
<li>Button labels are announced</li>
|
||||
<li>Disabled state communicated via aria-disabled</li>
|
||||
<li>Icons are hidden from screen readers (aria-hidden)</li>
|
||||
<li>Semantic button element used</li>
|
||||
</ul>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">Color Contrast</h5>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Enabled:</strong> Green 400 (#0DAA3E) on White = 4.52:1 (AA for large text)
|
||||
</li>
|
||||
<li>
|
||||
<strong>Hover:</strong> Green 500 (#078139) on Green 100 (#EAFCF1) = 4.87:1 (AA)
|
||||
</li>
|
||||
<li>
|
||||
<strong>Disabled:</strong> Gray 400 (#A2A2A4) on White = reduced contrast (acceptable for disabled state)
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Code Examples */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Code Examples</h2>
|
||||
<h6 className="eyebrow mb-3">Implementation</h6>
|
||||
</div>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#1e1e1e', color: '#d4d4d4' }}>
|
||||
<pre style={{ margin: 0, overflow: 'auto' }}>
|
||||
<code>{`import { Button } from 'shared/components/Button';
|
||||
|
||||
// Basic secondary button (green theme - default)
|
||||
<Button variant="secondary" onClick={handleClick}>
|
||||
Learn More
|
||||
</Button>
|
||||
|
||||
// Black color theme
|
||||
<Button variant="secondary" color="black" onClick={handleClick}>
|
||||
Learn More
|
||||
</Button>
|
||||
|
||||
// Disabled state
|
||||
<Button variant="secondary" disabled>
|
||||
Unavailable
|
||||
</Button>
|
||||
|
||||
// Without icon
|
||||
<Button variant="secondary" showIcon={false}>
|
||||
Cancel
|
||||
</Button>
|
||||
|
||||
// Primary + Secondary pairing
|
||||
<Button variant="primary" type="submit">
|
||||
Submit
|
||||
</Button>
|
||||
<Button variant="secondary" type="button">
|
||||
Cancel
|
||||
</Button>`}</code>
|
||||
</pre>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Design Specifications */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Design Specifications</h2>
|
||||
<h6 className="eyebrow mb-3">Visual Details</h6>
|
||||
</div>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<h5 className="mb-4">Typography</h5>
|
||||
<ul>
|
||||
<li>Font: Booton, sans-serif</li>
|
||||
<li>Size: 16px</li>
|
||||
<li>Weight: 400</li>
|
||||
<li>Line Height: 23.2px</li>
|
||||
<li>Letter Spacing: 0px</li>
|
||||
</ul>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<h5 className="mb-4">Spacing & Layout</h5>
|
||||
<ul>
|
||||
<li>Border Radius: 100px (fully rounded)</li>
|
||||
<li>Border Width: 2px solid</li>
|
||||
<li>Icon Size: 15px × 14px</li>
|
||||
<li>Icon Gap: 16px (default), 22px (hover/focus desktop), 21px (hover/focus mobile)</li>
|
||||
<li>Max Height: 40px</li>
|
||||
</ul>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">State Colors - Green Theme</h5>
|
||||
<div style={{ width: '100%', backgroundColor: '#FFFFFF' }}>
|
||||
{/* Header */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '2px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>State</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Text Color</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Background</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Border</div>
|
||||
</div>
|
||||
{/* Rows */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Enabled</div>
|
||||
<div style={{ padding: '12px' }}>#0DAA3E (Green 400)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>2px #0DAA3E (Green 400)</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Hover</div>
|
||||
<div style={{ padding: '12px' }}>#078139 (Green 500)</div>
|
||||
<div style={{ padding: '12px' }}>#EAFCF1 (Green 100)</div>
|
||||
<div style={{ padding: '12px' }}>2px #078139 (Green 500)</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Focus</div>
|
||||
<div style={{ padding: '12px' }}>#078139 (Green 500)</div>
|
||||
<div style={{ padding: '12px' }}>#EAFCF1 (Green 100)</div>
|
||||
<div style={{ padding: '12px' }}>2px #078139 + 2px #141414 outline</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Active</div>
|
||||
<div style={{ padding: '12px' }}>#0DAA3E (Green 400)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>2px #0DAA3E (Green 400)</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr' }}>
|
||||
<div style={{ padding: '12px' }}>Disabled</div>
|
||||
<div style={{ padding: '12px' }}>#A2A2A4 (Gray 400)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>2px #A2A2A4 (Gray 400)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">State Colors - Black Theme</h5>
|
||||
<div style={{ width: '100%', backgroundColor: '#FFFFFF' }}>
|
||||
{/* Header */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '2px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>State</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Text Color</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Background</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Border</div>
|
||||
</div>
|
||||
{/* Rows */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Enabled</div>
|
||||
<div style={{ padding: '12px' }}>#141414 (Neutral Black)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>2px #141414 (Neutral Black)</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Hover</div>
|
||||
<div style={{ padding: '12px' }}>#141414 (Neutral Black)</div>
|
||||
<div style={{ padding: '12px' }}>rgba(20, 20, 20, 0.15) (15% Black)</div>
|
||||
<div style={{ padding: '12px' }}>2px #141414 (Neutral Black)</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Focus</div>
|
||||
<div style={{ padding: '12px' }}>#141414 (Neutral Black)</div>
|
||||
<div style={{ padding: '12px' }}>rgba(20, 20, 20, 0.15) (15% Black)</div>
|
||||
<div style={{ padding: '12px' }}>2px #141414 + 2px #141414 outline</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Active</div>
|
||||
<div style={{ padding: '12px' }}>#141414 (Neutral Black)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>2px #141414 (Neutral Black)</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr' }}>
|
||||
<div style={{ padding: '12px' }}>Disabled</div>
|
||||
<div style={{ padding: '12px' }}>#A2A2A4 (Gray 400)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>2px #A2A2A4 (Gray 400)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Key Differences from Primary */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Key Differences from Primary</h2>
|
||||
<h6 className="eyebrow mb-3">Comparison</h6>
|
||||
</div>
|
||||
<div style={{ width: '100%', backgroundColor: '#FFFFFF' }}>
|
||||
{/* Header */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', borderBottom: '2px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Aspect</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Primary</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Secondary</div>
|
||||
</div>
|
||||
{/* Rows */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Background (Enabled)</div>
|
||||
<div style={{ padding: '12px' }}>Green 300 (#21E46B)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Background (Hover)</div>
|
||||
<div style={{ padding: '12px' }}>Green 200 (#70EE97)</div>
|
||||
<div style={{ padding: '12px' }}>Green 100 (#EAFCF1)</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Border (Enabled)</div>
|
||||
<div style={{ padding: '12px' }}>None</div>
|
||||
<div style={{ padding: '12px' }}>2px Green 400</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Text Color (Enabled)</div>
|
||||
<div style={{ padding: '12px' }}>Black (#141414)</div>
|
||||
<div style={{ padding: '12px' }}>Green 400 (#0DAA3E)</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Disabled Background</div>
|
||||
<div style={{ padding: '12px' }}>Gray 200 (#E0E0E1)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr' }}>
|
||||
<div style={{ padding: '12px' }}>Arrow Icon</div>
|
||||
<div style={{ padding: '12px' }}>✅ Shared</div>
|
||||
<div style={{ padding: '12px' }}>✅ Shared</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,561 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Button } from 'shared/components/Button';
|
||||
import { PageGrid, PageGridCol, PageGridRow } from 'shared/components/PageGrid/page-grid';
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
title: 'BDS Tertiary Button Component Showcase',
|
||||
description: 'Interactive showcase of the Brand Design System Tertiary Button component with all states and variants.',
|
||||
},
|
||||
};
|
||||
|
||||
export default function ButtonShowcaseTertiary() {
|
||||
const [clickCount, setClickCount] = React.useState(0);
|
||||
|
||||
const handleClick = () => {
|
||||
setClickCount((prev) => prev + 1);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="landing">
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse col-lg-8 mx-auto">
|
||||
<h1 className="mb-0">BDS Tertiary Button</h1>
|
||||
<h6 className="eyebrow mb-3">Brand Design System</h6>
|
||||
</div>
|
||||
<p className="col-lg-8 mx-auto mt-10">
|
||||
The Tertiary button is a text-only button style used for low-emphasis or contextual actions. It features no
|
||||
background fill or border, appearing as a simple text link with optional arrow icon. This variant provides the
|
||||
lowest visual emphasis while maintaining brand consistency through green text colors.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Basic Usage */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Basic Usage</h2>
|
||||
<h6 className="eyebrow mb-3">Tertiary Variant</h6>
|
||||
</div>
|
||||
<div className="d-flex flex-wrap align-items-center">
|
||||
<Button variant="tertiary" onClick={handleClick} className="me-4 mb-4">
|
||||
View Details
|
||||
</Button>
|
||||
<Button variant="tertiary" onClick={handleClick} className="me-4 mb-4">
|
||||
Learn More
|
||||
</Button>
|
||||
<Button variant="tertiary" onClick={handleClick} className="mb-4">
|
||||
Read More
|
||||
</Button>
|
||||
</div>
|
||||
{clickCount > 0 && (
|
||||
<p className="mt-4 text-muted">
|
||||
Button clicked {clickCount} time{clickCount !== 1 ? 's' : ''}
|
||||
</p>
|
||||
)}
|
||||
</section>
|
||||
|
||||
{/* Primary vs Secondary vs Tertiary Comparison */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Primary vs Secondary vs Tertiary</h2>
|
||||
<h6 className="eyebrow mb-3">Visual Hierarchy</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">
|
||||
Use Primary for main actions, Secondary for supporting actions, and Tertiary for low-emphasis or contextual
|
||||
actions to create clear visual hierarchy.
|
||||
</p>
|
||||
<div className="d-flex flex-wrap align-items-center">
|
||||
<Button variant="primary" onClick={handleClick} className="me-4 mb-4">
|
||||
Get Started
|
||||
</Button>
|
||||
<Button variant="secondary" onClick={handleClick} className="me-4 mb-4">
|
||||
Learn More
|
||||
</Button>
|
||||
<Button variant="tertiary" onClick={handleClick} className="mb-4">
|
||||
View Details
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* States */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Button States</h2>
|
||||
<h6 className="eyebrow mb-3">Interactive States</h6>
|
||||
</div>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<h5 className="mb-4">Enabled State</h5>
|
||||
<p className="mb-4 text-muted">Text-only style with green text color, no background or border.</p>
|
||||
<Button variant="tertiary" onClick={handleClick}>
|
||||
Enabled Button
|
||||
</Button>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<h5 className="mb-4">Disabled State</h5>
|
||||
<p className="mb-4 text-muted">Gray text indicates non-interactive state. Icon is hidden.</p>
|
||||
<Button variant="tertiary" disabled>
|
||||
Disabled Button
|
||||
</Button>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">Hover & Focus States</h5>
|
||||
<p className="mb-4 text-muted">
|
||||
Hover over the buttons or use Tab to focus them. Notice the underline appears and text color darkens to
|
||||
Green 500. The focus state adds a green outline around the text.
|
||||
</p>
|
||||
<div className="d-flex flex-wrap">
|
||||
<Button variant="tertiary" onClick={handleClick} className="me-4 mb-4">
|
||||
Hover Me
|
||||
</Button>
|
||||
<Button variant="tertiary" onClick={handleClick} className="mb-4">
|
||||
Focus Me (Tab)
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Black Color Variant */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Black Color Variant</h2>
|
||||
<h6 className="eyebrow mb-3">Color Theme</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">
|
||||
Tertiary buttons can use a black color theme with black text instead of green.
|
||||
</p>
|
||||
<div className="d-flex flex-wrap align-items-center">
|
||||
<Button variant="tertiary" color="black" onClick={handleClick} className="me-4 mb-4">
|
||||
Black Tertiary
|
||||
</Button>
|
||||
<Button variant="tertiary" color="black" onClick={handleClick} className="me-4 mb-4">
|
||||
View Details
|
||||
</Button>
|
||||
<Button variant="tertiary" color="black" onClick={handleClick} className="mb-4">
|
||||
Learn More
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Black Variant States */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Black Variant States</h2>
|
||||
<h6 className="eyebrow mb-3">Interactive States</h6>
|
||||
</div>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<h5 className="mb-4">Enabled State</h5>
|
||||
<p className="mb-4 text-muted">Black text with transparent background.</p>
|
||||
<Button variant="tertiary" color="black" onClick={handleClick}>
|
||||
Enabled Button
|
||||
</Button>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<h5 className="mb-4">Disabled State</h5>
|
||||
<p className="mb-4 text-muted">Same disabled styling as green variant.</p>
|
||||
<Button variant="tertiary" color="black" disabled>
|
||||
Disabled Button
|
||||
</Button>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">Hover & Focus States</h5>
|
||||
<p className="mb-4 text-muted">
|
||||
Hover over the buttons or use Tab to focus them. Notice the underline appears on hover/focus.
|
||||
</p>
|
||||
<div className="d-flex flex-wrap">
|
||||
<Button variant="tertiary" color="black" onClick={handleClick} className="me-4 mb-4">
|
||||
Hover Me
|
||||
</Button>
|
||||
<Button variant="tertiary" color="black" onClick={handleClick} className="mb-4">
|
||||
Focus Me (Tab)
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Green vs Black Comparison */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Green vs Black Comparison</h2>
|
||||
<h6 className="eyebrow mb-3">Color Themes</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">Compare the green (default) and black color themes side by side.</p>
|
||||
<div className="d-flex flex-wrap align-items-center">
|
||||
<Button variant="tertiary" color="green" onClick={handleClick} className="me-4 mb-4">
|
||||
Green Tertiary
|
||||
</Button>
|
||||
<Button variant="tertiary" color="black" onClick={handleClick} className="mb-4">
|
||||
Black Tertiary
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Without Icon */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Without Icon</h2>
|
||||
<h6 className="eyebrow mb-3">Icon Control</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">Tertiary buttons can also be rendered without the arrow icon.</p>
|
||||
<div className="d-flex flex-wrap">
|
||||
<Button variant="tertiary" showIcon={false} onClick={handleClick} className="me-4 mb-4">
|
||||
No Icon Button
|
||||
</Button>
|
||||
<Button variant="tertiary" showIcon={true} onClick={handleClick} className="mb-4">
|
||||
With Icon Button
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Button Types */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Button Types</h2>
|
||||
<h6 className="eyebrow mb-3">Form Integration</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">Tertiary buttons can be used for form actions like cancel or reset.</p>
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
alert('Form submitted!');
|
||||
}}
|
||||
className="d-flex flex-wrap"
|
||||
>
|
||||
<Button variant="primary" type="submit" className="me-4 mb-4">
|
||||
Submit
|
||||
</Button>
|
||||
<Button variant="tertiary" type="reset" className="me-4 mb-4">
|
||||
Reset
|
||||
</Button>
|
||||
<Button variant="tertiary" type="button" onClick={() => alert('Cancelled!')} className="mb-4">
|
||||
Cancel
|
||||
</Button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
{/* Responsive Behavior */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Responsive Behavior</h2>
|
||||
<h6 className="eyebrow mb-3">Breakpoint Adjustments</h6>
|
||||
</div>
|
||||
<p className="mb-4 text-muted">
|
||||
Button padding adjusts automatically across breakpoints. Resize your browser window to see the changes:
|
||||
</p>
|
||||
<ul className="mb-4">
|
||||
<li>
|
||||
<strong>Desktop (≥1024px):</strong> Padding: 8px 20px, Gap: 16px
|
||||
</li>
|
||||
<li>
|
||||
<strong>Tablet/Mobile (≤1023px):</strong> Padding: 8px 16px, Gap: 16px
|
||||
</li>
|
||||
<li>
|
||||
<strong>Hover/Focus:</strong> Gap increases (22px desktop, 21px mobile) with adjusted padding
|
||||
</li>
|
||||
</ul>
|
||||
<div className="d-flex flex-wrap">
|
||||
<Button variant="tertiary" onClick={handleClick} className="me-4 mb-4">
|
||||
Responsive Button
|
||||
</Button>
|
||||
<Button variant="tertiary" onClick={handleClick} className="mb-4">
|
||||
Long Button Label Example
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Accessibility */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Accessibility Features</h2>
|
||||
<h6 className="eyebrow mb-3">WCAG Compliance</h6>
|
||||
</div>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<h5 className="mb-4">Keyboard Navigation</h5>
|
||||
<ul>
|
||||
<li>Tab to focus buttons</li>
|
||||
<li>Enter or Space to activate</li>
|
||||
<li>Focus indicator: 2px green outline (Green 500)</li>
|
||||
<li>Disabled buttons are not focusable</li>
|
||||
</ul>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<h5 className="mb-4">Screen Reader Support</h5>
|
||||
<ul>
|
||||
<li>Button labels are announced</li>
|
||||
<li>Disabled state communicated via aria-disabled</li>
|
||||
<li>Icons are hidden from screen readers (aria-hidden)</li>
|
||||
<li>Semantic button element used</li>
|
||||
</ul>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">Color Contrast</h5>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Enabled:</strong> Green 400 (#0DAA3E) on White = 4.52:1 (AA for large text)
|
||||
</li>
|
||||
<li>
|
||||
<strong>Hover/Focus:</strong> Green 500 (#078139) on White = 5.12:1 (AA)
|
||||
</li>
|
||||
<li>
|
||||
<strong>Disabled:</strong> Gray 400 (#A2A2A4) on White = reduced contrast (acceptable for disabled state)
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Code Examples */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Code Examples</h2>
|
||||
<h6 className="eyebrow mb-3">Implementation</h6>
|
||||
</div>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#1e1e1e', color: '#d4d4d4' }}>
|
||||
<pre style={{ margin: 0, overflow: 'auto' }}>
|
||||
<code>{`import { Button } from 'shared/components/Button';
|
||||
|
||||
// Basic tertiary button (green theme - default)
|
||||
<Button variant="tertiary" onClick={handleClick}>
|
||||
View Details
|
||||
</Button>
|
||||
|
||||
// Black color theme
|
||||
<Button variant="tertiary" color="black" onClick={handleClick}>
|
||||
View Details
|
||||
</Button>
|
||||
|
||||
// Disabled state
|
||||
<Button variant="tertiary" disabled>
|
||||
Unavailable
|
||||
</Button>
|
||||
|
||||
// Without icon
|
||||
<Button variant="tertiary" showIcon={false}>
|
||||
Cancel
|
||||
</Button>
|
||||
|
||||
// Primary + Secondary + Tertiary pairing
|
||||
<Button variant="primary" type="submit">
|
||||
Submit
|
||||
</Button>
|
||||
<Button variant="secondary" type="button">
|
||||
Learn More
|
||||
</Button>
|
||||
<Button variant="tertiary" type="button">
|
||||
Cancel
|
||||
</Button>`}</code>
|
||||
</pre>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Design Specifications */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Design Specifications</h2>
|
||||
<h6 className="eyebrow mb-3">Visual Details</h6>
|
||||
</div>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<h5 className="mb-4">Typography</h5>
|
||||
<ul>
|
||||
<li>Font: Booton, sans-serif</li>
|
||||
<li>Size: 18px (Body R token - different from Primary/Secondary)</li>
|
||||
<li>Weight: 400</li>
|
||||
<li>Line Height: 26.1px</li>
|
||||
<li>Letter Spacing: -0.5px</li>
|
||||
</ul>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<h5 className="mb-4">Spacing & Layout</h5>
|
||||
<ul>
|
||||
<li>Border Radius: 100px (fully rounded - inherited but not visually apparent)</li>
|
||||
<li>Border: None</li>
|
||||
<li>Background: Transparent</li>
|
||||
<li>Icon Size: 15px × 14px</li>
|
||||
<li>Icon Gap: 16px (default), 22px (hover/focus desktop), 21px (hover/focus mobile)</li>
|
||||
<li>Max Height: 40px</li>
|
||||
</ul>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">State Colors - Green Theme</h5>
|
||||
<div style={{ width: '100%', backgroundColor: '#FFFFFF' }}>
|
||||
{/* Header */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '2px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>State</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Text Color</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Background</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Text Decoration</div>
|
||||
</div>
|
||||
{/* Rows */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Enabled</div>
|
||||
<div style={{ padding: '12px' }}>#0DAA3E (Green 400)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>None</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Hover</div>
|
||||
<div style={{ padding: '12px' }}>#078139 (Green 500)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>Underline</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Focus</div>
|
||||
<div style={{ padding: '12px' }}>#078139 (Green 500)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>Underline + 2px Green 500 outline</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Active</div>
|
||||
<div style={{ padding: '12px' }}>#0DAA3E (Green 400)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>Underline</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr' }}>
|
||||
<div style={{ padding: '12px' }}>Disabled</div>
|
||||
<div style={{ padding: '12px' }}>#A2A2A4 (Gray 400)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>None</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">State Colors - Black Theme</h5>
|
||||
<div style={{ width: '100%', backgroundColor: '#FFFFFF' }}>
|
||||
{/* Header */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '2px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>State</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Text Color</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Background</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Text Decoration</div>
|
||||
</div>
|
||||
{/* Rows */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Enabled</div>
|
||||
<div style={{ padding: '12px' }}>#141414 (Neutral Black)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>None</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Hover</div>
|
||||
<div style={{ padding: '12px' }}>#141414 (Neutral Black)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>Underline</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Focus</div>
|
||||
<div style={{ padding: '12px' }}>#141414 (Neutral Black)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>Underline + 2px Black outline</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Active</div>
|
||||
<div style={{ padding: '12px' }}>#141414 (Neutral Black)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>Underline</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr' }}>
|
||||
<div style={{ padding: '12px' }}>Disabled</div>
|
||||
<div style={{ padding: '12px' }}>#A2A2A4 (Gray 400)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>None</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Key Differences from Primary/Secondary */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Key Differences from Primary/Secondary</h2>
|
||||
<h6 className="eyebrow mb-3">Comparison</h6>
|
||||
</div>
|
||||
<div style={{ width: '100%', backgroundColor: '#FFFFFF' }}>
|
||||
{/* Header */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '2px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Aspect</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Primary</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Secondary</div>
|
||||
<div style={{ padding: '12px', fontWeight: 'bold' }}>Tertiary</div>
|
||||
</div>
|
||||
{/* Rows */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Background (Enabled)</div>
|
||||
<div style={{ padding: '12px' }}>Green 300 (#21E46B)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Background (Hover)</div>
|
||||
<div style={{ padding: '12px' }}>Green 200 (#70EE97)</div>
|
||||
<div style={{ padding: '12px' }}>Green 100 (#EAFCF1)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Border (Enabled)</div>
|
||||
<div style={{ padding: '12px' }}>None</div>
|
||||
<div style={{ padding: '12px' }}>2px Green 400</div>
|
||||
<div style={{ padding: '12px' }}>None</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Text Color (Enabled)</div>
|
||||
<div style={{ padding: '12px' }}>Black (#141414)</div>
|
||||
<div style={{ padding: '12px' }}>Green 400 (#0DAA3E)</div>
|
||||
<div style={{ padding: '12px' }}>Green 400 (#0DAA3E)</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Text Decoration</div>
|
||||
<div style={{ padding: '12px' }}>None</div>
|
||||
<div style={{ padding: '12px' }}>None</div>
|
||||
<div style={{ padding: '12px' }}>Underline (hover/focus/active)</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Typography Token</div>
|
||||
<div style={{ padding: '12px' }}>Label R (16px)</div>
|
||||
<div style={{ padding: '12px' }}>Label R (16px)</div>
|
||||
<div style={{ padding: '12px' }}>Body R (18px)</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Focus Indicator</div>
|
||||
<div style={{ padding: '12px' }}>2px Black border</div>
|
||||
<div style={{ padding: '12px' }}>2px Black outline</div>
|
||||
<div style={{ padding: '12px' }}>2px Green 500 outline</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}>Disabled Background</div>
|
||||
<div style={{ padding: '12px' }}>Gray 200 (#E0E0E1)</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
<div style={{ padding: '12px' }}>Transparent</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr' }}>
|
||||
<div style={{ padding: '12px' }}>Arrow Icon</div>
|
||||
<div style={{ padding: '12px' }}>✅ Shared</div>
|
||||
<div style={{ padding: '12px' }}>✅ Shared</div>
|
||||
<div style={{ padding: '12px' }}>✅ Shared</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,691 +0,0 @@
|
||||
import * as React from "react";
|
||||
import { PageGrid, PageGridRow, PageGridCol } from "shared/components/PageGrid/page-grid";
|
||||
import { CardIcon } from "shared/components/CardIcon";
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
title: 'CardIcon Component Showcase',
|
||||
description: "A comprehensive showcase of the CardIcon component variants, states, and responsive sizing in the XRPL.org Design System.",
|
||||
}
|
||||
};
|
||||
|
||||
export default function CardIconShowcase() {
|
||||
const handleClick = (message: string) => {
|
||||
console.log(`CardIcon clicked: ${message}`);
|
||||
};
|
||||
|
||||
// Sample icon SVG (black version for light backgrounds)
|
||||
const cardIconSvg = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='53' height='38' viewBox='0 0 53 38' fill='none'%3E%3Cpath d='M38.6603 0.0618191C35.7826 0.289503 33.3694 1.32168 31.5728 3.09764C29.7228 4.92673 28.8397 7.15805 28.8397 9.98896C28.8397 14.2239 30.5831 17.1839 34.4732 19.529C35.4629 20.121 36.8104 20.7661 39.1399 21.768C42.3144 23.1265 43.4944 23.7716 44.2481 24.5761C45.1769 25.5703 45.4357 27.1565 44.8495 28.3709C44.7353 28.6062 44.4384 29.0008 44.172 29.2664C43.2737 30.1696 41.8577 30.6477 40.0991 30.6477C37.1301 30.6477 34.9148 29.4334 33.1334 26.8074C32.8898 26.4583 32.669 26.1699 32.6385 26.1699C32.57 26.1699 26.7767 29.5017 26.6549 29.6156C26.5787 29.6839 26.6396 29.8433 26.9365 30.329C29.2508 34.2148 32.8669 36.4917 37.7544 37.1444C39.0333 37.319 41.4314 37.3114 42.657 37.1444C45.7326 36.7118 48.0393 35.6948 49.8283 33.9644C51.7315 32.1353 52.6679 29.7674 52.6679 26.7998C52.6679 24.9024 52.3558 23.4225 51.6478 21.9577C51.1605 20.9559 50.6733 20.2804 49.8359 19.4304C48.2296 17.8062 46.1513 16.5767 42.0023 14.8007C38.8658 13.4574 37.8153 12.8806 37.1225 12.1444C36.4602 11.4386 36.1785 10.6113 36.2394 9.57912C36.2927 8.75945 36.5211 8.20541 37.0235 7.66656C37.7468 6.88483 38.5842 6.55848 39.8783 6.56607C41.3476 6.56607 42.2992 6.94555 43.2661 7.91701C43.6086 8.25095 44.0502 8.78981 44.2557 9.11616C44.4917 9.48805 44.6668 9.69297 44.7277 9.6702C44.9256 9.58671 50.4602 6.01962 50.4602 5.9665C50.4602 5.93614 50.1785 5.49594 49.8359 4.97985C49.1051 3.88696 47.7881 2.52083 46.8821 1.92126C45.2073 0.813185 43.4183 0.243967 41.0583 0.0694065C39.9012 -0.0216694 39.7489 -0.0216694 38.6603 0.0618191Z' fill='black'/%3E%3Cpath d='M14.9592 13.8528L14.9364 27.2711L14.7689 27.901C14.5481 28.7283 14.2893 29.2216 13.8325 29.677C13.193 30.3145 12.3708 30.5802 11.0005 30.5877C9.04403 30.5953 7.87166 29.7681 6.50896 27.4457C6.28819 27.0814 6.09026 26.7854 6.06742 26.793C6.03697 26.8081 4.65905 27.6354 3.00706 28.6296L0 30.4511L0.228385 30.9065C1.59108 33.616 3.95105 35.6652 6.79064 36.6063C9.79009 37.6005 13.6422 37.5094 16.4665 36.3786C19.8542 35.0125 21.8412 32.1891 22.3665 27.9921C22.4121 27.5671 22.4426 22.8236 22.4426 13.8983V0.442009H18.7123H14.9896L14.9592 13.8528Z' fill='black'/%3E%3C/svg%3E";
|
||||
|
||||
// Use the same icon for all examples
|
||||
const jsIconBlack = cardIconSvg;
|
||||
const jsIconWhite = cardIconSvg;
|
||||
const pythonIcon = cardIconSvg;
|
||||
const goIcon = cardIconSvg;
|
||||
const rustIcon = cardIconSvg;
|
||||
|
||||
return (
|
||||
<div className="landing">
|
||||
<div className="overflow-hidden">
|
||||
{/* Hero Section */}
|
||||
<section className="py-26 text-center">
|
||||
<div className="col-lg-8 mx-auto">
|
||||
<h6 className="eyebrow mb-3">Component Showcase</h6>
|
||||
<h1 className="mb-4">CardIcon Component</h1>
|
||||
<p className="longform">
|
||||
A clickable card component featuring an icon (top-left) and label text with arrow (bottom).
|
||||
Supports two color variants (Neutral and Green), five interaction states, and responsive
|
||||
sizing that adapts at breakpoints. Full card is clickable.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Responsive Sizing */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Responsive Sizing</h2>
|
||||
<p className="mb-6">
|
||||
CardIcon automatically adapts its dimensions based on viewport width. Resize your browser to see the changes.
|
||||
</p>
|
||||
|
||||
<div className="d-flex flex-column gap-4 mb-6">
|
||||
<div className="d-flex flex-row gap-4 align-items-start" style={{ flexWrap: 'wrap' }}>
|
||||
<div style={{ flex: '1 1 300px', minWidth: '280px' }}>
|
||||
<h6 className="mb-3">LG Breakpoint (≥992px)</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Column width:</strong> 4 columns</li>
|
||||
<li><strong>Card height:</strong> 144px</li>
|
||||
<li><strong>Icon bounding box:</strong> 64×64 (1:1 ratio)</li>
|
||||
<li><strong>Padding:</strong> 16px</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 300px', minWidth: '280px' }}>
|
||||
<h6 className="mb-3">MD Breakpoint (576px–991px)</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Column width:</strong> 4 columns</li>
|
||||
<li><strong>Card height:</strong> 140px</li>
|
||||
<li><strong>Icon bounding box:</strong> 60×60 (1:1 ratio)</li>
|
||||
<li><strong>Padding:</strong> 12px</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 300px', minWidth: '280px' }}>
|
||||
<h6 className="mb-3">SM Breakpoint (<576px)</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Column width:</strong> 4 columns</li>
|
||||
<li><strong>Card height:</strong> 136px</li>
|
||||
<li><strong>Icon bounding box:</strong> 56×56 (1:1 ratio)</li>
|
||||
<li><strong>Padding:</strong> 8px</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="p-4 mb-6" style={{ backgroundColor: 'rgba(114, 119, 126, 0.1)', borderRadius: '8px' }}>
|
||||
<h6 className="mb-3">Icon Requirements</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Bounding box:</strong> 1:1 ratio (square)</li>
|
||||
<li><strong>Icon padding:</strong> At least 4px padding within bounding box</li>
|
||||
<li><strong>Icon color:</strong> Must be black or white (depending on background)</li>
|
||||
<li><strong>Full card clickable:</strong> Entire card area is interactive</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardIcon
|
||||
variant="neutral"
|
||||
icon={jsIconBlack}
|
||||
iconAlt="JavaScript"
|
||||
label="Get Started with Javascript"
|
||||
onClick={() => handleClick('responsive-demo')}
|
||||
/>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardIcon
|
||||
variant="green"
|
||||
icon={jsIconBlack}
|
||||
iconAlt="JavaScript"
|
||||
label="Get Started with Javascript"
|
||||
onClick={() => handleClick('responsive-demo-green')}
|
||||
/>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Color Variants */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Color Variants</h2>
|
||||
<p className="mb-6">
|
||||
CardIcon comes in two color variants to support different visual hierarchies and use cases.
|
||||
</p>
|
||||
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<div className="d-flex flex-column align-items-center">
|
||||
<CardIcon
|
||||
variant="neutral"
|
||||
icon={jsIconBlack}
|
||||
iconAlt="JavaScript"
|
||||
label="Get Started with Javascript"
|
||||
onClick={() => handleClick('neutral')}
|
||||
/>
|
||||
<div className="mt-3 text-center">
|
||||
<strong>Neutral</strong>
|
||||
<br />
|
||||
<small className="text-muted">General purpose, subtle presentation</small>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<div className="d-flex flex-column align-items-center">
|
||||
<CardIcon
|
||||
variant="green"
|
||||
icon={jsIconBlack}
|
||||
iconAlt="JavaScript"
|
||||
label="Get Started with Javascript"
|
||||
onClick={() => handleClick('green')}
|
||||
/>
|
||||
<div className="mt-3 text-center">
|
||||
<strong>Green</strong>
|
||||
<br />
|
||||
<small className="text-muted">Featured, primary highlights</small>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Interaction States - Neutral */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Interaction States: Neutral Variant</h2>
|
||||
<p className="mb-4">
|
||||
Hover over and interact with the cards below to see the different states.
|
||||
Use Tab key to see focus states.
|
||||
</p>
|
||||
|
||||
<PageGridRow>
|
||||
{/* Default */}
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<div className="d-flex flex-column align-items-center">
|
||||
<CardIcon
|
||||
variant="neutral"
|
||||
icon={jsIconBlack}
|
||||
iconAlt="JavaScript"
|
||||
label="Default State"
|
||||
onClick={() => handleClick('neutral-default')}
|
||||
/>
|
||||
<div className="mt-3 text-center">
|
||||
<strong>Default</strong>
|
||||
<br />
|
||||
<code className="small">$gray-200</code>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
|
||||
{/* Hover */}
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<div className="d-flex flex-column align-items-center">
|
||||
<CardIcon
|
||||
variant="neutral"
|
||||
icon={jsIconBlack}
|
||||
iconAlt="JavaScript"
|
||||
label="Hover to see"
|
||||
onClick={() => handleClick('neutral-hover')}
|
||||
/>
|
||||
<div className="mt-3 text-center">
|
||||
<strong>Hover</strong>
|
||||
<br />
|
||||
<code className="small">$gray-300</code>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
|
||||
{/* Focus */}
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<div className="d-flex flex-column align-items-center">
|
||||
<CardIcon
|
||||
variant="neutral"
|
||||
icon={jsIconBlack}
|
||||
iconAlt="JavaScript"
|
||||
label="Tab to see focus"
|
||||
onClick={() => handleClick('neutral-focus')}
|
||||
/>
|
||||
<div className="mt-3 text-center">
|
||||
<strong>Focused</strong>
|
||||
<br />
|
||||
<code className="small">+ black border</code>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
|
||||
{/* Pressed */}
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<div className="d-flex flex-column align-items-center">
|
||||
<CardIcon
|
||||
variant="neutral"
|
||||
icon={jsIconBlack}
|
||||
iconAlt="JavaScript"
|
||||
label="Click to see"
|
||||
onClick={() => handleClick('neutral-pressed')}
|
||||
/>
|
||||
<div className="mt-3 text-center">
|
||||
<strong>Pressed</strong>
|
||||
<br />
|
||||
<code className="small">$gray-400</code>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
|
||||
{/* Disabled */}
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<div className="d-flex flex-column align-items-center">
|
||||
<CardIcon
|
||||
variant="neutral"
|
||||
icon={jsIconBlack}
|
||||
iconAlt="JavaScript"
|
||||
label="Disabled State"
|
||||
disabled
|
||||
/>
|
||||
<div className="mt-3 text-center">
|
||||
<strong>Disabled</strong>
|
||||
<br />
|
||||
<code className="small">$gray-100</code>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Interaction States - Green */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Interaction States: Green Variant</h2>
|
||||
<p className="mb-4">
|
||||
The green variant follows the same interaction pattern but uses the brand green color palette.
|
||||
</p>
|
||||
|
||||
<PageGridRow>
|
||||
{/* Default */}
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<div className="d-flex flex-column align-items-center">
|
||||
<CardIcon
|
||||
variant="green"
|
||||
icon={jsIconBlack}
|
||||
iconAlt="JavaScript"
|
||||
label="Default State"
|
||||
onClick={() => handleClick('green-default')}
|
||||
/>
|
||||
<div className="mt-3 text-center">
|
||||
<strong>Default</strong>
|
||||
<br />
|
||||
<code className="small">$green-200</code>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
|
||||
{/* Hover */}
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<div className="d-flex flex-column align-items-center">
|
||||
<CardIcon
|
||||
variant="green"
|
||||
icon={jsIconBlack}
|
||||
iconAlt="JavaScript"
|
||||
label="Hover to see"
|
||||
onClick={() => handleClick('green-hover')}
|
||||
/>
|
||||
<div className="mt-3 text-center">
|
||||
<strong>Hover</strong>
|
||||
<br />
|
||||
<code className="small">$green-300</code>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
|
||||
{/* Focus */}
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<div className="d-flex flex-column align-items-center">
|
||||
<CardIcon
|
||||
variant="green"
|
||||
icon={jsIconBlack}
|
||||
iconAlt="JavaScript"
|
||||
label="Tab to see focus"
|
||||
onClick={() => handleClick('green-focus')}
|
||||
/>
|
||||
<div className="mt-3 text-center">
|
||||
<strong>Focused</strong>
|
||||
<br />
|
||||
<code className="small">+ black border</code>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
|
||||
{/* Pressed */}
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<div className="d-flex flex-column align-items-center">
|
||||
<CardIcon
|
||||
variant="green"
|
||||
icon={jsIconBlack}
|
||||
iconAlt="JavaScript"
|
||||
label="Click to see"
|
||||
onClick={() => handleClick('green-pressed')}
|
||||
/>
|
||||
<div className="mt-3 text-center">
|
||||
<strong>Pressed</strong>
|
||||
<br />
|
||||
<code className="small">$green-400</code>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
|
||||
{/* Disabled */}
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<div className="d-flex flex-column align-items-center">
|
||||
<CardIcon
|
||||
variant="green"
|
||||
icon={jsIconBlack}
|
||||
iconAlt="JavaScript"
|
||||
label="Disabled State"
|
||||
disabled
|
||||
/>
|
||||
<div className="mt-3 text-center">
|
||||
<strong>Disabled</strong>
|
||||
<br />
|
||||
<code className="small">$green-100</code>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Color Token Reference */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Color Token Reference</h2>
|
||||
<p className="mb-4">All colors are mapped from <code>styles/_colors.scss</code>. The component uses <code>html.dark</code> selector for dark mode styles.</p>
|
||||
|
||||
<div className="d-flex flex-row gap-6 mb-6" style={{ flexWrap: 'wrap' }}>
|
||||
{/* Light Mode Colors */}
|
||||
<div style={{ flex: '1 1 400px', minWidth: '320px' }}>
|
||||
<h6 className="mb-4">Light Mode</h6>
|
||||
|
||||
<div className="mb-4">
|
||||
<strong className="d-block mb-2">Neutral Variant</strong>
|
||||
<div className="d-flex flex-column gap-2">
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: '#E6EAF0', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div><code>Default: $gray-200</code> <small className="text-muted">#E6EAF0</small></div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: '#CAD4DF', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div><code>Hover/Focus: $gray-300</code> <small className="text-muted">#CAD4DF</small></div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: '#8A919A', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div><code>Pressed: $gray-400</code> <small className="text-muted">#8A919A</small></div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: '#F0F3F7', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div><code>Disabled: $gray-100</code> <small className="text-muted">#F0F3F7</small></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<strong className="d-block mb-2">Green Variant</strong>
|
||||
<div className="d-flex flex-column gap-2">
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: '#70EE97', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div><code>Default: $green-200</code> <small className="text-muted">#70EE97</small></div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: '#21E46B', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div><code>Hover/Focus: $green-300</code> <small className="text-muted">#21E46B</small></div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: '#0DAA3E', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div><code>Pressed: $green-400</code> <small className="text-muted">#0DAA3E</small></div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: '#EAFCF1', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div><code>Disabled: $green-100</code> <small className="text-muted">#EAFCF1</small></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-4">
|
||||
<strong className="d-block mb-2">Focus Border</strong>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: '#000000', borderRadius: '4px', flexShrink: 0 }}></div>
|
||||
<div><code>$black</code> <small className="text-muted">#000000</small></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Dark Mode Colors */}
|
||||
<div style={{ flex: '1 1 400px', minWidth: '320px' }}>
|
||||
<h6 className="mb-4">Dark Mode <code className="small">(html.dark)</code></h6>
|
||||
|
||||
<div className="mb-4">
|
||||
<strong className="d-block mb-2">Neutral Variant</strong>
|
||||
<div className="d-flex flex-column gap-2">
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: '#72777E', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div><code>Default: $gray-500</code> <small className="text-muted">#72777E + white text</small></div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: '#8A919A', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div><code>Hover/Focus: $gray-400</code> <small className="text-muted">#8A919A + white text</small></div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: 'rgba(114,119,126,0.7)', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div><code>Pressed: 70% $gray-500</code></div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: 'rgba(114,119,126,0.3)', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div><code>Disabled: 30% opacity</code></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<strong className="d-block mb-2">Green Variant</strong>
|
||||
<div className="d-flex flex-column gap-2">
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: '#21E46B', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div><code>Default: $green-300</code> <small className="text-muted">#21E46B + black text</small></div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: '#70EE97', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div><code>Hover/Focus: $green-200</code> <small className="text-muted">#70EE97 + black text</small></div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: '#0DAA3E', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div><code>Pressed: $green-400</code> <small className="text-muted">#0DAA3E</small></div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: 'rgba(114,119,126,0.3)', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div><code>Disabled: 30% $gray-500</code> <small className="text-muted">+ white text</small></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-4">
|
||||
<strong className="d-block mb-2">Focus Border</strong>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '32px', height: '32px', backgroundColor: '#FFFFFF', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div><code>$white</code> <small className="text-muted">#FFFFFF</small></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Real-World Examples */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Real-World Examples</h2>
|
||||
|
||||
<div className="d-flex flex-column gap-8 mb-10">
|
||||
{/* Language Tutorial Grid */}
|
||||
<div>
|
||||
<h6 className="mb-4">Language Tutorial Cards</h6>
|
||||
<p className="mb-4 text-muted">Use CardIcon for quick-access language tutorials in documentation.</p>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardIcon variant="neutral" icon={jsIconBlack} iconAlt="JavaScript" label="JavaScript Tutorial" href="#javascript" />
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardIcon variant="neutral" icon={pythonIcon} iconAlt="Python" label="Python Tutorial" href="#python" />
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardIcon variant="neutral" icon={goIcon} iconAlt="Go" label="Go Tutorial" href="#go" />
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardIcon variant="neutral" icon={rustIcon} iconAlt="Rust" label="Rust Tutorial" href="#rust" />
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</div>
|
||||
|
||||
{/* Featured Tutorials */}
|
||||
<div>
|
||||
<h6 className="mb-4">Featured Content</h6>
|
||||
<p className="mb-4 text-muted">Use green variant to highlight featured or recommended content.</p>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardIcon variant="green" icon={jsIconBlack} iconAlt="JavaScript" label="Quick Start Guide" onClick={() => handleClick('featured-quickstart')} />
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardIcon variant="green" icon={pythonIcon} iconAlt="Python" label="Build Your First App" onClick={() => handleClick('featured-first-app')} />
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardIcon variant="neutral" icon={goIcon} iconAlt="Go" label="Advanced Topics" onClick={() => handleClick('advanced')} />
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardIcon variant="neutral" icon={rustIcon} iconAlt="Rust" label="API Reference" onClick={() => handleClick('api-ref')} />
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</div>
|
||||
|
||||
{/* With Links */}
|
||||
<div>
|
||||
<h6 className="mb-4">Linked Cards</h6>
|
||||
<p className="mb-4 text-muted">Use href prop to navigate to other pages. Cards render as anchor elements.</p>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardIcon variant="neutral" icon={jsIconBlack} iconAlt="JavaScript" label="View Documentation" href="#documentation" />
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardIcon variant="green" icon={pythonIcon} iconAlt="Python" label="Get Started Now" href="#get-started" />
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</div>
|
||||
|
||||
{/* Disabled States */}
|
||||
<div>
|
||||
<h6 className="mb-4">Coming Soon / Unavailable</h6>
|
||||
<p className="mb-4 text-muted">Use disabled state for content that's not yet available.</p>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardIcon variant="neutral" icon={jsIconBlack} iconAlt="Coming Soon" label="Coming Soon" disabled />
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardIcon variant="green" icon={pythonIcon} iconAlt="Unavailable" label="Currently Unavailable" disabled />
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* API Reference */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Component API</h2>
|
||||
<div className="mb-10">
|
||||
{/* Header Row */}
|
||||
<div className="d-flex flex-row mb-3 pb-2" style={{ gap: '1rem', borderBottom: '2px solid var(--bs-border-color, #dee2e6)' }}>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><strong>Prop</strong></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><strong>Type</strong></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><strong>Default</strong></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><strong>Description</strong></div>
|
||||
</div>
|
||||
|
||||
{/* variant */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem', borderBottom: '1px solid var(--bs-border-color, #dee2e6)' }}>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>variant</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>'neutral' | 'green'</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>'neutral'</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Color variant of the card</div>
|
||||
</div>
|
||||
|
||||
{/* icon */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem', borderBottom: '1px solid var(--bs-border-color, #dee2e6)' }}>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>icon</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>string</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><em>required</em></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Icon image source (URL or path). Must be black or white.</div>
|
||||
</div>
|
||||
|
||||
{/* iconAlt */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem', borderBottom: '1px solid var(--bs-border-color, #dee2e6)' }}>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>iconAlt</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>string</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>''</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Alt text for the icon image</div>
|
||||
</div>
|
||||
|
||||
{/* label */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem', borderBottom: '1px solid var(--bs-border-color, #dee2e6)' }}>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>label</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>string</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><em>required</em></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Card label text displayed at bottom</div>
|
||||
</div>
|
||||
|
||||
{/* onClick */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem', borderBottom: '1px solid var(--bs-border-color, #dee2e6)' }}>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>onClick</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>() => void</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>undefined</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Click handler - renders as button</div>
|
||||
</div>
|
||||
|
||||
{/* href */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem', borderBottom: '1px solid var(--bs-border-color, #dee2e6)' }}>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>href</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>string</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>undefined</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Link destination - renders as anchor</div>
|
||||
</div>
|
||||
|
||||
{/* disabled */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem', borderBottom: '1px solid var(--bs-border-color, #dee2e6)' }}>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>disabled</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>boolean</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>false</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Disabled state - prevents interaction</div>
|
||||
</div>
|
||||
|
||||
{/* className */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>className</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>string</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>''</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Additional CSS classes</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Design References */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Design References</h2>
|
||||
<div className="d-flex flex-column gap-3">
|
||||
<div>
|
||||
<strong>Light Mode:</strong>{' '}
|
||||
<a href="https://www.figma.com/design/GypElq0Tas4ZwgPyBe4Ymi/Card---Icon?node-id=2028-612&m=dev" target="_blank" rel="noopener noreferrer">
|
||||
Figma - Light Mode Design
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<strong>Dark Mode:</strong>{' '}
|
||||
<a href="https://www.figma.com/design/GypElq0Tas4ZwgPyBe4Ymi/Card---Icon?node-id=2072-188&m=dev" target="_blank" rel="noopener noreferrer">
|
||||
Figma - Dark Mode Design
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<strong>Documentation:</strong>{' '}
|
||||
<code>shared/components/CardIcon/CardIcon.md</code>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,782 +0,0 @@
|
||||
import * as React from "react";
|
||||
import { PageGrid, PageGridRow, PageGridCol } from "shared/components/PageGrid/page-grid";
|
||||
import { CardImage } from "shared/components/CardImage";
|
||||
import { Divider } from "shared/components/Divider";
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
title: 'CardImage Component Showcase',
|
||||
description: "A comprehensive showcase of all CardImage component variants, states, and responsive behavior in the XRPL.org Design System.",
|
||||
}
|
||||
};
|
||||
|
||||
// Sample image URL for demonstration (1:1 ratio image)
|
||||
const SAMPLE_IMAGE = "/img/cards/card-image-showcase.png";
|
||||
|
||||
// Image from Figma Image Scaling spec (node 4171-104)
|
||||
const IMAGE_SCALING_DEMO = "/img/cards/card-image-scaling-demo.png";
|
||||
|
||||
export default function CardImageShowcase() {
|
||||
const [clickedCard, setClickedCard] = React.useState<string | null>(null);
|
||||
|
||||
const handleCardClick = (cardName: string) => {
|
||||
setClickedCard(cardName);
|
||||
setTimeout(() => setClickedCard(null), 1500);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="landing">
|
||||
<div className="overflow-hidden">
|
||||
{/* Hero Section */}
|
||||
<section className="py-26 text-center">
|
||||
<div className="col-lg-8 mx-auto">
|
||||
<h6 className="eyebrow mb-3">Component Showcase</h6>
|
||||
<h1 className="mb-4">CardImage Component</h1>
|
||||
<p className="longform">
|
||||
A responsive card component displaying an image, title, subtitle, and CTA button.
|
||||
Features three responsive size variants (LG/MD/SM) that adapt to viewport width,
|
||||
with card hover triggering the button's hover animation.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Design Constraints */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Design Constraints</h2>
|
||||
<div className="d-flex flex-row gap-6 mb-6" style={{ flexWrap: 'wrap' }}>
|
||||
<div style={{ flex: '1 1 250px' }}>
|
||||
<h6 className="mb-3">Image</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Aspect Ratio:</strong> 1:1 (square)</li>
|
||||
<li>Scales with card width</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 250px' }}>
|
||||
<h6 className="mb-3">Title</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Lines:</strong> 1 line only</li>
|
||||
<li>Truncated with ellipsis</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 250px' }}>
|
||||
<h6 className="mb-3">Subtitle</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Lines:</strong> Max 3 lines</li>
|
||||
<li>Truncated with ellipsis</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 250px' }}>
|
||||
<h6 className="mb-3">Button</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Position:</strong> Locked to bottom</li>
|
||||
<li>30px margin from card bottom</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Basic Showcase */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Basic Usage</h2>
|
||||
<p className="mb-6">
|
||||
The CardImage component displays an image (1:1 ratio), title (1 line only), subtitle (max 3 lines), and a primary button locked to the bottom.
|
||||
Hover over the card to see the button animation trigger.
|
||||
</p>
|
||||
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 12, md: 6, lg: 4 }}>
|
||||
<h6 className="mb-3">With Link (href)</h6>
|
||||
<CardImage
|
||||
image={SAMPLE_IMAGE}
|
||||
imageAlt="Documentation illustration"
|
||||
title="Documentation"
|
||||
subtitle="Access everything you need to get started working with the XRPL."
|
||||
buttonLabel="Get Started"
|
||||
href="#"
|
||||
/>
|
||||
</PageGridCol>
|
||||
|
||||
<PageGridCol span={{ base: 12, md: 6, lg: 4 }}>
|
||||
<h6 className="mb-3">With Click Handler</h6>
|
||||
<CardImage
|
||||
image={SAMPLE_IMAGE}
|
||||
imageAlt="Feature illustration"
|
||||
title="Developer Tools"
|
||||
subtitle="Build powerful applications with our comprehensive SDK and API documentation."
|
||||
buttonLabel="Learn More"
|
||||
onClick={() => handleCardClick('click-handler')}
|
||||
/>
|
||||
{clickedCard === 'click-handler' && (
|
||||
<p className="mt-2 text-success">✓ Card clicked!</p>
|
||||
)}
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Interactive States */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Interactive States</h2>
|
||||
<p className="mb-6">
|
||||
Hover, focus, and press the cards below to see the state transitions.
|
||||
Notice how hovering the card triggers the button's hover animation.
|
||||
</p>
|
||||
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 12, md: 6, lg: 4 }}>
|
||||
<div className="text-center">
|
||||
<small className="d-block mb-2 text-muted">Default / Hover</small>
|
||||
<CardImage
|
||||
image={SAMPLE_IMAGE}
|
||||
imageAlt="Default state"
|
||||
title="Default State"
|
||||
subtitle="Hover over this card to see the button animation. The entire card triggers the button's hover effect."
|
||||
buttonLabel="Medium Link"
|
||||
onClick={() => handleCardClick('default')}
|
||||
/>
|
||||
{clickedCard === 'default' && (
|
||||
<p className="mt-2 text-success">✓ Card clicked!</p>
|
||||
)}
|
||||
</div>
|
||||
</PageGridCol>
|
||||
|
||||
<PageGridCol span={{ base: 12, md: 6, lg: 4 }}>
|
||||
<div className="text-center">
|
||||
<small className="d-block mb-2 text-muted">Disabled</small>
|
||||
<CardImage
|
||||
image={SAMPLE_IMAGE}
|
||||
imageAlt="Disabled state"
|
||||
title="Disabled State"
|
||||
subtitle="This card is disabled. The button shows disabled styling and interactions are blocked."
|
||||
buttonLabel="Unavailable"
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Responsive Grid Demo */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Responsive Grid Layout</h2>
|
||||
<p className="mb-6">
|
||||
CardImage is designed to work with the PageGrid system. Resize your browser to see
|
||||
the responsive behavior: 4-column on desktop (LG), 2-column on tablet (MD), 1-column on mobile (SM).
|
||||
</p>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 12, md: 6, lg: 4 }}>
|
||||
<CardImage
|
||||
image={SAMPLE_IMAGE}
|
||||
imageAlt="Card 1"
|
||||
title="Documentation"
|
||||
subtitle="Access everything you need to get started working with the XRPL."
|
||||
buttonLabel="Get Started"
|
||||
href="#"
|
||||
/>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 12, md: 6, lg: 4 }}>
|
||||
<CardImage
|
||||
image={SAMPLE_IMAGE}
|
||||
imageAlt="Card 2"
|
||||
title="Tutorials"
|
||||
subtitle="Step-by-step guides to help you build on the XRP Ledger."
|
||||
buttonLabel="View Tutorials"
|
||||
href="#"
|
||||
/>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 12, md: 6, lg: 4 }}>
|
||||
<CardImage
|
||||
image={SAMPLE_IMAGE}
|
||||
imageAlt="Card 3"
|
||||
title="API Reference"
|
||||
subtitle="Comprehensive API documentation for all XRPL methods."
|
||||
buttonLabel="Explore API"
|
||||
href="#"
|
||||
/>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Color Palette - Light Mode */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Color Palette</h2>
|
||||
<p className="mb-6">
|
||||
All colors are mapped from <code>styles/_colors.scss</code>.
|
||||
The site defaults to <strong>dark mode</strong>. Light mode is activated via <code>html.light</code>.
|
||||
</p>
|
||||
|
||||
{/* Light Mode Colors */}
|
||||
<h5 className="mb-4">Light Mode (Default for this component)</h5>
|
||||
<div className="d-flex flex-column gap-3 mb-6">
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#FFFFFF', borderRadius: '4px', flexShrink: 0, border: '1px solid #CAD4DF' }}></div>
|
||||
<div>
|
||||
<strong>Card Background:</strong> <code>$white</code>
|
||||
<br />
|
||||
<small className="text-muted">#FFFFFF</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#CAD4DF', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div>
|
||||
<strong>Card Border:</strong> <code>$gray-300</code>
|
||||
<br />
|
||||
<small className="text-muted">#CAD4DF</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#F0F3F7', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div>
|
||||
<strong>Image Container:</strong> <code>$gray-100</code>
|
||||
<br />
|
||||
<small className="text-muted">#F0F3F7</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#141414', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div>
|
||||
<strong>Text Color:</strong> <code>#141414</code> (Neutral Black)
|
||||
<br />
|
||||
<small className="text-muted">Title and Subtitle</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Divider color="gray" className="my-6" />
|
||||
|
||||
{/* Dark Mode Colors */}
|
||||
<h5 className="mb-4">Dark Mode (<code>html.dark</code>)</h5>
|
||||
<div className="d-flex flex-column gap-3 mb-6">
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#111112', borderRadius: '4px', flexShrink: 0, border: '1px solid #444' }}></div>
|
||||
<div>
|
||||
<strong>Card Background:</strong> <code>$gray-900</code>
|
||||
<br />
|
||||
<small className="text-muted">#111112</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#72777E', borderRadius: '4px', flexShrink: 0, border: '1px solid #444' }}></div>
|
||||
<div>
|
||||
<strong>Image Container:</strong> <code>$gray-500</code>
|
||||
<br />
|
||||
<small className="text-muted">#72777E</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#FFFFFF', borderRadius: '4px', flexShrink: 0, border: '1px solid #444' }}></div>
|
||||
<div>
|
||||
<strong>Title:</strong> <code>$white</code>
|
||||
<br />
|
||||
<small className="text-muted">#FFFFFF</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#E6EAF0', borderRadius: '4px', flexShrink: 0, border: '1px solid #444' }}></div>
|
||||
<div>
|
||||
<strong>Subtitle:</strong> <code>$gray-200</code>
|
||||
<br />
|
||||
<small className="text-muted">#E6EAF0</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: 'rgba(114, 119, 126, 0.15)', borderRadius: '4px', flexShrink: 0, border: '1px solid #444' }}></div>
|
||||
<div>
|
||||
<strong>Hover Overlay:</strong> 15% black
|
||||
<br />
|
||||
<small className="text-muted">rgba(114, 119, 126, 0.15)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: 'rgba(114, 119, 126, 0.45)', borderRadius: '4px', flexShrink: 0, border: '1px solid #444' }}></div>
|
||||
<div>
|
||||
<strong>Pressed Overlay:</strong> 45% black
|
||||
<br />
|
||||
<small className="text-muted">rgba(114, 119, 126, 0.45)</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Dimensions */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Responsive Dimensions</h2>
|
||||
|
||||
<div className="mb-6">
|
||||
{/* Header Row */}
|
||||
<div className="d-flex flex-row mb-3 pb-2" style={{ gap: '1rem', borderBottom: '2px solid var(--bs-border-color, #dee2e6)' }}>
|
||||
<div style={{ width: '180px', flexShrink: 0 }}><strong>Variant</strong></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><strong>Breakpoint</strong></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><strong>Grid Columns</strong></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><strong>Card Height</strong></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><strong>Image Ratio</strong></div>
|
||||
</div>
|
||||
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '180px', flexShrink: 0 }}><strong>LG (Large)</strong></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>≥992px</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>4-column width</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>620px</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>1:1</code></div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '180px', flexShrink: 0 }}><strong>MD (Medium)</strong></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>576px - 991px</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>2-column width</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>560px</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>1:1</code></div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '180px', flexShrink: 0 }}><strong>SM (Small)</strong></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><576px</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>1-column width</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>536px</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>1:1</code></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Divider color="gray" className="my-6" />
|
||||
|
||||
<h5 className="mb-4">Spacing Tokens</h5>
|
||||
<div className="mb-6">
|
||||
{/* Header Row */}
|
||||
<div className="d-flex flex-row mb-3 pb-2" style={{ gap: '1rem', borderBottom: '2px solid var(--bs-border-color, #dee2e6)' }}>
|
||||
<div style={{ width: '220px', flexShrink: 0 }}><strong>Property</strong></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><strong>Value</strong></div>
|
||||
</div>
|
||||
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '220px', flexShrink: 0 }}>Image-to-content gap</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>24px</code></div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '220px', flexShrink: 0 }}>Title-to-subtitle gap</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>12px</code></div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '220px', flexShrink: 0 }}>Content horizontal padding</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>8px</code></div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '220px', flexShrink: 0 }}>Button margin-bottom</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>30px</code></div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '220px', flexShrink: 0 }}>Border radius</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>16px</code></div>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Typography */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Typography</h2>
|
||||
|
||||
<div className="d-flex flex-row gap-6 mb-6" style={{ flexWrap: 'wrap' }}>
|
||||
<div style={{ flex: '1 1 300px' }}>
|
||||
<h6 className="mb-3">Title (<code>.sh-md-l</code>)</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Font Size:</strong> 28px</li>
|
||||
<li><strong>Font Weight:</strong> 300 (light)</li>
|
||||
<li><strong>Line Height:</strong> 35px</li>
|
||||
<li><strong>Letter Spacing:</strong> -0.5px</li>
|
||||
<li><strong>Lines:</strong> 1 (truncated)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 300px' }}>
|
||||
<h6 className="mb-3">Subtitle (<code>.body-l</code>)</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Font Size:</strong> 18px</li>
|
||||
<li><strong>Font Weight:</strong> 300 (light)</li>
|
||||
<li><strong>Line Height:</strong> 26.1px</li>
|
||||
<li><strong>Letter Spacing:</strong> -0.5px</li>
|
||||
<li><strong>Lines:</strong> Max 3 (truncated)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Image Scaling Animation */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Image Scaling Animation</h2>
|
||||
<p className="mb-6">
|
||||
On hover, focus, and pressed states, the image inside the card scales up by <strong>10%</strong> while
|
||||
the image container remains fixed. This creates a subtle zoom effect that enhances interactivity without
|
||||
disrupting the card layout.
|
||||
</p>
|
||||
|
||||
<div className="d-flex flex-row gap-6 mb-6" style={{ flexWrap: 'wrap' }}>
|
||||
<div style={{ flex: '1 1 300px' }}>
|
||||
<h6 className="mb-3">Container Behavior</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Image box:</strong> Does NOT increase</li>
|
||||
<li><strong>Overflow:</strong> Hidden (clips scaled content)</li>
|
||||
<li><strong>Background:</strong> Remains visible at edges</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 300px' }}>
|
||||
<h6 className="mb-3">Image Behavior</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Scale:</strong> 110% (1.1x) on interaction</li>
|
||||
<li><strong>Transform origin:</strong> Center</li>
|
||||
<li><strong>Transition:</strong> 150ms cubic-bezier</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 300px' }}>
|
||||
<h6 className="mb-3">Trigger States</h6>
|
||||
<ul className="mb-0">
|
||||
<li>Hover (mouse over card)</li>
|
||||
<li>Focus (keyboard navigation)</li>
|
||||
<li>Pressed (active click)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 12, md: 6, lg: 4 }}>
|
||||
<div className="text-center">
|
||||
<small className="d-block mb-2 text-muted">Hover to see image zoom (fullBleed)</small>
|
||||
<CardImage
|
||||
image={IMAGE_SCALING_DEMO}
|
||||
imageAlt="3D metallic cubes illustration"
|
||||
title="Documentation"
|
||||
subtitle="Access everything you need to get started working with the XRPL. Line 3"
|
||||
buttonLabel="Medium Link"
|
||||
onClick={() => handleCardClick('image-scale')}
|
||||
fullBleed
|
||||
/>
|
||||
{clickedCard === 'image-scale' && (
|
||||
<p className="mt-2 text-success">✓ Card clicked!</p>
|
||||
)}
|
||||
</div>
|
||||
</PageGridCol>
|
||||
|
||||
<PageGridCol span={{ base: 12, md: 6, lg: 4 }}>
|
||||
<div className="text-center">
|
||||
<small className="d-block mb-2 text-muted">Custom backgroundColor</small>
|
||||
<CardImage
|
||||
image={SAMPLE_IMAGE}
|
||||
imageAlt="Sample illustration"
|
||||
title="Custom Background"
|
||||
subtitle="This card has a custom background color set via the backgroundColor prop."
|
||||
buttonLabel="Medium Link"
|
||||
onClick={() => handleCardClick('custom-bg')}
|
||||
backgroundColor="#1a1a2e"
|
||||
/>
|
||||
{clickedCard === 'custom-bg' && (
|
||||
<p className="mt-2 text-success">✓ Card clicked!</p>
|
||||
)}
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Animation Details */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Animation Specifications</h2>
|
||||
|
||||
<div className="d-flex flex-row gap-6 mb-6" style={{ flexWrap: 'wrap' }}>
|
||||
<div style={{ flex: '1 1 300px' }}>
|
||||
<h6 className="mb-3">Timing</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Duration:</strong> 150ms</li>
|
||||
<li><strong>Easing:</strong> <code>cubic-bezier(0.98, 0.12, 0.12, 0.98)</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 300px' }}>
|
||||
<h6 className="mb-3">Card Hover → Button Animation</h6>
|
||||
<ul className="mb-0">
|
||||
<li>Button background fills bottom → top</li>
|
||||
<li>Arrow icon line shrinks</li>
|
||||
<li>Gap between label and icon increases</li>
|
||||
<li>Padding adjusts for smooth transition</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 300px' }}>
|
||||
<h6 className="mb-3">State Flow</h6>
|
||||
<ul className="mb-0">
|
||||
<li>Default → Hover → Pressed</li>
|
||||
<li>Card hover triggers button hover</li>
|
||||
<li>Focus ring on keyboard navigation</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* API Reference */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Component API</h2>
|
||||
<div className="mb-10">
|
||||
{/* Header Row */}
|
||||
<div className="d-flex flex-row mb-3 pb-2" style={{ gap: '1rem', borderBottom: '2px solid var(--bs-border-color, #dee2e6)' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><strong>Prop</strong></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><strong>Type</strong></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><strong>Default</strong></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><strong>Description</strong></div>
|
||||
</div>
|
||||
|
||||
{/* image */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>image</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>string</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}>required</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Image source URL</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* imageAlt */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>imageAlt</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>string</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}>required</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Alt text for the image</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* title */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>title</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>string</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}>required</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Card title (1 line only)</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* subtitle */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>subtitle</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>string</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}>required</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Card subtitle (max 3 lines)</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* buttonLabel */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>buttonLabel</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>string</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}>required</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Button label text</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* href */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>href</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>string</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>undefined</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Link destination (makes card clickable)</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* onClick */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>onClick</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>() => void</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>undefined</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Click handler for button</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* disabled */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>disabled</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>boolean</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>false</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Disabled state</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* className */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>className</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>string</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>''</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Additional CSS classes</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Usage Examples */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Usage Examples</h2>
|
||||
|
||||
<div className="d-flex flex-column gap-6">
|
||||
{/* Basic Usage */}
|
||||
<div className="card p-4">
|
||||
<h6 className="mb-3">Basic Usage with Link</h6>
|
||||
<pre className="mb-0" style={{ backgroundColor: 'var(--bs-gray-800)', padding: '1rem', borderRadius: '4px', overflow: 'auto' }}>
|
||||
{`import { CardImage } from 'shared/components/CardImage';
|
||||
|
||||
<CardImage
|
||||
image="/images/docs-hero.png"
|
||||
imageAlt="Documentation illustration"
|
||||
title="Documentation"
|
||||
subtitle="Access everything you need to get started..."
|
||||
buttonLabel="Get Started"
|
||||
href="/docs"
|
||||
/>`}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
{/* With Click Handler */}
|
||||
<div className="card p-4">
|
||||
<h6 className="mb-3">With Click Handler</h6>
|
||||
<pre className="mb-0" style={{ backgroundColor: 'var(--bs-gray-800)', padding: '1rem', borderRadius: '4px', overflow: 'auto' }}>
|
||||
{`<CardImage
|
||||
image="/images/feature.png"
|
||||
imageAlt="Feature illustration"
|
||||
title="New Feature"
|
||||
subtitle="Learn about our latest feature..."
|
||||
buttonLabel="Learn More"
|
||||
onClick={() => console.log('clicked')}
|
||||
/>`}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
{/* In PageGrid */}
|
||||
<div className="card p-4">
|
||||
<h6 className="mb-3">With PageGrid (Responsive 4-Column)</h6>
|
||||
<pre className="mb-0" style={{ backgroundColor: 'var(--bs-gray-800)', padding: '1rem', borderRadius: '4px', overflow: 'auto' }}>
|
||||
{`import { PageGrid, PageGridRow, PageGridCol } from 'shared/components/PageGrid/page-grid';
|
||||
import { CardImage } from 'shared/components/CardImage';
|
||||
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 12, md: 6, lg: 4 }}>
|
||||
<CardImage
|
||||
image="/images/card1.png"
|
||||
imageAlt="Card 1"
|
||||
title="Documentation"
|
||||
subtitle="Access everything you need..."
|
||||
buttonLabel="Get Started"
|
||||
href="/docs"
|
||||
/>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 12, md: 6, lg: 4 }}>
|
||||
<CardImage
|
||||
image="/images/card2.png"
|
||||
imageAlt="Card 2"
|
||||
title="Tutorials"
|
||||
subtitle="Step-by-step guides..."
|
||||
buttonLabel="View Tutorials"
|
||||
href="/tutorials"
|
||||
/>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 12, md: 6, lg: 4 }}>
|
||||
<CardImage
|
||||
image="/images/card3.png"
|
||||
imageAlt="Card 3"
|
||||
title="API Reference"
|
||||
subtitle="Comprehensive API docs..."
|
||||
buttonLabel="Explore API"
|
||||
href="/api"
|
||||
/>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>`}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
{/* Disabled State */}
|
||||
<div className="card p-4">
|
||||
<h6 className="mb-3">Disabled State</h6>
|
||||
<pre className="mb-0" style={{ backgroundColor: 'var(--bs-gray-800)', padding: '1rem', borderRadius: '4px', overflow: 'auto' }}>
|
||||
{`<CardImage
|
||||
image="/images/coming-soon.png"
|
||||
imageAlt="Coming soon"
|
||||
title="Coming Soon"
|
||||
subtitle="This feature is not yet available..."
|
||||
buttonLabel="Unavailable"
|
||||
disabled
|
||||
/>`}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Figma References */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Figma References</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://www.figma.com/design/3KewCK6ylLtHm9Yd3eSZqs/Card---Image?node-id=4139-185&m=dev" target="_blank" rel="noopener noreferrer">
|
||||
Light Mode Design States
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.figma.com/design/3KewCK6ylLtHm9Yd3eSZqs/Card---Image?node-id=4139-245&m=dev" target="_blank" rel="noopener noreferrer">
|
||||
Dark Mode Design States
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.figma.com/design/3KewCK6ylLtHm9Yd3eSZqs/Card---Image?node-id=4171-104&m=dev" target="_blank" rel="noopener noreferrer">
|
||||
Image Scaling Animation Spec
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,630 +0,0 @@
|
||||
import * as React from "react";
|
||||
import { PageGrid, PageGridRow, PageGridCol } from "shared/components/PageGrid/page-grid";
|
||||
import { CardOffgrid } from "shared/components/CardOffgrid";
|
||||
import { Divider } from "shared/components/Divider";
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
title: 'CardOffgrid Component Showcase',
|
||||
description: "A comprehensive showcase of all CardOffgrid component variants, states, and interactions in the XRPL.org Design System.",
|
||||
}
|
||||
};
|
||||
|
||||
// Sample icon component for demonstration
|
||||
const SampleIcon = () => (
|
||||
<svg width="68" height="68" viewBox="0 0 68 68" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M34 8L58 20V44L34 56L10 44V20L34 8Z" stroke="currentColor" strokeWidth="2" fill="none"/>
|
||||
<path d="M34 8V32M34 32L58 20M34 32L10 20" stroke="currentColor" strokeWidth="2"/>
|
||||
<path d="M34 32V56" stroke="currentColor" strokeWidth="2"/>
|
||||
<circle cx="34" cy="32" r="6" fill="currentColor"/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
// Alternative icon for variety
|
||||
const MetadataIcon = () => (
|
||||
<svg width="68" height="68" viewBox="0 0 68 68" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14 18C14 15.7909 15.7909 14 18 14H50C52.2091 14 54 15.7909 54 18V50C54 52.2091 52.2091 54 50 54H18C15.7909 54 14 52.2091 14 50V18Z" stroke="currentColor" strokeWidth="2"/>
|
||||
<path d="M22 26H46M22 34H46M22 42H34" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
// Chain icon
|
||||
const ChainIcon = () => (
|
||||
<svg width="68" height="68" viewBox="0 0 68 68" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M28 34H40M24 28C24 25.7909 25.7909 24 28 24H32C34.2091 24 36 25.7909 36 28V40C36 42.2091 34.2091 44 32 44H28C25.7909 44 24 42.2091 24 40V28Z" stroke="currentColor" strokeWidth="2"/>
|
||||
<path d="M32 28C32 25.7909 33.7909 24 36 24H40C42.2091 24 44 25.7909 44 28V40C44 42.2091 42.2091 44 40 44H36C33.7909 44 32 42.2091 32 40V28Z" stroke="currentColor" strokeWidth="2"/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export default function CardOffgridShowcase() {
|
||||
const [clickedCard, setClickedCard] = React.useState<string | null>(null);
|
||||
|
||||
const handleCardClick = (cardName: string) => {
|
||||
setClickedCard(cardName);
|
||||
setTimeout(() => setClickedCard(null), 1500);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="landing">
|
||||
<div className="overflow-hidden">
|
||||
{/* Hero Section */}
|
||||
<section className="py-26 text-center">
|
||||
<div className="col-lg-8 mx-auto">
|
||||
<h6 className="eyebrow mb-3">Component Showcase</h6>
|
||||
<h1 className="mb-4">CardOffgrid Component</h1>
|
||||
<p className="longform">
|
||||
A versatile card component for displaying feature highlights with an icon, title, and description.
|
||||
Supports neutral and green color variants with interactive states and bottom-to-top gradient hover animation.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Variant Showcase */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Color Variants</h2>
|
||||
<p className="mb-6">CardOffgrid supports two color variants: <strong>neutral</strong> (default) and <strong>green</strong>.</p>
|
||||
|
||||
<div className="d-flex flex-row gap-6 mb-6" style={{ flexWrap: 'wrap' }}>
|
||||
<div>
|
||||
<h6 className="mb-3">Neutral Variant (Default)</h6>
|
||||
<CardOffgrid
|
||||
variant="neutral"
|
||||
icon={<SampleIcon />}
|
||||
title={"Onchain\nMetadata"}
|
||||
description="Easily store key asset information or link to off-chain data using simple APIs, giving token holders transparency."
|
||||
onClick={() => handleCardClick('neutral')}
|
||||
/>
|
||||
{clickedCard === 'neutral' && (
|
||||
<p className="mt-2 text-success">✓ Card clicked!</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h6 className="mb-3">Green Variant</h6>
|
||||
<CardOffgrid
|
||||
variant="green"
|
||||
icon={<SampleIcon />}
|
||||
title={"Onchain\nMetadata"}
|
||||
description="Easily store key asset information or link to off-chain data using simple APIs, giving token holders transparency."
|
||||
onClick={() => handleCardClick('green')}
|
||||
/>
|
||||
{clickedCard === 'green' && (
|
||||
<p className="mt-2 text-success">✓ Card clicked!</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Interactive States */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Interactive States</h2>
|
||||
<p className="mb-6">Hover, focus, and press the cards below to see the state transitions.</p>
|
||||
|
||||
{/* Neutral States */}
|
||||
<h5 className="mb-4">Neutral Variant States</h5>
|
||||
<div className="d-flex flex-row gap-4 mb-8" style={{ flexWrap: 'wrap' }}>
|
||||
<div className="text-center">
|
||||
<small className="d-block mb-2 text-muted">Default</small>
|
||||
<CardOffgrid
|
||||
variant="neutral"
|
||||
icon={<MetadataIcon />}
|
||||
title={"Token\nManagement"}
|
||||
description="Create and manage fungible and non-fungible tokens with built-in compliance features."
|
||||
onClick={() => handleCardClick('neutral-default')}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<small className="d-block mb-2 text-muted">Disabled</small>
|
||||
<CardOffgrid
|
||||
variant="neutral"
|
||||
icon={<MetadataIcon />}
|
||||
title={"Token\nManagement"}
|
||||
description="Create and manage fungible and non-fungible tokens with built-in compliance features."
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Green States */}
|
||||
<h5 className="mb-4">Green Variant States</h5>
|
||||
<div className="d-flex flex-row gap-4 mb-6" style={{ flexWrap: 'wrap' }}>
|
||||
<div className="text-center">
|
||||
<small className="d-block mb-2 text-muted">Default</small>
|
||||
<CardOffgrid
|
||||
variant="green"
|
||||
icon={<ChainIcon />}
|
||||
title={"Cross-Chain\nBridges"}
|
||||
description="Connect XRPL with other blockchain networks through secure and efficient bridge protocols."
|
||||
onClick={() => handleCardClick('green-default')}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<small className="d-block mb-2 text-muted">Disabled</small>
|
||||
<CardOffgrid
|
||||
variant="green"
|
||||
icon={<ChainIcon />}
|
||||
title={"Cross-Chain\nBridges"}
|
||||
description="Connect XRPL with other blockchain networks through secure and efficient bridge protocols."
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Color Palette */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Color Palette</h2>
|
||||
<p className="mb-6">
|
||||
All colors are mapped from <code>styles/_colors.scss</code>.
|
||||
The site defaults to <strong>dark mode</strong>. Light mode is activated via <code>html.light</code>.
|
||||
</p>
|
||||
|
||||
{/* Dark Mode Colors */}
|
||||
<h5 className="mb-4">Dark Mode (Default)</h5>
|
||||
<div className="d-flex flex-row gap-6 mb-6" style={{ flexWrap: 'wrap' }}>
|
||||
{/* Neutral Colors - Dark */}
|
||||
<div style={{ flex: '1 1 400px', minWidth: '320px' }}>
|
||||
<h6 className="mb-4">Neutral Variant</h6>
|
||||
<div className="d-flex flex-column gap-3">
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#72777E', borderRadius: '4px', flexShrink: 0, border: '1px solid #444' }}></div>
|
||||
<div>
|
||||
<strong>Default:</strong> <code>$gray-500</code>
|
||||
<br />
|
||||
<small className="text-muted">#72777E (white text)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#8A919A', borderRadius: '4px', flexShrink: 0, border: '1px solid #444' }}></div>
|
||||
<div>
|
||||
<strong>Hover/Focus:</strong> <code>$gray-400</code>
|
||||
<br />
|
||||
<small className="text-muted">#8A919A (white text)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: 'rgba(114, 119, 126, 0.7)', borderRadius: '4px', flexShrink: 0, border: '1px solid #444' }}></div>
|
||||
<div>
|
||||
<strong>Pressed:</strong> <code>rgba($gray-500, 0.7)</code>
|
||||
<br />
|
||||
<small className="text-muted">70% opacity</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#72777E', borderRadius: '4px', flexShrink: 0, border: '1px solid #444', opacity: 0.3 }}></div>
|
||||
<div>
|
||||
<strong>Disabled:</strong> <code>$gray-500 @ 30%</code>
|
||||
<br />
|
||||
<small className="text-muted">opacity: 0.3</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Green Colors - Dark */}
|
||||
<div style={{ flex: '1 1 400px', minWidth: '320px' }}>
|
||||
<h6 className="mb-4">Green Variant</h6>
|
||||
<div className="d-flex flex-column gap-3">
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#21E46B', borderRadius: '4px', flexShrink: 0, border: '1px solid #444' }}></div>
|
||||
<div>
|
||||
<strong>Default:</strong> <code>$green-300</code>
|
||||
<br />
|
||||
<small className="text-muted">#21E46B (black text)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#70EE97', borderRadius: '4px', flexShrink: 0, border: '1px solid #444' }}></div>
|
||||
<div>
|
||||
<strong>Hover/Focus:</strong> <code>$green-200</code>
|
||||
<br />
|
||||
<small className="text-muted">#70EE97 (black text)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#0DAA3E', borderRadius: '4px', flexShrink: 0, border: '1px solid #444' }}></div>
|
||||
<div>
|
||||
<strong>Pressed:</strong> <code>$green-400</code>
|
||||
<br />
|
||||
<small className="text-muted">#0DAA3E (black text)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#72777E', borderRadius: '4px', flexShrink: 0, border: '1px solid #444', opacity: 0.3 }}></div>
|
||||
<div>
|
||||
<strong>Disabled:</strong> <code>$gray-500 @ 30%</code>
|
||||
<br />
|
||||
<small className="text-muted">opacity: 0.3 (white text)</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Divider color="gray" className="my-6" />
|
||||
|
||||
{/* Light Mode Colors */}
|
||||
<h5 className="mb-4">Light Mode (<code>html.light</code>)</h5>
|
||||
<div className="d-flex flex-row gap-6 mb-6" style={{ flexWrap: 'wrap' }}>
|
||||
{/* Neutral Colors - Light */}
|
||||
<div style={{ flex: '1 1 400px', minWidth: '320px' }}>
|
||||
<h6 className="mb-4">Neutral Variant</h6>
|
||||
<div className="d-flex flex-column gap-3">
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#E6EAF0', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div>
|
||||
<strong>Default:</strong> <code>$gray-200</code>
|
||||
<br />
|
||||
<small className="text-muted">#E6EAF0 (dark text)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#CAD4DF', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div>
|
||||
<strong>Hover/Focus:</strong> <code>$gray-300</code>
|
||||
<br />
|
||||
<small className="text-muted">#CAD4DF (black text)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#8A919A', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div>
|
||||
<strong>Pressed:</strong> <code>$gray-400</code>
|
||||
<br />
|
||||
<small className="text-muted">#8A919A (black text)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#F0F3F7', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div>
|
||||
<strong>Disabled:</strong> <code>$gray-100</code>
|
||||
<br />
|
||||
<small className="text-muted">#F0F3F7 (gray text)</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Green Colors - Light */}
|
||||
<div style={{ flex: '1 1 400px', minWidth: '320px' }}>
|
||||
<h6 className="mb-4">Green Variant</h6>
|
||||
<div className="d-flex flex-column gap-3">
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#70EE97', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div>
|
||||
<strong>Default:</strong> <code>$green-200</code>
|
||||
<br />
|
||||
<small className="text-muted">#70EE97 (black text)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#21E46B', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div>
|
||||
<strong>Hover/Focus:</strong> <code>$green-300</code>
|
||||
<br />
|
||||
<small className="text-muted">#21E46B (black text)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#0DAA3E', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div>
|
||||
<strong>Pressed:</strong> <code>$green-400</code>
|
||||
<br />
|
||||
<small className="text-muted">#0DAA3E (black text)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '60px', height: '40px', backgroundColor: '#F0F3F7', borderRadius: '4px', flexShrink: 0, border: '1px solid #ccc' }}></div>
|
||||
<div>
|
||||
<strong>Disabled:</strong> <code>$gray-100</code>
|
||||
<br />
|
||||
<small className="text-muted">#F0F3F7 (gray text)</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Animation Details */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Animation Specifications</h2>
|
||||
|
||||
<div className="d-flex flex-row gap-6 mb-6" style={{ flexWrap: 'wrap' }}>
|
||||
<div style={{ flex: '1 1 300px' }}>
|
||||
<h6 className="mb-3">Timing</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Duration:</strong> 200ms</li>
|
||||
<li><strong>Easing:</strong> <code>cubic-bezier(0.98, 0.12, 0.12, 0.98)</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 300px' }}>
|
||||
<h6 className="mb-3">Hover Effect ("Window Shade")</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Hover in:</strong> Shade rises up (bottom → top)</li>
|
||||
<li><strong>Hover out:</strong> Shade falls down (top → bottom)</li>
|
||||
<li>Darker pressed state on click</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 300px' }}>
|
||||
<h6 className="mb-3">State Flow</h6>
|
||||
<ul className="mb-0">
|
||||
<li>Default → Hover → Pressed</li>
|
||||
<li>Full card area is clickable</li>
|
||||
<li>Focus ring on keyboard navigation</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Dimensions */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Dimensions</h2>
|
||||
|
||||
<div className="mb-6">
|
||||
{/* Header Row */}
|
||||
<div className="d-flex flex-row mb-3 pb-2" style={{ gap: '1rem', borderBottom: '2px solid var(--bs-border-color, #dee2e6)' }}>
|
||||
<div style={{ width: '180px', flexShrink: 0 }}><strong>Property</strong></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><strong>Value</strong></div>
|
||||
</div>
|
||||
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '180px', flexShrink: 0 }}>Card Width</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>400px</code> (full-width on mobile)</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '180px', flexShrink: 0 }}>Card Height</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>480px</code></div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '180px', flexShrink: 0 }}>Padding</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>24px</code></div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '180px', flexShrink: 0 }}>Icon Container</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>84px × 84px</code></div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '180px', flexShrink: 0 }}>Icon Size</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>~68px × 68px</code></div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '180px', flexShrink: 0 }}>Content Gap</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>40px</code> (between title and description)</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Typography */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Typography</h2>
|
||||
|
||||
<div className="d-flex flex-row gap-6 mb-6" style={{ flexWrap: 'wrap' }}>
|
||||
<div style={{ flex: '1 1 300px' }}>
|
||||
<h6 className="mb-3">Title</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Font Size:</strong> 32px</li>
|
||||
<li><strong>Font Weight:</strong> 300 (light)</li>
|
||||
<li><strong>Line Height:</strong> 40px</li>
|
||||
<li><strong>Letter Spacing:</strong> -1px</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 300px' }}>
|
||||
<h6 className="mb-3">Description</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Font Size:</strong> 18px</li>
|
||||
<li><strong>Font Weight:</strong> 300 (light)</li>
|
||||
<li><strong>Line Height:</strong> 26.1px</li>
|
||||
<li><strong>Letter Spacing:</strong> -0.5px</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* API Reference */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Component API</h2>
|
||||
<div className="mb-10">
|
||||
{/* Header Row */}
|
||||
<div className="d-flex flex-row mb-3 pb-2" style={{ gap: '1rem', borderBottom: '2px solid var(--bs-border-color, #dee2e6)' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><strong>Prop</strong></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><strong>Type</strong></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><strong>Default</strong></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><strong>Description</strong></div>
|
||||
</div>
|
||||
|
||||
{/* variant */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>variant</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>'neutral' | 'green'</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>'neutral'</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Color variant of the card</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* icon */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>icon</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>ReactNode | string</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}>required</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Icon element or image URL</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* title */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>title</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>string</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}>required</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Card title (use \n for line breaks)</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* description */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>description</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>string</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}>required</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Card description text</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* onClick */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>onClick</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>() => void</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>undefined</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Click handler (renders as button)</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* href */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>href</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>string</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>undefined</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Link destination (renders as anchor)</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* disabled */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>disabled</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>boolean</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>false</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Disabled state</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* className */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>className</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>string</code></div>
|
||||
<div style={{ width: '100px', flexShrink: 0 }}><code>''</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Additional CSS classes</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Usage Examples */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Usage Examples</h2>
|
||||
|
||||
<div className="d-flex flex-column gap-6">
|
||||
{/* Basic Usage */}
|
||||
<div className="card p-4">
|
||||
<h6 className="mb-3">Basic Usage</h6>
|
||||
<pre className="mb-0" style={{ backgroundColor: 'var(--bs-gray-800)', padding: '1rem', borderRadius: '4px', overflow: 'auto' }}>
|
||||
{`import { CardOffgrid } from 'shared/components/CardOffgrid';
|
||||
|
||||
<CardOffgrid
|
||||
variant="neutral"
|
||||
icon={<MyIcon />}
|
||||
title="Onchain\\nMetadata"
|
||||
description="Easily store key asset information..."
|
||||
onClick={() => console.log('clicked')}
|
||||
/>`}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
{/* With Link */}
|
||||
<div className="card p-4">
|
||||
<h6 className="mb-3">With Link</h6>
|
||||
<pre className="mb-0" style={{ backgroundColor: 'var(--bs-gray-800)', padding: '1rem', borderRadius: '4px', overflow: 'auto' }}>
|
||||
{`<CardOffgrid
|
||||
variant="green"
|
||||
icon="/icons/metadata.svg"
|
||||
title="Learn More"
|
||||
description="Click to navigate to documentation..."
|
||||
href="/docs/metadata"
|
||||
/>`}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
{/* Disabled State */}
|
||||
<div className="card p-4">
|
||||
<h6 className="mb-3">Disabled State</h6>
|
||||
<pre className="mb-0" style={{ backgroundColor: 'var(--bs-gray-800)', padding: '1rem', borderRadius: '4px', overflow: 'auto' }}>
|
||||
{`<CardOffgrid
|
||||
variant="neutral"
|
||||
icon={<MyIcon />}
|
||||
title="Coming Soon"
|
||||
description="This feature is not yet available..."
|
||||
disabled
|
||||
/>`}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Figma References */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Figma References</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://www.figma.com/design/vwDwMJ3mFrAklj5zvZwX5M/Card---OffGrid?node-id=8001-1963&m=dev" target="_blank" rel="noopener noreferrer">
|
||||
Light Mode Color States
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.figma.com/design/vwDwMJ3mFrAklj5zvZwX5M/Card---OffGrid?node-id=8001-2321&m=dev" target="_blank" rel="noopener noreferrer">
|
||||
Dark Mode Color States
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.figma.com/design/vwDwMJ3mFrAklj5zvZwX5M/Card---OffGrid?node-id=8007-1096&m=dev" target="_blank" rel="noopener noreferrer">
|
||||
Animation Specifications
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,537 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { CardStat } from 'shared/components/CardStat';
|
||||
import { PageGrid, PageGridCol, PageGridRow } from 'shared/components/PageGrid/page-grid';
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
title: 'CardStat Component Showcase',
|
||||
description: 'Interactive showcase of the Brand Design System CardStat component with all variants and configurations.',
|
||||
},
|
||||
};
|
||||
|
||||
export default function CardStatShowcase() {
|
||||
const [clickCount, setClickCount] = React.useState<Record<string, number>>({});
|
||||
|
||||
const handleClick = (id: string) => {
|
||||
setClickCount((prev) => ({ ...prev, [id]: (prev[id] || 0) + 1 }));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="landing">
|
||||
{/* Hero Section */}
|
||||
<PageGrid className="py-26">
|
||||
<div className="d-flex flex-column-reverse col-lg-8 mx-auto">
|
||||
<h1 className="mb-0">CardStat Component</h1>
|
||||
<h6 className="eyebrow mb-3">Brand Design System</h6>
|
||||
</div>
|
||||
<p className="col-lg-8 mx-auto mt-10">
|
||||
A statistics card component following the XRPL Brand Design System. This showcase demonstrates
|
||||
all color variants, button configurations, and responsive behavior using PageGrid.
|
||||
</p>
|
||||
</PageGrid>
|
||||
|
||||
{/* Basic Usage */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<div className="d-flex flex-column-reverse w-100">
|
||||
<h2 className="h4 mb-8">Basic Usage</h2>
|
||||
<h6 className="eyebrow mb-3">Simple Statistics</h6>
|
||||
</div>
|
||||
<p className="mb-8">
|
||||
CardStat components display prominent statistics with descriptive labels. They adapt responsively
|
||||
and can be used without buttons for purely informational displays.
|
||||
</p>
|
||||
</PageGridRow>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardStat
|
||||
statistic="6 Million"
|
||||
superscript="2"
|
||||
label="Active wallets"
|
||||
variant="lilac"
|
||||
/>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardStat
|
||||
statistic="$1 Trillion"
|
||||
superscript="*"
|
||||
label="Value moved"
|
||||
variant="green"
|
||||
/>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardStat
|
||||
statistic="12"
|
||||
superscript="+"
|
||||
label="Continuous uptime years"
|
||||
variant="light-gray"
|
||||
/>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Color Variants */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<div className="d-flex flex-column-reverse w-100">
|
||||
<h2 className="h4 mb-8">Color Variants</h2>
|
||||
<h6 className="eyebrow mb-3">Visual Themes</h6>
|
||||
</div>
|
||||
<p className="mb-8">
|
||||
Four color variants are available to match different types of statistics and visual contexts.
|
||||
</p>
|
||||
</PageGridRow>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 3 }}>
|
||||
<CardStat
|
||||
statistic="6M"
|
||||
superscript="+"
|
||||
label="Active wallets"
|
||||
variant="lilac"
|
||||
/>
|
||||
<p className="mt-4 text-muted"><strong>Lilac</strong> - User metrics, community stats</p>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 3 }}>
|
||||
<CardStat
|
||||
statistic="$1T"
|
||||
superscript="+"
|
||||
label="Value moved"
|
||||
variant="green"
|
||||
/>
|
||||
<p className="mt-4 text-muted"><strong>Green</strong> - Financial metrics, growth</p>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 3 }}>
|
||||
<CardStat
|
||||
statistic="12"
|
||||
superscript="+"
|
||||
label="Uptime years"
|
||||
variant="light-gray"
|
||||
/>
|
||||
<p className="mt-4 text-muted"><strong>Light Gray</strong> - Technical stats, reliability</p>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 3 }}>
|
||||
<CardStat
|
||||
statistic="70+"
|
||||
label="Partners"
|
||||
variant="dark-gray"
|
||||
/>
|
||||
<p className="mt-4 text-muted"><strong>Dark Gray</strong> - Neutral metrics, secondary info</p>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* With Single Button */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<div className="d-flex flex-column-reverse w-full">
|
||||
<h2 className="h4 mb-8">With Primary Button</h2>
|
||||
<h6 className="eyebrow mb-3">Single CTA</h6>
|
||||
</div>
|
||||
<p className="mb-8">
|
||||
Add a primary button for a main call-to-action. Buttons use the black variant for proper
|
||||
contrast on colored backgrounds.
|
||||
</p>
|
||||
</PageGridRow>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 6 }}>
|
||||
<CardStat
|
||||
statistic="6 Million"
|
||||
superscript="+"
|
||||
label="Active wallets"
|
||||
variant="lilac"
|
||||
primaryButton={{
|
||||
label: "Explore",
|
||||
onClick: () => handleClick('explore-1')
|
||||
}}
|
||||
/>
|
||||
{clickCount['explore-1'] > 0 && (
|
||||
<p className="mt-4 text-muted">Clicked {clickCount['explore-1']} time{clickCount['explore-1'] !== 1 ? 's' : ''}</p>
|
||||
)}
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 6 }}>
|
||||
<CardStat
|
||||
statistic="$1 Trillion"
|
||||
superscript="+"
|
||||
label="Value moved"
|
||||
variant="green"
|
||||
primaryButton={{
|
||||
label: "Learn More",
|
||||
onClick: () => handleClick('learn-1')
|
||||
}}
|
||||
/>
|
||||
{clickCount['learn-1'] > 0 && (
|
||||
<p className="mt-4 text-muted">Clicked {clickCount['learn-1']} time{clickCount['learn-1'] !== 1 ? 's' : ''}</p>
|
||||
)}
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 12 }}>
|
||||
<CardStat
|
||||
statistic="12"
|
||||
superscript="+"
|
||||
label="Continuous uptime years"
|
||||
variant="light-gray"
|
||||
primaryButton={{
|
||||
label: "View Details",
|
||||
onClick: () => handleClick('view-1')
|
||||
}}
|
||||
/>
|
||||
{clickCount['view-1'] > 0 && (
|
||||
<p className="mt-4 text-muted">Clicked {clickCount['view-1']} time{clickCount['view-1'] !== 1 ? 's' : ''}</p>
|
||||
)}
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* With Two Buttons */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<div className="d-flex flex-column-reverse w-full">
|
||||
<h2 className="h4 mb-8">With Two Buttons</h2>
|
||||
<h6 className="eyebrow mb-3">Multiple CTAs</h6>
|
||||
</div>
|
||||
<p className="mb-8">
|
||||
Include both primary and secondary buttons for multiple action options. Buttons wrap responsively
|
||||
and maintain consistent spacing.
|
||||
</p>
|
||||
</PageGridRow>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardStat
|
||||
statistic="6 Million"
|
||||
superscript="+"
|
||||
label="Active wallets"
|
||||
variant="lilac"
|
||||
primaryButton={{
|
||||
label: "Learn More",
|
||||
onClick: () => handleClick('primary-1')
|
||||
}}
|
||||
secondaryButton={{
|
||||
label: "Get Started",
|
||||
onClick: () => handleClick('secondary-1')
|
||||
}}
|
||||
/>
|
||||
{(clickCount['primary-1'] > 0 || clickCount['secondary-1'] > 0) && (
|
||||
<p className="mt-4 text-muted">
|
||||
Primary: {clickCount['primary-1'] || 0}, Secondary: {clickCount['secondary-1'] || 0}
|
||||
</p>
|
||||
)}
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardStat
|
||||
statistic="$1 Trillion"
|
||||
superscript="+"
|
||||
label="Value moved"
|
||||
variant="green"
|
||||
primaryButton={{
|
||||
label: "Explore",
|
||||
onClick: () => handleClick('primary-2')
|
||||
}}
|
||||
secondaryButton={{
|
||||
label: "View Stats",
|
||||
onClick: () => handleClick('secondary-2')
|
||||
}}
|
||||
/>
|
||||
{(clickCount['primary-2'] > 0 || clickCount['secondary-2'] > 0) && (
|
||||
<p className="mt-4 text-muted">
|
||||
Primary: {clickCount['primary-2'] || 0}, Secondary: {clickCount['secondary-2'] || 0}
|
||||
</p>
|
||||
)}
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardStat
|
||||
statistic="12"
|
||||
superscript="+"
|
||||
label="Continuous uptime years"
|
||||
variant="light-gray"
|
||||
primaryButton={{
|
||||
label: "Read More",
|
||||
onClick: () => handleClick('primary-3')
|
||||
}}
|
||||
secondaryButton={{
|
||||
label: "Try It",
|
||||
onClick: () => handleClick('secondary-3')
|
||||
}}
|
||||
/>
|
||||
{(clickCount['primary-3'] > 0 || clickCount['secondary-3'] > 0) && (
|
||||
<p className="mt-4 text-muted">
|
||||
Primary: {clickCount['primary-3'] || 0}, Secondary: {clickCount['secondary-3'] || 0}
|
||||
</p>
|
||||
)}
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Responsive Behavior */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<div className="d-flex flex-column-reverse w-full">
|
||||
<h2 className="h4 mb-8">Responsive Layout</h2>
|
||||
<h6 className="eyebrow mb-3">Adaptive Grid</h6>
|
||||
</div>
|
||||
<p className="mb-8">
|
||||
Cards adapt to different screen sizes. On mobile (base), cards stack vertically. On tablet (md),
|
||||
they can be arranged in 2 columns. On desktop (lg+), up to 3-4 columns are supported.
|
||||
</p>
|
||||
</PageGridRow>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 3 }}>
|
||||
<CardStat
|
||||
statistic="1M"
|
||||
superscript="+"
|
||||
label="Transactions daily"
|
||||
variant="lilac"
|
||||
/>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 3 }}>
|
||||
<CardStat
|
||||
statistic="150"
|
||||
superscript="+"
|
||||
label="Countries"
|
||||
variant="green"
|
||||
/>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 3 }}>
|
||||
<CardStat
|
||||
statistic="99.9"
|
||||
superscript="%"
|
||||
label="Uptime"
|
||||
variant="light-gray"
|
||||
/>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 3 }}>
|
||||
<CardStat
|
||||
statistic="24/7"
|
||||
label="Support"
|
||||
variant="dark-gray"
|
||||
/>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Mixed Configurations */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<div className="d-flex flex-column-reverse w-100">
|
||||
<h2 className="h4 mb-8">Mixed Configurations</h2>
|
||||
<h6 className="eyebrow mb-3">Flexible Usage</h6>
|
||||
</div>
|
||||
<p className="mb-8">
|
||||
Mix and match cards with different button configurations in the same layout.
|
||||
</p>
|
||||
</PageGridRow>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardStat
|
||||
statistic="6 Million"
|
||||
superscript="+"
|
||||
label="Active wallets"
|
||||
variant="lilac"
|
||||
/>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardStat
|
||||
statistic="$1 Trillion"
|
||||
superscript="+"
|
||||
label="Value moved"
|
||||
variant="green"
|
||||
primaryButton={{
|
||||
label: "Learn More",
|
||||
onClick: () => handleClick('mixed-1')
|
||||
}}
|
||||
/>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardStat
|
||||
statistic="12"
|
||||
superscript="+"
|
||||
label="Continuous uptime years"
|
||||
variant="light-gray"
|
||||
primaryButton={{
|
||||
label: "Explore",
|
||||
onClick: () => handleClick('mixed-2')
|
||||
}}
|
||||
secondaryButton={{
|
||||
label: "Get Started",
|
||||
onClick: () => handleClick('mixed-3')
|
||||
}}
|
||||
/>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Wide Layout */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<div className="d-flex flex-column-reverse w-100">
|
||||
<h2 className="h4 mb-8">Wide Card Layout</h2>
|
||||
<h6 className="eyebrow mb-3">Larger Spans</h6>
|
||||
</div>
|
||||
<p className="mb-8">
|
||||
Cards can span multiple columns for wider layouts on larger screens.
|
||||
</p>
|
||||
</PageGridRow>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, md: 8, lg: 6 }}>
|
||||
<CardStat
|
||||
statistic="6 Million"
|
||||
superscript="+"
|
||||
label="Active wallets using XRPL"
|
||||
variant="lilac"
|
||||
primaryButton={{
|
||||
label: "Explore Wallets",
|
||||
onClick: () => handleClick('wide-1')
|
||||
}}
|
||||
secondaryButton={{
|
||||
label: "Get Started",
|
||||
onClick: () => handleClick('wide-2')
|
||||
}}
|
||||
/>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 8, lg: 6 }}>
|
||||
<CardStat
|
||||
statistic="$1 Trillion"
|
||||
superscript="+"
|
||||
label="Total value moved on the network"
|
||||
variant="green"
|
||||
primaryButton={{
|
||||
label: "View Statistics",
|
||||
onClick: () => handleClick('wide-3')
|
||||
}}
|
||||
secondaryButton={{
|
||||
label: "Learn More",
|
||||
onClick: () => handleClick('wide-4')
|
||||
}}
|
||||
/>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Usage Guidelines */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<div className="d-flex flex-column-reverse w-100">
|
||||
<h2 className="h4 mb-8">Usage Guidelines</h2>
|
||||
<h6 className="eyebrow mb-3">Best Practices</h6>
|
||||
</div>
|
||||
<div className="col-lg-8 mx-auto w-100">
|
||||
<h5 className="mb-4">When to Use</h5>
|
||||
<ul className="mb-8">
|
||||
<li><strong>Key metrics</strong> - Highlight important numbers prominently</li>
|
||||
<li><strong>Dashboard sections</strong> - Create stat-focused areas on landing pages</li>
|
||||
<li><strong>About pages</strong> - Showcase company or product statistics</li>
|
||||
<li><strong>Feature sections</strong> - Emphasize quantitative benefits</li>
|
||||
</ul>
|
||||
|
||||
<h5 className="mb-4">Color Variant Selection</h5>
|
||||
<ul className="mb-8">
|
||||
<li><strong>Lilac</strong> - User-focused statistics, community metrics</li>
|
||||
<li><strong>Green</strong> - Financial metrics, growth indicators</li>
|
||||
<li><strong>Light Gray</strong> - Technical statistics, reliability metrics</li>
|
||||
<li><strong>Dark Gray</strong> - Neutral or secondary information</li>
|
||||
</ul>
|
||||
|
||||
<h5 className="mb-4">Button Configuration</h5>
|
||||
<ul className="mb-8">
|
||||
<li><strong>No buttons</strong> - For purely informational displays</li>
|
||||
<li><strong>Single button</strong> - For one clear call-to-action</li>
|
||||
<li><strong>Two buttons</strong> - For multiple action options</li>
|
||||
</ul>
|
||||
|
||||
<h5 className="mb-4">Tips</h5>
|
||||
<ul>
|
||||
<li>Keep statistics concise using abbreviations (M, K, T, +)</li>
|
||||
<li>Use descriptive labels that clearly explain the metric</li>
|
||||
<li>Choose colors that match the type of statistic</li>
|
||||
<li>Test on all breakpoints to ensure proper responsive behavior</li>
|
||||
<li>Limit buttons to essential actions</li>
|
||||
</ul>
|
||||
</div>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Implementation Examples */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<div className="col-lg-10 mx-auto d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Code Examples</h2>
|
||||
<h6 className="eyebrow mb-3">Implementation</h6>
|
||||
</div>
|
||||
<div className="col-lg-10 mx-auto">
|
||||
<h5 className="mb-4">Basic Card</h5>
|
||||
<div className="p-4 mb-8 br-4" style={{ backgroundColor: '#f5f5f7', fontFamily: 'monospace', fontSize: '14px' }}>
|
||||
<pre style={{ margin: 0, whiteSpace: 'pre-wrap', color: '#000' }}>{`<CardStat
|
||||
statistic="6 Million"
|
||||
superscript="+"
|
||||
label="Active wallets"
|
||||
variant="lilac"
|
||||
/>`}</pre>
|
||||
</div>
|
||||
|
||||
<h5 className="mb-4">With Primary Button</h5>
|
||||
<div className="p-4 mb-8 br-4" style={{ backgroundColor: '#f5f5f7', fontFamily: 'monospace', fontSize: '14px' }}>
|
||||
<pre style={{ margin: 0, whiteSpace: 'pre-wrap', color: '#000' }}>{`<CardStat
|
||||
statistic="$1 Trillion"
|
||||
superscript="+"
|
||||
label="Value moved"
|
||||
variant="green"
|
||||
primaryButton={{
|
||||
label: "Learn More",
|
||||
href: "/about"
|
||||
}}
|
||||
/>`}</pre>
|
||||
</div>
|
||||
|
||||
<h5 className="mb-4">With Two Buttons</h5>
|
||||
<div className="p-4 mb-8 br-4" style={{ backgroundColor: '#f5f5f7', fontFamily: 'monospace', fontSize: '14px' }}>
|
||||
<pre style={{ margin: 0, whiteSpace: 'pre-wrap', color: '#000' }}>{`<CardStat
|
||||
statistic="12"
|
||||
superscript="+"
|
||||
label="Continuous uptime years"
|
||||
variant="light-gray"
|
||||
primaryButton={{
|
||||
label: "Learn More",
|
||||
onClick: handleLearnMore
|
||||
}}
|
||||
secondaryButton={{
|
||||
label: "Get Started",
|
||||
href: "/start"
|
||||
}}
|
||||
/>`}</pre>
|
||||
</div>
|
||||
|
||||
<h5 className="mb-4">In PageGrid Layout</h5>
|
||||
<div className="p-4 br-4" style={{ backgroundColor: '#f5f5f7', fontFamily: 'monospace', fontSize: '14px' }}>
|
||||
<pre style={{ margin: 0, whiteSpace: 'pre-wrap', color: '#000' }}>{`<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardStat
|
||||
statistic="6 Million"
|
||||
superscript="+"
|
||||
label="Active wallets"
|
||||
variant="lilac"
|
||||
/>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardStat
|
||||
statistic="$1 Trillion"
|
||||
superscript="+"
|
||||
label="Value moved"
|
||||
variant="green"
|
||||
/>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, md: 4, lg: 4 }}>
|
||||
<CardStat
|
||||
statistic="12"
|
||||
superscript="+"
|
||||
label="Uptime years"
|
||||
variant="light-gray"
|
||||
/>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>`}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</ PageGridRow>
|
||||
</ PageGrid>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,465 +0,0 @@
|
||||
import * as React from "react";
|
||||
import { PageGrid, PageGridRow, PageGridCol } from "shared/components/PageGrid/page-grid";
|
||||
import { Divider } from "shared/components/Divider";
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
title: 'Divider Component Showcase',
|
||||
description: "A comprehensive showcase of all Divider component variants, weights, colors, and orientations in the XRPL.org Design System.",
|
||||
}
|
||||
};
|
||||
|
||||
export default function DividerShowcase() {
|
||||
return (
|
||||
<div className="landing">
|
||||
<div className="overflow-hidden">
|
||||
<section className="py-26 text-center">
|
||||
<div className="col-lg-8 mx-auto">
|
||||
<h6 className="eyebrow mb-3">Component Showcase</h6>
|
||||
<h1 className="mb-4">Divider Component</h1>
|
||||
<p className="longform">
|
||||
A comprehensive showcase of all Divider component variants, weights, colors, and orientations.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Weight by Color Matrix - Horizontal */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Horizontal Dividers: Weight by Color Matrix</h2>
|
||||
<div className="mb-10">
|
||||
{/* Header Row */}
|
||||
<div className="d-flex flex-row mb-4" style={{ gap: '2rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}>
|
||||
<h6 className="mb-0">Weight</h6>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<h6 className="mb-0">Gray</h6>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<h6 className="mb-0">Base</h6>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<h6 className="mb-0">Green</h6>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Thin Row */}
|
||||
<div className="d-flex flex-row mb-5 align-items-center" style={{ gap: '2rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}>
|
||||
<strong>Thin</strong>
|
||||
<br />
|
||||
<small className="text-muted">0.5px</small>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<Divider weight="thin" color="gray" />
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<Divider weight="thin" color="base" />
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<Divider weight="thin" color="green" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Regular Row */}
|
||||
<div className="d-flex flex-row mb-5 align-items-center" style={{ gap: '2rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}>
|
||||
<strong>Regular</strong>
|
||||
<br />
|
||||
<small className="text-muted">1px</small>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<Divider weight="regular" color="gray" />
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<Divider weight="regular" color="base" />
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<Divider weight="regular" color="green" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Strong Row */}
|
||||
<div className="d-flex flex-row align-items-center" style={{ gap: '2rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}>
|
||||
<strong>Strong</strong>
|
||||
<br />
|
||||
<small className="text-muted">2px</small>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<Divider weight="strong" color="gray" />
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<Divider weight="strong" color="base" />
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<Divider weight="strong" color="green" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Vertical Dividers */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Vertical Dividers: Weight by Color Matrix</h2>
|
||||
<div className="mb-10">
|
||||
{/* Header Row */}
|
||||
<div className="d-flex flex-row mb-4" style={{ gap: '2rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}>
|
||||
<h6 className="mb-0">Weight</h6>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<h6 className="mb-0">Gray</h6>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<h6 className="mb-0">Base</h6>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<h6 className="mb-0">Green</h6>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Thin Row */}
|
||||
<div className="d-flex flex-row mb-5 align-items-stretch" style={{ gap: '2rem', height: '120px' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }} className="d-flex align-items-center">
|
||||
<div>
|
||||
<strong>Thin</strong>
|
||||
<br />
|
||||
<small className="text-muted">0.5px</small>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }} className="d-flex justify-content-center">
|
||||
<Divider orientation="vertical" weight="thin" color="gray" />
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }} className="d-flex justify-content-center">
|
||||
<Divider orientation="vertical" weight="thin" color="base" />
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }} className="d-flex justify-content-center">
|
||||
<Divider orientation="vertical" weight="thin" color="green" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Regular Row */}
|
||||
<div className="d-flex flex-row mb-5 align-items-stretch" style={{ gap: '2rem', height: '120px' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }} className="d-flex align-items-center">
|
||||
<div>
|
||||
<strong>Regular</strong>
|
||||
<br />
|
||||
<small className="text-muted">1px</small>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }} className="d-flex justify-content-center">
|
||||
<Divider orientation="vertical" weight="regular" color="gray" />
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }} className="d-flex justify-content-center">
|
||||
<Divider orientation="vertical" weight="regular" color="base" />
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }} className="d-flex justify-content-center">
|
||||
<Divider orientation="vertical" weight="regular" color="green" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Strong Row */}
|
||||
<div className="d-flex flex-row align-items-stretch" style={{ gap: '2rem', height: '120px' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }} className="d-flex align-items-center">
|
||||
<div>
|
||||
<strong>Strong</strong>
|
||||
<br />
|
||||
<small className="text-muted">2px</small>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }} className="d-flex justify-content-center">
|
||||
<Divider orientation="vertical" weight="strong" color="gray" />
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }} className="d-flex justify-content-center">
|
||||
<Divider orientation="vertical" weight="strong" color="base" />
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }} className="d-flex justify-content-center">
|
||||
<Divider orientation="vertical" weight="strong" color="green" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Weights Comparison */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Stroke Weights</h2>
|
||||
<p className="mb-4">Dividers are available in three stroke weights to represent different levels of visual hierarchy.</p>
|
||||
<div className="d-flex flex-column gap-5 mb-10">
|
||||
<div>
|
||||
<h6 className="mb-3">Thin (0.5px) - Subtle separation</h6>
|
||||
<Divider weight="thin" />
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="mb-3">Regular (1px) - Default weight</h6>
|
||||
<Divider weight="regular" />
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="mb-3">Strong (2px) - Emphasized boundaries</h6>
|
||||
<Divider weight="strong" />
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Color Variants */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Color Variants</h2>
|
||||
<p className="mb-4">Colors are mapped from the XRPL Design System color palette:</p>
|
||||
|
||||
<div className="d-flex flex-row gap-6 mb-6" style={{ flexWrap: 'wrap' }}>
|
||||
{/* Dark Mode Colors (Default) */}
|
||||
<div style={{ flex: '1 1 300px', minWidth: '280px' }}>
|
||||
<h6 className="mb-3">Dark Mode (Default)</h6>
|
||||
<div className="d-flex flex-column gap-3">
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '40px', height: '40px', backgroundColor: '#454549', borderRadius: '4px', flexShrink: 0, border: '1px solid var(--bs-border-color, #dee2e6)' }}></div>
|
||||
<div>
|
||||
<strong>Gray:</strong> <code>$gray-600</code>
|
||||
<br />
|
||||
<small className="text-muted">#454549</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '40px', height: '40px', backgroundColor: '#FFFFFF', borderRadius: '4px', flexShrink: 0, border: '1px solid var(--bs-border-color, #dee2e6)' }}></div>
|
||||
<div>
|
||||
<strong>Base:</strong> <code>$white</code>
|
||||
<br />
|
||||
<small className="text-muted">#FFFFFF</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '40px', height: '40px', backgroundColor: '#21E46B', borderRadius: '4px', flexShrink: 0, border: '1px solid var(--bs-border-color, #dee2e6)' }}></div>
|
||||
<div>
|
||||
<strong>Green:</strong> <code>$green-300</code>
|
||||
<br />
|
||||
<small className="text-muted">#21E46B</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Light Mode Colors */}
|
||||
<div style={{ flex: '1 1 300px', minWidth: '280px' }}>
|
||||
<h6 className="mb-3">Light Mode</h6>
|
||||
<div className="d-flex flex-column gap-3">
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '40px', height: '40px', backgroundColor: '#C1C1C2', borderRadius: '4px', flexShrink: 0, border: '1px solid var(--bs-border-color, #dee2e6)' }}></div>
|
||||
<div>
|
||||
<strong>Gray:</strong> <code>$gray-300</code>
|
||||
<br />
|
||||
<small className="text-muted">#C1C1C2</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '40px', height: '40px', backgroundColor: '#111112', borderRadius: '4px', flexShrink: 0, border: '1px solid var(--bs-border-color, #dee2e6)' }}></div>
|
||||
<div>
|
||||
<strong>Base:</strong> <code>$gray-900</code>
|
||||
<br />
|
||||
<small className="text-muted">#111112</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row align-items-center gap-3">
|
||||
<div style={{ width: '40px', height: '40px', backgroundColor: '#21E46B', borderRadius: '4px', flexShrink: 0, border: '1px solid var(--bs-border-color, #dee2e6)' }}></div>
|
||||
<div>
|
||||
<strong>Green:</strong> <code>$green-300</code>
|
||||
<br />
|
||||
<small className="text-muted">#21E46B</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="d-flex flex-column gap-5 mb-10">
|
||||
<div>
|
||||
<h6 className="mb-3">Gray - Neutral separation (default)</h6>
|
||||
<Divider color="gray" weight="regular" />
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="mb-3">Base - High contrast separation (adapts to theme)</h6>
|
||||
<Divider color="base" weight="regular" />
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="mb-3">Green - Brand accent separation</h6>
|
||||
<Divider color="green" weight="regular" />
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Real-World Examples */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Real-World Examples</h2>
|
||||
|
||||
<div className="d-flex flex-column gap-6 mb-10">
|
||||
{/* Content Section Separation */}
|
||||
<div>
|
||||
<h6 className="mb-4">Content Section Separation</h6>
|
||||
<div className="card p-4">
|
||||
<h5>Section Title</h5>
|
||||
<p className="mb-4">This is some content in the first section that explains something important.</p>
|
||||
<Divider color="gray" weight="thin" />
|
||||
<p className="mt-4 mb-0">This is content in the second section that follows naturally from the first.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* List Item Separation */}
|
||||
<div>
|
||||
<h6 className="mb-4">List Item Separation</h6>
|
||||
<div className="card p-4">
|
||||
<div className="d-flex flex-column">
|
||||
<div className="py-3">
|
||||
<strong>Feature One</strong>
|
||||
<p className="mb-0 text-muted">Description of the first feature</p>
|
||||
</div>
|
||||
<Divider color="gray" weight="thin" />
|
||||
<div className="py-3">
|
||||
<strong>Feature Two</strong>
|
||||
<p className="mb-0 text-muted">Description of the second feature</p>
|
||||
</div>
|
||||
<Divider color="gray" weight="thin" />
|
||||
<div className="py-3">
|
||||
<strong>Feature Three</strong>
|
||||
<p className="mb-0 text-muted">Description of the third feature</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Vertical Divider Between Columns */}
|
||||
<div>
|
||||
<h6 className="mb-4">Vertical Divider Between Columns</h6>
|
||||
<div className="card p-4">
|
||||
<div className="d-flex flex-row align-items-stretch" style={{ gap: '1.5rem', minHeight: '100px' }}>
|
||||
<div style={{ flex: '1 1 0' }}>
|
||||
<strong>Column One</strong>
|
||||
<p className="mb-0 text-muted">Content for the first column</p>
|
||||
</div>
|
||||
<Divider orientation="vertical" color="gray" weight="regular" />
|
||||
<div style={{ flex: '1 1 0' }}>
|
||||
<strong>Column Two</strong>
|
||||
<p className="mb-0 text-muted">Content for the second column</p>
|
||||
</div>
|
||||
<Divider orientation="vertical" color="gray" weight="regular" />
|
||||
<div style={{ flex: '1 1 0' }}>
|
||||
<strong>Column Three</strong>
|
||||
<p className="mb-0 text-muted">Content for the third column</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Major Section Break */}
|
||||
<div>
|
||||
<h6 className="mb-4">Major Section Break (Strong + Green)</h6>
|
||||
<div className="card p-4">
|
||||
<h5>Primary Section</h5>
|
||||
<p className="mb-4">This section contains the main content of the page.</p>
|
||||
<Divider color="green" weight="strong" />
|
||||
<h5 className="mt-4">Secondary Section</h5>
|
||||
<p className="mb-0">This section is clearly separated with a strong branded divider.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Navigation Separator */}
|
||||
<div>
|
||||
<h6 className="mb-4">Navigation Item Separator</h6>
|
||||
<div className="card p-4">
|
||||
<div className="d-flex flex-row align-items-center" style={{ gap: '1rem', height: '24px' }}>
|
||||
<span>Home</span>
|
||||
<Divider orientation="vertical" color="gray" weight="thin" />
|
||||
<span>Documentation</span>
|
||||
<Divider orientation="vertical" color="gray" weight="thin" />
|
||||
<span>API Reference</span>
|
||||
<Divider orientation="vertical" color="gray" weight="thin" />
|
||||
<span>Community</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* API Reference */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Component API</h2>
|
||||
<div className="mb-10">
|
||||
{/* Header Row */}
|
||||
<div className="d-flex flex-row mb-3 pb-2" style={{ gap: '1rem', borderBottom: '2px solid var(--bs-border-color, #dee2e6)' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><strong>Prop</strong></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><strong>Type</strong></div>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><strong>Default</strong></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><strong>Description</strong></div>
|
||||
</div>
|
||||
|
||||
{/* orientation */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>orientation</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>'horizontal' | 'vertical'</code></div>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>'horizontal'</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Sets the divider orientation</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* weight */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>weight</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>'thin' | 'regular' | 'strong'</code></div>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>'regular'</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Controls the stroke thickness</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* color */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>color</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>'gray' | 'base' | 'green'</code></div>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>'gray'</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Sets the divider color</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* className */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>className</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>string</code></div>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>''</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Additional CSS classes</div>
|
||||
</div>
|
||||
<Divider weight="thin" color="gray" />
|
||||
|
||||
{/* decorative */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: '1rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>decorative</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}><code>boolean</code></div>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}><code>true</code></div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>Whether the divider is purely decorative (hides from screen readers)</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,409 +0,0 @@
|
||||
import * as React from "react";
|
||||
import { PageGrid, PageGridRow, PageGridCol } from "shared/components/PageGrid/page-grid";
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
title: 'PageGrid Showcase',
|
||||
description: "A comprehensive showcase and documentation for the PageGrid component system.",
|
||||
}
|
||||
};
|
||||
|
||||
// Demo component with bordered divs to visualize grid
|
||||
const GridDemo = ({ title, description, children, code }: {
|
||||
title: string;
|
||||
description?: string;
|
||||
children: React.ReactNode;
|
||||
code?: string;
|
||||
}) => (
|
||||
<div className="mb-26">
|
||||
<h3 className="h4 mb-4">{title}</h3>
|
||||
{description && <p className="mb-6">{description}</p>}
|
||||
{code && (
|
||||
<div className="mb-6 p-4 bg-light br-4 text-black" style={{ fontFamily: 'monospace', fontSize: '14px', overflow: 'auto' }}>
|
||||
<pre style={{ margin: 0, whiteSpace: 'pre-wrap', color: '#000' }}>{code}</pre>
|
||||
</div>
|
||||
)}
|
||||
<div style={{
|
||||
border: '1px dashed #ccc',
|
||||
padding: '16px',
|
||||
backgroundColor: '#f9f9f9',
|
||||
borderRadius: '8px'
|
||||
}}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
// Bordered column component for visualization
|
||||
const BorderedCol = ({ children, ...props }: { children: React.ReactNode } & any) => (
|
||||
<PageGridCol
|
||||
{...props}
|
||||
style={{
|
||||
border: '1px solid #0069ff',
|
||||
backgroundColor: 'rgba(0, 105, 255, 0.05)',
|
||||
padding: '16px',
|
||||
minHeight: '60px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
textAlign: 'center',
|
||||
...props.style
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</PageGridCol>
|
||||
);
|
||||
|
||||
export default function GridShowcase() {
|
||||
return (
|
||||
<div className="landing">
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol>
|
||||
<div className="text-center mb-26">
|
||||
<h1 className="h2 mb-4">PageGrid Component Showcase</h1>
|
||||
<p className="longform">
|
||||
A comprehensive guide to using the PageGrid responsive grid system.
|
||||
All examples below use bordered divs to visualize the grid structure.
|
||||
</p>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
|
||||
{/* Basic Grid Structure */}
|
||||
<PageGridRow>
|
||||
<PageGridCol>
|
||||
<GridDemo
|
||||
title="Basic Grid Structure"
|
||||
description="The PageGrid system consists of three components: PageGrid (container), PageGrid.Row (rows), and PageGrid.Col (columns)."
|
||||
code={`<PageGrid>
|
||||
<PageGrid.Row>
|
||||
<PageGrid.Col span={6}>Column 1</PageGrid.Col>
|
||||
<PageGrid.Col span={6}>Column 2</PageGrid.Col>
|
||||
<PageGrid.Col>[No span set]</PageGrid.Col>
|
||||
<PageGrid.Col>[No span set]</PageGrid.Col>
|
||||
</PageGrid.Row>
|
||||
</PageGrid>`}
|
||||
>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<BorderedCol span={6}>span={6}</BorderedCol>
|
||||
<BorderedCol span={6}>span={6}</BorderedCol>
|
||||
<BorderedCol>[No span set]</BorderedCol>
|
||||
<BorderedCol>[No span set]</BorderedCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</GridDemo>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
|
||||
{/* Equal Columns */}
|
||||
<PageGridRow>
|
||||
<PageGridCol>
|
||||
<GridDemo
|
||||
title="Equal Width Columns"
|
||||
description="Create equal-width columns that automatically divide the available space."
|
||||
code={`<PageGrid>
|
||||
<PageGrid.Row>
|
||||
<PageGrid.Col span={4}>Column 1</PageGrid.Col>
|
||||
<PageGrid.Col span={4}>Column 2</PageGrid.Col>
|
||||
<PageGrid.Col span={4}>Column 3</PageGrid.Col>
|
||||
</PageGrid.Row>
|
||||
</PageGrid>`}
|
||||
>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<BorderedCol span={4}>span={4}</BorderedCol>
|
||||
<BorderedCol span={4}>span={4}</BorderedCol>
|
||||
<BorderedCol span={4}>span={4}</BorderedCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</GridDemo>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
|
||||
{/* Auto and Fill */}
|
||||
<PageGridRow>
|
||||
<PageGridCol>
|
||||
<GridDemo
|
||||
title="Auto and Fill Columns"
|
||||
description="Use 'auto' for columns that size to their content, and 'fill' for columns that take remaining space."
|
||||
code={`<PageGrid>
|
||||
<PageGrid.Row>
|
||||
<PageGrid.Col span="auto">Auto</PageGrid.Col>
|
||||
<PageGrid.Col span="fill">Fill</PageGrid.Col>
|
||||
<PageGrid.Col span="auto">Auto</PageGrid.Col>
|
||||
</PageGrid.Row>
|
||||
</PageGrid>`}
|
||||
>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<BorderedCol span="auto">span="auto"</BorderedCol>
|
||||
<BorderedCol span="fill">span="fill"</BorderedCol>
|
||||
<BorderedCol span="auto">span="auto"</BorderedCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</GridDemo>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
|
||||
{/* Responsive Layout */}
|
||||
<PageGridRow>
|
||||
<PageGridCol>
|
||||
<GridDemo
|
||||
title="Responsive Layout"
|
||||
description="Create layouts that adapt to different screen sizes using responsive span values."
|
||||
code={`<PageGrid>
|
||||
<PageGrid.Row>
|
||||
<PageGrid.Col span={{
|
||||
base: 12, // Full width on mobile
|
||||
md: 6, // Half width on tablet
|
||||
lg: 4 // Third width on desktop
|
||||
}}>
|
||||
Responsive Column
|
||||
</PageGrid.Col>
|
||||
</PageGrid.Row>
|
||||
</PageGrid>`}
|
||||
>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<BorderedCol span={{ base: 4, md: 6, lg: 4 }}>
|
||||
base: 4, md: 6, lg: 4
|
||||
</BorderedCol>
|
||||
<BorderedCol span={{ base: 4, md: 6, lg: 4 }}>
|
||||
base: 4, md: 6, lg: 4
|
||||
</BorderedCol>
|
||||
<BorderedCol span={{ base: 4, md: 8, lg: 4 }}>
|
||||
base: 4, md: 8, lg: 4
|
||||
</BorderedCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</GridDemo>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
|
||||
{/* Offsets */}
|
||||
<PageGridRow>
|
||||
<PageGridCol>
|
||||
<GridDemo
|
||||
title="Column Offsets"
|
||||
description="Use offsets to push columns to the right, useful for centering content or creating spacing."
|
||||
code={`<PageGrid>
|
||||
<PageGrid.Row>
|
||||
<PageGrid.Col span={8} offset={2}>
|
||||
Centered (8 columns with 2 offset)
|
||||
</PageGrid.Col>
|
||||
</PageGrid.Row>
|
||||
</PageGrid>`}
|
||||
>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<BorderedCol span={8} offset={{ lg: 2 }}>
|
||||
span={8}, offset: lg: 2
|
||||
</BorderedCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</GridDemo>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
|
||||
{/* Responsive Offsets */}
|
||||
<PageGridRow>
|
||||
<PageGridCol>
|
||||
<GridDemo
|
||||
title="Responsive Offsets"
|
||||
description="Offsets can also be responsive, changing at different breakpoints."
|
||||
code={`<PageGrid>
|
||||
<PageGrid.Row>
|
||||
<PageGrid.Col
|
||||
span={6}
|
||||
offset={{
|
||||
base: 0, // No offset on mobile
|
||||
md: 3 // Offset by 3 on tablet+
|
||||
}}
|
||||
>
|
||||
Responsive Offset
|
||||
</PageGrid.Col>
|
||||
</PageGrid.Row>
|
||||
</PageGrid>`}
|
||||
>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<BorderedCol span={6} offset={{ base: 0, md: 3 }}>
|
||||
span={6}, offset: base=0, md=3
|
||||
</BorderedCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</GridDemo>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
|
||||
{/* Complex Layout */}
|
||||
<PageGridRow>
|
||||
<PageGridCol>
|
||||
<GridDemo
|
||||
title="Complex Layout Example"
|
||||
description="A real-world example showing a sidebar and main content area."
|
||||
code={`<PageGrid>
|
||||
<PageGrid.Row>
|
||||
<PageGrid.Col span={{ base: 12, lg: 4 }}>
|
||||
Sidebar
|
||||
</PageGrid.Col>
|
||||
<PageGrid.Col span={{ base: 12, lg: 8 }}>
|
||||
Main Content
|
||||
</PageGrid.Col>
|
||||
</PageGrid.Row>
|
||||
</PageGrid>`}
|
||||
>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<BorderedCol span={{ base: 4, lg: 4 }} style={{ backgroundColor: 'rgba(255, 200, 0, 0.1)' }}>
|
||||
Sidebar<br />(base: 4, lg: 4)
|
||||
</BorderedCol>
|
||||
<BorderedCol span={{ base: 4, lg: 8 }} style={{ backgroundColor: 'rgba(0, 200, 255, 0.1)' }}>
|
||||
Main Content<br />(base: 4, lg: 8)
|
||||
</BorderedCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</GridDemo>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
|
||||
{/* Breakpoints Documentation */}
|
||||
<PageGridRow>
|
||||
<PageGridCol>
|
||||
<div className="mb-26">
|
||||
<h2 className="h3 mb-6">Breakpoints</h2>
|
||||
<p className="mb-6">
|
||||
The PageGrid system uses the following breakpoints:
|
||||
</p>
|
||||
<div style={{ width: '100%', backgroundColor: '#FFFFFF', borderRadius: '4px', overflow: 'hidden', border: '1px solid #EEE', marginBottom: '24px' }}>
|
||||
{/* Header */}
|
||||
<div style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '1.2fr 1fr 1fr 1.5fr',
|
||||
borderBottom: '2px solid #E0E0E1',
|
||||
background: '#FAFAFA'
|
||||
}}>
|
||||
<div style={{ padding: '12px', fontWeight: 600 }}>Breakpoint</div>
|
||||
<div style={{ padding: '12px', fontWeight: 600 }}>Min Width</div>
|
||||
<div style={{ padding: '12px', fontWeight: 600 }}>Columns</div>
|
||||
<div style={{ padding: '12px', fontWeight: 600 }}>Container Padding</div>
|
||||
</div>
|
||||
|
||||
{/* Rows */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1.2fr 1fr 1fr 1.5fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}><code>base</code></div>
|
||||
<div style={{ padding: '12px' }}>0px</div>
|
||||
<div style={{ padding: '12px' }}>4 columns</div>
|
||||
<div style={{ padding: '12px' }}>16px</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1.2fr 1fr 1fr 1.5fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}><code>sm</code></div>
|
||||
<div style={{ padding: '12px' }}>576px</div>
|
||||
<div style={{ padding: '12px' }}>8 columns</div>
|
||||
<div style={{ padding: '12px' }}>24px</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1.2fr 1fr 1fr 1.5fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}><code>md</code></div>
|
||||
<div style={{ padding: '12px' }}>576px</div>
|
||||
<div style={{ padding: '12px' }}>8 columns</div>
|
||||
<div style={{ padding: '12px' }}>24px</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1.2fr 1fr 1fr 1.5fr', borderBottom: '1px solid #E0E0E1' }}>
|
||||
<div style={{ padding: '12px' }}><code>lg</code></div>
|
||||
<div style={{ padding: '12px' }}>992px</div>
|
||||
<div style={{ padding: '12px' }}>12 columns</div>
|
||||
<div style={{ padding: '12px' }}>32px</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1.2fr 1fr 1fr 1.5fr' }}>
|
||||
<div style={{ padding: '12px' }}><code>xl</code></div>
|
||||
<div style={{ padding: '12px' }}>1280px</div>
|
||||
<div style={{ padding: '12px' }}>12 columns</div>
|
||||
<div style={{ padding: '12px' }}>112px (max-width: 1440px)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
|
||||
{/* Usage Documentation */}
|
||||
<PageGridRow>
|
||||
<PageGridCol>
|
||||
<div className="mb-26">
|
||||
<h2 className="h3 mb-6">Usage</h2>
|
||||
|
||||
<h4 className="h5 mb-4">Import</h4>
|
||||
<div className="p-4 bg-light br-4 mb-6" style={{ fontFamily: 'monospace', fontSize: '14px' }}>
|
||||
<pre style={{ margin: 0, color: '#000' }}>{`import { PageGrid, PageGridRow, PageGridCol } from "shared/components/PageGrid/page-grid";`}</pre>
|
||||
</div>
|
||||
|
||||
<h4 className="h5 mb-4">Basic Example</h4>
|
||||
<div className="p-4 bg-light br-4 mb-6" style={{ fontFamily: 'monospace', fontSize: '14px', overflow: 'auto' }}>
|
||||
<pre style={{ margin: 0, whiteSpace: 'pre-wrap', color: '#000' }}>{`<PageGrid>
|
||||
<PageGrid.Row>
|
||||
<PageGrid.Col span={6}>
|
||||
Column 1
|
||||
</PageGrid.Col>
|
||||
<PageGrid.Col span={6}>
|
||||
Column 2
|
||||
</PageGrid.Col>
|
||||
</PageGrid.Row>
|
||||
</PageGrid>`}</pre>
|
||||
</div>
|
||||
|
||||
<h4 className="h5 mb-4">Props</h4>
|
||||
<div className="mb-6">
|
||||
<h5 className="h6 mb-3">PageGrid.Col Props</h5>
|
||||
<ul>
|
||||
<li><code>span</code> - Column span (number, "auto", "fill", or responsive object)</li>
|
||||
<li><code>offset</code> - Column offset (number or responsive object)</li>
|
||||
<li><code>className</code> - Additional CSS classes</li>
|
||||
<li>All standard HTML div attributes</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h4 className="h5 mb-4">Span Values</h4>
|
||||
<ul className="mb-6">
|
||||
<li><strong>Number</strong> (e.g., 1-12): Fixed column width</li>
|
||||
<li><strong>"auto"</strong>: Column sizes to its content</li>
|
||||
<li><strong>"fill"</strong>: Column fills remaining space</li>
|
||||
<li><strong>Responsive Object</strong>: Different spans for different breakpoints</li>
|
||||
</ul>
|
||||
|
||||
<h4 className="h5 mb-4">Best Practices</h4>
|
||||
<ul>
|
||||
<li>Always wrap columns in a <code>PageGrid.Row</code></li>
|
||||
<li>Use responsive values for mobile-first design</li>
|
||||
<li>Total column spans in a row should not exceed the grid columns (4 for base, 8 for sm/md, 12 for lg/xl)</li>
|
||||
<li>Use offsets for spacing and centering content</li>
|
||||
<li>Test layouts at all breakpoints</li>
|
||||
</ul>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
|
||||
{/* Visual Grid Demonstration */}
|
||||
<PageGridRow>
|
||||
<PageGridCol>
|
||||
<div className="mb-26">
|
||||
<h2 className="h3 mb-6">Visual Grid Demonstration</h2>
|
||||
<p className="mb-6">
|
||||
Below is a visual representation of the 12-column grid system at the lg breakpoint:
|
||||
</p>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
{[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].map((num) => (
|
||||
<BorderedCol key={num} span={{ base: 2, lg: 1 }} style={{ fontSize: '12px' }}>
|
||||
{num}
|
||||
</BorderedCol>
|
||||
))}
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -24,6 +24,14 @@ export default function History() {
|
||||
return (
|
||||
<div className="landing">
|
||||
<div className="overflow-hidden">
|
||||
<div className="position-relative">
|
||||
<img
|
||||
alt="background orange waves"
|
||||
src={require("../static/img/backgrounds/history-orange.svg")}
|
||||
className="landing-bg"
|
||||
id="history-orange"
|
||||
/>
|
||||
</div>
|
||||
<section className="py-26 text-center">
|
||||
<div className="col-lg-5 mx-auto text-center">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
@@ -53,6 +61,13 @@ export default function History() {
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<div className="position-relative d-none-sm">
|
||||
<img
|
||||
alt="background purple waves"
|
||||
src={require("../static/img/backgrounds/history-purple.svg")}
|
||||
id="history-purple"
|
||||
/>
|
||||
</div>
|
||||
<div className="container-new marketing-wrapper">
|
||||
<section className="row mb-60">
|
||||
<div className="timeline">
|
||||
|
||||
@@ -32,6 +32,14 @@ export default function Impact() {
|
||||
return (
|
||||
<div className="landing page-impact">
|
||||
<div className="overflow-hidden">
|
||||
<div className="position-relative d-none-sm">
|
||||
<img
|
||||
alt="purple waves"
|
||||
src={require("../static/img/backgrounds/community-purple.svg")}
|
||||
className="landing-bg"
|
||||
id="impact-purple"
|
||||
/>
|
||||
</div>
|
||||
<section className="container-new py-26 text-lg-center">
|
||||
<div className="p-0 col-lg-8 mx-lg-auto">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
@@ -44,6 +52,13 @@ export default function Impact() {
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div className="position-relative d-none-sm">
|
||||
<img
|
||||
alt="green waves"
|
||||
src={require("../static/img/backgrounds/home-green.svg")}
|
||||
id="impact-green"
|
||||
/>
|
||||
</div>
|
||||
{/* World map */}
|
||||
<section className="container-new py-10">
|
||||
<div className="col-sm-10 col-lg-6 offset-md-3 p-10-until-sm pl-0-sm pr-0-sm">
|
||||
@@ -118,6 +133,16 @@ export default function Impact() {
|
||||
{/* Card */}
|
||||
<section className="container-new py-26">
|
||||
<div className="col-md-6 offset-md-3 p-6-sm p-10-until-sm br-8 cta-card">
|
||||
<img
|
||||
alt="purple waves"
|
||||
src={require("../static/img/backgrounds/cta-community-purple.svg")}
|
||||
className="cta cta-top-left"
|
||||
/>
|
||||
<img
|
||||
alt="green waves"
|
||||
src={require("../static/img/backgrounds/cta-calculator-green.svg")}
|
||||
className="cta cta-bottom-right"
|
||||
/>
|
||||
<div className="z-index-1 position-relative">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 h2-sm mb-10-until-sm mb-8-sm">
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import * as React from "react";
|
||||
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
||||
import { Link } from '@redocly/theme/components/Link/Link';
|
||||
import { PageGrid, PageGridCol, PageGridRow } from "shared/components/PageGrid/page-grid";
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
@@ -79,6 +78,14 @@ export default function XrplOverview() {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="position-relative">
|
||||
<img
|
||||
alt="purple waves"
|
||||
src={require("../static/img/backgrounds/xrpl-overview-purple.svg")}
|
||||
className="landing-bg"
|
||||
id="xrpl-overview-purple"
|
||||
/>
|
||||
</div>
|
||||
<section className="py-26 text-center">
|
||||
<div className="col-lg-5 mx-auto text-center">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
@@ -93,6 +100,13 @@ export default function XrplOverview() {
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div className="position-relative d-none-sm">
|
||||
<img
|
||||
alt="orange waves"
|
||||
src={require("../static/img/backgrounds/xrpl-overview-orange.svg")}
|
||||
id="xrpl-overview-orange"
|
||||
/>
|
||||
</div>
|
||||
<section className="container-new py-26">
|
||||
<div className="card-grid card-grid-2xN">
|
||||
<div className="col">
|
||||
@@ -119,7 +133,7 @@ export default function XrplOverview() {
|
||||
{translate("Read Technical Docs")}
|
||||
</Link>{" "}
|
||||
<a
|
||||
className="ms-4 video-external-link"
|
||||
className="ml-4 video-external-link"
|
||||
target="_blank"
|
||||
href="https://www.youtube.com/playlist?list=PLJQ55Tj1hIVZtJ_JdTvSum2qMTsedWkNi"
|
||||
>
|
||||
@@ -154,7 +168,7 @@ export default function XrplOverview() {
|
||||
{translate("Read Technical Docs")}
|
||||
</Link>{" "}
|
||||
<a
|
||||
className="ms-4 video-external-link"
|
||||
className="ml-4 video-external-link"
|
||||
target="_blank"
|
||||
href="https://www.youtube.com/playlist?list=PLJQ55Tj1hIVZtJ_JdTvSum2qMTsedWkNi"
|
||||
>
|
||||
@@ -164,9 +178,9 @@ export default function XrplOverview() {
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGrid.Col span={{ base: 4, lg: 6 }}>
|
||||
<section className="container-new py-26">
|
||||
<div className="card-grid card-grid-2xN">
|
||||
<div className="col">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 h2-sm mb-8">
|
||||
{translate("How the Consensus Protocol works")}
|
||||
@@ -193,23 +207,25 @@ export default function XrplOverview() {
|
||||
<p className="mb-0">
|
||||
{translate('about.index.consensus.ppart1', 'Currently, over 120 ')}
|
||||
<a href="https://livenet.xrpl.org/network/validators" target="_blank">{translate('about.index.consensus.ppart2', 'validators')}</a>
|
||||
{translate('about.index.consensus.ppart3', ' are active on the ledger, operated by universities, exchanges, businesses, and individuals. As the validator pool grows, the consensus protocol ensures decentralization of the blockchain over time.')}
|
||||
{translate('about.index.consensus.ppart3', ' are active on the ledger, operated by universities, exchanges, businesses, and individuals. As the validator pool grows, the consensus protocol ensures decentralization of the blockchain over time.')}
|
||||
</p>
|
||||
</PageGrid.Col>
|
||||
<PageGrid.Col span={{ base: 4, lg: 6 }}>
|
||||
<div className="col mb-16-sm">
|
||||
<img
|
||||
className="mw-100"
|
||||
id="validator-graphic"
|
||||
alt="(Graphic: Validators in Consensus)"
|
||||
/>
|
||||
</div>
|
||||
</PageGrid.Col>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGrid.Col span={{ base: 4, lg: 6 }} offset={{ lg: 3 }} className="p-6-sm p-10-until-sm br-8 cta-card">
|
||||
</div>
|
||||
<div className="col mb-16-sm">
|
||||
<img
|
||||
className="mw-100"
|
||||
id="validator-graphic"
|
||||
alt="(Graphic: Validators in Consensus)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section className="container-new py-26">
|
||||
<div className="col-md-6 offset-md-3 p-6-sm p-10-until-sm br-8 cta-card">
|
||||
<img
|
||||
alt="green waves"
|
||||
src={require("../static/img/backgrounds/cta-xrpl-overview-green.svg")}
|
||||
className="cta cta-bottom-right"
|
||||
/>
|
||||
<div className="z-index-1 position-relative">
|
||||
<h2 className="h4 mb-10-until-sm mb-8-sm">
|
||||
{translate("A Sustainable Blockchain")}
|
||||
@@ -223,13 +239,11 @@ export default function XrplOverview() {
|
||||
{translate("Learn More")}
|
||||
</a>
|
||||
</div>
|
||||
</PageGrid.Col>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGrid.Col span={{ base: 4, lg: 6 }}>
|
||||
</div>
|
||||
</section>
|
||||
<section className="container-new py-26">
|
||||
<div className="card-grid card-grid-2xN">
|
||||
<div className="col">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h4 className="h4 h2-sm mb-8">
|
||||
{translate("Building with confidence on ")}
|
||||
@@ -251,8 +265,8 @@ export default function XrplOverview() {
|
||||
<a className="btn btn-primary btn-arrow mb-10-sm" href="/about/uses">
|
||||
{translate("Explore More")}
|
||||
</a>
|
||||
</PageGrid.Col>
|
||||
<PageGrid.Col span={{ base: 4, lg: 6 }}>
|
||||
</div>
|
||||
<div className="col mb-0">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h4 className="h4 h2-sm mb-8">
|
||||
{translate("Creating new value for long-term growth")}
|
||||
@@ -269,11 +283,11 @@ export default function XrplOverview() {
|
||||
"Significant investment in development, along with low transaction costs and energy usage, is fueling growth and opening up a wide variety of use cases at scale."
|
||||
)}
|
||||
</p>
|
||||
</PageGrid.Col>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse col-xl-6 mb-lg-4 ps-0 ">
|
||||
<div className="d-flex flex-column-reverse col-xl-6 mb-lg-4 pl-0 ">
|
||||
<h2 className="h4 h2-sm">
|
||||
{translate(
|
||||
"Watch the explainer video series to learn more about the XRP Ledger"
|
||||
@@ -361,6 +375,11 @@ export default function XrplOverview() {
|
||||
</section>
|
||||
<section className="container-new py-26">
|
||||
<div className="col-md-6 offset-md-3 p-6-sm p-10-until-sm br-8 cta-card">
|
||||
<img
|
||||
alt="orange waves"
|
||||
src={require("../static/img/backgrounds/cta-xrpl-overview-orange.svg")}
|
||||
className="cta cta-bottom-right"
|
||||
/>
|
||||
<div className="z-index-1 position-relative">
|
||||
<h4 className="h4 mb-10-until-sm mb-8-sm">
|
||||
{translate("Tomorrow’s Blockchain Starts With You")}
|
||||
@@ -388,7 +407,7 @@ export default function XrplOverview() {
|
||||
</section>
|
||||
<section className="container-new py-26">
|
||||
<div
|
||||
className="col-md-10 offset-md-1 col-lg-8 offset-lg-2 ps-0 pe-0 mini-faq"
|
||||
className="col-md-6 offset-md-3 w-100 pl-0 pr-0 mini-faq"
|
||||
id="minifaq-accordion"
|
||||
>
|
||||
{faqs.map((faq, index) => (
|
||||
@@ -396,8 +415,8 @@ export default function XrplOverview() {
|
||||
<a
|
||||
href={`#heading${index + 1}`}
|
||||
className="expander collapsed"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target={`#answer${index + 1}`}
|
||||
data-toggle="collapse"
|
||||
data-target={`#answer${index + 1}`}
|
||||
aria-expanded="false"
|
||||
aria-controls={`answer${index + 1}`}
|
||||
>
|
||||
|
||||
@@ -1,310 +0,0 @@
|
||||
import * as React from "react";
|
||||
import { PageGrid, PageGridRow, PageGridCol } from "shared/components/PageGrid/page-grid";
|
||||
import { BdsLink } from "shared/components/Link/Link";
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
title: 'Link Component Showcase',
|
||||
description: "A comprehensive showcase of all Link component variants, sizes, and states in the XRPL.org Design System.",
|
||||
}
|
||||
};
|
||||
|
||||
export default function LinkShowcase() {
|
||||
return (
|
||||
<div className="landing">
|
||||
<div className="overflow-hidden">
|
||||
<section className="py-26 text-center">
|
||||
<div className="col-lg-8 mx-auto">
|
||||
<h6 className="eyebrow mb-3">Component Showcase</h6>
|
||||
<h1 className="mb-4">Link Component</h1>
|
||||
<p className="longform">
|
||||
A comprehensive showcase of all Link component variants, sizes, and states.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Size by Variant Matrix</h2>
|
||||
<div className="mb-10">
|
||||
{/* Header Row */}
|
||||
<div className="d-flex flex-row mb-4" style={{ gap: '2rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}>
|
||||
<h6 className="mb-0">Size</h6>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<h6 className="mb-0">Internal Links</h6>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<h6 className="mb-0">External Links</h6>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<h6 className="mb-0">Disabled State</h6>
|
||||
</div>
|
||||
</div>
|
||||
{/* Small Row */}
|
||||
<div className="d-flex flex-row mb-5 align-items-center" style={{ gap: '2rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}>
|
||||
<strong>Small</strong>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<BdsLink href="/docs" variant="internal" size="small">
|
||||
Small Internal Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<BdsLink href="https://example.com" variant="external" size="small" target="_blank" rel="noopener noreferrer">
|
||||
Small External Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<BdsLink href="#" variant="internal" size="small" disabled>
|
||||
Disabled Internal Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
</div>
|
||||
{/* Medium Row */}
|
||||
<div className="d-flex flex-row mb-5 align-items-center" style={{ gap: '2rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}>
|
||||
<strong>Medium</strong>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<BdsLink href="/docs" variant="internal" size="medium">
|
||||
Medium Internal Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<BdsLink href="https://example.com" variant="external" size="medium" target="_blank" rel="noopener noreferrer">
|
||||
Medium External Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<BdsLink href="#" variant="external" size="medium" disabled>
|
||||
Disabled External Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
</div>
|
||||
{/* Large Row */}
|
||||
<div className="d-flex flex-row align-items-center" style={{ gap: '2rem' }}>
|
||||
<div style={{ width: '120px', flexShrink: 0 }}>
|
||||
<strong>Large</strong>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<BdsLink href="/docs" variant="internal" size="large">
|
||||
Large Internal Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<BdsLink href="https://example.com" variant="external" size="large" target="_blank" rel="noopener noreferrer">
|
||||
Large External Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 0', minWidth: 0 }}>
|
||||
<BdsLink href="#" variant="internal" size="large" disabled>
|
||||
Disabled Internal Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Sizes</h2>
|
||||
<div className="d-flex flex-column gap-4 mb-10">
|
||||
<div>
|
||||
<h6 className="mb-3">Small</h6>
|
||||
<BdsLink href="/docs" size="small">
|
||||
Small Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="mb-3">Medium</h6>
|
||||
<BdsLink href="/docs" size="medium">
|
||||
Medium Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="mb-3">Large</h6>
|
||||
<BdsLink href="/docs" size="large">
|
||||
Large Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Color States</h2>
|
||||
<p className="mb-4">Links automatically handle color states via CSS per theme:</p>
|
||||
|
||||
<div className="d-flex flex-row gap-6 mb-6" style={{ flexWrap: 'wrap' }}>
|
||||
{/* Light Mode Colors */}
|
||||
<div style={{ flex: '1 1 300px', minWidth: '280px' }}>
|
||||
<h6 className="mb-3">Light Mode</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Enabled:</strong> Green 400 <code style={{ color: '#0DAA3E' }}>#0DAA3E</code></li>
|
||||
<li><strong>Hover/Focus:</strong> Green 500 <code style={{ color: '#078139' }}>#078139</code> + underline</li>
|
||||
<li><strong>Active:</strong> Green 400 <code style={{ color: '#0DAA3E' }}>#0DAA3E</code> + underline</li>
|
||||
<li><strong>Visited:</strong> Lilac 400 <code style={{ color: '#7649E3' }}>#7649E3</code></li>
|
||||
<li><strong>Disabled:</strong> Gray 400 <code style={{ color: '#A2A2A4' }}>#A2A2A4</code></li>
|
||||
<li><strong>Focus Outline:</strong> Black <code style={{ color: '#000000' }}>#000000</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Dark Mode Colors */}
|
||||
<div style={{ flex: '1 1 300px', minWidth: '280px' }}>
|
||||
<h6 className="mb-3">Dark Mode</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Enabled:</strong> Green 300 <code style={{ color: '#21E46B' }}>#21E46B</code></li>
|
||||
<li><strong>Hover/Focus:</strong> Green 200 <code style={{ color: '#70EE97' }}>#70EE97</code> + underline</li>
|
||||
<li><strong>Active:</strong> Green 300 <code style={{ color: '#21E46B' }}>#21E46B</code> + underline</li>
|
||||
<li><strong>Visited:</strong> Lilac 300 <code style={{ color: '#C0A7FF' }}>#C0A7FF</code></li>
|
||||
<li><strong>Disabled:</strong> Gray 500 <code style={{ color: '#838386' }}>#838386</code></li>
|
||||
<li><strong>Focus Outline:</strong> White <code style={{ color: '#FFFFFF', backgroundColor: '#333', padding: '0 4px' }}>#FFFFFF</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="d-flex flex-column gap-4 mb-10">
|
||||
<div>
|
||||
<h6 className="mb-3">Default (hover to see state changes and arrow animation)</h6>
|
||||
<BdsLink href="/docs" size="medium">
|
||||
Default Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="mb-3">Disabled</h6>
|
||||
<BdsLink href="#" size="medium" disabled>
|
||||
Disabled Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Icon Types</h2>
|
||||
<p className="mb-4">Arrow icons animate to chevron shape on hover (150ms cubic-bezier transition).</p>
|
||||
<div className="d-flex flex-column gap-4 mb-10">
|
||||
<div>
|
||||
<h6 className="mb-3">Arrow (Internal) - animates to chevron on hover</h6>
|
||||
<BdsLink href="/docs" size="medium" icon="arrow">
|
||||
Arrow Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="mb-3">External</h6>
|
||||
<BdsLink href="https://example.com" size="medium" variant="external" target="_blank" rel="noopener noreferrer">
|
||||
External Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="mb-3">Inline (No Icon)</h6>
|
||||
<p>
|
||||
This is a paragraph with an{" "}
|
||||
<BdsLink href="/docs" variant="inline">
|
||||
inline link
|
||||
</BdsLink>{" "}
|
||||
embedded within the text.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Variants</h2>
|
||||
<div className="d-flex flex-column gap-4 mb-10">
|
||||
<div>
|
||||
<h6 className="mb-3">Internal</h6>
|
||||
<BdsLink href="/docs" variant="internal" size="medium">
|
||||
Internal Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="mb-3">External</h6>
|
||||
<BdsLink href="https://example.com" variant="external" size="medium" target="_blank" rel="noopener noreferrer">
|
||||
External Link
|
||||
</BdsLink>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="mb-3">Inline</h6>
|
||||
<p>
|
||||
This is a paragraph with an{" "}
|
||||
<BdsLink href="/docs" variant="inline">
|
||||
inline link
|
||||
</BdsLink>{" "}
|
||||
that appears within the text flow.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Real-World Examples</h2>
|
||||
<div className="d-flex flex-column gap-6 mb-10">
|
||||
<div>
|
||||
<h6 className="mb-4">Navigation Links</h6>
|
||||
<div className="d-flex flex-column gap-3">
|
||||
<BdsLink href="/docs" size="medium">
|
||||
View Documentation
|
||||
</BdsLink>
|
||||
<BdsLink href="/about" size="medium">
|
||||
Learn More About XRPL
|
||||
</BdsLink>
|
||||
<BdsLink href="https://github.com/XRPLF/xrpl-dev-portal" variant="external" size="medium" target="_blank" rel="noopener noreferrer">
|
||||
GitHub Repository
|
||||
</BdsLink>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="mb-4">Inline Text Links</h6>
|
||||
<p className="longform">
|
||||
The XRP Ledger is a decentralized public blockchain. You can{" "}
|
||||
<BdsLink href="/docs" variant="inline">
|
||||
read the technical documentation
|
||||
</BdsLink>{" "}
|
||||
to learn more about how it works. The network is maintained by a{" "}
|
||||
<BdsLink href="/about" variant="inline">
|
||||
global community
|
||||
</BdsLink>{" "}
|
||||
of developers and validators.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="mb-4">Call-to-Action Links</h6>
|
||||
<div className="d-flex flex-column gap-3">
|
||||
<BdsLink href="/docs" size="large">
|
||||
Get Started with XRPL
|
||||
</BdsLink>
|
||||
<BdsLink href="/about/uses" size="large">
|
||||
Explore Use Cases
|
||||
</BdsLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,820 +0,0 @@
|
||||
import * as React from "react";
|
||||
import {
|
||||
PageGrid,
|
||||
PageGridRow,
|
||||
PageGridCol,
|
||||
} from "shared/components/PageGrid/page-grid";
|
||||
import { SmallTilesSection } from "shared/components/SmallTilesSection/SmallTilesSection";
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
title: "SmallTilesSection Component Showcase",
|
||||
description:
|
||||
"A comprehensive showcase of the SmallTilesSection component, demonstrating its grid layout, variants, and responsive behavior.",
|
||||
},
|
||||
};
|
||||
|
||||
export default function SmallTilesSectionShowcase() {
|
||||
const handleClick = (message: string) => {
|
||||
console.log(`Card clicked: ${message}`);
|
||||
};
|
||||
|
||||
// Sample icon SVG (black version for light backgrounds)
|
||||
const cardIconSvg =
|
||||
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='53' height='38' viewBox='0 0 53 38' fill='none'%3E%3Cpath d='M38.6603 0.0618191C35.7826 0.289503 33.3694 1.32168 31.5728 3.09764C29.7228 4.92673 28.8397 7.15805 28.8397 9.98896C28.8397 14.2239 30.5831 17.1839 34.4732 19.529C35.4629 20.121 36.8104 20.7661 39.1399 21.768C42.3144 23.1265 43.4944 23.7716 44.2481 24.5761C45.1769 25.5703 45.4357 27.1565 44.8495 28.3709C44.7353 28.6062 44.4384 29.0008 44.172 29.2664C43.2737 30.1696 41.8577 30.6477 40.0991 30.6477C37.1301 30.6477 34.9148 29.4334 33.1334 26.8074C32.8898 26.4583 32.669 26.1699 32.6385 26.1699C32.57 26.1699 26.7767 29.5017 26.6549 29.6156C26.5787 29.6839 26.6396 29.8433 26.9365 30.329C29.2508 34.2148 32.8669 36.4917 37.7544 37.1444C39.0333 37.319 41.4314 37.3114 42.657 37.1444C45.7326 36.7118 48.0393 35.6948 49.8283 33.9644C51.7315 32.1353 52.6679 29.7674 52.6679 26.7998C52.6679 24.9024 52.3558 23.4225 51.6478 21.9577C51.1605 20.9559 50.6733 20.2804 49.8359 19.4304C48.2296 17.8062 46.1513 16.5767 42.0023 14.8007C38.8658 13.4574 37.8153 12.8806 37.1225 12.1444C36.4602 11.4386 36.1785 10.6113 36.2394 9.57912C36.2927 8.75945 36.5211 8.20541 37.0235 7.66656C37.7468 6.88483 38.5842 6.55848 39.8783 6.56607C41.3476 6.56607 42.2992 6.94555 43.2661 7.91701C43.6086 8.25095 44.0502 8.78981 44.2557 9.11616C44.4917 9.48805 44.6668 9.69297 44.7277 9.6702C44.9256 9.58671 50.4602 6.01962 50.4602 5.9665C50.4602 5.93614 50.1785 5.49594 49.8359 4.97985C49.1051 3.88696 47.7881 2.52083 46.8821 1.92126C45.2073 0.813185 43.4183 0.243967 41.0583 0.0694065C39.9012 -0.0216694 39.7489 -0.0216694 38.6603 0.0618191Z' fill='black'/%3E%3Cpath d='M14.9592 13.8528L14.9364 27.2711L14.7689 27.901C14.5481 28.7283 14.2893 29.2216 13.8325 29.677C13.193 30.3145 12.3708 30.5802 11.0005 30.5877C9.04403 30.5953 7.87166 29.7681 6.50896 27.4457C6.28819 27.0814 6.09026 26.7854 6.06742 26.793C6.03697 26.8081 4.65905 27.6354 3.00706 28.6296L0 30.4511L0.228385 30.9065C1.59108 33.616 3.95105 35.6652 6.79064 36.6063C9.79009 37.6005 13.6422 37.5094 16.4665 36.3786C19.8542 35.0125 21.8412 32.1891 22.3665 27.9921C22.4121 27.5671 22.4426 22.8236 22.4426 13.8983V0.442009H18.7123H14.9896L14.9592 13.8528Z' fill='black'/%3E%3C/svg%3E";
|
||||
|
||||
// Sample card data sets
|
||||
const languageTutorials = [
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "JavaScript",
|
||||
label: "JavaScript",
|
||||
href: "#javascript",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Python",
|
||||
label: "Python",
|
||||
href: "#python",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Go",
|
||||
label: "Go",
|
||||
href: "#go",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Rust",
|
||||
label: "Rust",
|
||||
href: "#rust",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Java",
|
||||
label: "Java",
|
||||
href: "#java",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "C++",
|
||||
label: "C++",
|
||||
href: "#cpp",
|
||||
},
|
||||
];
|
||||
|
||||
const featuredTopics = [
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Quick Start",
|
||||
label: "Quick Start Guide",
|
||||
onClick: () => handleClick("quickstart"),
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Getting Started",
|
||||
label: "Get Started",
|
||||
onClick: () => handleClick("getting-started"),
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Tutorial",
|
||||
label: "Build Your First App",
|
||||
onClick: () => handleClick("first-app"),
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Advanced",
|
||||
label: "Advanced Topics",
|
||||
onClick: () => handleClick("advanced"),
|
||||
},
|
||||
];
|
||||
|
||||
const largeCardSet = [
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Topic 1",
|
||||
label: "Topic One",
|
||||
href: "#topic1",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Topic 2",
|
||||
label: "Topic Two",
|
||||
href: "#topic2",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Topic 3",
|
||||
label: "Topic Three",
|
||||
href: "#topic3",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Topic 4",
|
||||
label: "Topic Four",
|
||||
href: "#topic4",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Topic 5",
|
||||
label: "Topic Five",
|
||||
href: "#topic5",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Topic 6",
|
||||
label: "Topic Six",
|
||||
href: "#topic6",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Topic 7",
|
||||
label: "Topic Seven",
|
||||
href: "#topic7",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Topic 8",
|
||||
label: "Topic Eight",
|
||||
href: "#topic8",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Topic 9",
|
||||
label: "Topic Nine",
|
||||
href: "#topic9",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Topic 10",
|
||||
label: "Topic Ten",
|
||||
href: "#topic10",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Topic 11",
|
||||
label: "Topic Eleven",
|
||||
href: "#topic11",
|
||||
},
|
||||
];
|
||||
|
||||
const mixedStates = [
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Active Card",
|
||||
label: "Active Card",
|
||||
href: "#active",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Clickable Card",
|
||||
label: "Clickable Card",
|
||||
onClick: () => handleClick("clickable"),
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Coming Soon",
|
||||
label: "Coming Soon",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Another Active",
|
||||
label: "Another Active",
|
||||
href: "#another",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Yet Another",
|
||||
label: "Yet Another",
|
||||
href: "#yetanother",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="landing">
|
||||
<div className="overflow-hidden">
|
||||
{/* Hero Section */}
|
||||
<section className="py-26 text-center">
|
||||
<div className="col-lg-8 mx-auto">
|
||||
<h6 className="eyebrow mb-3">Component Showcase</h6>
|
||||
<h1 className="mb-4">SmallTilesSection Component</h1>
|
||||
<p className="longform">
|
||||
A section component that displays multiple CardIcon components in
|
||||
a responsive grid layout. Features automatic grid adjustments at
|
||||
breakpoints, optional subtitle, and spacer support for large card
|
||||
sets (9+ cards).
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Basic Usage */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Basic Usage</h2>
|
||||
<p className="mb-6">
|
||||
SmallTilesSection automatically creates a responsive grid of
|
||||
CardIcon components. The grid adapts from 1 column on mobile, 2
|
||||
columns on tablets, to 3 columns on desktop.
|
||||
</p>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
<SmallTilesSection
|
||||
headline="Language Tutorials"
|
||||
subtitle="Choose a language to get started with XRPL development"
|
||||
cardVariant="neutral"
|
||||
cards={languageTutorials}
|
||||
/>
|
||||
|
||||
{/* Green Variant */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Green Variant</h2>
|
||||
<p className="mb-6">
|
||||
Use the green variant to highlight featured or recommended
|
||||
content.
|
||||
</p>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
<SmallTilesSection
|
||||
headline="Featured Topics"
|
||||
subtitle="Recommended content to help you get started"
|
||||
cardVariant="green"
|
||||
cards={featuredTopics}
|
||||
/>
|
||||
|
||||
{/* Without Subtitle */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Without Subtitle</h2>
|
||||
<p className="mb-6">
|
||||
The subtitle is optional. Here's an example without it.
|
||||
</p>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
<SmallTilesSection
|
||||
headline="Quick Links"
|
||||
cardVariant="neutral"
|
||||
cards={featuredTopics.slice(0, 3)}
|
||||
/>
|
||||
|
||||
{/* Large Card Set with Spacer */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Large Card Set (Spacer Feature)</h2>
|
||||
<p className="mb-6">
|
||||
When a section contains more than 8 cards, the component
|
||||
automatically adds a spacer element to improve grid alignment.
|
||||
This ensures cards align properly even with varying card counts.
|
||||
The spacer is visible on large screens (≥992px).
|
||||
</p>
|
||||
|
||||
<div
|
||||
className="p-4 mb-6"
|
||||
style={{
|
||||
backgroundColor: "rgba(114, 119, 126, 0.1)",
|
||||
borderRadius: "8px",
|
||||
}}
|
||||
>
|
||||
<h6 className="mb-3">Spacer Details</h6>
|
||||
<ul className="mb-0">
|
||||
<li>
|
||||
<strong>Threshold:</strong> 8 cards (spacer appears with 9+
|
||||
cards)
|
||||
</li>
|
||||
<li>
|
||||
<strong>Visibility:</strong> Only visible on large screens
|
||||
(≥992px)
|
||||
</li>
|
||||
<li>
|
||||
<strong>Purpose:</strong> Ensures proper grid alignment with
|
||||
varying card counts
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
<SmallTilesSection
|
||||
headline="All Topics"
|
||||
subtitle={`${largeCardSet.length} topics available (spacer enabled)`}
|
||||
cardVariant="neutral"
|
||||
cards={largeCardSet}
|
||||
/>
|
||||
|
||||
{/* Mixed States */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Mixed Card States</h2>
|
||||
<p className="mb-6">
|
||||
Individual cards within the section can have different states
|
||||
and behaviors. Cards can be links (href), buttons (onClick), or
|
||||
disabled.
|
||||
</p>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
<SmallTilesSection
|
||||
headline="Mixed States Example"
|
||||
subtitle="Combination of links, click handlers, and disabled cards"
|
||||
cardVariant="neutral"
|
||||
cards={mixedStates}
|
||||
/>
|
||||
|
||||
{/* Responsive Behavior */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Responsive Grid Behavior</h2>
|
||||
<p className="mb-6">
|
||||
The grid automatically adjusts based on viewport width. Resize
|
||||
your browser to see the changes.
|
||||
</p>
|
||||
|
||||
<div className="d-flex flex-column gap-4 mb-6">
|
||||
<div
|
||||
className="d-flex flex-row gap-4 align-items-start"
|
||||
style={{ flexWrap: "wrap" }}
|
||||
>
|
||||
<div style={{ flex: "1 1 300px", minWidth: "280px" }}>
|
||||
<h6 className="mb-3">Mobile (<576px)</h6>
|
||||
<ul className="mb-0">
|
||||
<li>
|
||||
<strong>Columns:</strong> 1
|
||||
</li>
|
||||
<li>
|
||||
<strong>Gap:</strong> 8px
|
||||
</li>
|
||||
<li>
|
||||
<strong>Layout:</strong> Single column stack
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ flex: "1 1 300px", minWidth: "280px" }}>
|
||||
<h6 className="mb-3">Tablet (576px–991px)</h6>
|
||||
<ul className="mb-0">
|
||||
<li>
|
||||
<strong>Columns:</strong> 2
|
||||
</li>
|
||||
<li>
|
||||
<strong>Gap:</strong> 8px
|
||||
</li>
|
||||
<li>
|
||||
<strong>Layout:</strong> Two column grid
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ flex: "1 1 300px", minWidth: "280px" }}>
|
||||
<h6 className="mb-3">Desktop (≥992px)</h6>
|
||||
<ul className="mb-0">
|
||||
<li>
|
||||
<strong>Columns:</strong> 3
|
||||
</li>
|
||||
<li>
|
||||
<strong>Gap:</strong> 8px
|
||||
</li>
|
||||
<li>
|
||||
<strong>Layout:</strong> Three column grid
|
||||
</li>
|
||||
<li>
|
||||
<strong>Spacer:</strong> Enabled for 9+ cards
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
<SmallTilesSection
|
||||
headline="Responsive Demo"
|
||||
subtitle="Resize your browser to see the grid adapt"
|
||||
cardVariant="neutral"
|
||||
cards={languageTutorials}
|
||||
/>
|
||||
|
||||
{/* Real-World Examples */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Real-World Examples</h2>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
<div className="d-flex flex-column gap-8 mb-10">
|
||||
{/* Documentation Categories */}
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h6 className="mb-4">Documentation Categories</h6>
|
||||
<p className="mb-4 text-muted">
|
||||
Use SmallTilesSection to organize documentation by category or
|
||||
topic.
|
||||
</p>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
<SmallTilesSection
|
||||
headline="Browse by Category"
|
||||
subtitle="Explore documentation organized by topic"
|
||||
cardVariant="neutral"
|
||||
cards={[
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Concepts",
|
||||
label: "Concepts",
|
||||
href: "#concepts",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Tutorials",
|
||||
label: "Tutorials",
|
||||
href: "#tutorials",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "References",
|
||||
label: "References",
|
||||
href: "#references",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Use Cases",
|
||||
label: "Use Cases",
|
||||
href: "#use-cases",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
{/* Featured Resources */}
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h6 className="mb-4">Featured Resources</h6>
|
||||
<p className="mb-4 text-muted">
|
||||
Highlight important resources using the green variant.
|
||||
</p>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
<SmallTilesSection
|
||||
headline="Featured Resources"
|
||||
subtitle="Start here for the most important resources"
|
||||
cardVariant="green"
|
||||
cards={[
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Getting Started",
|
||||
label: "Getting Started",
|
||||
href: "#getting-started",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Quick Start",
|
||||
label: "Quick Start Guide",
|
||||
href: "#quickstart",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Best Practices",
|
||||
label: "Best Practices",
|
||||
href: "#best-practices",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
{/* Development Tools */}
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h6 className="mb-4">Development Tools</h6>
|
||||
<p className="mb-4 text-muted">
|
||||
Showcase available tools and SDKs.
|
||||
</p>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
<SmallTilesSection
|
||||
headline="Development Tools & SDKs"
|
||||
cardVariant="neutral"
|
||||
cards={[
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "xrpl.js",
|
||||
label: "xrpl.js",
|
||||
href: "#xrpl-js",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "xrpl-py",
|
||||
label: "xrpl-py",
|
||||
href: "#xrpl-py",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "xrpl-clio",
|
||||
label: "xrpl-clio",
|
||||
href: "#xrpl-clio",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "XRPL Explorer",
|
||||
label: "XRPL Explorer",
|
||||
href: "#explorer",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Testnet Faucet",
|
||||
label: "Testnet Faucet",
|
||||
href: "#faucet",
|
||||
},
|
||||
{
|
||||
icon: cardIconSvg,
|
||||
iconAlt: "Validator",
|
||||
label: "Validator",
|
||||
href: "#validator",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* API Reference */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Component API</h2>
|
||||
<div className="mb-10">
|
||||
{/* Header Row */}
|
||||
<div
|
||||
className="d-flex flex-row mb-3 pb-2"
|
||||
style={{
|
||||
gap: "1rem",
|
||||
borderBottom: "2px solid var(--bs-border-color, #dee2e6)",
|
||||
}}
|
||||
>
|
||||
<div style={{ width: "120px", flexShrink: 0 }}>
|
||||
<strong>Prop</strong>
|
||||
</div>
|
||||
<div style={{ flex: "1 1 0", minWidth: 0 }}>
|
||||
<strong>Type</strong>
|
||||
</div>
|
||||
<div style={{ width: "100px", flexShrink: 0 }}>
|
||||
<strong>Default</strong>
|
||||
</div>
|
||||
<div style={{ flex: "1 1 0", minWidth: 0 }}>
|
||||
<strong>Description</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* headline */}
|
||||
<div
|
||||
className="d-flex flex-row py-3"
|
||||
style={{
|
||||
gap: "1rem",
|
||||
borderBottom: "1px solid var(--bs-border-color, #dee2e6)",
|
||||
}}
|
||||
>
|
||||
<div style={{ width: "120px", flexShrink: 0 }}>
|
||||
<code>headline</code>
|
||||
</div>
|
||||
<div style={{ flex: "1 1 0", minWidth: 0 }}>
|
||||
<code>React.ReactNode</code>
|
||||
</div>
|
||||
<div style={{ width: "100px", flexShrink: 0 }}>
|
||||
<em>required</em>
|
||||
</div>
|
||||
<div style={{ flex: "1 1 0", minWidth: 0 }}>
|
||||
Section headline displayed as h2
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* subtitle */}
|
||||
<div
|
||||
className="d-flex flex-row py-3"
|
||||
style={{
|
||||
gap: "1rem",
|
||||
borderBottom: "1px solid var(--bs-border-color, #dee2e6)",
|
||||
}}
|
||||
>
|
||||
<div style={{ width: "120px", flexShrink: 0 }}>
|
||||
<code>subtitle</code>
|
||||
</div>
|
||||
<div style={{ flex: "1 1 0", minWidth: 0 }}>
|
||||
<code>React.ReactNode</code>
|
||||
</div>
|
||||
<div style={{ width: "100px", flexShrink: 0 }}>
|
||||
<code>undefined</code>
|
||||
</div>
|
||||
<div style={{ flex: "1 1 0", minWidth: 0 }}>
|
||||
Optional subtitle text displayed below headline
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* cardVariant */}
|
||||
<div
|
||||
className="d-flex flex-row py-3"
|
||||
style={{
|
||||
gap: "1rem",
|
||||
borderBottom: "1px solid var(--bs-border-color, #dee2e6)",
|
||||
}}
|
||||
>
|
||||
<div style={{ width: "120px", flexShrink: 0 }}>
|
||||
<code>cardVariant</code>
|
||||
</div>
|
||||
<div style={{ flex: "1 1 0", minWidth: 0 }}>
|
||||
<code>'neutral' | 'green'</code>
|
||||
</div>
|
||||
<div style={{ width: "100px", flexShrink: 0 }}>
|
||||
<em>required</em>
|
||||
</div>
|
||||
<div style={{ flex: "1 1 0", minWidth: 0 }}>
|
||||
Color variant applied to all cards in the section
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* cards */}
|
||||
<div
|
||||
className="d-flex flex-row py-3"
|
||||
style={{
|
||||
gap: "1rem",
|
||||
borderBottom: "1px solid var(--bs-border-color, #dee2e6)",
|
||||
}}
|
||||
>
|
||||
<div style={{ width: "120px", flexShrink: 0 }}>
|
||||
<code>cards</code>
|
||||
</div>
|
||||
<div style={{ flex: "1 1 0", minWidth: 0 }}>
|
||||
<code>CardIconProps[]</code>
|
||||
</div>
|
||||
<div style={{ width: "100px", flexShrink: 0 }}>
|
||||
<em>required</em>
|
||||
</div>
|
||||
<div style={{ flex: "1 1 0", minWidth: 0 }}>
|
||||
Array of card configurations (CardIconProps without variant
|
||||
prop). Section renders nothing if array is empty.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* className */}
|
||||
<div
|
||||
className="d-flex flex-row py-3"
|
||||
style={{
|
||||
gap: "1rem",
|
||||
borderBottom: "1px solid var(--bs-border-color, #dee2e6)",
|
||||
}}
|
||||
>
|
||||
<div style={{ width: "120px", flexShrink: 0 }}>
|
||||
<code>className</code>
|
||||
</div>
|
||||
<div style={{ flex: "1 1 0", minWidth: 0 }}>
|
||||
<code>string</code>
|
||||
</div>
|
||||
<div style={{ width: "100px", flexShrink: 0 }}>
|
||||
<code>''</code>
|
||||
</div>
|
||||
<div style={{ flex: "1 1 0", minWidth: 0 }}>
|
||||
Additional CSS classes for the section element
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Standard section props */}
|
||||
<div className="d-flex flex-row py-3" style={{ gap: "1rem" }}>
|
||||
<div style={{ width: "120px", flexShrink: 0 }}>
|
||||
<code>...rest</code>
|
||||
</div>
|
||||
<div style={{ flex: "1 1 0", minWidth: 0 }}>
|
||||
<code>React.ComponentPropsWithoutRef<"section"></code>
|
||||
</div>
|
||||
<div style={{ width: "100px", flexShrink: 0 }}>
|
||||
<code>-</code>
|
||||
</div>
|
||||
<div style={{ flex: "1 1 0", minWidth: 0 }}>
|
||||
All standard HTML section element props
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mb-10">
|
||||
<h3 className="h5 mb-4">Card Props (cards array items)</h3>
|
||||
<p className="mb-4">
|
||||
Each item in the <code>cards</code> array accepts all CardIcon
|
||||
props except <code>variant</code> (which is set via{" "}
|
||||
<code>cardVariant</code>).
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<code>icon</code> (string, required) - Icon image source
|
||||
</li>
|
||||
<li>
|
||||
<code>iconAlt</code> (string, optional) - Alt text for icon
|
||||
</li>
|
||||
<li>
|
||||
<code>label</code> (string, required) - Card label text
|
||||
</li>
|
||||
<li>
|
||||
<code>href</code> (string, optional) - Link destination
|
||||
(renders as anchor)
|
||||
</li>
|
||||
<li>
|
||||
<code>onClick</code> (() => void, optional) - Click
|
||||
handler (renders as button)
|
||||
</li>
|
||||
<li>
|
||||
<code>disabled</code> (boolean, optional) - Disabled state
|
||||
</li>
|
||||
<li>
|
||||
<code>className</code> (string, optional) - Additional CSS
|
||||
classes
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
{/* Design Notes */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Design Notes</h2>
|
||||
<div className="d-flex flex-column gap-4">
|
||||
<div>
|
||||
<h6 className="mb-2">Grid Layout</h6>
|
||||
<ul>
|
||||
<li>
|
||||
Responsive grid with automatic column adjustments at
|
||||
breakpoints
|
||||
</li>
|
||||
<li>
|
||||
8px gap between cards (consistent across all breakpoints)
|
||||
</li>
|
||||
<li>
|
||||
Grid uses CSS Grid with <code>grid-auto-flow: row</code>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="mb-2">Spacer Feature</h6>
|
||||
<ul>
|
||||
<li>Automatically enabled when card count exceeds 8</li>
|
||||
<li>Spacer is a grid-spanning invisible element</li>
|
||||
<li>
|
||||
Only visible on large screens (≥992px) to improve
|
||||
alignment
|
||||
</li>
|
||||
<li>
|
||||
Helps maintain consistent grid layout with varying card
|
||||
counts
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="mb-2">Typography</h6>
|
||||
<ul>
|
||||
<li>
|
||||
Headline uses <code>h4</code> class
|
||||
</li>
|
||||
<li>
|
||||
Subtitle uses <code>body-r</code> class
|
||||
</li>
|
||||
<li>8px margin below headline</li>
|
||||
<li>24px margin below subtitle (when present)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="mb-2">Component Structure</h6>
|
||||
<ul>
|
||||
<li>
|
||||
Returns <code>null</code> if cards array is empty
|
||||
</li>
|
||||
<li>
|
||||
Each card is wrapped in a <code><li></code> element
|
||||
</li>
|
||||
<li>Cards are rendered using the CardIcon component</li>
|
||||
<li>All cards in a section share the same variant</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -1,656 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { PageGrid, PageGridRow, PageGridCol } from 'shared/components/PageGrid/page-grid';
|
||||
import { Divider } from 'shared/components/Divider';
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
title: 'Typography Showcase',
|
||||
description: 'A comprehensive showcase of the XRPL.org typography system including displays, headings, subheads, body text, and labels.',
|
||||
},
|
||||
};
|
||||
|
||||
export default function TypographyShowcase() {
|
||||
return (
|
||||
<div className="landing">
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse col-lg-8 mx-auto">
|
||||
<h1 className="mb-0">Typography System</h1>
|
||||
<h6 className="eyebrow mb-3">Brand Design System</h6>
|
||||
</div>
|
||||
<p className="col-lg-8 mx-auto mt-10">
|
||||
A comprehensive overview of the XRPL typography system featuring responsive type scales,
|
||||
font families (Booton and Tobias), and semantic styling for consistent visual hierarchy.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Display Styles */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Display Styles</h2>
|
||||
<h6 className="eyebrow mb-3">Largest Headlines</h6>
|
||||
</div>
|
||||
<p className="mb-10 text-muted">
|
||||
Display styles are used for the largest, most prominent headlines. They feature negative letter spacing
|
||||
and are optimized for impact at large sizes.
|
||||
</p>
|
||||
|
||||
<div className="d-flex flex-column gap-10">
|
||||
<div>
|
||||
<div className="mb-3">
|
||||
<code className="text-muted">display-lg</code>
|
||||
<span className="text-muted mx-2">·</span>
|
||||
<span className="text-muted">Booton Light (300)</span>
|
||||
</div>
|
||||
<div className="display-lg">Display Large</div>
|
||||
<div className="mt-3 text-muted">
|
||||
<small>Mobile: 64px · Tablet: 72px · Desktop: 92px · XL: 112px</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="mb-3">
|
||||
<code className="text-muted">display-md</code>
|
||||
<span className="text-muted mx-2">·</span>
|
||||
<span className="text-muted">Tobias Light (300)</span>
|
||||
</div>
|
||||
<div className="display-md">Display Medium</div>
|
||||
<div className="mt-3 text-muted">
|
||||
<small>Mobile: 48px · Tablet: 60px · Desktop: 72px</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="mb-3">
|
||||
<code className="text-muted">display-sm</code>
|
||||
<span className="text-muted mx-2">·</span>
|
||||
<span className="text-muted">Tobias Light (300)</span>
|
||||
</div>
|
||||
<div className="display-sm">Display Small</div>
|
||||
<div className="mt-3 text-muted">
|
||||
<small>Mobile: 40px · Tablet: 56px · Desktop: 64px</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Divider color="gray" weight="thin" />
|
||||
|
||||
{/* Heading Styles */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Heading Styles</h2>
|
||||
<h6 className="eyebrow mb-3">Section Headers</h6>
|
||||
</div>
|
||||
<p className="mb-10 text-muted">
|
||||
Heading styles are used for major section headers and page titles. All headings use the Tobias monospace
|
||||
font family for a distinctive technical aesthetic.
|
||||
</p>
|
||||
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 4 }}>
|
||||
<div className="mb-6">
|
||||
<div className="mb-3">
|
||||
<code className="text-muted">heading-lg / .h-lg</code>
|
||||
</div>
|
||||
<div className="h-lg">Heading Large</div>
|
||||
<div className="mt-3 text-muted">
|
||||
<small>Mobile: 36px · Tablet: 42px · Desktop: 48px</small>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
|
||||
<PageGridCol span={{ base: 4, lg: 4 }}>
|
||||
<div className="mb-6">
|
||||
<div className="mb-3">
|
||||
<code className="text-muted">heading-md / .h-md</code>
|
||||
</div>
|
||||
<div className="h-md">Heading Medium</div>
|
||||
<div className="mt-3 text-muted">
|
||||
<small>Mobile: 32px · Tablet: 36px · Desktop: 40px</small>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
|
||||
<PageGridCol span={{ base: 4, lg: 4 }}>
|
||||
<div className="mb-6">
|
||||
<div className="mb-3">
|
||||
<code className="text-muted">heading-sm / .h-sm</code>
|
||||
</div>
|
||||
<div className="h-sm">Heading Small</div>
|
||||
<div className="mt-3 text-muted">
|
||||
<small>Mobile: 24px · Tablet: 28px · Desktop: 32px</small>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">Legacy H1-H6 Styles</h5>
|
||||
<p className="mb-6 text-muted">
|
||||
Traditional semantic HTML heading tags are also supported with responsive sizing.
|
||||
</p>
|
||||
|
||||
<div className="d-flex flex-column gap-6">
|
||||
<div>
|
||||
<code className="text-muted mb-2 d-block">h1, .h1</code>
|
||||
<h1 className="mb-2">The quick brown fox jumps</h1>
|
||||
<small className="text-muted">Desktop: 62px / Mobile: 42px</small>
|
||||
</div>
|
||||
<div>
|
||||
<code className="text-muted mb-2 d-block">h2, .h2</code>
|
||||
<h2 className="mb-2">The quick brown fox jumps</h2>
|
||||
<small className="text-muted">Desktop: 56px / Mobile: 28px</small>
|
||||
</div>
|
||||
<div>
|
||||
<code className="text-muted mb-2 d-block">h3, .h3</code>
|
||||
<h3 className="mb-2">The quick brown fox jumps</h3>
|
||||
<small className="text-muted">Desktop: 48px / Mobile: 24px</small>
|
||||
</div>
|
||||
<div>
|
||||
<code className="text-muted mb-2 d-block">h4, .h4</code>
|
||||
<h4 className="mb-2">The quick brown fox jumps over the lazy dog</h4>
|
||||
<small className="text-muted">Desktop: 32px / Mobile: 20px</small>
|
||||
</div>
|
||||
<div>
|
||||
<code className="text-muted mb-2 d-block">h5, .h5</code>
|
||||
<h5 className="mb-2">The quick brown fox jumps over the lazy dog</h5>
|
||||
<small className="text-muted">Desktop: 24px / Mobile: 18px</small>
|
||||
</div>
|
||||
<div>
|
||||
<code className="text-muted mb-2 d-block">h6, .h6</code>
|
||||
<h6 className="mb-2">The quick brown fox jumps over the lazy dog</h6>
|
||||
<small className="text-muted">Desktop: 20px / Mobile: 16px</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Divider color="gray" weight="thin" />
|
||||
|
||||
{/* Subhead Styles */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Subhead Styles</h2>
|
||||
<h6 className="eyebrow mb-3">Supporting Headers</h6>
|
||||
</div>
|
||||
<p className="mb-10 text-muted">
|
||||
Subheads provide intermediate hierarchy between headings and body text. Available in two weights:
|
||||
Regular (400) for emphasis and Light (300) for subtler styling.
|
||||
</p>
|
||||
|
||||
<div className="d-flex flex-column gap-10">
|
||||
{/* Large Subheads */}
|
||||
<div>
|
||||
<h5 className="mb-6">Large Subheads</h5>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<code className="text-muted mb-3 d-block">subhead-lg-r / .sh-lg-r</code>
|
||||
<div className="sh-lg-r">Regular Weight Subhead</div>
|
||||
<div className="mt-3 text-muted">
|
||||
<small>Mobile: 24px · Tablet: 28px · Desktop: 32px · Weight: 400</small>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<code className="text-muted mb-3 d-block">subhead-lg-l / .sh-lg-l</code>
|
||||
<div className="sh-lg-l">Light Weight Subhead</div>
|
||||
<div className="mt-3 text-muted">
|
||||
<small>Mobile: 24px · Tablet: 28px · Desktop: 32px · Weight: 300</small>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</div>
|
||||
|
||||
{/* Medium Subheads */}
|
||||
<div>
|
||||
<h5 className="mb-6">Medium Subheads</h5>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<code className="text-muted mb-3 d-block">subhead-md-r / .sh-md-r</code>
|
||||
<div className="sh-md-r">Regular Weight Subhead</div>
|
||||
<div className="mt-3 text-muted">
|
||||
<small>Mobile: 24px · Tablet: 26px · Desktop: 28px · Weight: 400</small>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<code className="text-muted mb-3 d-block">subhead-md-l / .sh-md-l</code>
|
||||
<div className="sh-md-l">Light Weight Subhead</div>
|
||||
<div className="mt-3 text-muted">
|
||||
<small>Mobile: 24px · Tablet: 26px · Desktop: 28px · Weight: 300</small>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</div>
|
||||
|
||||
{/* Small Subheads */}
|
||||
<div>
|
||||
<h5 className="mb-6">Small Subheads</h5>
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<code className="text-muted mb-3 d-block">subhead-sm-r / .sh-sm-r</code>
|
||||
<div className="sh-sm-r">Regular Weight Subhead</div>
|
||||
<div className="mt-3 text-muted">
|
||||
<small>Mobile: 18px · Tablet: 18px · Desktop: 24px · Weight: 400</small>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<code className="text-muted mb-3 d-block">subhead-sm-l / .sh-sm-l</code>
|
||||
<div className="sh-sm-l">Light Weight Subhead</div>
|
||||
<div className="mt-3 text-muted">
|
||||
<small>Mobile: 18px · Tablet: 18px · Desktop: 24px · Weight: 300</small>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Divider color="gray" weight="thin" />
|
||||
|
||||
{/* Body Text */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Body Text</h2>
|
||||
<h6 className="eyebrow mb-3">Content Typography</h6>
|
||||
</div>
|
||||
<p className="mb-10 text-muted">
|
||||
Body text styles are used for the main content areas. Available in Regular (400) for standard text
|
||||
and Light (300) for less prominent content.
|
||||
</p>
|
||||
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<code className="text-muted mb-3 d-block">body-r / .body-r</code>
|
||||
<div className="body-r">
|
||||
The quick brown fox jumps over the lazy dog. This is the standard body text style
|
||||
used throughout the site. It provides good readability at comfortable sizes across
|
||||
all devices. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
</div>
|
||||
<div className="mt-4 text-muted">
|
||||
<small>Mobile: 16px (line: 23.2px) · Desktop: 18px (line: 26.1px) · Weight: 400</small>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<code className="text-muted mb-3 d-block">body-l / .body-l</code>
|
||||
<div className="body-l">
|
||||
The quick brown fox jumps over the lazy dog. This is the light body text style
|
||||
for secondary content. It maintains the same size as regular body but with lighter
|
||||
weight for visual hierarchy. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
</div>
|
||||
<div className="mt-4 text-muted">
|
||||
<small>Mobile: 16px (line: 23.2px) · Desktop: 18px (line: 26.1px) · Weight: 300</small>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">Standard Paragraph</h5>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<code className="text-muted mb-3 d-block">p / default paragraph</code>
|
||||
<p>
|
||||
The standard paragraph element uses a base size of 16px with a 24px line height.
|
||||
This is the default for all unstyled paragraph text. The quick brown fox jumps over
|
||||
the lazy dog. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua.
|
||||
</p>
|
||||
<div className="text-muted">
|
||||
<small>Font-size: 16px · Line-height: 24px</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-10">
|
||||
<h5 className="mb-4">Longform Text</h5>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<code className="text-muted mb-3 d-block">.longform</code>
|
||||
<div className="longform">
|
||||
Longform text is designed for extended reading experiences with larger sizing and
|
||||
medium weight. Perfect for article introductions or key content blocks.
|
||||
</div>
|
||||
<div className="mt-4 text-muted">
|
||||
<small>Mobile: 20px (line: 26px) · Desktop: 24px (line: 32px) · Weight: 500</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Divider color="gray" weight="thin" />
|
||||
|
||||
{/* Labels */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Label Text</h2>
|
||||
<h6 className="eyebrow mb-3">UI Elements</h6>
|
||||
</div>
|
||||
<p className="mb-10 text-muted">
|
||||
Label styles are designed for UI elements, form labels, captions, and supplementary text.
|
||||
Smaller and optimized for clarity at reduced sizes.
|
||||
</p>
|
||||
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<code className="text-muted mb-3 d-block">label-r / .label-r</code>
|
||||
<div className="label-r mb-3">
|
||||
Regular label text for form inputs, captions, and UI elements.
|
||||
Maintains readability at smaller sizes.
|
||||
</div>
|
||||
<div className="text-muted">
|
||||
<small>Mobile: 14px (line: 20.1px) · Desktop: 16px (line: 23.2px) · Weight: 400</small>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<code className="text-muted mb-3 d-block">label-l / .label-l</code>
|
||||
<div className="label-l mb-3">
|
||||
Light label text for secondary UI text, metadata, and supplementary information.
|
||||
Provides subtle hierarchy.
|
||||
</div>
|
||||
<div className="text-muted">
|
||||
<small>Mobile: 14px (line: 20.1px) · Desktop: 16px (line: 23.2px) · Weight: 300</small>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</section>
|
||||
|
||||
<Divider color="gray" weight="thin" />
|
||||
|
||||
{/* Special Styles */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Special Styles</h2>
|
||||
<h6 className="eyebrow mb-3">Distinctive Elements</h6>
|
||||
</div>
|
||||
|
||||
<div className="d-flex flex-column gap-10">
|
||||
<div>
|
||||
<h5 className="mb-4">Eyebrow Text</h5>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<code className="text-muted mb-3 d-block">.eyebrow</code>
|
||||
<div className="eyebrow">Brand Design System</div>
|
||||
<p className="mt-4 mb-0 text-muted">
|
||||
Small uppercase labels that appear above headings to provide context or categorization.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h5 className="mb-4">Numbers (Statistics)</h5>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#141414', color: 'white' }}>
|
||||
<code className="mb-3 d-block" style={{ color: '#70EE97' }}>.numbers</code>
|
||||
<div className="numbers">1,234</div>
|
||||
<p className="mt-4 mb-0" style={{ color: '#C1C1C2' }}>
|
||||
Extra-large bold numbers for statistics and key metrics. Desktop: 96px / Mobile: 62px
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Divider color="gray" weight="thin" />
|
||||
|
||||
{/* Font Families */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Font Families</h2>
|
||||
<h6 className="eyebrow mb-3">Type Stack</h6>
|
||||
</div>
|
||||
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<h5 className="mb-4">Booton</h5>
|
||||
<p className="mb-4 text-muted">Primary sans-serif font family</p>
|
||||
<div style={{ fontFamily: 'Booton, sans-serif', fontSize: '32px', lineHeight: '1.2' }}>
|
||||
ABCDEFGHIJKLMNOPQRSTUVWXYZ<br />
|
||||
abcdefghijklmnopqrstuvwxyz<br />
|
||||
0123456789
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<p className="mb-2"><strong>Used for:</strong></p>
|
||||
<ul className="mb-0">
|
||||
<li>Display Large</li>
|
||||
<li>All Subheads</li>
|
||||
<li>Body Text</li>
|
||||
<li>Labels</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<h5 className="mb-4">Tobias</h5>
|
||||
<p className="mb-4 text-muted">Monospace font family</p>
|
||||
<div style={{ fontFamily: 'Tobias, monospace', fontSize: '32px', lineHeight: '1.2' }}>
|
||||
ABCDEFGHIJKLMNOPQRSTUVWXYZ<br />
|
||||
abcdefghijklmnopqrstuvwxyz<br />
|
||||
0123456789
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<p className="mb-2"><strong>Used for:</strong></p>
|
||||
<ul className="mb-0">
|
||||
<li>Display Medium & Small</li>
|
||||
<li>All Headings</li>
|
||||
<li>Legacy H1-H6</li>
|
||||
<li>Code blocks</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</section>
|
||||
|
||||
<Divider color="gray" weight="thin" />
|
||||
|
||||
{/* Typography in Context */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Typography in Context</h2>
|
||||
<h6 className="eyebrow mb-3">Real-World Examples</h6>
|
||||
</div>
|
||||
|
||||
<div className="d-flex flex-column gap-10">
|
||||
{/* Article Layout */}
|
||||
<div>
|
||||
<h5 className="mb-6">Article Layout</h5>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<div className="eyebrow mb-3">Documentation</div>
|
||||
<h2 className="h4 mb-4">Understanding the XRP Ledger</h2>
|
||||
<p className="longform mb-6">
|
||||
A comprehensive introduction to the decentralized blockchain that powers fast,
|
||||
low-cost global payments.
|
||||
</p>
|
||||
<h5 className="mb-3">What is the XRP Ledger?</h5>
|
||||
<p className="mb-4">
|
||||
The XRP Ledger is a decentralized public blockchain. It was built to be a better
|
||||
blockchain specifically for payments, with a unique design optimized for enterprise
|
||||
use cases. The XRP Ledger allows anyone to transfer money across borders instantly,
|
||||
reliably, and for fractions of a penny.
|
||||
</p>
|
||||
<h5 className="mb-3">Key Features</h5>
|
||||
<p className="mb-2">
|
||||
The ledger provides a number of innovative features that make it ideal for financial
|
||||
applications:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Fast transaction settlement (3-5 seconds)</li>
|
||||
<li>Low transaction costs (fractions of a penny)</li>
|
||||
<li>High throughput (1,500 transactions per second)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Hero Section */}
|
||||
<div>
|
||||
<h5 className="mb-6">Hero Section</h5>
|
||||
<div className="p-6-sm p-10-until-sm br-8 text-center" style={{ backgroundColor: '#141414', color: 'white' }}>
|
||||
<div className="eyebrow mb-4" style={{ color: '#70EE97' }}>Blockchain for Payments</div>
|
||||
<div className="display-md mb-6" style={{ color: 'white' }}>
|
||||
Build the Future of Finance
|
||||
</div>
|
||||
<p className="longform col-lg-8 mx-auto mb-0" style={{ color: '#C1C1C2' }}>
|
||||
Join a global community developing on the XRP Ledger—the most sustainable
|
||||
blockchain optimized for payments and tokenization.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Card with Stats */}
|
||||
<div>
|
||||
<h5 className="mb-6">Statistics Card</h5>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#141414', color: 'white' }}>
|
||||
<div className="text-center">
|
||||
<div className="numbers" style={{ color: '#21E46B' }}>10+</div>
|
||||
<div className="sh-md-r mb-3">Years of Operation</div>
|
||||
<p className="label-l mb-0" style={{ color: '#C1C1C2' }}>
|
||||
Reliably processing transactions since 2012
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Divider color="gray" weight="thin" />
|
||||
|
||||
{/* Responsive Behavior */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Responsive Behavior</h2>
|
||||
<h6 className="eyebrow mb-3">Breakpoint Adjustments</h6>
|
||||
</div>
|
||||
<p className="mb-6 text-muted">
|
||||
All typography styles automatically adjust across breakpoints for optimal readability on any device.
|
||||
</p>
|
||||
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#f5f5f7' }}>
|
||||
<h5 className="mb-4">Breakpoint System</h5>
|
||||
<ul className="mb-4">
|
||||
<li><strong>Mobile:</strong> Base styles (0-767px)</li>
|
||||
<li><strong>Tablet:</strong> Medium breakpoint (768px-1023px)</li>
|
||||
<li><strong>Desktop:</strong> Large breakpoint (1024px+)</li>
|
||||
<li><strong>XL:</strong> Extra large (1200px+) — only used for Display Large</li>
|
||||
</ul>
|
||||
<p className="mb-0 text-muted">
|
||||
Resize your browser window to see typography scale responsively. Font sizes, line heights,
|
||||
and letter spacing all adjust to maintain optimal readability at every viewport size.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Divider color="gray" weight="thin" />
|
||||
|
||||
{/* Usage Guidelines */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Usage Guidelines</h2>
|
||||
<h6 className="eyebrow mb-3">Best Practices</h6>
|
||||
</div>
|
||||
|
||||
<PageGrid>
|
||||
<PageGridRow>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<h5 className="mb-4">Do</h5>
|
||||
<ul>
|
||||
<li>Use Display styles sparingly for maximum impact</li>
|
||||
<li>Maintain consistent hierarchy with heading levels</li>
|
||||
<li>Pair Regular and Light weights for visual contrast</li>
|
||||
<li>Use Eyebrow text above headings for context</li>
|
||||
<li>Apply Longform class to article introductions</li>
|
||||
<li>Let typography breathe with adequate spacing</li>
|
||||
</ul>
|
||||
</PageGridCol>
|
||||
<PageGridCol span={{ base: 4, lg: 6 }}>
|
||||
<h5 className="mb-4">Don't</h5>
|
||||
<ul>
|
||||
<li>Don't skip heading levels in the hierarchy</li>
|
||||
<li>Don't use Display styles for body content</li>
|
||||
<li>Don't mix too many font weights on one screen</li>
|
||||
<li>Don't override letter spacing on Display text</li>
|
||||
<li>Don't use Tobias for long-form reading</li>
|
||||
<li>Don't ignore responsive scaling</li>
|
||||
</ul>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</section>
|
||||
|
||||
<Divider color="gray" weight="thin" />
|
||||
|
||||
{/* Code Examples */}
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h2 className="h4 mb-8">Code Examples</h2>
|
||||
<h6 className="eyebrow mb-3">Implementation</h6>
|
||||
</div>
|
||||
<div className="p-6-sm p-10-until-sm br-8" style={{ backgroundColor: '#1e1e1e', color: '#d4d4d4' }}>
|
||||
<pre style={{ margin: 0, overflow: 'auto' }}>
|
||||
<code>{`// Display Styles
|
||||
<div className="display-lg">Largest headline</div>
|
||||
<div className="display-md">Medium display</div>
|
||||
<div className="display-sm">Small display</div>
|
||||
|
||||
// Headings
|
||||
<div className="h-lg">Large heading</div>
|
||||
<div className="h-md">Medium heading</div>
|
||||
<div className="h-sm">Small heading</div>
|
||||
|
||||
// Or use semantic HTML
|
||||
<h1>Heading Level 1</h1>
|
||||
<h2>Heading Level 2</h2>
|
||||
|
||||
// Subheads
|
||||
<div className="sh-lg-r">Large subhead regular</div>
|
||||
<div className="sh-md-l">Medium subhead light</div>
|
||||
<div className="sh-sm-r">Small subhead regular</div>
|
||||
|
||||
// Body Text
|
||||
<div className="body-r">Regular body text</div>
|
||||
<div className="body-l">Light body text</div>
|
||||
<p className="longform">Extended reading text</p>
|
||||
|
||||
// Labels
|
||||
<div className="label-r">UI label regular</div>
|
||||
<div className="label-l">UI label light</div>
|
||||
|
||||
// Special Styles
|
||||
<div className="eyebrow">Category Label</div>
|
||||
<div className="numbers">1,234</div>`}</code>
|
||||
</pre>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -850,17 +850,17 @@ export default function Uses() {
|
||||
</div>
|
||||
<a
|
||||
className="btn d-block d-lg-none"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#categoryFilterModal"
|
||||
data-toggle="modal"
|
||||
data-target="#categoryFilterModal"
|
||||
>
|
||||
<span className="me-3">
|
||||
<span className="mr-3">
|
||||
<img
|
||||
src={require("../static/img/uses/usecase-filter.svg")}
|
||||
alt="Filter button"
|
||||
/>
|
||||
</span>
|
||||
{translate("Filter by Categories")}
|
||||
<span className="ms-3 total_count category_count">2</span>
|
||||
<span className="ml-3 total_count category_count">2</span>
|
||||
</a>
|
||||
{/* Start company cards */}
|
||||
<div className="row col-12 m-0 p-0 mt-4 pt-2">
|
||||
|
||||
@@ -116,380 +116,400 @@ export default function XrpOverview() {
|
||||
const totalCols = Math.max(softwallets.length, hardwallets.length) + 1;
|
||||
return (
|
||||
<div className="landing">
|
||||
<section className="py-26 text-center">
|
||||
<div className="col-lg-5 mx-auto text-center">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h1 className="mb-0">
|
||||
{translate("Your Questions About XRP, Answered")}
|
||||
</h1>
|
||||
<h6 className="eyebrow mb-3">{translate("XRP Overview")}</h6>
|
||||
</div>
|
||||
<div>
|
||||
<div className="position-relative">
|
||||
<img
|
||||
alt="blue waves"
|
||||
src={require("../static/img/backgrounds/xrp-overview-blue.svg")}
|
||||
className="landing-bg"
|
||||
id="xrp-overview-blue"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
<section className="container-new my-20">
|
||||
<div className="card-grid card-grid-1x2">
|
||||
<div className="d-none-sm mt-lg-0">
|
||||
<ul className="page-toc no-sideline p-0 sticky-top floating-nav">
|
||||
{links.map((link) => (
|
||||
<li
|
||||
key={link.hash}
|
||||
className={`nav-item ${
|
||||
activeSection === link.hash.substring(1) ? "active" : ""
|
||||
}`}
|
||||
>
|
||||
<a
|
||||
className={`sidelinks nav-link ${
|
||||
<section className="py-26 text-center">
|
||||
<div className="col-lg-5 mx-auto text-center">
|
||||
<div className="d-flex flex-column-reverse">
|
||||
<h1 className="mb-0">
|
||||
{translate("Your Questions About XRP, Answered")}
|
||||
</h1>
|
||||
<h6 className="eyebrow mb-3">{translate("XRP Overview")}</h6>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section className="container-new my-20">
|
||||
<div className="card-grid card-grid-1x2">
|
||||
<div className="d-none-sm mt-lg-0">
|
||||
<ul className="page-toc no-sideline p-0 sticky-top floating-nav">
|
||||
{links.map((link) => (
|
||||
<li
|
||||
key={link.hash}
|
||||
className={`nav-item ${
|
||||
activeSection === link.hash.substring(1) ? "active" : ""
|
||||
}`}
|
||||
href={link.hash}
|
||||
>
|
||||
{translate(link.text)}
|
||||
<a
|
||||
className={`sidelinks nav-link ${
|
||||
activeSection === link.hash.substring(1) ? "active" : ""
|
||||
}`}
|
||||
href={link.hash}
|
||||
>
|
||||
{translate(link.text)}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div className="col mt-lg-0">
|
||||
<div className="link-section pb-26" id="about-xrp">
|
||||
<h2 className="h4 h2-sm mb-8">{translate("What Is XRP?")}</h2>
|
||||
<h5 className="longform mb-10">
|
||||
{translate(
|
||||
"about.xrp.what-is-xrp.ppart1",
|
||||
"XRP is a digital asset that’s native to the XRP Ledger—an open-source, permissionless and decentralized ",
|
||||
)}
|
||||
<a
|
||||
href="https://www.distributedagreement.com/2018/09/24/what-is-a-blockchain/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{translate("about.xrp.what-is-xrp.ppart2", "blockchain technology.")}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div className="col mt-lg-0">
|
||||
<div className="link-section pb-26" id="about-xrp">
|
||||
<h2 className="h4 h2-sm mb-8">{translate("What Is XRP?")}</h2>
|
||||
<h5 className="longform mb-10">
|
||||
{translate(
|
||||
"about.xrp.what-is-xrp.ppart1",
|
||||
"XRP is a digital asset that’s native to the XRP Ledger—an open-source, permissionless and decentralized ",
|
||||
)}
|
||||
<a
|
||||
href="https://www.distributedagreement.com/2018/09/24/what-is-a-blockchain/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{translate("about.xrp.what-is-xrp.ppart2", "blockchain technology.")}
|
||||
</a>
|
||||
{translate("about.xrp.what-is-xrp.ppart3", " ")}
|
||||
</h5>
|
||||
{translate("about.xrp.what-is-xrp.ppart3", " ")}
|
||||
</h5>
|
||||
|
||||
<p className="mb-6">
|
||||
{translate(
|
||||
"Created in 2012 specifically for payments, XRP can settle transactions on the ledger in 3-5 seconds. It was built to be a better Bitcoin—faster, cheaper and greener than any other digital asset."
|
||||
)}
|
||||
</p>
|
||||
<div className="overflow-x-xs">
|
||||
<table className="mb-10 landing-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<h6>{translate("Benefits")}</h6>
|
||||
</th>
|
||||
<th>
|
||||
<h6>{translate("XRP")}</h6>
|
||||
</th>
|
||||
<th>
|
||||
<h6>{translate("Bitcoin")}</h6>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{translate("Fast")}</td>
|
||||
<td>{translate("3-5 seconds to settle")}</td>
|
||||
<td>{translate("500 seconds to settle")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{translate("Low-Cost")}</td>
|
||||
<td>{translate("$0.0002/tx")}</td>
|
||||
<td>{translate("$0.50/tx")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{translate("Scalable")}</td>
|
||||
<td>{translate("1,500 tx per second")}</td>
|
||||
<td>{translate("3 tx per second")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{translate("Sustainable")}</td>
|
||||
<td>
|
||||
{translate(
|
||||
"Environmentally sustainable (negligible energy consumption)"
|
||||
)}
|
||||
</td>
|
||||
<td>
|
||||
{translate("0.3% of global energy consumption")}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p className="mb-10">
|
||||
{translate(
|
||||
"XRP can be sent directly without needing a central intermediary, making it a convenient instrument in bridging two different currencies quickly and efficiently. It is freely exchanged on the open market and used in the real world for enabling cross-border payments and microtransactions."
|
||||
)}
|
||||
</p>
|
||||
<div className="card-grid card-grid-2xN mb-10">
|
||||
<div>
|
||||
<p className="mb-6">
|
||||
{translate(
|
||||
"Created in 2012 specifically for payments, XRP can settle transactions on the ledger in 3-5 seconds. It was built to be a better Bitcoin—faster, cheaper and greener than any other digital asset."
|
||||
)}
|
||||
</p>
|
||||
<div className="overflow-x-xs">
|
||||
<table className="mb-10 landing-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<h6>{translate("Benefits")}</h6>
|
||||
</th>
|
||||
<th>
|
||||
<h6>{translate("XRP")}</h6>
|
||||
</th>
|
||||
<th>
|
||||
<h6>{translate("Bitcoin")}</h6>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{translate("Fast")}</td>
|
||||
<td>{translate("3-5 seconds to settle")}</td>
|
||||
<td>{translate("500 seconds to settle")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{translate("Low-Cost")}</td>
|
||||
<td>{translate("$0.0002/tx")}</td>
|
||||
<td>{translate("$0.50/tx")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{translate("Scalable")}</td>
|
||||
<td>{translate("1,500 tx per second")}</td>
|
||||
<td>{translate("3 tx per second")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{translate("Sustainable")}</td>
|
||||
<td>
|
||||
{translate(
|
||||
"Environmentally sustainable (negligible energy consumption)"
|
||||
)}
|
||||
</td>
|
||||
<td>
|
||||
{translate("0.3% of global energy consumption")}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p className="mb-10">
|
||||
{translate(
|
||||
"XRP can be sent directly without needing a central intermediary, making it a convenient instrument in bridging two different currencies quickly and efficiently. It is freely exchanged on the open market and used in the real world for enabling cross-border payments and microtransactions."
|
||||
)}
|
||||
</p>
|
||||
<div className="card-grid card-grid-2xN mb-10">
|
||||
<div>
|
||||
<img
|
||||
alt="briefcase"
|
||||
className="mw-100 mb-2 invertible-img"
|
||||
src={briefcaseIcon}
|
||||
/>
|
||||
<h6 className="fs-4-5">
|
||||
{translate("Financial Institutions")}
|
||||
</h6>
|
||||
<p className="">
|
||||
{translate(
|
||||
"Leverage XRP as a bridge currency to facilitate faster, more affordable cross-border payments around the world."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<img
|
||||
alt="user"
|
||||
className="mw-100 mb-2 invertible-img"
|
||||
src={userIcon}
|
||||
/>
|
||||
<h6 className="fs-4-5">
|
||||
{translate("Individual Consumers")}
|
||||
</h6>
|
||||
<p>
|
||||
{translate(
|
||||
"Use XRP to move different currencies around the world."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-10 p-10 br-8 cta-card position-relative">
|
||||
<img
|
||||
alt="briefcase"
|
||||
className="mw-100 mb-2 invertible-img"
|
||||
src={briefcaseIcon}
|
||||
alt="magenta waves"
|
||||
src={require("../static/img/backgrounds/cta-xrp-overview-magenta.svg")}
|
||||
className="cta cta-bottom-right"
|
||||
/>
|
||||
<h6 className="subhead-sm-r">
|
||||
{translate("Financial Institutions")}
|
||||
</h6>
|
||||
<p className="">
|
||||
{translate(
|
||||
"Leverage XRP as a bridge currency to facilitate faster, more affordable cross-border payments around the world."
|
||||
)}
|
||||
</p>
|
||||
<div className="z-index-1 position-relative">
|
||||
<h2 className="h4 mb-10-until-sm mb-8-sm">
|
||||
{translate(
|
||||
"The XRP Ledger is built for business."
|
||||
)}
|
||||
</h2>
|
||||
<p className="mb-10">
|
||||
{translate(
|
||||
"The only major L-1 blockchain that’s built for business and designed specifically to power finance use cases and applications at scale. Powerful enough to bootstrap a new economy, the XRP Ledger (XRPL) is fast, scalable, and sustainable."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
</div>
|
||||
<div className="py-26 link-section" id="xrp-trading">
|
||||
<h2 className="h4 h2-sm mb-8">
|
||||
{translate("How Is XRP Used in Trading?")}
|
||||
</h2>
|
||||
<h5 className="longform mb-10">
|
||||
{translate(
|
||||
"XRP is traded on more than 100 markets and exchanges worldwide."
|
||||
)}
|
||||
</h5>
|
||||
<p className="mb-6">
|
||||
{translate(
|
||||
"about.xrp.xrp-in-trading.ppart1",
|
||||
"XRP’s low transaction fees, reliability and high-speed enable traders to use the digital asset as high-speed, cost-efficient and reliable collateral across trading venues—"
|
||||
)}
|
||||
<a
|
||||
href="https://ripple.com/insights/xrp-a-preferred-base-currency-for-arbitrage-trading/"
|
||||
target="_blank"
|
||||
>
|
||||
{translate("about.xrp.xrp-in-trading.ppart2","seizing arbitrage opportunities")}
|
||||
</a>
|
||||
{translate(
|
||||
"about.xrp.xrp-in-trading.ppart3",
|
||||
", servicing margin calls and managing general trading inventory in real time."
|
||||
)}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
{translate(
|
||||
"Because of the properties inherent to XRP and the ecosystem around it, traders worldwide are able to shift collateral, bridge currencies and switch from one crypto into another nearly instantly, across any exchange on the planet."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div className="py-26 link-section" id="ripple">
|
||||
<h2 className="h4 h2-sm mb-8">
|
||||
{translate(
|
||||
"What Is the Relationship Between Ripple and XRP?"
|
||||
)}
|
||||
</h2>
|
||||
<h5 className="longform mb-10">
|
||||
<a href="https://ripple.com" target="_blank">
|
||||
{translate("Ripple")}
|
||||
</a>
|
||||
{translate(
|
||||
" is a technology company that makes it easier to build a high-performance, global payments business. XRP is a digital asset independent of this."
|
||||
)}
|
||||
</h5>
|
||||
|
||||
<p>
|
||||
{translate(
|
||||
"There is a finite amount of XRP. All XRP is already in existence today—no more than the original 100 billion can be created. The XRPL founders gifted 80 billion XRP, the platform’s native currency, to Ripple. To provide predictability to the XRP supply, Ripple has locked 55 billion XRP (55% of the total possible supply) into a series of escrows using the XRP Ledger itself. The XRPL's transaction processing rules, enforced by the consensus protocol, control the release of the XRP."
|
||||
)}
|
||||
</p>
|
||||
<div className="mt-10 p-10 br-8 cta-card position-relative">
|
||||
<img
|
||||
alt="user"
|
||||
className="mw-100 mb-2 invertible-img"
|
||||
src={userIcon}
|
||||
alt="green waves"
|
||||
src={require("../static/img/backgrounds/cta-xrp-overview-green-2.svg")}
|
||||
className="landing-bg cta cta-bottom-right"
|
||||
/>
|
||||
<h6 className="subhead-sm-r">
|
||||
{translate("Individual Consumers")}
|
||||
</h6>
|
||||
<p>
|
||||
{translate(
|
||||
"Use XRP to move different currencies around the world."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-10 p-10 br-8 cta-card position-relative">
|
||||
<div className="z-index-1 position-relative">
|
||||
<h2 className="h4 mb-10-until-sm mb-8-sm">
|
||||
{translate(
|
||||
"The XRP Ledger is built for business."
|
||||
)}
|
||||
</h2>
|
||||
<p className="mb-10">
|
||||
{translate(
|
||||
"The only major L-1 blockchain that’s built for business and designed specifically to power finance use cases and applications at scale. Powerful enough to bootstrap a new economy, the XRP Ledger (XRPL) is fast, scalable, and sustainable."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="py-26 link-section" id="xrp-trading">
|
||||
<h2 className="h4 h2-sm mb-8">
|
||||
{translate("How Is XRP Used in Trading?")}
|
||||
</h2>
|
||||
<h5 className="longform mb-10">
|
||||
{translate(
|
||||
"XRP is traded on more than 100 markets and exchanges worldwide."
|
||||
)}
|
||||
</h5>
|
||||
<p className="mb-6">
|
||||
{translate(
|
||||
"about.xrp.xrp-in-trading.ppart1",
|
||||
"XRP’s low transaction fees, reliability and high-speed enable traders to use the digital asset as high-speed, cost-efficient and reliable collateral across trading venues—"
|
||||
)}
|
||||
<a
|
||||
href="https://ripple.com/insights/xrp-a-preferred-base-currency-for-arbitrage-trading/"
|
||||
target="_blank"
|
||||
>
|
||||
{translate("about.xrp.xrp-in-trading.ppart2","seizing arbitrage opportunities")}
|
||||
</a>
|
||||
{translate(
|
||||
"about.xrp.xrp-in-trading.ppart3",
|
||||
", servicing margin calls and managing general trading inventory in real time."
|
||||
)}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
{translate(
|
||||
"Because of the properties inherent to XRP and the ecosystem around it, traders worldwide are able to shift collateral, bridge currencies and switch from one crypto into another nearly instantly, across any exchange on the planet."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div className="py-26 link-section" id="ripple">
|
||||
<h2 className="h4 h2-sm mb-8">
|
||||
{translate(
|
||||
"What Is the Relationship Between Ripple and XRP?"
|
||||
)}
|
||||
</h2>
|
||||
<h5 className="longform mb-10">
|
||||
<a href="https://ripple.com" target="_blank">
|
||||
{translate("Ripple")}
|
||||
</a>
|
||||
{translate(
|
||||
" is a technology company that makes it easier to build a high-performance, global payments business. XRP is a digital asset independent of this."
|
||||
)}
|
||||
</h5>
|
||||
|
||||
<p>
|
||||
{translate(
|
||||
"There is a finite amount of XRP. All XRP is already in existence today—no more than the original 100 billion can be created. The XRPL founders gifted 80 billion XRP, the platform’s native currency, to Ripple. To provide predictability to the XRP supply, Ripple has locked 55 billion XRP (55% of the total possible supply) into a series of escrows using the XRP Ledger itself. The XRPL's transaction processing rules, enforced by the consensus protocol, control the release of the XRP."
|
||||
)}
|
||||
</p>
|
||||
<div className="mt-10 p-10 br-8 cta-card position-relative">
|
||||
<div className="z-index-1 position-relative">
|
||||
<h3 className="h4">
|
||||
{translate("about.xrp.ripple-escrow.ppart1","As of ")}
|
||||
<span className="stat-highlight" id="ripple-escrow-as-of">
|
||||
{translate("about.xrp.ripple-escrow.ppart2","October 2024")}
|
||||
</span>
|
||||
{translate("about.xrp.ripple-escrow.ppart3"," ")}
|
||||
<br />
|
||||
<span className="d-inline-flex">
|
||||
<img
|
||||
id="xrp-mark-overview"
|
||||
className="mw-100 invertible-img me-2"
|
||||
src={require("../static/img/logos/xrp-mark.svg")}
|
||||
alt="XRP Logo Mark"
|
||||
/>
|
||||
<span
|
||||
className="numbers stat-highlight"
|
||||
id="ripple-escrow-amount"
|
||||
>
|
||||
{translate("38B")}
|
||||
<div className="z-index-1 position-relative">
|
||||
<h3 className="h4">
|
||||
{translate("about.xrp.ripple-escrow.ppart1","As of ")}
|
||||
<span className="stat-highlight" id="ripple-escrow-as-of">
|
||||
{translate("about.xrp.ripple-escrow.ppart2","October 2024")}
|
||||
</span>
|
||||
</span>
|
||||
<br />
|
||||
{translate("XRP remains in escrow")}
|
||||
</h3>
|
||||
{translate("about.xrp.ripple-escrow.ppart3"," ")}
|
||||
<br />
|
||||
<span className="d-inline-flex">
|
||||
<img
|
||||
id="xrp-mark-overview"
|
||||
className="mw-100 invertible-img mr-2"
|
||||
src={require("../static/img/logos/xrp-mark.svg")}
|
||||
alt="XRP Logo Mark"
|
||||
/>
|
||||
<span
|
||||
className="numbers stat-highlight"
|
||||
id="ripple-escrow-amount"
|
||||
>
|
||||
{translate("38B")}
|
||||
</span>
|
||||
</span>
|
||||
<br />
|
||||
{translate("XRP remains in escrow")}
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="link-section py-26" id="wallets">
|
||||
<h2 className="h4 h2-sm mb-8">
|
||||
{translate("What Wallets Support XRP?")}
|
||||
</h2>
|
||||
<h5 className="longform mb-10">
|
||||
{translate(
|
||||
"Digital wallets are pieces of software that allow people to send, receive, and store cryptocurrencies, including XRP. There are two types of digital wallets: hardware and software."
|
||||
)}
|
||||
</h5>
|
||||
<ul className={`nav nav-grid-lg cols-of-${totalCols}`} id="wallets">
|
||||
<li className="nav-item nav-grid-head">
|
||||
<h6 className="subhead-sm-r">{translate("Software Wallets")}</h6>
|
||||
</li>
|
||||
{softwallets.map((wallet) => (
|
||||
<li key={wallet.id} className="nav-item">
|
||||
<a
|
||||
className="nav-link external-link"
|
||||
href={wallet.href}
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
className={`mw-100 ${
|
||||
!!wallet?.imgclasses && wallet.imgclasses
|
||||
}`}
|
||||
id={wallet.id}
|
||||
alt={wallet.alt}
|
||||
/>
|
||||
</a>
|
||||
<div className="link-section py-26" id="wallets">
|
||||
<h2 className="h4 h2-sm mb-8">
|
||||
{translate("What Wallets Support XRP?")}
|
||||
</h2>
|
||||
<h5 className="longform mb-10">
|
||||
{translate(
|
||||
"Digital wallets are pieces of software that allow people to send, receive, and store cryptocurrencies, including XRP. There are two types of digital wallets: hardware and software."
|
||||
)}
|
||||
</h5>
|
||||
<ul className={`nav nav-grid-lg cols-of-${totalCols}`} id="wallets">
|
||||
<li className="nav-item nav-grid-head">
|
||||
<h6 className="fs-4-5">{translate("Software Wallets")}</h6>
|
||||
</li>
|
||||
))}
|
||||
<li className="nav-item nav-grid-head">
|
||||
<h6 className="subhead-sm-r">{translate("Hardware Wallets")}</h6>
|
||||
</li>
|
||||
{hardwallets.map((wallet) => (
|
||||
<li className="nav-item" key={wallet.id}>
|
||||
<a
|
||||
className="nav-link external-link"
|
||||
href={wallet.href}
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
className={`mw-100 ${
|
||||
!!wallet.imgclasses && wallet.imgclasses
|
||||
}`}
|
||||
id={wallet.id}
|
||||
alt={wallet.alt}
|
||||
/>
|
||||
</a>
|
||||
{softwallets.map((wallet) => (
|
||||
<li key={wallet.id} className="nav-item">
|
||||
<a
|
||||
className="nav-link external-link"
|
||||
href={wallet.href}
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
className={`mw-100 ${
|
||||
!!wallet?.imgclasses && wallet.imgclasses
|
||||
}`}
|
||||
id={wallet.id}
|
||||
alt={wallet.alt}
|
||||
/>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
<li className="nav-item nav-grid-head">
|
||||
<h6 className="fs-4-5">{translate("Hardware Wallets")}</h6>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<p className="label-l mt-10">
|
||||
{translate(
|
||||
"Disclaimer: This information is drawn from other sources on the internet. XRPL.org does not endorse or recommend any exchanges or make any representations with respect to exchanges or the purchase or sale of digital assets more generally. It’s advisable to conduct your own due diligence before relying on any third party or third-party technology, and providers may vary significantly in their compliance, data security, and privacy practices."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div className="py-26 link-section" id="exchanges">
|
||||
<h2 className="h4 h2-sm mb-8">
|
||||
{translate("What Exchanges Support XRP?")}
|
||||
</h2>
|
||||
<h5 className="longform mb-10">
|
||||
{translate(
|
||||
"Exchanges are where people trade currencies. XRP is traded on more than 100 markets and exchanges worldwide."
|
||||
)}
|
||||
</h5>
|
||||
<p className="mb-10">
|
||||
{translate(
|
||||
"There are different types of exchanges that vary depending on the type of market (spot, futures, options, swaps), and the type of security model (custodial, non-custodial)."
|
||||
)}
|
||||
</p>
|
||||
<div className="card-grid card-grid-2xN mb-10">
|
||||
<div>
|
||||
<h6 className="subhead-sm-r">{translate("Spot Exchanges")}</h6>
|
||||
<p className="mb-0">
|
||||
{translate(
|
||||
"Spot exchanges allow people to buy and sell cryptocurrencies at current (spot) market rates."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="subhead-sm-r">
|
||||
{translate("Futures, Options and Swap Exchanges")}
|
||||
</h6>
|
||||
<p className="mb-0">
|
||||
{translate(
|
||||
"Futures, options and swap exchanges allow people to buy and sell standardized contracts of cryptocurrency market rates in the future."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="subhead-sm-r">
|
||||
{translate("Custodial Exchanges")}
|
||||
</h6>
|
||||
<p className="mb-0">
|
||||
{translate(
|
||||
"Custodial exchanges manage a user’s private keys, and publish centralized order books of buyers and sellers."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="subhead-sm-r">
|
||||
{translate("Non-Custodial Exchanges")}
|
||||
</h6>
|
||||
<p className="mb-0">
|
||||
{translate(
|
||||
"Non-custodial exchanges, also known as decentralized exchanges, do not manage a user’s private keys, and publish decentralized order books of buyers and sellers on a blockchain."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
{hardwallets.map((wallet) => (
|
||||
<li className="nav-item" key={wallet.id}>
|
||||
<a
|
||||
className="nav-link external-link"
|
||||
href={wallet.href}
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
className={`mw-100 ${
|
||||
!!wallet.imgclasses && wallet.imgclasses
|
||||
}`}
|
||||
id={wallet.id}
|
||||
alt={wallet.alt}
|
||||
/>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<p className="fs-3 mt-10">
|
||||
{translate(
|
||||
"Disclaimer: This information is drawn from other sources on the internet. XRPL.org does not endorse or recommend any exchanges or make any representations with respect to exchanges or the purchase or sale of digital assets more generally. It’s advisable to conduct your own due diligence before relying on any third party or third-party technology, and providers may vary significantly in their compliance, data security, and privacy practices."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div className="py-26 link-section" id="exchanges">
|
||||
<h2 className="h4 h2-sm mb-8">
|
||||
{translate("What Exchanges Support XRP?")}
|
||||
</h2>
|
||||
<h5 className="longform mb-10">
|
||||
{translate(
|
||||
"Exchanges are where people trade currencies. XRP is traded on more than 100 markets and exchanges worldwide."
|
||||
)}
|
||||
</h5>
|
||||
<p className="mb-10">
|
||||
{translate(
|
||||
"There are different types of exchanges that vary depending on the type of market (spot, futures, options, swaps), and the type of security model (custodial, non-custodial)."
|
||||
)}
|
||||
</p>
|
||||
<div className="card-grid card-grid-2xN mb-10">
|
||||
<div>
|
||||
<h6 className="fs-4-5">{translate("Spot Exchanges")}</h6>
|
||||
<p className="mb-0">
|
||||
{translate(
|
||||
"Spot exchanges allow people to buy and sell cryptocurrencies at current (spot) market rates."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="fs-4-5">
|
||||
{translate("Futures, Options and Swap Exchanges")}
|
||||
</h6>
|
||||
<p className="mb-0">
|
||||
{translate(
|
||||
"Futures, options and swap exchanges allow people to buy and sell standardized contracts of cryptocurrency market rates in the future."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="fs-4-5">
|
||||
{translate("Custodial Exchanges")}
|
||||
</h6>
|
||||
<p className="mb-0">
|
||||
{translate(
|
||||
"Custodial exchanges manage a user’s private keys, and publish centralized order books of buyers and sellers."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="fs-4-5">
|
||||
{translate("Non-Custodial Exchanges")}
|
||||
</h6>
|
||||
<p className="mb-0">
|
||||
{translate(
|
||||
"Non-custodial exchanges, also known as decentralized exchanges, do not manage a user’s private keys, and publish decentralized order books of buyers and sellers on a blockchain."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<h6>
|
||||
{translate("Top Exchanges, according to CryptoCompare")}
|
||||
</h6>
|
||||
<ul
|
||||
className="nav nav-grid-lg cols-of-5 mb-10"
|
||||
id="top-exchanges"
|
||||
>
|
||||
{exchanges.map((exch, i) => (
|
||||
<li className="nav-item" key={exch.id}>
|
||||
<a
|
||||
className="nav-link external-link"
|
||||
href={exch.href}
|
||||
target="_blank"
|
||||
>
|
||||
<span className="longform mr-3">{i+1}</span>
|
||||
<img className="mw-100" id={exch.id} alt={exch.alt} />
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<p className="fs-3 mt-10 mb-0">
|
||||
{translate(
|
||||
"Disclaimer: This information is drawn from other sources on the internet. XRPL.org does not endorse or recommend any exchanges or make any representations with respect to exchanges or the purchase or sale of digital assets more generally. It’s advisable to conduct your own due diligence before relying on any third party or third-party technology, and providers may vary significantly in their compliance, data security, and privacy practices."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<h6>
|
||||
{translate("Top Exchanges, according to CryptoCompare")}
|
||||
</h6>
|
||||
<ul
|
||||
className="nav nav-grid-lg cols-of-5 mb-10"
|
||||
id="top-exchanges"
|
||||
>
|
||||
{exchanges.map((exch, i) => (
|
||||
<li className="nav-item" key={exch.id}>
|
||||
<a
|
||||
className="nav-link external-link"
|
||||
href={exch.href}
|
||||
target="_blank"
|
||||
>
|
||||
<span className="longform me-3">{i+1}</span>
|
||||
<img className="mw-100" id={exch.id} alt={exch.alt} />
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<p className="label-l mt-10 mb-0">
|
||||
{translate(
|
||||
"Disclaimer: This information is drawn from other sources on the internet. XRPL.org does not endorse or recommend any exchanges or make any representations with respect to exchanges or the purchase or sale of digital assets more generally. It’s advisable to conduct your own due diligence before relying on any third party or third-party technology, and providers may vary significantly in their compliance, data security, and privacy practices."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -25,14 +25,14 @@ The Ripple Consensus Ledger's multi-signing feature also allows signers to indep
|
||||
|
||||
1. Include the signer's address in your SignerList.
|
||||
2. Fund the signer's address in the ledger.
|
||||
3. [Assign a Regular Key Pair](/docs/tutorials/how-tos/manage-account-settings/assign-a-regular-key-pair) to the signer's address and disable its master key. (Funded addresses can only sign using their master key pair if it's not disabled.)
|
||||
3. [Assign a Regular Key Pair](/docs/tutorials/best-practices/key-management/assign-a-regular-key-pair.md) to the signer's address and disable its master key. (Funded addresses can only sign using their master key pair if it's not disabled.)
|
||||
4. Have that signer use its regular key pair to contribute to your multi-signatures.
|
||||
|
||||
|
||||
## Further Reading ##
|
||||
|
||||
- [Multi-Signing Summary](/docs/concepts/accounts/multi-signing)
|
||||
- [How to Multi-Sign](/docs/tutorials/how-tos/manage-account-settings/send-a-multi-signed-transaction)
|
||||
- [How to Multi-Sign](/docs/tutorials/best-practices/key-management/send-a-multi-signed-transaction.md)
|
||||
- [MultiSign Amendment](/resources/known-amendments.md#multisign)
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ markdown:
|
||||
|
||||
The multi-signing amendment is currently supported by the majority of voting validators on Ripple, and is scheduled to become active on the protocol on Monday, **2016-06-27**. For more information, please see the multi-signing documentation in the Ripple Developer Portal:
|
||||
|
||||
* [How to Multi-Sign](/docs/tutorials/how-tos/manage-account-settings/send-a-multi-signed-transaction)
|
||||
* [How to Multi-Sign](/docs/tutorials/best-practices/key-management/send-a-multi-signed-transaction.md)
|
||||
* [MultiSign Amendment Information](/resources/known-amendments.md#multisign)
|
||||
|
||||
To continue receiving updates about the `rippled` server, please subscribe to the Ripple Server Google Group:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user