@onetype/framework 2.0.22 → 2.0.25

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 (128) hide show
  1. package/addons/core/assets/back/functions/import.js +24 -0
  2. package/docs/architecture.md +58 -10
  3. package/docs/frontend.md +29 -12
  4. package/lib/items/elements/form/button/button.js +106 -0
  5. package/lib/items/elements/form/button/styles/base.css +176 -0
  6. package/lib/items/elements/form/button/styles/sizes.css +78 -0
  7. package/lib/items/elements/form/button/styles/variants.css +421 -0
  8. package/lib/items/elements/form/checkbox/checkbox.js +58 -0
  9. package/lib/items/elements/form/checkbox/styles/base.css +52 -0
  10. package/lib/items/elements/form/checkbox/styles/sizes.css +39 -0
  11. package/lib/items/elements/form/checkbox/styles/variants.css +121 -0
  12. package/lib/items/elements/form/field/field.css +96 -0
  13. package/lib/items/elements/form/field/field.js +40 -0
  14. package/lib/items/elements/form/input/input.css +111 -0
  15. package/lib/items/elements/form/input/input.js +79 -0
  16. package/lib/items/elements/form/input/styles/base.css +26 -0
  17. package/lib/items/elements/form/input/styles/sizes.css +15 -0
  18. package/lib/items/elements/form/input/styles/variants.css +98 -0
  19. package/lib/items/elements/form/radio/radio.js +58 -0
  20. package/lib/items/elements/form/radio/styles/base.css +48 -0
  21. package/lib/items/elements/form/radio/styles/sizes.css +36 -0
  22. package/lib/items/elements/form/radio/styles/variants.css +121 -0
  23. package/lib/items/elements/form/rating/rating.css +95 -0
  24. package/lib/items/elements/form/rating/rating.js +89 -0
  25. package/lib/items/elements/form/section/section.css +129 -0
  26. package/lib/items/elements/form/section/section.js +40 -0
  27. package/lib/items/elements/form/slider/slider.css +244 -0
  28. package/lib/items/elements/form/slider/slider.js +70 -0
  29. package/lib/items/elements/form/textarea/textarea.css +117 -0
  30. package/lib/items/elements/form/textarea/textarea.js +70 -0
  31. package/lib/items/elements/global/card/card.css +57 -0
  32. package/lib/items/elements/global/card/card.js +48 -0
  33. package/lib/items/elements/global/code/code.css +66 -0
  34. package/lib/items/elements/global/code/code.js +40 -0
  35. package/lib/items/elements/global/faq/faq.css +76 -0
  36. package/lib/items/elements/global/faq/faq.js +44 -0
  37. package/lib/items/elements/global/heading/heading.css +106 -0
  38. package/lib/items/elements/global/heading/heading.js +52 -0
  39. package/lib/items/elements/global/markdown/markdown.css +248 -0
  40. package/lib/items/elements/global/markdown/markdown.js +23 -0
  41. package/lib/items/elements/global/notice/notice.css +91 -0
  42. package/lib/items/elements/global/notice/notice.js +35 -0
  43. package/lib/items/elements/global/parameters/params.css +69 -0
  44. package/lib/items/elements/global/parameters/params.js +32 -0
  45. package/lib/items/elements/global/tabs/tabs.css +47 -0
  46. package/lib/items/elements/global/tabs/tabs.js +32 -0
  47. package/lib/items/elements/global/tags/tags.css +42 -0
  48. package/lib/items/elements/global/tags/tags.js +46 -0
  49. package/lib/items/elements/sections/footer/footer.css +205 -0
  50. package/lib/items/elements/sections/footer/footer.js +109 -0
  51. package/lib/items/elements/sections/hero/hero.css +100 -0
  52. package/lib/items/elements/sections/hero/hero.js +54 -0
  53. package/lib/items/elements/sections/navbar/navbar.css +80 -0
  54. package/lib/items/elements/sections/navbar/navbar.js +42 -0
  55. package/lib/items/elements/sections/stats/stats.css +34 -0
  56. package/lib/items/elements/sections/stats/stats.js +74 -0
  57. package/lib/items/elements/status/code/code.css +48 -0
  58. package/lib/items/elements/status/code/code.js +44 -0
  59. package/lib/items/elements/status/empty/empty.css +59 -0
  60. package/lib/items/elements/status/empty/empty.js +43 -0
  61. package/lib/items/elements/status/error/error.css +55 -0
  62. package/lib/items/elements/status/error/error.js +55 -0
  63. package/lib/items/elements/status/loading/loading.css +62 -0
  64. package/lib/items/elements/status/loading/loading.js +31 -0
  65. package/lib/load.js +83 -5
  66. package/lib/src/classes/addon/class.js +1 -1
  67. package/lib/src/classes/addon/mixins/store.js +8 -8
  68. package/lib/src/mixins/assets.js +65 -0
  69. package/lib/src/onetype.js +4 -0
  70. package/lib/styles/classes/layout.css +36 -0
  71. package/lib/styles/classes/spacing.css +96 -0
  72. package/lib/styles/queries.css +6 -0
  73. package/lib/styles/reset.css +169 -0
  74. package/lib/styles/variables.css +71 -0
  75. package/package.json +3 -3
  76. package/addons/core/clients/LICENSE.txt +0 -40
  77. package/addons/core/clients/README.md +0 -123
  78. package/addons/core/database/README.md +0 -276
  79. package/addons/render/assets/back/README.md +0 -1
  80. package/addons/render/assets/back/functions/import.js +0 -45
  81. package/addons/render/items/js/#register/addon.js +0 -14
  82. package/addons/render/items/js/functions/count.js +0 -9
  83. package/addons/render/items/js/functions/get.js +0 -34
  84. package/addons/render/items/js/functions/groups.js +0 -16
  85. package/addons/render/items/js/functions/render.js +0 -44
  86. package/addons/render/items/js/item/catch/add.js +0 -18
  87. package/test/front/test.js +0 -56
  88. package/test.js +0 -55
  89. /package/addons/{render → core}/assets/back/addon.js +0 -0
  90. /package/addons/{render → core}/assets/back/functions/css.js +0 -0
  91. /package/addons/{render → core}/assets/back/functions/js.js +0 -0
  92. /package/addons/{render → core}/assets/back/functions/scan/directories.js +0 -0
  93. /package/addons/{render → core}/assets/back/functions/scan/files.js +0 -0
  94. /package/addons/{render → core}/assets/back/functions/utils/read.js +0 -0
  95. /package/addons/{render → core}/assets/back/functions/utils/transform.js +0 -0
  96. /package/addons/{render → core}/assets/back/items/commands/css.js +0 -0
  97. /package/addons/{render → core}/assets/back/items/commands/js.js +0 -0
  98. /package/addons/{render → core}/assets/back/items/html/css.js +0 -0
  99. /package/addons/{render → core}/assets/back/items/html/js.js +0 -0
  100. /package/addons/{render → core}/assets/back/load.js +0 -0
  101. /package/addons/core/database/front/{#register/addon.js → addon.js} +0 -0
  102. /package/addons/float/modals/front/js/{#register/addon.js → addon.js} +0 -0
  103. /package/addons/float/overlays/front/js/{#register/addon.js → addon.js} +0 -0
  104. /package/addons/float/popups/js/{#register/addon.js → addon.js} +0 -0
  105. /package/addons/float/toasts/{#register/addon.js → addon.js} +0 -0
  106. /package/addons/float/tooltips/{#register/addon.js → addon.js} +0 -0
  107. /package/addons/render/transforms/{front/js/#register/addon.js → addon.js} +0 -0
  108. /package/addons/render/transforms/{front/js/functions → functions}/load/assets.js +0 -0
  109. /package/addons/render/transforms/{front/js/items → items}/directives/transform.js +0 -0
  110. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms/accordion}/accordion.js +0 -0
  111. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms}/chart/area.js +0 -0
  112. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms}/chart/bar.js +0 -0
  113. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms}/chart/bubble.js +0 -0
  114. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms}/chart/doughnut.js +0 -0
  115. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms}/chart/line.js +0 -0
  116. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms}/chart/pie.js +0 -0
  117. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms}/chart/radar.js +0 -0
  118. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms}/chart/scatter.js +0 -0
  119. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms/codeflask}/codeflask.js +0 -0
  120. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms/codemirror}/codemirror.js +0 -0
  121. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms/comparison}/comparison.js +0 -0
  122. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms/heatmap}/heatmap.js +0 -0
  123. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms/interact}/interact.js +0 -0
  124. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms/particles}/particles.js +0 -0
  125. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms/sparkline}/sparkline.js +0 -0
  126. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms/swiper}/swiper.js +0 -0
  127. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms/tabs}/tabs.js +0 -0
  128. /package/{addons/render/transforms/front/js/items/self → lib/items/transforms/typed}/typed.js +0 -0
@@ -0,0 +1,70 @@
1
+ onetype.AddonReady('elements', (elements) =>
2
+ {
3
+ elements.ItemAdd({
4
+ id: 'form-slider',
5
+ icon: 'linear_scale',
6
+ name: 'Slider',
7
+ description: 'Range slider input for selecting numeric values.',
8
+ category: 'Form',
9
+ author: 'OneType',
10
+ config: {
11
+ value: {
12
+ type: 'number',
13
+ value: 50
14
+ },
15
+ min: {
16
+ type: 'number',
17
+ value: 0
18
+ },
19
+ max: {
20
+ type: 'number',
21
+ value: 100
22
+ },
23
+ step: {
24
+ type: 'number',
25
+ value: 10
26
+ },
27
+ variant: {
28
+ type: 'array',
29
+ value: ['brand', 'size-m'],
30
+ options: ['brand', 'blue', 'red', 'orange', 'green', 'size-s', 'size-m', 'size-l']
31
+ },
32
+ onChange: {
33
+ type: 'function'
34
+ }
35
+ },
36
+ render: function()
37
+ {
38
+ this.handleInput = (event) =>
39
+ {
40
+ this.value = parseFloat(event.target.value);
41
+ if (this.onChange)
42
+ {
43
+ this.onChange(this.value);
44
+ }
45
+ };
46
+
47
+ this.getPercentage = () =>
48
+ {
49
+ return ((this.value - this.min) / (this.max - this.min)) * 100;
50
+ };
51
+
52
+ return `
53
+ <div class="holder" :variant="variant.join(' ')">
54
+ <div class="track">
55
+ <div class="fill" :style="'width: ' + getPercentage() + '%'"></div>
56
+ </div>
57
+ <input
58
+ type="range"
59
+ class="input"
60
+ :value="value"
61
+ :min="min"
62
+ :max="max"
63
+ :step="step"
64
+ ot-input="handleInput"
65
+ />
66
+ </div>
67
+ `;
68
+ }
69
+ });
70
+ });
@@ -0,0 +1,117 @@
1
+ /* Base */
2
+ .e-5973ffcd > .holder
3
+ {
4
+ position: relative;
5
+ width: 100%;
6
+ padding: var(--ot-spacing-s) var(--ot-spacing-m);
7
+ border-radius: var(--ot-radius-m);
8
+ border: none;
9
+ background: transparent;
10
+ transition: all 0.2s;
11
+ }
12
+
13
+ .e-5973ffcd > .holder > textarea
14
+ {
15
+ width: 100%;
16
+ background: transparent;
17
+ border: none;
18
+ outline: none;
19
+ min-height: 100px;
20
+ resize: none;
21
+ color: var(--ot-text-1);
22
+ padding: 0;
23
+ }
24
+
25
+ .e-5973ffcd > .holder > textarea::placeholder
26
+ {
27
+ color: var(--ot-text-2);
28
+ }
29
+
30
+ .e-5973ffcd > .holder > textarea:disabled
31
+ {
32
+ opacity: 0.5;
33
+ cursor: not-allowed;
34
+ }
35
+
36
+ /* Variants - Background */
37
+ .e-5973ffcd > .holder[variant*="transparent"]
38
+ {
39
+ background: transparent;
40
+ padding: 0;
41
+ }
42
+
43
+ .e-5973ffcd > .holder[variant*="border"]
44
+ {
45
+ background: transparent;
46
+ }
47
+
48
+ .e-5973ffcd > .holder[variant*="bg-1"]
49
+ {
50
+ background: var(--ot-bg-1);
51
+ }
52
+
53
+ .e-5973ffcd > .holder[variant*="bg-1"]:hover
54
+ {
55
+ background: var(--ot-bg-1-hover);
56
+ }
57
+
58
+ .e-5973ffcd > .holder[variant*="bg-2"]
59
+ {
60
+ background: var(--ot-bg-2);
61
+ }
62
+
63
+ .e-5973ffcd > .holder[variant*="bg-2"]:hover
64
+ {
65
+ background: var(--ot-bg-2-hover);
66
+ }
67
+
68
+ .e-5973ffcd > .holder[variant*="bg-3"]
69
+ {
70
+ background: var(--ot-bg-3);
71
+ }
72
+
73
+ .e-5973ffcd > .holder[variant*="bg-3"]:hover
74
+ {
75
+ background: var(--ot-bg-3-hover);
76
+ }
77
+
78
+ .e-5973ffcd > .holder[variant*="bg-4"]
79
+ {
80
+ background: var(--ot-bg-4);
81
+ }
82
+
83
+ .e-5973ffcd > .holder[variant*="bg-4"]:hover
84
+ {
85
+ background: var(--ot-bg-4-hover);
86
+ }
87
+
88
+ /* Variants - Border */
89
+ .e-5973ffcd > .holder[variant*="border"]
90
+ {
91
+ border: 1px solid var(--ot-bg-2-border);
92
+ }
93
+
94
+ .e-5973ffcd > .holder[variant*="bg-1"][variant*="border"]
95
+ {
96
+ border: 1px solid var(--ot-bg-1-border);
97
+ }
98
+
99
+ .e-5973ffcd > .holder[variant*="bg-2"][variant*="border"]
100
+ {
101
+ border: 1px solid var(--ot-bg-2-border);
102
+ }
103
+
104
+ .e-5973ffcd > .holder[variant*="bg-3"][variant*="border"]
105
+ {
106
+ border: 1px solid var(--ot-bg-3-border);
107
+ }
108
+
109
+ .e-5973ffcd > .holder[variant*="bg-4"][variant*="border"]
110
+ {
111
+ border: 1px solid var(--ot-bg-4-border);
112
+ }
113
+
114
+ .e-5973ffcd > .holder[variant*="border"]:focus-within
115
+ {
116
+ border-color: var(--ot-brand);
117
+ }
@@ -0,0 +1,70 @@
1
+ onetype.AddonReady('elements', (elements) =>
2
+ {
3
+ elements.ItemAdd({
4
+ id: 'form-textarea',
5
+ icon: 'notes',
6
+ name: 'Textarea',
7
+ description: 'Multi-line text input with auto-resize option, character counting, and variant support for different UI contexts.',
8
+ category: 'Form',
9
+ author: 'OneType',
10
+ config: {
11
+ value: {
12
+ type: 'string'
13
+ },
14
+ name: {
15
+ type: 'string'
16
+ },
17
+ placeholder: {
18
+ type: 'string'
19
+ },
20
+ rows: {
21
+ type: 'number',
22
+ value: 4
23
+ },
24
+ maxLength: {
25
+ type: 'number'
26
+ },
27
+ disabled: {
28
+ type: 'boolean'
29
+ },
30
+ readonly: {
31
+ type: 'boolean'
32
+ },
33
+ variant: {
34
+ type: 'array',
35
+ value: ['bg-2'],
36
+ options: ['transparent', 'border', 'bg-1', 'bg-2', 'bg-3', 'bg-4']
37
+ },
38
+ size: {
39
+ type: 'string',
40
+ value: 'm',
41
+ options: ['s', 'm', 'l']
42
+ },
43
+ onInput: {
44
+ type: 'function'
45
+ },
46
+ onChange: {
47
+ type: 'function'
48
+ }
49
+ },
50
+ render: function()
51
+ {
52
+ return `
53
+ <div class="holder" :variant="variant.join(' ')" :size="size">
54
+ <textarea
55
+ :value="value"
56
+ :placeholder="placeholder"
57
+ :name="name"
58
+ :rows="rows"
59
+ :maxlength="maxLength"
60
+ :disabled="disabled"
61
+ :readonly="readonly"
62
+ autocomplete="off"
63
+ ot-input="onInput"
64
+ ot-change="onChange"
65
+ ></textarea>
66
+ </div>
67
+ `;
68
+ }
69
+ });
70
+ });
@@ -0,0 +1,57 @@
1
+ .e-4a157f24
2
+ {
3
+ display: flex;
4
+ }
5
+
6
+ .e-4a157f24 > .holder
7
+ {
8
+ display: flex;
9
+ flex-direction: column;
10
+ gap: var(--ot-spacing-s);
11
+ padding: var(--ot-spacing-m);
12
+ border-radius: 8px;
13
+ background: var(--ot-bg-2);
14
+ border: 1px solid var(--ot-bg-2-border);
15
+ width: 100%;
16
+ }
17
+
18
+ .e-4a157f24 > .holder.link
19
+ {
20
+ text-decoration: none;
21
+ transition: border-color 0.15s ease, background 0.15s ease;
22
+ cursor: pointer;
23
+ }
24
+
25
+ .e-4a157f24 > .holder.link:hover
26
+ {
27
+ border-color: var(--ot-brand);
28
+ background: var(--ot-bg-3);
29
+ }
30
+
31
+ /* Icon */
32
+
33
+ .e-4a157f24 > .holder > .icon
34
+ {
35
+ font-size: 24px;
36
+ color: var(--ot-brand);
37
+ }
38
+
39
+ /* Title */
40
+
41
+ .e-4a157f24 > .holder > .title
42
+ {
43
+ font-size: var(--ot-size-m);
44
+ font-weight: 600;
45
+ color: var(--ot-text-1);
46
+ margin: 0;
47
+ }
48
+
49
+ /* Description */
50
+
51
+ .e-4a157f24 > .holder > .description
52
+ {
53
+ font-size: var(--ot-size-s);
54
+ color: var(--ot-text-2);
55
+ line-height: 1.5;
56
+ margin: 0;
57
+ }
@@ -0,0 +1,48 @@
1
+ onetype.AddonReady('elements', (elements) =>
2
+ {
3
+ elements.ItemAdd({
4
+ id: 'global-card',
5
+ icon: 'crop_square',
6
+ name: 'Card',
7
+ description: 'Reusable card with icon, title, description, and optional link.',
8
+ category: 'Global',
9
+ author: 'OneType',
10
+ config: {
11
+ icon: {
12
+ type: 'string',
13
+ value: ''
14
+ },
15
+ title: {
16
+ type: 'string',
17
+ value: ''
18
+ },
19
+ description: {
20
+ type: 'string',
21
+ value: ''
22
+ },
23
+ href: {
24
+ type: 'string',
25
+ value: ''
26
+ },
27
+ target: {
28
+ type: 'string',
29
+ value: ''
30
+ }
31
+ },
32
+ render: function()
33
+ {
34
+ const content = `
35
+ <i ot-if="icon" class="icon">{{ icon }}</i>
36
+ <h3 class="title">{{ title }}</h3>
37
+ <p ot-if="description" class="description">{{ description }}</p>
38
+ `;
39
+
40
+ if(this.href)
41
+ {
42
+ return `<a class="holder link" :href="href" :target="target">${content}</a>`;
43
+ }
44
+
45
+ return `<div class="holder">${content}</div>`;
46
+ }
47
+ });
48
+ });
@@ -0,0 +1,66 @@
1
+ .e-4a15b201
2
+ {
3
+ display: flex;
4
+ width: 100%;
5
+ }
6
+
7
+ .e-4a15b201 > .holder
8
+ {
9
+ display: flex;
10
+ flex-direction: column;
11
+ width: 100%;
12
+ border: 1px solid var(--ot-bg-2-border);
13
+ border-radius: 8px;
14
+ overflow: hidden;
15
+ }
16
+
17
+ .e-4a15b201 > .holder > .label
18
+ {
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: space-between;
22
+ padding: var(--ot-spacing-s) var(--ot-spacing-m);
23
+ font-size: var(--ot-size-s);
24
+ font-weight: 600;
25
+ font-family: monospace;
26
+ color: var(--ot-text-2);
27
+ background: var(--ot-bg-3);
28
+ border-bottom: 1px solid var(--ot-bg-2-border);
29
+ }
30
+
31
+ .e-4a15b201 > .holder > .label > .copy
32
+ {
33
+ display: flex;
34
+ align-items: center;
35
+ justify-content: center;
36
+ padding: 0;
37
+ background: none;
38
+ border: none;
39
+ color: var(--ot-text-2);
40
+ cursor: pointer;
41
+ transition: color 0.2s ease;
42
+ }
43
+
44
+ .e-4a15b201 > .holder > .label > .copy:hover
45
+ {
46
+ color: var(--ot-text-1);
47
+ }
48
+
49
+ .e-4a15b201 > .holder > .label > .copy > i
50
+ {
51
+ font-size: 16px;
52
+ }
53
+
54
+ .e-4a15b201 > .holder > .content
55
+ {
56
+ padding: var(--ot-spacing-m);
57
+ margin: 0;
58
+ font-size: 12px;
59
+ font-family: monospace;
60
+ color: var(--ot-text-2);
61
+ line-height: 1.6;
62
+ background: var(--ot-bg-2);
63
+ overflow-x: auto;
64
+ white-space: pre;
65
+ tab-size: 4;
66
+ }
@@ -0,0 +1,40 @@
1
+ onetype.AddonReady('elements', (elements) =>
2
+ {
3
+ elements.ItemAdd({
4
+ id: 'global-code',
5
+ icon: 'code',
6
+ name: 'Code',
7
+ description: 'Code block with label header and preformatted content.',
8
+ category: 'Global',
9
+ author: 'OneType',
10
+ config: {
11
+ label: {
12
+ type: 'string',
13
+ value: ''
14
+ }
15
+ },
16
+ render: function()
17
+ {
18
+ this.copied = false;
19
+
20
+ this.copy = (event, ctx) =>
21
+ {
22
+ const text = ctx.node.closest('.holder').querySelector('.content').textContent;
23
+ navigator.clipboard.writeText(text);
24
+ this.copied = true;
25
+ this.Update();
26
+ setTimeout(() => { this.copied = false; this.Update(); }, 2000);
27
+ };
28
+
29
+ return `
30
+ <div class="holder">
31
+ <div class="label">
32
+ <span ot-if="label">{{ label }}</span>
33
+ <button class="copy" ot-click="copy"><i ot-if="!copied">content_copy</i><i ot-if="copied">check</i></button>
34
+ </div>
35
+ <pre class="content"><slot name="content"></slot></pre>
36
+ </div>
37
+ `;
38
+ }
39
+ });
40
+ });
@@ -0,0 +1,76 @@
1
+ .e-e204b7e
2
+ {
3
+ display: flex;
4
+ width: 100%;
5
+ }
6
+
7
+ .e-e204b7e > .holder
8
+ {
9
+ display: flex;
10
+ flex-direction: column;
11
+ width: 100%;
12
+ border: 1px solid var(--ot-bg-2-border);
13
+ border-radius: 8px;
14
+ overflow: hidden;
15
+ }
16
+
17
+ /* Item */
18
+
19
+ .e-e204b7e > .holder > .item
20
+ {
21
+ display: flex;
22
+ flex-direction: column;
23
+ cursor: pointer;
24
+ border-bottom: 1px solid var(--ot-bg-2-border);
25
+ transition: background 0.15s ease;
26
+ }
27
+
28
+ .e-e204b7e > .holder > .item:last-child
29
+ {
30
+ border-bottom: none;
31
+ }
32
+
33
+ .e-e204b7e > .holder > .item:hover
34
+ {
35
+ background: var(--ot-bg-2);
36
+ }
37
+
38
+ .e-e204b7e > .holder > .item.active
39
+ {
40
+ background: var(--ot-bg-2);
41
+ }
42
+
43
+ /* Question */
44
+
45
+ .e-e204b7e > .holder > .item > .question
46
+ {
47
+ display: flex;
48
+ align-items: center;
49
+ justify-content: space-between;
50
+ gap: var(--ot-spacing-s);
51
+ padding: var(--ot-spacing-s) var(--ot-spacing-m);
52
+ }
53
+
54
+ .e-e204b7e > .holder > .item > .question > .text
55
+ {
56
+ font-size: var(--ot-size-m);
57
+ font-weight: 600;
58
+ color: var(--ot-text-1);
59
+ }
60
+
61
+ .e-e204b7e > .holder > .item > .question > .icon
62
+ {
63
+ font-size: 20px;
64
+ color: var(--ot-text-2);
65
+ flex-shrink: 0;
66
+ }
67
+
68
+ /* Answer */
69
+
70
+ .e-e204b7e > .holder > .item > .answer
71
+ {
72
+ padding: 0 var(--ot-spacing-m) var(--ot-spacing-s);
73
+ font-size: var(--ot-size-m);
74
+ color: var(--ot-text-2);
75
+ line-height: 1.6;
76
+ }
@@ -0,0 +1,44 @@
1
+ onetype.AddonReady('elements', (elements) =>
2
+ {
3
+ elements.ItemAdd({
4
+ id: 'global-faq',
5
+ icon: 'help',
6
+ name: 'FAQ',
7
+ description: 'Expandable FAQ accordion.',
8
+ category: 'Global',
9
+ author: 'OneType',
10
+ config: {
11
+ items: {
12
+ type: 'array',
13
+ value: []
14
+ }
15
+ },
16
+ render: function()
17
+ {
18
+ this.open = -1;
19
+
20
+ this.toggle = (index) =>
21
+ {
22
+ this.open = this.open === index ? -1 : index;
23
+ this.Update();
24
+ };
25
+
26
+ this.isOpen = (index) =>
27
+ {
28
+ return this.open === index;
29
+ };
30
+
31
+ return `
32
+ <div class="holder">
33
+ <div ot-for="item, index in items" :class="'item' + (isOpen(index) ? ' active' : '')" ot-click="toggle(index)">
34
+ <div class="question">
35
+ <span class="text">{{ item.question }}</span>
36
+ <i class="icon">{{ isOpen(index) ? 'remove' : 'add' }}</i>
37
+ </div>
38
+ <div ot-if="isOpen(index)" class="answer">{{ item.answer }}</div>
39
+ </div>
40
+ </div>
41
+ `;
42
+ }
43
+ });
44
+ });
@@ -0,0 +1,106 @@
1
+ .e-49fb116e
2
+ {
3
+ display: flex;
4
+ width: 100%;
5
+ }
6
+
7
+ .e-49fb116e > .holder
8
+ {
9
+ width: 100%;
10
+ display: flex;
11
+ flex-direction: column;
12
+ gap: var(--ot-spacing-x);
13
+ border-bottom: 1px solid var(--ot-bg-2-border);
14
+ padding-bottom: var(--ot-spacing-m);
15
+ }
16
+
17
+ .e-49fb116e > .holder > .icon
18
+ {
19
+ font-size: 36px;
20
+ color: var(--ot-text-2);
21
+ }
22
+
23
+ .e-49fb116e > .holder > .title
24
+ {
25
+ font-size: 18px;
26
+ font-weight: 600;
27
+ color: var(--ot-text-1);
28
+ }
29
+
30
+ .e-49fb116e > .holder > .description
31
+ {
32
+ font-size: var(--ot-size-m);
33
+ color: var(--ot-text-2);
34
+ }
35
+
36
+ /* Alignment */
37
+
38
+ .e-49fb116e > .holder.center
39
+ {
40
+ align-items: center;
41
+ text-align: center;
42
+ }
43
+
44
+ .e-49fb116e > .holder.right
45
+ {
46
+ align-items: flex-end;
47
+ text-align: right;
48
+ }
49
+
50
+ /* Variants */
51
+
52
+ .e-49fb116e > .holder.clean
53
+ {
54
+ border-bottom: none;
55
+ padding-bottom: 0;
56
+ }
57
+
58
+ .e-49fb116e > .holder.page
59
+ {
60
+ border-bottom: none;
61
+ padding-bottom: 0;
62
+ }
63
+
64
+ .e-49fb116e > .holder.page > .title
65
+ {
66
+ font-size: 36px;
67
+ font-weight: 800;
68
+ }
69
+
70
+ /* Sizes */
71
+
72
+ .e-49fb116e > .holder.size-s > .title
73
+ {
74
+ font-size: 16px;
75
+ }
76
+
77
+ .e-49fb116e > .holder.size-s > .description
78
+ {
79
+ font-size: var(--ot-size-s);
80
+ }
81
+
82
+ .e-49fb116e > .holder.size-m > .title
83
+ {
84
+ font-size: 28px;
85
+ font-weight: 700;
86
+ }
87
+
88
+ .e-49fb116e > .holder.size-m > .description
89
+ {
90
+ font-size: var(--ot-size-m);
91
+ line-height: 1.6;
92
+ max-width: 500px;
93
+ }
94
+
95
+ .e-49fb116e > .holder.size-l > .title
96
+ {
97
+ font-size: 36px;
98
+ font-weight: 800;
99
+ }
100
+
101
+ .e-49fb116e > .holder.size-l > .description
102
+ {
103
+ font-size: var(--ot-size-l);
104
+ line-height: 1.6;
105
+ max-width: 600px;
106
+ }