glib-web 4.39.1 → 4.40.0

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.
@@ -1,26 +1,84 @@
1
1
  class Glib::JsonUi::ViewBuilder
2
+ # Field components for JSON UI forms.
3
+ #
4
+ # This module contains all field types that can be used in forms, providing a consistent
5
+ # interface between Ruby backend and Vue.js frontend components.
6
+ #
7
+ # All fields automatically integrate with form validation, I18n labels, and model binding.
2
8
  module Fields
3
9
 
10
+ # Base class for all field components.
11
+ #
12
+ # AbstractField provides common functionality shared by all form fields including:
13
+ # - Automatic label and placeholder resolution from I18n
14
+ # - Model property binding with `prop` parameter
15
+ # - Client-side validation with automatic error messages
16
+ # - Form integration and dirty checking
17
+ # - Change event handlers
18
+ #
19
+ # @abstract Subclass and override {#determine_value} to customize value extraction from models
20
+ # @see Panels::Form Form panel that contains field components
4
21
  class AbstractField < View
5
22
  include Rails.application.routes.url_helpers
6
23
 
24
+ # Makes field read-only (user can see but not edit the value).
7
25
  bool :readOnly
26
+
27
+ # Disables field entirely (grayed out, not submitted with form).
8
28
  bool :disabled
29
+
30
+ # Shows a clear button to reset the field value to empty.
9
31
  bool :clearable
32
+
33
+ # Action triggered when field value changes.
34
+ # @example
35
+ # onChange: ->(action) do
36
+ # action.http_get url: preview_path, silent: true
37
+ # end
10
38
  action :onChange
39
+
40
+ # Action triggered when field value changes, with page reload.
41
+ # Use this when the change requires server-side processing and page refresh.
11
42
  action :onChangeAndLoad
43
+
44
+ # Custom parameter name for form submission data.
45
+ # Overrides the default parameter name derived from the model and property.
12
46
  string :paramNameForFormData
47
+
48
+ # Custom parameter name for field identification.
49
+ # Used to identify this field in form validation and error messages.
13
50
  string :paramNameForFieldName
51
+
52
+ # Makes field corners rounded (visual styling).
14
53
  bool :rounded
15
- string :autocomplete # https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete
54
+
55
+ # HTML autocomplete attribute value.
56
+ # Controls browser autocomplete behavior.
57
+ # @see https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete MDN autocomplete reference
58
+ string :autocomplete
16
59
 
17
60
  def default_url_options
18
61
  { only_path: true }
19
62
  end
20
63
 
64
+ # Validates field input according to specified rules.
65
+ # @param validation [Hash] Hash of validation types and their options
66
+ # @example
67
+ # validation presence: { message: 'Required' }
68
+ # validation format: { with: /\A\d+\z/, message: 'Must be a number' }
69
+ # validation length: { minimum: 3, maximum: 20, message: { too_short: 'Too short', too_long: 'Too long' } }
70
+ # @note Supported validation types: presence, required, absence, acceptance, numericality, format, inclusion, exclusion, length
71
+ # @see /home/hgani/workspace/glib-web-npm/components/validation.js Frontend validation implementation
21
72
  def validation(validation)
22
73
  return if validation.blank?
23
74
 
75
+ # Validate that all keys are supported validation types
76
+ supported_validations = %i[presence required absence acceptance numericality format inclusion exclusion length]
77
+ invalid_keys = validation.keys.map(&:to_sym) - supported_validations
78
+ if invalid_keys.any?
79
+ raise ArgumentError, "Unsupported validation type(s): #{invalid_keys.join(', ')}. Supported types: #{supported_validations.join(', ')}"
80
+ end
81
+
24
82
  if validation[:format].present?
25
83
  context.cast_to_js_regex(validation[:format])
26
84
  end
@@ -125,36 +183,141 @@ class Glib::JsonUi::ViewBuilder
125
183
  end
126
184
  end
127
185
 
186
+ # Basic text input field for single-line text entry.
187
+ #
188
+ # The most common field type, supporting various customizations like
189
+ # icons, prefix/suffix text, character limits, and typing event handlers.
190
+ #
191
+ # @example Basic text field
192
+ # form.fields_text name: 'user[name]', width: 'matchParent', label: 'Name'
193
+ #
194
+ # @example Text field with model property binding
195
+ # form.fields_text \
196
+ # prop: :name,
197
+ # name: 'user[name]',
198
+ # width: 'matchParent',
199
+ # label: 'Name'
200
+ #
201
+ # @see app/views/json_ui/garage/forms/basic.json.jbuilder Garage example
128
202
  class Text < AbstractField
203
+ # Maximum number of characters allowed.
129
204
  int :maxLength
205
+
206
+ # Icon displayed on the left side of the input.
207
+ # @example leftIcon: { name: 'account', color: 'primary' }
130
208
  icon :leftIcon
209
+
210
+ # Icon displayed on the right side of the input.
131
211
  icon :rightIcon
212
+
213
+ # Static text displayed on the left side of the input.
214
+ # @example leftText: '$' for currency inputs
132
215
  string :leftText
216
+
217
+ # Static text displayed on the right side of the input.
218
+ # @example rightText: 'USD' for currency inputs
133
219
  string :rightText
220
+
221
+ # Action triggered when user starts typing.
134
222
  action :onTypeStart
223
+
224
+ # Action triggered when user stops typing (debounced).
225
+ # Useful for search-as-you-type functionality.
135
226
  action :onTypeEnd
227
+
228
+ # Shows a clear button to reset the field value.
136
229
  bool :clearable
137
230
  end
138
231
 
232
+ # Numeric input field with number-specific validation.
233
+ #
234
+ # Extends Text field with min/max constraints and decimal precision support.
235
+ # Automatically validates that input is a valid number.
236
+ #
237
+ # @example Numeric field with validation
238
+ # form.fields_number \
239
+ # prop: :age,
240
+ # name: 'user[age]',
241
+ # width: 'matchParent',
242
+ # label: 'Age',
243
+ # clearable: true
244
+ #
245
+ # @see app/views/json_ui/garage/forms/text_validation.json.jbuilder Garage example
139
246
  class Number < Text
247
+ # Minimum numeric value allowed.
140
248
  int :min
249
+
250
+ # Maximum numeric value allowed.
141
251
  int :max
252
+
253
+ # Number of decimal places to allow.
254
+ # @example precision: 2 for currency (e.g., 10.99)
142
255
  int :precision
143
256
  end
144
257
 
258
+ # Email input field with email format validation.
259
+ #
260
+ # Uses browser's built-in email validation and provides
261
+ # appropriate keyboard on mobile devices.
262
+ #
263
+ # @example Email field with clearable button
264
+ # form.fields_email \
265
+ # name: 'user[email]',
266
+ # width: 'matchParent',
267
+ # label: 'Email',
268
+ # clearable: true
269
+ #
270
+ # @see app/views/json_ui/garage/forms/text_validation.json.jbuilder Garage example
145
271
  class Email < Text
146
272
  end
147
273
 
274
+ # URL input field with URL format validation.
275
+ #
276
+ # Validates that input is a properly formatted URL and provides
277
+ # appropriate keyboard on mobile devices.
278
+ #
279
+ # @example URL field
280
+ # form.fields_url \
281
+ # name: 'user[url]',
282
+ # width: 'matchParent',
283
+ # label: 'URL',
284
+ # clearable: true
285
+ #
286
+ # @see app/views/json_ui/garage/forms/text_validation.json.jbuilder Garage example
148
287
  class Url < Text
149
288
  end
150
289
 
290
+ # Password input field with masked input.
291
+ #
292
+ # Masks the input text and provides a toggle button to show/hide the password.
293
+ # Never pre-fills password values for security.
294
+ #
295
+ # @example Password field with icon and hint
296
+ # form.fields_password \
297
+ # name: 'user[password]',
298
+ # width: 'matchParent',
299
+ # label: 'Password',
300
+ # hint: 'Should contain at least 6 characters',
301
+ # leftIcon: 'lock',
302
+ # clearable: true
303
+ #
304
+ # @see app/views/json_ui/garage/forms/text_validation.json.jbuilder Garage example
151
305
  class Password < Text
152
306
  end
153
307
 
308
+ # Hidden input field not visible to users.
309
+ #
310
+ # Submitted with the form but not displayed. Useful for passing
311
+ # data like IDs, tokens, or state that users shouldn't see or modify.
312
+ #
313
+ # @example Hidden field
314
+ # form.fields_hidden name: 'mode', value: 'dialog'
315
+ #
316
+ # @see app/views/json_ui/garage/forms/_basic_content.json.jbuilder Garage example
154
317
  class Hidden < Text
155
318
 
156
319
  def created
157
- # no need to auto translate this
320
+ # Hidden fields don't need labels or placeholders
158
321
  @label = ''
159
322
  @placeholder = ''
160
323
 
@@ -162,40 +325,159 @@ class Glib::JsonUi::ViewBuilder
162
325
  end
163
326
  end
164
327
 
328
+ # Timer/stopwatch field for time tracking.
329
+ #
330
+ # Can count up (stopwatch mode) or down (countdown timer mode).
331
+ # Supports min/max time constraints.
332
+ #
333
+ # @example Countdown timer (backward)
334
+ # form.fields_timer \
335
+ # width: 160,
336
+ # styleClasses: ['outlined'],
337
+ # label: 'Timer',
338
+ # name: 'user[timer]',
339
+ # value: 60,
340
+ # min: 30
341
+ #
342
+ # @example Stopwatch (forward)
343
+ # form.fields_timer \
344
+ # width: 160,
345
+ # styleClasses: ['outlined'],
346
+ # label: 'Stop Watch',
347
+ # name: 'user[stop_watch]',
348
+ # value: 10,
349
+ # max: 20,
350
+ # forward: true
351
+ #
352
+ # @see app/views/json_ui/garage/forms/timers.json.jbuilder Garage example
165
353
  class Timer < Text
166
- # hash :actionCable
354
+ # hash :actionCable # Future: ActionCable integration for real-time updates
355
+
356
+ # Minimum timer value (in seconds).
167
357
  int :min
358
+
359
+ # Maximum timer value (in seconds).
168
360
  int :max
361
+
362
+ # Direction of counting.
363
+ # - true: Count up (stopwatch mode)
364
+ # - false: Count down (timer mode)
169
365
  bool :forward
170
366
  end
171
367
 
172
- # Benefits of using `fields/submit` over `button`
173
- # - On the web, it translates to input[type=submit] which provides builtin functionality such as
174
- # submitting upon pressing enter on a field and remembering values for autofill.
175
- # - We can attach name-value param to it. See https://www.w3schools.com/tags/att_button_value.asp
176
- # - It has a default onClick so no need to specify `onClick: ->(action) { action.forms_submit }`
368
+ # Submit button field for form submission.
369
+ #
370
+ # Benefits of using `fields/submit` over regular `button`:
371
+ # - On the web, translates to input[type=submit] which provides built-in browser
372
+ # functionality like submitting on Enter key and remembering values for autofill
373
+ # - Can attach name-value params (unlike regular buttons)
374
+ # - Has default onClick behavior so no need to manually specify form submission
375
+ #
376
+ # @example Basic submit button
377
+ # form.fields_submit text: 'Submit'
378
+ #
379
+ # @see app/views/json_ui/garage/forms/basic.json.jbuilder Garage example
380
+ # @see https://www.w3schools.com/tags/att_button_value.asp HTML button value attribute
177
381
  class Submit < AbstractField
382
+ # Button text to display.
178
383
  string :text
384
+
385
+ # Button color theme.
386
+ # @example color: 'primary', 'secondary', 'error'
179
387
  color :color
388
+
389
+ # Icon to display in the button.
180
390
  icon :icon
181
- # This will not work if the form contains multiple fields with the same name,
182
- # even if only one field is showing at any one time"
391
+
392
+ # Disables button when form has validation errors.
393
+ # Note: This will not work correctly if the form contains multiple fields
394
+ # with the same name, even if only one field is visible at a time.
183
395
  bool :disableIfFormInvalid
184
396
  end
185
397
 
398
+ # Group of checkbox fields managed as a collection.
399
+ #
400
+ # Manages multiple checkboxes as a single form field, useful for
401
+ # multi-select scenarios where values are submitted as an array.
402
+ #
403
+ # @example Basic checkbox group
404
+ # form.fields_checkGroup \
405
+ # name: 'user[skills][]',
406
+ # uncheckValue: 1,
407
+ # childViews: ->(group) do
408
+ # group.fields_check checkValue: 2, label: 'Game Development (readOnly)', readOnly: true
409
+ # group.fields_check checkValue: 3, label: 'Web Development'
410
+ # group.fields_check checkValue: 4, label: 'Mobile Development'
411
+ # end
412
+ #
413
+ # @example Checkbox group with "none of above" option
414
+ # form.fields_checkGroup \
415
+ # valueForDisableAll: 'none_of_above',
416
+ # name: 'user[favorite_fruits][]',
417
+ # value: 'grape',
418
+ # uncheckValue: 1,
419
+ # childViews: ->(group) do
420
+ # group.fields_check label: 'Grape', checkValue: 'grape'
421
+ # group.fields_check label: 'Banana', checkValue: 'banana'
422
+ # group.fields_check label: 'Durian', checkValue: 'durian'
423
+ # group.fields_check label: 'I dont like fruits', checkValue: 'none_of_above'
424
+ # end
425
+ #
426
+ # @see app/views/json_ui/garage/forms/checkboxes.json.jbuilder Garage example
186
427
  class CheckGroup < AbstractField
428
+ # Child checkbox field components.
187
429
  views :childViews
430
+
431
+ # Value to use when a checkbox is unchecked.
432
+ # @example uncheckValue: '0'
188
433
  string :uncheckValue
434
+
435
+ # Special value that, when checked, disables all other checkboxes.
436
+ # Useful for "None" or "Disable All" options.
189
437
  string :valueForDisableAll
190
438
  end
191
439
 
440
+ # Individual checkbox field.
441
+ #
442
+ # Can be used standalone or within a CheckGroup. Supports custom icons,
443
+ # images, and indeterminate state for partial selections.
444
+ #
445
+ # @example Single checkbox with default value
446
+ # form.fields_check \
447
+ # name: 'user[age_range]',
448
+ # value: '16+',
449
+ # checkValue: '16+',
450
+ # uncheckValue: '0-16',
451
+ # label: 'I am over 16 (has default value)'
452
+ #
453
+ # @example Standalone checkboxes without group
454
+ # form.fields_check name: 'user[choice][]', label: 'Choice 1', checkValue: 'choice_1'
455
+ # form.fields_check name: 'user[choice][]', label: 'Choice 2', checkValue: 'choice_2'
456
+ #
457
+ # @see app/views/json_ui/garage/forms/checkboxes.json.jbuilder Garage example
458
+ # @see app/views/json_ui/garage/forms/pickers.json.jbuilder Garage example for single checkbox
192
459
  class Check < Text
460
+ # Value when checkbox is unchecked.
193
461
  any :uncheckValue
462
+
463
+ # Value when checkbox is checked.
194
464
  any :checkValue
465
+
466
+ # Icon to display when checked.
195
467
  string :onIcon
468
+
469
+ # Icon to display when unchecked.
196
470
  string :offIcon
471
+
472
+ # Label to display when checked (replaces default label).
197
473
  string :onLabel
474
+
475
+ # Image to display instead of standard checkbox.
476
+ # @example image: { url: '/checkmark.png', template: 'image', width: 24, height: 24 }
198
477
  hash :image, required: [:url, :template], optional: [:width, :height]
478
+
479
+ # Shows indeterminate state (partially checked).
480
+ # Useful for "select all" checkboxes when some but not all children are selected.
199
481
  bool :indeterminate
200
482
 
201
483
  def value(value)
@@ -203,18 +485,79 @@ class Glib::JsonUi::ViewBuilder
203
485
  end
204
486
  end
205
487
 
206
- # This doesn't use camel case because some terms have become single words (e.g. snackbar)
488
+ # Multi-line text input field.
489
+ #
490
+ # For longer text entries that need multiple lines, such as comments,
491
+ # descriptions, or notes.
492
+ #
493
+ # @example Textarea with character limit
494
+ # form.fields_textarea \
495
+ # prop: :words,
496
+ # name: 'user[words]',
497
+ # width: 'matchParent',
498
+ # label: 'Textarea with maxLength',
499
+ # maxLength: 1000,
500
+ # clearable: true
501
+ #
502
+ # @see app/views/json_ui/garage/forms/text_validation.json.jbuilder Garage example
207
503
  class Textarea < Text
208
504
  end
209
505
 
506
+ # Rich text editor field with WYSIWYG editing.
507
+ #
508
+ # Provides a full-featured text editor with formatting options, image uploads,
509
+ # and @mention support. Can output HTML or Markdown.
510
+ #
511
+ # @example Rich text editor with image upload and mentions
512
+ # avatar = 'https://example.com/avatar.jpg'
513
+ # mention_list = [
514
+ # { id: 'johndoe', value: 'johndoe', text: 'John Doe', avatar: avatar, group: 'Programmer' },
515
+ # { id: 'budi', value: 'budi', text: 'Budi', avatar: avatar, group: 'Programmer' }
516
+ # ]
517
+ # form.fields_richText \
518
+ # width: 'matchParent',
519
+ # produce: :markdown,
520
+ # label: 'Content',
521
+ # name: 'user[message]',
522
+ # value: initial_message,
523
+ # mentionList: mention_list,
524
+ # imageUploader: {
525
+ # name: 'user[images_attributes][]',
526
+ # accepts: { fileType: ['image', 'csv', 'xlsx', 'pptx', 'docx'], maxFileSize: 5000 },
527
+ # directUploadUrl: glib_direct_uploads_url,
528
+ # blobUrlGenerator: glib_blob_url_generators_url
529
+ # },
530
+ # debug: true
531
+ #
532
+ # @see app/views/json_ui/garage/forms/rich_text.json.jbuilder Garage example
210
533
  class RichText < Text
534
+ # Pre-loaded images already in the content.
211
535
  array :images
536
+
537
+ # Configuration for image upload functionality.
538
+ # @example
539
+ # imageUploader: {
540
+ # name: 'post[images][]',
541
+ # directUploadUrl: rails_direct_uploads_path,
542
+ # accepts: 'image/png,image/jpeg'
543
+ # }
212
544
  hash :imageUploader, required: [:name], optional: [:accepts, :directUploadUrl, :blobUrlGenerator]
213
- # `html` or `markdown`
214
- string :produce
215
- string :accept
545
+
546
+ # Output format for the editor content.
547
+ enum :produce, options: [:html, :markdown]
548
+
549
+ # Input format the editor should accept.
550
+ enum :accept, options: [:html, :markdown]
551
+
552
+ # Cache key for editor state persistence.
553
+ # Helps restore editor content if the page is reloaded.
216
554
  string :cacheKey
555
+
556
+ # List of users/entities that can be mentioned with @ symbol.
557
+ # @example mentionList: [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]
217
558
  array :mentionList
559
+
560
+ # Enables debug mode with additional logging.
218
561
  bool :debug
219
562
  end
220
563
 
@@ -411,12 +754,14 @@ class Glib::JsonUi::ViewBuilder
411
754
  key = "glib.multi_upload.responseMessages.#{status}"
412
755
  @responseMessages[status] = I18n.t(key) if I18n.exists?(key)
413
756
  end
414
- json.responseMessages (@responseMessages || {}).reverse_merge({
415
- '200' => 'Completed',
416
- '403' => 'Forbidden',
417
- '401' => 'Session expired',
418
- 'else' => 'Failed'
419
- })
757
+ json.responseMessages(
758
+ (@responseMessages || {}).reverse_merge(
759
+ '200' => 'Completed',
760
+ '403' => 'Forbidden',
761
+ '401' => 'Session expired',
762
+ 'else' => 'Failed'
763
+ )
764
+ )
420
765
 
421
766
  json.placeholder @placeholder if @placeholder
422
767
  json.hint @hint if @hint
@@ -463,12 +808,14 @@ class Glib::JsonUi::ViewBuilder
463
808
  @multi_progress['responseMessages'][status] = I18n.t(key) if I18n.exists?(key)
464
809
  end
465
810
 
466
- json.responseMessages (@multi_progress['responseMessages'] || {}).reverse_merge({
467
- '200' => 'Completed',
468
- '403' => 'Forbidden',
469
- '401' => 'Session expired',
470
- 'else' => 'Failed'
471
- })
811
+ json.responseMessages(
812
+ (@multi_progress['responseMessages'] || {}).reverse_merge(
813
+ '200' => 'Completed',
814
+ '403' => 'Forbidden',
815
+ '401' => 'Session expired',
816
+ 'else' => 'Failed'
817
+ )
818
+ )
472
819
 
473
820
  json.placeholder @placeholder if @placeholder
474
821
  json.hint @hint if @hint
@@ -504,7 +851,10 @@ class Glib::JsonUi::ViewBuilder
504
851
  class Date < AbstractField
505
852
  date :min
506
853
  date :max
507
- string :type
854
+ # Date picker type.
855
+ # - :month - Month picker (YYYY-MM format)
856
+ # - nil/omitted - Standard date picker (YYYY-MM-DD format)
857
+ enum :type, options: [:month]
508
858
  bool :clearable
509
859
  bool :buttonTemplate # TODO: Remove
510
860
  hash :template, required: [:type]
@@ -528,45 +878,215 @@ class Glib::JsonUi::ViewBuilder
528
878
  hash :template, required: [:type]
529
879
  end
530
880
 
881
+ # Location/address field with Google Places autocomplete integration.
882
+ #
883
+ # Integrates with Google Places API to provide address autocomplete
884
+ # and geocoding. Can optionally store latitude, longitude, and zoom level
885
+ # in separate fields.
886
+ #
887
+ # @example Location field with coordinates and country restriction
888
+ # form.fields_location \
889
+ # name: 'user[address]',
890
+ # width: 'matchParent',
891
+ # label: 'Type an address',
892
+ # value: 'Sydney Harbour Bridge',
893
+ # autocompleteOptions: { componentRestrictions: { country: 'au' }, types: ['(cities)'] },
894
+ # latitudeField: { view: 'fields/text', name: 'user[latitude]', label: 'Lat', value: -33.8523063, readOnly: true },
895
+ # longitudeField: { view: 'fields/text', name: 'user[longitude]', label: 'Long', value: 151.21078710000006, readOnly: true },
896
+ # zoomField: { view: 'fields/text', name: 'user[zoom]', label: 'Zoom' }
897
+ #
898
+ # @see app/views/json_ui/garage/forms/pickers.json.jbuilder Garage example
899
+ # @see https://developers.google.com/maps/documentation/javascript/reference/places-widget#AutocompleteOptions Google Places API
531
900
  class Location < AbstractField
901
+ # Hidden field configuration for storing latitude value.
902
+ # @example latitudeField: { name: 'venue[latitude]' }
532
903
  hash :latitudeField
904
+
905
+ # Hidden field configuration for storing longitude value.
906
+ # @example longitudeField: { name: 'venue[longitude]' }
533
907
  hash :longitudeField
908
+
909
+ # Hidden field configuration for storing map zoom level.
534
910
  hash :zoomField
535
- # https://developers.google.com/maps/documentation/javascript/reference/places-widget#AutocompleteOptions
911
+
912
+ # Google Places Autocomplete options for customizing search behavior.
913
+ # @example
914
+ # autocompleteOptions: {
915
+ # componentRestrictions: { country: ['us', 'ca'] },
916
+ # types: ['geocode'],
917
+ # fields: ['formatted_address', 'geometry']
918
+ # }
919
+ # @see https://developers.google.com/maps/documentation/javascript/reference/places-widget#AutocompleteOptions
536
920
  hash :autocompleteOptions, optional: [:bounds, :componentRestrictions, :fields, :strictBounds, :types]
537
921
  end
538
922
 
923
+ # Stripe payment token field for secure card tokenization.
924
+ #
925
+ # Generates Stripe tokens from credit card information without your server
926
+ # ever handling raw card details. Compliant with PCI DSS requirements.
927
+ #
928
+ # @example Stripe credit card token field
929
+ # form.fields_stripeToken \
930
+ # name: 'user[stripe_token]',
931
+ # width: 'matchParent',
932
+ # publicKey: 'pk_test_TYooMQauvdEDq54NiTphI7jx'
933
+ #
934
+ # @see app/views/json_ui/garage/forms/payments.json.jbuilder Garage example
935
+ # @see https://stripe.com/docs/stripe-js Stripe.js documentation
539
936
  class StripeToken < AbstractField
937
+ # Your Stripe publishable key.
938
+ # Never use your secret key in client-side code.
540
939
  string :publicKey
541
940
  end
542
941
 
942
+ # Stripe external account field for Connect platform.
943
+ #
944
+ # Allows users to connect their bank accounts to receive payouts via Stripe Connect.
945
+ # Handles bank account details securely without storing sensitive information.
946
+ #
947
+ # @example Stripe bank account field
948
+ # form.fields_stripeExternalAccount \
949
+ # name: 'user[stripe_external_account]',
950
+ # width: 'matchParent',
951
+ # publicKey: 'pk_test_TYooMQauvdEDq54NiTphI7jx',
952
+ # accountHolderName: 'John Doe',
953
+ # accountHolderType: 'individual',
954
+ # country: 'AU',
955
+ # currency: 'AUD'
956
+ #
957
+ # @see app/views/json_ui/garage/forms/payments.json.jbuilder Garage example
958
+ # @see https://stripe.com/docs/connect/payouts Stripe Connect documentation
543
959
  class StripeExternalAccount < AbstractField
960
+ # Your Stripe publishable key.
544
961
  string :publicKey
962
+
963
+ # Name of the bank account holder.
545
964
  string :accountHolderName
546
- string :accountHolderType
965
+
966
+ # Type of account holder.
967
+ enum :accountHolderType, options: [:individual, :company]
968
+
969
+ # Two-letter country code (ISO 3166-1 alpha-2).
970
+ # @example country: 'US', 'CA', 'GB'
547
971
  string :country
972
+
973
+ # Three-letter currency code (ISO 4217).
974
+ # @example currency: 'usd', 'eur', 'gbp'
548
975
  string :currency
549
976
  end
550
977
 
978
+ # International phone number input field.
979
+ #
980
+ # Provides phone number input with country code selector and automatic
981
+ # formatting. Includes validation for phone number formats.
982
+ #
983
+ # @example Basic phone field with auto-detect
984
+ # form.fields_phone \
985
+ # name: 'user[phone1]',
986
+ # width: 'matchParent',
987
+ # label: 'Phone field',
988
+ # clearable: true
989
+ #
990
+ # @example Phone field with default country (no auto-detect)
991
+ # form.fields_phone \
992
+ # name: 'user[phone2]',
993
+ # width: 'matchParent',
994
+ # label: 'Phone field with Australia as the default country',
995
+ # disableAutoDetect: true,
996
+ # defaultCountry: 'AU'
997
+ #
998
+ # @see app/views/json_ui/garage/forms/text_validation.json.jbuilder Garage example
551
999
  class Phone < AbstractField
1000
+ # Default country code to preselect.
1001
+ # @example defaultCountry: 'US', 'GB', 'AU'
552
1002
  string :defaultCountry
1003
+
1004
+ # Disables automatic country detection based on user's location.
553
1005
  bool :disableAutoDetect
1006
+
1007
+ # Shows a clear button to reset the field value.
554
1008
  bool :clearable
555
1009
  end
556
1010
 
1011
+ # Credit card input field with secure tokenization.
1012
+ #
1013
+ # Integrates with payment processors to securely collect credit card details.
1014
+ # Handles card number, expiry, and CVV without exposing sensitive data to your server.
1015
+ #
1016
+ # @example Credit card field
1017
+ # form.fields_credit_card \
1018
+ # prop: :payment_token,
1019
+ # publicKey: ENV['PAYMENT_PROCESSOR_PUBLIC_KEY']
557
1020
  class CreditCard < AbstractField
1021
+ # Payment processor's public/publishable key.
1022
+ # Used for client-side tokenization.
558
1023
  string :publicKey
559
1024
  end
560
1025
 
1026
+ # One-Time Password (OTP) input field.
1027
+ #
1028
+ # Provides a specialized input for entering verification codes with
1029
+ # separate boxes for each digit. Commonly used for 2FA or phone verification.
1030
+ #
1031
+ # @example 7-character OTP field (text type)
1032
+ # form.fields_otp \
1033
+ # name: 'user[otp_summary1]',
1034
+ # length: 7,
1035
+ # type: 'text'
1036
+ #
1037
+ # @example 3-digit OTP field (number type)
1038
+ # form.fields_otp \
1039
+ # name: 'user[otp_summary2]',
1040
+ # length: 3,
1041
+ # type: 'number'
1042
+ #
1043
+ # @see app/views/json_ui/garage/forms/otp_field.json.jbuilder Garage example
561
1044
  class Otp < AbstractField
562
- int :length
563
- string :type
1045
+ # Number of OTP digits/characters.
1046
+ # @example length: 4, 6, or 8
1047
+ int :length
1048
+
1049
+ # Input type for each character box.
1050
+ enum :type, options: [:text, :number]
564
1051
  end
565
1052
 
1053
+ # Star rating input field.
1054
+ #
1055
+ # Provides an interactive star rating interface for collecting user ratings.
1056
+ # Supports full and half-star increments with customizable appearance.
1057
+ #
1058
+ # @example Rating with full increments
1059
+ # form.fields_rating \
1060
+ # name: 'user[rating_summary1]',
1061
+ # value: 1,
1062
+ # color: 'primary'
1063
+ #
1064
+ # @example Rating with half-star increments
1065
+ # form.fields_rating \
1066
+ # name: 'user[rating_summary2]',
1067
+ # value: 1.5,
1068
+ # halfIncrements: true,
1069
+ # color: 'secondary'
1070
+ #
1071
+ # @example Rating with custom size
1072
+ # form.fields_rating \
1073
+ # name: 'user[rating_summary3]',
1074
+ # value: 2,
1075
+ # color: 'ternary',
1076
+ # size: 35
1077
+ #
1078
+ # @see app/views/json_ui/garage/forms/ratings.json.jbuilder Garage example
566
1079
  class Rating < AbstractField
567
- bool :halfIncrements
568
- string :color
569
- int :size
1080
+ # Allows selecting half-star values (e.g., 3.5 stars).
1081
+ bool :halfIncrements
1082
+
1083
+ # Color theme for the stars.
1084
+ # @example color: 'amber', 'yellow', 'orange'
1085
+ string :color
1086
+
1087
+ # Size of each star in pixels.
1088
+ # @example size: 24, 32, 48
1089
+ int :size
570
1090
  end
571
1091
  end
572
1092
  end