@redneckz/wildless-cms-uni-blocks 0.2.76 → 0.2.79
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/bundle/blocks.schema.json +5 -82
- package/bundle/bundle.umd.js +35 -0
- package/bundle/bundle.umd.min.js +1 -1
- package/dist/components/Accordion/Accordion.d.ts +5 -0
- package/dist/components/Accordion/Accordion.js +10 -0
- package/dist/components/Accordion/Accordion.js.map +1 -0
- package/dist/components/Accordion/AccordionBlocks.d.ts +4 -0
- package/dist/components/Accordion/AccordionBlocks.js +7 -0
- package/dist/components/Accordion/AccordionBlocks.js.map +1 -0
- package/dist/components/Accordion/AccordionContent.d.ts +14 -0
- package/dist/components/Accordion/AccordionContent.js +2 -0
- package/dist/components/Accordion/AccordionContent.js.map +1 -0
- package/dist/components/Accordion/AccordionItem.d.ts +5 -0
- package/dist/components/Accordion/AccordionItem.js +35 -0
- package/dist/components/Accordion/AccordionItem.js.map +1 -0
- package/dist/components/Blocks.d.ts +1 -0
- package/dist/components/Blocks.js +2 -0
- package/dist/components/Blocks.js.map +1 -1
- package/dist/components/CreditCalculator/CreditCalculator.d.ts +4 -0
- package/dist/components/CreditCalculator/CreditCalculator.js +29 -0
- package/dist/components/CreditCalculator/CreditCalculator.js.map +1 -0
- package/dist/content-page-repository/ContentPageRepository.d.ts +3 -0
- package/dist/content-page-repository/ContentPageRepository.js +14 -0
- package/dist/content-page-repository/ContentPageRepository.js.map +1 -1
- package/dist/ui-kit/Checkbox/Checkbox.d.ts +2 -0
- package/dist/ui-kit/Checkbox/Checkbox.js +17 -0
- package/dist/ui-kit/Checkbox/Checkbox.js.map +1 -0
- package/dist/ui-kit/Checkbox/CheckboxProps.d.ts +6 -0
- package/dist/ui-kit/Checkbox/CheckboxProps.js +2 -0
- package/dist/ui-kit/Checkbox/CheckboxProps.js.map +1 -0
- package/dist/ui-kit/Icon/IconProps.d.ts +4 -1
- package/dist/ui-kit/Icon/IconProps.js +3 -0
- package/dist/ui-kit/Icon/IconProps.js.map +1 -1
- package/dist/ui-kit/InputRange/InputRange.d.ts +2 -0
- package/dist/ui-kit/InputRange/InputRange.js +25 -0
- package/dist/ui-kit/InputRange/InputRange.js.map +1 -0
- package/dist/ui-kit/InputRange/InputRangeProps.d.ts +10 -0
- package/dist/ui-kit/InputRange/InputRangeProps.js +2 -0
- package/dist/ui-kit/InputRange/InputRangeProps.js.map +1 -0
- package/dist/utils/clamp.d.ts +1 -0
- package/dist/utils/clamp.js +5 -0
- package/dist/utils/clamp.js.map +1 -0
- package/lib/common.css +1 -1
- package/lib/components/Accordion/Accordion.d.ts +5 -0
- package/lib/components/Accordion/Accordion.js +8 -0
- package/lib/components/Accordion/Accordion.js.map +1 -0
- package/lib/components/Accordion/AccordionBlocks.d.ts +4 -0
- package/lib/components/Accordion/AccordionBlocks.js +6 -0
- package/lib/components/Accordion/AccordionBlocks.js.map +1 -0
- package/lib/components/Accordion/AccordionContent.d.ts +14 -0
- package/lib/components/Accordion/AccordionContent.js +2 -0
- package/lib/components/Accordion/AccordionContent.js.map +1 -0
- package/lib/components/Accordion/AccordionItem.d.ts +5 -0
- package/lib/components/Accordion/AccordionItem.js +30 -0
- package/lib/components/Accordion/AccordionItem.js.map +1 -0
- package/lib/components/Blocks.d.ts +1 -0
- package/lib/components/Blocks.js +2 -0
- package/lib/components/Blocks.js.map +1 -1
- package/lib/components/CreditCalculator/CreditCalculator.d.ts +4 -0
- package/lib/components/CreditCalculator/CreditCalculator.js +27 -0
- package/lib/components/CreditCalculator/CreditCalculator.js.map +1 -0
- package/lib/content-page-repository/ContentPageRepository.d.ts +3 -0
- package/lib/content-page-repository/ContentPageRepository.js +14 -0
- package/lib/content-page-repository/ContentPageRepository.js.map +1 -1
- package/lib/ui-kit/Checkbox/Checkbox.d.ts +2 -0
- package/lib/ui-kit/Checkbox/Checkbox.js +15 -0
- package/lib/ui-kit/Checkbox/Checkbox.js.map +1 -0
- package/lib/ui-kit/Checkbox/CheckboxProps.d.ts +6 -0
- package/lib/ui-kit/Checkbox/CheckboxProps.js +2 -0
- package/lib/ui-kit/Checkbox/CheckboxProps.js.map +1 -0
- package/lib/ui-kit/Icon/IconProps.d.ts +4 -1
- package/lib/ui-kit/Icon/IconProps.js +3 -0
- package/lib/ui-kit/Icon/IconProps.js.map +1 -1
- package/lib/ui-kit/InputRange/InputRange.d.ts +2 -0
- package/lib/ui-kit/InputRange/InputRange.js +23 -0
- package/lib/ui-kit/InputRange/InputRange.js.map +1 -0
- package/lib/ui-kit/InputRange/InputRangeProps.d.ts +10 -0
- package/lib/ui-kit/InputRange/InputRangeProps.js +2 -0
- package/lib/ui-kit/InputRange/InputRangeProps.js.map +1 -0
- package/lib/utils/clamp.d.ts +1 -0
- package/lib/utils/clamp.js +2 -0
- package/lib/utils/clamp.js.map +1 -0
- package/package.json +3 -3
- package/src/common.css +40 -0
- package/src/components/Accordion/Accordion.fixture.tsx +62 -0
- package/src/components/Accordion/Accordion.tsx +22 -0
- package/src/components/Accordion/AccordionBlocks.tsx +7 -0
- package/src/components/Accordion/AccordionContent.ts +18 -0
- package/src/components/Accordion/AccordionItem.tsx +68 -0
- package/src/components/Blocks.ts +2 -0
- package/src/components/ContentPage/ContentPage.page.json +78 -0
- package/src/components/CreditCalculator/CreditCalculator.fixture.tsx +4 -0
- package/src/components/CreditCalculator/CreditCalculator.tsx +106 -0
- package/src/content-page-repository/ContentPageRepository.ts +17 -0
- package/src/icons/DocIcon.svg +5 -0
- package/src/icons/MinusIcon.svg +1 -0
- package/src/icons/PlusIcon.svg +1 -0
- package/src/ui-kit/Checkbox/Checkbox.tsx +36 -0
- package/src/ui-kit/Checkbox/CheckboxProps.ts +6 -0
- package/src/ui-kit/Icon/IconProps.ts +3 -0
- package/src/ui-kit/InputRange/InputRange.tsx +63 -0
- package/src/ui-kit/InputRange/InputRangeProps.ts +10 -0
- package/src/utils/clamp.ts +2 -0
|
@@ -20,5 +20,8 @@ export var IconMap;
|
|
|
20
20
|
IconMap[IconMap["TelegramIcon"] = 17] = "TelegramIcon";
|
|
21
21
|
IconMap[IconMap["VKIcon"] = 18] = "VKIcon";
|
|
22
22
|
IconMap[IconMap["GlassIcon"] = 19] = "GlassIcon";
|
|
23
|
+
IconMap[IconMap["DocIcon"] = 20] = "DocIcon";
|
|
24
|
+
IconMap[IconMap["PlusIcon"] = 21] = "PlusIcon";
|
|
25
|
+
IconMap[IconMap["MinusIcon"] = 22] = "MinusIcon";
|
|
23
26
|
})(IconMap || (IconMap = {}));
|
|
24
27
|
//# sourceMappingURL=IconProps.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconProps.js","sourceRoot":"","sources":["../../../src/ui-kit/Icon/IconProps.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,
|
|
1
|
+
{"version":3,"file":"IconProps.js","sourceRoot":"","sources":["../../../src/ui-kit/Icon/IconProps.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,OAwBX;AAxBD,WAAY,OAAO;IACjB,+DAAmB,CAAA;IACnB,+CAAW,CAAA;IACX,qDAAc,CAAA;IACd,+CAAW,CAAA;IACX,mEAAqB,CAAA;IACrB,iDAAY,CAAA;IACZ,2DAAiB,CAAA;IACjB,6CAAU,CAAA;IACV,6CAAU,CAAA;IACV,+CAAW,CAAA;IACX,kDAAY,CAAA;IACZ,0CAAQ,CAAA;IACR,sDAAc,CAAA;IACd,sEAAsB,CAAA;IACtB,0DAAgB,CAAA;IAChB,oDAAa,CAAA;IACb,sDAAc,CAAA;IACd,sDAAc,CAAA;IACd,0CAAQ,CAAA;IACR,gDAAW,CAAA;IACX,4CAAS,CAAA;IACT,8CAAU,CAAA;IACV,gDAAW,CAAA;AACb,CAAC,EAxBW,OAAO,KAAP,OAAO,QAwBlB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@redneckz/uni-jsx/jsx-runtime";
|
|
2
|
+
import { JSX } from '@redneckz/uni-jsx';
|
|
3
|
+
export const InputRange = JSX(({ className, title, items = [], min = 1, max = 100, step = 1, value = min, onChange }) => {
|
|
4
|
+
const handleChange = (value) => {
|
|
5
|
+
if (!onChange)
|
|
6
|
+
return;
|
|
7
|
+
const sanitizedValue = Number(value.replace(/\D/g, ''));
|
|
8
|
+
onChange(sanitizedValue);
|
|
9
|
+
};
|
|
10
|
+
const inputStyle = {
|
|
11
|
+
backgroundSize: `${(value * 100) / max - 1}% 100%`,
|
|
12
|
+
};
|
|
13
|
+
const handleBlur = () => {
|
|
14
|
+
if (!onChange)
|
|
15
|
+
return;
|
|
16
|
+
if (value < min)
|
|
17
|
+
onChange(min);
|
|
18
|
+
if (value > max)
|
|
19
|
+
onChange(max);
|
|
20
|
+
};
|
|
21
|
+
return (_jsxs("div", { className: className, children: [_jsxs("div", { className: "relative", children: [title ? (_jsx("span", { className: "absolute text-xs text-secondary-text top-1 mt-0.5 pl-4 ml-0.5", children: title })) : null, _jsx("input", { className: `m-0 font-sans text-sm w-full h-12 border-2 border-solid border-main-divider rounded-md outline-none p-0 pl-4 m-0 box-border text-primary-text ${title ? 'pt-4' : ''}`, value: String(value).replace(/\B(?=(\d{3})+(?!\d))/g, ' '), onChange: (e) => handleChange(e.target.value), onBlur: handleBlur }), _jsx("div", { className: "absolute inset-x-0 mt-0.5 top-8 px-4", children: _jsx("input", { className: "box-border w-full m-0 cursor-pointer slider", type: "range", min: min, max: max, step: step, value: value, onChange: (e) => handleChange(e.target.value), style: inputStyle }) })] }), _jsx("div", { className: "flex justify-between mt-3 mb-4", children: items.map((item, i) => (_jsx("span", { className: "text-xs text-secondary-text pl-4", children: item }, String(i)))) })] }));
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=InputRange.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InputRange.js","sourceRoot":"","sources":["../../../src/ui-kit/InputRange/InputRange.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAGxC,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAC3B,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,EAAE,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE;IACxF,MAAM,YAAY,GAAG,CAAC,KAAa,EAAE,EAAE;QACrC,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;QACxD,QAAQ,CAAC,cAAc,CAAC,CAAC;IAC3B,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG;QACjB,cAAc,EAAE,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,QAAQ;KACnD,CAAC;IAEF,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,IAAI,KAAK,GAAG,GAAG;YAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,GAAG,GAAG;YAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAE,SAAS,aACvB,eAAK,SAAS,EAAC,UAAU,aACtB,KAAK,CAAC,CAAC,CAAC,CACP,eAAM,SAAS,EAAC,+DAA+D,YAC5E,KAAK,GACD,CACR,CAAC,CAAC,CAAC,IAAI,EACR,gBACE,SAAS,EAAE,iJACT,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EACnB,EAAE,EACF,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,uBAAuB,EAAE,GAAG,CAAC,EAC1D,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC7C,MAAM,EAAE,UAAU,GAClB,EACF,cAAK,SAAS,EAAC,sCAAsC,YACnD,gBACE,SAAS,EAAC,6CAA6C,EACvD,IAAI,EAAC,OAAO,EACZ,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC7C,KAAK,EAAE,UAAU,GACjB,GACE,IACF,EACN,cAAK,SAAS,EAAC,gCAAgC,YAC5C,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CACtB,eAAsB,SAAS,EAAC,kCAAkC,YAC/D,IAAI,IADI,MAAM,CAAC,CAAC,CAAC,CAEb,CACR,CAAC,GACE,IACF,CACP,CAAC;AACJ,CAAC,CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InputRangeProps.js","sourceRoot":"","sources":["../../../src/ui-kit/InputRange/InputRangeProps.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const clamp: (value: number, min: number, max: number) => number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clamp.js","sourceRoot":"","sources":["../../src/utils/clamp.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,EAAE,CAC/D,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redneckz/wildless-cms-uni-blocks",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.79",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -84,8 +84,8 @@
|
|
|
84
84
|
"postbuild:lib": "replace-in-file --configFile=replace-config.lib.cjs --verbose",
|
|
85
85
|
"build:commonjs": "rimraf ./dist && tsc --module commonjs --noImplicitUseStrict --outDir dist",
|
|
86
86
|
"bundle": "rimraf ./bundle && rollup -c && npm run build:schema",
|
|
87
|
-
"build:schema": "ts-json-schema-generator --path
|
|
88
|
-
"build:style": "postcss
|
|
87
|
+
"build:schema": "ts-json-schema-generator --path ./src/**/*Content.ts --no-type-check -o ./bundle/blocks.schema.json",
|
|
88
|
+
"build:style": "postcss ./src/**/*.css --env production --dir ./lib",
|
|
89
89
|
"build:icons": "svgo -f ./src/icons -o ./cosmos-static/icons",
|
|
90
90
|
"size": "size-limit",
|
|
91
91
|
"test": "jest --coverage",
|
package/src/common.css
CHANGED
|
@@ -98,4 +98,44 @@
|
|
|
98
98
|
scroll-snap-stop: always;
|
|
99
99
|
width: 100%;
|
|
100
100
|
}
|
|
101
|
+
|
|
102
|
+
input[type='range'].slider {
|
|
103
|
+
-webkit-appearance: none;
|
|
104
|
+
height: 4px;
|
|
105
|
+
background: transparent;
|
|
106
|
+
border-radius: 5px;
|
|
107
|
+
background-image: linear-gradient(#42ab44, #42ab44);
|
|
108
|
+
background-repeat: no-repeat;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
input[type='range'].slider::-webkit-slider-thumb {
|
|
112
|
+
-webkit-appearance: none;
|
|
113
|
+
height: 18px;
|
|
114
|
+
width: 18px;
|
|
115
|
+
border-radius: 50%;
|
|
116
|
+
background: #fff;
|
|
117
|
+
cursor: pointer;
|
|
118
|
+
box-shadow: none;
|
|
119
|
+
border: 3px solid #42ab44;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
input[type='range'].slider::-moz-range-thumb {
|
|
123
|
+
height: 12px;
|
|
124
|
+
width: 12px;
|
|
125
|
+
border-radius: 50%;
|
|
126
|
+
background: #fff;
|
|
127
|
+
cursor: pointer;
|
|
128
|
+
box-shadow: none;
|
|
129
|
+
border: 3px solid #42ab44;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
input[type='range'].slider::-ms-thumb {
|
|
133
|
+
height: 18px;
|
|
134
|
+
width: 18px;
|
|
135
|
+
border-radius: 50%;
|
|
136
|
+
background: #fff;
|
|
137
|
+
cursor: pointer;
|
|
138
|
+
box-shadow: none;
|
|
139
|
+
border: 3px solid #42ab44;
|
|
140
|
+
}
|
|
101
141
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { context } from '../../setup-fixture';
|
|
2
|
+
import type { AccordionProps } from './Accordion';
|
|
3
|
+
import type { TextBlockContent } from '../TextBlock/TextBlockContent';
|
|
4
|
+
import { Accordion } from './Accordion';
|
|
5
|
+
|
|
6
|
+
const TEXT_BLOCK: TextBlockContent = {
|
|
7
|
+
title: 'Title',
|
|
8
|
+
description:
|
|
9
|
+
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloremque minima odio soluta cupiditate pariatur, labore molestias quas necessitatibus nesciunt in praesentium accusamus provident sequi maiores autem. Voluptas quam neque iste?',
|
|
10
|
+
blockVersion: 'secondary-light',
|
|
11
|
+
iconVersion: 'small',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const propsTextBlock: AccordionProps = {
|
|
15
|
+
title: 'Accordion title',
|
|
16
|
+
context,
|
|
17
|
+
accordionItems: [
|
|
18
|
+
{
|
|
19
|
+
label: 'Accordion label 1',
|
|
20
|
+
blocks: [
|
|
21
|
+
{
|
|
22
|
+
type: 'TextBlock',
|
|
23
|
+
data: TEXT_BLOCK,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
type: 'TextBlock',
|
|
27
|
+
data: TEXT_BLOCK,
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
label: 'Accordion label 2',
|
|
33
|
+
blocks: [
|
|
34
|
+
{
|
|
35
|
+
type: 'TextBlock',
|
|
36
|
+
data: TEXT_BLOCK,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
type: 'TextBlock',
|
|
40
|
+
data: TEXT_BLOCK,
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
label: 'Accordion label 3',
|
|
46
|
+
blocks: [
|
|
47
|
+
{
|
|
48
|
+
type: 'TextBlock',
|
|
49
|
+
data: TEXT_BLOCK,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
type: 'TextBlock',
|
|
53
|
+
data: TEXT_BLOCK,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export default {
|
|
61
|
+
'with text block': <Accordion {...propsTextBlock} />,
|
|
62
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import type { UniBlockProps } from '../../types';
|
|
3
|
+
import type { AccordionContent } from './AccordionContent';
|
|
4
|
+
import { AccordionItem } from './AccordionItem';
|
|
5
|
+
import { Title } from '../../ui-kit/Title/Title';
|
|
6
|
+
|
|
7
|
+
export interface AccordionProps extends AccordionContent, UniBlockProps {}
|
|
8
|
+
|
|
9
|
+
export const Accordion = JSX<AccordionProps>(({ title, accordionItems, context, className }) => {
|
|
10
|
+
return (
|
|
11
|
+
<section className={`p-[50px] font-sans bg-white text-primary-text ${className || ''}`}>
|
|
12
|
+
{title ? <Title className="m-0 mb-2.5">{title}</Title> : null}
|
|
13
|
+
{accordionItems?.length ? (
|
|
14
|
+
<ul className="list-none m-0 p-0">
|
|
15
|
+
{accordionItems.map((item, i) => (
|
|
16
|
+
<AccordionItem key={`AccordionItem${i}`} {...item} context={context} />
|
|
17
|
+
))}
|
|
18
|
+
</ul>
|
|
19
|
+
) : null}
|
|
20
|
+
</section>
|
|
21
|
+
);
|
|
22
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { TextBlockContent } from '../TextBlock/TextBlockContent';
|
|
2
|
+
|
|
3
|
+
export interface AccordionContent {
|
|
4
|
+
title?: string;
|
|
5
|
+
accordionItems?: AccordionItemContent[];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface AccordionItemContent {
|
|
9
|
+
label?: string;
|
|
10
|
+
blocks?: AccordionBlockContent[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type AccordionBlockContent = {
|
|
14
|
+
type?: string;
|
|
15
|
+
data?: AccordionDataContent;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type AccordionDataContent = TextBlockContent;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import type { UniBlockProps } from '../../types';
|
|
3
|
+
import type { AccordionItemContent, AccordionBlockContent } from './AccordionContent';
|
|
4
|
+
import { Icon } from '../../ui-kit/Icon/Icon';
|
|
5
|
+
import AccordionBlocks from './AccordionBlocks';
|
|
6
|
+
|
|
7
|
+
export interface AccordionItemProps extends AccordionItemContent, UniBlockProps {}
|
|
8
|
+
|
|
9
|
+
export const AccordionItem = JSX<AccordionItemProps>(({ label, blocks, context }) => {
|
|
10
|
+
const [isActive, setIsActive] = context.useState(false);
|
|
11
|
+
const hasContent = blocks?.length;
|
|
12
|
+
const icon = isActive ? 'MinusIcon' : 'PlusIcon';
|
|
13
|
+
|
|
14
|
+
const handleToggle = (e) => {
|
|
15
|
+
if (!hasContent) return null;
|
|
16
|
+
setIsActive(!isActive);
|
|
17
|
+
const contentBlock = getContentBlock(e);
|
|
18
|
+
contentBlock.style.maxHeight = contentBlock.style.maxHeight
|
|
19
|
+
? null
|
|
20
|
+
: `${contentBlock.scrollHeight}px`;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<li className="border-0 border-b border-solid border-main-divider last:border-b-0">
|
|
25
|
+
<button
|
|
26
|
+
className={`border-none bg-transparent px-0 py-5 flex justify-between text-left w-full font-sans text-primary-text
|
|
27
|
+
${hasContent ? 'group cursor-pointer' : ''}`}
|
|
28
|
+
onClick={handleToggle}
|
|
29
|
+
>
|
|
30
|
+
<span
|
|
31
|
+
className={`m-0 text-xl pr-2.5 font-medium ${
|
|
32
|
+
hasContent ? 'group-hover:text-primary-main' : ''
|
|
33
|
+
}`}
|
|
34
|
+
>
|
|
35
|
+
{label}
|
|
36
|
+
</span>
|
|
37
|
+
{hasContent ? <Icon name={icon} width="24" height="24" /> : null}
|
|
38
|
+
</button>
|
|
39
|
+
{hasContent ? (
|
|
40
|
+
<div
|
|
41
|
+
className={`${
|
|
42
|
+
isActive ? 'pb-5' : ''
|
|
43
|
+
} text-sm transition-all duration-300 max-h-0 overflow-hidden group-last:last:pb-0 `}
|
|
44
|
+
>
|
|
45
|
+
{blocks?.length ? blocks.map(renderComponent) : null}
|
|
46
|
+
</div>
|
|
47
|
+
) : null}
|
|
48
|
+
</li>
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// TODO: draft, for dynamic rendering of components
|
|
53
|
+
|
|
54
|
+
const renderComponent = (block: AccordionBlockContent, i: number) => {
|
|
55
|
+
if (block.type && block.data && !AccordionBlocks.hasOwnProperty(block.type)) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const AccordionBlock = block.type && AccordionBlocks[block.type];
|
|
60
|
+
return (
|
|
61
|
+
<div className="mb-5 last:mb-0" key={`component${i}`}>
|
|
62
|
+
<AccordionBlock {...block.data} />
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const getContentBlock = (e) =>
|
|
68
|
+
e.target.tagName === 'BUTTON' ? e.target.nextSibling : e.target.parentNode.nextSibling;
|
package/src/components/Blocks.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { StepsBlock } from './StepsBlock/StepsBlock';
|
|
|
14
14
|
import { TextBlock } from './TextBlock/TextBlock';
|
|
15
15
|
import { Tile } from './Tile/Tile';
|
|
16
16
|
import { ComparisonTable } from './ComparisonTable/ComparisonTable';
|
|
17
|
+
import { Accordion } from './Accordion/Accordion';
|
|
17
18
|
|
|
18
19
|
export const Blocks = {
|
|
19
20
|
Header,
|
|
@@ -32,4 +33,5 @@ export const Blocks = {
|
|
|
32
33
|
Gallery,
|
|
33
34
|
MiniGallery,
|
|
34
35
|
ComparisonTable,
|
|
36
|
+
Accordion,
|
|
35
37
|
};
|
|
@@ -1282,6 +1282,84 @@
|
|
|
1282
1282
|
]
|
|
1283
1283
|
}
|
|
1284
1284
|
},
|
|
1285
|
+
{
|
|
1286
|
+
"type": "Accordion",
|
|
1287
|
+
"style": ["col-span-12"],
|
|
1288
|
+
"content": {
|
|
1289
|
+
"title": "Accordion title",
|
|
1290
|
+
"accordionItems": [
|
|
1291
|
+
{
|
|
1292
|
+
"label": "Accordion label 1",
|
|
1293
|
+
"blocks": [
|
|
1294
|
+
{
|
|
1295
|
+
"type": "TextBlock",
|
|
1296
|
+
"data": {
|
|
1297
|
+
"title": "Title",
|
|
1298
|
+
"description": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloremque minima odio soluta cupiditate pariatur, labore molestias quas necessitatibus nesciunt in praesentium accusamus provident sequi maiores autem. Voluptas quam neque iste?",
|
|
1299
|
+
"blockVersion": "secondary-light",
|
|
1300
|
+
"iconVersion": "small"
|
|
1301
|
+
}
|
|
1302
|
+
},
|
|
1303
|
+
{
|
|
1304
|
+
"type": "TextBlock",
|
|
1305
|
+
"data": {
|
|
1306
|
+
"title": "Title",
|
|
1307
|
+
"description": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloremque minima odio soluta cupiditate pariatur, labore molestias quas necessitatibus nesciunt in praesentium accusamus provident sequi maiores autem. Voluptas quam neque iste?",
|
|
1308
|
+
"blockVersion": "secondary-light",
|
|
1309
|
+
"iconVersion": "small"
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
]
|
|
1313
|
+
},
|
|
1314
|
+
{
|
|
1315
|
+
"label": "Accordion label 2",
|
|
1316
|
+
"blocks": [
|
|
1317
|
+
{
|
|
1318
|
+
"type": "TextBlock",
|
|
1319
|
+
"data": {
|
|
1320
|
+
"title": "Title",
|
|
1321
|
+
"description": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloremque minima odio soluta cupiditate pariatur, labore molestias quas necessitatibus nesciunt in praesentium accusamus provident sequi maiores autem. Voluptas quam neque iste?",
|
|
1322
|
+
"blockVersion": "secondary-light",
|
|
1323
|
+
"iconVersion": "small"
|
|
1324
|
+
}
|
|
1325
|
+
},
|
|
1326
|
+
{
|
|
1327
|
+
"type": "TextBlock",
|
|
1328
|
+
"data": {
|
|
1329
|
+
"title": "Title",
|
|
1330
|
+
"description": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloremque minima odio soluta cupiditate pariatur, labore molestias quas necessitatibus nesciunt in praesentium accusamus provident sequi maiores autem. Voluptas quam neque iste?",
|
|
1331
|
+
"blockVersion": "secondary-light",
|
|
1332
|
+
"iconVersion": "small"
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
]
|
|
1336
|
+
},
|
|
1337
|
+
{
|
|
1338
|
+
"label": "Accordion label 3",
|
|
1339
|
+
"blocks": [
|
|
1340
|
+
{
|
|
1341
|
+
"type": "TextBlock",
|
|
1342
|
+
"data": {
|
|
1343
|
+
"title": "Title",
|
|
1344
|
+
"description": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloremque minima odio soluta cupiditate pariatur, labore molestias quas necessitatibus nesciunt in praesentium accusamus provident sequi maiores autem. Voluptas quam neque iste?",
|
|
1345
|
+
"blockVersion": "secondary-light",
|
|
1346
|
+
"iconVersion": "small"
|
|
1347
|
+
}
|
|
1348
|
+
},
|
|
1349
|
+
{
|
|
1350
|
+
"type": "TextBlock",
|
|
1351
|
+
"data": {
|
|
1352
|
+
"title": "Title",
|
|
1353
|
+
"description": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloremque minima odio soluta cupiditate pariatur, labore molestias quas necessitatibus nesciunt in praesentium accusamus provident sequi maiores autem. Voluptas quam neque iste?",
|
|
1354
|
+
"blockVersion": "secondary-light",
|
|
1355
|
+
"iconVersion": "small"
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
]
|
|
1359
|
+
}
|
|
1360
|
+
]
|
|
1361
|
+
}
|
|
1362
|
+
},
|
|
1285
1363
|
{
|
|
1286
1364
|
"type": "Footer",
|
|
1287
1365
|
"style": ["col-span-12"],
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import { UniBlockProps } from '../../types';
|
|
3
|
+
import { Button } from '../../ui-kit/Button/Button';
|
|
4
|
+
import { Checkbox } from '../../ui-kit/Checkbox/Checkbox';
|
|
5
|
+
import { InputRange } from '../../ui-kit/InputRange/InputRange';
|
|
6
|
+
import { clamp } from '../../utils/clamp';
|
|
7
|
+
|
|
8
|
+
export interface CreditCalculatorProps extends UniBlockProps {}
|
|
9
|
+
|
|
10
|
+
const borderStyle = 'border-solid border-3 border-primary-main rounded-md';
|
|
11
|
+
|
|
12
|
+
const MIN_MONEY = 50000;
|
|
13
|
+
const MAX_MONEY = 3000000;
|
|
14
|
+
const STEP_MONEY = 1000;
|
|
15
|
+
|
|
16
|
+
const CREDIT_TERM_YEARS = [2, 3, 4, 5, 6, 7];
|
|
17
|
+
|
|
18
|
+
const MIN_MONTHS = 1;
|
|
19
|
+
const MAX_MONTHS = 84;
|
|
20
|
+
const STEP_MONTHS = 1;
|
|
21
|
+
|
|
22
|
+
const MONTHS_IN_YEAR = 12;
|
|
23
|
+
|
|
24
|
+
export const CreditCalculator = JSX<CreditCalculatorProps>(({ context, className }) => {
|
|
25
|
+
const [moneyValue, setMoneyValue] = context.useState(350000);
|
|
26
|
+
const [monthsValue, setMonthsValue] = context.useState(12);
|
|
27
|
+
const [isAnnuityChecked, setIsAnnuityChecked] = context.useState(true);
|
|
28
|
+
const [isInsuranceChecked, setIsInsuranceChecked] = context.useState(true);
|
|
29
|
+
|
|
30
|
+
const handleButtonClick = (value: number) => {
|
|
31
|
+
setMonthsValue(clamp(value * MONTHS_IN_YEAR, MIN_MONTHS, MAX_MONTHS));
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<section className={`font-sans text-primary-text bg-white p-4 ${className}`}>
|
|
36
|
+
<div className={`box-border p-12 flex flex-col justify-between ${borderStyle}`}>
|
|
37
|
+
<div className="flex justify-between">
|
|
38
|
+
<div className="grow mr-11">
|
|
39
|
+
<InputRange
|
|
40
|
+
title="Желаемая сумма кредита, ₽"
|
|
41
|
+
items={['От 50 000 рублей', 'До 3 000 000 рублей']}
|
|
42
|
+
min={MIN_MONEY}
|
|
43
|
+
max={MAX_MONEY}
|
|
44
|
+
step={STEP_MONEY}
|
|
45
|
+
value={moneyValue}
|
|
46
|
+
onChange={setMoneyValue}
|
|
47
|
+
/>
|
|
48
|
+
<InputRange
|
|
49
|
+
title="Срок кредита, месяцев"
|
|
50
|
+
items={['Или выберите из предложенных вариантов ниже']}
|
|
51
|
+
min={MIN_MONTHS}
|
|
52
|
+
max={MAX_MONTHS}
|
|
53
|
+
step={STEP_MONTHS}
|
|
54
|
+
value={monthsValue}
|
|
55
|
+
onChange={setMonthsValue}
|
|
56
|
+
/>
|
|
57
|
+
<div className="flex mb-7">
|
|
58
|
+
{CREDIT_TERM_YEARS.map((number, i) => renderButton(number, i, handleButtonClick))}
|
|
59
|
+
</div>
|
|
60
|
+
<Checkbox
|
|
61
|
+
text="Получаю пенсию на карту Россельхозбанка"
|
|
62
|
+
checked={isAnnuityChecked}
|
|
63
|
+
onChange={setIsAnnuityChecked}
|
|
64
|
+
/>
|
|
65
|
+
<Checkbox
|
|
66
|
+
className="mb-4"
|
|
67
|
+
text="Комплексная страховая защита"
|
|
68
|
+
checked={isInsuranceChecked}
|
|
69
|
+
onChange={setIsInsuranceChecked}
|
|
70
|
+
/>
|
|
71
|
+
</div>
|
|
72
|
+
<div className="p-9 bg-primary-main rounded-md text-white">
|
|
73
|
+
<div className="text-base mb-5">Наше предложение</div>
|
|
74
|
+
<div className="text-sm opacity-60">Ежемесячный платёж</div>
|
|
75
|
+
<div className="text-lg mb-3">26 827 ₽</div>
|
|
76
|
+
<div className="text-sm opacity-60">Ставка</div>
|
|
77
|
+
<div className="text-lg">16,9 %</div>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
<div className="flex items-center">
|
|
81
|
+
<Button className="mr-3" text="Отправить заявку" version="primary" href="#" />
|
|
82
|
+
<div
|
|
83
|
+
className="w-80 text-xxs leading-4 text-secondary-text"
|
|
84
|
+
aria-label="Соглашение на обработку персональных данных"
|
|
85
|
+
>
|
|
86
|
+
Отправляя заявку, вы соглашаетесь на обработку персональных данных соответственно
|
|
87
|
+
требованиям ФЗ «О персональных данных»
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
</section>
|
|
92
|
+
);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const renderButton = (number: number, i: number, handleClick: (number: number) => void) => (
|
|
96
|
+
<div
|
|
97
|
+
key={String(i)}
|
|
98
|
+
className="bg-secondary-light rounded-3xl h-10 w-[75px] box-border mr-2 flex items-center justify-center cursor-pointer"
|
|
99
|
+
role="button"
|
|
100
|
+
onClick={() => handleClick(number)}
|
|
101
|
+
>
|
|
102
|
+
<span className="font-medium text-sm">
|
|
103
|
+
{number} {number > 4 ? 'лет' : 'года'}
|
|
104
|
+
</span>
|
|
105
|
+
</div>
|
|
106
|
+
);
|
|
@@ -5,6 +5,7 @@ import type { ContentPageDef } from '../types';
|
|
|
5
5
|
import type { TransformationOptions } from './TransformationOptions';
|
|
6
6
|
import { transformContentPage } from './transformContentPage';
|
|
7
7
|
|
|
8
|
+
const INDEX_PAGE_SLUG = 'index';
|
|
8
9
|
const find = util.promisify(glob);
|
|
9
10
|
|
|
10
11
|
export function ContentPageRepository({
|
|
@@ -16,6 +17,11 @@ export function ContentPageRepository({
|
|
|
16
17
|
return await Promise.all(pagePaths.map(readPage));
|
|
17
18
|
}
|
|
18
19
|
|
|
20
|
+
async function getSecondaryContentPages() {
|
|
21
|
+
const pages = await getAllContentPages();
|
|
22
|
+
return pages.filter((content) => content.slug !== INDEX_PAGE_SLUG);
|
|
23
|
+
}
|
|
24
|
+
|
|
19
25
|
async function getContentPageBySlug(slug: string): Promise<ContentPageDef | undefined> {
|
|
20
26
|
const pages = await getAllContentPages();
|
|
21
27
|
return pages.find((content) => content.slug === slug);
|
|
@@ -26,6 +32,14 @@ export function ContentPageRepository({
|
|
|
26
32
|
return page && toMobilePage(page);
|
|
27
33
|
}
|
|
28
34
|
|
|
35
|
+
async function getIndexPage() {
|
|
36
|
+
return await getContentPageBySlug(INDEX_PAGE_SLUG);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function getIndexMobilePage() {
|
|
40
|
+
return await getMobilePageBySlug(INDEX_PAGE_SLUG);
|
|
41
|
+
}
|
|
42
|
+
|
|
29
43
|
const cache: Record<string, ContentPageDef> = {};
|
|
30
44
|
async function readPage(filePath: string): Promise<ContentPageDef> {
|
|
31
45
|
if (!(filePath in cache)) {
|
|
@@ -41,5 +55,8 @@ export function ContentPageRepository({
|
|
|
41
55
|
getAllContentPages,
|
|
42
56
|
getContentPageBySlug,
|
|
43
57
|
getMobilePageBySlug,
|
|
58
|
+
getSecondaryContentPages,
|
|
59
|
+
getIndexPage,
|
|
60
|
+
getIndexMobilePage,
|
|
44
61
|
};
|
|
45
62
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.809 2.759A2.813 2.813 0 0 1 11.742 2h5.524C18.776 2 20 3.16 20 4.59v13.82c0 1.43-1.224 2.59-2.734 2.59H6.734C5.224 21 4 19.84 4 18.41v-5.95c0-.477.408-.864.911-.864.504 0 .912.387.912.864v5.95c0 .476.408.863.911.863h10.532c.503 0 .911-.387.911-.864V4.591c0-.477-.408-.864-.911-.864h-5.367v4.03c0 .955-.816 1.728-1.823 1.728H4.911c-.368 0-.7-.21-.842-.533a.83.83 0 0 1 .198-.941l5.542-5.252Zm.267 2.19L7.112 7.758h2.964v-2.81Z" fill="#1C1C1C" />
|
|
3
|
+
<rect x="8" y="12" width="8" height="2" rx="1" fill="#42AB44" />
|
|
4
|
+
<rect x="8" y="15" width="5" height="2" rx="1" fill="#42AB44" />
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15 12h5M4 12h7" stroke="#42AB44" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 18V6M15 12h5M4 12h7M12 20V4" stroke="#42AB44" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import type { CheckboxProps } from './CheckboxProps';
|
|
3
|
+
import { SVG } from '../SVG';
|
|
4
|
+
|
|
5
|
+
const CHECK_PATHS = [
|
|
6
|
+
{
|
|
7
|
+
d: 'M10.207.793a1 1 0 0 1 0 1.414l-6 6a1 1 0 0 1-1.414 0l-2.5-2.5a1 1 0 0 1 1.414-1.414L3.5 6.086 8.793.793a1 1 0 0 1 1.414 0Z',
|
|
8
|
+
fillRule: 'evenodd',
|
|
9
|
+
clipRule: 'evenodd',
|
|
10
|
+
fill: 'white',
|
|
11
|
+
},
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
export const Checkbox = JSX<CheckboxProps>(({ text, checked, onChange, className }) => (
|
|
15
|
+
<div className={className}>
|
|
16
|
+
<label className="flex items-center cursor-pointer relative">
|
|
17
|
+
<input
|
|
18
|
+
className={`peer appearance-none w-5 h-5 border-solid border rounded border-black checked:bg-primary-main checked:border-primary-main`}
|
|
19
|
+
type="checkbox"
|
|
20
|
+
onChange={(e) => {
|
|
21
|
+
onChange(e.target.checked);
|
|
22
|
+
}}
|
|
23
|
+
checked={checked}
|
|
24
|
+
/>
|
|
25
|
+
<SVG
|
|
26
|
+
paths={CHECK_PATHS}
|
|
27
|
+
className="hidden absolute left-2 ml-px peer-checked:block"
|
|
28
|
+
width="11"
|
|
29
|
+
height="9"
|
|
30
|
+
fill="white"
|
|
31
|
+
viewBox="0 0 11 9"
|
|
32
|
+
/>
|
|
33
|
+
{text ? <span className="font-sans ml-2 text-sm cursor-pointer">{text}</span> : null}
|
|
34
|
+
</label>
|
|
35
|
+
</div>
|
|
36
|
+
));
|