kwikid-components-react
Version:
KwikID's Component Library in React
602 lines (583 loc) • 19.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.WithMockAPI = exports.LightTheme = exports.ExtendedConfiguration = exports.Default = exports.DarkTheme = void 0;
var _react = _interopRequireWildcard(require("react"));
var _Configurator = _interopRequireDefault(require("./Configurator"));
var _Configurator2 = require("./Configurator.defaults");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
const JSON_PADDING = 2;
// Sample JSON data for the stories
const sampleUserJson = {
name: "User Configuration",
version: "1.0.0",
settings: {
theme: "light",
notifications: true,
language: "en",
timezone: "UTC",
features: {
darkMode: true,
mfa: true,
apiAccess: false
}
}
};
const sampleAgentJson = {
name: "Agent Configuration",
version: "1.0.0",
settings: {
maxCalls: 10,
autoAnswer: false,
callRecording: true,
features: {
chatTransfer: true,
videoCall: true,
screenShare: true
}
}
};
// Sample Form config JSON
const sampleFormJson = {
formId: "contact-form",
title: "Contact Information",
fields: [{
id: "fullName",
label: "Full Name",
type: "text",
required: true,
validation: {
minLength: 2,
maxLength: 100
}
}, {
id: "email",
label: "Email Address",
type: "email",
required: true
}, {
id: "phone",
label: "Phone Number",
type: "tel",
required: false
}, {
id: "message",
label: "Message",
type: "textarea",
required: true,
validation: {
minLength: 10,
maxLength: 500
}
}],
buttons: [{
id: "submit",
label: "Submit",
type: "submit",
style: "primary"
}, {
id: "reset",
label: "Reset",
type: "reset",
style: "secondary"
}]
};
// Sample UI Theme config JSON
const sampleThemeJson = {
name: "Corporate Theme",
version: "1.2.0",
colors: {
primary: "#0e639c",
secondary: "#4c9aff",
success: "#36b37e",
warning: "#ffab00",
danger: "#ff5630",
info: "#00b8d9",
light: "#f4f5f7",
dark: "#172b4d",
background: "#ffffff",
text: "#172b4d",
muted: "#6b778c"
},
typography: {
fontFamily: "Manrope, sans-serif",
fontSize: "16px",
lineHeight: 1.5,
headings: {
h1: {
fontSize: "2.5rem",
fontWeight: 700
},
h2: {
fontSize: "2rem",
fontWeight: 600
},
h3: {
fontSize: "1.75rem",
fontWeight: 600
}
}
},
spacing: {
unit: "8px",
small: "8px",
medium: "16px",
large: "24px",
xlarge: "32px"
},
shadows: {
small: "0 1px 3px rgba(0,0,0,0.12)",
medium: "0 4px 6px rgba(0,0,0,0.12)",
large: "0 10px 20px rgba(0,0,0,0.15)"
},
borderRadius: {
small: "4px",
medium: "8px",
large: "12px",
circle: "50%"
}
};
// Mock file structure data with multiple configuration types
const mockFileStructure = {
user: [{
name: "user_config.json",
path: "config/user/user_config.json",
type: "file",
content: JSON.stringify(sampleUserJson, null, JSON_PADDING)
}, {
name: "user_settings.json",
path: "config/user/user_settings.json",
type: "file",
content: JSON.stringify({
settings: {
locale: "en-US",
dateFormat: "MM/DD/YYYY",
timeFormat: "12h"
}
}, null, JSON_PADDING)
}],
agent: [{
name: "agent_config.json",
path: "config/agent/agent_config.json",
type: "file",
content: JSON.stringify(sampleAgentJson, null, JSON_PADDING)
}],
admin: [{
name: "system_config.json",
path: "config/admin/system_config.json",
type: "file",
content: JSON.stringify({
system: {
maxUsers: 1000,
maxAgents: 100,
maintenance: false,
version: "2.5.0"
}
}, null, JSON_PADDING)
}],
forms: [{
name: "contact_form.json",
path: "config/forms/contact_form.json",
type: "file",
content: JSON.stringify(sampleFormJson, null, JSON_PADDING)
}, {
name: "registration_form.json",
path: "config/forms/registration_form.json",
type: "file",
content: JSON.stringify({
formId: "registration-form",
title: "User Registration",
fields: [{
id: "username",
label: "Username",
type: "text",
required: true
}, {
id: "password",
label: "Password",
type: "password",
required: true
}, {
id: "confirmPassword",
label: "Confirm Password",
type: "password",
required: true
}]
}, null, JSON_PADDING)
}],
themes: [{
name: "theme_corporate.json",
path: "config/themes/theme_corporate.json",
type: "file",
content: JSON.stringify(sampleThemeJson, null, JSON_PADDING)
}, {
name: "theme_dark.json",
path: "config/themes/theme_dark.json",
type: "file",
content: JSON.stringify({
name: "Dark Theme",
version: "1.0.0",
colors: {
primary: "#7289DA",
background: "#36393F",
text: "#FFFFFF"
}
}, null, JSON_PADDING)
}]
};
// Extended mock file structure with even more examples
const extendedMockFileStructure = _objectSpread(_objectSpread({}, mockFileStructure), {}, {
workflows: [{
name: "onboarding_workflow.json",
path: "config/workflows/onboarding_workflow.json",
type: "file",
content: JSON.stringify({
id: "user-onboarding",
name: "User Onboarding",
version: "1.0.0",
steps: [{
id: "welcome",
title: "Welcome",
description: "Welcome to our platform",
nextStep: "personal-info"
}, {
id: "personal-info",
title: "Personal Information",
formId: "personal-info-form",
nextStep: "verification"
}, {
id: "verification",
title: "Identity Verification",
formId: "id-verification-form",
nextStep: "completion"
}, {
id: "completion",
title: "Completion",
description: "Your account is now set up!"
}]
}, null, JSON_PADDING)
}],
api: [{
name: "endpoints.json",
path: "config/api/endpoints.json",
type: "file",
content: JSON.stringify({
baseUrl: "https://api.example.com/v1",
endpoints: {
users: "/users",
auth: {
login: "/auth/login",
register: "/auth/register",
forgotPassword: "/auth/forgot-password"
},
products: "/products"
},
timeoutMs: 30000
}, null, JSON_PADDING)
}]
});
// Mock API functions to handle file operations
const mockApiHandler = {
// Get file list
getFilesList: () => {
return Promise.resolve(mockFileStructure);
},
// Extended file list
getExtendedFilesList: () => {
return Promise.resolve(extendedMockFileStructure);
},
// Get file content
getFileContent: params => {
const {
configPath
} = params;
let content = null;
// Search through all categories
function findInStructure(structure) {
Object.keys(structure).forEach(category => {
structure[category].forEach(file => {
if (file.path === configPath) {
content = JSON.parse(file.content);
}
});
});
}
findInStructure(mockFileStructure);
if (!content) {
findInStructure(extendedMockFileStructure);
}
return Promise.resolve(content);
},
// Save file content
saveFileContent: params => {
const {
configPath,
configData
} = params;
console.log(configPath, configData);
// In a real app, this would update the file on the server
// Here we just return success
return Promise.resolve({
success: true
});
}
};
/**
* The Configurator component provides a visual interface for configuring and customizing forms and views.
* It allows users to browse configuration files and edit them in a code editor.
*/
var _default = exports.default = {
title: "Editors/Configurator",
component: _Configurator.default,
parameters: {
docs: {
description: {
component: "\nThe Configurator component allows users to customize forms and views through a visual interface.\nIt provides a way to configure various aspects of the KwikID components through a file browser and code editor.\n\n## Features\n- File tree navigation with intuitive visual interface\n- Monaco editor integration with syntax highlighting and error detection\n- Light and dark theme support (auto-detected from system preferences)\n- Real-time JSON validation and formatting\n- Configuration file management with categories\n- Support for various configuration types (users, agents, forms, themes, etc.)\n "
}
},
componentSubtitle: "Visual configuration tool for KwikID components",
backgrounds: {
default: "light",
values: [{
name: "light",
value: "#ffffff"
}, {
name: "dark",
value: "#1e1e1e"
}]
}
},
tags: ["autodocs"],
argTypes: {
value: {
description: "The initial configuration value"
},
onEmitEvent: {
description: "Callback function for when the configuration changes",
action: "changed"
},
id: {
description: "Unique identifier for the component"
},
config: {
description: "Configuration object containing API endpoints and other settings"
},
styles: {
description: "Custom styles for the component"
},
initialTheme: {
description: "Initial theme (dark or light)",
control: {
type: "radio"
},
options: ["auto", "dark", "light"],
defaultValue: "auto"
},
variant: {
description: "Variant of mock data to use",
control: {
type: "select"
},
options: ["default", "extended"],
defaultValue: "default"
}
}
}; // Create a template for the stories
const Template = args => {
// Add initialTheme as a custom prop to be managed by the story
const [initialTheme, setInitialTheme] = _react.default.useState(args.initialTheme || "auto");
const [localValue, setValue] = _react.default.useState(args.value || "");
const handleOnEmitEvent = (id, value) => {
setValue(value);
// For demonstration in Storybook
console.log("Value changed for ".concat(id, ":"), value);
};
// Handler for fetch mock
const handleFetchMock = (structure, url, options) => {
if (typeof url === "string") {
if (url.includes("get/paths")) {
return {
ok: true,
json: () => structure === "extended" ? mockApiHandler.getExtendedFilesList(JSON.parse((options === null || options === void 0 ? void 0 : options.body) || "{}")) : mockApiHandler.getFilesList(JSON.parse((options === null || options === void 0 ? void 0 : options.body) || "{}"))
};
} else if (url.includes("get/config_file")) {
return {
ok: true,
json: () => mockApiHandler.getFileContent(JSON.parse((options === null || options === void 0 ? void 0 : options.body) || "{}"))
};
} else if (url.includes("set/config_file")) {
return {
ok: true,
json: () => mockApiHandler.saveFileContent(JSON.parse((options === null || options === void 0 ? void 0 : options.body) || "{}"))
};
}
}
return null;
};
// Replace fetch with mocked implementation for storybook
_react.default.useEffect(() => {
const originalFetch = window.fetch;
window.fetch = async (url, options) => {
// For Default story with mock endpoints
if (typeof url === "string" && url.includes("mock-api")) {
const response = handleFetchMock(args.variant || "default", url, options);
if (response) return response;
}
// For WithMockAPI story
else if (typeof url === "string" && url.includes("api-example.com")) {
const response = handleFetchMock(args.variant || "default", url, options);
if (response) return response;
}
return originalFetch(url, options);
};
return () => {
window.fetch = originalFetch;
};
}, [args.variant]);
// Set the component's theme based on the Storybook background
(0, _react.useEffect)(() => {
// If args.initialTheme changes, update our local state
setInitialTheme(args.initialTheme);
}, [args.initialTheme]);
// Set document body background to match the current theme for better preview
(0, _react.useEffect)(() => {
// This is just for Storybook preview aesthetics
const isDark = initialTheme === "dark" || initialTheme === "auto" && window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
document.body.style.backgroundColor = isDark ? "#1e1e1e" : "#f9f9f9";
document.body.style.transition = "background-color 0.3s ease";
return () => {
document.body.style.backgroundColor = "";
};
}, [initialTheme]);
return /*#__PURE__*/_react.default.createElement("div", {
style: {
width: "100%",
height: "80vh",
border: "1px solid ".concat(initialTheme === "dark" ? "#333" : "#e0e0e0"),
borderRadius: "4px",
overflow: "hidden"
}
}, /*#__PURE__*/_react.default.createElement(_Configurator.default, _extends({}, args, {
onEmitEvent: handleOnEmitEvent,
value: localValue
})));
};
/**
* Basic implementation of the Configurator component with default settings.
* This version uses mock data to simulate the file browser and editor functionality.
*/
const Default = exports.Default = {
render: Template,
args: {
id: "configurator-example",
value: "",
config: {
GET_CONFIG_FILE_URL: "mock-api/config/get/config_file",
GET_FILES_LIST: "mock-api/config/get/paths",
SET_CONFIG_FILE_URL: "mock-api/config/set/config_file",
PORTAL_NAMES: ["USER", "AGENT", "ADMIN"],
CONFIG_KEY: "mock_config"
},
styles: _Configurator2.KWIKID__CONFIGURATOR__DEFAULTS.styles,
variant: "default",
initialTheme: "auto"
}
};
/**
* Example showing the Configurator with a more extensive configuration.
* This includes additional configuration types for forms, themes, and workflows.
*/
const ExtendedConfiguration = exports.ExtendedConfiguration = {
render: Template,
args: {
id: "configurator-extended",
value: "",
config: {
GET_CONFIG_FILE_URL: "mock-api/config/get/config_file",
GET_FILES_LIST: "mock-api/config/get/paths",
SET_CONFIG_FILE_URL: "mock-api/config/set/config_file",
PORTAL_NAMES: ["USER", "AGENT", "ADMIN", "FORMS", "THEMES", "WORKFLOWS", "API"],
CONFIG_KEY: "extended_config"
},
styles: _Configurator2.KWIKID__CONFIGURATOR__DEFAULTS.styles,
variant: "extended",
initialTheme: "auto"
}
};
/**
* Dark theme version of the Configurator, for applications with dark mode UI.
*/
const DarkTheme = exports.DarkTheme = {
render: Template,
args: {
id: "configurator-dark",
value: "",
config: {
GET_CONFIG_FILE_URL: "mock-api/config/get/config_file",
GET_FILES_LIST: "mock-api/config/get/paths",
SET_CONFIG_FILE_URL: "mock-api/config/set/config_file",
PORTAL_NAMES: ["USER", "AGENT", "ADMIN", "FORMS", "THEMES"],
CONFIG_KEY: "dark_config"
},
variant: "extended",
initialTheme: "dark"
},
parameters: {
backgrounds: {
default: "dark"
}
}
};
/**
* Light theme version of the Configurator, for applications with light mode UI.
*/
const LightTheme = exports.LightTheme = {
render: Template,
args: {
id: "configurator-light",
value: "",
config: {
GET_CONFIG_FILE_URL: "mock-api/config/get/config_file",
GET_FILES_LIST: "mock-api/config/get/paths",
SET_CONFIG_FILE_URL: "mock-api/config/set/config_file",
PORTAL_NAMES: ["USER", "AGENT", "ADMIN", "FORMS", "THEMES"],
CONFIG_KEY: "light_config"
},
variant: "extended",
initialTheme: "light"
},
parameters: {
backgrounds: {
default: "light"
}
}
};
/**
* Example showing the Configurator with a simulated API configuration.
* This demonstrates how the component would be used with real API endpoints.
*/
const WithMockAPI = exports.WithMockAPI = {
render: Template,
args: {
id: "configurator-with-api",
value: "",
config: {
GET_CONFIG_FILE_URL: "https://api-example.com/config/get/config_file",
GET_FILES_LIST: "https://api-example.com/config/get/paths",
SET_CONFIG_FILE_URL: "https://api-example.com/config/set/config_file",
PORTAL_NAMES: ["USER", "ADMIN", "FORMS", "THEMES"],
CONFIG_KEY: "example_config",
apiToken: "mock-api-token"
},
variant: "extended",
initialTheme: "auto"
}
};