Compare commits

...

377 Commits

Author SHA1 Message Date
Calvin
4c8025fa7d compressing images (#3642) 2026-05-14 13:19:16 -07:00
Calvin Jhunjhuwala
a565ceb59d Merge master into xrpl-brand-update-2026
Resolve all merge conflicts:
- package.json: keep Bootstrap 5 + modern build toolchain
- package-lock.json: accept branch version
- .gitignore: keep both sides (css.map + go/java ignores)
- .claude/settings.json, Navbar.tsx, events.page.tsx,
  community/index.page.tsx, xrp-faucets.page.tsx: resolved
- styles/xrpl.scss: keep shared component imports
- static/css/devportal2024-v1.css: regenerated from SCSS
- Fix undefined $blue-purple-600 → $blue-purple-500 in
  _tutorials.scss and light/_light-theme.scss
- styles/_feedback.scss: auto-merged

Co-Authored-By: Oz <oz-agent@warp.dev>
2026-05-14 10:12:16 -07:00
Calvin
f10dbc8c29 [feat] page composition (#3640)
* updating docs landing page, took far but not complete. Pushing for Gabe take over

* Refactor home page sections and introduce new components

- Replaced existing content in index.page.tsx with new section components for improved structure and maintainability.
- Added new sections: HomeBeginJourneySection, HomeBlockchainStatsSection, HomeComplianceDirectorySection, HomeDevelopersFeatureSection, HomeFutureFinanceCallout, HomeHeroCallout, HomeInstitutionsFeatureSection, HomePartnerLogosSection, HomeStayConnectedSection, and HomeCarousel.
- Updated styles for CarouselFeatured and CardStat components to enhance visual consistency and responsiveness.
- Introduced SCSS for HomeHero section to manage layout and spacing effectively.

* Add Payments Page and Sections

- Created a new Payments page with multiple sections including Hero, Why Choose, Advanced Features, Stablecoins, Embedded Payments, Partner Logos, Flexible Integration, Developer Spotlight, and Stay Connected.
- Each section is designed to highlight various aspects of the XRP Ledger Payments Infrastructure, featuring components like FeaturedVideoHero and CardsIconGrid.
- Added corresponding styles and images to enhance the visual presentation of the new sections.

* adding icons, updating docs landing page

* updating the claude command, wrapping text with translate wrapper

* use case tokenization page built

* Enhance CarouselFeatured styles for improved responsiveness

- Added flex-direction adjustments for CarouselFeatured component to support column-reverse layout on smaller screens and row layout on medium and larger screens.
- Removed redundant vendor prefixes from box-sizing and text-decoration properties in devportal2024-v1.css for cleaner code and improved maintainability.

* moving payments page to correct folder, moving payments under pages

* adding developers home page

* code clean up

---------

Co-authored-by: gabriel-ortiz <gabriel.ortiz.github@gmail.com>
Co-authored-by: gabriel-ortiz <gortiz@ripple.com>
2026-05-13 08:10:05 -07:00
Rome Reginelli
03dae02593 Merge pull request #3629 from tetherkim/docs-fix-redundant-credential-tx-descriptions
docs: remove redundant field description sentences from credential transactions
2026-05-05 09:58:27 -07:00
Maria Shodunke
b82df3bb5d Fix amm_info missing request fields (#3620) 2026-05-05 13:52:50 +01:00
tetherkim
9e1bc798ba docs: remove redundant field description sentences from credential transactions
Removed redundant sentences in CredentialAccept and CredentialDelete documentation that were already provided by the 'tx-fields-intro.md' snippet.
2026-05-03 23:07:17 +09:00
Amarantha Kulkarni
c8cb28fd80 Merge pull request #3526 from XRPLF/add-feedback-widget
Add feedback scale widget
2026-05-01 16:58:26 -07:00
amarantha-k
b09fe6c7b3 Update color for feedback boxes to fix white text on a white background in dark mode 2026-05-01 16:18:03 -07:00
mDuo13
28af114305 Fix article bottom border not appearing on preview build 2026-05-01 15:39:08 -07:00
mDuo13
d846367857 Update feedback styles 2026-05-01 15:37:40 -07:00
amarantha-k
8481e05d6e Add feedback scale widget 2026-05-01 15:32:39 -07:00
Rome Reginelli
b0428e30d4 Merge pull request #3626 from XRPLF/revise-transaction-types-landing-page
Revise transaction types landing page
2026-05-01 15:30:22 -07:00
mDuo13
4b65061304 Contrib: fix header hierarchy typo 2026-05-01 15:17:12 -07:00
mDuo13
6d99930c9a Re-gen CSS (rebase after #3622) 2026-05-01 15:13:39 -07:00
mDuo13
84f78d83dd Transaction Types landing: revisions per review 2026-05-01 15:13:06 -07:00
mDuo13
5311ffb3b4 Add contributor documentation for tx landing tags 2026-05-01 15:13:06 -07:00
mDuo13
4f991e14a5 Add tx icon legend component 2026-05-01 15:13:06 -07:00
mDuo13
da17bb427f [JA] fix frontmatter of AccountDelete 2026-05-01 15:13:06 -07:00
mDuo13
c10456f103 [JA] Revise tx type index to use automatic categories 2026-05-01 15:13:06 -07:00
mDuo13
a31124c94b Revise tx type index to use automatic categories 2026-05-01 15:13:06 -07:00
mDuo13
7f2588c514 [JA] Update tx type metadata for use on index page 2026-05-01 15:13:06 -07:00
mDuo13
bba796d818 Update transaction type metadata for use on index page 2026-05-01 15:13:06 -07:00
mDuo13
7d3145b0a1 Add styles for TxRefs components 2026-05-01 15:13:06 -07:00
mDuo13
a874b034d7 Reorg components & impl. TxRef component 2026-05-01 15:13:06 -07:00
rachelflynn
0defd68316 Revised transaction types landing page 2026-05-01 15:13:05 -07:00
Rome Reginelli
a439eef72b Merge pull request #3622 from XRPLF/improve-faucet
Improve faucet page
2026-05-01 15:12:08 -07:00
Rome Reginelli
e94068b0db Edit faucet request text
Co-authored-by: Amarantha Kulkarni <amarantha-k@users.noreply.github.com>
2026-05-01 13:54:03 -07:00
mDuo13
71e5ff4bdb Re-gen CSS (faucet w/ suggested changes) 2026-04-30 13:26:38 -07:00
Rome Reginelli
ccaaa55ca3 Faucet: apply suggested CSS changes
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2026-04-30 13:26:06 -07:00
oeggert
e2da8d58a0 Merge pull request #3618 from XRPLF/java-credentials
Add Java code samples for credentials
2026-04-30 10:58:16 -07:00
Rome Reginelli
e0cc0849ad Merge pull request #3619 from XRPLF/dependabot/pip/_code-samples/delete-account/py/python-dotenv-1.2.2
Bump python-dotenv from 1.2.1 to 1.2.2 in /_code-samples/delete-account/py
2026-04-29 16:53:28 -07:00
mDuo13
19b376be8e Improve XRP faucet w/ custom amount & address (squashed)
Faucet: improve handling of saved address, display of modes

Faucet improvements: suggestions from code review

Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2026-04-29 16:49:11 -07:00
Rome Reginelli
59a119db66 Merge pull request #3617 from XRPLF/rm_unused_code_samples
Remove some unused code samples, bump Redocly to 0.132.1, and related fixes
2026-04-29 16:43:50 -07:00
Oliver Eggert
2041b55e4b add reviewer suggestions 2026-04-29 15:45:29 -07:00
Oliver Eggert
d51da2ff5c fix tab styling in dark/light mode 2026-04-29 13:12:42 -07:00
mDuo13
19aad7809b Bump Redocly to Realm v0.132.1 and update xmldom to resolve security alerts 2026-04-28 13:23:42 -07:00
Oliver Eggert
508a39908c add manage credentials tutorial with java sample 2026-04-24 19:19:12 -07:00
oeggert
aca16f3609 Merge pull request #3625 from XRPLF/clarify-oracle-scale
Clarify AssetPrice and Scale interactions with new vs existing pairs
2026-04-24 12:06:15 -07:00
oeggert
187542fef5 Update docs/references/protocol/transactions/types/oracleset.md
Co-authored-by: Amarantha Kulkarni <amarantha-k@users.noreply.github.com>
2026-04-24 12:00:36 -07:00
oeggert
0972abb0b6 Merge pull request #3599 from XRPLF/ai-resources
Add AI Tools page
2026-04-24 11:40:10 -07:00
Amarantha Kulkarni
6256e1d7c8 Merge pull request #3606 from XRPLF/VODF-172
VODF-172 - Add Batch transaction integration considerations
2026-04-24 11:39:06 -07:00
oeggert
9f7c675517 Update resources/dev-tools/ai-tools.md
Co-authored-by: Amarantha Kulkarni <amarantha-k@users.noreply.github.com>
2026-04-24 11:39:04 -07:00
Maria Shodunke
202a16288c Address review comments 2026-04-24 15:37:46 +01:00
Oliver Eggert
8c68d4a7ad update readme file 2026-04-23 18:10:53 -07:00
Oliver Eggert
5e63775a97 clarify AssetPrice and Scale interactions with new vs existing pairs 2026-04-23 16:18:16 -07:00
rachelflynn
3e96de6323 Merge pull request #3586 from rachelflynn/fix-checks-js-code-samples
Fix JS code samples for checks tutorials and add set up scripts
2026-04-23 15:57:41 -04:00
Oliver Eggert
4e7d0aadc9 add requireSuccess helper and finalize script steps 2026-04-23 01:08:59 -07:00
Oliver Eggert
bbe80b34c9 update helpers for async and sequential error handling/calls 2026-04-22 18:43:44 -07:00
Oliver Eggert
3152430e47 improve error handling and output 2026-04-22 17:23:29 -07:00
Oliver Eggert
81279b4761 more helper cleanup 2026-04-22 16:27:07 -07:00
Oliver Eggert
aaa4668392 update helpers 2026-04-21 21:59:45 -07:00
dependabot[bot]
89de054d4d Bump python-dotenv in /_code-samples/delete-account/py
Bumps [python-dotenv](https://github.com/theskumar/python-dotenv) from 1.2.1 to 1.2.2.
- [Release notes](https://github.com/theskumar/python-dotenv/releases)
- [Changelog](https://github.com/theskumar/python-dotenv/blob/main/CHANGELOG.md)
- [Commits](https://github.com/theskumar/python-dotenv/compare/v1.2.1...v1.2.2)

---
updated-dependencies:
- dependency-name: python-dotenv
  dependency-version: 1.2.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-21 22:51:49 +00:00
Oliver Eggert
583b169680 update code sample to use up-to-date functions and code conventions 2026-04-18 13:53:00 -07:00
Oliver Eggert
1241a33a5d restructure for java conventions 2026-04-18 09:56:08 -07:00
Oliver Eggert
d0f6d04715 add logback.xml 2026-04-18 08:49:04 -07:00
Oliver Eggert
f8d7ca470d add java target folder to gitignore 2026-04-18 08:43:36 -07:00
Oliver Eggert
d0187414a5 initial code sample and file structure 2026-04-17 20:16:40 -07:00
mDuo13
aed88784d9 Fix sidebar highlight color issues in Realm 0.132 2026-04-17 16:03:55 -07:00
mDuo13
dc13312be6 Fix broken redirects identified by Realm 0.132 2026-04-17 16:03:35 -07:00
mDuo13
a063951f9e Bump Redocly to Realm 0.132.0 2026-04-17 15:57:51 -07:00
mDuo13
6ac6893f4a Remove some modular tutorial files that are no longer used 2026-04-17 15:41:38 -07:00
mDuo13
25bfaca2c0 Remove images & code from removed auction slot modular tutorial 2026-04-17 15:23:49 -07:00
mDuo13
5728345a42 Restore & update old auction slot tutorial 2026-04-17 15:19:50 -07:00
rachelflynn
f60393e9fa Addressed PR review feedback 2026-04-17 17:14:40 -04:00
mDuo13
028e523b6d Remove unused Airgapped Wallet code sample 2026-04-17 13:57:52 -07:00
Maria Shodunke
d945d6a5d6 Tutorials landing page v2 (#3572) 2026-04-17 11:52:23 +01:00
oeggert
fed058fe51 Merge pull request #3574 from XRPLF/release-notes-skill
Claude Code Release Notes Skill
2026-04-16 14:44:49 -07:00
Rome Reginelli
c3e898c047 Merge pull request #3555 from XRPLF/dependabot/pip/_code-samples/build-a-desktop-wallet/py/requests-2.33.0
Bump requests from 2.32.4 to 2.33.0 in /_code-samples/build-a-desktop-wallet/py
2026-04-15 17:26:04 -07:00
Rome Reginelli
98db42f996 Merge pull request #3504 from zgrguric/patch-8
LoanBroker LedgerEntry - Change DebtMaximum field from required to optional
2026-04-15 14:41:37 -07:00
Rome Reginelli
3f551f68e3 Merge pull request #3535 from XRPLF/dependabot/go_modules/_code-samples/assign-regular-key/go/golang.org/x/crypto-0.45.0
Bump golang.org/x/crypto from 0.35.0 to 0.45.0 in /_code-samples/assign-regular-key/go
2026-04-15 14:21:06 -07:00
mDuo13
4c5f65ff54 Add README for Assign Regular Key (Go) 2026-04-15 14:20:26 -07:00
gabriel-ortiz
8d65b8e751 Merge pull request #3604 from XRPLF/go/chore/featureTwoColumnPatternQA
Update FeatureTwoColumn component and related styles
2026-04-15 13:53:46 -07:00
gabriel-ortiz
339bd84540 Enhance styling for LinkTextCard and SectionHeader components
- Added dark mode support for paragraph text in LinkTextCard.
- Introduced responsive margin adjustments for button groups in SectionHeader.
- Updated FeatureSingleTopic styles to include proper heading and description classes for consistency.
2026-04-15 13:52:36 -07:00
Calvin
25760d1ef8 minor refactoring, adding font class on text class (#3608) 2026-04-15 08:13:35 -07:00
gabriel-ortiz
c714657c62 Remove aspect-ratio property from FeatureTwoColumn styles for improved layout consistency 2026-04-14 14:03:59 -07:00
Maria Shodunke
9b72e6c6ff VODF-172 - Add Batch transaction integration considerations 2026-04-14 12:40:11 +01:00
gabriel-ortiz
5e19f0e01c Refactor CSS styles for improved consistency and layout
- Removed redundant vendor prefixes from box-sizing and text-decoration properties.
- Adjusted line-height for the legend element to ensure proper spacing.
- Updated display classes to maintain consistent styling across breakpoints.
- Cleaned up unused CSS rules to enhance maintainability.
2026-04-13 14:40:18 -07:00
Calvin
3c86f7ac29 Qa/grids and text directory (#3605)
* qa fixes for 3 sections

* removing unnecessary class
2026-04-13 14:18:57 -07:00
gabriel-ortiz
7d2ea6110e Update FeatureTwoColumn component and related styles
- Downgraded Bootstrap version from 5.3.8 to 5.3.3 in package-lock.json.
- Refactored import paths in plugin files to use local types.
- Enhanced FeatureTwoColumn component with improved layout and responsive behavior.
- Updated SCSS for consistent spacing and layout adjustments across breakpoints.
- Revised documentation in FeatureTwoColumn.md for clarity on layout behavior and props.
2026-04-13 13:49:01 -07:00
Oliver Eggert
5e500d58ca add release notes section to contribute blog page 2026-04-10 21:32:37 -07:00
Oliver Eggert
cb48d4f789 add optional --output arg to skill file 2026-04-10 21:31:16 -07:00
Calvin
b7db009786 Qa/section cards (#3596)
* qa/section-cards: link colors, dark mode green TextCard, CardTextIconCard text color

Co-Authored-By: Oz <oz-agent@warp.dev>

* updating documentation, fix per QA feedback

* removing important and css clean up

---------

Co-authored-by: Oz <oz-agent@warp.dev>
2026-04-10 16:33:25 -07:00
Oliver Eggert
39f5b9ab66 fix spelling, grammar, and formatting 2026-04-10 16:04:06 -07:00
gabriel-ortiz
97bb0f13c9 Merge pull request #3598 from XRPLF/go/chore/HeaderHeroPrimaryMediaQA
Update ButtonGroup styles and props for improved spacing options
2026-04-10 15:34:56 -07:00
gabriel-ortiz
74e6d20ec5 Update ButtonGroup styles and props for improved spacing options
- Adjusted the gap for the small variant from 8px to 4px.
- Introduced a new medium gap variant with responsive settings (16px on mobile/tablet, 24px on desktop).
- Updated ButtonGroupProps interface to include the new medium gap option.
- Modified HeaderHeroPrimaryMedia to utilize the new medium gap setting for button groups.
2026-04-10 13:55:08 -07:00
Oliver Eggert
3d3ac6adb3 second iteration 2026-04-09 16:52:21 -07:00
gabriel-ortiz
06de729eba Merge pull request #3595 from XRPLF/go/chore/featureCarouselQA
Enhance CarouselFeatured styles for improved layout and spacing
2026-04-09 16:43:44 -07:00
gabriel-ortiz
3f1d5a148e Merge branch 'xrpl-brand-update-2026' into go/chore/featureCarouselQA 2026-04-09 16:39:08 -07:00
gabriel-ortiz
8498fef70e Enhance CarouselFeatured styles for improved layout and spacing
- Added responsive gap settings for grid rows in CarouselFeatured.
- Standardized margin and padding for the CarouselFeatured component.
- Updated SCSS and CSS files to reflect these changes for better visual consistency.
2026-04-09 16:33:28 -07:00
Calvin
f9d84f916d Fix to TileLogo and fix to svg for external link (#3594)
* fixes for link arrow and tile logo

* ran prod build, seeing css changes

* fixing css
2026-04-09 15:46:44 -07:00
gabriel-ortiz
3ff8607cc5 Merge pull request #3590 from XRPLF/go/chore/mediaCalloutHero
Update CalloutMediaBanner styles and improve CSS variables for dark mode
2026-04-09 13:46:36 -07:00
Oliver Eggert
539cef2510 initial draft 2026-04-09 10:25:00 -07:00
rachelflynn
0da70afdff Added set up scripts for updated code samples 2026-04-09 11:24:15 -04:00
gabriel-ortiz
4e3a6f322b Update CalloutMediaBanner styles and improve CSS variables for dark mode
- Adjusted background and text colors for various variants in CalloutMediaBanner.
- Updated SCSS variables for improved color consistency across dark mode.
- Cleaned up and standardized CSS formatting for better readability.
2026-04-08 16:24:44 -07:00
Calvin
2a3746eb07 dark mode for the grid (#3565) 2026-04-07 18:49:59 -07:00
rachelflynn
513c86dff3 Fix JS code samples for Use Checks tutorials: update to ES modules, fix syntax highlighting and indentation rendering, and improve code consistency 2026-04-07 16:47:25 -04:00
gabriel-ortiz
35571903e0 Merge pull request #3582 from XRPLF/go/qa/standardCardGroupSection
Enhance StandardCard styles for dark mode and clean up showcase component
2026-04-06 18:04:33 -07:00
gabriel-ortiz
a89fcbb275 Enhance StandardCard styles for dark mode and clean up showcase component
- Added dark mode background color for the StandardCard component.
- Removed unnecessary padding and border radius from the showcase StandardCard group section for a cleaner look.
- Updated CSS files with new styles and optimizations.
2026-04-06 16:44:33 -07:00
Oliver Eggert
b0e99161bb clean up claude code files 2026-04-01 16:38:17 -07:00
Oliver Eggert
a441171000 improve amendment sorting logic, frontmatter and intro descriptions, and bug disclosure text 2026-04-01 15:14:22 -07:00
Oliver Eggert
892714550e more improvements to sorting script and AI instructions 2026-04-01 13:19:12 -07:00
Oliver Eggert
b6388ccb13 improve skills md edit vs write and not chunk context 2026-03-31 18:18:01 -07:00
Oliver Eggert
6ab5de13bb fix bug when passing different date and output years in args 2026-03-28 00:18:10 -07:00
Oliver Eggert
38000f19d6 fix sidebars.yaml entry logic 2026-03-27 23:35:06 -07:00
Oliver Eggert
ad9e5e14fa improve skill.md to prevent losing content 2026-03-27 22:20:46 -07:00
Oliver Eggert
663cd6df6a add skills.md and writing release notes to sidebars.yaml 2026-03-27 21:45:34 -07:00
Oliver Eggert
6bee1983eb append fix to fix amendment names 2026-03-27 20:37:40 -07:00
Oliver Eggert
9df53455e9 add amendment diff fetching for additional sorting context 2026-03-27 20:09:36 -07:00
Oliver Eggert
13dddb8b22 add basic amendment sorting 2026-03-27 12:11:39 -07:00
Oliver Eggert
b47c96d91a update logic for generating entries on commit-only entries and entries with broken PR/Issue links 2026-03-27 11:48:04 -07:00
Oliver Eggert
93abc4dc09 remove sys exit for failed file lookups, and minor cleanup to comments and section header location 2026-03-26 18:30:14 -07:00
Oliver Eggert
ae266aba7f add files for entry context. include commits linked to issues and commits without any links 2026-03-26 18:08:18 -07:00
Oliver Eggert
ab9eec63f5 merge version fetching functions and clean up credits intro 2026-03-26 15:10:46 -07:00
Oliver Eggert
8b8ed4c6ea fix fetch_version_commit to only check buildinfo.cpp 2026-03-26 14:48:30 -07:00
Oliver Eggert
6aaca7f568 ignore ripple users in credits and improve graphql handling of issues vs pulls 2026-03-26 14:07:40 -07:00
Calvin
0dcab2ccd1 QA: Link Component
clean up css, lilac properly documented for links (#3564)
2026-03-26 13:30:11 -07:00
Calvin
10b3b7f081 QA: Typography 2026-03-26 13:21:45 -07:00
Calvin
79e7cee695 QA: Buttons (#3562)
* fixed to the button for light + dark, all three buttons

* empty commit

Co-Authored-By: Oz <oz-agent@warp.dev>

* testing link to qa branch

* fix spacing

* minifying css

---------

Co-authored-by: Oz <oz-agent@warp.dev>
2026-03-26 13:15:14 -07:00
Calvin
8eb5173ebc focus state fixed, updated documentation, typography + focus state fixed (#3561) 2026-03-26 11:32:47 -07:00
Calvin
2acc7c4213 QA for TileLogo Component (#3560)
* qa feedback implemented

* style clean up
2026-03-26 11:19:28 -07:00
Calvin
e7904a0f0f tilelink working, fixed all QA items (#3559) 2026-03-26 10:50:17 -07:00
Oliver Eggert
a045e9e40c clean up functions 2026-03-25 22:22:40 -07:00
Calvin
68f10b41ad QA/CardIcon (#3558)
* fixing light + dark mode for card icon

* fix pressed on dark mode for gray
2026-03-25 16:33:48 -07:00
Oliver Eggert
ad9327c4c0 add comments and improve ordering of helpers 2026-03-25 15:05:35 -07:00
Oliver Eggert
53983bf8e2 update to use graphql and remove categorization logic 2026-03-25 14:47:00 -07:00
dependabot[bot]
aa3b5e173c Bump requests in /_code-samples/build-a-desktop-wallet/py
Bumps [requests](https://github.com/psf/requests) from 2.32.4 to 2.33.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.32.4...v2.33.0)

---
updated-dependencies:
- dependency-name: requests
  dependency-version: 2.33.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-25 17:18:04 +00:00
Oliver Eggert
4bceb09b1b initial draft of release notes script 2026-03-24 19:06:53 -07:00
Oliver Eggert
0da3a1e13c scaffold claude specific tools and generic agents.md 2026-03-24 12:17:26 -07:00
Calvin
3e6dd8687d Navbar icon updates: new 18×18 icons, dedicated Community icons, and code cleanup (#3544)
* updating navigation with the correct icons

* clean up code, add alt tags

* consolidate, code clean up

* minor tweak to icons.ts
2026-03-18 17:12:03 -07:00
dependabot[bot]
5d2e8f5f98 Bump golang.org/x/crypto in /_code-samples/assign-regular-key/go
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.35.0 to 0.45.0.
- [Commits](https://github.com/golang/crypto/compare/v0.35.0...v0.45.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.45.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 04:43:40 +00:00
Calvin Jhunjhuwala
84109910b2 merged master 2026-02-23 15:11:26 -08:00
Calvin Jhunjhuwala
8f0db49832 Merge origin/master into xrpl-brand-update-2026
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-23 15:09:03 -08:00
Calvin
32e89c1299 Component Library Refactor & New Components (#3510)
* adding showcase page

* adding CardStatsList

* clean up, tighter code

* code review and code clean up

* update import, clean up env for error message

* tweak some css code

* less css, rebuilt

* re-adding bem, modifier for bds variants
2026-02-23 15:00:18 -08:00
Calvin
a97a009d93 Add CardsIconGrid and CardsTextGrid Section Patterns (#3505)
* CardsIconGrid and CardsTextGrid + showcase pages

* cleaning up code

* more code clean up

* using the spacing tokens for values
2026-02-18 16:19:01 -08:00
zgrguric
d4726e0816 Change DebtMaximum field from required to optional 2026-02-18 15:17:57 +01:00
Aria Keshmiri
df074e625b Merge pull request #3488 from XRPLF/feature/optimize
Feature/optimize
2026-02-17 14:30:46 -08:00
Calvin
a4b1925b31 [feat] Add LinkTextCard and LinkTextDirectory Components (#3501)
* adding linktextcard + linktextdirectory

* adding dark mode

* code review clean up

* code review comments
2026-02-17 12:21:10 -08:00
akcodez
26d1cf102c test 2026-02-13 10:50:27 -08:00
akcodez
a41a9e31cc fix optimization 2026-02-10 10:54:28 -08:00
akcodez
159ac52acc stashing work 2026-02-10 10:36:41 -08:00
Calvin
c7e01d322a Merge pull request #3485 from XRPLF/pattern/tile-link
Add TileLink Component and LinkSmallGrid Pattern
2026-02-09 15:03:21 -08:00
Calvin Jhunjhuwala
17582d543d updating comments in scss file 2026-02-09 14:58:48 -08:00
Calvin Jhunjhuwala
986ca23ff7 removing import for break points 2026-02-09 14:54:44 -08:00
Calvin Jhunjhuwala
acb2476d7d tweaks to pattern and section 2026-02-07 10:55:48 -08:00
Calvin Jhunjhuwala
f5c38ffe77 cleaning up key 2026-02-06 23:51:37 -08:00
Calvin Jhunjhuwala
ee6a32d159 adding TileLinks pattern, adding LinkSmallGrid 2026-02-06 23:37:57 -08:00
Calvin
e1d18bd621 Merge pull request #3480 from XRPLF/section/feature-single-topic
Add FeatureSingleTopic pattern component with associated styles
2026-02-05 09:59:59 -08:00
Calvin Jhunjhuwala
a85dc47781 fix button utils, remove separate file, enhance within main BUttonGroup file 2026-02-05 09:48:40 -08:00
Calvin Jhunjhuwala
eecd14d763 adding button group utils for validation, cleaning up styling for FeatureSingleTopic 2026-02-04 16:20:03 -08:00
Calvin Jhunjhuwala
42282a2012 Merge branch 'xrpl-brand-update-2026' of github.com:XRPLF/xrpl-dev-portal into section/feature-single-topic 2026-02-04 14:57:33 -08:00
akcodez
6442318205 Enhance FeatureSingleTopic component with button variant support and responsive behavior updates
- Updated the FeatureSingleTopic component to allow configurable button variants (primary or secondary) based on the `singleButtonVariant` prop.
- Improved mobile and tablet responsiveness by ensuring content always appears above the image, regardless of orientation.
- Refined button rendering logic for better clarity in the README and component documentation.
- Adjusted SCSS styles for improved spacing and alignment across different screen sizes.
2026-02-04 11:29:56 -08:00
Calvin
1ee76bfbea Merge pull request #3482 from XRPLF/quick-fix-020426
fix back to html.light, will consolidate later
2026-02-04 11:24:33 -08:00
Calvin Jhunjhuwala
d558b7474d fix back to html.light, will consolidate later 2026-02-04 11:22:59 -08:00
Calvin
da49b0a154 Merge pull request #3477 from XRPLF/section/carousel-feature-image
Add CarouselButton component and integrate into CarouselCardList and …
2026-02-04 11:19:14 -08:00
Calvin Jhunjhuwala
01931bd177 stylesheet clean up 2026-02-04 11:14:42 -08:00
Calvin Jhunjhuwala
c2ef761b01 cleaning up the files, removing dead css, leveraging the grid more 2026-02-03 16:26:47 -08:00
akcodez
d6ce246420 Add FeatureSingleTopic pattern component with associated styles
- Introduced the FeatureSingleTopic component, enhancing layout flexibility with responsive design.
- Added SCSS styles for various screen sizes, including media queries for improved spacing and alignment.
- Implemented dark mode styles for better accessibility and visual consistency.
2026-02-03 13:29:24 -08:00
akcodez
33c6315510 Refactor CarouselCardList and CarouselFeatured to streamline button rendering logic using a map function for navigation buttons, enhancing code maintainability and consistency across components. 2026-02-03 10:40:08 -08:00
akcodez
af0b8cd40a Refactor CarouselFeatured to use ButtonGroup for button management, simplifying button rendering logic and improving code maintainability. 2026-02-03 10:38:45 -08:00
akcodez
95c4ffaa1b merge buttongroup in 2026-02-03 10:29:25 -08:00
Calvin
08c5572f16 Merge pull request #3475 from XRPLF/go/feat/FeaturedVideoSection
Add FeaturedVideoHero pattern component with showcase and styles
2026-02-03 10:25:12 -08:00
Calvin Jhunjhuwala
b49bc02dd2 fixing button and button groups for feature 2 column 2026-02-02 17:03:04 -08:00
Calvin Jhunjhuwala
65a61c5e47 fixing spacing and alignments 2026-02-02 16:20:50 -08:00
Calvin Jhunjhuwala
237ddc3c74 cleaning up styles, aligning text to bottom for section 2026-02-02 15:57:20 -08:00
Calvin
dd6cfd34fe Merge pull request #3474 from XRPLF/pattern/button-group
Add ButtonGroup pattern component
2026-02-02 14:30:26 -08:00
akcodez
607f8bdf07 Add CarouselButton component and integrate into CarouselCardList and CarouselFeatured showcases
- Introduced CarouselButton component for navigation with multiple color variants (neutral, green, black).
- Enhanced CarouselCardListShowcase to include a visual showcase of CarouselButton in various states.
- Created CarouselFeatured component showcasing featured images with navigation and responsive behavior.
- Updated styles for CarouselButton and integrated it into existing patterns for improved navigation experience.
2026-02-02 13:56:00 -08:00
Calvin Jhunjhuwala
7b601da3a0 updating to add more warnings/dev feedback 2026-02-02 13:20:12 -08:00
Aria Keshmiri
dc85b8c241 Merge pull request #3472 from XRPLF/navbar/updates
Update navigation constants and submenu data for improved routing
2026-02-02 08:59:34 -08:00
akcodez
0a25b1b9c0 hide scroll on open mobile menu 2026-02-02 08:59:13 -08:00
gabriel-ortiz
6021b458e6 Add FeaturedVideoHero pattern component with showcase and styles
- Introduced the FeaturedVideoHero component featuring a responsive layout with a headline, optional subtitle, call-to-action buttons, and a video element.
- Added associated SCSS styles for the component to ensure proper spacing and theming.
- Created a showcase page to demonstrate the usage of the FeaturedVideoHero pattern.
- Updated types to include design constraints for buttons and video elements.
- Implemented validation for required props to enhance development experience.
2026-01-30 13:47:38 -08:00
Calvin Jhunjhuwala
e5f3bf75e3 minor add for maxnumber 2026-01-30 10:30:53 -08:00
Calvin Jhunjhuwala
7dd32d63da working button group, updated examples 2026-01-29 16:50:32 -08:00
akcodez
7376dce9ef Update navigation constants and submenu data for improved routing
- Changed hrefs for main navigation items to reflect new paths.
- Updated submenu data for 'Develop' and 'Use Cases' sections with new links.
- Adjusted community submenu links for better resource access.
- Refined network submenu data to include relevant resources and insights.
2026-01-29 10:21:57 -08:00
Aria Keshmiri
ce9012f26f Merge pull request #3465 from XRPLF/section/cards-two-column
Add CardsTwoColumn pattern styles and integrate into XRPL styles
2026-01-29 09:51:13 -08:00
akcodez
9042a60b28 Refactor TextCard component structure and styles
- Removed unnecessary wrapper elements for header and footer in TextCard, simplifying the markup.
- Updated class names in SCSS for better clarity and consistency.
- Enhanced CardsTwoColumnProps documentation to specify that description and secondaryDescription can be either string or ReactNode.
- Cleaned up CSS by removing redundant vendor prefixes for better maintainability.
2026-01-29 09:50:59 -08:00
akcodez
9ff586b172 merge main branch in 2026-01-29 09:46:07 -08:00
Aria Keshmiri
a082d9030c Merge pull request #3457 from XRPLF/section/card-stats
Add Section Card Stat + slight optimizations to card stat component
2026-01-28 15:02:03 -08:00
akcodez
9814a24dcf merge 2026-01-28 15:01:49 -08:00
Aria Keshmiri
05c36beae2 Merge pull request #3454 from XRPLF/section/carousel-card-list
Add CarouselCardList pattern component and showcase
2026-01-28 15:00:03 -08:00
akcodez
41e01b51bd Refactor CarouselCardList component to improve code clarity and maintainability
- Introduced a constant for the BEM class name to enhance readability.
- Updated buttonVariant prop type to derive from ButtonProps for consistency.
- Replaced hardcoded class name with the new constant in the component's render method.
2026-01-28 14:59:46 -08:00
akcodez
4c2b2d487c merg 2026-01-28 14:58:33 -08:00
gabriel-ortiz
dec76b1f71 Merge pull request #3467 from XRPLF/go/feat/cardStandardSection
Add StandardCardGroupSection pattern component and related styles
2026-01-28 14:53:41 -08:00
gabriel-ortiz
b26b185c04 Merge branch 'xrpl-brand-update-2026' into go/feat/cardStandardSection 2026-01-28 14:52:55 -08:00
akcodez
fb7707c6b6 Update TextCard and CardsTwoColumn documentation to reflect new features 2026-01-28 14:48:51 -08:00
akcodez
ee80283265 Add disabled state to TextCard component and update showcase
- Implemented a disabled state for the TextCard component, enhancing accessibility and user experience.
- Updated the CardsTwoColumnShowcase to include examples of disabled TextCards in both light and dark modes.
- Refined styles for the disabled state to ensure visual clarity and consistency across themes.
- Enhanced documentation to reflect the new disabled functionality in the TextCard component.
2026-01-28 14:39:53 -08:00
gabriel-ortiz
a3119f9fc0 Fix typo in DesignContrainedButtonProps to DesignConstrainedButtonProps across multiple components and utility files for consistency. 2026-01-28 14:36:46 -08:00
akcodez
5c87e7e1cb Enhance TextCard component and update CardsTwoColumn pattern
- Introduced the TextCard component with 6 color variants and interactive states, including hover and pressed effects.
- Updated CardsTwoColumn pattern to utilize the new TextCard component, showcasing all 6 color variants in a responsive layout.
- Improved documentation for both TextCard and CardsTwoColumn, detailing usage, props, and responsive behavior.
- Refactored styles to ensure consistency and maintainability across components.
2026-01-28 13:53:03 -08:00
Calvin
9084d37db3 Merge pull request #3468 from XRPLF/qa-card-stats-section
CardStats Component Refactoring and Grid Integration
2026-01-28 12:43:04 -08:00
Calvin
bf7bd6fbd7 Merge pull request #3460 from XRPLF/pattern/logo-rectangle-grid
Pattern/logo rectangle grid
2026-01-28 09:22:37 -08:00
Calvin Jhunjhuwala
50df631f8a merging master 2026-01-27 21:54:28 -08:00
Calvin Jhunjhuwala
0d779b4d47 code clean up, ready for additional review 2026-01-27 21:50:04 -08:00
Calvin Jhunjhuwala
071e940e6b merging main branch 2026-01-27 18:06:41 -08:00
Calvin Jhunjhuwala
9fe2a7377f cleaning up code, consolidating and attaching the CardStat to the grid, less css 2026-01-27 17:09:59 -08:00
gabriel-ortiz
e40ea50259 Update error handling and clean up imports in StandardCardGroupSection and helpers
- Changed console warning to error for better visibility when no cards are provided in StandardCardGroupSection.
- Simplified imports in helpers by removing unused React types to enhance code clarity.
2026-01-27 14:36:05 -08:00
gabriel-ortiz
41e3e82984 Refactor StandardCard component and utility functions
- Replaced the hasChildren utility function with isEmpty for better clarity in child element checks.
- Updated SCSS styles for the StandardCard buttons to maintain consistent alignment and spacing across breakpoints.
- Removed the deprecated hasChildren function from the helpers module to streamline utility functions.
2026-01-27 14:14:37 -08:00
gabriel-ortiz
1ba6c9753d Add StandardCardGroupSection pattern component and related styles
- Introduced the StandardCardGroupSection component, which displays a headline, description, and a responsive grid of StandardCard components.
- Implemented SCSS styles for the StandardCardGroupSection, ensuring consistent spacing and dark mode support.
- Added utility functions for key generation and environment checks to enhance component functionality.
- Created a README file detailing usage, props, and best practices for the StandardCardGroupSection.
- Included new StandardCard component with customizable variants and button handling.
2026-01-27 14:05:48 -08:00
gabriel-ortiz
0fe57025c6 Merge pull request #3462 from XRPLF/go/primaryHeaderTertiaryHotfix
Update padding for CTA buttons in HeaderHeroPrimaryMedia component
2026-01-26 13:21:50 -08:00
akcodez
e43ce195a4 rm dead code 2026-01-26 13:16:09 -08:00
akcodez
c192ccec70 Add CardsTwoColumn pattern styles and integrate into XRPL styles
- Introduced new styles for the CardsTwoColumn pattern, including responsive layouts and various card designs.
- Updated the xrpl.scss file to import the new CardsTwoColumn styles, ensuring they are included in the overall styling framework.
2026-01-26 13:14:52 -08:00
gabriel-ortiz
8a2ff6e69f Update padding for CTA buttons in HeaderHeroPrimaryMedia component
- Added !important to padding for hover and focus states of tertiary buttons to ensure consistent styling across interactions.
2026-01-22 18:08:30 -08:00
gabriel-ortiz
6bce7efae0 Merge pull request #3450 from XRPLF/go/xrpl-brand-update/PrimaryHero
Add HeaderHeroPrimaryMedia component and styles
2026-01-22 14:15:03 -08:00
Calvin Jhunjhuwala
df1ab88ef7 cleaning up duplicate, cleaning up button group, useMemo for rectangle grid 2026-01-21 18:41:19 -08:00
Calvin Jhunjhuwala
8f931a2a4c working ofset for large and medium 2026-01-21 17:06:57 -08:00
Calvin Jhunjhuwala
be46c362cf merging master 2026-01-21 16:02:20 -08:00
Calvin
99d3442bef Merge pull request #3451 from XRPLF/pattern/logo-square-grid
Pattern/Logo Square Grid
2026-01-21 15:51:58 -08:00
Calvin Jhunjhuwala
e66a877868 merging master 2026-01-21 15:20:22 -08:00
Calvin Jhunjhuwala
b9410305ef merging master, fixing merge conflicts 2026-01-21 15:19:30 -08:00
akcodez
d5e7fceb21 add forceCOlor 2026-01-21 12:31:36 -08:00
akcodez
7be7ad4806 Merge remote-tracking branch 'origin' into section/card-stats 2026-01-21 12:29:19 -08:00
Aria Keshmiri
7498f9820c Merge pull request #3446 from XRPLF/pattern/feature-two-column
Pattern/feature two column
2026-01-21 12:29:04 -08:00
Calvin Jhunjhuwala
9d4ed9a477 updates to logo rectangle, need to work on the offsetting 2026-01-21 11:46:18 -08:00
akcodez
7a6aab6493 design changes 2026-01-21 11:20:09 -08:00
akcodez
a992f0ddf3 Refactor CardStat component buttons and add CardStats styles
- Simplified button rendering in CardStat component by consolidating href and onClick handling.
- Introduced new styles for CardStats, including responsive design for various screen sizes and dark mode support.
- Updated SCSS imports to include CardStats styles.
2026-01-21 10:27:17 -08:00
akcodez
87c3c6ef19 fix 2026-01-21 09:58:17 -08:00
akcodez
8c5f6f79c1 update 2026-01-21 09:56:23 -08:00
akcodez
a6fde81c36 Refactor FeatureTwoColumn styles and improve button key handling
- Centralized background color variants for light and dark modes using a map structure in SCSS.
- Updated the button rendering logic to use a unique key based on link properties, enhancing performance and preventing potential key collisions.
- Improved code readability and maintainability by reducing redundancy in background color definitions.
2026-01-21 09:55:53 -08:00
gabriel-ortiz
b085502a4d Refactor HeaderHeroPrimaryMedia styles and component structure
- Updated SCSS styles for improved layout and responsiveness, including adjustments to padding and margin for various breakpoints.
- Enhanced the HeaderHeroPrimaryMedia component by refining the media rendering logic and updating prop types for better type safety.
- Changed subtitle class from 'label-l' to 'body-l' for consistent styling.
- Ensured proper handling of empty values in the isEmpty utility function.
2026-01-20 19:54:31 -08:00
Calvin Jhunjhuwala
4da20f1ac1 correct layout, working on right align next 2026-01-20 17:50:08 -08:00
akcodez
ef200ee737 Add CarouselCardList pattern component and showcase
- Introduced the CarouselCardList component for a horizontal scrolling card carousel with navigation buttons.
- Implemented responsive design for mobile, tablet, and desktop views.
- Added SCSS styles for light and dark mode support.
- Created a dedicated showcase page demonstrating the CarouselCardList features and usage examples.
- Included comprehensive documentation for props and variants.
2026-01-20 12:41:58 -08:00
Aria Keshmiri
9b05da7131 Merge pull request #3448 from XRPLF/pattern/cards-featured
Add CardsFeatured pattern component and styles
2026-01-20 10:12:57 -08:00
Calvin Jhunjhuwala
f7c80a5c04 fixing size on tablet for text 2026-01-19 15:49:22 -08:00
Calvin Jhunjhuwala
1e61c71c94 logo square grid ready for review 2026-01-17 17:52:46 -08:00
gabriel-ortiz
bf88924d3d Add HeaderHeroPrimaryMedia component and styles
- Introduced HeaderHeroPrimaryMedia component for a responsive hero section featuring a headline, subtitle, call-to-action buttons, and media elements (images, videos, or custom React components).
- Implemented associated SCSS styles to ensure proper layout and design constraints, including aspect ratios and object-fit properties.
- Added README documentation detailing usage, props, and best practices for the component.
- Included validation for required props with console warnings for missing fields.
2026-01-16 17:47:10 -08:00
akcodez
daa8b7d292 add markdoc 2026-01-15 12:08:09 -08:00
akcodez
3873ae0085 design QA and changes with Design team 2026-01-15 11:23:24 -08:00
akcodez
f630796da0 53 ---> 52 2026-01-15 10:34:41 -08:00
akcodez
eac1859507 changes with design review 2026-01-15 10:31:35 -08:00
akcodez
2d75a0a727 Add CardsFeatured pattern component and styles
- Introduced the CardsFeatured component to showcase a grid of card images with headings and descriptions.
- Implemented responsive design for mobile, tablet, and desktop views.
- Added SCSS styles for light and dark mode support.
- Created a dedicated page for the CardsFeatured pattern showcase, including design specifications and examples.
2026-01-15 09:44:08 -08:00
akcodez
f62c99b387 fix tablet 2026-01-14 14:07:59 -08:00
akcodez
7383bf8044 add back bundle 2026-01-14 14:05:49 -08:00
akcodez
e12b1bf8dc complete pattern and showcase 2026-01-14 14:04:58 -08:00
akcodez
0b52e5f747 Add FeatureTwoColumn pattern and button enhancements
- Introduced the FeatureTwoColumn pattern for showcasing features in a two-column layout, supporting multiple color themes and responsive design.
- Implemented button behavior based on the number of links, with configurations for 1 to 5 links.
- Added `forceColor` prop to Button component to maintain button color across light and dark themes, particularly useful for colored backgrounds.
- Updated styles and documentation for both the FeatureTwoColumn pattern and Button component to reflect new features and usage guidelines.
2026-01-14 14:04:17 -08:00
akcodez
161e4305e6 add bun lock as build container is using bun 2026-01-14 10:30:58 -08:00
akcodez
8e7d7ecba1 resolve build erros 2026-01-14 10:27:07 -08:00
Aria Keshmiri
32f6a1de2d Merge pull request #3436 from XRPLF/go/feat/pattern/smallTiles
[feat][site] - Add SmallTilesSection component and styles
2026-01-14 10:22:42 -08:00
akcodez
e3459b336e merge main branch in rebundle css 2026-01-14 10:21:36 -08:00
Aria Keshmiri
1a1e1b30a6 Merge pull request #3445 from XRPLF/brand/merge-master-in
Brand/merge master in
2026-01-14 10:19:02 -08:00
akcodez
5eb98cacac merge master in, resolve conflicts 2026-01-14 10:06:48 -08:00
gabriel-ortiz
9a7f9479d4 Merge branch 'xrpl-brand-update-2026' into go/feat/pattern/smallTiles 2026-01-13 16:12:21 -08:00
Aria Keshmiri
c21785855f Merge pull request #3443 from XRPLF/brand-update-header
Brand update header
2026-01-13 13:19:10 -08:00
akcodez
887e1f38f5 Enhance Navbar and Submenu components for improved accessibility and keyboard navigation
- Added keyboard navigation support to NavItems, allowing users to close submenus with the Escape key and toggle with Enter/Space.
- Implemented onClose callback in Submenu components to facilitate submenu closure.
- Updated Navbar to handle submenu closing for keyboard navigation.
- Adjusted styles for better layout and responsiveness in submenus.
2026-01-13 12:30:51 -08:00
Aria Keshmiri
79294acb05 Merge pull request #3434 from XRPLF/pattern/header-hero-split-media
Pattern/header hero split media
2026-01-13 12:13:30 -08:00
akcodez
5cb06eaf86 merge xrpl branch in, resolve comments 2026-01-13 12:11:34 -08:00
Calvin Jhunjhuwala
fe0057aa9f css clean up 2026-01-13 12:07:29 -08:00
Calvin Jhunjhuwala
1e3ca30ace fixing per comments 2026-01-13 12:07:29 -08:00
Calvin Jhunjhuwala
66356984b4 added light image variant for example page 2026-01-13 12:07:29 -08:00
Calvin Jhunjhuwala
1fcc294ffb fixing button spacing + image background 2026-01-13 12:07:29 -08:00
Calvin Jhunjhuwala
0d0fc38344 cleaning up css 2026-01-13 12:07:28 -08:00
Calvin Jhunjhuwala
cd1759332d fixing errors 2026-01-13 12:07:28 -08:00
Calvin Jhunjhuwala
62d23ce36b updated and working showcase for call out media 2026-01-13 12:07:28 -08:00
Calvin Jhunjhuwala
678e168029 adding a README 2026-01-13 12:07:28 -08:00
akcodez
31a9cac20b merge main in, resolve comments 2026-01-13 12:06:52 -08:00
akcodez
79f40fb2c6 fix card 2026-01-13 12:05:49 -08:00
akcodez
9738402921 Focus should not activate button hover - cardimage 2026-01-13 12:05:49 -08:00
akcodez
e064ce02d0 Card - image : hovering card should not activate button hover state 2026-01-13 12:05:49 -08:00
akcodez
862a5c42d8 fix disasbled dark mode link color 2026-01-13 12:05:49 -08:00
akcodez
d29a5083d1 Refactor button typography for responsiveness and consistency
- Updated Button component styles to use responsive typography mixins for better adaptability across devices.
- Removed redundant media queries and adjusted font sizes and line heights for both button types.
- Ensured margin resets to maintain consistent spacing in various contexts.
- Enhanced CSS for improved readability and maintainability.
2026-01-13 12:05:49 -08:00
akcodez
60fc8eb22e Update CardImage and TileLogo components for improved responsiveness and layout
- Adjusted column spans in CardImage showcase to support a 4-column layout on larger screens.
- Updated TileLogo showcase to reflect changes in aspect ratios and responsive behavior, ensuring proper display across different screen sizes.
- Enhanced SCSS styles for both components to maintain consistency in appearance and functionality in light and dark themes.
- Refined documentation to clarify usage and responsive design principles for both CardImage and TileLogo components.
2026-01-13 12:05:49 -08:00
akcodez
ec4ef6e9fc Update HeaderHeroSplitMedia styles for aspect ratio and title alignment
- Changed tablet aspect ratio from 2:1 to 16:9 for better compatibility with an 8-column grid.
- Adjusted title alignment in the title-only layout from center to top for improved visual hierarchy.
2026-01-13 12:02:11 -08:00
akcodez
42552e4d24 add translations 2026-01-13 11:56:47 -08:00
akcodez
e46e4006d5 Refactor submenu styles for improved layout and spacing
- Updated .bds-submenu__section to use justify-content: space-between for better distribution of space between header and items.
- Removed gap property and set margin-top to 0 for .bds-submenu__tier2 to enhance visual alignment in Use Cases section.
2026-01-13 10:25:35 -08:00
akcodez
5cf22174dc Add LanguageDropdown component to Navbar and enhance LanguagePill functionality
- Introduced LanguageDropdown for improved language selection in Navbar and MobileMenu.
- Updated LanguagePill to display the current language dynamically and manage dropdown state.
- Enhanced styles for language-related components to support open/close states and transitions.
- Added mobile-specific dropdown positioning and styles for better user experience.
2026-01-13 10:20:37 -08:00
akcodez
7fd39abb2b Integrate search functionality into Navbar and MobileMenu components, utilizing Redocly's search dialog. Update AlertBanner to prevent hydration mismatch with null initial state for displayDate. Adjust NavControls and NetworkSubmenu to handle theme detection more effectively. 2026-01-13 10:05:02 -08:00
Calvin
d7e042bdb6 Merge pull request #3437 from XRPLF/layout/callout-media-banner
Layout/callout media banner
2026-01-13 09:40:31 -08:00
akcodez
9006dc3812 Refactor Navbar component structure by modularizing subcomponents and removing legacy exports for improved maintainability and clarity. 2026-01-13 09:33:25 -08:00
gabriel-ortiz
f3bef3784f Add theme mode mixin and update CardIcon focus styles
- Introduced a new SCSS mixin for theme mode that applies styles based on light or dark themes, with validation for mode parameters.
- Updated CardIcon styles to maintain background color on focus for both light and green themes, enhancing accessibility and user experience.
- Removed unnecessary import from SmallTilesSection styles to streamline the codebase.
2026-01-12 21:02:29 -08:00
Calvin Jhunjhuwala
b8286bf6b4 css clean up 2026-01-12 19:30:21 -08:00
Calvin Jhunjhuwala
3feb69a1da fixing per comments 2026-01-12 14:28:57 -08:00
akcodez
e94be3ca20 PERFECT THE ANIMATION 2026-01-12 13:01:19 -08:00
akcodez
4776c45c33 Enhance Navbar with XRP Ledger text animation and update styles for dark mode and submenu transitions 2026-01-12 12:55:28 -08:00
akcodez
1278b1aca9 add proper icons 2026-01-12 11:25:24 -08:00
akcodez
da529fd71e add arrow moving logic 2026-01-12 10:05:17 -08:00
akcodez
e467e27448 add dark mode styles 2026-01-12 09:59:32 -08:00
Calvin Jhunjhuwala
de84fa25a8 added light image variant for example page 2026-01-09 15:50:48 -08:00
Calvin Jhunjhuwala
b4ddfa7955 fixing button spacing + image background 2026-01-09 15:29:22 -08:00
akcodez
ce75b4388c minor qa changes 2026-01-09 12:58:07 -08:00
Calvin Jhunjhuwala
46add22436 cleaning up css 2026-01-08 16:41:47 -08:00
Calvin Jhunjhuwala
93ca38ed76 fixing errors 2026-01-08 15:24:04 -08:00
Calvin Jhunjhuwala
e0430b9899 updated and working showcase for call out media 2026-01-08 14:08:51 -08:00
akcodez
5df5f38e83 fix animation 2026-01-08 13:18:17 -08:00
akcodez
2b15495835 udpate animations 2026-01-08 13:14:36 -08:00
gabriel-ortiz
ab366c79ef Add warning for empty cards in SmallTilesSection
- Implemented a console warning in the SmallTilesSection component to notify when no cards are provided, improving debugging and user feedback.
2026-01-08 11:29:01 -08:00
akcodez
1074670da7 fix nav heights 2026-01-08 11:27:42 -08:00
akcodez
1a2cb105f3 add all submenus 2026-01-08 11:23:41 -08:00
gabriel-ortiz
3badef78c1 Add SmallTilesSection component and styles
- Introduced the SmallTilesSection component for displaying multiple CardIcon components in a responsive grid layout.
- Implemented SCSS styles for the SmallTilesSection, including responsive grid behavior and spacing adjustments.
- Added documentation for the SmallTilesSection component, detailing usage, props, and examples.
- Updated main stylesheet to include SmallTilesSection styles.
2026-01-08 10:09:48 -08:00
Calvin Jhunjhuwala
a1f4c82e3a adding a README 2026-01-07 16:30:43 -08:00
Calvin Jhunjhuwala
478f5784ee updating callout media banner, styling for extra width 2026-01-07 16:28:21 -08:00
akcodez
471bf7f193 add basis for navbar 2026-01-07 13:48:30 -08:00
akcodez
f346a80ce0 Refactor HeaderHeroSplitMedia styles for tablet and accent surfaces
- Updated spacing variables for tablet view to enhance layout consistency.
- Introduced accent-specific spacing for title and description groups on tablet and desktop.
- Adjusted margin and gap values for improved responsiveness and visual hierarchy.
2026-01-06 13:28:20 -08:00
akcodez
e849cc95b9 Update HeaderHeroSplitMedia styles for improved color consistency and dark mode support
- Refactored color variables to use design tokens for better maintainability.
- Ensured consistent text colors for titles and descriptions in both light and dark modes.
- Adjusted color values for better contrast and readability across themes.
2026-01-06 13:20:09 -08:00
akcodez
0bff1aab4c Add HeaderHeroSplitMedia styles and adjust typography margins
- Introduced new styles for the HeaderHeroSplitMedia component, including layout, typography, and responsive design adjustments.
- Updated margin-bottom for paragraph and label-r elements to enhance spacing consistency.
2026-01-06 13:15:12 -08:00
Aria Keshmiri
e6aa704841 Merge pull request #3431 from XRPLF/design-qa-review
Design qa review
2026-01-06 10:43:41 -08:00
akcodez
9415ae085a fix card 2026-01-05 13:10:51 -08:00
akcodez
4cb232a068 Focus should not activate button hover - cardimage 2026-01-05 13:01:02 -08:00
akcodez
35958ebede Card - image : hovering card should not activate button hover state 2026-01-05 12:59:59 -08:00
akcodez
688ac5dc91 fix disasbled dark mode link color 2026-01-05 12:54:05 -08:00
Aria Keshmiri
e298a45902 Merge pull request #3430 from XRPLF/fix-typography-010526
fixing typography for label-r
2026-01-05 12:53:31 -08:00
akcodez
176e187c6a Refactor button typography for responsiveness and consistency
- Updated Button component styles to use responsive typography mixins for better adaptability across devices.
- Removed redundant media queries and adjusted font sizes and line heights for both button types.
- Ensured margin resets to maintain consistent spacing in various contexts.
- Enhanced CSS for improved readability and maintainability.
2026-01-05 12:44:14 -08:00
Calvin Jhunjhuwala
15046f431e fixing typography for label-r 2026-01-05 12:44:11 -08:00
akcodez
ecd4a1bb66 Merge remote-tracking branch 'origin/xrpl-brand-update-2026' into design-qa-review 2026-01-05 12:22:06 -08:00
Calvin
3fbed79209 Merge pull request #3421 from XRPLF/fix-bds-session-121125
Fix typography
2026-01-05 12:07:55 -08:00
Aria Keshmiri
fc472a4f77 Merge pull request #3417 from XRPLF/link-rename
rename link
2026-01-05 11:55:15 -08:00
Aria Keshmiri
bebc019daa Merge pull request #3420 from XRPLF/component/button-href-fix
Add link button functionality and styles
2026-01-05 11:55:04 -08:00
Calvin Jhunjhuwala
b3f235ded6 adding typography showcase page 2026-01-05 11:33:11 -08:00
akcodez
7b223aafc2 Update CardImage and TileLogo components for improved responsiveness and layout
- Adjusted column spans in CardImage showcase to support a 4-column layout on larger screens.
- Updated TileLogo showcase to reflect changes in aspect ratios and responsive behavior, ensuring proper display across different screen sizes.
- Enhanced SCSS styles for both components to maintain consistency in appearance and functionality in light and dark themes.
- Refined documentation to clarify usage and responsive design principles for both CardImage and TileLogo components.
2026-01-05 10:12:11 -08:00
Calvin Jhunjhuwala
ffe0eff61a lg + xl separate for the display-lg font class 2025-12-11 15:29:01 -08:00
Calvin Jhunjhuwala
be0e324d0b working font styles and updated card grid 2025-12-11 15:01:08 -08:00
akcodez
fadfde1775 Add link button functionality and styles
- Introduced link button support in the Button component, allowing buttons to render as anchor elements when an `href` prop is provided.
- Updated Button showcase to demonstrate link buttons for internal and external navigation.
- Enhanced Button SCSS styles to ensure proper appearance and behavior for link buttons in both light and dark themes.
- Added documentation for link button usage in the Button showcase.
2025-12-11 11:23:23 -08:00
akcodez
32899e9c41 rename link 2025-12-10 13:53:21 -08:00
Aria Keshmiri
15f48991c3 Merge pull request #3415 from XRPLF/component/card-image
Add CardImage component with showcase and documentation
2025-12-10 12:45:37 -08:00
akcodez
642c0dd2ce add bottom padding 2025-12-10 12:45:04 -08:00
akcodez
a08b24ed5d Enhance CardImage showcase with image scaling demo and responsive layout adjustments
- Added a new image scaling demonstration to the CardImage showcase, illustrating a zoom effect on hover.
- Updated layout of CardImage components to improve responsiveness, adjusting column spans for various screen sizes.
- Introduced a new image from Figma for the scaling demo and included detailed descriptions of the scaling behavior.
- Refined SCSS styles to support the new layout and ensure consistent spacing across different screen sizes.
2025-12-10 10:35:14 -08:00
Aria Keshmiri
74e8be5a13 Merge pull request #3413 from XRPLF/component/card-icon
Add CardIcon component with showcase and documentation
2025-12-10 09:37:01 -08:00
Calvin
7895d6dee9 Merge pull request #3410 from XRPLF/component/card-stat
[feat][site] Component/Card-Stat
2025-12-09 12:33:19 -08:00
akcodez
8e6d8f7c30 Add CardImage component with showcase and documentation
- Introduced the CardImage component, a responsive card designed to display an image, title, subtitle, and call-to-action button.
- Implemented three responsive size variants (LG, MD, SM) that adapt to viewport width.
- Added interactive states including default, hover, focus, pressed, and disabled.
- Created a comprehensive showcase page demonstrating all variants and states of the CardImage component.
- Included detailed documentation covering usage examples, props API, design tokens, and accessibility features.
- Added SCSS styles for the CardImage component, ensuring compatibility with both light and dark themes.
2025-12-09 12:29:03 -08:00
Calvin Jhunjhuwala
36785bc0f1 fixing css conflict 2025-12-09 12:28:14 -08:00
Calvin Jhunjhuwala
977c37ef83 minor copy change, pushiong fixed color 2025-12-09 12:00:11 -08:00
Calvin Jhunjhuwala
52d895b1d0 edits for dark mode card 2025-12-09 11:56:34 -08:00
akcodez
230ddcbe21 Add CardIcon component with showcase and documentation
- Introduced the CardIcon component, a clickable card featuring an icon and label text, supporting two color variants (Neutral and Green) and five interaction states (Default, Hover, Focused, Pressed, Disabled).
- Implemented responsive sizing that adapts at breakpoints (SM, MD, LG).
- Created a comprehensive showcase page demonstrating all variants, states, and usage examples.
- Added detailed documentation covering usage guidelines, best practices, and API reference.
- Included SCSS styles for the CardIcon component, ensuring compatibility with both light and dark themes.
2025-12-09 10:37:40 -08:00
Aria Keshmiri
1ee5828747 Merge pull request #3406 from XRPLF/component/card-offgrid
Add CardOffgrid component with showcase and documentation
2025-12-09 10:13:16 -08:00
Aria Keshmiri
314980a667 Merge pull request #3409 from XRPLF/component/tile-logo
Add TileLogo component with showcase and documentation
2025-12-09 10:13:06 -08:00
akcodez
2783d90cf6 Refactor CardOffgrid typography styles to utilize predefined classes
- Updated CardOffgrid component to use .subhead-lg-l and .body-l classes for title and description typography, respectively.
- Removed custom font size and line height definitions from SCSS and CSS files for improved consistency and maintainability.
- Adjusted related styles to ensure compatibility with the new typography approach.
2025-12-09 06:15:22 -08:00
akcodez
5fbdbb8d42 Refactor TileLogo showcase layout to use PageGrid components
- Replaced div-based layout with PageGridRow and PageGridCol components for better responsiveness and alignment.
- Updated all instances of logo displays within the TileLogo showcase to utilize the new grid structure.
- Ensured consistent spacing and alignment across different logo variants and states.
2025-12-09 06:05:54 -08:00
Calvin Jhunjhuwala
b7ba976fb2 consolidating classes, still need superscript specs 2025-12-08 21:06:56 -08:00
Calvin Jhunjhuwala
a6eb9e63e5 complete showcase pagfe 2025-12-08 15:30:42 -08:00
Calvin Jhunjhuwala
7d694c76a5 working card stat, finalizing sup, cleaning up code cleanliness 2025-12-08 13:58:57 -08:00
akcodez
cbc56937e6 Refactor TileLogo component styles and class naming to align with BDS conventions
- Updated SCSS styles to replace 'tile-logo' namespace with 'bds-tile-logo' for consistency with the Brand Design System.
- Adjusted class names in the TileLogo component to reflect the new naming convention.
- Ensured all styles and variants (square, rectangle, neutral, green) are updated accordingly for both light and dark themes.
2025-12-08 10:57:02 -08:00
akcodez
1a9fa9b970 Add TileLogo component with showcase and documentation
- Introduced the TileLogo component, designed for displaying brand logos with interactive states.
- Implemented two shape variants (Square and Rectangle) and two color variants (Neutral and Green), with responsive sizing.
- Created a comprehensive showcase page demonstrating all variants, states, and usage examples.
- Added detailed documentation covering usage guidelines, best practices, and API reference.
- Included SCSS styles for the TileLogo component, ensuring compatibility with both light and dark themes.
2025-12-08 10:52:37 -08:00
akcodez
cd82ea5484 rm link 2025-12-08 10:13:05 -08:00
akcodez
57898ab010 Add CardOffgrid component with showcase and documentation
- Introduced the CardOffgrid component, designed for displaying feature highlights with customizable icons, titles, and descriptions.
- Implemented two color variants: neutral and green, with interactive states and a unique hover animation.
- Created a comprehensive showcase page demonstrating all variants and states of the CardOffgrid component.
- Added detailed documentation covering usage guidelines, best practices, and API reference.
- Included SCSS styles for the CardOffgrid component, ensuring compatibility with both light and dark themes.
2025-12-05 11:41:18 -08:00
Aria Keshmiri
2dbb111943 Merge pull request #3405 from XRPLF/component/divider
Add Divider component and documentation
2025-12-04 15:34:04 -08:00
akcodez
cb6323d153 Update Divider component to replace 'black' color variant with 'base' for improved theme adaptability
- Changed all instances of 'black' to 'base' in the Divider component and its documentation to reflect the new high-contrast color that adapts to light and dark themes.
- Updated showcase page and styles to ensure consistency with the new color naming convention.
2025-12-04 15:33:32 -08:00
akcodez
08941588aa fix colors 2025-12-04 13:51:04 -08:00
akcodez
e183369ef6 add height 2025-12-04 13:48:23 -08:00
akcodez
702e180de6 Add Divider component and documentation
- Introduced the Divider component following the XRPL Brand Design System, supporting horizontal and vertical orientations, three stroke weights (thin, regular, strong), and three color variants (gray, black, green).
- Created a comprehensive showcase page for the Divider component, demonstrating its usage and variations.
- Added detailed documentation for the Divider component, including props API, usage examples, and best practices.
- Included styles for the Divider component in SCSS format, ensuring compatibility with light and dark themes.
2025-12-04 12:20:18 -08:00
Calvin
a265f82980 Merge pull request #3404 from XRPLF/grid-optimization
[fix] Grid optimization
2025-12-03 16:17:54 -08:00
Calvin Jhunjhuwala
021899906d removing unnecessary npm package 2025-12-03 16:14:09 -08:00
Calvin Jhunjhuwala
f022c48f6c changing showcase file 2025-12-03 16:06:59 -08:00
Calvin Jhunjhuwala
3e07b8400d removing extra css 2025-12-03 16:02:08 -08:00
Calvin Jhunjhuwala
5433894f20 renaming class name to bds 2025-12-03 14:51:59 -08:00
Calvin Jhunjhuwala
a6d84de417 working grid for fill and auto 2025-12-03 13:34:05 -08:00
Calvin Jhunjhuwala
6f76d4ece5 clean up of grid, working on all screen sizes, logic built out 2025-12-03 13:09:39 -08:00
Aria Keshmiri
17778ad84b Merge pull request #3399 from XRPLF/component/button
Component/button
2025-12-03 10:58:04 -08:00
Aria Keshmiri
518585227d Merge pull request #3401 from XRPLF/component/link
Add BDS link styles and update existing link styles
2025-12-03 10:57:25 -08:00
akcodez
ad0631f701 add arialbel 2025-12-03 10:56:43 -08:00
akcodez
01c19628a9 fix link spacing 2025-12-02 15:27:52 -08:00
akcodez
44614dba9d Refactor Button Styles for Responsive Design
Updated button styles to enhance responsiveness across devices by replacing fixed breakpoints with a mixin for the xl breakpoint. Adjusted typography and padding for smaller screens to ensure consistent appearance and usability. Improved comments for clarity on the import order and design tokens.
2025-12-02 12:40:27 -08:00
akcodez
621db81c7d add proper breakpoint sizing 2025-12-02 12:23:35 -08:00
akcodez
c01749eba2 rm deprecated linkCOlor 2025-12-02 11:52:23 -08:00
akcodez
2ff14e4224 Add BDS link styles and update existing link styles
- Introduced new styles for BDS link icons, including hover and focus states.
- Updated existing link styles to exclude BDS links from certain color and hover effects.
- Ensured consistent styling across light and dark themes for BDS links.
- Refactored landing page link styles to accommodate new BDS link classes.
2025-12-02 10:21:52 -08:00
akcodez
7685c2eb1e Refactor Tertiary Button Styles for Dark Mode
Updated the styles for the tertiary button in dark mode, including hover, focus, active, and disabled states. Adjusted padding and added text decoration for better visual feedback. Enhanced responsiveness for smaller screens to ensure consistent behavior across devices.
2025-12-01 14:27:02 -08:00
akcodez
2de2bac211 Enhance dark mode styles for primary and secondary buttons, adding detailed states for hover, focus, active, and disabled conditions. Update CSS to reflect new design specifications for secondary button in dark mode. 2025-12-01 14:21:14 -08:00
akcodez
bdc69f047a add primary dark mode 2025-12-01 14:17:25 -08:00
akcodez
f20177b5f9 Add Tertiary Button Showcase Component
Introduced a new ButtonShowcaseTertiary component to demonstrate the BDS Tertiary Button, including its various states and usage examples. Removed the previous ButtonShowcase component to streamline the showcase and focus on the Tertiary variant. Updated Button component to support the new variant and adjusted related styles in the CSS for both green and black themes.
2025-12-01 14:07:29 -08:00
akcodez
73b2127f87 add proper focus and active / hover states 2025-12-01 13:45:21 -08:00
akcodez
32b309c878 merge main brand branch in 2025-12-01 12:03:09 -08:00
akcodez
9cf1b07954 add full primary button 2025-12-01 12:01:50 -08:00
Calvin
5b73ccb8be Merge pull request #3393 from XRPLF/bds-font-update
[fix][fonts] Clean up of fonts, folder re-structuring
2025-12-01 11:01:58 -08:00
Calvin Jhunjhuwala
c4188c47d6 updating css for medium 2025-11-26 16:06:00 -08:00
Calvin Jhunjhuwala
2429574182 removing px reversion for medium 2025-11-26 16:03:51 -08:00
Calvin Jhunjhuwala
42ec50df27 removing fake button folder 2025-11-26 16:00:14 -08:00
Calvin Jhunjhuwala
37e96a9dae more documentation around page grid 2025-11-25 21:36:38 -08:00
Calvin Jhunjhuwala
f3ae760c40 move page grid css to page grid folder, removing more text class styling 2025-11-25 21:30:25 -08:00
Calvin Jhunjhuwala
97c302822a adding folder structure, cleaning up font, add readme for page grid 2025-11-25 17:29:58 -08:00
Calvin Jhunjhuwala
e92929e148 removing old background images, updating font classes 2025-11-13 12:08:33 -08:00
Calvin Jhunjhuwala
9d3d11800a adding page grid component + stylersheet 2025-11-03 10:42:35 -08:00
Calvin Jhunjhuwala
a956d5ae78 removing empty card footer 2025-10-30 10:42:30 -07:00
Calvin Jhunjhuwala
52e070dcf6 removing background from css as well 2025-10-30 10:38:53 -07:00
Calvin Jhunjhuwala
605eb70aed removed all old fonts, remove all old backgrounds 2025-10-30 10:33:42 -07:00
akcodez
0c2a1bc249 Refactor color migration strategy to a clean implementation, removing backward compatibility aliases and consolidating color scales. Update SCSS files to reflect new design tokens and ensure all references are migrated. Adjust event card layout in community events page for improved responsiveness. Modify CSS styles for better alignment with updated color palette and remove unnecessary padding in card components. 2025-10-21 14:04:55 -07:00
akcodez
51e763b967 Enhance PostCSS configuration with expanded safelist for Bootstrap utility classes, update layout in about and resources pages, and refine color palette in CSS files for improved design consistency. Adjusted card styles and link behaviors to align with new design tokens. 2025-10-21 13:42:07 -07:00
akcodez
86998c82d6 Implement CSS optimization pipeline with PurgeCSS, Autoprefixer, and cssnano; reduce bundle size by 42% (uncompressed) and 39% (gzipped). Add analysis tool for CSS metrics and update build scripts in package.json. Create comprehensive documentation for CSS optimization process. 2025-10-21 10:06:53 -07:00
akcodez
c2287a7fe6 run css compiler 2025-10-21 09:23:47 -07:00
akcodez
f09ab44280 upgrade bootstrap, add new fonts 2025-10-21 09:22:02 -07:00
Calvin Jhunjhuwala
08807db2e9 ran css 2025-10-21 09:17:17 -07:00
Calvin Jhunjhuwala
201479ced6 new fonts added working across website 2025-10-21 09:09:56 -07:00
Calvin Jhunjhuwala
ce49c8b6ba updating bootstrap to v5 2025-10-17 16:28:07 -07:00
781 changed files with 61934 additions and 16507 deletions

19
.claude/CLAUDE.md Normal file
View File

@@ -0,0 +1,19 @@
# XRPL Dev Portal — Claude Code Instructions
## Quick Reference
- **Framework:** Redocly Realm
- **Production branch:** `master`
- **Local preview:** `npm start`
## Localization
- Default: `en-US`
- Japanese: `ja`
- Translations mirror `docs/` structure under `@l10n/<language-code>/`
## Navigation
- Update `sidebars.yaml` when adding new doc pages
- Blog posts have a separate `blog/sidebars.yaml`
- Redirects go in `redirects.yaml`

View File

@@ -0,0 +1,268 @@
# Figma Build Page
Build a `.page.tsx` file from a Figma design URL by mapping each Figma section to an existing shared section component, and export any new images/icons from Figma into the project's asset folders.
**Usage:** `/figma-build-page <figma-url> <target-page-file>`
**Example:** `/figma-build-page https://www.figma.com/design/7vhTxPgH1in2AjIETuX49Z/Documentation?node-id=0-1 docs/index.page.tsx`
---
## Workflow
### Step 1 — Parse the input
Extract from `$ARGUMENTS`:
- **Figma URL**: extract `fileKey` and `nodeId` (convert `-` to `:` in nodeId)
- **Target file**: the `.page.tsx` file path to rebuild
- **Page slug**: derive from the target file path (e.g. `docs/index.page.tsx``docs`, `resources/about.page.tsx``resources-about`). This is used to prefix shared media filenames.
### Step 2 — Understand the design structure
Run in parallel:
1. Read the current target page file to understand what already exists
2. Run `find shared/sections -name "*.tsx"` and `find shared/components -name "*.tsx"` to inventory available components
3. Run `find static/img/icons/2026 static/img/logos/black static/img/bds-2026 -type f` to inventory existing assets so the build can reuse them instead of re-exporting duplicates
4. Call `mcp__claude_ai_Figma__get_metadata` on the **page root** (the parent of the `nodeId` you were given) — pass `nodeId="0:1"` if you don't know the page id, otherwise walk up one level from the given node. The goal is to see ALL sibling frames on the canvas, not just the LG/MD/SM page mockups. Section frames alone are not enough — designers also park reference data in sibling frames.
#### Step 2A — Locate the Assets frame (REQUIRED, do this before anything else design-side)
Designers park clean, isolated versions of the page's icons, logos, photos, and **canonical card/list content** in a sibling frame on the same canvas — typically named `Assets`, `Assets Library`, `Exports`, `Resources`, `Content`, or similar. It lives outside the main `LG`/`MD`/`SM` page frames, usually far to the right or below them.
From the page-root metadata, find any frame whose name matches `/asset|export|library|resource|content/i` OR whose x/y position places it clearly outside the LG/MD/SM stack. Record:
- Its `nodeId` and name
- Every child node's `nodeId`, layer name, and visual role (icon vs photo vs logo vs card content)
**Then immediately call `mcp__claude_ai_Figma__get_design_context` on the Assets frame** to extract its contents — child layer names, image asset URLs, and any text labels. Do this BEFORE fetching the section contexts in Step 3, because the Assets frame is the source of truth for:
- **Real partner/customer logos** — the LG frame typically shows placeholder logos (e.g. the same logo repeated 8×); the Assets frame holds the real brand SVGs.
- **Full carousel card sets** — the LG frame may only show 3-4 visible slides (with duplicates as overflow placeholders); the Assets frame holds the full N-card list with no duplicates.
- **Canonical icon artwork** — the icon inside a section is often a low-fidelity instance of the master icon in the Assets frame.
- **Per-card hrefs, hidden subtitles, alt text, video URLs** — content the section mockup doesn't have room to show.
Build an **Assets Index**: `{ layerName, nodeId, role, imageAssetUrl?, associatedSectionHint? }` for every child. Use the layer name to associate each asset with a section (e.g. layer `RWA Partner — Archax` belongs in the logo grid; layer `Carousel Card 04 — Onchain Trading` belongs in the carousel).
**If the page also has annotations pointing at the Assets frame** (e.g. `data-annotations="Logo - see right side asset frame"`, `"Full list in Assets"`, `"Cards continue in Assets frame"`), treat that as a hard contract: the Assets frame is the authoritative content for that section, and the LG mockup is just a visual stub.
**Fail-loud if no Assets frame is found:** if you can't find a sibling frame and the page has more than one media/logo/icon, surface this to the user before continuing — e.g. "I didn't find an Assets/Exports frame on this canvas. The LG mockup shows N placeholder logos and a 3-card carousel — proceed treating those as the final content, or point me at the Assets frame?" Don't silently fall back to the LG mockup when the design clearly references external content.
### Step 3 — Fetch design context for each section (cross-reference with Assets frame)
For every top-level section frame found in the metadata, call `mcp__claude_ai_Figma__get_design_context` in parallel batches (max 3 at a time). For each section, gather:
- The heading/title text
- Any body/description text
- All link labels and their annotation `href` values (from `data-annotations`)
- Color variants visible (background color tells you which variant to use)
- The arrangement (left/right, content vs media position)
- Every distinct image/icon node — capture its Figma `nodeId`, layer name, fill color, and visual role (icon vs photo, monochrome vs colored)
**Then cross-reference against the Assets Index from Step 2A:**
- For carousels/lists: if the LG mockup shows fewer cards than the Assets frame, USE THE ASSETS-FRAME COUNT and content. If cards in the mockup look like exact duplicates (same icon + same text), treat them as overflow placeholders and drop them in favor of the Assets-frame set.
- For logo grids: if the mockup repeats the same logo, IGNORE that and use the distinct logos from the Assets frame.
- For media: if the section's media node and an Assets-frame node share a layer name or visible image, prefer the Assets-frame node — it's higher fidelity and isolated from section chrome.
- For icons: if a section icon has a matching layer name in the Assets frame, export from the Assets frame, not the section instance.
**Important:** Note any Figma annotations that say content should be removed or changed, OR that redirect to the Assets frame ("see right side asset frame", "real logos in assets", etc.) — annotations override what the mockup shows.
### Step 4 — Map sections to existing components
For each Figma section, find the best matching component from `shared/sections/`. Common mappings:
| Figma Section Name | Component | Import |
|---|---|---|
| `headerHeroPrimaryMedia` | `HeaderHeroPrimaryMedia` (default export) | `shared/sections/HeaderHeroPrimaryMedia/HeaderHeroPrimaryMedia` |
| `CarouselCardListOffGrid` | `CarouselCardList` | `shared/sections/CarouselCardList/CarouselCardList` |
| `TextGridCard` | `CardsTextGrid` | `shared/sections/CardsTextGrid/CardsTextGrid` |
| `VideoFeatured` | `FeaturedVideoHero` (default export) | `shared/sections/FeaturedVideoHero/FeaturedVideoHero` |
| `LinkSmallGrid` | `LinkSmallGrid` | `shared/sections/LinkSmallGrid/LinkSmallGrid` |
| `LinkTextDirectory` | `LinkTextDirectory` | `shared/sections/LinkTextDirectory/LinkTextDirectory` |
| `FeatureTwoColumn` | `FeatureTwoColumn` | `shared/sections/FeatureTwoColumn/FeatureTwoColumn` |
| `LinkSmallTiles` | `SmallTilesSection` | `shared/sections/SmallTilesSection/SmallTilesSection` |
| `IconTextGridCard` | `CardsIconGrid` | `shared/sections/CardsIconGrid/CardsIconGrid` |
| `StandardCard` group | `StandardCardGroupSection` | `shared/sections/StandardCardGroupSection/StandardCardGroupSection` |
Read the prop interfaces of each matched component before writing (`head -60` of the component file is usually enough).
**Key prop notes:**
- `HeaderHeroPrimaryMedia` / `FeaturedVideoHero`**default exports**; all others are named exports
- `FeaturedVideoHero` video source: `{ type: 'embed', embedUrl: 'https://www.youtube.com/embed/VIDEO_ID' }`
- `FeatureTwoColumn` `description` prop is required — pass `""` if the Figma shows no body text
- `LinkTextDirectory` buttons use `ButtonConfig`: `{ label: string; href?: string }`
- `StandardCardGroupSection` callsToAction uses `DesignConstrainedButtonProps`: `{ children: ReactNode; href?: string }`
- `CardsTextGrid` / `CardsIconGrid` `description` field accepts `React.ReactNode` — use this for inline links
- `SmallTilesSection` uses existing logo assets: `require('../static/img/logos/black/javascript.svg')` etc.
### Step 5 — Determine color variants from Figma
Match Figma background colors to component variant props:
- White / `#ffffff``"neutral"` or `"gray"` (default)
- Green `#70ee97` / `#21e46b``"green"`
- Lilac/purple `#d9caff``"lilac"`
- Yellow → `"yellow"`
### Step 6 — Plan asset exports
For every image/icon node identified in Step 3, decide:
**A) Source node — always prefer the Assets frame:** For each asset slot in the page, look up the matching node in the Assets Index from Step 2A by layer name or visual match. **Export from the Assets-frame node, not the section instance.** Section instances are often scaled-down thumbnails or shared placeholders; the Assets frame holds the master artwork at its intended export size. Only fall back to the section instance if the Assets frame genuinely doesn't have a counterpart.
**B) Reuse vs export:** If a visually-equivalent asset already exists in the inventory from Step 2 (same role, same color), reuse its path and skip export. Otherwise schedule a new export.
**C) Target folder** — route by section type and asset role:
| Section / role | Folder | Format |
|---|---|---|
| `CarouselCardList` card icons (monochrome glyphs) | `static/img/icons/2026/black/` | `.svg` |
| `CardsIconGrid` card icons (colored glyphs) | `static/img/icons/2026/color/<color>/` | `.svg` |
| `SmallTilesSection` card icons (SDK / language logos) | `static/img/logos/black/` | `.svg` |
| `LogoRectangleGrid` partner logos (rendered from inner `Logo` frame, 1.5× scale) | `static/img/logos/black/` | `.png` |
| `HeaderHeroPrimaryMedia` hero media (photo) | `static/img/bds-2026/` | `.jpg` (composite raw asset onto Figma bg color at native size, see Step 7) |
| `HeaderHeroSplitMedia` hero media (photo) | `static/img/bds-2026/` | `.jpg` (composite raw asset onto Figma bg color at native size, see Step 7) |
| `FeatureTwoColumn` media (photo) | `static/img/bds-2026/` | `.jpg` (composite raw asset onto Figma bg color at native size, see Step 7) |
| `FeatureSingleTopic` media (photo) | `static/img/bds-2026/` | `.jpg` (composite raw asset onto Figma bg color at native size, see Step 7) |
| `CardsFeatured` / `logoRectangleGrid`-as-image-cards card media | `static/img/bds-2026/` | `.jpg` (screenshot card-image frame at 1.5×, see Step 7) |
| `FeaturedVideoHero` poster (if used) | `static/img/bds-2026/` | `.jpg` (composite raw asset onto Figma bg color at native size, see Step 7) |
| `CarouselFeatured` slide HeroMedia (photo) | `static/img/bds-2026/` | `.jpg` (composite raw asset onto Figma bg color at native size, see Step 7) |
| Any other colored decorative icon | `static/img/icons/2026/color/<color>/` | `.svg` |
| Any other monochrome icon | `static/img/icons/2026/black/` | `.svg` |
For the colored-icon folders, pick `<color>` from the Figma fill on the icon (or, if the icon inherits color from a parent component, the parent section's variant prop). Existing folders: `lilac`. Create a new sibling folder (`green`, `yellow`, etc.) if the design uses a new color — never dump differently-colored icons into the wrong folder.
**D) Filename — always kebab-case:**
1. Start from the Figma layer name.
2. Lowercase, replace spaces / underscores / camelCase boundaries with `-`, strip non-`[a-z0-9-]`.
3. For shared photographic media in `bds-2026/`, **prefix with the page slug** to avoid cross-page collisions:
- hero media → `<page-slug>-hero-media.jpg`
- feature media (multi) → `<page-slug>-feature-media-1.jpg`, `<page-slug>-feature-media-2.jpg`, …
4. Icons and SDK logos are not page-prefixed — they're meant to be reusable across pages.
Examples:
- Figma layer `Ready to Use Code Samples` (CarouselCardList icon) → `static/img/icons/2026/black/ready-to-use-code-samples.svg`
- Figma layer `XRPL Server` (CardsIconGrid icon, lilac fill) → `static/img/icons/2026/color/lilac/xrpl-server.svg`
- Figma layer `Hero Image` on `docs/index.page.tsx``static/img/bds-2026/docs-hero-media.jpg`
- Figma layer `Feature 02` on `resources/about.page.tsx``static/img/bds-2026/resources-about-feature-media-2.jpg`
- Figma frame `Logo_Circle``Logo` (inner, LogoRectangleGrid partner) → `static/img/logos/black/circle.png` (1.5× PNG, see Step 7)
- Figma frame `Logo_Ondo``Logo` (inner, LogoRectangleGrid partner) → `static/img/logos/black/ondo.png`
### Step 7 — Export the assets from Figma
For each scheduled export from Step 6 (sourced from the Assets frame per Step 6A whenever possible):
1. Ensure the target folder exists (`mkdir -p` it if not).
2. **Get the raw Figma asset URL.** Calling `mcp__claude_ai_Figma__get_design_context` on a frame returns inline TS that declares `const imgXxx = "https://www.figma.com/api/mcp/asset/<uuid>"` constants — one per leaf image/icon node. These URLs serve the **raw underlying asset** (SVG for vector icons, PNG for photos/rasters), NOT a re-rendered screenshot of the surrounding chrome. Pull the URL for the specific Assets-frame child you mapped to this slot.
3. **Download with `curl -sL`** for raw vector assets that render as-is with no framing chrome — typically SVG icons and SDK/language logos:
- SVG icons / vector logos → `curl -sL <url> -o <target>.svg` — Figma serves the actual SVG markup for vector nodes, so no conversion is needed.
- Verify the format with `file <path>` after downloading the first one of each type, in case Figma serves something unexpected.
3a. **Photographic media with backgrounds — composite the raw image onto the design's background color, save as JPG at native size.** Most media nodes in the design system (hero media, FeatureTwoColumn media, FeatureSingleTopic media, FeaturedVideoHero poster, CardsFeatured card image, CarouselFeatured slide hero) live inside a wrapper frame named `HeroMedia` / `FeatureMedia` / similar. In Figma, that wrapper frame may have a background fill (e.g. `bg-neutral/100` = `#f0f3f7`, `bg-neutral/200` = `#e6eaf0`) BEHIND a foreground illustration. The raw `imgXxx` URL gives you the foreground image only — strips the background, leaves transparent edges. When the JPG converter then flattens to white, the image looks "floating on white" instead of "sitting on the gray tile" the designer intended.
To capture the composited image + background fill as a flat JPG **at the source image's native size** (no upscale):
1. **Pull the asset URL from the Assets frame.** This is the priority. Calling `get_design_context` on the Assets frame returns the master `imgXxx = "https://www.figma.com/api/mcp/asset/<uuid>"` constants — clean, isolated, full-size. Only fall back to the section instance's asset URL when the Assets frame has no counterpart.
2. **Inspect the design context to find the background color** the image sits on. Look at the wrapper frame around the `<img>` for a sibling/child div with `bg-[var(--neutral\/100,#f0f3f7)]`, `bg-[var(--neutral\/200,#e6eaf0)]`, or similar. If there's no bg div, use `#ffffff`.
3. **Download the raw asset:** `curl -sL <imgXxx-url> -o /tmp/<name>.png`. Most photo nodes return PNG with alpha (illustrations / partial photos); some return JPEG (full-bleed photos with no alpha).
4. **Composite onto the background color and save as JPG using ImageMagick** (install once with `brew install imagemagick`):
```
magick /tmp/<name>.png -background "<hex>" -alpha remove -alpha off -quality 85 <target>.jpg
```
**No `-resize` flag** — preserve the source's native dimensions. (For very large source PNGs above ~2000px, you may add `-resize "1500x1500>"` to cap size for web, but otherwise leave the native size alone — the designer chose it.) The `-alpha remove -alpha off` flattens alpha onto the `-background` color BEFORE the JPEG encoder strips alpha to white, giving the correct background instead of white.
**Size budget — ≤250 KB per non-hero photo, ≤500 KB for the hero.** After step 4, check the JPG size. If a non-hero photo lands above ~250 KB (a hero may go to ~500 KB), re-encode at lower quality:
```
magick <target>.jpg -resize "1500x1500>" -quality 78 /tmp/recomp.jpg && mv /tmp/recomp.jpg <target>.jpg
```
Why: cumulative image weight across a single page's `require()` calls (often 510 images at ~250 KB) plus the rest of the bundle pushes Redocly's cloud builder close to its memory cap. Three outlier 600670 KB photos on one branch contributed to an OOM build failure; consistent ≤250 KB compression keeps headroom.
5. Save with the `<page-slug>-feature-media-N.jpg` (or `-hero-media.jpg`, `-video-poster.jpg`, etc.) naming convention from Step 6.
**DO NOT use `get_screenshot` on the media frame** — instance children inside design-system components have IDs like `I<sectionId>;<...>` which are not screenshotable, and the MCP rejects them. The composite-from-raw-asset approach above works for all cases.
**Sanity-check the first one.** After exporting the first media of each kind, eyeball the JPG: the foreground illustration should sit on a uniform colored tile (`#f0f3f7` light gray, `#e6eaf0` slightly darker gray, etc.) — NOT on white when the design called for gray. If it's still white-flat, you used the wrong `-background` hex; re-read the Figma frame's `bg-` value.
4. **LogoRectangleGrid partner logos — special procedure.** Multi-layer brand logos (Circle, Zeconomy, DB Schenker, etc.) decompose into many vector pieces under `get_design_context`, so the raw-asset-URL technique above gives you fragments, not a composite. Use this instead:
1. Target the **inner `Logo` frame** (the 170×96 child of `Logo_<Name>`), not the gray-tile parent (`Logo_<Name>`) and not the bottom-most leaf layer (e.g. `Ondo finance`, `DB Schenker_Logo_0 1`).
2. Call `mcp__claude_ai_Figma__get_screenshot` on that inner Logo frame with `contentsOnly: true` and `maxDimension: 256` to request the longer-edge at ~1.5× the native 170 px. Note that Figma's MCP does not supersample beyond a frame's native render size, so the returned PNG is typically still 170×96 — that's expected, not an error.
3. Download the PNG: `curl -sL <image_url> -o /tmp/<name>.png`.
4. Upscale to the 1.5× target dimensions (255×144) using `sips`: `sips -z 144 255 /tmp/<name>.png --out static/img/logos/black/<name>.png`. This gives a crisper-on-retina raster at the design's intended display proportion, even if the resampled pixels don't add new detail.
5. Save as `.png` (not `.svg` — partner logos in the grid are raster). Filename is kebab-case of the layer name with the `Logo_` prefix stripped (e.g. `Logo_DBS` → `db-schenker.png` — use the visually-recognized brand name, not the literal Figma slug if it's an abbreviation).
6. **Surface logo-files annotations.** Designers often annotate one of the logo frames (e.g. `Logo_Circle`) with `data-assets-annotations` text like `"Need logo files"` plus a Google Drive link. When present, add a `MISSING_ASSETS` entry: `{ note: "Partner logos are placeholder reproductions — final brand-approved files pending from <Drive URL>", affects: [list of logo paths] }`. The exports are still useful as stand-ins until the user swaps in real assets.
5. **Do NOT use `get_screenshot` on the section frame** to capture media — that re-renders the whole section (chrome, text, padding) and the resulting image cannot be used as a clean media src. The right target for media is the **named media frame inside the section** (e.g. `HeroMedia`, `FeatureMedia`, the `CardImage` media child) per Step 3a above, not the section itself and not the leaf `<img>` (which would strip the background fill).
6. **Fallback when export fails or returns nothing usable:** create a zero-byte placeholder file at the target path AND record `{ figmaNodeId, layerName, targetPath, reason }` in a `MISSING_ASSETS` list. Do not silently drop the asset.
After all attempted exports, run `ls -la` on each unique target folder so the user can see what landed.
### Step 8 — Write the implementation (Plan Mode)
Present a plan first showing:
- All sections in order with their mapped component
- The full content (text, links, variants) for each section
- Any content removed per Figma annotations
- **For each list/grid/carousel section, the canonical item count and source** — e.g. "Logo grid: 8 distinct partner logos from Assets frame (LG mockup showed 8× placeholder, ignored)" or "Carousel: 5 cards from Assets frame (LG mockup showed 3 + 2 duplicates, kept 5)". Make it explicit that the Assets frame won, so the user can spot if something was missed.
- **The asset manifest**: for every image/icon, show `figma layer → source (assets-frame node / section-instance fallback) → target path → status (exported | reused | missing)`
After approval, write the full `.page.tsx`:
1. Keep the existing `frontmatter` export (SEO metadata)
2. Import all section components at the top
3. **Import and use the translate hook inside the default-exported component:**
```tsx
import { useThemeHooks } from '@redocly/theme/core/hooks';
// ...
export default function MyPage() {
const { useTranslate } = useThemeHooks();
const { translate } = useTranslate();
return (/* ... */);
}
```
4. **Wrap every user-facing string in `translate(...)`** — this includes every prop value that renders as visible text. No bare string literals in JSX text or text-bearing props. Apply to:
- `headline`, `subtitle`, `title`, `description`, `heading`, `label`, `iconAlt`, `alt` props
- Every entry's `title`, `description`, `label`, `heading` inside `cards`, `links`, `buttons` arrays
- `children` strings (including `callsToAction[].children` on `StandardCardGroupSection`)
- Inline-link anchor text inside `React.ReactNode` descriptions (e.g. `<a href="...">{translate('Read More')}</a>`)
- **Do not** translate URLs (`href`, `src`), variant strings (`"green"`, `"left"`), or `embedUrl` values
- Example pattern (mirrors the project's house style):
```tsx
<HeaderHeroPrimaryMedia
headline={translate("XRP Ledger (XRPL) Documentation")}
subtitle={translate("Explore XRPL documentation with our essential guide for developers and admins who want to start building and integrating with the XRP Ledger.")}
media={{ type: 'image', src: require('../static/img/bds-2026/docs-hero-media.jpg'), alt: translate('XRPL Documentation') }}
/>
```
5. Render sections in Figma order inside a wrapper `<div className="landing">`
6. For every image/icon, reference it via `require('../static/img/...')` using the exact path from the manifest — even if the export failed (the placeholder file holds the path)
7. Apply all link `href` values from Figma `data-annotations`
8. Use `React.ReactNode` descriptions to embed inline links where headings link to pages
### Step 9 — Fix TypeScript errors
After writing, check IDE diagnostics and fix:
- Default vs named export mismatches
- Wrong video source type (`type: 'embed'` not `type: 'embed_url'`)
- Missing required props
- `callsToAction` tuple shape `[primary, secondary?]`
### Step 10 — Report
End the run by printing:
- The list of exported assets and their final paths
- The `MISSING_ASSETS` list (if any) so the user knows exactly which Figma nodes need manual export
- The full target file path
---
## Rules
- **Never install Tailwind** — the project uses SCSS + Bootstrap
- **Never create new components** — only use what exists in `shared/sections/` and `shared/components/`
- **The Assets frame is the source of truth.** Before fetching any section context, find and read the sibling Assets/Exports/Library/Resources frame on the page canvas. Use it for: real partner logos (not LG mockup placeholders), full carousel/list item sets (not the truncated visible cards), master icon artwork, and per-item hrefs the mockup hides. If you can't find an Assets frame and the design references one (via annotations or repeated placeholders), surface that to the user before guessing.
- **Carousel and logo-grid item counts come from the Assets frame.** If the LG mockup shows repeated identical cards/logos, treat them as overflow placeholders and use the Assets-frame count instead.
- **Export from Assets-frame nodes, not section instances.** Section instances are usually thumbnails of the master artwork in the Assets frame.
- **Always apply links** from Figma annotations to make lists navigable
- **Respect Figma notes** — if a section is annotated for removal, skip it; if it's annotated to redirect content to the Assets frame ("see right side asset frame", "logos in assets", etc.), follow that pointer rather than using the visible mockup content
- **Light mode only** — follow the light mode variant of any design that shows both
- **Always use `require('../static/img/...')` for images** — every image/icon prop must point at a real path under `static/img/` following the folder routing in Step 6. Never pass `src=""` and never inline a remote URL.
- **Kebab-case all new asset filenames.** Shared photographic media in `bds-2026/` must be prefixed with the page slug; icons and logos are not page-prefixed.
- **Reuse existing assets** when the inventory in Step 2 already has a matching icon/logo — do not re-export duplicates with new names.
- **Never delete or overwrite an existing asset** without explicit user confirmation. If an export would collide with an existing file, rename the new export with a `-2` suffix and flag it in the plan.
- **Always use `translate(...)` for visible text.** Import `useThemeHooks` from `@redocly/theme/core/hooks`, call `const { useTranslate } = useThemeHooks(); const { translate } = useTranslate();` at the top of the component, and wrap every user-facing string in `translate(...)`. Never leave a bare string literal in a text-bearing prop or as JSX text. URLs, variant enums, and embed URLs are not text — leave those untranslated.

13
.claude/settings.json Normal file
View File

@@ -0,0 +1,13 @@
{
"permissions": {
"allow": [
"mcp__claude_ai_Figma__get_design_context",
"mcp__claude_ai_Figma__get_metadata",
"mcp__claude_ai_Figma__get_screenshot",
"mcp__claude_ai_Figma__whoami"
],
"deny": [
"Bash(git push *)"
]
}
}

View File

@@ -0,0 +1,117 @@
---
name: generate-release-notes
description: Generate and sort rippled release notes from GitHub commit history
argument-hint: --from <ref> --to <ref> [--date YYYY-MM-DD] [--output <path>]
allowed-tools: Bash, Read, Edit, Write, Grep, Glob
effort: max
---
# Generate rippled Release Notes
This skill generates a draft release notes blog post for a new rippled version, then sorts the entries into the correct subsections.
## Execution constraints
- **Do NOT write scripts** to sort or process the file. Prefer the Edit tool for targeted changes. Use Write only when replacing large sections that are impractical to edit incrementally.
- **Output progress**: Before each major step (generating raw release notes, reviewing file, processing amendments, sorting entries, reformatting, cleanup), output a brief status message so the user can see progress.
## Step 1: Generate the raw release notes
Run the Python script from the repo root. Pass through all arguments from `$ARGUMENTS`:
```bash
python3 tools/generate-release-notes.py $ARGUMENTS
```
If the user didn't provide `--from` or `--to`, ask them for the base and target refs (tags or branches).
The script will:
- Fetch the version string from `BuildInfo.cpp`
- Fetch all commits between the two refs
- Fetch PR details (title, link, labels, files, description) via GraphQL
- Compare `features.macro` between refs to identify amendment changes
- Auto-sort amendment entries into the Amendments section
- Output all other entries as unsorted with full context
## Step 2: Review the generated file
Read the output file (path shown in script output). Note the **Full Changelog** structure:
- **Amendments section**: Contains auto-sorted entries and an HTML comment listing which amendments to include or remove
- **Empty subsections**: Features, Breaking Changes, Bug Fixes, Refactors, Documentation, Testing, CI/Build
- **Unsorted entries**: After the **Bug Bounties and Responsible Disclosures** section is an unsorted list of entries with title, link, labels, files, and description for context
## Step 3: Process amendments
Handle Amendments first, before sorting other entries.
**3a. Process the auto-sorted Amendments subsection:**
The HTML comment contains three lists — follow them exactly:
- **Include**: Keep these entries.
- **Exclude**: Remove these entries.
- Entries on **neither** list: Remove these entries.
**3b. Scan unsorted entries for unreleased amendment work:**
Search through ALL unsorted entries for titles, labels, descriptions, or files that reference amendments on the "Exclude" or "Other amendments not part of this release" lists. Remove entries that directly implement, enable, fix, or refactor these amendments. Keep entries that are general changes that merely reference the amendment as motivation — if the code change is useful on its own regardless of whether the amendment ships, keep it.
**3c. If you disagree with any amendment decisions, make a note to the user but do NOT deviate from the rules.**
## Step 4: Sort remaining unsorted entries into subsections
Move each remaining unsorted entry into the appropriate subsection.
Use these signals to categorize:
**Files changed** (strongest signal):
- Only `.github/`, `CMakeLists.txt`, `conan*`, CI config files → **CI/Build**
- Only `src/test/`, `*_test.cpp` files → **Testing**
- Only `*.md`, `docs/` files → **Documentation**
**Labels** (strong signal):
- `Bug` label → **Bug Fixes**
**Title prefixes** (medium signal):
- `fix:`**Bug Fixes**
- `feat:`**Features**
- `refactor:`**Refactors**
- `docs:`**Documentation**
- `test:`**Testing**
- `ci:`, `build:`, `chore:`**CI/Build**
**Description content** (when other signals are ambiguous):
- Read the PR description to understand the change's purpose
- PRs that change API behavior, remove features, or have "Breaking change" checked in their description → **Breaking Changes**
Additional sorting guidance:
- Watch for revert pairs: If a PR was committed and then reverted (or vice versa), check that the net effect is accounted for — don't include both.
## Step 5: Reformat sorted entries
After sorting, reformat each entry to match the release notes style.
**Amendment entries** should follow this format:
```markdown
- **amendmentName**: Description of what the amendment does. ([#1234](https://github.com/XRPLF/rippled/pull/1234))
```
- Use more detail for amendment descriptions since they are the most important. Use present tense.
- If there are multiple entries for the same amendment, merge into one, prioritizing the entry that describes the actual amendment.
**Feature and Breaking Change entries** should follow this format:
```markdown
- Description of the change. ([#1234](https://github.com/XRPLF/rippled/pull/1234))
```
- Keep the description concise. Use past tense.
**All other entries** should follow this format:
```markdown
- The PR title of the entry. ([#1234](https://github.com/XRPLF/rippled/pull/1234))
```
- Copy the PR title as-is. Only fix capitalization, remove conventional commit prefixes (fix:, feat:, ci:, refactor:, docs:, test:, chore:, build:), and adjust to past tense if needed. Do NOT rewrite, paraphrase, or summarize.
## Step 6: Clean up
- Add a short and generic description of changes to the existing `seo.description` frontmatter, e.g., "This version introduces new amendments and bug fixes." Do not create long lists of detailed changes.
- Add a more detailed summary of the release to the existing "Introducing XRP Ledger Version X.Y.Z" section. Include amendment names (organized in a list if more than 2), featuress, and breaking changes. Limit this to 1 paragraph.
- Do NOT delete the **Credits** or **Bug Bounties and Responsible Disclosures** sections
- Remove empty subsections that have no entries
- Remove all HTML comments (sorting instructions)
- Do a final review of the release notes. If you see anything strange, or were forced to take unintuitive actions by these instructions, notify the user, but don't make changes.

3
.gitignore vendored
View File

@@ -8,8 +8,11 @@ yarn-error.log
*.iml
.venv/
_code-samples/*/js/package-lock.json
*.css.map
_code-samples/*/go/go.sum
_code-samples/*/java/target/
_code-samples/*/*/*[Ss]etup.json
# PHP
composer.lock
.cursor/

View File

@@ -2,6 +2,7 @@ navbar.about: Acerca de
navbar.docs: Docs
navbar.resources: Recursos
navbar.community: Comunidad
navbar.showcase: Escaparate
footer.about: Acerca de
footer.docs: Docs
footer.resources: Recursos

View File

@@ -2,7 +2,9 @@
seo:
description: アカウントの削除
labels:
- アカウント
- Accounts
requiredAmendment: DeletableAccounts
txIcon: cancel
---
# AccountDelete
@@ -10,7 +12,7 @@ labels:
AccountDeleteトランザクションは、XRP Ledgerで[アカウント](../../ledger-data/ledger-entry-types/accountroot.md)と、アカウントが所有するオブジェクトを削除し、可能であれば、アカウントの残りのXRPを指定された送金先アカウントに送信します。アカウントを削除する要件については、[アカウントの削除](../../../../concepts/accounts/deleting-accounts.md)をご覧ください。
_[DeletableAccounts Amendment][]が必要です。_
{% amendment-disclaimer name="DeletableAccounts" /%}
## {% $frontmatter.seo.title %} JSONの例

View File

@@ -2,7 +2,8 @@
seo:
description: XRP Ledgerのアカウントのプロパティーを修正します。
labels:
- アカウント
- Accounts
txIcon: modify
---
# AccountSet

View File

@@ -1,10 +1,11 @@
---
html: ammbid.html
parent: transaction-types.html
seo:
description: 自動マーケットメーカーのオークションスロットに入札することで、手数料の割引を受けることができます。
labels:
- AMM
- AMM
- DEX
requiredAmendment: AMM
txIcon: modify
---
# AMMBid
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/AMMBid.cpp "Source")

View File

@@ -2,8 +2,10 @@
seo:
description: 自動マーケットメーカープールに発行済みトークンを預け入れた保有者から、トークンを回収する。
labels:
- AMM
- Tokens
- AMM
- DEX
requiredAmendment: AMMClawback
txIcon: cancel
---
# AMMClawback

View File

@@ -4,7 +4,10 @@ parent: transaction-types.html
seo:
description: 指定された資産ペアを取引するための新しい自動マーケットメーカーを作成します。
labels:
- AMM
- AMM
- DEX
requiredAmendment: AMM
txIcon: create
---
# AMMCreate
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/AMMCreate.cpp "Source")

View File

@@ -1,10 +1,11 @@
---
html: ammdelete.html
parent: transaction-types.html
seo:
description: 空のプールを持つ自動マーケットメーカーのインスタンスを削除します。
labels:
- AMM
- AMM
- DEX
requiredAmendment: AMM
txIcon: cancel
---
# AMMDelete
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/AMMDelete.cpp "Source")

View File

@@ -4,7 +4,10 @@ parent: transaction-types.html
seo:
description: 自動マーケットメーカーに資金を預け、LPTokenを受け取ります。
labels:
- AMM
- AMM
- DEX
requiredAmendment: AMM
txIcon: send
---
# AMMDeposit
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/AMMDeposit.cpp "Source")

View File

@@ -4,7 +4,10 @@ parent: transaction-types.html
seo:
description: 自動マーケットメーカーインスタンスの取引手数料へ投票する。
labels:
- AMM
- AMM
- DEX
requiredAmendment: AMM
txIcon: modify
---
# AMMVote
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/AMMVote.cpp "Source")

View File

@@ -4,7 +4,10 @@ parent: transaction-types.html
seo:
description: LPトークを自動マーケットメーカーに返却し、プールが保有する資産の一部と引き換えマス。
labels:
- AMM
- AMM
- DEX
requiredAmendment: AMM
txIcon: send
---
# AMMWithdraw
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/AMMWithdraw.cpp "Source")

View File

@@ -2,15 +2,19 @@
seo:
description: 最大8件のトランザクションをまとめて作成・送信し、それらがすべて成功するか、すべて失敗するようにアトミックに処理されるようにします。
labels:
- Batch
- Transaction Sending
- Transaction Sending
- Other Transactions
requiredAmendment: Batch
status: not_enabled
txIcon: other
---
# Batch
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/Batch.cpp "Source")
`Batch`トランザクションは、最大8つのトランザクションを単一のバッチで送信します。各トランザクションは、4つのモード(全て成功または全て失敗All or Nothing、一つのみ成功Only One、失敗まで継続Until Failure、および独立実行Independent)のいずれかでアトミックに実行されます。
{% amendment-disclaimer name="Batch" /%}
## {% $frontmatter.seo.title %} JSONの例
### 単一アカウントの場合

View File

@@ -1,17 +1,18 @@
---
html: checkcancel.html
parent: transaction-types.html
seo:
description: 未清算のCheckを取り消し、送金を行わずにレジャーから削除します。
labels:
- Checks
- Checks
- Payments
requiredAmendment: Checks
txIcon: cancel
---
# CheckCancel
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/CancelCheck.cpp "Source")
未清算のCheckを取り消し、送金を行わずにレジャーから削除します。Checkの送金元または送金先は、いつでもこのトランザクションタイプを使用してCheckを取り消すことができます。有効期限切れのCheckはすべてのアドレスが取り消すことができます。
_[Checks Amendment][]が必要です_
{% amendment-disclaimer name="Checks" /%}
## {% $frontmatter.seo.title %} JSONの例

View File

@@ -1,10 +1,11 @@
---
html: checkcash.html
parent: transaction-types.html
seo:
description: レジャーでCheckオブジェクトの清算を試みます。
labels:
- Checks
- Checks
- Payments
requiredAmendment: Checks
txIcon: finish
---
# CheckCash
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/CashCheck.cpp "Source")
@@ -13,7 +14,7 @@ labels:
Checkに相当する資金があるとは保証されないため、送金元に十分な残高がないか、または資金を送金できるだけの十分な流動性がないことが原因で、Checkの清算が失敗することがあります。このような状況が発生した場合、Checkはレジャーに残り、送金先は後でこのCheckの換金を再試行するか、または異なる額で換金を試みることができます。
_[Checks Amendment][]が必要です_
{% amendment-disclaimer name="Checks" /%}
## {% $frontmatter.seo.title %} JSONの例

View File

@@ -1,17 +1,18 @@
---
html: checkcreate.html
parent: transaction-types.html
seo:
description: レジャーにCheckオブジェクトを作成します
labels:
- Checks
- Checks
- Payments
requiredAmendment: Checks
txIcon: create
---
# CheckCreate
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/CreateCheck.cpp "Source")
レジャーにCheckオブジェクトを作成します。これにより指定の送金先は後日換金することができます。このトランザクションの送信者はCheckの送金元です。
_[Checks Amendment][]が必要です_
{% amendment-disclaimer name="Checks" /%}
## {% $frontmatter.seo.title %} JSONの例

View File

@@ -2,7 +2,9 @@
seo:
description: 発行したトークンを取り戻します。
labels:
- トークン
- Tokens
requiredAmendment: Clawback
txIcon: cancel
---
# Clawback

View File

@@ -1,12 +1,18 @@
---
seo:
description: アカウントに仮発行された資格情報を承認します。
status: not_enabled
labels:
- Decentralized Storage
- Credentials
requiredAmendment: Credentials
txIcon: finish
---
# CredentialAccept
CredentialAcceptトランザクションは資格情報を承認し、その資格情報を有効にします。資格情報の対象者のみがこの操作を実行できます。
{% amendment-disclaimer name="Credentials" /%}
## CredentialAccept JSONの例
```json

View File

@@ -1,13 +1,19 @@
---
seo:
description: アカウントに対して暫定的に資格情報を発行します。
status: not_enabled
labels:
- Decentralized Storage
- Credentials
requiredAmendment: Credentials
txIcon: create
---
# CredentialCreate
CredentialCreateトランザクションは、レジャーにCredentialを作成します。Credential(資格情報)の発行者はこのトランザクションを使用して、暫定的に資格情報を発行します。Credentialは、その対象アカウントが[CredentialAcceptトランザクション][]で承認するまで有効になりません。
{% amendment-disclaimer name="Credentials" /%}
## CredentialCreate JSONの例
```json

View File

@@ -1,7 +1,11 @@
---
seo:
description: レジャーから認証情報を削除し、事実上失効させます。
status: not_enabled
labels:
- Decentralized Storage
- Credentials
requiredAmendment: Credentials
txIcon: cancel
---
# CredentialDelete

View File

@@ -2,7 +2,10 @@
seo:
description: DepositPreauthトランザクションは別のアカウントに対し、このトランザクションの送信者に支払いを送金することを事前承認します。
labels:
- セキュリティ
- Accounts
- Security
requiredAmendment: DepositPreauth
txIcon: modify
---
# DepositPreauth
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/DepositPreauth.cpp "Source")

View File

@@ -1,21 +1,20 @@
---
html: diddelete.html
parent: transaction-types.html
seo:
description: DIDを削除する。
labels:
- DID
- DID
- Decentralized Storage
requiredAmendment: DID
txIcon: cancel
---
# DIDDelete
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/DID.cpp "ソース")
_([DID Amendment][])_
指定した`Account`フィールドに関連付けられている[DIDレジャーエントリ](../../ledger-data/ledger-entry-types/did.md)を削除します。
{% admonition type="info" name="注記" %}このトランザクションは[共通フィールド][]のみ利用します。{% /admonition %}
{% amendment-disclaimer name="DID" /%}
## {% $frontmatter.seo.title %} JSONの例

View File

@@ -1,19 +1,18 @@
---
html: didset.html
parent: transaction-types.html
seo:
description: DIDを作成または更新します。
labels:
- DID
- DID
- Decentralized Storage
requiredAmendment: DID
txIcon: create
---
# DIDSet
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/DID.cpp "ソース")
_([DID Amendment][])_
新しい[DIDレジャーエントリ](../../ledger-data/ledger-entry-types/did.md)を作成したり、既存の項目を更新したりします。
{% amendment-disclaimer name="DID" /%}
## {% $frontmatter.seo.title %} JSONの例

View File

@@ -3,6 +3,9 @@ seo:
description: Escrowに留保されているXRPを送金元に返金します。
labels:
- Escrow
- Payments
requiredAmendment: Escrow
txIcon: cancel
---
# EscrowCancel
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/Escrow.cpp "Source")

View File

@@ -3,6 +3,9 @@ seo:
description: Escrowプロセスが終了または取り消されるまでXRPを隔離します。
labels:
- Escrow
- Payments
requiredAmendment: Escrow
txIcon: create
---
# EscrowCreate
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/Escrow.cpp "Source")

View File

@@ -3,6 +3,9 @@ seo:
description: エスクローされたXRPを受取人へ送金します。
labels:
- Escrow
- Payments
requiredAmendment: Escrow
txIcon: finish
---
# EscrowFinish
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/Escrow.cpp "Source")

View File

@@ -1,22 +1,40 @@
---
html: transaction-types.html
parent: transaction-formats.html
seo:
description: トランザクションのタイプは、どういったタイプの操作を実行することが想定されているのかを示します。
metadata:
indexPage: true
indexPage: true
labels:
- ブロックチェーン
- ブロックチェーン
---
# トランザクションのタイプ
トランザクションのタイプ(`TransactionType`フィールド)は、トランザクションに関する最も基本的な情報です。トランザクションで、どういったタイプの操作を実行することが想定されているのかを示します。
トランザクションのタイプ(`TransactionType`フィールド)は、どういったタイプの操作を実行することが想定されているのかを示します。すべてのトランザクションに、[共通フィールド](../common-fields.md)が含まれています。
すべてのトランザクションに、特定の共通フィールドが含まれています。
## アカウント
* [共通フィールド](../common-fields.md)
{% tx-category name="Accounts" /%}
トランザクションのタイプごとに、実行される操作のタイプに関連した追加のフィールドが含まれています。
## 支払い
{% tx-category name="Payments" /%}
## トークン
{% tx-category name="Tokens" /%}
## 分散型取引所DEX
{% tx-category name="DEX" /%}
## 分散型ストレージ
{% tx-category name="Decentralized Storage" /%}
## XRPLサイドチェーン
{% tx-category name="Interoperability" /%}
## その他
{% tx-category name="Other Transactions" /%}
{% child-pages /%}

View File

@@ -2,9 +2,11 @@
seo:
description: アカウントが特定のMPTの残高を保持することを許可します。
labels:
- Multi-Purpose Token, MPT
- Multi-purpose Tokens, MPTs
- Tokens
requiredAmendment: MPTokensV1
txIcon: modify
---
# MPTokenAuthorize
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/MPTokenAuthorize.cpp "ソース")

View File

@@ -2,7 +2,10 @@
seo:
description: 新しいMulti-Purpose Tokenを発行します。
labels:
- Multi-Purpose Token, MPT
- Multi-purpose Tokens, MPTs
- Tokens
requiredAmendment: MPTokensV1
txIcon: create
---
# MPTokenIssuanceCreate

View File

@@ -2,7 +2,10 @@
seo:
description: Multi-Purpose Tokenを削除します。
labels:
- Multi-Purpose Token, MPT
- Multi-purpose Tokens, MPTs
- Tokens
requiredAmendment: MPTokensV1
txIcon: cancel
---
# MPTokenIssuanceDestroy
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.cpp "ソース")

View File

@@ -2,7 +2,10 @@
seo:
description: MPTの変更可能なプロパティを設定します。
labels:
- Multi-Purpose Token, MPT
- Multi-purpose Tokens, MPTs
- Tokens
requiredAmendment: MPTokensV1
txIcon: modify
---
# MPTokenIssuanceSet
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/MPTokenIssuanceSet.cpp "ソース")

View File

@@ -2,7 +2,11 @@
seo:
description: NFTokenの購入または売却のオファーを受け入れる。
labels:
- NFT, 非代替性トークン
- Non-fungible Tokens, NFTs
- Tokens
- DEX
requiredAmendment: NonFungibleTokensV1_1
txIcon: finish
---
# NFTokenAcceptOffer
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/NFTokenAcceptOffer.cpp "ソース")

View File

@@ -1,10 +1,11 @@
---
html: nftokenburn.html
parent: transaction-types.html
seo:
description: TokenBurnを使用して、NFTを永久に破棄します。
labels:
- 非代替性トークン, NFT
- Non-fungible Tokens, NFTs
- Tokens
requiredAmendment: NonFungibleTokensV1_1
txIcon: cancel
---
# NFTokenBurn

View File

@@ -1,10 +1,12 @@
---
html: nftokencanceloffer.html
parent: transaction-types.html
seo:
description: NFTokenの売買のための既存のトークンへのオファーをキャンセルする。
labels:
- NFT, 非代替性トークン
- Non-fungible Tokens, NFTs
- Tokens
- DEX
requiredAmendment: NonFungibleTokensV1_1
txIcon: cancel
---
# NFTokenCancelOffer
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/NFTokenCancelOffer.cpp "ソース")

View File

@@ -1,10 +1,12 @@
---
html: nftokencreateoffer.html
parent: transaction-types.html
seo:
description: NFTの売買のオファーを作成する。
labels:
- 非代替性トークン, NFT
- Non-fungible Tokens, NFTs
- Tokens
- DEX
requiredAmendment: NonFungibleTokensV1_1
txIcon: create
---
# NFTokenCreateOffer
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/NFTokenCreateOffer.cpp "ソース")

View File

@@ -2,7 +2,10 @@
seo:
description: NFTokenMintを使用して新規NFTを発行する。
labels:
- 非代替性トークン, NFT
- Non-fungible Tokens, NFTs
- Tokens
requiredAmendment: NonFungibleTokensV1_1
txIcon: create
---
# NFTokenMint
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/NFTokenMint.cpp "Source")

View File

@@ -2,15 +2,18 @@
seo:
description: ダイナミックNFTを変更します。
labels:
- 非代替性トークン, トークン, NFT
title:
- NFTokenModify
- Non-fungible Tokens, NFTs
- Tokens
requiredAmendment: DynamicNFT
txIcon: modify
---
# NFTokenModify
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/NFTokenModify.cpp "ソース")
`NFTokenModify`は、NFTの`URI`フィールドを別のURIに変更し、NFTのサポートデータを更新するために使用されます。NFTは、`tfMutable`フラグが設定された状態でミントされている必要があります。[ダイナミックNFT](../../../../concepts/tokens/nfts/dynamic-nfts.md)をご覧ください。
{% amendment-disclaimer name="DynamicNFT" /%}
## {% $frontmatter.seo.title %} JSONの例

View File

@@ -1,16 +1,15 @@
---
html: offercancel.html
parent: transaction-types.html
seo:
description: XRP LedgerからOfferオブジェクトを削除します。
description: 分散型取引所からオファーを削除します。
labels:
- 分散型取引所
- DEX
txIcon: cancel
---
# OfferCancel
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/CancelOffer.cpp "Source")
OfferCancelトランザクションは、XRP LedgerからOfferオブジェクトを削除します。
[分散型取引所](../../../../concepts/tokens/decentralized-exchange/index.md)からオファーを削除します。
## {% $frontmatter.seo.title %}のJSONの例

View File

@@ -2,10 +2,10 @@
seo:
description: 通貨交換の注文を作成します。
labels:
- 分散型取引所
- DEX
txIcon: create
---
# OfferCreate
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/CreateOffer.cpp "ソース")
OfferCreateトランザクションは[分散型取引所](../../../../concepts/tokens/decentralized-exchange/index.md)で[注文](../../../../concepts/tokens/decentralized-exchange/offers.md)を作成します。

View File

@@ -2,15 +2,17 @@
seo:
description: 既存の価格オラクルを削除します。
labels:
- オラクル
- Oracle
- Decentralized Storage
requiredAmendment: PriceOracle
txIcon: cancel
---
# OracleDelete
_([PriceOracle Amendment][])_
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/DeleteOracle.cpp "ソース")
既存の`Oracle`レジャーエントリを削除します。
{% amendment-disclaimer name="PriceOracle" /%}
## OracleDeleteのJSONの例

View File

@@ -2,15 +2,17 @@
seo:
description: 価格オラクルを作成または更新します。
labels:
- オラクル
- Oracle
- Decentralized Storage
requiredAmendment: PriceOracle
txIcon: create
---
# OracleSet
_([PriceOracle Amendment][])_
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/SetOracle.cpp "ソース")
Oracle Document ID を使用して、新しい`Oracle`レジャーエントリを作成するか、既存のフィールドを更新します。
{% amendment-disclaimer name="PriceOracle" /%}
## OracleSetのJSONの例

View File

@@ -1,11 +1,12 @@
---
seo:
description: アカウント間での価値の移動します。
description: アカウント間での価値の移動します、またはアカウントを作成する
labels:
- 支払い
- XRP
- クロスカレンシー
- トークン
- Accounts
- Payments
- XRP
- Cross-Currency
txIcon: send
---
# Payment
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/Payment.cpp "ソース")

View File

@@ -2,7 +2,10 @@
seo:
description: Payment Channelに対しXRPを請求します。
labels:
- Payment Channel
- Payment Channels
- Payments
requiredAmendment: PayChan
txIcon: finish
---
# PaymentChannelClaim
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/PayChan.cpp "Source")

View File

@@ -2,7 +2,10 @@
seo:
description: 新しいペイメントチャネルを作成します。
labels:
- Payment Channel
- Payment Channels
- Payments
requiredAmendment: PayChan
txIcon: create
---
# PaymentChannelCreate
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/PayChan.cpp "ソース")

View File

@@ -2,7 +2,10 @@
seo:
description: Payment ChannelにXRPを追加します。
labels:
- Payment Channel
- Payment Channels
- Payments
requiredAmendment: PayChan
txIcon: modify
---
# PaymentChannelFund
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/PayChan.cpp "Source")

View File

@@ -2,15 +2,18 @@
seo:
description: 許可型ドメインのレジャーエントリを削除する
labels:
- コンプライアンス
- 許可型ドメイン
- Compliance
- Permissioned Domains
- Decentralized Storage
requiredAmendment: PermissionedDomains
txIcon: cancel
---
# PermissionedDomainDelete
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/PermissionedDomainDelete.cpp "ソース")
所有する[許可型ドメイン][]を削除します。
_([PermissionedDomains amendment][]が必要です {% not-enabled /%})_
{% amendment-disclaimer name="PermissionedDomains" /%}
## {% $frontmatter.seo.title %}のJSONの例

View File

@@ -2,15 +2,18 @@
seo:
description: 許可型ドメインを作成または更新する
labels:
- コンプライアンス
- 許可型ドメイン
- Compliance
- Permissioned Domains
- Decentralized Storage
requiredAmendment: PermissionedDomains
txIcon: create
---
# PermissionedDomainSet
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/PermissionedDomainSet.cpp "ソース")
[許可型ドメイン][]を作成するか、所有するドメインを変更します。
_([PermissionedDomains amendment][]が必要です {% not-enabled /%})_
{% amendment-disclaimer name="PermissionedDomains" /%}
## {% $frontmatter.seo.title %}のJSONの例

View File

@@ -1,10 +1,10 @@
---
html: setregularkey.html
parent: transaction-types.html
seo:
description: アカウントに関連付けられているレギュラーキーペアの割り当て、変更、削除を行います。
labels:
- セキュリティ
- Security
- Accounts
txIcon: modify
---
# SetRegularKey
@@ -29,7 +29,6 @@ labels:
{% tx-example txid="6AA6F6EAAAB56E65F7F738A9A2A8A7525439D65BA990E9BA08F6F4B1C2D349B4" /%}
{% raw-partial file="/@l10n/ja/docs/_snippets/tx-fields-intro.md" /%}
<!--{# fix md highlighting_ #}-->
| フィールド | JSONの型 | [内部の型][] | 説明 |
|:-------------|:----------|:------------------|:------------------------------|

View File

@@ -1,17 +1,19 @@
---
html: signerlistset.html
parent: transaction-types.html
seo:
description: トランザクションのマルチシグに使用できる署名者のリストを作成、置換、削除します。
labels:
- セキュリティ
- Security
- Accounts
requiredAmendment: MultiSign
txIcon: modify
---
# SignerListSet
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/SetSignerList.cpp "ソース")
SignerListSetトランザクションは、トランザクションの[マルチシグ](../../../../concepts/accounts/multi-signing.md)に使用できる署名者のリストを作成、置換、削除します。このトランザクションタイプは[MultiSign Amendment][]により導入されました。
{% amendment-disclaimer name="MultiSign" /%}
## {% $frontmatter.seo.title %}のJSONの例
```json

View File

@@ -1,19 +1,19 @@
---
html: ticketcreate.html
parent: transaction-types.html
seo:
description: チケットとして1つ以上のシーケンス番号を確保する。
labels:
- Transaction Sending
- Transaction Sending
- Accounts
requiredAmendment: TicketBatch
txIcon: create
---
# TicketCreate
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/CreateTicket.cpp "Source")
_([TicketBatch amendment][]が必要です)_
TicketCreateトランザクションは、1つまたは複数の[シーケンス番号](../../data-types/basic-data-types.md#アカウントシーケンス)を[Tickets](../../ledger-data/ledger-entry-types/ticket.md)として確保します。
{% amendment-disclaimer name="TicketBatch" /%}
## {% $frontmatter.seo.title %}JSONの例
```json
@@ -28,9 +28,6 @@ TicketCreateトランザクションは、1つまたは複数の[シーケンス
{% tx-example txid="738AEF36B48CA4A2D85C2B74910DC34DDBBCA4C83643F2DB84A58785ED5AD3E3" /%}
{% raw-partial file="/@l10n/ja/docs/_snippets/tx-fields-intro.md" /%}
<!--{# fix md highlighting_ #}-->
| フィールド | JSONの型 | [内部の型][] | 説明 |
|:-----------------|:-----------------|:------------------|:-------------------|
| `TicketCount` | 数値 | UInt32 | 作成するチケットの枚数。これは正の数でなければならず、このトランザクションの実行の結果、アカウントが250枚以上のチケットを所有することはできません。 |

View File

@@ -1,13 +1,11 @@
---
html: trustset.html
parent: transaction-types.html
seo:
description: トラストラインを作成または変更します。
labels:
- トークン
- Tokens
txIcon: modify
---
# TrustSet
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/SetTrust.cpp "Source")
2つのアカウントをリンクする[トラストライン](../../../../concepts/tokens/fungible-tokens/index.md)を作成または変更します。

View File

@@ -1,23 +1,20 @@
---
html: xchainaccountcreatecommit.html
parent: transaction-types.html
seo:
description: ブリッジが接続するチェーンの一つでアカウントを作成します。このアカウントがそのチェーンのブリッジの入り口となります。
labels:
- 相互運用性
- Interoperability
requiredAmendment: XChainBridge
status: not_enabled
txIcon: create
---
# XChainAccountCreateCommit
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/ripple/protocol/impl/TxFormats.cpp#L466-L474 "ソース")
_[XChainBridge Amendment][] {% not-enabled /%} が必要です_
このトランザクションはXRP-XRPブリッジにのみ使用できます。
`XChainAccountCreateCommit`トランザクションは、発行チェーンにトランザクションを送信するために、Witnessサーバ用の新しいアカウントを作成します。
発行チェーンにトランザクションを送信するために、Witnessサーバ用の新しいアカウントを作成します。このトランザクションはXRP-XRPブリッジにのみ使用できます。
{% admonition type="warning" name="注意" %}このトランザクションは、Witnessの証明書が送信先チェーンに確実に送信される場合にのみ実行されるべきです。署名が送信されない場合、証明書が受信されるまでアカウント作成はブロックされます。XRP-XRPブリッジでこのトランザクションを無効にするには、ブリッジの`MinAccountCreateAmount`フィールドを省略します。{% /admonition %}
{% amendment-disclaimer name="XChainBridge" /%}
## XChainAccountCreateCommit JSONの例

View File

@@ -1,18 +1,16 @@
---
html: xchainaddaccountcreateattestation.html
parent: transaction-types.html
seo:
description: XChainAddAccountCreateAttestationトランザクションは他のチェーンでXChainAccountCreateCommitトランザクションが発生した証明をWitnessサーバから提示します。
labels:
- 相互運用性
- Interoperability
requiredAmendment: XChainBridge
status: not_enabled
txIcon: create
---
# XChainAddAccountCreateAttestation
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/ripple/protocol/impl/TxFormats.cpp#L447-L464 "ソース")
_[XChainBridge Amendment][] {% not-enabled /%} が必要です_
`XChainAddAccountCreateAttestation`トランザクションは、`XChainAccountCreateCommit`トランザクションがもう一方のチェーンで発生したというWitnessサーバからの証明を提示します。
`XChainAccountCreateCommit`トランザクションがもう一方のチェーンで発生したというWitnessサーバからの証明を提示します。
この署名は署名が提供された時点のドアの署名者リストにある鍵の一つでなければなりません。署名が提出されてから定足数に達するまでの間に署名者リストが変更された場合、新しい署名セットが使用され、現在収集されている署名の一部が削除される可能性があります。
@@ -20,6 +18,7 @@ _[XChainBridge Amendment][] {% not-enabled /%} が必要です_
{% admonition type="info" name="注記" %}報酬は現在のリストにある鍵を持っているアカウントにのみ送られます。署名者の定足数は`SignatureReward`に一致する必要があります。より大きな報酬を得ようとして、一つのWitnessサーバがこの値に不正な値を指定することはできません。{% /admonition %}
{% amendment-disclaimer name="XChainBridge" /%}
## XChainAddAccountCreateAttestation JSONの例

View File

@@ -1,18 +1,16 @@
---
html: xchainaddclaimattestation.html
parent: transaction-types.html
seo:
description: 送信元チェーンで発生したイベントを、送信先チェーンに証明(アテスト)します。
labels:
- 相互運用性
- Interoperability
requiredAmendment: XChainBridge
status: not_enabled
txIcon: modify
---
# XChainAddClaimAttestation
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/ripple/protocol/impl/TxFormats.cpp#L429-L445 "ソース")
_[XChainBridge Amendment][] {% not-enabled /%} が必要です_
`XChainAddClaimAttestation`トランザクションは`XChainCommit`トランザクションを証明するWitnessサーバの署名を提供します。
`XChainCommit`トランザクションを証明するWitnessサーバの署名を提供します。
この署名は、署名が提出された時点のドアの署名者リストにある鍵の一つでなければなりません。ただし、署名が提出されてから定足数に達するまでの間に署名者リストが変更された場合は、新しい署名セットが使用され、現在収集されている署名の一部が削除されることがあります。
@@ -20,6 +18,7 @@ _[XChainBridge Amendment][] {% not-enabled /%} が必要です_
{% admonition type="info" name="注記" %}報酬は現在のリストにある鍵を持っているアカウントにのみ送られます。署名者の定足数は`SignatureReward`に一致する必要があります。より大きな報酬を得ようとして、一つのWitnessサーバがこの値に不正な値を指定することはできません。{% /admonition %}
{% amendment-disclaimer name="XChainBridge" /%}
## XChainAddClaimAttestation JSONの例

View File

@@ -1,21 +1,20 @@
---
html: xchainclaim.html
parent: transaction-types.html
seo:
description: 送信先チェーンで金額を請求することで、クロスチェーンでの価値移転を完了させます。
labels:
- 相互運用性
- Interoperability
requiredAmendment: XChainBridge
status: not_enabled
txIcon: finish
---
# XChainClaim
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/ripple/protocol/impl/TxFormats.cpp#L418-L427 "ソース")
_[XChainBridge Amendment][] {% not-enabled /%} が必要です_
`XChainClaim`トランザクションはクロスチェーンでの価値の移転を完了させます。`XChainClaim`トランザクションにより、ユーザは送信元チェーンでロックされた価値と同等の価値を送信先チェーンで請求することができます。ユーザは、送金元チェーンでロックされた価値に関連付けられたクロスチェーン請求ID`Account`フィールド)を所有している場合にのみ、その価値を請求することができます。ユーザは誰にでも資金を送ることができます(`Destination`フィールド)。このトランザクションが必要になるのは`XChainCommit`トランザクションで`OtherChainDestination`が指定されていない場合、または自動送金で何か問題が発生した場合のみです。
トランザクションによって送金に成功すると、対象の`XChainOwnedClaimID`レジャーオブジェクトは削除されます。これはトランザクションのリプレイを防ぎます。トランザクションが失敗した場合、`XChainOwnedClaimID`は削除されず、異なるパラメータでトランザクションを再実行できます。
{% amendment-disclaimer name="XChainBridge" /%}
## XChainClaim JSONの例

View File

@@ -1,19 +1,18 @@
---
html: xchaincommit.html
parent: transaction-types.html
seo:
description: クロスチェーンでの価値移転を開始します。
labels:
- 相互運用性
- Interoperability
requiredAmendment: XChainBridge
status: not_enabled
txIcon: send
---
# XChainCommit
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/ripple/protocol/impl/TxFormats.cpp#L408-L416 "ソース")
_[XChainBridge Amendment][] {% not-enabled /%} が必要です_
`XChainCommit`はクロスチェーン送金の2番目のステップです。`XChainCommit`は発行チェーンでラップできるようにロックチェーンで資産を保管したり、ロックチェーンで返却できるように発行チェーンでラップされた資産をバーンしたりします。
クロスチェーン送金の2番目のステップです。`XChainCommit`は発行チェーンでラップできるようにロックチェーンで資産を保管したり、ロックチェーンで返却できるように発行チェーンでラップされた資産をバーンしたりします。
{% amendment-disclaimer name="XChainBridge" /%}
## XChainCommit JSONの例

View File

@@ -1,18 +1,16 @@
---
html: xchaincreatebridge.html
parent: transaction-types.html
seo:
description: 2つのチェーン間にブリッジを作成します。
labels:
- 相互運用性
- Interoperability
requiredAmendment: XChainBridge
status: not_enabled
txIcon: create
---
# XChainCreateBridge
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/ripple/protocol/impl/TxFormats.cpp#L381-L388 "ソース")
_[XChainBridge Amendment][] {% not-enabled /%} が必要です_
`XChainCreateBridge`トランザクションは新しい`Bridge`レジャーオブジェクトを作成し、トランザクショ ンが送信されたチェーン上に新しいクロスチェーンブリッジの入り口を定義します。これにはブリッジのドアアカウントと資産に関する情報が含まれます。
新しい`Bridge`レジャーオブジェクトを作成し、トランザクショ ンが送信されたチェーン上に新しいクロスチェーンブリッジの入り口を定義します。これにはブリッジのドアアカウントと資産に関する情報が含まれます。
このトランザクションは、ロックチェーンのドアアカウントが最初に送信する必要があります。有効なブリッジをセットアップするには、Witnessサーバのセットアップに加えて、両チェーンのドアアカウントがこのトランザクションを送信しなければなりません。
@@ -20,6 +18,7 @@ _[XChainBridge Amendment][] {% not-enabled /%} が必要です_
{% admonition type="info" name="注記" %}各ドアアカウントは1つのブリッジしか持つことができません。これにより、同じ資産に対して複数のブリッジが作成され、いずれかのチェーンで資産が不一致となるのを防ぐことができます。{% /admonition %}
{% amendment-disclaimer name="XChainBridge" /%}
## XChainCreateBridge JSONの例

View File

@@ -1,23 +1,22 @@
---
html: xchaincreateclaimid.html
parent: transaction-types.html
seo:
description: クロスチェーン送金に使用するクロスチェーン請求IDを作成します。
labels:
- 相互運用性
- Interoperability
requiredAmendment: XChainBridge
status: not_enabled
txIcon: create
---
# XChainCreateClaimID
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/ripple/protocol/impl/TxFormats.cpp#L399-L406 "ソース")
_[XChainBridge Amendment][] {% not-enabled /%} が必要です_
`XChainCreateClaimID`トランザクションはクロスチェーン送金に使われる新しいクロスチェーン請求IDを作成します。クロスチェーン請求IDは*1つの*クロスチェーン送金を表します。
このトランザクションはクロスチェーン送金の最初のステップであり、送金元チェーンではなく、送金先チェーンで送信されます。
また、送金元チェーン上の資金をロックまたはバーンする送金元チェーン上のアカウントも含まれます。
{% amendment-disclaimer name="XChainBridge" /%}
## XChainCreateClaimID JSONの例

View File

@@ -1,23 +1,22 @@
---
html: xchainmodifybridge.html
parent: transaction-types.html
seo:
description: ブリッジの設定を変更します。
labels:
- 相互運用性
- Interoperability
requiredAmendment: XChainBridge
status: not_enabled
txIcon: modify
---
# XChainModifyBridge
[[ソース]](https://github.com/XRPLF/rippled/blob/develop/src/ripple/protocol/impl/TxFormats.cpp#L390-L397 "ソース")
_[XChainBridge Amendment][] {% not-enabled /%} が必要です_
`XChainModifyBridge`トランザクションでは、ブリッジ管理者がブリッジの設定を変更することができます。変更できるのは`SignatureReward``MinAccountCreateAmount`だけです。
このトランザクションはドアアカウントから送信される必要があり、Witnessサーバを管理するエンティティがこのトランザクションのために協調し、署名を提供する必要があります。この調整はレジャーの外部で行われます。
{% admonition type="info" name="注記" %}このトランザクションでブリッジの署名者リストを変更することはできません。署名者リストはドアアカウント自体にあり、署名者リストがアカウント上で変更されるのと同じ方法で変更されます(`SignerListSet`トランザクションを利用)。{% /admonition %}
{% amendment-disclaimer name="XChainBridge" /%}
## XChainModifyBridge JSONの例

View File

@@ -16,6 +16,7 @@ navbar.about: 概要
navbar.docs: ドキュメント
navbar.resources: リソース
navbar.community: コミュニティ
navbar.showcase: ショーケース
footer.about: 概要
footer.docs: ドキュメント
footer.resources: リソース

View File

@@ -1,3 +1,5 @@
// Components related to XRPL Amendment previews and statuses
import * as React from 'react'
import { Link } from '@redocly/theme/components/Link/Link'
import { useThemeHooks } from '@redocly/theme/core/hooks'

View File

@@ -0,0 +1,26 @@
// Component for {% child-pages /%} markdoc tag.
// Return a list of children of the current page.
import { useThemeHooks } from '@redocly/theme/core/hooks'
import { Link } from '@redocly/theme/components/Link/Link'
import NotEnabled from './NotEnabled'
export default function ChildPages() {
const { usePageSharedData } = useThemeHooks()
const data = usePageSharedData('index-page-items') as any[]
return (
<div className="children-display">
<ul>
{data?.map((item: any) => (
<li className="level-1" key={item.slug}>
<Link to={item.slug}>{item.title}</Link>
{
item.status === "not_enabled" ? (<NotEnabled />) : ""
}
<p className="blurb child-blurb">{item.seo?.description}</p>
</li>
))}
</ul>
</div>
)
}

View File

@@ -0,0 +1,11 @@
// Component for {% code-page-name /%} Markdoc tag.
// Returns the current page title in monospace (code) font.
// Useful in includes / templates that may be reused across pages.
export default function CodePageName(props: {
name: string
}) {
return (
<code>{props.name}</code>
)
}

View File

@@ -0,0 +1,28 @@
import { useState } from "react"
// Copyable URL component with click-to-copy functionality
export default function CopyableUrl({ url, translate }: { url: string; translate: (text: string) => string }) {
const [copied, setCopied] = useState(false)
const handleCopy = async () => {
try {
await navigator.clipboard.writeText(url)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
} catch (err) {
console.error("Failed to copy:", err)
}
}
return (
<button
type="button"
className={`quick-ref-value-btn ${copied ? "copied" : ""}`}
onClick={handleCopy}
title={copied ? translate("Copied!") : translate("Click to copy")}
>
<code className="quick-ref-value">{url}</code>
<span className="copy-icon">{copied ? "✓" : ""}</span>
</button>
)
}

View File

@@ -0,0 +1,45 @@
// Component for {% interactive-block %} markdoc tag. Used in legacy interactive
// tutorials; not recommended for new tutorials.
import * as React from 'react'
import { useLocation } from 'react-router-dom'
import dynamicReact from '@markdoc/markdoc/dist/react'
import { idify } from '../helpers'
export default function InteractiveBlock(props: {
children: React.ReactNode
label: string
steps: string[]
}) {
const stepId = idify(props.label)
const { pathname } = useLocation()
return (
// add key={pathname} to ensure old step state gets rerendered on page navigation
<div className="interactive-block" id={'interactive-' + stepId} key={pathname}>
<div className="interactive-block-inner">
<div className="breadcrumbs-wrap">
<ul
className="breadcrumb tutorial-step-crumbs"
id={'bc-ul-' + stepId}
data-steplabel={props.label}
data-stepid={stepId}
>
{props.steps?.map((step, idx) => {
const iterStepId = idify(step).toLowerCase()
let className = `breadcrumb-item bc-${iterStepId}`
if (idx > 0) className += ' disabled'
if (iterStepId === stepId) className += ' current'
return (
<li className={className} key={iterStepId}>
<a href={`#interactive-${iterStepId}`}>{step}</a>
</li>
)
})}
</ul>
</div>
<div className="interactive-block-ui">{dynamicReact(props.children, React, {})}</div>
</div>
</div>
)
}

View File

@@ -1,4 +1,5 @@
import React from 'react';
// Replaces Redocly's built-in language picker with our custom language picker component.
import styled from 'styled-components';
import { DropdownMenu } from '@redocly/theme/components/Dropdown/DropdownMenu';

View File

@@ -1,4 +1,8 @@
import * as React from "react";
import { useSearchDialog } from "@redocly/theme/core/hooks";
import { SearchDialog } from "@redocly/theme/components/Search/SearchDialog";
// Replaces the top navbar with our custom XRPL.org top navbar
import { useThemeConfig, useThemeHooks } from "@redocly/theme/core/hooks";
import { LanguagePicker } from "@redocly/theme/components/LanguagePicker/LanguagePicker";
import { slugify } from "../../helpers";
@@ -8,442 +12,151 @@ import { Search } from "@redocly/theme/components/Search/Search";
import arrowUpRight from "../../../static/img/icons/arrow-up-right-custom.svg";
import moment from "moment-timezone";
// @ts-ignore
// Import from modular components
import { AlertBanner } from "./components/AlertBanner";
import { NavLogo } from "./components/NavLogo";
import { NavItems } from "./components/NavItems";
import { NavControls, HamburgerButton } from "./controls";
import { DevelopSubmenu, UseCasesSubmenu, CommunitySubmenu, NetworkSubmenu } from "./submenus";
import { MobileMenu } from "./mobile-menu";
import { alertBanner } from "./constants/navigation";
const alertBanner = {
show: false,
message: "APEX 2025",
button: "REGISTER",
link: "https://www.xrpledgerapex.com/?utm_source=xrplwebsite&utm_medium=direct&utm_campaign=xrpl-event-ho-xrplapex-glb-2025-q1_xrplwebsite_ari_arp_bf_rsvp&utm_content=cta_btn_english_pencilbanner"
};
// Re-export AlertBanner for backwards compatibility
export { AlertBanner } from "./components/AlertBanner";
export function AlertBanner({ message, button, link, show }) {
const { useTranslate } = useThemeHooks();
const { translate } = useTranslate();
const bannerRef = React.useRef(null);
const [displayDate, setDisplayDate] = React.useState("JUNE 10-12");
React.useEffect(() => {
const calculateCountdown = () => {
// Calculate days until June 11, 2025 8AM Singapore time
// This will automatically adjust for the user's timezone
const target = moment.tz('2025-06-11 08:00:00', 'Asia/Singapore');
const now = moment();
const daysUntil = target.diff(now, 'days');
// Show countdown if event is in the future, otherwise show the provided date
let newDisplayDate = "JUNE 10-12";
if (daysUntil > 0) {
newDisplayDate = daysUntil === 1 ? 'IN 1 DAY' : `IN ${daysUntil} DAYS`;
} else if (daysUntil === 0) {
// Check if it's today
const hoursUntil = target.diff(now, 'hours');
newDisplayDate = hoursUntil > 0 ? 'TODAY' : "JUNE 10-12";
}
setDisplayDate(newDisplayDate);
};
// Calculate immediately
calculateCountdown();
// Update every hour
const interval = setInterval(calculateCountdown, 60 * 60 * 1000);
return () => clearInterval(interval);
}, []);
React.useEffect(() => {
const banner = bannerRef.current;
if (!banner) return;
const handleMouseEnter = () => {
banner.classList.add("has-hover");
};
// Attach the event listener
banner.addEventListener("mouseenter", handleMouseEnter);
// Clean up the event listener on unmount
return () => {
banner.removeEventListener("mouseenter", handleMouseEnter);
};
}, []);
if (show) {
return (
<a
href={link}
target="_blank"
ref={bannerRef}
className="top-banner fixed-top web-banner"
rel="noopener noreferrer"
aria-label="Get Tickets for the APEX 2025 Event"
>
<div className="banner-event-details">
<div className="event-info">{translate(message)}</div>
<div className="event-date">{displayDate}</div>
</div>
<div className="banner-button">
<div className="button-text">{translate(button)}</div>
<img
className="button-icon"
src={arrowUpRight}
alt="Get Tickets Icon"
/>
</div>
</a>
);
}
return null;
// Props interface for Navbar (extensible for future use)
interface NavbarProps {
className?: string;
}
export function Navbar(props) {
// const [isOpen, setIsOpen] = useMobileMenu(false);
const themeConfig = useThemeConfig();
const { useL10n } = useThemeHooks();
const { changeLanguage } = useL10n();
const menu = themeConfig.navbar?.items;
const logo = themeConfig.logo;
const { href, altText, items } = props;
const pathPrefix = "";
/**
* Main Navbar Component.
* Renders the complete navigation bar including:
* - Alert banner (when enabled)
* - Logo
* - Navigation items with desktop submenus
* - Control buttons (search, theme toggle, language)
* - Mobile menu
*/
export function Navbar(_props: NavbarProps = {}) {
const [mobileMenuOpen, setMobileMenuOpen] = React.useState(false);
const [activeSubmenu, setActiveSubmenu] = React.useState<string | null>(null);
const [closingSubmenu, setClosingSubmenu] = React.useState<string | null>(null);
const submenuTimeoutRef = React.useRef<NodeJS.Timeout | null>(null);
const closingTimeoutRef = React.useRef<NodeJS.Timeout | null>(null);
const navItems = menu.map((item, index) => {
if (item.type === "group") {
return (
<NavDropdown
key={index}
label={item.label}
labelTranslationKey={item.labelTranslationKey}
items={item.items}
pathPrefix={pathPrefix}
/>
);
} else {
return (
<NavItem key={index}>
<Link to={item.link} className="nav-link">
{item.label}
</Link>
</NavItem>
);
// Use Redocly's search dialog hook - shared across navbar and mobile menu
const { isOpen: isSearchOpen, onOpen: onSearchOpen, onClose: onSearchClose } = useSearchDialog();
const handleHamburgerClick = () => {
setMobileMenuOpen(true);
};
const handleMobileMenuClose = () => {
setMobileMenuOpen(false);
};
const handleSubmenuMouseEnter = (itemLabel: string) => {
// Clear any pending close/closing timeouts
if (submenuTimeoutRef.current) {
clearTimeout(submenuTimeoutRef.current);
submenuTimeoutRef.current = null;
}
});
if (closingTimeoutRef.current) {
clearTimeout(closingTimeoutRef.current);
closingTimeoutRef.current = null;
}
// Cancel closing state and activate the new submenu
setClosingSubmenu(null);
setActiveSubmenu(itemLabel);
};
const handleSubmenuMouseLeave = () => {
submenuTimeoutRef.current = setTimeout(() => {
// Start closing animation
const currentSubmenu = activeSubmenu;
if (currentSubmenu) {
setClosingSubmenu(currentSubmenu);
setActiveSubmenu(null);
// After animation completes (300ms), clear closing state
closingTimeoutRef.current = setTimeout(() => {
setClosingSubmenu(null);
}, 350); // Slightly longer than animation to ensure completion
}
}, 150);
};
const handleSubmenuClose = () => {
// Close submenu immediately (for keyboard navigation)
if (activeSubmenu) {
setClosingSubmenu(activeSubmenu);
setActiveSubmenu(null);
// After animation completes, clear closing state
closingTimeoutRef.current = setTimeout(() => {
setClosingSubmenu(null);
}, 350);
}
};
// Handle scroll lock when submenu is open or closing
React.useEffect(() => {
if (activeSubmenu || closingSubmenu) {
document.body.classList.add('bds-submenu-open');
} else {
document.body.classList.remove('bds-submenu-open');
}
return () => {
document.body.classList.remove('bds-submenu-open');
};
}, [activeSubmenu, closingSubmenu]);
React.useEffect(() => {
// 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 dds = $("#topnav-pages .dropdown");
const top_main_nav = document.querySelector("#top-main-nav");
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";
if (isNavbarCollapsed) {
navbarToggler?.click(); // Simulate click to toggle navbar
return () => {
if (submenuTimeoutRef.current) {
clearTimeout(submenuTimeoutRef.current);
}
if (closingTimeoutRef.current) {
clearTimeout(closingTimeoutRef.current);
}
};
const dropdownItems = document.querySelectorAll(".dropdown-item");
dropdownItems.forEach((item) => {
item.addEventListener("click", toggleNavbar);
});
// Cleanup function to remove event listeners
return () => {
dropdownItems.forEach((item) => {
item.removeEventListener("click", toggleNavbar);
});
};
}, []);
const navbarClasses = [
"bds-navbar",
alertBanner.show ? "bds-navbar--with-banner" : ""
].filter(Boolean).join(" ");
return (
<>
<AlertBanner {...alertBanner} />
<NavWrapper belowAlertBanner={alertBanner.show}>
<LogoBlock to={href} img={logo} alt={altText} />
<NavControls>
<MobileMenuIcon />
</NavControls>
<TopNavCollapsible>
<NavItems>
{navItems}
<div id="topnav-search" className="nav-item search">
<Search className="topnav-search" />
</div>
<div id="topnav-language" className="nav-item">
<LanguagePicker
onChangeLanguage={changeLanguage}
onlyIcon
alignment="end"
/>
</div>
<div id="topnav-theme" className="nav-item">
<ColorModeSwitcher />
</div>
</NavItems>
</TopNavCollapsible>
</NavWrapper>
{/* Backdrop blur overlay when submenu is open or closing */}
<div
className={`bds-submenu-backdrop ${activeSubmenu || closingSubmenu ? 'bds-submenu-backdrop--active' : ''}`}
onClick={() => setActiveSubmenu(null)}
/>
<header
className={navbarClasses}
onMouseLeave={handleSubmenuMouseLeave}
>
<div className="bds-navbar__content">
<NavLogo />
<NavItems activeSubmenu={activeSubmenu} onSubmenuEnter={handleSubmenuMouseEnter} onSubmenuClose={handleSubmenuClose} />
<NavControls onSearch={onSearchOpen} />
<HamburgerButton onClick={handleHamburgerClick} />
</div>
{/* Submenus positioned relative to navbar */}
<div onMouseEnter={() => activeSubmenu && handleSubmenuMouseEnter(activeSubmenu)}>
<DevelopSubmenu isActive={activeSubmenu === 'Develop'} isClosing={closingSubmenu === 'Develop'} onClose={handleSubmenuClose} />
<UseCasesSubmenu isActive={activeSubmenu === 'Use Cases'} isClosing={closingSubmenu === 'Use Cases'} onClose={handleSubmenuClose} />
<CommunitySubmenu isActive={activeSubmenu === 'Community'} isClosing={closingSubmenu === 'Community'} onClose={handleSubmenuClose} />
<NetworkSubmenu isActive={activeSubmenu === 'Network'} isClosing={closingSubmenu === 'Network'} onClose={handleSubmenuClose} />
</div>
</header>
<MobileMenu isOpen={mobileMenuOpen} onClose={handleMobileMenuClose} onSearch={onSearchOpen} />
{/* Render SearchDialog when open - this is the actual search modal */}
{isSearchOpen && <SearchDialog onClose={onSearchClose} />}
</>
);
}
export function TopNavCollapsible({ children }) {
return (
<div
className="collapse navbar-collapse justify-content-between"
id="top-main-nav"
>
{children}
</div>
);
}
export function NavDropdown(props) {
const { label, items, pathPrefix, labelTranslationKey } = props;
const { useTranslate } = useThemeHooks();
const { translate } = useTranslate();
const dropdownGroups = items.map((item, index) => {
if (item.items) {
const groupLinks = item.items.map((item2, index2) => {
const cls2 = item2.external
? "dropdown-item external-link"
: "dropdown-item";
let item2_href = item2.link;
if (item2_href && !item2_href.match(/^https?:/)) {
item2_href = pathPrefix + item2_href;
}
//conditional specific for brand kit
if (item2.link === "/XRPL_Brand_Kit.zip") {
return (
<a target="_blank" key={index2} href="/XRPL_Brand_Kit.zip" className={cls2}>
{translate(item2.labelTranslationKey, item2.label)}
</a>
);
}
return (
<Link key={index2} className={cls2} to={item2_href}>
{translate(item2.labelTranslationKey, item2.label)}
</Link>
);
});
const clnm = "navcol col-for-" + slugify(item.label);
return (
<div key={index} className={clnm}>
<h5 className="dropdown-item">
{translate(item.labelTranslationKey, item.label)}
</h5>
{groupLinks}
</div>
);
} else if (item.icon) {
const hero_id = "dropdown-hero-for-" + slugify(label);
const img_alt = item.label + " icon";
let hero_href = item.link;
if (hero_href && !hero_href.match(/^https?:/)) {
hero_href = pathPrefix + hero_href;
}
const splitlabel = item.label.split(" || ");
let splittranslationkey = ["", ""];
if (item.labelTranslationKey) {
splittranslationkey = item.labelTranslationKey.split(" || ");
}
const newlabel = translate(splittranslationkey[0], splitlabel[0]);
const description = translate(splittranslationkey[1], splitlabel[1]); // splitlabel[1] might be undefined, that's ok
return (
<Link
key={index}
className="dropdown-item dropdown-hero"
id={hero_id}
to={hero_href}
>
<img id={item.hero} alt={img_alt} src={item.icon} />
<div className="dropdown-hero-text">
<h4>{newlabel}</h4>
<p>{description}</p>
</div>
</Link>
);
} else {
const cls = item.external
? "dropdown-item ungrouped external-link"
: "dropdown-item ungrouped";
let item_href = item.link;
if (item_href && !item_href.match(/^https?:/)) {
item_href = pathPrefix + item_href;
}
return (
<Link key={index} className={cls} to={item_href}>
{translate(item.labelTranslationKey, item.label)}
</Link>
);
}
});
const toggler_id = "topnav_" + slugify(label);
const dd_id = "topnav_dd_" + slugify(label);
return (
<li className="nav-item dropdown">
<a
className="nav-link dropdown-toggle"
href="#"
id={toggler_id}
role="button"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
<span>{translate(labelTranslationKey, label)}</span>
</a>
<div className="dropdown-menu" aria-labelledby={toggler_id} id={dd_id}>
{dropdownGroups}
</div>
</li>
);
}
export function NavWrapper(props) {
return (
<nav
className="top-nav navbar navbar-expand-lg navbar-dark fixed-top"
style={props.belowAlertBanner ? { marginTop: "52px" } : {}}
>
{props.children}
</nav>
);
}
export function NavControls(props) {
return (
<button
className="navbar-toggler collapsed"
type="button"
data-toggle="collapse"
data-target="#top-main-nav"
aria-controls="navbarHolder"
aria-expanded="false"
aria-label="Toggle navigation"
>
{props.children}
</button>
);
}
export function MobileMenuIcon() {
return (
<span className="navbar-toggler-icon">
<div></div>
</span>
);
}
export function GetStartedButton() {
const { useTranslate } = useThemeHooks();
const { translate } = useTranslate();
return (
<Link
className="btn btn-primary"
to={"/docs/tutorials"}
style={{ height: "38px", paddingTop: "11px" }}
>
{translate("Get Started")}
</Link>
);
}
export function NavItems(props) {
return (
<ul className="nav navbar-nav" id="topnav-pages">
{props.children}
</ul>
);
}
export function NavItem(props) {
return <li className="nav-item">{props.children}</li>;
}
export function LogoBlock(props) {
const { to, img, altText } = props;
return (
<Link className="navbar-brand" to="/">
<img className="logo" alt={"XRP LEDGER"} height="40" src="data:," />
</Link>
);
}
export class ThemeToggle extends React.Component {
auto_update_theme() {
const upc = window.localStorage.getItem("user-prefers-color");
let theme = "dark"; // Default to dark theme
if (!upc) {
// User hasn't saved a preference specifically for this site; check
// the browser-level preferences.
if (
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: light)").matches
) {
theme = "light";
}
} else {
// Follow user's saved setting.
theme = upc == "light" ? "light" : "dark";
}
const disable_theme = theme == "dark" ? "light" : "dark";
document.documentElement.classList.add(theme);
document.documentElement.classList.remove(disable_theme);
}
user_choose_theme() {
const new_theme = document.documentElement.classList.contains("dark")
? "light"
: "dark";
window.localStorage.setItem("user-prefers-color", new_theme);
document.body.style.transition = "background-color .2s ease";
const disable_theme = new_theme == "dark" ? "light" : "dark";
document.documentElement.classList.add(new_theme);
document.documentElement.classList.remove(disable_theme);
}
render() {
return (
<div className="nav-item" id="topnav-theme">
<form className="form-inline">
<div
className="custom-control custom-theme-toggle form-inline-item"
title=""
data-toggle="tooltip"
data-placement="left"
data-original-title="Toggle Dark Mode"
>
<input
type="checkbox"
className="custom-control-input"
id="css-toggle-btn"
onClick={this.user_choose_theme}
/>
<label className="custom-control-label" htmlFor="css-toggle-btn">
<span className="d-lg-none">Light/Dark Theme</span>
</label>
</div>
</form>
</div>
);
}
componentDidMount() {
this.auto_update_theme();
}
}

View File

@@ -0,0 +1,82 @@
import * as React from "react";
import { useThemeHooks } from "@redocly/theme/core/hooks";
import moment from "moment-timezone";
import { arrowUpRight } from "../constants/icons";
interface AlertBannerProps {
message: string;
button: string;
link: string;
show: boolean;
}
/**
* Alert Banner Component.
* Displays a promotional banner at the top of the page.
*/
export function AlertBanner({ message, button, link, show }: AlertBannerProps) {
const { useTranslate } = useThemeHooks();
const { translate } = useTranslate();
const bannerRef = React.useRef<HTMLAnchorElement>(null);
// Use null initial state to avoid hydration mismatch - server and client both render null initially
const [displayDate, setDisplayDate] = React.useState<string | null>(null);
React.useEffect(() => {
const calculateCountdown = () => {
const target = moment.tz('2025-06-11 08:00:00', 'Asia/Singapore');
const now = moment();
const daysUntil = target.diff(now, 'days');
let newDisplayDate = "JUNE 10-12";
if (daysUntil > 0) {
newDisplayDate = daysUntil === 1 ? 'IN 1 DAY' : `IN ${daysUntil} DAYS`;
} else if (daysUntil === 0) {
const hoursUntil = target.diff(now, 'hours');
newDisplayDate = hoursUntil > 0 ? 'TODAY' : "JUNE 10-12";
}
setDisplayDate(newDisplayDate);
};
calculateCountdown();
const interval = setInterval(calculateCountdown, 60 * 60 * 1000);
return () => clearInterval(interval);
}, []);
React.useEffect(() => {
const banner = bannerRef.current;
if (!banner) return;
const handleMouseEnter = () => {
banner.classList.add("has-hover");
};
banner.addEventListener("mouseenter", handleMouseEnter);
return () => {
banner.removeEventListener("mouseenter", handleMouseEnter);
};
}, []);
if (!show) return null;
return (
<a
href={link}
target="_blank"
ref={bannerRef}
className="top-banner fixed-top web-banner"
rel="noopener noreferrer"
aria-label={translate("Get Tickets for the APEX 2025 Event")}
>
<div className="banner-event-details">
<div className="event-info">{translate(message)}</div>
<div className="event-date">{displayDate ?? translate("JUNE 10-12")}</div>
</div>
<div className="banner-button">
<div className="button-text">{translate(button)}</div>
<img className="button-icon" src={arrowUpRight} alt="" />
</div>
</a>
);
}

View File

@@ -0,0 +1,114 @@
import * as React from "react";
import { useThemeHooks } from "@redocly/theme/core/hooks";
import { BdsLink } from "../../../../shared/components/Link/Link";
import { navItems } from "../constants/navigation";
interface NavItemsProps {
activeSubmenu: string | null;
onSubmenuEnter: (itemLabel: string) => void;
onSubmenuClose?: () => void;
}
/**
* Nav Items Component.
* Centered navigation links with submenu support.
* ARIA compliant with full keyboard navigation support.
*/
export function NavItems({ activeSubmenu, onSubmenuEnter, onSubmenuClose }: NavItemsProps) {
const { useTranslate } = useThemeHooks();
const { translate } = useTranslate();
const [activeItem, setActiveItem] = React.useState<string | null>(null);
const handleMouseEnter = (itemLabel: string, hasSubmenu: boolean) => {
setActiveItem(itemLabel);
if (hasSubmenu) {
onSubmenuEnter(itemLabel);
}
};
const handleMouseLeave = (hasSubmenu: boolean) => {
if (!hasSubmenu) {
setActiveItem(null);
}
// Don't close submenu on leave - let the parent Navbar handle that
};
const handleKeyDown = (event: React.KeyboardEvent, itemLabel: string) => {
switch (event.key) {
case 'Enter':
case ' ':
event.preventDefault();
// Toggle submenu on Enter/Space
if (activeSubmenu === itemLabel) {
onSubmenuClose?.();
} else {
onSubmenuEnter(itemLabel);
}
break;
case 'Escape':
event.preventDefault();
onSubmenuClose?.();
break;
case 'Tab':
// If submenu is open and Tab is pressed (without Shift), move focus into submenu
if (activeSubmenu === itemLabel && !event.shiftKey) {
event.preventDefault();
// Focus first focusable element in submenu
const submenu = document.querySelector('.bds-submenu--active');
const firstFocusable = submenu?.querySelector<HTMLElement>('a, button');
firstFocusable?.focus();
}
break;
case 'ArrowDown':
// If submenu is open, move focus into submenu
if (activeSubmenu === itemLabel) {
event.preventDefault();
// Focus first focusable element in submenu
const submenu = document.querySelector('.bds-submenu--active');
const firstFocusable = submenu?.querySelector<HTMLElement>('a, button');
firstFocusable?.focus();
}
break;
}
};
// Sync activeItem with activeSubmenu state
React.useEffect(() => {
if (!activeSubmenu) {
setActiveItem(null);
}
}, [activeSubmenu]);
return (
<nav className="bds-navbar__items" aria-label={translate("Main navigation")}>
{navItems.map((item) => (
item.hasSubmenu ? (
<button
key={item.label}
type="button"
className={`bds-navbar__item ${activeItem === item.label || activeSubmenu === item.label ? 'bds-navbar__item--active' : ''}`}
onMouseEnter={() => handleMouseEnter(item.label, true)}
onMouseLeave={() => handleMouseLeave(true)}
onKeyDown={(e) => handleKeyDown(e, item.label)}
aria-expanded={activeSubmenu === item.label}
aria-haspopup="menu"
>
{translate(item.labelTranslationKey, item.label)}
</button>
) : (
<BdsLink
key={item.label}
href={item.href}
className={`bds-navbar__item ${activeItem === item.label ? 'bds-navbar__item--active' : ''}`}
onMouseEnter={() => handleMouseEnter(item.label, false)}
onMouseLeave={() => handleMouseLeave(false)}
variant="inline"
>
{translate(item.labelTranslationKey, item.label)}
</BdsLink>
)
))}
</nav>
);
}

View File

@@ -0,0 +1,34 @@
import { useThemeHooks } from "@redocly/theme/core/hooks";
import { BdsLink } from "../../../../shared/components/Link/Link";
import { xrpSymbolBlack, xrpLogotypeBlack, xrpLedgerNav } from "../constants/icons";
/**
* Nav Logo Component.
* Shows symbol on desktop/mobile, full logotype on tablet.
* On desktop hover, the "XRP LEDGER" text animates out to the right.
*/
export function NavLogo() {
const { useTranslate } = useThemeHooks();
const { translate } = useTranslate();
return (
<BdsLink href="/" className="bds-navbar__logo" aria-label={translate("XRP Ledger Home")} variant="inline">
<img
src={xrpSymbolBlack}
alt={translate("XRP Ledger")}
className="bds-navbar__logo-symbol"
/>
<img
src={xrpLedgerNav}
alt=""
className="bds-navbar__logo-text"
/>
<img
src={xrpLogotypeBlack}
alt={translate("XRP Ledger")}
className="bds-navbar__logo-full"
/>
</BdsLink>
);
}

View File

@@ -0,0 +1,5 @@
// Re-export navbar components
export { AlertBanner } from './AlertBanner';
export { NavLogo } from './NavLogo';
export { NavItems } from './NavItems';

View File

@@ -0,0 +1,71 @@
// Navbar icon imports
// Main navbar icons
export { default as xrpSymbolBlack } from "../../../../static/img/navbar/xrp-symbol-black.svg";
export { default as xrpLogotypeBlack } from "../../../../static/img/navbar/xrp-logotype-black.svg";
export { default as xrpLedgerNav } from "../../../../static/img/navbar/xrp-ledger-nav.svg";
export { default as searchIcon } from "../../../../static/img/navbar/search-icon.svg";
export { default as modeToggleIcon } from "../../../../static/img/navbar/mode-toggle.svg";
export { default as globeIcon } from "../../../../static/img/navbar/globe-icon.svg";
export { default as chevronDown } from "../../../../static/img/navbar/chevron-down.svg";
export { default as hamburgerIcon } from "../../../../static/img/navbar/hamburger-icon.svg";
export { default as arrowUpRight } from "../../../../static/img/icons/arrow-up-right-custom.svg";
// Network submenu pattern images (used for both light and dark mode)
export { default as resourcesIconPattern } from "../../../../static/img/navbar/resources-icon.svg";
export { default as insightsIconPattern } from "../../../../static/img/navbar/insights-icon.svg";
// Submenu icons - imported once, exported individually and used in navIcons mapping
import devHomeIcon from "../../../../static/img/navbar/dev_home.svg";
import learnIcon from "../../../../static/img/navbar/learn.svg";
import codeSamplesIcon from "../../../../static/img/navbar/code_samples.svg";
import docsIcon from "../../../../static/img/navbar/docs.svg";
import clientLibIcon from "../../../../static/img/navbar/client_lib.svg";
import paymentsIcon from "../../../../static/img/navbar/payments.svg";
import tokenizationIcon from "../../../../static/img/navbar/tokenization.svg";
import creditIcon from "../../../../static/img/navbar/credit.svg";
import tradingIcon from "../../../../static/img/navbar/trading.svg";
import communityIcon from "../../../../static/img/navbar/community.svg";
import fundingIcon from "../../../../static/img/navbar/funding.svg";
import contributeIcon from "../../../../static/img/navbar/contribute.svg";
import ecosystemIcon from "../../../../static/img/navbar/ecosystem.svg";
import insightsIcon from "../../../../static/img/navbar/insights.svg";
import resourcesIcon from "../../../../static/img/navbar/resources.svg";
// Re-export submenu icons for direct imports
export default {
devHomeIcon,
learnIcon,
codeSamplesIcon,
docsIcon,
clientLibIcon,
paymentsIcon,
tokenizationIcon,
creditIcon,
tradingIcon,
communityIcon,
fundingIcon,
contributeIcon,
ecosystemIcon,
insightsIcon,
resourcesIcon,
};
// Dynamic icon lookup for navbar submenus
export const navIcons: Record<string, string> = {
dev_home: devHomeIcon,
learn: learnIcon,
code_samples: codeSamplesIcon,
docs: docsIcon,
client_lib: clientLibIcon,
payments: paymentsIcon,
tokenization: tokenizationIcon,
credit: creditIcon,
trading: tradingIcon,
community: communityIcon,
contribute: contributeIcon,
insights: insightsIcon,
resources: resourcesIcon,
ecosystem: ecosystemIcon,
funding: fundingIcon,
};

View File

@@ -0,0 +1,4 @@
// Re-export all constants
export * from './icons';
export * from './navigation';

View File

@@ -0,0 +1,161 @@
import type { NavItem, SubmenuItemBase, SubmenuItemWithChildren, SubmenuItem, NetworkSubmenuSection } from '../types';
// Alert Banner Configuration
export const alertBanner = {
show: false,
message: "APEX 2025",
button: "REGISTER",
link: "https://www.xrpledgerapex.com/?utm_source=xrplwebsite&utm_medium=direct&utm_campaign=xrpl-event-ho-xrplapex-glb-2025-q1_xrplwebsite_ari_arp_bf_rsvp&utm_content=cta_btn_english_pencilbanner"
};
// Main navigation items
export const navItems: NavItem[] = [
{ label: "Develop", labelTranslationKey: "navbar.develop", href: "/develop", hasSubmenu: true },
{ label: "Use Cases", labelTranslationKey: "navbar.usecases", href: "/use-cases", hasSubmenu: true },
{ label: "Community", labelTranslationKey: "navbar.community", href: "/community", hasSubmenu: true },
{ label: "Network", labelTranslationKey: "navbar.network", href: "/resources", hasSubmenu: true },
{ label: "Showcase (Temporary)", labelTranslationKey: "navbar.showcase", href: "/showcase", hasSubmenu: false },
];
// Develop submenu data structure
export const developSubmenuData: {
left: SubmenuItemBase[];
right: SubmenuItemWithChildren[];
} = {
left: [
{ label: "Developer's Home", href: "/develop", icon: "dev_home" },
{ label: "Learn", href: "https://learn.xrpl.org", icon: "learn" },
{ label: "Code Samples", href: "/resources/code-samples", icon: "code_samples" },
],
right: [
{
label: "Docs",
href: "/docs",
icon: "docs",
children: [
{ label: "API Reference", href: "/docs/references" },
{ label: "Tutorials", href: "/docs/tutorials" },
{ label: "Concepts", href: "/docs/concepts" },
{ label: "Infrastructure", href: "/docs/infrastructure" },
],
},
{
label: "Client Libraries",
href: "/docs/tutorials",
icon: "client_lib",
children: [
{ label: "JavaScript", href: "/docs/tutorials/get-started/get-started-javascript" },
{ label: "Python", href: "/docs/tutorials/get-started/get-started-python" },
{ label: "PHP", href: "/docs/tutorials/get-started/get-started-php" },
{ label: "Go", href: "/docs/tutorials/get-started/get-started-go" },
],
},
],
};
// Use Cases submenu data structure
export const useCasesSubmenuData: {
left: SubmenuItemWithChildren[];
right: SubmenuItemWithChildren[];
} = {
left: [
{
label: "Payments",
href: "/docs/use-cases/payments",
icon: "payments",
children: [
{ label: "Direct XRP Payments", href: "/docs/use-cases/payments/direct-xrp-payments" },
{ label: "Cross-currency Payments", href: "/docs/use-cases/payments/cross-currency-payments" },
{ label: "Escrow", href: "/docs/use-cases/payments/escrow" },
{ label: "Checks", href: "/docs/use-cases/payments/checks" },
],
},
{
label: "Tokenization",
href: "/docs/use-cases/tokenization",
icon: "tokenization",
children: [
{ label: "Stablecoin", href: "/docs/use-cases/tokenization/stablecoin" },
{ label: "NFT", href: "/docs/use-cases/tokenization/nft" },
],
},
],
right: [
{
label: "Credit",
href: "/docs/use-cases/credit",
icon: "credit",
children: [
{ label: "Lending", href: "/docs/use-cases/credit/lending" },
{ label: "Collateralization", href: "/docs/use-cases/credit/collateralization" },
{ label: "Sustainability", href: "/docs/use-cases/credit/sustainability" },
],
},
{
label: "Trading",
href: "/docs/use-cases/trading",
icon: "trading",
children: [
{ label: "DEX", href: "/docs/use-cases/trading/dex" },
{ label: "Permissioned Trading", href: "/docs/use-cases/trading/permissioned-trading" },
{ label: "AMM", href: "/docs/use-cases/trading/amm" },
],
},
],
};
// Community submenu data structure
export const communitySubmenuData: {
left: SubmenuItem[];
right: SubmenuItem[];
} = {
left: [
{
label: "Community",
href: "/community",
icon: "community",
children: [
{ label: "Events", href: "/community/events" },
{ label: "Blog", href: "/blog" },
],
},
{ label: "Funding", href: "/community/developer-funding", icon: "funding" },
],
right: [
{
label: "Contribute",
href: "/community/contribute",
icon: "contribute",
children: [
{ label: "Bug Bounty", href: "/blog/2020/rippled-1.5.0#bug-bounties-and-responsible-disclosures" },
{ label: "Research", href: "https://xls.xrpl.org/" },
],
},
{ label: "Ecosystem Map", href: "/about/uses", icon: "ecosystem" },
],
};
// Network submenu data
export const networkSubmenuData: NetworkSubmenuSection[] = [
{
label: "Resources",
href: "/resources",
icon: "resources",
children: [
{ label: "About", href: "/about/history" },
{ label: "XRPL Brand Kit", href: "/community/brand-kit" },
],
patternColor: 'lilac',
},
{
label: "Insights",
href: "/insights",
icon: "insights",
children: [
{ label: "Explorer", href: "https://livenet.xrpl.org" },
{ label: "Amendment Voting Status", href: "https://xrpl.org/resources/known-amendments" },
],
patternColor: 'green',
},
];

View File

@@ -0,0 +1,19 @@
import { useThemeHooks } from "@redocly/theme/core/hooks";
import { IconButton } from "./IconButton";
import { hamburgerIcon } from "../constants/icons";
interface HamburgerButtonProps {
onClick?: () => void;
}
/**
* Hamburger Menu Button Component.
* Mobile-only button that opens the mobile menu.
*/
export function HamburgerButton({ onClick }: HamburgerButtonProps) {
const { useTranslate } = useThemeHooks();
const { translate } = useTranslate();
return <IconButton icon={hamburgerIcon} ariaLabel={translate("Open menu")} className="bds-navbar__hamburger" onClick={onClick} />;
}

View File

@@ -0,0 +1,28 @@
interface IconButtonProps {
/** The icon image source */
icon: string;
/** Accessible label for the button */
ariaLabel: string;
/** Optional click handler */
onClick?: () => void;
/** CSS class name for styling variants */
className?: string;
}
/**
* Unified Icon Button component.
* Used for search, mode toggle, hamburger menu, and other icon-only buttons.
*/
export function IconButton({ icon, ariaLabel, onClick, className = "bds-navbar__icon" }: IconButtonProps) {
return (
<button
type="button"
className={className}
aria-label={ariaLabel}
onClick={onClick}
>
<img src={icon} alt="" />
</button>
);
}

View File

@@ -0,0 +1,85 @@
import * as React from "react";
import { useLanguagePicker, useThemeHooks } from "@redocly/theme/core/hooks";
interface LanguageDropdownProps {
isOpen: boolean;
onClose: () => void;
}
/**
* Language Dropdown Component.
* Displays available language options in a dropdown menu.
* Based on Figma design: dark background with rounded corners.
*/
export function LanguageDropdown({ isOpen, onClose }: LanguageDropdownProps) {
const { currentLocale, locales, setLocale } = useLanguagePicker();
const { useL10n, useTranslate } = useThemeHooks();
const { changeLanguage } = useL10n();
const { translate } = useTranslate();
const dropdownRef = React.useRef<HTMLDivElement>(null);
// Handle clicking outside to close
React.useEffect(() => {
if (!isOpen) return;
const handleClickOutside = (event: MouseEvent) => {
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
// Check if click was on the language pill (parent trigger)
const target = event.target as HTMLElement;
if (!target.closest('.bds-navbar__lang-pill')) {
onClose();
}
}
};
const handleEscape = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
onClose();
}
};
document.addEventListener('mousedown', handleClickOutside);
document.addEventListener('keydown', handleEscape);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
document.removeEventListener('keydown', handleEscape);
};
}, [isOpen, onClose]);
if (!isOpen || locales.length < 2) {
return null;
}
const handleLanguageSelect = (localeCode: string) => {
setLocale(localeCode);
changeLanguage(localeCode);
onClose();
};
return (
<div
ref={dropdownRef}
className="bds-lang-dropdown"
role="menu"
aria-label={translate("Language selection")}
>
{locales.map((locale) => {
const isActive = locale.code === currentLocale?.code;
return (
<button
key={locale.code}
type="button"
role="menuitem"
className={`bds-lang-dropdown__item ${isActive ? 'bds-lang-dropdown__item--active' : ''}`}
onClick={() => handleLanguageSelect(locale.code)}
aria-current={isActive ? 'true' : undefined}
>
{locale.name || locale.code}
</button>
);
})}
</div>
);
}

View File

@@ -0,0 +1,53 @@
import { useLanguagePicker, useThemeHooks } from "@redocly/theme/core/hooks";
import { globeIcon, chevronDown } from "../constants/icons";
interface LanguagePillProps {
onClick?: () => void;
isOpen?: boolean;
}
/**
* Get short display name for a locale code.
* e.g., "en-US" -> "En", "ja" -> "日本語"
*/
function getLocaleShortName(code: string | undefined): string {
if (!code) return "En";
// Map locale codes to short display names
const shortNames: Record<string, string> = {
"en-US": "En",
"en": "En",
"ja": "日本語",
};
return shortNames[code] || code.substring(0, 2).toUpperCase();
}
/**
* Language Pill Button Component.
* Shows current language and opens language selector.
*/
export function LanguagePill({ onClick, isOpen }: LanguagePillProps) {
const { currentLocale } = useLanguagePicker();
const { useTranslate } = useThemeHooks();
const { translate } = useTranslate();
const displayName = getLocaleShortName(currentLocale?.code);
return (
<button
type="button"
className={`bds-navbar__lang-pill ${isOpen ? 'bds-navbar__lang-pill--open' : ''}`}
aria-label={translate("Select language")}
aria-expanded={isOpen}
aria-haspopup="menu"
onClick={onClick}
>
<img src={globeIcon} alt="" className="bds-navbar__lang-pill-icon" />
<span className="bds-navbar__lang-pill-text">
<span>{displayName}</span>
<img src={chevronDown} alt="" className="bds-navbar__lang-pill-chevron" />
</span>
</button>
);
}

View File

@@ -0,0 +1,19 @@
import { useThemeHooks } from "@redocly/theme/core/hooks";
import { IconButton } from "./IconButton";
import { modeToggleIcon } from "../constants/icons";
interface ModeToggleButtonProps {
onClick?: () => void;
}
/**
* Mode Toggle Button Component.
* Icon button that toggles between light and dark mode.
*/
export function ModeToggleButton({ onClick }: ModeToggleButtonProps) {
const { useTranslate } = useThemeHooks();
const { translate } = useTranslate();
return <IconButton icon={modeToggleIcon} ariaLabel={translate("Toggle color mode")} onClick={onClick} />;
}

View File

@@ -0,0 +1,46 @@
import * as React from "react";
import { SearchButton } from "./SearchButton";
import { ModeToggleButton } from "./ModeToggleButton";
import { LanguagePill } from "./LanguagePill";
import { LanguageDropdown } from "./LanguageDropdown";
interface NavControlsProps {
onSearch?: () => void;
}
/**
* Nav Controls Component.
* Right side of the navbar containing search, mode toggle, and language selector.
*/
export function NavControls({ onSearch }: NavControlsProps) {
const [isLanguageDropdownOpen, setIsLanguageDropdownOpen] = React.useState(false);
const handleModeToggle = () => {
// Toggle between light and dark theme
const newTheme = document.documentElement.classList.contains("dark") ? "light" : "dark";
window.localStorage.setItem("user-prefers-color", newTheme);
document.body.style.transition = "background-color .2s ease";
document.documentElement.classList.remove("dark", "light");
document.documentElement.classList.add(newTheme);
};
const handleLanguageClick = () => {
setIsLanguageDropdownOpen(!isLanguageDropdownOpen);
};
const handleLanguageDropdownClose = () => {
setIsLanguageDropdownOpen(false);
};
return (
<div className="bds-navbar__controls">
<SearchButton onClick={onSearch} />
<ModeToggleButton onClick={handleModeToggle} />
<div className="bds-navbar__lang-wrapper">
<LanguagePill onClick={handleLanguageClick} isOpen={isLanguageDropdownOpen} />
<LanguageDropdown isOpen={isLanguageDropdownOpen} onClose={handleLanguageDropdownClose} />
</div>
</div>
);
}

View File

@@ -0,0 +1,19 @@
import { useThemeHooks } from "@redocly/theme/core/hooks";
import { IconButton } from "./IconButton";
import { searchIcon } from "../constants/icons";
interface SearchButtonProps {
onClick?: () => void;
}
/**
* Search Button Component.
* Icon button that triggers the search modal.
*/
export function SearchButton({ onClick }: SearchButtonProps) {
const { useTranslate } = useThemeHooks();
const { translate } = useTranslate();
return <IconButton icon={searchIcon} ariaLabel={translate("Search")} onClick={onClick} />;
}

View File

@@ -0,0 +1,11 @@
// Unified base component
export { IconButton } from './IconButton';
// Specific button implementations (use IconButton internally)
export { NavControls } from './NavControls';
export { SearchButton } from './SearchButton';
export { ModeToggleButton } from './ModeToggleButton';
export { LanguagePill } from './LanguagePill';
export { LanguageDropdown } from './LanguageDropdown';
export { HamburgerButton } from './HamburgerButton';

View File

@@ -0,0 +1,30 @@
import * as React from "react";
interface ChevronIconProps {
expanded: boolean;
}
/**
* Chevron Icon Component for Mobile Accordion
*/
export function ChevronIcon({ expanded }: ChevronIconProps) {
return (
<svg
className={`bds-mobile-menu__chevron ${expanded ? 'bds-mobile-menu__chevron--expanded' : ''}`}
width="13"
height="8"
viewBox="0 0 13 8"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1 1L6.5 6.5L12 1"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}

View File

@@ -0,0 +1,14 @@
import * as React from "react";
/**
* Close Icon Component for Mobile Menu
*/
export function CloseIcon() {
return (
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<line x1="7" y1="7" x2="21" y2="21" stroke="#141414" strokeWidth="2" strokeLinecap="round" />
<line x1="21" y1="7" x2="7" y2="21" stroke="#141414" strokeWidth="2" strokeLinecap="round" />
</svg>
);
}

View File

@@ -0,0 +1,56 @@
interface ArrowIconProps {
className?: string;
color?: string;
/**
* When true, the horizontal line has a class for CSS animation (parent links).
* When false, the full arrow is shown without animation class (child links).
*/
animated?: boolean;
}
/**
* Unified Arrow Icon component.
* - For parent links (animated=true): horizontal line animates away on hover
* - For child links (animated=false): full static arrow
*/
export function ArrowIcon({ className, color = "currentColor", animated = true }: ArrowIconProps) {
return (
<svg
className={className}
width="15"
height="14"
viewBox="0 0 26 22"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
{/* Chevron part */}
<path
d="M14.0019 1.00191L24.0015 11.0015L14.0019 21.001"
stroke={color}
strokeWidth="2"
strokeMiterlimit="10"
strokeLinecap="round"
/>
{/* Horizontal line */}
<path
d="M23.999 10.999H0"
stroke={color}
strokeWidth="2"
strokeMiterlimit="10"
strokeLinecap="round"
className={animated ? "arrow-horizontal" : undefined}
/>
</svg>
);
}
// Backwards-compatible aliases
export const SubmenuArrow = (props: Omit<ArrowIconProps, 'animated'>) => (
<ArrowIcon {...props} animated={true} />
);
export const SubmenuChildArrow = (props: Omit<ArrowIconProps, 'animated'>) => (
<ArrowIcon {...props} animated={false} />
);

View File

@@ -0,0 +1,6 @@
// Re-export all icon components
// Unified arrow icon with backwards-compatible aliases
export { ArrowIcon, SubmenuArrow, SubmenuChildArrow } from './SubmenuArrow';
export { CloseIcon } from './CloseIcon';
export { ChevronIcon } from './ChevronIcon';

View File

@@ -0,0 +1,13 @@
// Main Navbar component
export { Navbar } from './Navbar';
// Re-export types
export * from './types';
// Re-export components for advanced usage
export * from './components';
export * from './controls';
export * from './submenus';
export * from './mobile-menu';
export * from './icons';

View File

@@ -0,0 +1,215 @@
import * as React from "react";
import { useThemeHooks, useLanguagePicker } from "@redocly/theme/core/hooks";
import { BdsLink } from "../../../../shared/components/Link/Link";
import { CloseIcon, ChevronIcon } from "../icons";
import { xrpSymbolBlack, globeIcon, chevronDown, modeToggleIcon, searchIcon } from "../constants/icons";
import { navItems } from "../constants/navigation";
import { MobileMenuContent, type MobileMenuKey } from "./MobileMenuContent";
interface MobileMenuProps {
isOpen: boolean;
onClose: () => void;
onSearch?: () => void;
}
/**
* Mobile Menu Component.
* Full-screen slide-out menu for mobile devices.
*/
export function MobileMenu({ isOpen, onClose, onSearch }: MobileMenuProps) {
const { useTranslate } = useThemeHooks();
const { translate } = useTranslate();
const [expandedItem, setExpandedItem] = React.useState<string | null>("Develop");
// Handle body scroll lock
React.useEffect(() => {
if (isOpen) {
document.body.classList.add('bds-mobile-menu-open');
} else {
document.body.classList.remove('bds-mobile-menu-open');
}
return () => {
document.body.classList.remove('bds-mobile-menu-open');
};
}, [isOpen]);
const toggleAccordion = (item: string) => {
setExpandedItem(expandedItem === item ? null : item);
};
const handleSearch = () => {
if (onSearch) {
onSearch();
}
onClose();
};
const handleModeToggle = () => {
const newTheme = document.documentElement.classList.contains("dark") ? "light" : "dark";
window.localStorage.setItem("user-prefers-color", newTheme);
document.body.style.transition = "background-color .2s ease";
document.documentElement.classList.remove("dark", "light");
document.documentElement.classList.add(newTheme);
};
const renderAccordionContent = (label: string) => {
// All nav items with submenus use the unified MobileMenuContent
const validKeys: MobileMenuKey[] = ['Develop', 'Use Cases', 'Community', 'Network'];
if (validKeys.includes(label as MobileMenuKey)) {
return <MobileMenuContent menuKey={label as MobileMenuKey} />;
}
return null;
};
return (
<div className={`bds-mobile-menu ${isOpen ? 'bds-mobile-menu--open' : ''}`}>
{/* Header */}
<div className="bds-mobile-menu__header">
<BdsLink href="/" className="bds-navbar__logo" aria-label={translate("XRP Ledger Home")} onClick={onClose} variant="inline">
<img src={xrpSymbolBlack} alt={translate("XRP Ledger")} className="bds-navbar__logo-symbol" style={{ width: 33, height: 28 }} />
</BdsLink>
<button
type="button"
className="bds-mobile-menu__close"
aria-label={translate("Close menu")}
onClick={onClose}
>
<CloseIcon />
</button>
</div>
{/* Content */}
<div className="bds-mobile-menu__content">
<div className="bds-mobile-menu__accordion">
{navItems.map((item) => (
<React.Fragment key={item.label}>
<button
type="button"
className="bds-mobile-menu__accordion-header"
onClick={() => item.hasSubmenu ? toggleAccordion(item.label) : null}
aria-expanded={expandedItem === item.label}
>
{item.hasSubmenu ? (
<>
<span>{translate(item.labelTranslationKey, item.label)}</span>
<ChevronIcon expanded={expandedItem === item.label} />
</>
) : (
<BdsLink
href={item.href}
onClick={onClose}
variant="inline"
style={{
display: 'flex',
width: '100%',
justifyContent: 'space-between',
alignItems: 'center',
color: 'inherit',
textDecoration: 'none'
}}
>
<span>{translate(item.labelTranslationKey, item.label)}</span>
<ChevronIcon expanded={false} />
</BdsLink>
)}
</button>
{item.hasSubmenu && (
<div
className={`bds-mobile-menu__accordion-content ${
expandedItem === item.label ? 'bds-mobile-menu__accordion-content--expanded' : ''
}`}
>
{renderAccordionContent(item.label)}
</div>
)}
</React.Fragment>
))}
</div>
</div>
{/* Footer */}
<MobileMenuFooter
onModeToggle={handleModeToggle}
onSearch={handleSearch}
/>
</div>
);
}
interface MobileMenuFooterProps {
onModeToggle: () => void;
onSearch: () => void;
}
/**
* Get short display name for a locale code.
*/
function getLocaleShortName(code: string | undefined): string {
if (!code) return "En";
const shortNames: Record<string, string> = {
"en-US": "En",
"en": "En",
"ja": "日本語",
};
return shortNames[code] || code.substring(0, 2).toUpperCase();
}
function MobileMenuFooter({ onModeToggle, onSearch }: MobileMenuFooterProps) {
const { currentLocale, locales, setLocale } = useLanguagePicker();
const { useL10n, useTranslate } = useThemeHooks();
const { changeLanguage } = useL10n();
const { translate } = useTranslate();
const [isLangOpen, setIsLangOpen] = React.useState(false);
const displayName = getLocaleShortName(currentLocale?.code);
const handleLanguageSelect = (localeCode: string) => {
setLocale(localeCode);
changeLanguage(localeCode);
setIsLangOpen(false);
};
return (
<div className="bds-mobile-menu__footer">
<div className="bds-mobile-menu__lang-wrapper">
<button
type="button"
className={`bds-mobile-menu__lang-pill ${isLangOpen ? 'bds-mobile-menu__lang-pill--open' : ''}`}
aria-label={translate("Select language")}
aria-expanded={isLangOpen}
onClick={() => setIsLangOpen(!isLangOpen)}
>
<img src={globeIcon} alt="" className="bds-mobile-menu__lang-pill-icon" />
<span className="bds-mobile-menu__lang-pill-text">
<span>{displayName}</span>
<img src={chevronDown} alt="" className="bds-mobile-menu__lang-pill-chevron" />
</span>
</button>
{isLangOpen && locales.length >= 2 && (
<div className="bds-lang-dropdown bds-lang-dropdown--mobile" role="menu">
{locales.map((locale) => {
const isActive = locale.code === currentLocale?.code;
return (
<button
key={locale.code}
type="button"
role="menuitem"
className={`bds-lang-dropdown__item ${isActive ? 'bds-lang-dropdown__item--active' : ''}`}
onClick={() => handleLanguageSelect(locale.code)}
>
{locale.name || locale.code}
</button>
);
})}
</div>
)}
</div>
<button type="button" className="bds-mobile-menu__footer-icon" aria-label={translate("Toggle color mode")} onClick={onModeToggle}>
<img src={modeToggleIcon} alt="" />
</button>
<button type="button" className="bds-mobile-menu__footer-icon" aria-label={translate("Search")} onClick={onSearch}>
<img src={searchIcon} alt="" />
</button>
</div>
);
}

View File

@@ -0,0 +1,47 @@
import { MobileMenuSection } from "./MobileMenuSection";
import { developSubmenuData, useCasesSubmenuData, communitySubmenuData, networkSubmenuData } from "../constants/navigation";
import type { SubmenuItem, SubmenuItemWithChildren, NetworkSubmenuSection } from "../types";
export type MobileMenuKey = 'Develop' | 'Use Cases' | 'Community' | 'Network';
interface MobileMenuContentProps {
/** Which menu section to render */
menuKey: MobileMenuKey;
}
/** Get flattened menu items based on menu key */
function getMenuItems(menuKey: MobileMenuKey): (SubmenuItem | SubmenuItemWithChildren | NetworkSubmenuSection)[] {
switch (menuKey) {
case 'Develop':
return [...developSubmenuData.left, ...developSubmenuData.right];
case 'Use Cases':
return [...useCasesSubmenuData.left, ...useCasesSubmenuData.right];
case 'Community':
return [...communitySubmenuData.left, ...communitySubmenuData.right];
case 'Network':
return networkSubmenuData;
}
}
/**
* Unified Mobile Menu Content component.
* Renders accordion content for any menu section.
*/
export function MobileMenuContent({ menuKey }: MobileMenuContentProps) {
const items = getMenuItems(menuKey);
return (
<div className="bds-mobile-menu__tier-list">
{items.map((item) => (
<MobileMenuSection key={item.label} item={item} />
))}
</div>
);
}
// Backwards-compatible named exports
export const MobileMenuDevelopContent = () => <MobileMenuContent menuKey="Develop" />;
export const MobileMenuUseCasesContent = () => <MobileMenuContent menuKey="Use Cases" />;
export const MobileMenuCommunityContent = () => <MobileMenuContent menuKey="Community" />;
export const MobileMenuNetworkContent = () => <MobileMenuContent menuKey="Network" />;

View File

@@ -0,0 +1,54 @@
import * as React from "react";
import { useThemeHooks } from "@redocly/theme/core/hooks";
import { SubmenuArrow, SubmenuChildArrow } from "../icons";
import { navIcons } from "../constants/icons";
import { hasChildren, type SubmenuItem } from "../types";
interface MobileMenuSectionProps {
item: SubmenuItem;
}
/**
* Reusable mobile menu section component.
* Renders a parent link with icon, and optionally child links.
*/
export function MobileMenuSection({ item }: MobileMenuSectionProps) {
const { useTranslate } = useThemeHooks();
const { translate } = useTranslate();
const itemHasChildren = hasChildren(item);
return (
<React.Fragment>
<a href={item.href} className="bds-mobile-menu__tier1 bds-mobile-menu__parent-link">
<span className="bds-mobile-menu__icon">
<img src={navIcons[item.icon]} alt={translate(item.label)} />
</span>
<span className="bds-mobile-menu__link bds-mobile-menu__link--bold">
{translate(item.label)}
<span className="bds-mobile-menu__arrow">
<SubmenuArrow />
</span>
</span>
</a>
{itemHasChildren && (
<div className="bds-mobile-menu__tier2">
{item.children.map((child) => (
<a
key={child.label}
href={child.href}
className="bds-mobile-menu__sublink"
target={child.href.startsWith('http') ? '_blank' : undefined}
rel={child.href.startsWith('http') ? 'noopener noreferrer' : undefined}
>
{translate(child.label)}
<span className="bds-mobile-menu__sublink-arrow">
<SubmenuChildArrow />
</span>
</a>
))}
</div>
)}
</React.Fragment>
);
}

View File

@@ -0,0 +1,16 @@
// Main mobile menu component
export { MobileMenu } from './MobileMenu';
// Unified content component with backwards-compatible aliases
export {
MobileMenuContent,
MobileMenuDevelopContent,
MobileMenuUseCasesContent,
MobileMenuCommunityContent,
MobileMenuNetworkContent,
type MobileMenuKey
} from './MobileMenuContent';
// Reusable section component
export { MobileMenuSection } from './MobileMenuSection';

View File

@@ -0,0 +1,16 @@
import { Submenu } from "./Submenu";
interface CommunitySubmenuProps {
isActive: boolean;
isClosing: boolean;
onClose?: () => void;
}
/**
* Desktop Community Submenu Component.
* Wrapper for unified Submenu component with 'community' variant.
*/
export function CommunitySubmenu({ isActive, isClosing, onClose }: CommunitySubmenuProps) {
return <Submenu variant="community" isActive={isActive} isClosing={isClosing} onClose={onClose} />;
}

View File

@@ -0,0 +1,16 @@
import { Submenu } from "./Submenu";
interface DevelopSubmenuProps {
isActive: boolean;
isClosing: boolean;
onClose?: () => void;
}
/**
* Desktop Develop Submenu Component.
* Wrapper for unified Submenu component with 'develop' variant.
*/
export function DevelopSubmenu({ isActive, isClosing, onClose }: DevelopSubmenuProps) {
return <Submenu variant="develop" isActive={isActive} isClosing={isClosing} onClose={onClose} />;
}

View File

@@ -0,0 +1,16 @@
import { Submenu } from "./Submenu";
interface NetworkSubmenuProps {
isActive: boolean;
isClosing: boolean;
onClose?: () => void;
}
/**
* Desktop Network Submenu Component.
* Wrapper for unified Submenu component with 'network' variant.
*/
export function NetworkSubmenu({ isActive, isClosing, onClose }: NetworkSubmenuProps) {
return <Submenu variant="network" isActive={isActive} isClosing={isClosing} onClose={onClose} />;
}

View File

@@ -0,0 +1,277 @@
import * as React from "react";
import { useThemeHooks } from "@redocly/theme/core/hooks";
import { SubmenuSection } from "./SubmenuSection";
import { ArrowIcon } from "../icons";
import { navIcons, resourcesIconPattern, insightsIconPattern } from "../constants/icons";
import { developSubmenuData, useCasesSubmenuData, communitySubmenuData, networkSubmenuData } from "../constants/navigation";
import type { SubmenuItem, SubmenuItemWithChildren, NetworkSubmenuSection } from "../types";
export type SubmenuVariant = 'develop' | 'use-cases' | 'community' | 'network';
interface SubmenuProps {
/** Which submenu variant to render */
variant: SubmenuVariant;
/** Whether this submenu is currently active (visible) */
isActive: boolean;
/** Whether this submenu is in closing animation */
isClosing: boolean;
/** Callback when submenu should close (e.g., Escape key) */
onClose?: () => void;
}
/** Get submenu data based on variant */
function getSubmenuData(variant: SubmenuVariant) {
switch (variant) {
case 'develop': return developSubmenuData;
case 'use-cases': return useCasesSubmenuData;
case 'community': return communitySubmenuData;
case 'network': return networkSubmenuData;
}
}
/** Get CSS modifier class for variant */
function getVariantClass(variant: SubmenuVariant): string {
if (variant === 'develop') return '';
return `bds-submenu--${variant}`;
}
/**
* Get all focusable elements within a container
*/
function getFocusableElements(container: HTMLElement | null): HTMLElement[] {
if (!container) return [];
return Array.from(
container.querySelectorAll<HTMLElement>('a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])')
);
}
/**
* Find the next nav item button after the current expanded one
*/
function getNextNavItem(): HTMLElement | null {
const navItems = document.querySelectorAll<HTMLElement>('.bds-navbar__item');
const currentIndex = Array.from(navItems).findIndex(item =>
item.getAttribute('aria-expanded') === 'true'
);
if (currentIndex >= 0 && currentIndex < navItems.length - 1) {
return navItems[currentIndex + 1];
}
// If at the last nav item, go to the first control button (search, etc.)
const controls = document.querySelector<HTMLElement>('.bds-navbar__controls button, .bds-navbar__controls a');
return controls;
}
/**
* Unified Submenu component.
* Handles all submenu variants (develop, use-cases, community, network).
* ARIA compliant with full keyboard navigation support.
*/
export function Submenu({ variant, isActive, isClosing, onClose }: SubmenuProps) {
const submenuRef = React.useRef<HTMLDivElement>(null);
// Handle keyboard events for accessibility
const handleKeyDown = React.useCallback((event: KeyboardEvent) => {
if (!isActive) return;
if (event.key === 'Escape') {
event.preventDefault();
onClose?.();
// Return focus to the trigger button
const triggerButton = document.querySelector<HTMLButtonElement>(
`.bds-navbar__item[aria-expanded="true"]`
);
triggerButton?.focus();
}
// Handle Tab at end of submenu - move to next nav item
if (event.key === 'Tab' && !event.shiftKey) {
const activeSubmenu = document.querySelector<HTMLElement>('.bds-submenu--active');
const focusableElements = getFocusableElements(activeSubmenu);
const lastFocusable = focusableElements[focusableElements.length - 1];
if (document.activeElement === lastFocusable) {
event.preventDefault();
onClose?.();
const nextItem = getNextNavItem();
nextItem?.focus();
}
}
// Handle Shift+Tab at start of submenu - move back to trigger button
if (event.key === 'Tab' && event.shiftKey) {
const activeSubmenu = document.querySelector<HTMLElement>('.bds-submenu--active');
const focusableElements = getFocusableElements(activeSubmenu);
const firstFocusable = focusableElements[0];
if (document.activeElement === firstFocusable) {
event.preventDefault();
onClose?.();
// Return focus to the trigger button
const triggerButton = document.querySelector<HTMLButtonElement>(
`.bds-navbar__item[aria-expanded="true"]`
);
triggerButton?.focus();
}
}
}, [isActive, onClose]);
// Add keyboard event listener when submenu is active
React.useEffect(() => {
if (isActive) {
document.addEventListener('keydown', handleKeyDown);
return () => document.removeEventListener('keydown', handleKeyDown);
}
}, [isActive, handleKeyDown]);
// Network submenu needs special handling for theme-aware patterns
if (variant === 'network') {
return <NetworkSubmenuContent isActive={isActive} isClosing={isClosing} onClose={onClose} />;
}
const data = getSubmenuData(variant);
const classNames = [
'bds-submenu',
getVariantClass(variant),
isActive ? 'bds-submenu--active' : '',
isClosing ? 'bds-submenu--closing' : '',
].filter(Boolean).join(' ');
// Standard two-column layout
const leftItems = 'left' in data ? data.left : [];
const rightItems = 'right' in data ? data.right : [];
return (
<div
ref={submenuRef}
className={classNames}
role="menu"
aria-hidden={!isActive}
>
<div className="bds-submenu__left">
{leftItems.map((item: SubmenuItem | SubmenuItemWithChildren) => (
<SubmenuSection key={item.label} item={item} />
))}
</div>
<div className="bds-submenu__right">
{rightItems.map((item: SubmenuItem | SubmenuItemWithChildren) => (
<SubmenuSection key={item.label} item={item} />
))}
</div>
</div>
);
}
/** Network submenu with pattern images (same for light and dark mode) */
function NetworkSubmenuContent({ isActive, isClosing, onClose }: { isActive: boolean; isClosing: boolean; onClose?: () => void }) {
const { useTranslate } = useThemeHooks();
const { translate } = useTranslate();
// Handle keyboard events for accessibility
const handleKeyDown = React.useCallback((event: KeyboardEvent) => {
if (!isActive) return;
if (event.key === 'Escape') {
event.preventDefault();
onClose?.();
// Return focus to the trigger button
const triggerButton = document.querySelector<HTMLButtonElement>(
`.bds-navbar__item[aria-expanded="true"]`
);
triggerButton?.focus();
}
// Handle Tab at end of submenu - move to next nav item
if (event.key === 'Tab' && !event.shiftKey) {
const activeSubmenu = document.querySelector<HTMLElement>('.bds-submenu--active');
const focusableElements = getFocusableElements(activeSubmenu);
const lastFocusable = focusableElements[focusableElements.length - 1];
if (document.activeElement === lastFocusable) {
event.preventDefault();
onClose?.();
const nextItem = getNextNavItem();
nextItem?.focus();
}
}
// Handle Shift+Tab at start of submenu - move back to trigger button
if (event.key === 'Tab' && event.shiftKey) {
const activeSubmenu = document.querySelector<HTMLElement>('.bds-submenu--active');
const focusableElements = getFocusableElements(activeSubmenu);
const firstFocusable = focusableElements[0];
if (document.activeElement === firstFocusable) {
event.preventDefault();
onClose?.();
// Return focus to the trigger button
const triggerButton = document.querySelector<HTMLButtonElement>(
`.bds-navbar__item[aria-expanded="true"]`
);
triggerButton?.focus();
}
}
}, [isActive, onClose]);
// Add keyboard event listener when submenu is active
React.useEffect(() => {
if (isActive) {
document.addEventListener('keydown', handleKeyDown);
return () => document.removeEventListener('keydown', handleKeyDown);
}
}, [isActive, handleKeyDown]);
// Use same pattern images for both light and dark mode
const patternImages = {
lilac: resourcesIconPattern,
green: insightsIconPattern,
};
const classNames = [
'bds-submenu',
'bds-submenu--network',
isActive ? 'bds-submenu--active' : '',
isClosing ? 'bds-submenu--closing' : '',
].filter(Boolean).join(' ');
return (
<div className={classNames} role="menu" aria-hidden={!isActive}>
{networkSubmenuData.map((section: NetworkSubmenuSection) => (
<div key={section.label} className="bds-submenu__section">
<a href={section.href} className="bds-submenu__tier1 bds-submenu__parent-link">
<span className="bds-submenu__icon">
<img src={navIcons[section.icon]} alt={translate(section.label)} />
</span>
<span className="bds-submenu__link bds-submenu__link--bold">
{translate(section.label)}
<span className="bds-submenu__arrow">
<ArrowIcon animated />
</span>
</span>
</a>
<div className="bds-submenu__network-content">
<div className="bds-submenu__tier2">
{section.children.map((child) => (
<a
key={child.label}
href={child.href}
className="bds-submenu__sublink"
target={child.href.startsWith('http') ? '_blank' : undefined}
rel={child.href.startsWith('http') ? 'noopener noreferrer' : undefined}
>
{translate(child.label)}
<span className="bds-submenu__sublink-arrow">
<ArrowIcon animated={false} />
</span>
</a>
))}
</div>
<div className="bds-submenu__pattern-container">
<img src={patternImages[section.patternColor]} alt="" className="bds-submenu__pattern" />
</div>
</div>
</div>
))}
</div>
);
}

View File

@@ -0,0 +1,70 @@
import { useThemeHooks } from "@redocly/theme/core/hooks";
import { ArrowIcon } from "../icons";
import { navIcons } from "../constants/icons";
import { hasChildren, type SubmenuItem, type SubmenuItemWithChildren, type SubmenuItemBase } from "../types";
interface SubmenuSectionProps {
/** The menu item data */
item: SubmenuItem | SubmenuItemWithChildren | SubmenuItemBase;
/** Whether to render children links (default: true) */
showChildren?: boolean;
}
/**
* Unified submenu section component.
* Renders a parent link with icon, and optionally child links if the item has them.
*
* Usage:
* - For items that may or may not have children: <SubmenuSection item={item} />
* - For parent-only rendering: <SubmenuSection item={item} showChildren={false} />
*/
export function SubmenuSection({ item, showChildren = true }: SubmenuSectionProps) {
const { useTranslate } = useThemeHooks();
const { translate } = useTranslate();
const itemHasChildren = hasChildren(item as SubmenuItem);
const shouldShowChildren = showChildren && itemHasChildren;
return (
<div className="bds-submenu__section">
<a href={item.href} className="bds-submenu__tier1 bds-submenu__parent-link">
<span className="bds-submenu__icon">
<img src={navIcons[item.icon]} alt={translate(item.label)} />
</span>
<span className="bds-submenu__link bds-submenu__link--bold">
{translate(item.label)}
<span className="bds-submenu__arrow">
<ArrowIcon animated />
</span>
</span>
</a>
{shouldShowChildren && (
<div className="bds-submenu__tier2">
{(item as SubmenuItemWithChildren).children.map((child) => (
<a
key={child.label}
href={child.href}
className="bds-submenu__sublink"
target={child.href.startsWith('http') ? '_blank' : undefined}
rel={child.href.startsWith('http') ? 'noopener noreferrer' : undefined}
>
{translate(child.label)}
<span className="bds-submenu__sublink-arrow">
<ArrowIcon animated={false} />
</span>
</a>
))}
</div>
)}
</div>
);
}
// Backwards-compatible aliases (all use the unified SubmenuSection)
export const SubmenuParentOnly = ({ item }: { item: SubmenuItemBase }) => (
<SubmenuSection item={item} showChildren={false} />
);
export const SubmenuWithChildren = ({ item }: { item: SubmenuItemWithChildren }) => (
<SubmenuSection item={item} showChildren={true} />
);

View File

@@ -0,0 +1,16 @@
import { Submenu } from "./Submenu";
interface UseCasesSubmenuProps {
isActive: boolean;
isClosing: boolean;
onClose?: () => void;
}
/**
* Desktop Use Cases Submenu Component.
* Wrapper for unified Submenu component with 'use-cases' variant.
*/
export function UseCasesSubmenu({ isActive, isClosing, onClose }: UseCasesSubmenuProps) {
return <Submenu variant="use-cases" isActive={isActive} isClosing={isClosing} onClose={onClose} />;
}

Some files were not shown because too many files have changed in this diff Show More