veleta-templates 0.0.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.
Files changed (147) hide show
  1. package/README.md +288 -0
  2. package/dist/cjs/app-globals-V2Kpy_OQ.js +8 -0
  3. package/dist/cjs/app-globals-V2Kpy_OQ.js.map +1 -0
  4. package/dist/cjs/index-rvPH40G4.js +1366 -0
  5. package/dist/cjs/index-rvPH40G4.js.map +1 -0
  6. package/dist/cjs/index.cjs.js +5 -0
  7. package/dist/cjs/index.cjs.js.map +1 -0
  8. package/dist/cjs/loader.cjs.js +16 -0
  9. package/dist/cjs/loader.cjs.js.map +1 -0
  10. package/dist/cjs/prop-parser-CqlyGycg.js +129 -0
  11. package/dist/cjs/prop-parser-CqlyGycg.js.map +1 -0
  12. package/dist/cjs/veleta-demo-template.cjs.entry.js +39 -0
  13. package/dist/cjs/veleta-menu-template-b.cjs.entry.js +60 -0
  14. package/dist/cjs/veleta-templates.cjs.js +28 -0
  15. package/dist/cjs/veleta-templates.cjs.js.map +1 -0
  16. package/dist/cjs/webfontloader-CDgRDOZ3.js +64 -0
  17. package/dist/cjs/webfontloader-CDgRDOZ3.js.map +1 -0
  18. package/dist/collection/collection-manifest.json +13 -0
  19. package/dist/collection/components/demo-template/demo-template.css +57 -0
  20. package/dist/collection/components/demo-template/demo-template.js +144 -0
  21. package/dist/collection/components/demo-template/demo-template.js.map +1 -0
  22. package/dist/collection/components/menu-template-b/menu-template-b.css +305 -0
  23. package/dist/collection/components/menu-template-b/menu-template-b.js +150 -0
  24. package/dist/collection/components/menu-template-b/menu-template-b.js.map +1 -0
  25. package/dist/collection/components.js +3 -0
  26. package/dist/collection/components.js.map +1 -0
  27. package/dist/collection/index.js +2 -0
  28. package/dist/collection/index.js.map +1 -0
  29. package/dist/collection/types/index.js +2 -0
  30. package/dist/collection/types/index.js.map +1 -0
  31. package/dist/collection/types/interfaces.js +2 -0
  32. package/dist/collection/types/interfaces.js.map +1 -0
  33. package/dist/collection/utils/data-helpers.js +16 -0
  34. package/dist/collection/utils/data-helpers.js.map +1 -0
  35. package/dist/collection/utils/font-loader.js +55 -0
  36. package/dist/collection/utils/font-loader.js.map +1 -0
  37. package/dist/collection/utils/mock-data.js +85 -0
  38. package/dist/collection/utils/mock-data.js.map +1 -0
  39. package/dist/collection/utils/prop-parser.js +65 -0
  40. package/dist/collection/utils/prop-parser.js.map +1 -0
  41. package/dist/components/index.d.ts +33 -0
  42. package/dist/components/index.js +1126 -0
  43. package/dist/components/index.js.map +1 -0
  44. package/dist/components/p-BtFpp-ge.js +124 -0
  45. package/dist/components/p-BtFpp-ge.js.map +1 -0
  46. package/dist/components/p-DjUJwx0S.js +62 -0
  47. package/dist/components/p-DjUJwx0S.js.map +1 -0
  48. package/dist/components/veleta-demo-template.d.ts +11 -0
  49. package/dist/components/veleta-demo-template.js +64 -0
  50. package/dist/components/veleta-demo-template.js.map +1 -0
  51. package/dist/components/veleta-menu-template-b.d.ts +11 -0
  52. package/dist/components/veleta-menu-template-b.js +85 -0
  53. package/dist/components/veleta-menu-template-b.js.map +1 -0
  54. package/dist/esm/app-globals-DQuL1Twl.js +6 -0
  55. package/dist/esm/app-globals-DQuL1Twl.js.map +1 -0
  56. package/dist/esm/index-zOTWMTLj.js +1341 -0
  57. package/dist/esm/index-zOTWMTLj.js.map +1 -0
  58. package/dist/esm/index.js +4 -0
  59. package/dist/esm/index.js.map +1 -0
  60. package/dist/esm/loader.js +14 -0
  61. package/dist/esm/loader.js.map +1 -0
  62. package/dist/esm/polyfills/core-js.js +11 -0
  63. package/dist/esm/polyfills/dom.js +79 -0
  64. package/dist/esm/polyfills/es5-html-element.js +1 -0
  65. package/dist/esm/polyfills/index.js +34 -0
  66. package/dist/esm/polyfills/system.js +6 -0
  67. package/dist/esm/prop-parser-D5qpnUIY.js +124 -0
  68. package/dist/esm/prop-parser-D5qpnUIY.js.map +1 -0
  69. package/dist/esm/veleta-demo-template.entry.js +37 -0
  70. package/dist/esm/veleta-demo-template.entry.js.map +1 -0
  71. package/dist/esm/veleta-menu-template-b.entry.js +58 -0
  72. package/dist/esm/veleta-menu-template-b.entry.js.map +1 -0
  73. package/dist/esm/veleta-templates.js +24 -0
  74. package/dist/esm/veleta-templates.js.map +1 -0
  75. package/dist/esm/webfontloader-DjUJwx0S.js +62 -0
  76. package/dist/esm/webfontloader-DjUJwx0S.js.map +1 -0
  77. package/dist/esm-es5/app-globals-DQuL1Twl.js +2 -0
  78. package/dist/esm-es5/app-globals-DQuL1Twl.js.map +1 -0
  79. package/dist/esm-es5/index-zOTWMTLj.js +2 -0
  80. package/dist/esm-es5/index-zOTWMTLj.js.map +1 -0
  81. package/dist/esm-es5/index.js +2 -0
  82. package/dist/esm-es5/index.js.map +1 -0
  83. package/dist/esm-es5/loader.js +2 -0
  84. package/dist/esm-es5/loader.js.map +1 -0
  85. package/dist/esm-es5/prop-parser-D5qpnUIY.js +2 -0
  86. package/dist/esm-es5/prop-parser-D5qpnUIY.js.map +1 -0
  87. package/dist/esm-es5/veleta-demo-template.entry.js +2 -0
  88. package/dist/esm-es5/veleta-demo-template.entry.js.map +1 -0
  89. package/dist/esm-es5/veleta-menu-template-b.entry.js +2 -0
  90. package/dist/esm-es5/veleta-menu-template-b.entry.js.map +1 -0
  91. package/dist/esm-es5/veleta-templates.js +2 -0
  92. package/dist/esm-es5/veleta-templates.js.map +1 -0
  93. package/dist/esm-es5/webfontloader-DjUJwx0S.js +2 -0
  94. package/dist/esm-es5/webfontloader-DjUJwx0S.js.map +1 -0
  95. package/dist/index.cjs.js +1 -0
  96. package/dist/index.js +1 -0
  97. package/dist/types/components/demo-template/demo-template.d.ts +12 -0
  98. package/dist/types/components/menu-template-b/menu-template-b.d.ts +11 -0
  99. package/dist/types/components.d.ts +116 -0
  100. package/dist/types/index.d.ts +1 -0
  101. package/dist/types/stencil-public-runtime.d.ts +1799 -0
  102. package/dist/types/types/index.d.ts +1 -0
  103. package/dist/types/types/interfaces.d.ts +39 -0
  104. package/dist/types/utils/data-helpers.d.ts +10 -0
  105. package/dist/types/utils/font-loader.d.ts +33 -0
  106. package/dist/types/utils/mock-data.d.ts +9 -0
  107. package/dist/types/utils/prop-parser.d.ts +11 -0
  108. package/dist/veleta-templates/index.esm.js +2 -0
  109. package/dist/veleta-templates/index.esm.js.map +1 -0
  110. package/dist/veleta-templates/loader.esm.js.map +1 -0
  111. package/dist/veleta-templates/p-1da2f609.entry.js +2 -0
  112. package/dist/veleta-templates/p-1da2f609.entry.js.map +1 -0
  113. package/dist/veleta-templates/p-6f14da26.system.entry.js +2 -0
  114. package/dist/veleta-templates/p-6f14da26.system.entry.js.map +1 -0
  115. package/dist/veleta-templates/p-6tMTQRgb.system.js +2 -0
  116. package/dist/veleta-templates/p-6tMTQRgb.system.js.map +1 -0
  117. package/dist/veleta-templates/p-9e099798.entry.js +2 -0
  118. package/dist/veleta-templates/p-9e099798.entry.js.map +1 -0
  119. package/dist/veleta-templates/p-BbPAtVJG.system.js +2 -0
  120. package/dist/veleta-templates/p-BbPAtVJG.system.js.map +1 -0
  121. package/dist/veleta-templates/p-BtFpp-ge.js +2 -0
  122. package/dist/veleta-templates/p-BtFpp-ge.js.map +1 -0
  123. package/dist/veleta-templates/p-D1BkLoGd.system.js +2 -0
  124. package/dist/veleta-templates/p-D1BkLoGd.system.js.map +1 -0
  125. package/dist/veleta-templates/p-D3ESHVSd.system.js +3 -0
  126. package/dist/veleta-templates/p-D3ESHVSd.system.js.map +1 -0
  127. package/dist/veleta-templates/p-DQuL1Twl.js +2 -0
  128. package/dist/veleta-templates/p-DQuL1Twl.js.map +1 -0
  129. package/dist/veleta-templates/p-DjUJwx0S.js +2 -0
  130. package/dist/veleta-templates/p-DjUJwx0S.js.map +1 -0
  131. package/dist/veleta-templates/p-YWpyar7R.system.js +2 -0
  132. package/dist/veleta-templates/p-YWpyar7R.system.js.map +1 -0
  133. package/dist/veleta-templates/p-bbAxcnzz.system.js +2 -0
  134. package/dist/veleta-templates/p-bbAxcnzz.system.js.map +1 -0
  135. package/dist/veleta-templates/p-e7ecc57b.system.entry.js +2 -0
  136. package/dist/veleta-templates/p-e7ecc57b.system.entry.js.map +1 -0
  137. package/dist/veleta-templates/p-zOTWMTLj.js +3 -0
  138. package/dist/veleta-templates/p-zOTWMTLj.js.map +1 -0
  139. package/dist/veleta-templates/veleta-templates.esm.js +2 -0
  140. package/dist/veleta-templates/veleta-templates.esm.js.map +1 -0
  141. package/dist/veleta-templates/veleta-templates.js +127 -0
  142. package/loader/cdn.js +2 -0
  143. package/loader/index.cjs.js +2 -0
  144. package/loader/index.d.ts +24 -0
  145. package/loader/index.es2017.js +2 -0
  146. package/loader/index.js +3 -0
  147. package/package.json +41 -0
@@ -0,0 +1,144 @@
1
+ import { h } from "@stencil/core";
2
+ import { loadFonts, applyFontFamily } from "../../utils/font-loader";
3
+ import { parseList } from "../../utils/prop-parser";
4
+ export class DemoTemplate {
5
+ constructor() {
6
+ this.sectionsJson = '[]';
7
+ this.dishesJson = '[]';
8
+ this.themeJson = '{}';
9
+ this.restaurantName = '';
10
+ // Configuración de fuente fija para este template
11
+ this.fontFamily = 'Roboto, sans-serif';
12
+ this.fontConfig = {
13
+ google: {
14
+ families: ['Roboto:300,400,700']
15
+ }
16
+ };
17
+ }
18
+ async componentWillLoad() {
19
+ // Cargar la fuente fija del template
20
+ await loadFonts(this.fontConfig);
21
+ applyFontFamily(this.el, this.fontFamily);
22
+ }
23
+ render() {
24
+ const sections = parseList(this.sectionsJson);
25
+ return (h("div", { key: '3603e4d5bad99be18a27160cf265f7d6c0e8c3dc', class: "veleta-demo-template" }, this.restaurantName && (h("h1", { key: '181dfda2dd33e72e14617f362399ad7fc5b02d87', class: "restaurant-name" }, this.restaurantName)), sections.length > 0 ? (h("div", { class: "sections-list" }, h("h2", { class: "sections-title" }, "Secciones"), h("ul", { class: "sections-ul" }, sections
26
+ .sort((a, b) => a.order - b.order)
27
+ .map((section) => (h("li", { key: section.id, class: "section-item" }, h("div", { class: "section-title-text" }, section.title), section.description && (h("div", { class: "section-description-text" }, section.description)))))))) : (h("p", { class: "no-sections" }, "No hay secciones disponibles"))));
28
+ }
29
+ static get is() { return "veleta-demo-template"; }
30
+ static get originalStyleUrls() {
31
+ return {
32
+ "$": ["demo-template.css"]
33
+ };
34
+ }
35
+ static get styleUrls() {
36
+ return {
37
+ "$": ["demo-template.css"]
38
+ };
39
+ }
40
+ static get properties() {
41
+ return {
42
+ "sectionsJson": {
43
+ "type": "string",
44
+ "mutable": false,
45
+ "complexType": {
46
+ "original": "string | Section[]",
47
+ "resolved": "Section[] | string",
48
+ "references": {
49
+ "Section": {
50
+ "location": "import",
51
+ "path": "../../types/interfaces",
52
+ "id": "src/types/interfaces.ts::Section"
53
+ }
54
+ }
55
+ },
56
+ "required": false,
57
+ "optional": false,
58
+ "docs": {
59
+ "tags": [],
60
+ "text": ""
61
+ },
62
+ "getter": false,
63
+ "setter": false,
64
+ "reflect": false,
65
+ "attribute": "sections-json",
66
+ "defaultValue": "'[]'"
67
+ },
68
+ "dishesJson": {
69
+ "type": "string",
70
+ "mutable": false,
71
+ "complexType": {
72
+ "original": "string | Dish[]",
73
+ "resolved": "Dish[] | string",
74
+ "references": {
75
+ "Dish": {
76
+ "location": "import",
77
+ "path": "../../types/interfaces",
78
+ "id": "src/types/interfaces.ts::Dish"
79
+ }
80
+ }
81
+ },
82
+ "required": false,
83
+ "optional": false,
84
+ "docs": {
85
+ "tags": [],
86
+ "text": ""
87
+ },
88
+ "getter": false,
89
+ "setter": false,
90
+ "reflect": false,
91
+ "attribute": "dishes-json",
92
+ "defaultValue": "'[]'"
93
+ },
94
+ "themeJson": {
95
+ "type": "string",
96
+ "mutable": false,
97
+ "complexType": {
98
+ "original": "string | Theme",
99
+ "resolved": "Theme | string",
100
+ "references": {
101
+ "Theme": {
102
+ "location": "import",
103
+ "path": "../../types/interfaces",
104
+ "id": "src/types/interfaces.ts::Theme"
105
+ }
106
+ }
107
+ },
108
+ "required": false,
109
+ "optional": false,
110
+ "docs": {
111
+ "tags": [],
112
+ "text": ""
113
+ },
114
+ "getter": false,
115
+ "setter": false,
116
+ "reflect": false,
117
+ "attribute": "theme-json",
118
+ "defaultValue": "'{}'"
119
+ },
120
+ "restaurantName": {
121
+ "type": "string",
122
+ "mutable": false,
123
+ "complexType": {
124
+ "original": "string",
125
+ "resolved": "string",
126
+ "references": {}
127
+ },
128
+ "required": false,
129
+ "optional": false,
130
+ "docs": {
131
+ "tags": [],
132
+ "text": ""
133
+ },
134
+ "getter": false,
135
+ "setter": false,
136
+ "reflect": false,
137
+ "attribute": "restaurant-name",
138
+ "defaultValue": "''"
139
+ }
140
+ };
141
+ }
142
+ static get elementRef() { return "el"; }
143
+ }
144
+ //# sourceMappingURL=demo-template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo-template.js","sourceRoot":"","sources":["../../../src/components/demo-template/demo-template.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE5D,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAOpD,MAAM,OAAO,YAAY;IALzB;QAQU,iBAAY,GAAuB,IAAI,CAAC;QACxC,eAAU,GAAoB,IAAI,CAAC;QACnC,cAAS,GAAmB,IAAI,CAAC;QACjC,mBAAc,GAAW,EAAE,CAAC;QAEpC,kDAAkD;QACjC,eAAU,GAAW,oBAAoB,CAAC;QAC1C,eAAU,GAAG;YAC5B,MAAM,EAAE;gBACN,QAAQ,EAAE,CAAC,oBAAoB,CAAC;aACjC;SACF,CAAC;KA2CH;IAzCC,KAAK,CAAC,iBAAiB;QACrB,qCAAqC;QACrC,MAAM,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACjC,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM;QACJ,MAAM,QAAQ,GAAG,SAAS,CAAU,IAAI,CAAC,YAAY,CAAC,CAAC;QAEvD,OAAO,CACL,4DAAK,KAAK,EAAC,sBAAsB;YAC9B,IAAI,CAAC,cAAc,IAAI,CACtB,2DAAI,KAAK,EAAC,iBAAiB,IACxB,IAAI,CAAC,cAAc,CACjB,CACN;YAEA,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACrB,WAAK,KAAK,EAAC,eAAe;gBACxB,UAAI,KAAK,EAAC,gBAAgB,gBAAe;gBACzC,UAAI,KAAK,EAAC,aAAa,IACpB,QAAQ;qBACN,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;qBACjC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAChB,UAAI,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAC,cAAc;oBACvC,WAAK,KAAK,EAAC,oBAAoB,IAAE,OAAO,CAAC,KAAK,CAAO;oBACpD,OAAO,CAAC,WAAW,IAAI,CACtB,WAAK,KAAK,EAAC,0BAA0B,IAClC,OAAO,CAAC,WAAW,CAChB,CACP,CACE,CACN,CAAC,CACD,CACD,CACP,CAAC,CAAC,CAAC,CACF,SAAG,KAAK,EAAC,aAAa,mCAAiC,CACxD,CACG,CACP,CAAC;IACJ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CACF","sourcesContent":["import { Component, Prop, h, Element } from '@stencil/core';\nimport { Section, Dish, Theme } from '../../types/interfaces';\nimport { loadFonts, applyFontFamily } from '../../utils/font-loader';\nimport { parseList } from '../../utils/prop-parser';\n\n@Component({\n tag: 'veleta-demo-template',\n styleUrl: 'demo-template.css',\n shadow: false,\n})\nexport class DemoTemplate {\n @Element() el: HTMLElement;\n\n @Prop() sectionsJson: string | Section[] = '[]';\n @Prop() dishesJson: string | Dish[] = '[]';\n @Prop() themeJson: string | Theme = '{}';\n @Prop() restaurantName: string = '';\n\n // Configuración de fuente fija para este template\n private readonly fontFamily: string = 'Roboto, sans-serif';\n private readonly fontConfig = {\n google: {\n families: ['Roboto:300,400,700']\n }\n };\n\n async componentWillLoad() {\n // Cargar la fuente fija del template\n await loadFonts(this.fontConfig);\n applyFontFamily(this.el, this.fontFamily);\n }\n\n render() {\n const sections = parseList<Section>(this.sectionsJson);\n\n return (\n <div class=\"veleta-demo-template\">\n {this.restaurantName && (\n <h1 class=\"restaurant-name\">\n {this.restaurantName}\n </h1>\n )}\n \n {sections.length > 0 ? (\n <div class=\"sections-list\">\n <h2 class=\"sections-title\">Secciones</h2>\n <ul class=\"sections-ul\">\n {sections\n .sort((a, b) => a.order - b.order)\n .map((section) => (\n <li key={section.id} class=\"section-item\">\n <div class=\"section-title-text\">{section.title}</div>\n {section.description && (\n <div class=\"section-description-text\">\n {section.description}\n </div>\n )}\n </li>\n ))}\n </ul>\n </div>\n ) : (\n <p class=\"no-sections\">No hay secciones disponibles</p>\n )}\n </div>\n );\n }\n}\n\n"]}
@@ -0,0 +1,305 @@
1
+ .menu-wrapper {
2
+ min-height: 100vh;
3
+ width: 100%;
4
+ padding: 1.5rem 1rem;
5
+ font-family: 'Merriweather', serif;
6
+ /* Reset para aislar de estilos globales */
7
+ box-sizing: border-box;
8
+ margin: 0;
9
+ display: block;
10
+ }
11
+
12
+ /* Asegurar que todos los elementos hijos usen border-box */
13
+ .menu-wrapper *,
14
+ .menu-wrapper *::before,
15
+ .menu-wrapper *::after {
16
+ box-sizing: border-box;
17
+ }
18
+
19
+ /* Reset completo de márgenes para todos los elementos HTML comunes */
20
+ .menu-wrapper h1,
21
+ .menu-wrapper h2,
22
+ .menu-wrapper h3,
23
+ .menu-wrapper h4,
24
+ .menu-wrapper h5,
25
+ .menu-wrapper h6,
26
+ .menu-wrapper p,
27
+ .menu-wrapper ul,
28
+ .menu-wrapper ol,
29
+ .menu-wrapper li,
30
+ .menu-wrapper header,
31
+ .menu-wrapper section,
32
+ .menu-wrapper article,
33
+ .menu-wrapper aside,
34
+ .menu-wrapper nav,
35
+ .menu-wrapper blockquote,
36
+ .menu-wrapper figure,
37
+ .menu-wrapper figcaption {
38
+ margin: 0;
39
+ margin-block-start: 0;
40
+ margin-block-end: 0;
41
+ margin-inline-start: 0;
42
+ margin-inline-end: 0;
43
+ }
44
+
45
+ /* Reset adicional para padding en listas */
46
+ .menu-wrapper ul,
47
+ .menu-wrapper ol {
48
+ padding: 0;
49
+ }
50
+
51
+ @media (min-width: 640px) {
52
+ .menu-wrapper {
53
+ padding: 2rem 1.5rem;
54
+ }
55
+ }
56
+
57
+ @media (min-width: 768px) {
58
+ .menu-wrapper {
59
+ padding: 2rem 1rem;
60
+ }
61
+ }
62
+
63
+ .menu-container {
64
+ max-width: 1280px;
65
+ margin: 0 auto;
66
+ }
67
+
68
+ .menu-header {
69
+ text-align: center;
70
+ }
71
+
72
+ @media (min-width: 768px) {
73
+ .menu-header {
74
+ margin-bottom: 3rem;
75
+ }
76
+ }
77
+
78
+ .restaurant-title {
79
+ font-size: 2rem;
80
+ font-weight: 700;
81
+ text-transform: uppercase;
82
+ letter-spacing: 0.05em;
83
+ line-height: 1.1;
84
+ margin: 0 0 1.5rem 0!important;
85
+ }
86
+
87
+ @media (min-width: 640px) {
88
+ .restaurant-title {
89
+ font-size: 2.5rem;
90
+ margin: 0 0 3rem 0!important;
91
+ }
92
+ }
93
+
94
+ @media (min-width: 768px) {
95
+ .restaurant-title {
96
+ font-size: 3rem;
97
+ }
98
+ }
99
+
100
+ @media (min-width: 1024px) {
101
+ .restaurant-title {
102
+ font-size: 3.5rem;
103
+ }
104
+ }
105
+
106
+ .sections-container {
107
+ display: grid;
108
+ grid-template-columns: 1fr;
109
+ gap: 3rem;
110
+ }
111
+
112
+ @media (min-width: 768px) {
113
+ .sections-container {
114
+ grid-template-columns: repeat(2, 1fr);
115
+ gap: 4rem;
116
+ }
117
+ }
118
+
119
+ .menu-section {
120
+ display: flex;
121
+ width: 100%;
122
+ position: relative;
123
+ }
124
+
125
+ /* Título vertical izquierdo */
126
+ .section-label-wrapper {
127
+ position: relative;
128
+ width: 3rem;
129
+ flex-shrink: 0;
130
+ margin-right: 1rem;
131
+ display: flex;
132
+ flex-direction: column;
133
+ align-items: center;
134
+ justify-content: flex-end;
135
+ }
136
+
137
+ .section-label-line {
138
+ position: absolute;
139
+ right: 0;
140
+ top: 0;
141
+ bottom: 0;
142
+ width: 1px;
143
+ border-right: 1px solid;
144
+ }
145
+
146
+ .section-label {
147
+ font-weight: 700;
148
+ font-size: 1.125rem;
149
+ text-transform: uppercase;
150
+ letter-spacing: 0.15em;
151
+ writing-mode: vertical-rl;
152
+ transform: rotate(180deg);
153
+ text-align: right;
154
+ white-space: nowrap;
155
+ margin: 0 0 0.5rem 0;
156
+ margin-block-end: 0.5rem;
157
+ position: absolute;
158
+ top: 0;
159
+ }
160
+
161
+ @media (min-width: 640px) {
162
+ .section-label {
163
+ font-size: 1.2375rem;
164
+ }
165
+ }
166
+
167
+ @media (min-width: 768px) {
168
+ .section-label {
169
+ font-size: 1.35rem;
170
+ }
171
+ }
172
+
173
+ @media (min-width: 1024px) {
174
+ .section-label {
175
+ font-size: 1.51875rem;
176
+ }
177
+ }
178
+
179
+ /* Contenido de la sección */
180
+ .section-content {
181
+ flex: 1;
182
+ padding-top: 0.25rem;
183
+ }
184
+
185
+ .section-description {
186
+ font-size: 0.875rem;
187
+ font-style: italic;
188
+ margin: 0 0 1rem 0!important;
189
+ margin-block-end: 1rem;
190
+ opacity: 0.75;
191
+ color: inherit;
192
+ }
193
+
194
+ @media (min-width: 640px) {
195
+ .section-description {
196
+ font-size: 0.9625rem;
197
+ }
198
+ }
199
+
200
+ @media (min-width: 768px) {
201
+ .section-description {
202
+ font-size: 1.05rem;
203
+ }
204
+ }
205
+
206
+ @media (min-width: 1024px) {
207
+ .section-description {
208
+ font-size: 1.18125rem;
209
+ }
210
+ }
211
+
212
+ .dishes-list {
213
+ list-style: none;
214
+ padding: 0;
215
+ margin: 0;
216
+ display: flex;
217
+ flex-direction: column;
218
+ gap: 1rem;
219
+ }
220
+
221
+ .dish-item {
222
+ position: relative;
223
+ }
224
+
225
+ .dish-header {
226
+ display: flex;
227
+ align-items: baseline;
228
+ width: 100%;
229
+ gap: 0.5rem;
230
+ }
231
+
232
+ .dish-name {
233
+ font-size: 1rem;
234
+ font-weight: 700;
235
+ text-transform: uppercase;
236
+ letter-spacing: 0.05em;
237
+ flex-shrink: 0;
238
+ }
239
+
240
+ @media (min-width: 640px) {
241
+ .dish-name {
242
+ font-size: 1.1rem;
243
+ }
244
+ }
245
+
246
+ @media (min-width: 768px) {
247
+ .dish-name {
248
+ font-size: 1.2rem;
249
+ }
250
+ }
251
+
252
+ @media (min-width: 1024px) {
253
+ .dish-name {
254
+ font-size: 1.35rem;
255
+ }
256
+ }
257
+
258
+ .dish-dots {
259
+ flex: 1;
260
+ opacity: 0.25;
261
+ border-bottom: 1px dotted;
262
+ margin: 0 0.55rem;
263
+ position: relative;
264
+ top: -5px;
265
+ border-color: currentColor;
266
+ }
267
+
268
+ .dish-price {
269
+ font-size: 1rem;
270
+ font-weight: 700;
271
+ flex-shrink: 0;
272
+ text-align: right;
273
+ }
274
+
275
+ @media (min-width: 640px) {
276
+ .dish-price {
277
+ font-size: 1.1rem;
278
+ }
279
+ }
280
+
281
+ @media (min-width: 768px) {
282
+ .dish-price {
283
+ font-size: 1.2rem;
284
+ }
285
+ }
286
+
287
+ @media (min-width: 1024px) {
288
+ .dish-price {
289
+ font-size: 1.35rem;
290
+ }
291
+ }
292
+
293
+ .dish-description {
294
+ font-size: 0.8125rem;
295
+ margin-top: -0.9rem;
296
+ line-height: 1.4;
297
+ opacity: 0.7;
298
+ color: inherit;
299
+ }
300
+
301
+ @media (min-width: 640px) {
302
+ .dish-description {
303
+ font-size: 0.9425rem;
304
+ }
305
+ }
@@ -0,0 +1,150 @@
1
+ import { h } from "@stencil/core";
2
+ import { loadFonts, applyFontFamily } from "../../utils/font-loader";
3
+ import { parseList, parseTheme } from "../../utils/prop-parser";
4
+ import { getDishesBySection, formatPrice } from "../../utils/data-helpers";
5
+ export class MenuTemplateB {
6
+ constructor() {
7
+ this.sectionsJson = '[]';
8
+ this.dishesJson = '[]';
9
+ this.themeJson = '{}';
10
+ this.restaurantName = '';
11
+ this.fontConfig = {
12
+ google: {
13
+ families: ['Oswald:400,600,700', 'Merriweather:300,400,700'],
14
+ },
15
+ };
16
+ }
17
+ async componentWillLoad() {
18
+ await loadFonts(this.fontConfig);
19
+ applyFontFamily(this.el, 'Merriweather, serif');
20
+ }
21
+ render() {
22
+ const sections = parseList(this.sectionsJson).sort((a, b) => a.order - b.order);
23
+ const dishes = parseList(this.dishesJson);
24
+ const theme = parseTheme(this.themeJson);
25
+ const primary = (theme === null || theme === void 0 ? void 0 : theme.primaryColor) || '#1a365d';
26
+ const fontBody = 'Merriweather, serif';
27
+ const fontTitle = 'Oswald, sans-serif';
28
+ return (h("div", { key: '13f686e0069dee50b0b177187cd377f50d6935d2', class: "menu-wrapper", style: { color: primary } }, h("div", { key: 'b3d1b79d94cb4060e429f520122f2780b67e284b', class: "menu-container" }, this.restaurantName && (h("header", { key: '80b7b01796c067c64191ebe02904df58156b1305', class: "menu-header" }, h("h1", { key: 'b75dd9d478241674dc1e7728d238b1d390cfac82', class: "restaurant-title", style: { fontFamily: fontTitle } }, this.restaurantName))), h("div", { key: '96995a7755759113e096c9defb125ee41fda20b6', class: "sections-container" }, sections.map(section => {
29
+ const sectionDishes = getDishesBySection(section.id, dishes);
30
+ if (!sectionDishes.length)
31
+ return null;
32
+ return (h("section", { key: section.id, class: "menu-section" }, h("div", { class: "section-label-wrapper" }, h("div", { class: "section-label-line", style: { borderColor: primary } }), h("h2", { class: "section-label", style: { fontFamily: fontTitle, color: primary } }, section.title)), h("div", { class: "section-content" }, section.description && (h("p", { class: "section-description", style: { fontFamily: fontBody } }, section.description)), h("ul", { class: "dishes-list" }, sectionDishes.map(dish => (h("li", { key: dish.id, class: "dish-item" }, h("div", { class: "dish-header" }, h("h3", { class: "dish-name", style: { fontFamily: fontTitle, color: primary } }, dish.name), h("div", { class: "dish-dots" }), h("span", { class: "dish-price", style: { fontFamily: fontTitle, color: primary } }, formatPrice(dish.price))), dish.description && (h("p", { class: "dish-description", style: { fontFamily: fontBody } }, dish.description)))))))));
33
+ })))));
34
+ }
35
+ static get is() { return "veleta-menu-template-b"; }
36
+ static get originalStyleUrls() {
37
+ return {
38
+ "$": ["menu-template-b.css"]
39
+ };
40
+ }
41
+ static get styleUrls() {
42
+ return {
43
+ "$": ["menu-template-b.css"]
44
+ };
45
+ }
46
+ static get properties() {
47
+ return {
48
+ "sectionsJson": {
49
+ "type": "string",
50
+ "mutable": false,
51
+ "complexType": {
52
+ "original": "string | Section[]",
53
+ "resolved": "Section[] | string",
54
+ "references": {
55
+ "Section": {
56
+ "location": "import",
57
+ "path": "../../types/interfaces",
58
+ "id": "src/types/interfaces.ts::Section"
59
+ }
60
+ }
61
+ },
62
+ "required": false,
63
+ "optional": false,
64
+ "docs": {
65
+ "tags": [],
66
+ "text": ""
67
+ },
68
+ "getter": false,
69
+ "setter": false,
70
+ "reflect": false,
71
+ "attribute": "sections-json",
72
+ "defaultValue": "'[]'"
73
+ },
74
+ "dishesJson": {
75
+ "type": "string",
76
+ "mutable": false,
77
+ "complexType": {
78
+ "original": "string | Dish[]",
79
+ "resolved": "Dish[] | string",
80
+ "references": {
81
+ "Dish": {
82
+ "location": "import",
83
+ "path": "../../types/interfaces",
84
+ "id": "src/types/interfaces.ts::Dish"
85
+ }
86
+ }
87
+ },
88
+ "required": false,
89
+ "optional": false,
90
+ "docs": {
91
+ "tags": [],
92
+ "text": ""
93
+ },
94
+ "getter": false,
95
+ "setter": false,
96
+ "reflect": false,
97
+ "attribute": "dishes-json",
98
+ "defaultValue": "'[]'"
99
+ },
100
+ "themeJson": {
101
+ "type": "string",
102
+ "mutable": false,
103
+ "complexType": {
104
+ "original": "string | Theme",
105
+ "resolved": "Theme | string",
106
+ "references": {
107
+ "Theme": {
108
+ "location": "import",
109
+ "path": "../../types/interfaces",
110
+ "id": "src/types/interfaces.ts::Theme"
111
+ }
112
+ }
113
+ },
114
+ "required": false,
115
+ "optional": false,
116
+ "docs": {
117
+ "tags": [],
118
+ "text": ""
119
+ },
120
+ "getter": false,
121
+ "setter": false,
122
+ "reflect": false,
123
+ "attribute": "theme-json",
124
+ "defaultValue": "'{}'"
125
+ },
126
+ "restaurantName": {
127
+ "type": "string",
128
+ "mutable": false,
129
+ "complexType": {
130
+ "original": "string",
131
+ "resolved": "string",
132
+ "references": {}
133
+ },
134
+ "required": false,
135
+ "optional": false,
136
+ "docs": {
137
+ "tags": [],
138
+ "text": ""
139
+ },
140
+ "getter": false,
141
+ "setter": false,
142
+ "reflect": false,
143
+ "attribute": "restaurant-name",
144
+ "defaultValue": "''"
145
+ }
146
+ };
147
+ }
148
+ static get elementRef() { return "el"; }
149
+ }
150
+ //# sourceMappingURL=menu-template-b.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu-template-b.js","sourceRoot":"","sources":["../../../src/components/menu-template-b/menu-template-b.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Prop, h, Element } from '@stencil/core';\nimport { Section, Dish, Theme } from '../../types/interfaces';\nimport { loadFonts, applyFontFamily } from '../../utils/font-loader';\nimport { parseList, parseTheme } from '../../utils/prop-parser';\nimport { getDishesBySection, formatPrice } from '../../utils/data-helpers';\n\n@Component({\n tag: 'veleta-menu-template-b',\n styleUrl: 'menu-template-b.css',\n shadow: false,\n})\nexport class MenuTemplateB {\n @Element() el: HTMLElement;\n\n @Prop() sectionsJson: string | Section[] = '[]';\n @Prop() dishesJson: string | Dish[] = '[]';\n @Prop() themeJson: string | Theme = '{}';\n @Prop() restaurantName: string = '';\n\n private readonly fontConfig = {\n google: {\n families: ['Oswald:400,600,700', 'Merriweather:300,400,700'],\n },\n };\n\n async componentWillLoad() {\n await loadFonts(this.fontConfig);\n applyFontFamily(this.el, 'Merriweather, serif');\n }\n\n render() {\n const sections = parseList<Section>(this.sectionsJson).sort(\n (a, b) => a.order - b.order,\n );\n const dishes = parseList<Dish>(this.dishesJson);\n const theme = parseTheme(this.themeJson);\n\n const primary = theme?.primaryColor || '#1a365d';\n const fontBody = 'Merriweather, serif';\n const fontTitle = 'Oswald, sans-serif';\n\n return (\n <div\n class=\"menu-wrapper\"\n style={{ color: primary }}\n >\n <div class=\"menu-container\">\n {this.restaurantName && (\n <header class=\"menu-header\">\n <h1 class=\"restaurant-title\" style={{ fontFamily: fontTitle }}>\n {this.restaurantName}\n </h1>\n </header>\n )}\n\n {/* Layout: 1 columna mobile, 2 columnas tablet/desktop */}\n <div class=\"sections-container\">\n {sections.map(section => {\n const sectionDishes = getDishesBySection(section.id, dishes);\n if (!sectionDishes.length) return null;\n\n return (\n <section key={section.id} class=\"menu-section\">\n {/* Título vertical izquierdo */}\n <div class=\"section-label-wrapper\">\n <div class=\"section-label-line\" style={{ borderColor: primary }}></div>\n <h2\n class=\"section-label\"\n style={{ fontFamily: fontTitle, color: primary }}\n >\n {section.title}\n </h2>\n </div>\n\n {/* Contenido de platos */}\n <div class=\"section-content\">\n {section.description && (\n <p class=\"section-description\" style={{ fontFamily: fontBody }}>\n {section.description}\n </p>\n )}\n\n <ul class=\"dishes-list\">\n {sectionDishes.map(dish => (\n <li key={dish.id} class=\"dish-item\">\n <div class=\"dish-header\">\n <h3\n class=\"dish-name\"\n style={{ fontFamily: fontTitle, color: primary }}\n >\n {dish.name}\n </h3>\n <div\n class=\"dish-dots\"\n ></div>\n <span\n class=\"dish-price\"\n style={{ fontFamily: fontTitle, color: primary }}\n >\n {formatPrice(dish.price)}\n </span>\n </div>\n {dish.description && (\n <p class=\"dish-description\" style={{ fontFamily: fontBody }}>\n {dish.description}\n </p>\n )}\n </li>\n ))}\n </ul>\n </div>\n </section>\n );\n })}\n </div>\n </div>\n </div>\n );\n }\n}"]}
@@ -0,0 +1,3 @@
1
+ export * from './components/demo-template/demo-template';
2
+ export * from './components/menu-template-b/menu-template-b';
3
+ //# sourceMappingURL=components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.js","sourceRoot":"","sources":["../src/components.ts"],"names":[],"mappings":"AAAA,cAAc,0CAA0C,CAAC;AACzD,cAAc,8CAA8C,CAAC","sourcesContent":["export * from './components/demo-template/demo-template';\nexport * from './components/menu-template-b/menu-template-b';\n\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"","sourcesContent":["export { Components, JSX } from './components.d';\n\n"]}
@@ -0,0 +1,2 @@
1
+ export * from './interfaces';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC","sourcesContent":["export * from './interfaces';\n\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=interfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../src/types/interfaces.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Representa una sección del menú que agrupa platos.\n */\nexport interface Section {\n id: string; // Identificador único de la sección (requerido)\n title: string; // Título de la sección (requerido)\n description?: string; // Descripción opcional de la sección\n order: number; // Índice de orden para ordenar secciones (requerido)\n}\n\n/**\n * Representa un plato individual del menú que pertenece a una sección.\n */\nexport interface Dish {\n id: string; // Identificador único del plato (requerido)\n name: string; // Nombre del plato (requerido)\n price: number; // Precio del plato en euros (requerido, > 0)\n description?: string; // Descripción opcional del plato\n sectionId: string; // ID de la sección a la que pertenece (requerido)\n order: number; // Índice de orden dentro de la sección (requerido)\n}\n\n/**\n * Representa la configuración de colores del tema para el template.\n */\nexport interface Theme {\n id: string; // Identificador único del tema (requerido)\n name: string; // Nombre del tema (requerido)\n primaryColor: string; // Color primario en formato hexadecimal (requerido, ej: \"#3B82F6\")\n secondaryColor?: string | null; // Color secundario en formato hexadecimal (opcional, ej: \"#60A5FA\")\n backgroundColor?: string | null; // Color de fondo en formato hexadecimal (opcional, ej: \"#FFFFFF\")\n}\n\n/**\n * Propiedades que reciben los componentes Stencil como strings JSON.\n */\nexport interface TemplateProps {\n restaurantName: string; // Nombre del restaurante\n sectionsJson: string; // JSON string del array de secciones\n dishesJson: string; // JSON string del array de platos\n themeJson: string; // JSON string del objeto de tema\n}\n\n"]}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Obtiene los platos de una sección específica, ordenados por order.
3
+ */
4
+ export function getDishesBySection(sectionId, dishes) {
5
+ return dishes
6
+ .filter(d => d.sectionId === sectionId)
7
+ .sort((a, b) => a.order - b.order);
8
+ }
9
+ /**
10
+ * Formatea un precio como string con símbolo de euro.
11
+ * Si es un número entero, no muestra decimales.
12
+ */
13
+ export function formatPrice(price) {
14
+ return (price % 1 === 0 ? price.toString() : price.toFixed(2)) + '€';
15
+ }
16
+ //# sourceMappingURL=data-helpers.js.map