@onlistify/storefront 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +108 -17
- package/dist/cli.js +233 -0
- package/dist/index-CxOAQ9Nx.d.cts +53 -0
- package/dist/index-CxOAQ9Nx.d.ts +53 -0
- package/dist/index.cjs +4 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -55
- package/dist/index.d.ts +8 -55
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/node.cjs +139 -0
- package/dist/node.cjs.map +1 -0
- package/dist/node.d.cts +26 -0
- package/dist/node.d.ts +26 -0
- package/dist/node.js +125 -0
- package/dist/node.js.map +1 -0
- package/dist/plugins/README.txt +24 -0
- package/dist/plugins/header-plugin.css +58 -0
- package/dist/plugins/header-plugin.js +72 -0
- package/dist/plugins/header-plugin.schema.json +45 -0
- package/dist/plugins/hero-plugin.css +34 -0
- package/dist/plugins/hero-plugin.js +56 -0
- package/dist/plugins/hero-plugin.schema.json +38 -0
- package/package.json +16 -2
package/dist/node.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { fileURLToPath } from 'url';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
|
|
5
|
+
// src/sdk/node-api.ts
|
|
6
|
+
|
|
7
|
+
// ../shared/site-contract/src/index.ts
|
|
8
|
+
function isRecord(value) {
|
|
9
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
10
|
+
}
|
|
11
|
+
function normalizeBlock(block) {
|
|
12
|
+
if (!isRecord(block)) {
|
|
13
|
+
return { id: "", type: "", props: {} };
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
id: typeof block.id === "string" ? block.id : "",
|
|
17
|
+
type: typeof block.type === "string" ? block.type : "",
|
|
18
|
+
props: isRecord(block.props) ? block.props : {}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function normalizePage(page) {
|
|
22
|
+
if (!isRecord(page)) {
|
|
23
|
+
return { id: "", path: "/", blocks: [] };
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
id: typeof page.id === "string" ? page.id : "",
|
|
27
|
+
path: typeof page.path === "string" ? page.path : "/",
|
|
28
|
+
blocks: Array.isArray(page.blocks) ? page.blocks.map((block) => normalizeBlock(block)) : []
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function extractSiteObject(raw) {
|
|
32
|
+
if (!isRecord(raw)) {
|
|
33
|
+
return raw;
|
|
34
|
+
}
|
|
35
|
+
if (raw.data !== void 0) {
|
|
36
|
+
return extractSiteObject(raw.data);
|
|
37
|
+
}
|
|
38
|
+
return raw;
|
|
39
|
+
}
|
|
40
|
+
function normalizeSiteConfig(raw) {
|
|
41
|
+
const source = extractSiteObject(raw);
|
|
42
|
+
if (!isRecord(source)) {
|
|
43
|
+
return { version: 1, pages: [] };
|
|
44
|
+
}
|
|
45
|
+
const pages = Array.isArray(source.pages) ? source.pages.map((page) => normalizePage(page)) : [];
|
|
46
|
+
return {
|
|
47
|
+
version: typeof source.version === "number" ? source.version : 1,
|
|
48
|
+
theme: isRecord(source.theme) ? source.theme : void 0,
|
|
49
|
+
themeOverrides: isRecord(source.themeOverrides) ? source.themeOverrides : void 0,
|
|
50
|
+
pages
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// src/sdk/node-api.ts
|
|
55
|
+
var BASE_PATH = "/api/v1/public";
|
|
56
|
+
function getModuleDir() {
|
|
57
|
+
return path.dirname(fileURLToPath(import.meta.url));
|
|
58
|
+
}
|
|
59
|
+
async function pullSiteConfig(options, environment = "draft") {
|
|
60
|
+
const base = options.apiUrl.replace(/\/$/, "");
|
|
61
|
+
const url = `${base}${BASE_PATH}/site-config?environment=${environment}`;
|
|
62
|
+
const res = await fetch(url, { headers: { "X-API-Key": options.apiKey } });
|
|
63
|
+
if (!res.ok) throw new Error(`pullSiteConfig: ${res.status} ${await res.text()}`);
|
|
64
|
+
const data = await res.json();
|
|
65
|
+
const raw = data?.data ?? data ?? { pages: [] };
|
|
66
|
+
return normalizeSiteConfig(raw);
|
|
67
|
+
}
|
|
68
|
+
async function pushSiteConfig(options, config) {
|
|
69
|
+
const base = options.apiUrl.replace(/\/$/, "");
|
|
70
|
+
const url = `${base}${BASE_PATH}/site-config?environment=draft`;
|
|
71
|
+
const res = await fetch(url, {
|
|
72
|
+
method: "PUT",
|
|
73
|
+
headers: { "X-API-Key": options.apiKey, "Content-Type": "application/json" },
|
|
74
|
+
body: JSON.stringify(config)
|
|
75
|
+
});
|
|
76
|
+
if (!res.ok) throw new Error(`pushSiteConfig: ${res.status} ${await res.text()}`);
|
|
77
|
+
}
|
|
78
|
+
async function promoteSiteConfig(options) {
|
|
79
|
+
const base = options.apiUrl.replace(/\/$/, "");
|
|
80
|
+
const url = `${base}${BASE_PATH}/site-config/promote`;
|
|
81
|
+
const res = await fetch(url, { method: "POST", headers: { "X-API-Key": options.apiKey } });
|
|
82
|
+
if (!res.ok) throw new Error(`promoteSiteConfig: ${res.status} ${await res.text()}`);
|
|
83
|
+
}
|
|
84
|
+
async function triggerWebhook(webhookUrl, payload) {
|
|
85
|
+
const url = webhookUrl.trim();
|
|
86
|
+
if (!url) return;
|
|
87
|
+
await fetch(url, {
|
|
88
|
+
method: "POST",
|
|
89
|
+
headers: { "Content-Type": "application/json" },
|
|
90
|
+
body: JSON.stringify(payload ?? { event: "onlistify.update" })
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
var DEFAULT_PLUGIN_TYPES = ["onl-hero", "onl-header"];
|
|
94
|
+
function getDefaultPluginsDir() {
|
|
95
|
+
return path.join(getModuleDir(), "..", "plugins");
|
|
96
|
+
}
|
|
97
|
+
function getDefaultPluginTypes() {
|
|
98
|
+
return DEFAULT_PLUGIN_TYPES;
|
|
99
|
+
}
|
|
100
|
+
async function exportSiteProject(options, exportOptions) {
|
|
101
|
+
const config = await pullSiteConfig(options, exportOptions.environment ?? "draft");
|
|
102
|
+
const outDir = path.resolve(process.cwd(), exportOptions.outputDir);
|
|
103
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
104
|
+
const configPath = path.join(outDir, "site-config.draft.json");
|
|
105
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf8");
|
|
106
|
+
let pluginsPath;
|
|
107
|
+
if (exportOptions.includePlugins !== false) {
|
|
108
|
+
const pluginsDir = path.join(outDir, "plugins");
|
|
109
|
+
fs.mkdirSync(pluginsDir, { recursive: true });
|
|
110
|
+
const sdkPluginsDir = getDefaultPluginsDir();
|
|
111
|
+
if (fs.existsSync(sdkPluginsDir)) {
|
|
112
|
+
const files = fs.readdirSync(sdkPluginsDir);
|
|
113
|
+
for (const f of files) {
|
|
114
|
+
const src = path.join(sdkPluginsDir, f);
|
|
115
|
+
if (fs.statSync(src).isFile()) fs.copyFileSync(src, path.join(pluginsDir, f));
|
|
116
|
+
}
|
|
117
|
+
pluginsPath = pluginsDir;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return { configPath, pluginsPath };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export { exportSiteProject, getDefaultPluginTypes, getDefaultPluginsDir, promoteSiteConfig, pullSiteConfig, pushSiteConfig, triggerWebhook };
|
|
124
|
+
//# sourceMappingURL=node.js.map
|
|
125
|
+
//# sourceMappingURL=node.js.map
|
package/dist/node.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../shared/site-contract/src/index.ts","../src/sdk/node-api.ts"],"names":[],"mappings":"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","file":"node.js","sourcesContent":["export type SiteEnvironment = 'draft' | 'live';\n\nexport interface SiteConfigTheme {\n primaryColor?: string;\n accentColor?: string;\n logoUrl?: string;\n customCssVars?: Record<string, string>;\n}\n\nexport interface PropiedadCardBlockProps {\n theme?: {\n primaryColor?: string;\n accentColor?: string;\n badgeBackground?: string;\n cardBorderRadius?: string;\n imageAspectRatio?: '16/9' | '4/3' | '1/1';\n };\n showFields?: Record<string, boolean>;\n badges?: {\n featured?: { enabled: boolean; label?: string };\n virtualTour?: { enabled: boolean; label?: string };\n custom?: Array<{ key: string; label: string; when?: string }>;\n };\n layout?: 'compact' | 'default' | 'minimal';\n linkTarget?: '_self' | '_blank';\n openDetailIn?: 'same' | 'modal' | 'drawer';\n}\n\nexport interface BlockDef<TProps = Record<string, unknown>> {\n id: string;\n type: string;\n props?: TProps;\n}\n\nexport interface PageDef {\n id: string;\n path: string;\n blocks: BlockDef[];\n}\n\nexport interface SiteConfig {\n version?: number;\n theme?: SiteConfigTheme;\n themeOverrides?: Record<string, unknown>;\n pages?: PageDef[];\n}\n\nexport interface ResolvedSiteTheme {\n primaryColor: string;\n accentColor: string;\n logoUrl?: string;\n customCssVars: Record<string, string>;\n}\n\nconst DEFAULT_SITE_THEME: ResolvedSiteTheme = {\n primaryColor: '#1a365d',\n accentColor: '#2b6cb0',\n customCssVars: {},\n};\n\nconst DEFAULT_HERO_BLOCK: BlockDef = {\n id: 'hero-1',\n type: 'onl-hero',\n props: {\n title: 'Bienvenido a tu inmobiliaria',\n subtitle: 'Encuentra tu próximo hogar',\n ctaText: 'Ver propiedades',\n ctaUrl: '#',\n backgroundColor: '#1a365d',\n textColor: '#fff',\n },\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction normalizeBlock(block: unknown): BlockDef {\n if (!isRecord(block)) {\n return { id: '', type: '', props: {} };\n }\n\n return {\n id: typeof block.id === 'string' ? block.id : '',\n type: typeof block.type === 'string' ? block.type : '',\n props: isRecord(block.props) ? block.props : {},\n };\n}\n\nfunction normalizePage(page: unknown): PageDef {\n if (!isRecord(page)) {\n return { id: '', path: '/', blocks: [] };\n }\n\n return {\n id: typeof page.id === 'string' ? page.id : '',\n path: typeof page.path === 'string' ? page.path : '/',\n blocks: Array.isArray(page.blocks) ? page.blocks.map((block) => normalizeBlock(block)) : [],\n };\n}\n\nfunction extractSiteObject(raw: unknown): unknown {\n if (!isRecord(raw)) {\n return raw;\n }\n\n if (raw.data !== undefined) {\n return extractSiteObject(raw.data);\n }\n\n return raw;\n}\n\nexport function normalizeSiteConfig(raw: unknown): SiteConfig {\n const source = extractSiteObject(raw);\n\n if (!isRecord(source)) {\n return { version: 1, pages: [] };\n }\n\n const pages = Array.isArray(source.pages) ? source.pages.map((page) => normalizePage(page)) : [];\n\n return {\n version: typeof source.version === 'number' ? source.version : 1,\n theme: isRecord(source.theme) ? (source.theme as SiteConfigTheme) : undefined,\n themeOverrides: isRecord(source.themeOverrides) ? (source.themeOverrides as Record<string, unknown>) : undefined,\n pages,\n };\n}\n\nexport function createDefaultHeroBlock(): BlockDef {\n return {\n ...DEFAULT_HERO_BLOCK,\n props: { ...DEFAULT_HERO_BLOCK.props },\n };\n}\n\nexport function getPrimaryPage(config: SiteConfig): PageDef | undefined {\n const pages = config.pages ?? [];\n return pages.find((page) => page.path === '/' || page.id === 'listado') ?? pages[0];\n}\n\nexport function getPageBlocks(config: SiteConfig): BlockDef[] {\n return getPrimaryPage(config)?.blocks ?? [];\n}\n\nexport function ensureDefaultHeroInConfig(config: SiteConfig): SiteConfig {\n const pages = config.pages ?? [];\n\n if (!pages.length) {\n return {\n ...config,\n version: config.version ?? 1,\n pages: [{ id: 'listado', path: '/', blocks: [createDefaultHeroBlock()] }],\n };\n }\n\n const first = pages[0];\n const blocks = first.blocks ?? [];\n\n if (blocks.some((block) => block.type === 'onl-hero')) {\n return {\n ...config,\n version: config.version ?? 1,\n pages,\n };\n }\n\n return {\n ...config,\n version: config.version ?? 1,\n pages: [{ ...first, blocks: [createDefaultHeroBlock(), ...blocks] }, ...pages.slice(1)],\n };\n}\n\nexport function getPropiedadCardProps(config: SiteConfig): PropiedadCardBlockProps {\n const block = getPageBlocks(config).find((item) => item.type === 'propiedad-card');\n return (block?.props ?? {}) as PropiedadCardBlockProps;\n}\n\nexport function resolveSiteTheme(config: SiteConfig): ResolvedSiteTheme {\n const theme = config.theme ?? {};\n const overrides = (config.themeOverrides ?? {}) as Record<string, string>;\n\n return {\n primaryColor: overrides.primaryColor ?? theme.primaryColor ?? DEFAULT_SITE_THEME.primaryColor,\n accentColor: overrides.accentColor ?? theme.accentColor ?? DEFAULT_SITE_THEME.accentColor,\n logoUrl: theme.logoUrl,\n customCssVars: theme.customCssVars ?? {},\n };\n}\n","/// <reference types=\"node\" />\nimport { fileURLToPath } from 'node:url';\nimport path from 'node:path';\nimport fs from 'node:fs';\nimport { normalizeSiteConfig } from '../../../shared/site-contract/src/index';\nimport type { SiteConfig } from '../../../shared/site-contract/src/index';\n\nconst BASE_PATH = '/api/v1/public';\n\nexport interface NodeApiOptions {\n apiUrl: string;\n apiKey: string;\n}\n\nfunction getModuleDir(): string {\n return path.dirname(fileURLToPath(import.meta.url));\n}\n\nexport async function pullSiteConfig(options: NodeApiOptions, environment: 'draft' | 'live' = 'draft'): Promise<SiteConfig> {\n const base = options.apiUrl.replace(/\\/$/, '');\n const url = `${base}${BASE_PATH}/site-config?environment=${environment}`;\n const res = await fetch(url, { headers: { 'X-API-Key': options.apiKey } });\n if (!res.ok) throw new Error(`pullSiteConfig: ${res.status} ${await res.text()}`);\n const data = await res.json();\n const raw = data?.data ?? data ?? { pages: [] };\n return normalizeSiteConfig(raw);\n}\n\nexport async function pushSiteConfig(options: NodeApiOptions, config: SiteConfig): Promise<void> {\n const base = options.apiUrl.replace(/\\/$/, '');\n const url = `${base}${BASE_PATH}/site-config?environment=draft`;\n const res = await fetch(url, {\n method: 'PUT',\n headers: { 'X-API-Key': options.apiKey, 'Content-Type': 'application/json' },\n body: JSON.stringify(config),\n });\n if (!res.ok) throw new Error(`pushSiteConfig: ${res.status} ${await res.text()}`);\n}\n\nexport async function promoteSiteConfig(options: NodeApiOptions): Promise<void> {\n const base = options.apiUrl.replace(/\\/$/, '');\n const url = `${base}${BASE_PATH}/site-config/promote`;\n const res = await fetch(url, { method: 'POST', headers: { 'X-API-Key': options.apiKey } });\n if (!res.ok) throw new Error(`promoteSiteConfig: ${res.status} ${await res.text()}`);\n}\n\nexport async function triggerWebhook(webhookUrl: string, payload?: { event: string; [k: string]: unknown }): Promise<void> {\n const url = webhookUrl.trim();\n if (!url) return;\n await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload ?? { event: 'onlistify.update' }),\n });\n}\n\nconst DEFAULT_PLUGIN_TYPES = ['onl-hero', 'onl-header'] as const;\n\nexport function getDefaultPluginsDir(): string {\n return path.join(getModuleDir(), '..', 'plugins');\n}\n\nexport function getDefaultPluginTypes(): readonly string[] {\n return DEFAULT_PLUGIN_TYPES;\n}\n\nexport interface ExportSiteProjectOptions {\n outputDir: string;\n environment?: 'draft' | 'live';\n includePlugins?: boolean;\n}\n\nexport async function exportSiteProject(\n options: NodeApiOptions,\n exportOptions: ExportSiteProjectOptions\n): Promise<{ configPath: string; pluginsPath?: string }> {\n const config = await pullSiteConfig(options, exportOptions.environment ?? 'draft');\n const outDir = path.resolve(process.cwd(), exportOptions.outputDir);\n fs.mkdirSync(outDir, { recursive: true });\n const configPath = path.join(outDir, 'site-config.draft.json');\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');\n\n let pluginsPath: string | undefined;\n if (exportOptions.includePlugins !== false) {\n const pluginsDir = path.join(outDir, 'plugins');\n fs.mkdirSync(pluginsDir, { recursive: true });\n const sdkPluginsDir = getDefaultPluginsDir();\n if (fs.existsSync(sdkPluginsDir)) {\n const files = fs.readdirSync(sdkPluginsDir);\n for (const f of files) {\n const src = path.join(sdkPluginsDir, f);\n if (fs.statSync(src).isFile()) fs.copyFileSync(src, path.join(pluginsDir, f));\n }\n pluginsPath = pluginsDir;\n }\n }\n return { configPath, pluginsPath };\n}\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Plugin de ejemplo: Hero (onl-hero)
|
|
2
|
+
|
|
3
|
+
Archivos:
|
|
4
|
+
- hero-plugin.js: define el custom element <onl-hero>
|
|
5
|
+
- hero-plugin.css: estilos del hero
|
|
6
|
+
- hero-plugin.schema.json: JSON Schema para validación y formularios en el editor
|
|
7
|
+
|
|
8
|
+
Contrato de bloque (estándar ONlistify):
|
|
9
|
+
- Tipo: identificador con guión (tag del custom element), ej. onl-hero.
|
|
10
|
+
- Props: el host inyecta data-props (JSON) o propiedad .props. El bloque lee y renderiza en connectedCallback.
|
|
11
|
+
- Entrada: el storefront hace createElement(block.type), asigna props, appendChild. Sin asumir framework; debe exponer custom element con ese tag.
|
|
12
|
+
|
|
13
|
+
Schema de bloque:
|
|
14
|
+
- Un schema.json por plugin con type "object", "title", "properties" (cada una con type, title, default). El editor puede usarlo para generar formularios. Ver hero-plugin.schema.json.
|
|
15
|
+
|
|
16
|
+
Políticas:
|
|
17
|
+
- Solo se cargan scripts desde URLs del registro de plugins (o PLUGIN_URLS por defecto). CSP del storefront debe incluir esos orígenes en script-src.
|
|
18
|
+
- Límites: bloques por página y tamaño de config validables en backend.
|
|
19
|
+
|
|
20
|
+
Crear otro plugin:
|
|
21
|
+
1. JS con customElements.define('mi-tag', MiClase); leer props de data-props o .props.
|
|
22
|
+
2. Opcional: schema.json y styles.css.
|
|
23
|
+
3. Registrar en PLUGIN_URLS (storefront) o vía API tenant_plugins.
|
|
24
|
+
4. En config del sitio: block con type: 'mi-tag' y props: { ... }.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
.onl-header {
|
|
2
|
+
background: var(--onl-header-bg, #1a365d);
|
|
3
|
+
color: var(--onl-header-color, #fff);
|
|
4
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
|
|
5
|
+
}
|
|
6
|
+
.onl-header--sticky {
|
|
7
|
+
position: sticky;
|
|
8
|
+
top: 0;
|
|
9
|
+
z-index: 100;
|
|
10
|
+
}
|
|
11
|
+
.onl-header-inner {
|
|
12
|
+
display: flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
justify-content: space-between;
|
|
15
|
+
gap: 1.5rem;
|
|
16
|
+
max-width: 1200px;
|
|
17
|
+
margin: 0 auto;
|
|
18
|
+
padding: 0.75rem 1.5rem;
|
|
19
|
+
flex-wrap: wrap;
|
|
20
|
+
}
|
|
21
|
+
.onl-header-brand {
|
|
22
|
+
display: flex;
|
|
23
|
+
align-items: center;
|
|
24
|
+
color: inherit;
|
|
25
|
+
text-decoration: none;
|
|
26
|
+
font-weight: 700;
|
|
27
|
+
}
|
|
28
|
+
.onl-header-brand:hover {
|
|
29
|
+
opacity: 0.9;
|
|
30
|
+
}
|
|
31
|
+
.onl-header-logo {
|
|
32
|
+
height: 2rem;
|
|
33
|
+
width: auto;
|
|
34
|
+
max-width: 160px;
|
|
35
|
+
object-fit: contain;
|
|
36
|
+
}
|
|
37
|
+
.onl-header-site-name {
|
|
38
|
+
font-size: 1.25rem;
|
|
39
|
+
letter-spacing: -0.02em;
|
|
40
|
+
}
|
|
41
|
+
.onl-header-nav {
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: center;
|
|
44
|
+
gap: 0.25rem 1.25rem;
|
|
45
|
+
flex-wrap: wrap;
|
|
46
|
+
}
|
|
47
|
+
.onl-header-link {
|
|
48
|
+
color: inherit;
|
|
49
|
+
text-decoration: none;
|
|
50
|
+
font-size: 0.9375rem;
|
|
51
|
+
font-weight: 500;
|
|
52
|
+
padding: 0.5rem 0.75rem;
|
|
53
|
+
border-radius: 6px;
|
|
54
|
+
transition: background 0.15s;
|
|
55
|
+
}
|
|
56
|
+
.onl-header-link:hover {
|
|
57
|
+
background: rgba(255, 255, 255, 0.15);
|
|
58
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
const tag = 'onl-header';
|
|
3
|
+
if (customElements.get(tag)) return;
|
|
4
|
+
|
|
5
|
+
class OnlHeader extends HTMLElement {
|
|
6
|
+
static get observedAttributes() { return ['data-props']; }
|
|
7
|
+
|
|
8
|
+
get props() {
|
|
9
|
+
try {
|
|
10
|
+
const raw = this.getAttribute('data-props') || this._propsJson || '{}';
|
|
11
|
+
return typeof raw === 'string' ? JSON.parse(raw) : raw;
|
|
12
|
+
} catch {
|
|
13
|
+
return {};
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
set props(v) {
|
|
17
|
+
this._propsJson = v;
|
|
18
|
+
this.setAttribute('data-props', JSON.stringify(v || {}));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
connectedCallback() {
|
|
22
|
+
const p = this.props;
|
|
23
|
+
const logoUrl = p.logoUrl || '';
|
|
24
|
+
const siteName = p.siteName || 'Inmobiliaria';
|
|
25
|
+
const navLinks = Array.isArray(p.navLinks) ? p.navLinks : [];
|
|
26
|
+
const bgColor = p.backgroundColor || 'var(--storefront-primary, #1a365d)';
|
|
27
|
+
const textColor = p.textColor || '#fff';
|
|
28
|
+
const sticky = p.sticky !== false;
|
|
29
|
+
|
|
30
|
+
const logoHtml = logoUrl
|
|
31
|
+
? `<img src="${escapeAttr(logoUrl)}" alt="${escapeAttr(siteName)}" class="onl-header-logo" />`
|
|
32
|
+
: `<span class="onl-header-site-name">${escapeHtml(siteName)}</span>`;
|
|
33
|
+
|
|
34
|
+
const navHtml =
|
|
35
|
+
navLinks.length > 0
|
|
36
|
+
? `<nav class="onl-header-nav">${navLinks
|
|
37
|
+
.map(
|
|
38
|
+
(link) =>
|
|
39
|
+
`<a href="${escapeAttr(link.href || '#')}" class="onl-header-link">${escapeHtml(link.label || '')}</a>`
|
|
40
|
+
)
|
|
41
|
+
.join('')}</nav>`
|
|
42
|
+
: '';
|
|
43
|
+
|
|
44
|
+
this.innerHTML = `
|
|
45
|
+
<header class="onl-header ${sticky ? 'onl-header--sticky' : ''}" style="--onl-header-bg:${escapeCss(bgColor)};--onl-header-color:${escapeCss(textColor)}">
|
|
46
|
+
<div class="onl-header-inner">
|
|
47
|
+
<a href="/" class="onl-header-brand">${logoHtml}</a>
|
|
48
|
+
${navHtml}
|
|
49
|
+
</div>
|
|
50
|
+
</header>
|
|
51
|
+
`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
attributeChangedCallback(name) {
|
|
55
|
+
if (name === 'data-props' && this.isConnected) this.connectedCallback();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function escapeHtml(s) {
|
|
60
|
+
const div = document.createElement('div');
|
|
61
|
+
div.textContent = s;
|
|
62
|
+
return div.innerHTML;
|
|
63
|
+
}
|
|
64
|
+
function escapeAttr(s) {
|
|
65
|
+
return String(s).replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
|
|
66
|
+
}
|
|
67
|
+
function escapeCss(s) {
|
|
68
|
+
return String(s).replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
customElements.define(tag, OnlHeader);
|
|
72
|
+
})();
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"type": "object",
|
|
4
|
+
"title": "Header",
|
|
5
|
+
"description": "Cabecera del sitio (onl-header). Logo, nombre y enlaces de navegación.",
|
|
6
|
+
"properties": {
|
|
7
|
+
"logoUrl": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"title": "URL del logo",
|
|
10
|
+
"default": ""
|
|
11
|
+
},
|
|
12
|
+
"siteName": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"title": "Nombre del sitio",
|
|
15
|
+
"default": "Inmobiliaria"
|
|
16
|
+
},
|
|
17
|
+
"navLinks": {
|
|
18
|
+
"type": "array",
|
|
19
|
+
"title": "Enlaces de navegación",
|
|
20
|
+
"items": {
|
|
21
|
+
"type": "object",
|
|
22
|
+
"properties": {
|
|
23
|
+
"label": { "type": "string", "title": "Texto" },
|
|
24
|
+
"href": { "type": "string", "title": "URL", "default": "#" }
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"default": []
|
|
28
|
+
},
|
|
29
|
+
"backgroundColor": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"title": "Color de fondo",
|
|
32
|
+
"default": "#1a365d"
|
|
33
|
+
},
|
|
34
|
+
"textColor": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"title": "Color del texto",
|
|
37
|
+
"default": "#fff"
|
|
38
|
+
},
|
|
39
|
+
"sticky": {
|
|
40
|
+
"type": "boolean",
|
|
41
|
+
"title": "Cabecera fija al hacer scroll",
|
|
42
|
+
"default": true
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
.onl-hero {
|
|
2
|
+
background: var(--onl-hero-bg, #1a365d);
|
|
3
|
+
color: var(--onl-hero-color, #fff);
|
|
4
|
+
padding: 3rem 1.5rem;
|
|
5
|
+
text-align: center;
|
|
6
|
+
}
|
|
7
|
+
.onl-hero-inner {
|
|
8
|
+
max-width: 720px;
|
|
9
|
+
margin: 0 auto;
|
|
10
|
+
}
|
|
11
|
+
.onl-hero-title {
|
|
12
|
+
margin: 0 0 0.75rem 0;
|
|
13
|
+
font-size: clamp(1.5rem, 4vw, 2.25rem);
|
|
14
|
+
font-weight: 700;
|
|
15
|
+
line-height: 1.2;
|
|
16
|
+
}
|
|
17
|
+
.onl-hero-subtitle {
|
|
18
|
+
margin: 0 0 1.5rem 0;
|
|
19
|
+
font-size: 1.125rem;
|
|
20
|
+
opacity: 0.95;
|
|
21
|
+
}
|
|
22
|
+
.onl-hero-cta {
|
|
23
|
+
display: inline-block;
|
|
24
|
+
padding: 0.75rem 1.5rem;
|
|
25
|
+
background: rgba(255,255,255,0.2);
|
|
26
|
+
color: inherit;
|
|
27
|
+
text-decoration: none;
|
|
28
|
+
border-radius: 8px;
|
|
29
|
+
font-weight: 600;
|
|
30
|
+
transition: background 0.2s;
|
|
31
|
+
}
|
|
32
|
+
.onl-hero-cta:hover {
|
|
33
|
+
background: rgba(255,255,255,0.3);
|
|
34
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
const tag = 'onl-hero';
|
|
3
|
+
if (customElements.get(tag)) return;
|
|
4
|
+
|
|
5
|
+
class OnlHero extends HTMLElement {
|
|
6
|
+
static get observedAttributes() { return ['data-props']; }
|
|
7
|
+
|
|
8
|
+
get props() {
|
|
9
|
+
try {
|
|
10
|
+
const raw = this.getAttribute('data-props') || this._propsJson || '{}';
|
|
11
|
+
return typeof raw === 'string' ? JSON.parse(raw) : raw;
|
|
12
|
+
} catch {
|
|
13
|
+
return {};
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
set props(v) {
|
|
17
|
+
this._propsJson = v;
|
|
18
|
+
this.setAttribute('data-props', JSON.stringify(v || {}));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
connectedCallback() {
|
|
22
|
+
const p = this.props;
|
|
23
|
+
const title = p.title || 'Bienvenido';
|
|
24
|
+
const subtitle = p.subtitle || '';
|
|
25
|
+
const ctaText = p.ctaText || '';
|
|
26
|
+
const ctaUrl = p.ctaUrl || '#';
|
|
27
|
+
const bgColor = p.backgroundColor || 'var(--storefront-primary, #1a365d)';
|
|
28
|
+
const textColor = p.textColor || '#fff';
|
|
29
|
+
|
|
30
|
+
this.innerHTML = `
|
|
31
|
+
<div class="onl-hero" style="--onl-hero-bg:${bgColor};--onl-hero-color:${textColor}">
|
|
32
|
+
<div class="onl-hero-inner">
|
|
33
|
+
<h1 class="onl-hero-title">${escapeHtml(title)}</h1>
|
|
34
|
+
${subtitle ? `<p class="onl-hero-subtitle">${escapeHtml(subtitle)}</p>` : ''}
|
|
35
|
+
${ctaText ? `<a href="${escapeAttr(ctaUrl)}" class="onl-hero-cta">${escapeHtml(ctaText)}</a>` : ''}
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
attributeChangedCallback(name) {
|
|
42
|
+
if (name === 'data-props' && this.isConnected) this.connectedCallback();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function escapeHtml(s) {
|
|
47
|
+
const div = document.createElement('div');
|
|
48
|
+
div.textContent = s;
|
|
49
|
+
return div.innerHTML;
|
|
50
|
+
}
|
|
51
|
+
function escapeAttr(s) {
|
|
52
|
+
return String(s).replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
customElements.define(tag, OnlHero);
|
|
56
|
+
})();
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"type": "object",
|
|
4
|
+
"title": "Hero",
|
|
5
|
+
"description": "Bloque Hero (onl-hero). Título, subtítulo y CTA.",
|
|
6
|
+
"properties": {
|
|
7
|
+
"title": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"title": "Título",
|
|
10
|
+
"default": "Bienvenido a tu inmobiliaria"
|
|
11
|
+
},
|
|
12
|
+
"subtitle": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"title": "Subtítulo",
|
|
15
|
+
"default": "Encuentra tu próximo hogar"
|
|
16
|
+
},
|
|
17
|
+
"ctaText": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"title": "Texto del botón",
|
|
20
|
+
"default": "Ver propiedades"
|
|
21
|
+
},
|
|
22
|
+
"ctaUrl": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"title": "URL del botón",
|
|
25
|
+
"default": "#"
|
|
26
|
+
},
|
|
27
|
+
"backgroundColor": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"title": "Color de fondo",
|
|
30
|
+
"default": "#1a365d"
|
|
31
|
+
},
|
|
32
|
+
"textColor": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"title": "Color del texto",
|
|
35
|
+
"default": "#fff"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onlistify/storefront",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -15,8 +15,21 @@
|
|
|
15
15
|
"types": "./dist/index.d.cts",
|
|
16
16
|
"default": "./dist/index.cjs"
|
|
17
17
|
}
|
|
18
|
+
},
|
|
19
|
+
"./node": {
|
|
20
|
+
"import": {
|
|
21
|
+
"types": "./dist/node.d.ts",
|
|
22
|
+
"default": "./dist/node.js"
|
|
23
|
+
},
|
|
24
|
+
"require": {
|
|
25
|
+
"types": "./dist/node.d.cts",
|
|
26
|
+
"default": "./dist/node.cjs"
|
|
27
|
+
}
|
|
18
28
|
}
|
|
19
29
|
},
|
|
30
|
+
"bin": {
|
|
31
|
+
"onlistify": "./dist/cli.js"
|
|
32
|
+
},
|
|
20
33
|
"files": [
|
|
21
34
|
"dist"
|
|
22
35
|
],
|
|
@@ -33,6 +46,7 @@
|
|
|
33
46
|
"ramda": "^0.29.1"
|
|
34
47
|
},
|
|
35
48
|
"devDependencies": {
|
|
49
|
+
"@types/node": "^25.5.0",
|
|
36
50
|
"@types/ramda": "^0.31.1",
|
|
37
51
|
"tsup": "^8.5.1",
|
|
38
52
|
"typescript": "~5.6.0",
|
|
@@ -41,7 +55,7 @@
|
|
|
41
55
|
"scripts": {
|
|
42
56
|
"dev": "vite",
|
|
43
57
|
"build": "tsc && vite build",
|
|
44
|
-
"build:sdk": "tsup",
|
|
58
|
+
"build:sdk": "tsup && node scripts/copy-plugins-to-dist.js",
|
|
45
59
|
"preview": "vite preview"
|
|
46
60
|
}
|
|
47
61
|
}
|