Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/bundler-cadence-json.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@onflow/fcl-bundle": minor
---

Add support for importing `.cdc` (Cadence) and `.json` files in bundled packages. Cadence files are imported as raw strings, enabling packages to include Cadence scripts as separate files rather than inline template strings.

3,732 changes: 257 additions & 3,475 deletions package-lock.json

Large diffs are not rendered by default.

162 changes: 162 additions & 0 deletions packages/demo/src/components/component-cards/fund-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import {useState} from "react"
import {Fund, useFlowChainId} from "@onflow/react-sdk"
import {useDarkMode} from "../flow-provider-wrapper"
import {DemoCard, type PropDefinition} from "../ui/demo-card"
import {PlusGridIcon} from "../ui/plus-grid"

const IMPLEMENTATION_CODE = `import { Fund } from "@onflow/react-sdk"

// Basic usage - opens modal with funding options
<Fund />

// With custom variant
<Fund variant="secondary" />`

const PROPS: PropDefinition[] = [
{
name: "variant",
type: '"primary" | "secondary" | "outline" | "link"',
required: false,
description: "The visual style variant of the fund button",
defaultValue: '"primary"',
},
]

export function FundCard() {
const {darkMode} = useDarkMode()
const {data: chainId, isLoading} = useFlowChainId()
const [variant, setVariant] = useState<
"primary" | "secondary" | "outline" | "link"
>("primary")

return (
<DemoCard
id="fund"
title="<Fund />"
description="The Fund Account component provides users with a simple, unified way to bring liquidity into the Flow ecosystem, supporting both Flow EVM and Cadence accounts. It streamlines the process of funding a user wallet by offering two clear on-ramps."
code={IMPLEMENTATION_CODE}
props={PROPS}
>
<div className="space-y-6">
<div className="grid grid-cols-3 gap-4">
<div
className={`relative p-4 rounded-lg border ${
darkMode
? "bg-gray-900/50 border-white/10"
: "bg-gray-50 border-black/5"
}`}
>
<PlusGridIcon placement="top left" className="absolute" />
<h4
className={`text-xs font-medium mb-1 ${darkMode ? "text-gray-500" : "text-gray-500"}`}
>
Unified Interface
</h4>
<p className={`text-sm ${darkMode ? "text-white" : "text-black"}`}>
Single component for all funding
</p>
</div>

<div
className={`relative p-4 rounded-lg border ${
darkMode
? "bg-gray-900/50 border-white/10"
: "bg-gray-50 border-black/5"
}`}
>
<PlusGridIcon placement="top right" className="absolute" />
<h4
className={`text-xs font-medium mb-1 ${darkMode ? "text-gray-500" : "text-gray-500"}`}
>
Cross-VM Support
</h4>
<p className={`text-sm ${darkMode ? "text-white" : "text-black"}`}>
Flow EVM & Cadence accounts
</p>
</div>

<div
className={`relative p-4 rounded-lg border ${
darkMode
? "bg-gray-900/50 border-white/10"
: "bg-gray-50 border-black/5"
}`}
>
<PlusGridIcon placement="bottom left" className="absolute" />
<h4
className={`text-xs font-medium mb-1 ${darkMode ? "text-gray-500" : "text-gray-500"}`}
>
Streamlined Flow
</h4>
<p
className={`text-xs ${darkMode ? "text-gray-400" : "text-gray-600"}`}
>
Simple on-ramp experience
</p>
</div>
</div>

<div className="flex gap-4">
<div
className={`relative flex-1 rounded-lg border flex items-center justify-center ${
darkMode
? "bg-gray-900/50 border-white/10"
: "bg-gray-50 border-black/5"
}`}
>
{isLoading ? (
<div className="text-center py-12">
<div
className={`inline-block animate-spin rounded-full h-8 w-8 border-b-2 ${
darkMode ? "border-white" : "border-black" }`}
></div>
</div>
) : (
<div className="w-full p-6 flex items-center justify-center">
<Fund variant={variant} />
</div>
)}
</div>

<div
className={`w-56 p-4 rounded-lg border space-y-4 ${
darkMode
? "bg-gray-900/50 border-white/10"
: "bg-gray-50 border-black/5"
}`}
>
<div>
<label
className={`text-xs font-medium mb-2 block ${darkMode ? "text-gray-500" : "text-gray-500"}`}
>
Variant
</label>
<div className="space-y-1.5">
{(["primary", "secondary", "outline", "link"] as const).map(
variantOption => (
<button
key={variantOption}
onClick={() => setVariant(variantOption)}
className={`w-full text-sm px-3 py-2 rounded-lg transition-colors text-left ${
variant === variantOption
? darkMode
? "bg-blue-600 hover:bg-blue-700 text-white"
: "bg-blue-500 hover:bg-blue-600 text-white"
: darkMode
? "bg-gray-800 hover:bg-gray-700 text-white"
: "bg-white hover:bg-gray-100 text-black border border-black/10"
}`}
>
{variantOption.charAt(0).toUpperCase() +
variantOption.slice(1)}
</button>
)
)}
</div>
</div>
</div>
</div>
</div>
</DemoCard>
)
}
2 changes: 2 additions & 0 deletions packages/demo/src/components/content-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {ThemingCard} from "./advanced-cards/theming-card"
// Import component cards
import {ConnectCard} from "./component-cards/connect-card"
import {ProfileCard} from "./component-cards/profile-card"
import {FundCard} from "./component-cards/fund-card"
import {TransactionButtonCard} from "./component-cards/transaction-button-card"
import {TransactionDialogCard} from "./component-cards/transaction-dialog-card"
import {TransactionLinkCard} from "./component-cards/transaction-link-card"
Expand Down Expand Up @@ -70,6 +71,7 @@ export function ContentSection() {

<ConnectCard />
<ProfileCard />
<FundCard />
<TransactionButtonCard />
<TransactionDialogCard />
<TransactionLinkCard />
Expand Down
6 changes: 6 additions & 0 deletions packages/demo/src/components/content-sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ const sidebarItems: SidebarItem[] = [
category: "components",
description: "Standalone profile display",
},
{
id: "fund",
label: "Fund",
category: "components",
description: "Account funding component",
},
{
id: "transactionbutton",
label: "Transaction Button",
Expand Down
1 change: 1 addition & 0 deletions packages/fcl-bundle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-commonjs": "^28.0.1",
"@rollup/plugin-image": "^3.0.3",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.3.0",
"@rollup/plugin-replace": "^6.0.1",
"@rollup/plugin-terser": "^0.4.4",
Expand Down
5 changes: 5 additions & 0 deletions packages/fcl-bundle/src/build/get-input-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ const terser = require("@rollup/plugin-terser")
const typescript = require("rollup-plugin-typescript2")
const postcss = require("rollup-plugin-postcss")
const imagePlugin = require("@rollup/plugin-image")
const json = require("@rollup/plugin-json")
const {DEFAULT_EXTENSIONS} = require("@babel/core")
const {getPackageRoot} = require("../util")
const {preserveDirective} = require("rollup-preserve-directives")
const cadence = require("../plugins/cadence")

const SUPPRESSED_WARNING_CODES = [
"MISSING_GLOBAL_NAME",
Expand Down Expand Up @@ -68,6 +70,7 @@ module.exports = function getInputOptions(package, build) {
".mts",
".cts",
".svg",
".cdc",
])

const postcssConfigPath = path.resolve(getPackageRoot(), "postcss.config.js")
Expand All @@ -81,6 +84,8 @@ module.exports = function getInputOptions(package, build) {
},
plugins: [
preserveDirective(),
cadence(),
json(),
imagePlugin(),
nodeResolve({
browser: true,
Expand Down
16 changes: 16 additions & 0 deletions packages/fcl-bundle/src/plugins/cadence.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Rollup plugin to import .cdc (Cadence) files as raw strings
*/
module.exports = function cadence() {
return {
name: "cadence",
transform(code, id) {
if (!id.endsWith(".cdc")) return null

return {
code: `export default ${JSON.stringify(code)};`,
map: null,
}
},
}
}
Loading
Loading