diff --git a/samples/Vuejs-sample/.gitignore b/samples/Vuejs-sample/.gitignore
new file mode 100644
index 0000000..403adbc
--- /dev/null
+++ b/samples/Vuejs-sample/.gitignore
@@ -0,0 +1,23 @@
+.DS_Store
+node_modules
+/dist
+
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/samples/Vuejs-sample/README.md b/samples/Vuejs-sample/README.md
new file mode 100644
index 0000000..afa21ff
--- /dev/null
+++ b/samples/Vuejs-sample/README.md
@@ -0,0 +1,19 @@
+# vuejs-skyflow-react-sample
+
+## Project setup
+```
+npm install
+```
+
+### Compiles and hot-reloads for development
+```
+npm run serve
+```
+
+### Compiles and minifies for production
+```
+npm run build
+```
+
+### Customize configuration
+See [Configuration Reference](https://cli.vuejs.org/config/).
diff --git a/samples/Vuejs-sample/babel.config.js b/samples/Vuejs-sample/babel.config.js
new file mode 100644
index 0000000..6acb5cb
--- /dev/null
+++ b/samples/Vuejs-sample/babel.config.js
@@ -0,0 +1,7 @@
+module.exports = {
+ presets: [
+ ['@vue/cli-plugin-babel/preset'],
+ ['@babel/preset-react'],
+ ['@babel/preset-typescript']
+ ]
+}
\ No newline at end of file
diff --git a/samples/Vuejs-sample/package.json b/samples/Vuejs-sample/package.json
new file mode 100644
index 0000000..d278493
--- /dev/null
+++ b/samples/Vuejs-sample/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "vuejs-skyflow-reactsdk-sample",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "serve": "vue-cli-service serve --host localhost --port 8080 --public localhost:8080",
+ "build": "vue-cli-service build"
+ },
+ "dependencies": {
+ "@types/react": "^19.1.8",
+ "react": "^19.1.0",
+ "react-dom": "^19.1.0",
+ "react-to-webcomponent": "^2.0.1",
+ "skyflow-js": "^2.3.2",
+ "skyflow-react-js": "^2.4.3",
+ "vue": "^3.2.13"
+ },
+ "devDependencies": {
+ "@babel/preset-react": "^7.27.1",
+ "@babel/preset-typescript": "^7.27.1",
+ "@types/react-dom": "^19.1.6",
+ "@vue/babel-preset-jsx": "^1.4.0",
+ "@vue/cli-plugin-babel": "^5.0.8",
+ "@vue/cli-plugin-typescript": "~5.0.0",
+ "@vue/cli-service": "~5.0.0",
+ "babel-loader": "^10.0.0",
+ "typescript": "~4.5.5",
+ "webpack": "^5.99.9"
+ }
+}
diff --git a/samples/Vuejs-sample/public/favicon.ico b/samples/Vuejs-sample/public/favicon.ico
new file mode 100644
index 0000000..df36fcf
Binary files /dev/null and b/samples/Vuejs-sample/public/favicon.ico differ
diff --git a/samples/Vuejs-sample/public/index.html b/samples/Vuejs-sample/public/index.html
new file mode 100644
index 0000000..3e5a139
--- /dev/null
+++ b/samples/Vuejs-sample/public/index.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+ <%= htmlWebpackPlugin.options.title %>
+
+
+
+
+
+
+
diff --git a/samples/Vuejs-sample/src/App.vue b/samples/Vuejs-sample/src/App.vue
new file mode 100644
index 0000000..68a17cf
--- /dev/null
+++ b/samples/Vuejs-sample/src/App.vue
@@ -0,0 +1,10 @@
+
+
+
+
+
+ React + Vue
+
+
diff --git a/samples/Vuejs-sample/src/assets/logo.png b/samples/Vuejs-sample/src/assets/logo.png
new file mode 100644
index 0000000..f3d2503
Binary files /dev/null and b/samples/Vuejs-sample/src/assets/logo.png differ
diff --git a/samples/Vuejs-sample/src/components/CollectComponents.tsx b/samples/Vuejs-sample/src/components/CollectComponents.tsx
new file mode 100644
index 0000000..964d443
--- /dev/null
+++ b/samples/Vuejs-sample/src/components/CollectComponents.tsx
@@ -0,0 +1,188 @@
+import React from 'react';
+import {
+ CardHolderNameElement,
+ CardNumberElement,
+ CVVElement,
+ ExpirationDateElement,
+ ExpirationMonthElement,
+ ExpirationYearElement,
+ FileInputElement,
+ InputFieldElement,
+ PinElement,
+ useCollectContainer,
+ useMakeSkyflowStyles
+} from 'skyflow-react-js';
+
+export const CollectComponents: React.FC = () => {
+ // Initialize Skyflow container for collecting sensitive data
+ const container = useCollectContainer();
+
+ if (!container) {
+ return Loading...
;
+ }
+
+ // Handler for collecting form data
+ const handleCollect = () => {
+ const response = container.collect();
+ response
+ .then((res: unknown) => {
+ console.log(JSON.stringify(res));
+ })
+ .catch((e: unknown) => {
+ console.log(e);
+ });
+ };
+
+ // Handler for file uploads
+ const handleFile = () => {
+ const response = container.uploadFiles({});
+ response
+ .then((res: unknown) => {
+ console.log(JSON.stringify(res));
+ })
+ .catch((e: unknown) => {
+ console.log(e);
+ });
+ };
+
+ // Define styles for Skyflow elements
+ const useStyles = useMakeSkyflowStyles({
+ // Input field styles
+ inputStyles: {
+ base: {
+ border: '1px solid blue',
+ borderRadius: '4px',
+ color: 'red',
+ padding: '10px 16px',
+ fontFamily: '"Roboto", sans-serif',
+ },
+ complete: { color: '#4caf50' },
+ empty: {},
+ focus: {},
+ invalid: { color: '#f44336' },
+ global: {
+ '@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
+ }
+ },
+ // Label styles
+ labelStyles: {
+ base: {
+ fontSize: '16px',
+ fontWeight: 'bold',
+ fontFamily: '"Roboto", sans-serif'
+ },
+ global: {
+ '@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
+ },
+ requiredAsterisk: { color: 'red' }
+ },
+ // Error message styles
+ errorTextStyles: {
+ base: {
+ color: 'red',
+ fontFamily: '"Roboto", sans-serif',
+ },
+ global: {
+ '@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
+ },
+ },
+ });
+
+ // File upload options (empty for now)
+ const options = {}
+
+ // Apply styles to elements
+ const classes = useStyles();
+
+ return (
+
+
Collect Components
+
+
+
'} // replace with actual column name
+ label='Collect CVV'
+ placeholder='CVV'
+ />
+ '} // replace with actual column name
+ label='Collect Exp Month'
+ placeholder='MM'
+ />
+ '} // replace with actual column name
+ label='Collect Exp Year'
+ placeholder='YY'
+ />
+ '} // replace with actual table name
+ column={''} // replace with actual column name
+ label={'Expiration Date'}
+ placeholder='MM/YY'
+ />
+
+ '}
+ column={''} // replace with actual column name
+ label={'Pin'}
+ placeholder='122334'
+ />
+
+ '}
+ column={''} // replace with actual column name
+ label={'SSN'}
+ placeholder='123-45-6789'
+ />
+ '}
+ column={''} // replace with actual column name
+ skyflowID=''
+ label={'file-input'}
+ options={options}
+ />
+
+
+
+ );
+};
+
+
diff --git a/samples/Vuejs-sample/src/components/Connector.tsx b/samples/Vuejs-sample/src/components/Connector.tsx
new file mode 100644
index 0000000..27d7b72
--- /dev/null
+++ b/samples/Vuejs-sample/src/components/Connector.tsx
@@ -0,0 +1,69 @@
+import React, { useState } from "react";
+import { CollectComponents } from "./CollectComponents";
+import { SkyflowWrapper } from "./SkyflowWrapper";
+import { Root, createRoot } from 'react-dom/client';
+import RevealComponents from "./RevealComponents";
+
+// Component to manage visibility state of Collect and Reveal forms
+const ComponentWrapper: React.FC = () => {
+ // State hooks for toggling component visibility
+ const [showCollect, setShowCollect] = useState(false);
+ const [showReveal, setShowReveal] = useState(false);
+
+ return (
+
+ {/* Button container */}
+
+ {/* Toggle Collect form visibility */}
+
+ {/* Toggle Reveal form visibility */}
+
+
+
+ {/* Conditional rendering of components */}
+ {showCollect &&
}
+ {showReveal &&
}
+
+ );
+};
+
+// Class to handle React integration with Vue
+export class ReactConnector {
+ // Store React root instance
+ private root: Root | null = null;
+
+ // Initialize React root with target DOM element
+ constructor(targetEl: HTMLElement) {
+ if (targetEl) {
+ this.root = createRoot(targetEl);
+ }
+ }
+
+ // Render React components with Skyflow context
+ render() {
+ if (this.root) {
+ this.root.render(
+
+
+
+ );
+ }
+ }
+
+ // Cleanup method to prevent memory leaks
+ cleanup() {
+ if (this.root) {
+ this.root.unmount();
+ this.root = null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/Vuejs-sample/src/components/RevealComponents.tsx b/samples/Vuejs-sample/src/components/RevealComponents.tsx
new file mode 100644
index 0000000..640f731
--- /dev/null
+++ b/samples/Vuejs-sample/src/components/RevealComponents.tsx
@@ -0,0 +1,145 @@
+/*
+ Copyright (c) 2022 Skyflow, Inc.
+*/
+import React from 'react'
+import Skyflow from 'skyflow-js'
+import { FileRenderElement, RevealElement, useMakeSkyflowStyles, useRenderFile, useRevealContainer } from 'skyflow-react-js'
+
+const RevealComponents = () => {
+ // Initialize container for revealing sensitive data
+ const revealContainer = useRevealContainer()
+
+ if (!revealContainer) {
+ return Loading...
+ }
+
+ // Styles for reveal elements (text fields)
+ const useStyles = useMakeSkyflowStyles({
+ inputStyles: {
+ base: {
+ border: '1px solid black',
+ borderRadius: '4px',
+ color: '#1d1d1d',
+ padding: '10px 16px',
+ fontFamily: '"Roboto", sans-serif',
+ },
+ complete: {
+ color: '#4caf50',
+ },
+ empty: {},
+ focus: {},
+ invalid: {
+ color: '#f44336',
+ },
+ global: {
+ '@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
+ },
+ },
+ labelStyles: {
+ base: {
+ fontSize: '16px',
+ fontWeight: 'bold',
+ fontFamily: '"Roboto", sans-serif',
+ },
+ global: {
+ '@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
+ },
+ },
+ errorTextStyles: {
+ base: {
+ color: 'red',
+ fontFamily: '"Roboto", sans-serif',
+ },
+ global: {
+ '@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
+ },
+ },
+ })
+ const classes = useStyles()
+
+ // Styles specifically for file rendering
+ const useRenderStyles = useMakeSkyflowStyles({
+ inputStyles: {
+ base: {
+ height: '300px',
+ border: '1px solid black',
+ borderRadius: '4px',
+ color: '#1d1d1d',
+ padding: '10px 16px',
+ },
+ },
+ errorTextStyles: {
+ base: {
+ color: 'red',
+ fontFamily: '"Roboto", sans-serif',
+ },
+ global: {
+ '@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
+ },
+ },
+ })
+ const renderClasses = useRenderStyles()
+
+ // Handle reveal action for all elements in container
+ const handleReveal = () => {
+ revealContainer
+ .reveal()
+ .then((res: any) => console.log(res))
+ .catch((err: any) => console.log(err))
+ }
+
+ // Initialize file renderer with element ID
+ const render = useRenderFile('fileElement-1')
+
+ // Handle file rendering action
+ const handleRender = () => {
+ render
+ ?.renderFile()
+ .then((data) => console.log(data))
+ .catch((err) => console.log(err))
+ }
+
+ return (
+
+
Reveal Elements
+
+ {/* Reveal elements */}
+
+
+
+
+ {/* File render element */}
+
'}
+ classes={renderClasses}
+ column={''}
+ table={''}
+ altText={'Image File'}
+ />
+
+ {/* Action buttons */}
+
+
+
+ )
+}
+
+export default RevealComponents
diff --git a/samples/Vuejs-sample/src/components/SkyflowWrapper.tsx b/samples/Vuejs-sample/src/components/SkyflowWrapper.tsx
new file mode 100644
index 0000000..b766091
--- /dev/null
+++ b/samples/Vuejs-sample/src/components/SkyflowWrapper.tsx
@@ -0,0 +1,43 @@
+import React from 'react';
+import { SkyflowElements } from 'skyflow-react-js';
+
+interface Props {
+ children: React.ReactNode;
+}
+const getBearerToken = () => {
+ return new Promise((resolve, reject) => {
+ const Http = new XMLHttpRequest();
+
+ Http.onreadystatechange = () => {
+ if (Http.readyState === 4) {
+ if (Http.status === 200) {
+ resolve('');
+ } else {
+ reject('Error occured');
+ }
+ }
+ };
+
+ Http.onerror = () => {
+ reject('Error occured');
+ };
+
+ const url = ''
+ Http.open('GET', url)
+ Http.send()
+ })
+}
+
+export const SkyflowWrapper: React.FC = ({ children }) => {
+ const config = {
+ vaultID: '', // Replace with your vault ID
+ vaultURL: '', // Replace with your vault URL
+ getBearerToken: getBearerToken
+ };
+
+ return (
+
+ {children}
+
+ );
+};
\ No newline at end of file
diff --git a/samples/Vuejs-sample/src/components/VueComponent.vue b/samples/Vuejs-sample/src/components/VueComponent.vue
new file mode 100644
index 0000000..ac6daa6
--- /dev/null
+++ b/samples/Vuejs-sample/src/components/VueComponent.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/Vuejs-sample/src/main.ts b/samples/Vuejs-sample/src/main.ts
new file mode 100644
index 0000000..a436af0
--- /dev/null
+++ b/samples/Vuejs-sample/src/main.ts
@@ -0,0 +1,5 @@
+import { createApp } from 'vue'
+import App from './App.vue'
+import './components/Connector'
+
+createApp(App).mount('#app')
diff --git a/samples/Vuejs-sample/src/shims-vue.d.ts b/samples/Vuejs-sample/src/shims-vue.d.ts
new file mode 100644
index 0000000..3804a43
--- /dev/null
+++ b/samples/Vuejs-sample/src/shims-vue.d.ts
@@ -0,0 +1,6 @@
+/* eslint-disable */
+declare module '*.vue' {
+ import type { DefineComponent } from 'vue'
+ const component: DefineComponent<{}, {}, any>
+ export default component
+}
diff --git a/samples/Vuejs-sample/tsconfig.json b/samples/Vuejs-sample/tsconfig.json
new file mode 100644
index 0000000..426a200
--- /dev/null
+++ b/samples/Vuejs-sample/tsconfig.json
@@ -0,0 +1,37 @@
+{
+ "compilerOptions": {
+ "target": "esnext",
+ "module": "esnext",
+ "strict": true,
+ "jsx": "react",
+ "importHelpers": true,
+ "moduleResolution": "node",
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "sourceMap": true,
+ "baseUrl": ".",
+ "types": [
+ "webpack-env"
+ ],
+ "paths": {
+ "@/*": [
+ "src/*"
+ ]
+ },
+ "lib": [
+ "esnext",
+ "dom",
+ "dom.iterable",
+ "scripthost"
+ ]
+ },
+ "include": [
+ "src/**/*.ts",
+ "src/**/*.tsx",
+ "src/**/*.vue"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}
diff --git a/samples/Vuejs-sample/vue.config.js b/samples/Vuejs-sample/vue.config.js
new file mode 100644
index 0000000..377f15b
--- /dev/null
+++ b/samples/Vuejs-sample/vue.config.js
@@ -0,0 +1,43 @@
+const { defineConfig } = require('@vue/cli-service')
+const webpack = require('webpack')
+
+module.exports = defineConfig({
+ devServer: {
+ host: 'localhost',
+ port: 8080,
+ client: {
+ webSocketURL: 'ws://localhost:8080/ws'
+ },
+ allowedHosts: 'all'
+ },
+ configureWebpack: {
+ plugins: [
+ new webpack.DefinePlugin({
+ __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false',
+ __VUE_OPTIONS_API__: 'true',
+ __VUE_PROD_DEVTOOLS__: 'false',
+ })
+ ],
+ module: {
+ rules: [
+ {
+ test: /\.(tsx|ts)$/,
+ use: [
+ 'babel-loader',
+ {
+ loader: 'ts-loader',
+ options: {
+ transpileOnly: true,
+ appendTsSuffixTo: ['\\.vue$']
+ }
+ }
+ ],
+ exclude: /node_modules/
+ }
+ ]
+ },
+ resolve: {
+ extensions: ['.tsx', '.ts', '.js']
+ }
+ }
+})
\ No newline at end of file