@webbycrown/advanced-fields 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -6
- package/dist/_chunks/en-BPwepUqK.js +84 -0
- package/dist/_chunks/en-CJmJkBE0.mjs +84 -0
- package/dist/_chunks/index-C-A6rX1K.mjs +268 -0
- package/dist/_chunks/index-CCaZAiQR.js +268 -0
- package/{admin/src/components/AdvancedInput/index.jsx → dist/_chunks/index-DTSlHlvg.mjs} +44 -77
- package/dist/_chunks/index-DXVpJkpj.mjs +282 -0
- package/dist/_chunks/index-TmoGbq0j.js +282 -0
- package/dist/_chunks/index-lJs3vGYF.js +130 -0
- package/dist/admin/index.js +867 -0
- package/dist/admin/index.mjs +868 -0
- package/index.js +3 -47
- package/package.json +6 -5
- package/admin/jsconfig.json +0 -10
- package/admin/src/components/AdvancedCheckbox/index.jsx +0 -397
- package/admin/src/components/AdvancedRadio/index.jsx +0 -344
- package/admin/src/components/Initializer.jsx +0 -18
- package/admin/src/components/PluginIcon.jsx +0 -115
- package/admin/src/index.js +0 -739
- package/admin/src/pages/App.jsx +0 -13
- package/admin/src/pluginId.js +0 -3
- package/admin/src/utils/getTranslation.js +0 -5
- /package/{admin/src → dist/admin}/translations/en.json +0 -0
package/README.md
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
Professional custom fields for Strapi CMS that provide advanced functionality with comprehensive validation, dynamic options, and user-friendly interfaces.
|
|
8
8
|
|
|
9
|
+
📦 **NPM Package**: [@webbycrown/advanced-fields](https://www.npmjs.com/package/@webbycrown/advanced-fields)
|
|
10
|
+
|
|
9
11
|
## ✨ Features
|
|
10
12
|
|
|
11
13
|
### 🔤 Advanced Input
|
|
@@ -14,6 +16,7 @@ Professional custom fields for Strapi CMS that provide advanced functionality wi
|
|
|
14
16
|
- **Custom Error Messages**: User-friendly validation feedback
|
|
15
17
|
- **Default Values**: Pre-filled content for new entries
|
|
16
18
|
- **Placeholder Support**: Helpful hints for content creators
|
|
19
|
+
- **Field Notes**: Display helpful notes below the field
|
|
17
20
|
- **Private Fields**: Hide sensitive data from API responses
|
|
18
21
|
|
|
19
22
|
### ☑️ Advanced Checkbox
|
|
@@ -22,6 +25,7 @@ Professional custom fields for Strapi CMS that provide advanced functionality wi
|
|
|
22
25
|
- **Min/Max Validation**: Control minimum and maximum selections
|
|
23
26
|
- **Layout Options**: Vertical, horizontal, or grid layouts
|
|
24
27
|
- **Default Selections**: Pre-select options for new entries
|
|
28
|
+
- **Field Notes**: Display helpful notes below the field
|
|
25
29
|
|
|
26
30
|
### 🔘 Advanced Radio
|
|
27
31
|
- **Single & Multiple Selection**: Choose between single or multiple radio selections
|
|
@@ -29,6 +33,7 @@ Professional custom fields for Strapi CMS that provide advanced functionality wi
|
|
|
29
33
|
- **Selection Limits**: Control minimum and maximum choices
|
|
30
34
|
- **Layout Flexibility**: Multiple visual layouts
|
|
31
35
|
- **Custom Validation**: Tailored error messages
|
|
36
|
+
- **Field Notes**: Display helpful notes below the field
|
|
32
37
|
|
|
33
38
|
## 🛠️ Installation
|
|
34
39
|
|
|
@@ -57,7 +62,7 @@ yarn add @webbycrown/advanced-fields
|
|
|
57
62
|
### Advanced Input Configuration
|
|
58
63
|
|
|
59
64
|
```javascript
|
|
60
|
-
// Example: Text validation with custom error message
|
|
65
|
+
// Example: Text validation with custom error message and field note
|
|
61
66
|
{
|
|
62
67
|
"required": true,
|
|
63
68
|
"maxLength": 255,
|
|
@@ -66,7 +71,8 @@ yarn add @webbycrown/advanced-fields
|
|
|
66
71
|
"options": {
|
|
67
72
|
"customErrorMessage": "Please enter valid text",
|
|
68
73
|
"placeholder": "Enter your text here",
|
|
69
|
-
"defaultValue": "Default text"
|
|
74
|
+
"defaultValue": "Default text",
|
|
75
|
+
"fieldNote": "This field accepts alphanumeric characters and spaces only"
|
|
70
76
|
}
|
|
71
77
|
}
|
|
72
78
|
```
|
|
@@ -74,7 +80,7 @@ yarn add @webbycrown/advanced-fields
|
|
|
74
80
|
### Advanced Checkbox Configuration
|
|
75
81
|
|
|
76
82
|
```javascript
|
|
77
|
-
// Example: Multiple checkbox with validation
|
|
83
|
+
// Example: Multiple checkbox with validation and field note
|
|
78
84
|
{
|
|
79
85
|
"required": true,
|
|
80
86
|
"options": {
|
|
@@ -83,7 +89,8 @@ yarn add @webbycrown/advanced-fields
|
|
|
83
89
|
"minChoices": 1,
|
|
84
90
|
"maxChoices": 2,
|
|
85
91
|
"layout": "vertical",
|
|
86
|
-
"defaultSelected": "1\n2"
|
|
92
|
+
"defaultSelected": "1\n2",
|
|
93
|
+
"fieldNote": "Please select at least 1 and at most 2 options"
|
|
87
94
|
}
|
|
88
95
|
}
|
|
89
96
|
```
|
|
@@ -91,14 +98,15 @@ yarn add @webbycrown/advanced-fields
|
|
|
91
98
|
### Advanced Radio Configuration
|
|
92
99
|
|
|
93
100
|
```javascript
|
|
94
|
-
// Example: Single radio with dynamic options
|
|
101
|
+
// Example: Single radio with dynamic options and field note
|
|
95
102
|
{
|
|
96
103
|
"required": true,
|
|
97
104
|
"options": {
|
|
98
105
|
"selectionType": "single",
|
|
99
106
|
"radioOptions": "small|Small\nmedium|Medium\nlarge|Large",
|
|
100
107
|
"layout": "horizontal",
|
|
101
|
-
"defaultSelected": "medium"
|
|
108
|
+
"defaultSelected": "medium",
|
|
109
|
+
"fieldNote": "Choose the size that best fits your needs"
|
|
102
110
|
}
|
|
103
111
|
}
|
|
104
112
|
```
|
|
@@ -117,6 +125,7 @@ yarn add @webbycrown/advanced-fields
|
|
|
117
125
|
| `options.defaultValue` | string | Pre-filled value | `""` |
|
|
118
126
|
| `options.placeholder` | string | Placeholder text | `""` |
|
|
119
127
|
| `options.customErrorMessage` | string | Custom error message | `""` |
|
|
128
|
+
| `options.fieldNote` | string | Helpful note displayed below field | `""` |
|
|
120
129
|
| `private` | boolean | Hide from API | `false` |
|
|
121
130
|
|
|
122
131
|
### Advanced Checkbox Options
|
|
@@ -131,6 +140,7 @@ yarn add @webbycrown/advanced-fields
|
|
|
131
140
|
| `options.maxChoices` | number | Maximum selections | `0` |
|
|
132
141
|
| `options.layout` | string | `vertical`, `horizontal`, or `grid` | `vertical` |
|
|
133
142
|
| `options.customErrorMessage` | string | Custom error message | `""` |
|
|
143
|
+
| `options.fieldNote` | string | Helpful note displayed below field | `""` |
|
|
134
144
|
| `private` | boolean | Hide from API | `false` |
|
|
135
145
|
|
|
136
146
|
### Advanced Radio Options
|
|
@@ -145,6 +155,7 @@ yarn add @webbycrown/advanced-fields
|
|
|
145
155
|
| `options.maxChoices` | number | Maximum selections | `0` |
|
|
146
156
|
| `options.layout` | string | `vertical`, `horizontal`, or `grid` | `vertical` |
|
|
147
157
|
| `options.customErrorMessage` | string | Custom error message | `""` |
|
|
158
|
+
| `options.fieldNote` | string | Helpful note displayed below field | `""` |
|
|
148
159
|
| `private` | boolean | Hide from API | `false` |
|
|
149
160
|
|
|
150
161
|
## 🔧 API Usage
|
|
@@ -259,8 +270,10 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
259
270
|
- 🔘 Advanced Radio (single/multiple)
|
|
260
271
|
- 🎨 Multiple layout options
|
|
261
272
|
- ✅ Comprehensive validation system
|
|
273
|
+
- 📝 Field notes support for all field types
|
|
262
274
|
- 📱 Responsive design
|
|
263
275
|
- 🌐 Internationalization support
|
|
276
|
+
- 🚀 Published to NPM: [@webbycrown/advanced-fields](https://www.npmjs.com/package/@webbycrown/advanced-fields)
|
|
264
277
|
|
|
265
278
|
---
|
|
266
279
|
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const en = {
|
|
4
|
+
"advanced-fields.plugin.name": "Advanced Fields",
|
|
5
|
+
"advanced-fields.input.label": "Advanced Input",
|
|
6
|
+
"advanced-fields.input.description": "Professional-grade text input with comprehensive validation and advanced configuration options",
|
|
7
|
+
"advanced-fields.checkbox.label": "Advanced Checkbox",
|
|
8
|
+
"advanced-fields.checkbox.description": "Unified checkbox field supporting both single and multiple selections with advanced configuration",
|
|
9
|
+
"advanced-fields.selectinput.label": "Select Input",
|
|
10
|
+
"advanced-fields.selectinput.description": "Select an option",
|
|
11
|
+
"advanced-fields.input.settings.base.label": "Basic settings",
|
|
12
|
+
"advanced-fields.input.options.required.label": "Required field",
|
|
13
|
+
"advanced-fields.input.options.required.description": "You won't be able to create an entry if this field is empty",
|
|
14
|
+
"advanced-fields.input.options.unique.label": "Unique field",
|
|
15
|
+
"advanced-fields.input.options.unique.description": "You won't be able to create an entry if there is an existing entry with identical content",
|
|
16
|
+
"advanced-fields.input.options.maxLength.label": "Maximum length",
|
|
17
|
+
"advanced-fields.input.options.maxLength.description": "Set the maximum number of characters allowed",
|
|
18
|
+
"advanced-fields.input.options.minLength.label": "Minimum length",
|
|
19
|
+
"advanced-fields.input.options.minLength.description": "Set the minimum number of characters allowed",
|
|
20
|
+
"advanced-fields.input.options.defaultValue.label": "Default value",
|
|
21
|
+
"advanced-fields.input.options.defaultValue.description": "Set the default value for this field",
|
|
22
|
+
"advanced-fields.input.settings.advanced.label": "Advanced settings",
|
|
23
|
+
"advanced-fields.input.options.regex.label": "RegExp pattern",
|
|
24
|
+
"advanced-fields.input.options.regex.description": "The text of the regular expression",
|
|
25
|
+
"advanced-fields.input.options.placeholder.label": "Placeholder",
|
|
26
|
+
"advanced-fields.input.options.placeholder.description": "Display text when the field is empty",
|
|
27
|
+
"advanced-fields.input.options.private.label": "Private field",
|
|
28
|
+
"advanced-fields.input.options.private.description": "This field will not be included in API responses",
|
|
29
|
+
"advanced-fields.input.options.customErrorMessage.label": "Custom error message",
|
|
30
|
+
"advanced-fields.input.options.customErrorMessage.description": "Display a custom error message when validation fails",
|
|
31
|
+
"advanced-fields.checkbox.settings.base.label": "Basic settings",
|
|
32
|
+
"advanced-fields.checkbox.options.required.label": "Required field",
|
|
33
|
+
"advanced-fields.checkbox.options.required.description": "You won't be able to create an entry if this field is empty",
|
|
34
|
+
"advanced-fields.checkbox.options.checkboxType.label": "Checkbox Type",
|
|
35
|
+
"advanced-fields.checkbox.options.checkboxType.description": "Choose between single checkbox or multiple checkboxes",
|
|
36
|
+
"advanced-fields.checkbox.options.checkboxType.single": "Single Checkbox",
|
|
37
|
+
"advanced-fields.checkbox.options.checkboxType.multiple": "Multiple Checkboxes",
|
|
38
|
+
"advanced-fields.checkbox.options.defaultValue.label": "Default State",
|
|
39
|
+
"advanced-fields.checkbox.options.defaultValue.description": "Pre-checked state for single checkbox",
|
|
40
|
+
"advanced-fields.checkbox.options.defaultValue.options.true": "Checked (True)",
|
|
41
|
+
"advanced-fields.checkbox.options.defaultValue.options.false": "Unchecked (False)",
|
|
42
|
+
"advanced-fields.checkbox.settings.advanced.label": "Advanced settings",
|
|
43
|
+
"advanced-fields.checkbox.options.customErrorMessage.label": "Custom error message",
|
|
44
|
+
"advanced-fields.checkbox.options.customErrorMessage.description": "Display a custom error message when validation fails",
|
|
45
|
+
"advanced-fields.checkbox.options.customErrorMessage.placeholder": "Enter custom error message",
|
|
46
|
+
"advanced-fields.checkbox.options.private.label": "Private field",
|
|
47
|
+
"advanced-fields.checkbox.options.private.description": "This field will not be included in API responses",
|
|
48
|
+
"advanced-fields.checkbox.options.labelOn.label": "Checked Label",
|
|
49
|
+
"advanced-fields.checkbox.options.labelOn.description": "Custom label displayed when single checkbox is checked",
|
|
50
|
+
"advanced-fields.checkbox.options.labelOff.label": "Unchecked Label",
|
|
51
|
+
"advanced-fields.checkbox.options.labelOff.description": "Custom label displayed when single checkbox is unchecked",
|
|
52
|
+
"advanced-fields.checkbox.options.checkboxOptions.label": "Checkbox Options",
|
|
53
|
+
"advanced-fields.checkbox.options.checkboxOptions.description": "Define available options for multiple checkboxes (one per line: value|label)",
|
|
54
|
+
"advanced-fields.checkbox.options.checkboxOptions.placeholder": "option1|Option 1\noption2|Option 2\noption3|Option 3",
|
|
55
|
+
"advanced-fields.checkbox.options.defaultSelected.label": "Default Selected",
|
|
56
|
+
"advanced-fields.checkbox.options.defaultSelected.description": "Pre-selected options for multiple checkboxes (one per line)",
|
|
57
|
+
"advanced-fields.checkbox.options.defaultSelected.placeholder": "option1\noption2",
|
|
58
|
+
"advanced-fields.checkbox.options.minChoices.label": "Minimum Choices",
|
|
59
|
+
"advanced-fields.checkbox.options.minChoices.description": "Minimum number of options that must be selected (0 for no minimum)",
|
|
60
|
+
"advanced-fields.checkbox.options.maxChoices.label": "Maximum Choices",
|
|
61
|
+
"advanced-fields.checkbox.options.maxChoices.description": "Maximum number of options that can be selected (0 for no maximum)",
|
|
62
|
+
"advanced-fields.checkbox.options.layout.label": "Layout Style",
|
|
63
|
+
"advanced-fields.checkbox.options.layout.description": "Visual layout of multiple checkbox options",
|
|
64
|
+
"advanced-fields.checkbox.options.layout.vertical": "Vertical Stack",
|
|
65
|
+
"advanced-fields.checkbox.options.layout.horizontal": "Horizontal Row",
|
|
66
|
+
"advanced-fields.checkbox.options.layout.grid": "Grid Layout",
|
|
67
|
+
"advanced-fields.radio.label": "Multiple Type Choice",
|
|
68
|
+
"advanced-fields.radio.description": "Select one or more options (radio style)",
|
|
69
|
+
"advanced-fields.radio.settings.base.label": "Basic settings",
|
|
70
|
+
"advanced-fields.radio.options.required.label": "Multiple Type Choice",
|
|
71
|
+
"advanced-fields.radio.options.required.description": "You won't be able to create an entry if this field is empty",
|
|
72
|
+
"advanced-fields.radio.options.radioOptions.label": "Multiple Type Choice",
|
|
73
|
+
"advanced-fields.radio.options.radioOptions.description": 'Enter one option per line in format: value|label (e.g., "1|Option 1")',
|
|
74
|
+
"advanced-fields.radio.options.radioOptions.placeholder": "1|Option 1\n2|Option 2\n3|Option 3",
|
|
75
|
+
"advanced-fields.radio.options.selectionType.label": "Selection Type",
|
|
76
|
+
"advanced-fields.radio.options.selectionType.description": "Allow selecting only one or multiple type choices",
|
|
77
|
+
"advanced-fields.radio.options.customErrorMessage.label": "Custom error message",
|
|
78
|
+
"advanced-fields.radio.options.customErrorMessage.description": "Display a custom error message when validation fails",
|
|
79
|
+
"advanced-fields.radio.options.customErrorMessage.placeholder": "Enter custom error message",
|
|
80
|
+
"advanced-fields.radio.no-options": "No options defined. Please configure this field in the content type settings.",
|
|
81
|
+
"advanced-fields.radio.options.type.single": "Single selection",
|
|
82
|
+
"advanced-fields.radio.options.type.multiple": "Multiple selection"
|
|
83
|
+
};
|
|
84
|
+
exports.default = en;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const en = {
|
|
2
|
+
"advanced-fields.plugin.name": "Advanced Fields",
|
|
3
|
+
"advanced-fields.input.label": "Advanced Input",
|
|
4
|
+
"advanced-fields.input.description": "Professional-grade text input with comprehensive validation and advanced configuration options",
|
|
5
|
+
"advanced-fields.checkbox.label": "Advanced Checkbox",
|
|
6
|
+
"advanced-fields.checkbox.description": "Unified checkbox field supporting both single and multiple selections with advanced configuration",
|
|
7
|
+
"advanced-fields.selectinput.label": "Select Input",
|
|
8
|
+
"advanced-fields.selectinput.description": "Select an option",
|
|
9
|
+
"advanced-fields.input.settings.base.label": "Basic settings",
|
|
10
|
+
"advanced-fields.input.options.required.label": "Required field",
|
|
11
|
+
"advanced-fields.input.options.required.description": "You won't be able to create an entry if this field is empty",
|
|
12
|
+
"advanced-fields.input.options.unique.label": "Unique field",
|
|
13
|
+
"advanced-fields.input.options.unique.description": "You won't be able to create an entry if there is an existing entry with identical content",
|
|
14
|
+
"advanced-fields.input.options.maxLength.label": "Maximum length",
|
|
15
|
+
"advanced-fields.input.options.maxLength.description": "Set the maximum number of characters allowed",
|
|
16
|
+
"advanced-fields.input.options.minLength.label": "Minimum length",
|
|
17
|
+
"advanced-fields.input.options.minLength.description": "Set the minimum number of characters allowed",
|
|
18
|
+
"advanced-fields.input.options.defaultValue.label": "Default value",
|
|
19
|
+
"advanced-fields.input.options.defaultValue.description": "Set the default value for this field",
|
|
20
|
+
"advanced-fields.input.settings.advanced.label": "Advanced settings",
|
|
21
|
+
"advanced-fields.input.options.regex.label": "RegExp pattern",
|
|
22
|
+
"advanced-fields.input.options.regex.description": "The text of the regular expression",
|
|
23
|
+
"advanced-fields.input.options.placeholder.label": "Placeholder",
|
|
24
|
+
"advanced-fields.input.options.placeholder.description": "Display text when the field is empty",
|
|
25
|
+
"advanced-fields.input.options.private.label": "Private field",
|
|
26
|
+
"advanced-fields.input.options.private.description": "This field will not be included in API responses",
|
|
27
|
+
"advanced-fields.input.options.customErrorMessage.label": "Custom error message",
|
|
28
|
+
"advanced-fields.input.options.customErrorMessage.description": "Display a custom error message when validation fails",
|
|
29
|
+
"advanced-fields.checkbox.settings.base.label": "Basic settings",
|
|
30
|
+
"advanced-fields.checkbox.options.required.label": "Required field",
|
|
31
|
+
"advanced-fields.checkbox.options.required.description": "You won't be able to create an entry if this field is empty",
|
|
32
|
+
"advanced-fields.checkbox.options.checkboxType.label": "Checkbox Type",
|
|
33
|
+
"advanced-fields.checkbox.options.checkboxType.description": "Choose between single checkbox or multiple checkboxes",
|
|
34
|
+
"advanced-fields.checkbox.options.checkboxType.single": "Single Checkbox",
|
|
35
|
+
"advanced-fields.checkbox.options.checkboxType.multiple": "Multiple Checkboxes",
|
|
36
|
+
"advanced-fields.checkbox.options.defaultValue.label": "Default State",
|
|
37
|
+
"advanced-fields.checkbox.options.defaultValue.description": "Pre-checked state for single checkbox",
|
|
38
|
+
"advanced-fields.checkbox.options.defaultValue.options.true": "Checked (True)",
|
|
39
|
+
"advanced-fields.checkbox.options.defaultValue.options.false": "Unchecked (False)",
|
|
40
|
+
"advanced-fields.checkbox.settings.advanced.label": "Advanced settings",
|
|
41
|
+
"advanced-fields.checkbox.options.customErrorMessage.label": "Custom error message",
|
|
42
|
+
"advanced-fields.checkbox.options.customErrorMessage.description": "Display a custom error message when validation fails",
|
|
43
|
+
"advanced-fields.checkbox.options.customErrorMessage.placeholder": "Enter custom error message",
|
|
44
|
+
"advanced-fields.checkbox.options.private.label": "Private field",
|
|
45
|
+
"advanced-fields.checkbox.options.private.description": "This field will not be included in API responses",
|
|
46
|
+
"advanced-fields.checkbox.options.labelOn.label": "Checked Label",
|
|
47
|
+
"advanced-fields.checkbox.options.labelOn.description": "Custom label displayed when single checkbox is checked",
|
|
48
|
+
"advanced-fields.checkbox.options.labelOff.label": "Unchecked Label",
|
|
49
|
+
"advanced-fields.checkbox.options.labelOff.description": "Custom label displayed when single checkbox is unchecked",
|
|
50
|
+
"advanced-fields.checkbox.options.checkboxOptions.label": "Checkbox Options",
|
|
51
|
+
"advanced-fields.checkbox.options.checkboxOptions.description": "Define available options for multiple checkboxes (one per line: value|label)",
|
|
52
|
+
"advanced-fields.checkbox.options.checkboxOptions.placeholder": "option1|Option 1\noption2|Option 2\noption3|Option 3",
|
|
53
|
+
"advanced-fields.checkbox.options.defaultSelected.label": "Default Selected",
|
|
54
|
+
"advanced-fields.checkbox.options.defaultSelected.description": "Pre-selected options for multiple checkboxes (one per line)",
|
|
55
|
+
"advanced-fields.checkbox.options.defaultSelected.placeholder": "option1\noption2",
|
|
56
|
+
"advanced-fields.checkbox.options.minChoices.label": "Minimum Choices",
|
|
57
|
+
"advanced-fields.checkbox.options.minChoices.description": "Minimum number of options that must be selected (0 for no minimum)",
|
|
58
|
+
"advanced-fields.checkbox.options.maxChoices.label": "Maximum Choices",
|
|
59
|
+
"advanced-fields.checkbox.options.maxChoices.description": "Maximum number of options that can be selected (0 for no maximum)",
|
|
60
|
+
"advanced-fields.checkbox.options.layout.label": "Layout Style",
|
|
61
|
+
"advanced-fields.checkbox.options.layout.description": "Visual layout of multiple checkbox options",
|
|
62
|
+
"advanced-fields.checkbox.options.layout.vertical": "Vertical Stack",
|
|
63
|
+
"advanced-fields.checkbox.options.layout.horizontal": "Horizontal Row",
|
|
64
|
+
"advanced-fields.checkbox.options.layout.grid": "Grid Layout",
|
|
65
|
+
"advanced-fields.radio.label": "Multiple Type Choice",
|
|
66
|
+
"advanced-fields.radio.description": "Select one or more options (radio style)",
|
|
67
|
+
"advanced-fields.radio.settings.base.label": "Basic settings",
|
|
68
|
+
"advanced-fields.radio.options.required.label": "Multiple Type Choice",
|
|
69
|
+
"advanced-fields.radio.options.required.description": "You won't be able to create an entry if this field is empty",
|
|
70
|
+
"advanced-fields.radio.options.radioOptions.label": "Multiple Type Choice",
|
|
71
|
+
"advanced-fields.radio.options.radioOptions.description": 'Enter one option per line in format: value|label (e.g., "1|Option 1")',
|
|
72
|
+
"advanced-fields.radio.options.radioOptions.placeholder": "1|Option 1\n2|Option 2\n3|Option 3",
|
|
73
|
+
"advanced-fields.radio.options.selectionType.label": "Selection Type",
|
|
74
|
+
"advanced-fields.radio.options.selectionType.description": "Allow selecting only one or multiple type choices",
|
|
75
|
+
"advanced-fields.radio.options.customErrorMessage.label": "Custom error message",
|
|
76
|
+
"advanced-fields.radio.options.customErrorMessage.description": "Display a custom error message when validation fails",
|
|
77
|
+
"advanced-fields.radio.options.customErrorMessage.placeholder": "Enter custom error message",
|
|
78
|
+
"advanced-fields.radio.no-options": "No options defined. Please configure this field in the content type settings.",
|
|
79
|
+
"advanced-fields.radio.options.type.single": "Single selection",
|
|
80
|
+
"advanced-fields.radio.options.type.multiple": "Multiple selection"
|
|
81
|
+
};
|
|
82
|
+
export {
|
|
83
|
+
en as default
|
|
84
|
+
};
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useIntl } from "react-intl";
|
|
3
|
+
import { Box, Field, Flex } from "@strapi/design-system";
|
|
4
|
+
import { useState, useEffect } from "react";
|
|
5
|
+
const AdvancedRadio = ({
|
|
6
|
+
attribute = {},
|
|
7
|
+
description = { id: "", defaultMessage: "" },
|
|
8
|
+
disabled,
|
|
9
|
+
error,
|
|
10
|
+
intlLabel = { id: "", defaultMessage: "" },
|
|
11
|
+
labelAction,
|
|
12
|
+
name,
|
|
13
|
+
onChange,
|
|
14
|
+
required,
|
|
15
|
+
value
|
|
16
|
+
}) => {
|
|
17
|
+
const { formatMessage } = useIntl();
|
|
18
|
+
const [selectedValues, setSelectedValues] = useState([]);
|
|
19
|
+
const [validationError, setValidationError] = useState(null);
|
|
20
|
+
const [hasInteracted, setHasInteracted] = useState(false);
|
|
21
|
+
const [isInitialized, setIsInitialized] = useState(false);
|
|
22
|
+
const {
|
|
23
|
+
selectionType = "single",
|
|
24
|
+
layout = "vertical",
|
|
25
|
+
minChoices = 0,
|
|
26
|
+
maxChoices = 0,
|
|
27
|
+
defaultSelected = "",
|
|
28
|
+
radioOptions = "",
|
|
29
|
+
customErrorMessage = "",
|
|
30
|
+
fieldNote = ""
|
|
31
|
+
} = attribute.options || attribute;
|
|
32
|
+
const fieldNoteFromAttribute = attribute.options?.fieldNote || "";
|
|
33
|
+
const options = radioOptions.split("\n").filter((opt) => opt.trim()).map((opt) => {
|
|
34
|
+
const [value2, label] = opt.split("|");
|
|
35
|
+
return { value: value2?.trim() || "", label: label?.trim() || value2?.trim() || "" };
|
|
36
|
+
});
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
let initialValues = [];
|
|
39
|
+
if (value && Array.isArray(value)) {
|
|
40
|
+
initialValues = value;
|
|
41
|
+
} else if (value && typeof value === "string") {
|
|
42
|
+
initialValues = value.split(",").map((v) => v.trim()).filter((v) => v);
|
|
43
|
+
} else if (defaultSelected) {
|
|
44
|
+
initialValues = defaultSelected.split(",").map((v) => v.trim()).filter((v) => v);
|
|
45
|
+
}
|
|
46
|
+
setSelectedValues(initialValues);
|
|
47
|
+
const validationResult = validateSelection(initialValues);
|
|
48
|
+
setValidationError(validationResult);
|
|
49
|
+
if (onChange && initialValues.length > 0 && (!value || Array.isArray(value) && value.length === 0) && !isInitialized) {
|
|
50
|
+
setTimeout(() => {
|
|
51
|
+
onChange({
|
|
52
|
+
target: {
|
|
53
|
+
value: initialValues,
|
|
54
|
+
name,
|
|
55
|
+
id: name
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
setIsInitialized(true);
|
|
59
|
+
}, 0);
|
|
60
|
+
} else if (!isInitialized) {
|
|
61
|
+
setIsInitialized(true);
|
|
62
|
+
}
|
|
63
|
+
}, [value, defaultSelected, onChange, error]);
|
|
64
|
+
const validateSelection = (values) => {
|
|
65
|
+
const valArray = Array.isArray(values) ? values : [];
|
|
66
|
+
if (required && valArray.length === 0) {
|
|
67
|
+
return customErrorMessage || "This field is required";
|
|
68
|
+
}
|
|
69
|
+
if (valArray.length === 0) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
if (selectionType === "multiple") {
|
|
73
|
+
if (minChoices > 0 && valArray.length < minChoices) {
|
|
74
|
+
return customErrorMessage || `Please select at least ${minChoices} option${minChoices > 1 ? "s" : ""}`;
|
|
75
|
+
}
|
|
76
|
+
if (maxChoices > 0 && valArray.length > maxChoices) {
|
|
77
|
+
return customErrorMessage || `Please select at most ${maxChoices} option${maxChoices > 1 ? "s" : ""}`;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
};
|
|
82
|
+
const handleRadioChange = (optionValue, isChecked) => {
|
|
83
|
+
let newValues;
|
|
84
|
+
if (selectionType === "single") {
|
|
85
|
+
newValues = isChecked ? [optionValue] : [];
|
|
86
|
+
} else {
|
|
87
|
+
if (isChecked) {
|
|
88
|
+
newValues = [...selectedValues, optionValue];
|
|
89
|
+
} else {
|
|
90
|
+
newValues = selectedValues.filter((val) => val !== optionValue);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
setSelectedValues(newValues);
|
|
94
|
+
setHasInteracted(true);
|
|
95
|
+
const error2 = validateSelection(newValues);
|
|
96
|
+
setValidationError(error2);
|
|
97
|
+
if (onChange) {
|
|
98
|
+
const event = {
|
|
99
|
+
target: {
|
|
100
|
+
name,
|
|
101
|
+
id: name,
|
|
102
|
+
value: newValues
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
onChange(event);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
const displayError = error || hasInteracted && validationError;
|
|
109
|
+
const renderRadios = () => {
|
|
110
|
+
const radioStyle = {
|
|
111
|
+
display: "flex",
|
|
112
|
+
alignItems: "center",
|
|
113
|
+
gap: "8px",
|
|
114
|
+
padding: "4px 0"
|
|
115
|
+
};
|
|
116
|
+
const radioInputStyle = {
|
|
117
|
+
width: "16px",
|
|
118
|
+
height: "16px",
|
|
119
|
+
accentColor: "#4945ff",
|
|
120
|
+
margin: "0",
|
|
121
|
+
padding: "0",
|
|
122
|
+
opacity: "1",
|
|
123
|
+
visibility: "visible",
|
|
124
|
+
display: "block",
|
|
125
|
+
position: "relative",
|
|
126
|
+
zIndex: "1",
|
|
127
|
+
cursor: "pointer",
|
|
128
|
+
border: "2px solid #dcdce4",
|
|
129
|
+
borderRadius: "50%",
|
|
130
|
+
backgroundColor: "white",
|
|
131
|
+
transition: "all 0.2s ease"
|
|
132
|
+
};
|
|
133
|
+
const customRadioStyle = {
|
|
134
|
+
width: "16px",
|
|
135
|
+
height: "16px",
|
|
136
|
+
borderRadius: "50%",
|
|
137
|
+
borderWidth: "1px",
|
|
138
|
+
borderStyle: "solid",
|
|
139
|
+
backgroundColor: "#ffffff",
|
|
140
|
+
cursor: "pointer",
|
|
141
|
+
transition: "all 0.2s ease",
|
|
142
|
+
position: "relative",
|
|
143
|
+
display: "flex",
|
|
144
|
+
alignItems: "center",
|
|
145
|
+
justifyContent: "center"
|
|
146
|
+
};
|
|
147
|
+
const customRadioCheckedStyle = {
|
|
148
|
+
...customRadioStyle,
|
|
149
|
+
backgroundColor: "#ffffff",
|
|
150
|
+
borderColor: "#4945ff"
|
|
151
|
+
};
|
|
152
|
+
const customRadioDotStyle = {
|
|
153
|
+
width: "10px",
|
|
154
|
+
height: "10px",
|
|
155
|
+
borderRadius: "50%",
|
|
156
|
+
backgroundColor: "#4945ff"
|
|
157
|
+
};
|
|
158
|
+
const radioLabelStyle = {
|
|
159
|
+
fontSize: "14px",
|
|
160
|
+
fontFamily: "inherit",
|
|
161
|
+
cursor: "pointer",
|
|
162
|
+
userSelect: "none",
|
|
163
|
+
color: "#32324d",
|
|
164
|
+
fontWeight: "400",
|
|
165
|
+
lineHeight: "1.5",
|
|
166
|
+
marginLeft: "4px"
|
|
167
|
+
};
|
|
168
|
+
if (!options || options.length === 0) {
|
|
169
|
+
return /* @__PURE__ */ jsx("div", { style: { padding: "8px", color: "#666", fontStyle: "italic" }, children: formatMessage({
|
|
170
|
+
id: "advanced-fields.radio.no-options",
|
|
171
|
+
defaultMessage: "No options defined. Please configure this field in the content type settings."
|
|
172
|
+
}) });
|
|
173
|
+
}
|
|
174
|
+
if (layout === "horizontal") {
|
|
175
|
+
return /* @__PURE__ */ jsx(Flex, { wrap: "wrap", gap: 2, children: options.map((option) => /* @__PURE__ */ jsxs("div", { style: radioStyle, children: [
|
|
176
|
+
selectionType === "multiple" ? (
|
|
177
|
+
// Custom radio button appearance for multiple selection
|
|
178
|
+
/* @__PURE__ */ jsx(
|
|
179
|
+
"div",
|
|
180
|
+
{
|
|
181
|
+
style: selectedValues.includes(option.value) ? customRadioCheckedStyle : customRadioStyle,
|
|
182
|
+
onClick: () => handleRadioChange(option.value, !selectedValues.includes(option.value)),
|
|
183
|
+
children: selectedValues.includes(option.value) && /* @__PURE__ */ jsx("div", { style: customRadioDotStyle })
|
|
184
|
+
}
|
|
185
|
+
)
|
|
186
|
+
) : (
|
|
187
|
+
// Regular radio button for single selection
|
|
188
|
+
/* @__PURE__ */ jsx(
|
|
189
|
+
"input",
|
|
190
|
+
{
|
|
191
|
+
type: "radio",
|
|
192
|
+
id: `${name}-${option.value}`,
|
|
193
|
+
name,
|
|
194
|
+
checked: selectedValues.includes(option.value),
|
|
195
|
+
onChange: (e) => handleRadioChange(option.value, e.target.checked),
|
|
196
|
+
disabled,
|
|
197
|
+
style: radioInputStyle
|
|
198
|
+
}
|
|
199
|
+
)
|
|
200
|
+
),
|
|
201
|
+
/* @__PURE__ */ jsx(
|
|
202
|
+
"label",
|
|
203
|
+
{
|
|
204
|
+
htmlFor: selectionType === "single" ? `${name}-${option.value}` : void 0,
|
|
205
|
+
style: radioLabelStyle,
|
|
206
|
+
onClick: selectionType === "multiple" ? () => handleRadioChange(option.value, !selectedValues.includes(option.value)) : void 0,
|
|
207
|
+
children: option.label
|
|
208
|
+
}
|
|
209
|
+
)
|
|
210
|
+
] }, option.value)) });
|
|
211
|
+
}
|
|
212
|
+
return /* @__PURE__ */ jsx("div", { children: options.map((option) => /* @__PURE__ */ jsxs("div", { style: radioStyle, children: [
|
|
213
|
+
selectionType === "multiple" ? (
|
|
214
|
+
// Custom radio button appearance for multiple selection
|
|
215
|
+
/* @__PURE__ */ jsx(
|
|
216
|
+
"div",
|
|
217
|
+
{
|
|
218
|
+
style: selectedValues.includes(option.value) ? customRadioCheckedStyle : customRadioStyle,
|
|
219
|
+
onClick: () => handleRadioChange(option.value, !selectedValues.includes(option.value)),
|
|
220
|
+
children: selectedValues.includes(option.value) && /* @__PURE__ */ jsx("div", { style: customRadioDotStyle })
|
|
221
|
+
}
|
|
222
|
+
)
|
|
223
|
+
) : (
|
|
224
|
+
// Regular radio button for single selection
|
|
225
|
+
/* @__PURE__ */ jsx(
|
|
226
|
+
"input",
|
|
227
|
+
{
|
|
228
|
+
type: "radio",
|
|
229
|
+
id: `${name}-${option.value}`,
|
|
230
|
+
name,
|
|
231
|
+
checked: selectedValues.includes(option.value),
|
|
232
|
+
onChange: (e) => handleRadioChange(option.value, e.target.checked),
|
|
233
|
+
disabled,
|
|
234
|
+
style: radioInputStyle
|
|
235
|
+
}
|
|
236
|
+
)
|
|
237
|
+
),
|
|
238
|
+
/* @__PURE__ */ jsx(
|
|
239
|
+
"label",
|
|
240
|
+
{
|
|
241
|
+
htmlFor: selectionType === "single" ? `${name}-${option.value}` : void 0,
|
|
242
|
+
style: radioLabelStyle,
|
|
243
|
+
onClick: selectionType === "multiple" ? () => handleRadioChange(option.value, !selectedValues.includes(option.value)) : void 0,
|
|
244
|
+
children: option.label
|
|
245
|
+
}
|
|
246
|
+
)
|
|
247
|
+
] }, option.value)) });
|
|
248
|
+
};
|
|
249
|
+
return /* @__PURE__ */ jsx(Box, { col: 6, children: /* @__PURE__ */ jsxs(Field.Root, { name, error: displayError, children: [
|
|
250
|
+
/* @__PURE__ */ jsxs(Field.Label, { children: [
|
|
251
|
+
intlLabel.id ? formatMessage(intlLabel) : intlLabel.defaultMessage || name,
|
|
252
|
+
required && /* @__PURE__ */ jsx("span", { style: { color: "#d02b20", marginLeft: "4px" }, children: "*" })
|
|
253
|
+
] }),
|
|
254
|
+
renderRadios(),
|
|
255
|
+
displayError && /* @__PURE__ */ jsx(Field.Error, { children: displayError }),
|
|
256
|
+
description && (description.id || description.defaultMessage) && /* @__PURE__ */ jsx(Field.Hint, { children: description.id ? formatMessage(description) : description.defaultMessage }),
|
|
257
|
+
(fieldNote || fieldNoteFromAttribute) && /* @__PURE__ */ jsx("span", { style: {
|
|
258
|
+
fontStyle: "italic",
|
|
259
|
+
color: "#666",
|
|
260
|
+
fontSize: "12px",
|
|
261
|
+
display: "block",
|
|
262
|
+
marginTop: "4px"
|
|
263
|
+
}, children: fieldNote || fieldNoteFromAttribute })
|
|
264
|
+
] }) });
|
|
265
|
+
};
|
|
266
|
+
export {
|
|
267
|
+
AdvancedRadio as default
|
|
268
|
+
};
|