glib-web 4.39.2 → 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,18 +1,61 @@
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 }
@@ -31,7 +74,7 @@ class Glib::JsonUi::ViewBuilder
31
74
 
32
75
  # Validate that all keys are supported validation types
33
76
  supported_validations = %i[presence required absence acceptance numericality format inclusion exclusion length]
34
- invalid_keys = validation.keys - supported_validations
77
+ invalid_keys = validation.keys.map(&:to_sym) - supported_validations
35
78
  if invalid_keys.any?
36
79
  raise ArgumentError, "Unsupported validation type(s): #{invalid_keys.join(', ')}. Supported types: #{supported_validations.join(', ')}"
37
80
  end
@@ -140,36 +183,141 @@ class Glib::JsonUi::ViewBuilder
140
183
  end
141
184
  end
142
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
143
202
  class Text < AbstractField
203
+ # Maximum number of characters allowed.
144
204
  int :maxLength
205
+
206
+ # Icon displayed on the left side of the input.
207
+ # @example leftIcon: { name: 'account', color: 'primary' }
145
208
  icon :leftIcon
209
+
210
+ # Icon displayed on the right side of the input.
146
211
  icon :rightIcon
212
+
213
+ # Static text displayed on the left side of the input.
214
+ # @example leftText: '$' for currency inputs
147
215
  string :leftText
216
+
217
+ # Static text displayed on the right side of the input.
218
+ # @example rightText: 'USD' for currency inputs
148
219
  string :rightText
220
+
221
+ # Action triggered when user starts typing.
149
222
  action :onTypeStart
223
+
224
+ # Action triggered when user stops typing (debounced).
225
+ # Useful for search-as-you-type functionality.
150
226
  action :onTypeEnd
227
+
228
+ # Shows a clear button to reset the field value.
151
229
  bool :clearable
152
230
  end
153
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
154
246
  class Number < Text
247
+ # Minimum numeric value allowed.
155
248
  int :min
249
+
250
+ # Maximum numeric value allowed.
156
251
  int :max
252
+
253
+ # Number of decimal places to allow.
254
+ # @example precision: 2 for currency (e.g., 10.99)
157
255
  int :precision
158
256
  end
159
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
160
271
  class Email < Text
161
272
  end
162
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
163
287
  class Url < Text
164
288
  end
165
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
166
305
  class Password < Text
167
306
  end
168
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
169
317
  class Hidden < Text
170
318
 
171
319
  def created
172
- # no need to auto translate this
320
+ # Hidden fields don't need labels or placeholders
173
321
  @label = ''
174
322
  @placeholder = ''
175
323
 
@@ -177,40 +325,159 @@ class Glib::JsonUi::ViewBuilder
177
325
  end
178
326
  end
179
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
180
353
  class Timer < Text
181
- # hash :actionCable
354
+ # hash :actionCable # Future: ActionCable integration for real-time updates
355
+
356
+ # Minimum timer value (in seconds).
182
357
  int :min
358
+
359
+ # Maximum timer value (in seconds).
183
360
  int :max
361
+
362
+ # Direction of counting.
363
+ # - true: Count up (stopwatch mode)
364
+ # - false: Count down (timer mode)
184
365
  bool :forward
185
366
  end
186
367
 
187
- # Benefits of using `fields/submit` over `button`
188
- # - On the web, it translates to input[type=submit] which provides builtin functionality such as
189
- # submitting upon pressing enter on a field and remembering values for autofill.
190
- # - We can attach name-value param to it. See https://www.w3schools.com/tags/att_button_value.asp
191
- # - 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
192
381
  class Submit < AbstractField
382
+ # Button text to display.
193
383
  string :text
384
+
385
+ # Button color theme.
386
+ # @example color: 'primary', 'secondary', 'error'
194
387
  color :color
388
+
389
+ # Icon to display in the button.
195
390
  icon :icon
196
- # This will not work if the form contains multiple fields with the same name,
197
- # 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.
198
395
  bool :disableIfFormInvalid
199
396
  end
200
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
201
427
  class CheckGroup < AbstractField
428
+ # Child checkbox field components.
202
429
  views :childViews
430
+
431
+ # Value to use when a checkbox is unchecked.
432
+ # @example uncheckValue: '0'
203
433
  string :uncheckValue
434
+
435
+ # Special value that, when checked, disables all other checkboxes.
436
+ # Useful for "None" or "Disable All" options.
204
437
  string :valueForDisableAll
205
438
  end
206
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
207
459
  class Check < Text
460
+ # Value when checkbox is unchecked.
208
461
  any :uncheckValue
462
+
463
+ # Value when checkbox is checked.
209
464
  any :checkValue
465
+
466
+ # Icon to display when checked.
210
467
  string :onIcon
468
+
469
+ # Icon to display when unchecked.
211
470
  string :offIcon
471
+
472
+ # Label to display when checked (replaces default label).
212
473
  string :onLabel
474
+
475
+ # Image to display instead of standard checkbox.
476
+ # @example image: { url: '/checkmark.png', template: 'image', width: 24, height: 24 }
213
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.
214
481
  bool :indeterminate
215
482
 
216
483
  def value(value)
@@ -218,18 +485,79 @@ class Glib::JsonUi::ViewBuilder
218
485
  end
219
486
  end
220
487
 
221
- # 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
222
503
  class Textarea < Text
223
504
  end
224
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
225
533
  class RichText < Text
534
+ # Pre-loaded images already in the content.
226
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
+ # }
227
544
  hash :imageUploader, required: [:name], optional: [:accepts, :directUploadUrl, :blobUrlGenerator]
228
- # `html` or `markdown`
229
- string :produce
230
- 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.
231
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' }]
232
558
  array :mentionList
559
+
560
+ # Enables debug mode with additional logging.
233
561
  bool :debug
234
562
  end
235
563
 
@@ -426,12 +754,14 @@ class Glib::JsonUi::ViewBuilder
426
754
  key = "glib.multi_upload.responseMessages.#{status}"
427
755
  @responseMessages[status] = I18n.t(key) if I18n.exists?(key)
428
756
  end
429
- json.responseMessages (@responseMessages || {}).reverse_merge({
430
- '200' => 'Completed',
431
- '403' => 'Forbidden',
432
- '401' => 'Session expired',
433
- 'else' => 'Failed'
434
- })
757
+ json.responseMessages(
758
+ (@responseMessages || {}).reverse_merge(
759
+ '200' => 'Completed',
760
+ '403' => 'Forbidden',
761
+ '401' => 'Session expired',
762
+ 'else' => 'Failed'
763
+ )
764
+ )
435
765
 
436
766
  json.placeholder @placeholder if @placeholder
437
767
  json.hint @hint if @hint
@@ -478,12 +808,14 @@ class Glib::JsonUi::ViewBuilder
478
808
  @multi_progress['responseMessages'][status] = I18n.t(key) if I18n.exists?(key)
479
809
  end
480
810
 
481
- json.responseMessages (@multi_progress['responseMessages'] || {}).reverse_merge({
482
- '200' => 'Completed',
483
- '403' => 'Forbidden',
484
- '401' => 'Session expired',
485
- 'else' => 'Failed'
486
- })
811
+ json.responseMessages(
812
+ (@multi_progress['responseMessages'] || {}).reverse_merge(
813
+ '200' => 'Completed',
814
+ '403' => 'Forbidden',
815
+ '401' => 'Session expired',
816
+ 'else' => 'Failed'
817
+ )
818
+ )
487
819
 
488
820
  json.placeholder @placeholder if @placeholder
489
821
  json.hint @hint if @hint
@@ -519,7 +851,10 @@ class Glib::JsonUi::ViewBuilder
519
851
  class Date < AbstractField
520
852
  date :min
521
853
  date :max
522
- 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]
523
858
  bool :clearable
524
859
  bool :buttonTemplate # TODO: Remove
525
860
  hash :template, required: [:type]
@@ -543,45 +878,215 @@ class Glib::JsonUi::ViewBuilder
543
878
  hash :template, required: [:type]
544
879
  end
545
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
546
900
  class Location < AbstractField
901
+ # Hidden field configuration for storing latitude value.
902
+ # @example latitudeField: { name: 'venue[latitude]' }
547
903
  hash :latitudeField
904
+
905
+ # Hidden field configuration for storing longitude value.
906
+ # @example longitudeField: { name: 'venue[longitude]' }
548
907
  hash :longitudeField
908
+
909
+ # Hidden field configuration for storing map zoom level.
549
910
  hash :zoomField
550
- # 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
551
920
  hash :autocompleteOptions, optional: [:bounds, :componentRestrictions, :fields, :strictBounds, :types]
552
921
  end
553
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
554
936
  class StripeToken < AbstractField
937
+ # Your Stripe publishable key.
938
+ # Never use your secret key in client-side code.
555
939
  string :publicKey
556
940
  end
557
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
558
959
  class StripeExternalAccount < AbstractField
960
+ # Your Stripe publishable key.
559
961
  string :publicKey
962
+
963
+ # Name of the bank account holder.
560
964
  string :accountHolderName
561
- 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'
562
971
  string :country
972
+
973
+ # Three-letter currency code (ISO 4217).
974
+ # @example currency: 'usd', 'eur', 'gbp'
563
975
  string :currency
564
976
  end
565
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
566
999
  class Phone < AbstractField
1000
+ # Default country code to preselect.
1001
+ # @example defaultCountry: 'US', 'GB', 'AU'
567
1002
  string :defaultCountry
1003
+
1004
+ # Disables automatic country detection based on user's location.
568
1005
  bool :disableAutoDetect
1006
+
1007
+ # Shows a clear button to reset the field value.
569
1008
  bool :clearable
570
1009
  end
571
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']
572
1020
  class CreditCard < AbstractField
1021
+ # Payment processor's public/publishable key.
1022
+ # Used for client-side tokenization.
573
1023
  string :publicKey
574
1024
  end
575
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
576
1044
  class Otp < AbstractField
577
- int :length
578
- 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]
579
1051
  end
580
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
581
1079
  class Rating < AbstractField
582
- bool :halfIncrements
583
- string :color
584
- 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
585
1090
  end
586
1091
  end
587
1092
  end