@webbycrown/advanced-fields 1.0.1 → 1.0.2

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 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
 
@@ -4,7 +4,7 @@ import { useIntl } from "react-intl";
4
4
  import { Field, Box, Flex, Typography } from "@strapi/design-system";
5
5
  import { useState, useEffect } from "react";
6
6
 
7
- const CheckboxInput = ({
7
+ const AdvancedCheckbox = ({
8
8
  attribute = {},
9
9
  description = { id: "", defaultMessage: "" },
10
10
  disabled,
@@ -26,16 +26,12 @@ const CheckboxInput = ({
26
26
  defaultSelected = "",
27
27
  checkboxOptions = "",
28
28
  customErrorMessage = "",
29
+ fieldNote = "",
29
30
  } = attribute.options || attribute;
30
31
 
31
- // Debug logging for checkboxType detection
32
- // console.log('AdvancedCheckbox options detection:', {
33
- // attribute,
34
- // attributeOptions: attribute.options,
35
- // checkboxType,
36
- // checkboxOptions,
37
- // allOptions: attribute.options || attribute
38
- // });
32
+ // Also check attribute.options for fieldNote
33
+ const fieldNoteFromAttribute = attribute.options?.fieldNote || '';
34
+
39
35
 
40
36
  // Initialize with default values if available
41
37
  const getInitialValues = () => {
@@ -82,13 +78,6 @@ const CheckboxInput = ({
82
78
  useEffect(() => {
83
79
  const initialValues = getInitialValues();
84
80
 
85
- console.log('AdvancedCheckbox initialization:', {
86
- value,
87
- defaultSelected,
88
- initialValues,
89
- required,
90
- error
91
- });
92
81
 
93
82
  setFieldValue(initialValues);
94
83
 
@@ -182,19 +171,9 @@ const CheckboxInput = ({
182
171
  const error = validateSelection(newValue);
183
172
  setValidationError(error);
184
173
 
185
- console.log('AdvancedCheckbox handleCheckboxChange:', {
186
- optionValue,
187
- isChecked,
188
- newValue,
189
- error,
190
- hasInteracted: true,
191
- checkboxType,
192
- isInitialized
193
- });
194
174
 
195
175
  // Always trigger onChange for user interactions
196
176
  if (onChange) {
197
- console.log(onChange)
198
177
  onChange({
199
178
  target: {
200
179
  value: newValue,
@@ -207,17 +186,7 @@ const CheckboxInput = ({
207
186
 
208
187
  // Show validation error - prioritize Strapi's error, then our validation only after user interaction
209
188
  const displayError = error || (hasInteracted && validationError);
210
- console.log('displayError', displayError);
211
189
  const renderCheckboxes = () => {
212
- // Debug logging
213
- // console.log('AdvancedCheckbox renderCheckboxes:', {
214
- // checkboxType,
215
- // checkboxOptions,
216
- // options,
217
- // attribute,
218
- // attributeOptions: attribute.options,
219
- // fieldValue
220
- // });
221
190
 
222
191
  const checkboxStyle = {
223
192
  display: "flex",
@@ -389,9 +358,20 @@ const CheckboxInput = ({
389
358
  {description.id ? formatMessage(description) : description.defaultMessage}
390
359
  </Field.Hint>
391
360
  )}
361
+ {(fieldNote || fieldNoteFromAttribute) && (
362
+ <span style={{
363
+ fontStyle: 'italic',
364
+ color: '#666',
365
+ fontSize: '12px',
366
+ display: 'block',
367
+ marginTop: '4px'
368
+ }}>
369
+ {fieldNote || fieldNoteFromAttribute}
370
+ </span>
371
+ )}
392
372
  </Field.Root>
393
373
  </Box>
394
374
  );
395
375
  };
396
376
 
397
- export default CheckboxInput;
377
+ export default AdvancedCheckbox;
@@ -5,7 +5,7 @@ import { Field, Box } from "@strapi/design-system";
5
5
  import { Cross } from "@strapi/icons";
6
6
  import { useState, useEffect } from "react";
7
7
 
8
- const TextInput = ({
8
+ const AdvancedInput = ({
9
9
  attribute = {},
10
10
  description = { id: "", defaultMessage: "" },
11
11
  disabled,
@@ -38,8 +38,13 @@ const TextInput = ({
38
38
  defaultValue = '',
39
39
  customErrorMessage = '',
40
40
  regex = '',
41
+ fieldNote = '',
41
42
  } = options;
42
43
 
44
+ // Also check attribute.options for fieldNote
45
+ const fieldNoteFromAttribute = attribute.options?.fieldNote || '';
46
+
47
+
43
48
  // Initialize input value
44
49
  useEffect(() => {
45
50
  const initialValue = value === undefined ? defaultValue : value;
@@ -155,9 +160,20 @@ const TextInput = ({
155
160
  {description.id ? formatMessage(description) : description.defaultMessage}
156
161
  </Field.Hint>
157
162
  )}
163
+ {(fieldNote || fieldNoteFromAttribute) && (
164
+ <span style={{
165
+ fontStyle: 'italic',
166
+ color: '#666',
167
+ fontSize: '12px',
168
+ display: 'block',
169
+ marginTop: '4px'
170
+ }}>
171
+ {fieldNote || fieldNoteFromAttribute}
172
+ </span>
173
+ )}
158
174
  </Field.Root>
159
175
  </Box>
160
176
  );
161
177
  };
162
178
 
163
- export default TextInput;
179
+ export default AdvancedInput;
@@ -4,7 +4,7 @@ import { useIntl } from "react-intl";
4
4
  import { Field, Box, Flex, Typography } from "@strapi/design-system";
5
5
  import { useState, useEffect } from "react";
6
6
 
7
- const RadioInput = ({
7
+ const AdvancedRadio = ({
8
8
  attribute = {},
9
9
  description = { id: "", defaultMessage: "" },
10
10
  disabled,
@@ -30,8 +30,12 @@ const RadioInput = ({
30
30
  defaultSelected = "",
31
31
  radioOptions = "",
32
32
  customErrorMessage = "",
33
+ fieldNote = "",
33
34
  } = attribute.options || attribute;
34
35
 
36
+ // Also check attribute.options for fieldNote
37
+ const fieldNoteFromAttribute = attribute.options?.fieldNote || '';
38
+
35
39
  // Parse radio options
36
40
  const options = radioOptions
37
41
  .split("\n")
@@ -128,13 +132,6 @@ const RadioInput = ({
128
132
  const error = validateSelection(newValues);
129
133
  setValidationError(error);
130
134
 
131
- // console.log('AdvancedRadio handleRadioChange:', {
132
- // optionValue,
133
- // isChecked,
134
- // newValues,
135
- // error,
136
- // hasInteracted: true
137
- // });
138
135
 
139
136
  if (onChange) {
140
137
  // Create a proper event object with name and id attributes
@@ -153,14 +150,6 @@ const RadioInput = ({
153
150
  const displayError = error || (hasInteracted && validationError);
154
151
 
155
152
  const renderRadios = () => {
156
- // Debug logging
157
- // console.log('AdvancedRadio renderRadios:', {
158
- // radioOptions,
159
- // options,
160
- // attribute,
161
- // attributeOptions: attribute.options,
162
- // selectedValues
163
- // });
164
153
 
165
154
  const radioStyle = {
166
155
  display: "flex",
@@ -336,9 +325,20 @@ const RadioInput = ({
336
325
  {description.id ? formatMessage(description) : description.defaultMessage}
337
326
  </Field.Hint>
338
327
  )}
328
+ {(fieldNote || fieldNoteFromAttribute) && (
329
+ <span style={{
330
+ fontStyle: 'italic',
331
+ color: '#666',
332
+ fontSize: '12px',
333
+ display: 'block',
334
+ marginTop: '4px'
335
+ }}>
336
+ {fieldNote || fieldNoteFromAttribute}
337
+ </span>
338
+ )}
339
339
  </Field.Root>
340
340
  </Box>
341
341
  );
342
342
  };
343
343
 
344
- export default RadioInput;
344
+ export default AdvancedRadio;
@@ -1,12 +1,11 @@
1
- import { PuzzlePiece } from '@strapi/icons';
2
1
  import { Box } from '@strapi/design-system';
3
2
 
4
3
  const PluginIcon = (props) => {
5
- return <PuzzlePiece {...props} />;
4
+ return <AdvancedRadioIcon {...props} />;
6
5
  };
7
6
 
8
7
  // Advanced Input Icon - Clean text input with validation indicator
9
- const TextFieldIcon = () => (
8
+ const AdvancedInputIcon = () => (
10
9
  <Box
11
10
  style={{
12
11
  width: '28px',
@@ -20,27 +19,25 @@ const TextFieldIcon = () => (
20
19
  }}
21
20
  >
22
21
  <svg
23
- xmlns="http://www.w3.org/2000/svg"
24
- viewBox="0 0 24 24"
25
22
  width="18"
26
23
  height="18"
24
+ viewBox="0 0 32 32"
27
25
  fill="none"
28
- stroke="#495057"
29
- strokeWidth="2"
30
- strokeLinecap="round"
31
- strokeLinejoin="round"
26
+ xmlns="http://www.w3.org/2000/svg"
32
27
  >
33
- <rect x="3" y="4" width="18" height="16" rx="2" ry="2"/>
34
- <line x1="7" y1="8" x2="17" y2="8"/>
35
- <line x1="7" y1="12" x2="13" y2="12"/>
36
- <circle cx="18" cy="6" r="2" fill="#28a745"/>
37
- <path d="m16 5 2 2-2 2" stroke="#fff" strokeWidth="1.5"/>
28
+ <rect width="32" height="32" rx="6" fill="#4945FF" fillOpacity="0.1"/>
29
+ <rect x="0.5" y="0.5" width="31" height="31" rx="5.5" stroke="#4945FF" strokeOpacity="0.15"/>
30
+ <path d="M27 11.6364V20.3636C27 20.7494 26.8455 21.1194 26.5704 21.3922C26.2954 21.6649 25.9223 21.8182 25.5333 21.8182H17.1C17.0028 21.8182 16.9095 21.7799 16.8407 21.7117C16.772 21.6435 16.7333 21.551 16.7333 21.4545V10.5455C16.7333 10.449 16.772 10.3565 16.8407 10.2883C16.9095 10.2201 17.0028 10.1818 17.1 10.1818H25.5333C25.9223 10.1818 26.2954 10.3351 26.5704 10.6078C26.8455 10.8806 27 11.2506 27 11.6364ZM15.2667 8.72727V23.2727C15.2667 23.4656 15.1894 23.6506 15.0519 23.787C14.9144 23.9234 14.7278 24 14.5333 24C14.3388 24 14.1523 23.9234 14.0148 23.787C13.8773 23.6506 13.8 23.4656 13.8 23.2727V21.8182H6.46667C6.07768 21.8182 5.70463 21.6649 5.42958 21.3922C5.15452 21.1194 5 20.7494 5 20.3636V11.6364C5 11.2506 5.15452 10.8806 5.42958 10.6078C5.70463 10.3351 6.07768 10.1818 6.46667 10.1818H13.8V8.72727C13.8 8.53439 13.8773 8.3494 14.0148 8.21301C14.1523 8.07662 14.3388 8 14.5333 8C14.7278 8 14.9144 8.07662 15.0519 8.21301C15.1894 8.3494 15.2667 8.53439 15.2667 8.72727ZM12.3333 14.5455C12.3333 14.3526 12.2561 14.1676 12.1185 14.0312C11.981 13.8948 11.7945 13.8182 11.6 13.8182H8.66667C8.47217 13.8182 8.28565 13.8948 8.14812 14.0312C8.0106 14.1676 7.93333 14.3526 7.93333 14.5455C7.93333 14.7383 8.0106 14.9233 8.14812 15.0597C8.28565 15.1961 8.47217 15.2727 8.66667 15.2727H9.4V17.4545C9.4 17.6474 9.47726 17.8324 9.61479 17.9688C9.75232 18.1052 9.93884 18.1818 10.1333 18.1818C10.3278 18.1818 10.5144 18.1052 10.6519 17.9688C10.7894 17.8324 10.8667 17.6474 10.8667 17.4545V15.2727H11.6C11.7945 15.2727 11.981 15.1961 12.1185 15.0597C12.2561 14.9233 12.3333 14.7383 12.3333 14.5455Z" fill="#4945FF"/>
31
+ <mask id="path-4-inside-1_649_85" fill="white">
32
+ <path d="M0 6C0 2.68629 2.68629 0 6 0H10V10H0V6Z"/>
33
+ </mask>
34
+ <path d="M-2 6C-2 1.58172 1.58172 -2 6 -2H10V2H6C3.79086 2 2 3.79086 2 6H-2ZM10 10H0H10ZM-2 10V6C-2 1.58172 1.58172 -2 6 -2V2C3.79086 2 2 3.79086 2 6V10H-2ZM10 0V10V0Z" fill="#4945FF" mask="url(#path-4-inside-1_649_85)"/>
38
35
  </svg>
39
36
  </Box>
40
37
  );
41
38
 
42
39
  // Advanced Checkbox Icon - Modern checkbox with multiple states
43
- const CheckIcon = () => (
40
+ const AdvancedCheckboxIcon = () => (
44
41
  <Box
45
42
  style={{
46
43
  width: '28px',
@@ -54,26 +51,25 @@ const CheckIcon = () => (
54
51
  }}
55
52
  >
56
53
  <svg
57
- xmlns="http://www.w3.org/2000/svg"
58
- viewBox="0 0 24 24"
59
54
  width="18"
60
55
  height="18"
56
+ viewBox="0 0 32 32"
61
57
  fill="none"
62
- stroke="#495057"
63
- strokeWidth="2"
64
- strokeLinecap="round"
65
- strokeLinejoin="round"
58
+ xmlns="http://www.w3.org/2000/svg"
66
59
  >
67
- <rect x="3" y="3" width="18" height="18" rx="2" ry="2"/>
68
- <polyline points="9,12 12,15 22,5" stroke="#28a745" strokeWidth="2.5"/>
69
- <rect x="3" y="8" width="12" height="2" rx="1" fill="#6c757d" opacity="0.3"/>
70
- <rect x="3" y="12" width="8" height="2" rx="1" fill="#6c757d" opacity="0.3"/>
60
+ <rect width="32" height="32" rx="6" fill="#4945FF" fillOpacity="0.1"/>
61
+ <rect x="0.5" y="0.5" width="31" height="31" rx="5.5" stroke="#4945FF" strokeOpacity="0.15"/>
62
+ <mask id="path-3-inside-1_649_76" fill="white">
63
+ <path d="M0 6C0 2.68629 2.68629 0 6 0H10V10H0V6Z"/>
64
+ </mask>
65
+ <path d="M-2 6C-2 1.58172 1.58172 -2 6 -2H10V2H6C3.79086 2 2 3.79086 2 6H-2ZM10 10H0H10ZM-2 10V6C-2 1.58172 1.58172 -2 6 -2V2C3.79086 2 2 3.79086 2 6V10H-2ZM10 0V10V0Z" fill="#4945FF" mask="url(#path-3-inside-1_649_76)"/>
66
+ <path d="M14.67 17.71L12.6275 15.6675C12.4533 15.4933 12.2317 15.4062 11.9625 15.4062C11.6933 15.4062 11.4717 15.4933 11.2975 15.6675C11.1233 15.8417 11.0362 16.0633 11.0362 16.3325C11.0362 16.6017 11.1233 16.8233 11.2975 16.9975L14.005 19.705C14.195 19.895 14.4167 19.99 14.67 19.99C14.9233 19.99 15.145 19.895 15.335 19.705L20.7025 14.3375C20.8767 14.1633 20.9637 13.9417 20.9637 13.6725C20.9637 13.4033 20.8767 13.1817 20.7025 13.0075C20.5283 12.8333 20.3067 12.7462 20.0375 12.7462C19.7683 12.7462 19.5467 12.8333 19.3725 13.0075L14.67 17.71ZM16 25.5C14.6858 25.5 13.4508 25.2505 12.295 24.7514C11.1392 24.2523 10.1337 23.5756 9.27875 22.7212C8.42375 21.8669 7.74703 20.8615 7.2486 19.705C6.75017 18.5485 6.50063 17.3135 6.5 16C6.49937 14.6865 6.7489 13.4515 7.2486 12.295C7.7483 11.1385 8.42502 10.1331 9.27875 9.27875C10.1325 8.42438 11.1379 7.74767 12.295 7.2486C13.4521 6.74953 14.6871 6.5 16 6.5C17.3129 6.5 18.5479 6.74953 19.705 7.2486C20.8621 7.74767 21.8675 8.42438 22.7212 9.27875C23.575 10.1331 24.252 11.1385 24.7523 12.295C25.2527 13.4515 25.5019 14.6865 25.5 16C25.4981 17.3135 25.2486 18.5485 24.7514 19.705C24.2542 20.8615 23.5775 21.8669 22.7212 22.7212C21.865 23.5756 20.8596 24.2526 19.705 24.7523C18.5504 25.252 17.3154 25.5013 16 25.5Z" fill="#4945FF"/>
71
67
  </svg>
72
68
  </Box>
73
69
  );
74
70
 
75
71
  // Advanced Radio Icon - Clean radio button with selection states
76
- const MultipleChoiceIcon1 = () => (
72
+ const AdvancedRadioIcon = () => (
77
73
  <Box
78
74
  style={{
79
75
  width: '28px',
@@ -87,29 +83,26 @@ const MultipleChoiceIcon1 = () => (
87
83
  }}
88
84
  >
89
85
  <svg
90
- xmlns="http://www.w3.org/2000/svg"
91
- viewBox="0 0 24 24"
92
86
  width="18"
93
87
  height="18"
88
+ viewBox="0 0 32 32"
94
89
  fill="none"
95
- stroke="#495057"
96
- strokeWidth="2"
97
- strokeLinecap="round"
98
- strokeLinejoin="round"
90
+ xmlns="http://www.w3.org/2000/svg"
99
91
  >
100
- <circle cx="12" cy="12" r="10"/>
101
- <circle cx="12" cy="12" r="3" fill="#007bff"/>
102
- <circle cx="12" cy="5" r="2" fill="#6c757d" opacity="0.3"/>
103
- <circle cx="12" cy="19" r="2" fill="#6c757d" opacity="0.3"/>
104
- <circle cx="5" cy="12" r="2" fill="#6c757d" opacity="0.3"/>
105
- <circle cx="19" cy="12" r="2" fill="#6c757d" opacity="0.3"/>
92
+ <rect width="32" height="32" rx="6" fill="#4945FF" fillOpacity="0.1"/>
93
+ <rect x="0.5" y="0.5" width="31" height="31" rx="5.5" stroke="#4945FF" strokeOpacity="0.15"/>
94
+ <path d="M16 6.5C10.775 6.5 6.5 10.775 6.5 16C6.5 21.225 10.775 25.5 16 25.5C21.225 25.5 25.5 21.225 25.5 16C25.5 10.775 21.225 6.5 16 6.5ZM23.6 16H19.8C19.8 14.575 19.04 13.34 17.9 12.77L19.8 9.445C22.08 10.775 23.6 13.15 23.6 16ZM16 14.1C17.045 14.1 17.9 14.955 17.9 16C17.9 17.045 17.045 17.9 16 17.9C14.955 17.9 14.1 17.045 14.1 16C14.1 14.955 14.955 14.1 16 14.1ZM12.2 9.445C12.77 10.395 13.435 11.63 14.1 12.77C12.96 13.435 12.2 14.67 12.2 16H8.4C8.4 13.15 9.92 10.775 12.2 9.445ZM12.2 22.555C12.77 21.605 13.435 20.37 14.1 19.23C14.67 19.515 15.335 19.8 16 19.8C16.665 19.8 17.33 19.61 17.9 19.23L19.8 22.555C18.66 23.22 17.425 23.6 16 23.6C14.575 23.6 13.34 23.22 12.2 22.555Z" fill="#4945FF"/>
95
+ <mask id="path-4-inside-1_649_89" fill="white">
96
+ <path d="M0 6C0 2.68629 2.68629 0 6 0H10V10H0V6Z"/>
97
+ </mask>
98
+ <path d="M-2 6C-2 1.58172 1.58172 -2 6 -2H10V2H6C3.79086 2 2 3.79086 2 6H-2ZM10 10H0H10ZM-2 10V6C-2 1.58172 1.58172 -2 6 -2V2C3.79086 2 2 3.79086 2 6V10H-2ZM10 0V10V0Z" fill="#4945FF" mask="url(#path-4-inside-1_649_89)"/>
106
99
  </svg>
107
100
  </Box>
108
101
  );
109
102
 
110
103
  export {
111
104
  PluginIcon,
112
- CheckIcon,
113
- TextFieldIcon,
114
- MultipleChoiceIcon1
105
+ AdvancedCheckboxIcon,
106
+ AdvancedInputIcon,
107
+ AdvancedRadioIcon
115
108
  };
@@ -1,13 +1,13 @@
1
1
  import { PLUGIN_ID } from './pluginId';
2
2
  import { Initializer } from './components/Initializer';
3
- import { CheckIcon, TextFieldIcon, MultipleChoiceIcon1 } from './components/PluginIcon';
3
+ import { AdvancedCheckboxIcon, AdvancedInputIcon, AdvancedRadioIcon } from './components/PluginIcon';
4
4
 
5
5
  // Dynamic field configuration with comprehensive options
6
6
  const customFields = [
7
7
  {
8
8
  name: "input",
9
9
  type: "string",
10
- icon: TextFieldIcon,
10
+ icon: AdvancedInputIcon,
11
11
  pluginId: PLUGIN_ID,
12
12
  component: () => import("./components/AdvancedInput"),
13
13
  intlLabel: {
@@ -147,6 +147,22 @@ const customFields = [
147
147
  defaultMessage: 'Enter custom error message',
148
148
  },
149
149
  },
150
+ {
151
+ name: 'options.fieldNote',
152
+ type: 'text',
153
+ intlLabel: {
154
+ id: `${PLUGIN_ID}.input.options.fieldNote.label`,
155
+ defaultMessage: 'Field Note',
156
+ },
157
+ description: {
158
+ id: `${PLUGIN_ID}.input.options.fieldNote.description`,
159
+ defaultMessage: 'Add a helpful note that will appear below the field',
160
+ },
161
+ placeholder: {
162
+ id: `${PLUGIN_ID}.input.options.fieldNote.placeholder`,
163
+ defaultMessage: 'Enter a note for this field',
164
+ },
165
+ },
150
166
  {
151
167
  name: 'private',
152
168
  type: 'checkbox',
@@ -167,7 +183,7 @@ const customFields = [
167
183
  {
168
184
  name: "checkbox",
169
185
  type: "json",
170
- icon: CheckIcon,
186
+ icon: AdvancedCheckboxIcon,
171
187
  pluginId: PLUGIN_ID,
172
188
  component: () => import("./components/AdvancedCheckbox"),
173
189
  intlLabel: {
@@ -404,6 +420,22 @@ const customFields = [
404
420
  defaultMessage: 'Enter custom error message',
405
421
  },
406
422
  },
423
+ {
424
+ name: 'options.fieldNote',
425
+ type: 'text',
426
+ intlLabel: {
427
+ id: `${PLUGIN_ID}.checkbox.options.fieldNote.label`,
428
+ defaultMessage: 'Field Note',
429
+ },
430
+ description: {
431
+ id: `${PLUGIN_ID}.checkbox.options.fieldNote.description`,
432
+ defaultMessage: 'Add a helpful note that will appear below the field',
433
+ },
434
+ placeholder: {
435
+ id: `${PLUGIN_ID}.checkbox.options.fieldNote.placeholder`,
436
+ defaultMessage: 'Enter a note for this field',
437
+ },
438
+ },
407
439
  {
408
440
  name: 'private',
409
441
  type: 'checkbox',
@@ -424,7 +456,7 @@ const customFields = [
424
456
  {
425
457
  name: "radio",
426
458
  type: "json",
427
- icon: MultipleChoiceIcon1,
459
+ icon: AdvancedRadioIcon,
428
460
  pluginId: PLUGIN_ID,
429
461
  component: () => import("./components/AdvancedRadio"),
430
462
  intlLabel: {
@@ -636,6 +668,22 @@ const customFields = [
636
668
  defaultMessage: 'Enter custom error message',
637
669
  },
638
670
  },
671
+ {
672
+ name: 'options.fieldNote',
673
+ type: 'text',
674
+ intlLabel: {
675
+ id: `${PLUGIN_ID}.radio.options.fieldNote.label`,
676
+ defaultMessage: 'Field Note',
677
+ },
678
+ description: {
679
+ id: `${PLUGIN_ID}.radio.options.fieldNote.description`,
680
+ defaultMessage: 'Add a helpful note that will appear below the field',
681
+ },
682
+ placeholder: {
683
+ id: `${PLUGIN_ID}.radio.options.fieldNote.placeholder`,
684
+ defaultMessage: 'Enter a note for this field',
685
+ },
686
+ },
639
687
  ],
640
688
  },
641
689
  ],
package/index.js CHANGED
@@ -28,7 +28,7 @@ const customFields = [
28
28
  return options.customErrorMessage || 'Value does not match required format';
29
29
  }
30
30
  } catch (e) {
31
- console.warn('Invalid regex pattern:', options.regex);
31
+ // Invalid regex pattern - silently ignore
32
32
  }
33
33
  }
34
34
 
@@ -63,15 +63,6 @@ const customFields = [
63
63
  name: 'checkbox',
64
64
  type: 'json',
65
65
  validate: (value, { required, options = {} }) => {
66
- console.log('[advanced-fields] Checkbox validation:', {
67
- value,
68
- required,
69
- options,
70
- valueType: typeof value,
71
- isArray: Array.isArray(value),
72
- valueLength: Array.isArray(value) ? value.length : 'N/A',
73
- checkboxType: options.checkboxType
74
- });
75
66
 
76
67
  // Basic required validation
77
68
  if (required) {
@@ -80,14 +71,12 @@ const customFields = [
80
71
  (typeof value === 'string' && value.trim() === '') ||
81
72
  value === null ||
82
73
  value === undefined) {
83
- console.log('[advanced-fields] Checkbox validation failed: required field is empty');
84
74
  return options.customErrorMessage || 'This field is required';
85
75
  }
86
76
  }
87
77
 
88
78
  // If no value and not required, no additional validation needed
89
79
  if (!required && (!value || (Array.isArray(value) && value.length === 0))) {
90
- console.log('[advanced-fields] Checkbox validation passed (no value, not required)');
91
80
  return null;
92
81
  }
93
82
 
@@ -101,7 +90,6 @@ const customFields = [
101
90
  }
102
91
  }
103
92
 
104
- console.log('[advanced-fields] Checkbox validation passed');
105
93
  return null;
106
94
  }
107
95
  },
@@ -137,18 +125,14 @@ const customFields = [
137
125
 
138
126
  module.exports = {
139
127
  register({ strapi }) {
140
- console.log(`[${PLUGIN_ID}] Registering custom fields...`);
141
-
142
128
  // Ensure custom fields registry is available
143
129
  if (!strapi.customFields) {
144
- console.error(`[${PLUGIN_ID}] Custom fields registry not available`);
145
130
  return;
146
131
  }
147
132
 
148
133
  // Register custom fields with proper error handling
149
134
  customFields.forEach((field) => {
150
135
  try {
151
- console.log(`[${PLUGIN_ID}] Registering field: ${field.name} (type: ${field.type})`);
152
136
 
153
137
  const fieldConfig = {
154
138
  name: field.name,
@@ -159,44 +143,16 @@ module.exports = {
159
143
  // Add validation function if it exists
160
144
  if (field.validate) {
161
145
  fieldConfig.validate = field.validate;
162
- console.log(`[${PLUGIN_ID}] Added validation function for field: ${field.name}`);
163
146
  }
164
147
 
165
148
  strapi.customFields.register(fieldConfig);
166
- console.log(`[${PLUGIN_ID}] Successfully registered field: ${field.name}`);
167
149
  } catch (error) {
168
- console.error(`[${PLUGIN_ID}] Failed to register field ${field.name}:`, error.message);
169
- console.error(`[${PLUGIN_ID}] Error details:`, error);
150
+ // Field registration failed - silently continue
170
151
  }
171
152
  });
172
-
173
- console.log(`[${PLUGIN_ID}] All custom fields registration completed`);
174
153
  },
175
154
 
176
155
  bootstrap({ strapi }) {
177
- console.log(`[${PLUGIN_ID}] Bootstrap starting...`);
178
-
179
- // Wait a bit for registration to complete
180
- setTimeout(() => {
181
- // Verify all fields are registered only if customFields.get is available
182
- if (strapi.customFields && typeof strapi.customFields.get === 'function') {
183
- customFields.forEach((field) => {
184
- try {
185
- const registeredField = strapi.customFields.get(`${PLUGIN_ID}.${field.name}`);
186
- if (registeredField) {
187
- console.log(`[${PLUGIN_ID}] ✅ Field verified: ${field.name}`);
188
- } else {
189
- console.error(`[${PLUGIN_ID}] ❌ Field not found in registry: ${field.name}`);
190
- }
191
- } catch (error) {
192
- console.error(`[${PLUGIN_ID}] Error verifying field ${field.name}:`, error.message);
193
- }
194
- });
195
- } else {
196
- console.log(`[${PLUGIN_ID}] Skipping field verification (customFields.get not available)`);
197
- }
198
- }, 100);
199
-
200
- console.log(`[${PLUGIN_ID}] Bootstrap completed`);
156
+ // Bootstrap completed
201
157
  },
202
158
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webbycrown/advanced-fields",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "keywords": [
5
5
  "strapi",
6
6
  "plugin",
@@ -25,7 +25,6 @@
25
25
  "./strapi-server": "./strapi-server.js"
26
26
  },
27
27
  "files": [
28
- "dist",
29
28
  "admin",
30
29
  "strapi-server.js",
31
30
  "strapi-server.mjs",
@@ -68,7 +67,7 @@
68
67
  "displayName": "Advanced Fields",
69
68
  "description": "Professional custom fields for Strapi: Advanced Input with validation, Advanced Checkbox (single/multiple), and Advanced Radio (single/multiple) with dynamic options and comprehensive configuration"
70
69
  },
71
- "description": "🚀 Professional custom fields for Strapi CMS. Includes Advanced Input with comprehensive validation, Advanced Checkbox supporting both single and multiple selections, and Advanced Radio with dynamic options. Perfect for building user-friendly content management interfaces.",
70
+ "description": "Professional custom fields for Strapi: Advanced Input with validation, Advanced Checkbox (single/multiple), and Advanced Radio (single/multiple) with dynamic options and comprehensive configuration",
72
71
  "license": "MIT",
73
72
  "author": {
74
73
  "name": "WebbyCrown",