playbook_ui 16.7.0 → 16.8.0.pre.alpha.PLAY2935formbuilderrequiredindicatorbug16780
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.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +2 -0
- data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +2 -0
- data/app/pb_kits/playbook/pb_advanced_table/Components/VirtualizedTableView.tsx +5 -1
- data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +24 -0
- data/app/pb_kits/playbook/pb_advanced_table/Utilities/ColumnLayoutHelper.ts +138 -0
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +144 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling.jsx +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling.md +6 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_width.jsx +57 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_width.md +66 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_enable_toggle_expansion_rails.html.erb +62 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_enable_toggle_expansion_rails.md +7 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_header.jsx +12 -4
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_header.md +4 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_header_rails.html.erb +16 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_header_rails.md +4 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_scroll_limitation.jsx +68 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_scroll_limitation.md +7 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header.html.erb +16 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header.jsx +12 -5
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header_rails.md +4 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header_react.md +5 -3
- data/app/pb_kits/playbook/pb_advanced_table/docs/_playground.json +180 -5839
- data/app/pb_kits/playbook/pb_advanced_table/docs/_playground.overrides.json +5 -30
- data/app/pb_kits/playbook/pb_advanced_table/docs/advanced_table_column_definitions_styling.json +4 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +3 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +2 -0
- data/app/pb_kits/playbook/pb_card/_card.tsx +1 -1
- data/app/pb_kits/playbook/pb_card/card.html.erb +1 -1
- data/app/pb_kits/playbook/pb_currency/_currency.tsx +9 -6
- data/app/pb_kits/playbook/pb_currency/currency.rb +5 -10
- data/app/pb_kits/playbook/pb_currency/currency.test.js +44 -1
- data/app/pb_kits/playbook/pb_date/docs/_playground.json +13 -17
- data/app/pb_kits/playbook/pb_date/docs/_playground.overrides.json +13 -16
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +3 -2
- data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +38 -23
- data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +2 -1
- data/app/pb_kits/playbook/pb_date_picker/date_picker.test.js +31 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_dialog_submission.jsx +2 -2
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_inline.html.erb +0 -2
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_inline.jsx +0 -2
- data/app/pb_kits/playbook/pb_date_picker/docs/_playground.json +136 -42
- data/app/pb_kits/playbook/pb_date_picker/docs/_playground.overrides.json +113 -45
- data/app/pb_kits/playbook/pb_date_range_inline/docs/_playground.json +48 -6
- data/app/pb_kits/playbook/pb_date_range_inline/docs/_playground.overrides.json +57 -0
- data/app/pb_kits/playbook/pb_date_range_stacked/docs/_playground.json +28 -5
- data/app/pb_kits/playbook/pb_date_range_stacked/docs/_playground.overrides.json +38 -0
- data/app/pb_kits/playbook/pb_date_stacked/docs/_playground.json +1 -1
- data/app/pb_kits/playbook/pb_date_stacked/docs/_playground.overrides.json +1 -1
- data/app/pb_kits/playbook/pb_date_time/docs/_playground.json +16 -3
- data/app/pb_kits/playbook/pb_date_time/docs/_playground.overrides.json +16 -3
- data/app/pb_kits/playbook/pb_date_time_stacked/docs/_playground.json +11 -15
- data/app/pb_kits/playbook/pb_date_time_stacked/docs/_playground.overrides.json +11 -15
- data/app/pb_kits/playbook/pb_date_year_stacked/docs/_playground.json +4 -4
- data/app/pb_kits/playbook/pb_date_year_stacked/docs/_playground.overrides.json +4 -4
- data/app/pb_kits/playbook/pb_detail/docs/_playground.json +12 -18
- data/app/pb_kits/playbook/pb_detail/docs/_playground.overrides.json +13 -12
- data/app/pb_kits/playbook/pb_dialog/docs/_playground.json +108 -42
- data/app/pb_kits/playbook/pb_dialog/docs/_playground.overrides.json +88 -40
- data/app/pb_kits/playbook/pb_distribution_bar/docs/_playground.json +65 -7
- data/app/pb_kits/playbook/pb_distribution_bar/docs/_playground.overrides.json +45 -0
- data/app/pb_kits/playbook/pb_draggable/_draggable.scss +19 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards_rails.md +2 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards_react.md +1 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list_rails.md +2 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list_react.md +3 -1
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list_rails.md +3 -1
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list_react.md +3 -1
- data/app/pb_kits/playbook/pb_draggable/draggable.test.jsx +16 -0
- data/app/pb_kits/playbook/pb_draggable/draggable_container.html.erb +3 -1
- data/app/pb_kits/playbook/pb_draggable/draggable_item.html.erb +1 -0
- data/app/pb_kits/playbook/pb_draggable/index.js +149 -7
- data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableContainer.tsx +1 -0
- data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableItem.tsx +67 -1
- data/app/pb_kits/playbook/pb_draggable/touchDrag.test.js +38 -0
- data/app/pb_kits/playbook/pb_draggable/utilities/touchDrag.ts +173 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_playground.json +318 -21
- data/app/pb_kits/playbook/pb_dropdown/docs/_playground.overrides.json +192 -19
- data/app/pb_kits/playbook/pb_empty_state/docs/_playground.json +77 -12
- data/app/pb_kits/playbook/pb_empty_state/docs/_playground.overrides.json +79 -0
- data/app/pb_kits/playbook/pb_file_upload/docs/_playground.json +98 -13
- data/app/pb_kits/playbook/pb_file_upload/docs/_playground.overrides.json +99 -0
- data/app/pb_kits/playbook/pb_form/docs/_form_with_required_indicator.html.erb +20 -19
- data/app/pb_kits/playbook/pb_icon/_icon.scss +2 -1
- data/app/pb_kits/playbook/pb_icon/docs/example.yml +0 -2
- data/app/pb_kits/playbook/pb_icon/docs/index.js +0 -1
- data/app/pb_kits/playbook/pb_link/docs/_playground.json +81 -40
- data/app/pb_kits/playbook/pb_link/docs/_playground.overrides.json +88 -30
- data/app/pb_kits/playbook/pb_list/_list_item.tsx +4 -1
- data/app/pb_kits/playbook/pb_list/item.html.erb +1 -1
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_centered_data.html.erb +90 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_centered_data.jsx +100 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_centered_data.md +1 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_default.jsx +1 -1
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_playground.json +4 -2
- data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.tsx +1 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/_tiptap_styles.scss +262 -43
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_default.html.erb +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_default.md +12 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_simple.html.erb +9 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_simple.md +8 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/kit.schema.json +18 -9
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.html.erb +162 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.rb +71 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor_rails.js +202 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_sticky.html.erb +85 -83
- data/app/pb_kits/playbook/pb_table/docs/_table_sticky.jsx +88 -86
- data/app/pb_kits/playbook/pb_table/docs/_table_sticky.md +3 -1
- data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_external_filter_rails.md +1 -1
- data/app/pb_kits/playbook/pb_text_input/_text_input.scss +37 -0
- data/app/pb_kits/playbook/pb_title/docs/_playground.json +72 -23
- data/app/pb_kits/playbook/pb_title/docs/_playground.overrides.json +80 -16
- data/app/pb_kits/playbook/pb_tooltip/_tooltip.scss +133 -102
- data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +54 -41
- data/app/pb_kits/playbook/pb_tooltip/tooltip.test.jsx +60 -2
- data/dist/chunks/{_pb_line_graph-CIWJe3Gr.js → _pb_line_graph-BgsTI0CL.js} +1 -1
- data/dist/chunks/_typeahead-DA__Kgp5.js +5 -0
- data/dist/chunks/{globalProps-CqO4Tko1.js → globalProps-DOB47YGB.js} +1 -1
- data/dist/chunks/{lib-czQnE40X.js → lib-BzglXly2.js} +2 -2
- data/dist/chunks/vendor.js +4 -4
- data/dist/menu.yml +71 -132
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/forms/builder/form_field_builder.rb +2 -0
- data/lib/playbook/version.rb +2 -2
- metadata +31 -10
- data/app/pb_kits/playbook/pb_icon/docs/_icon_fa_kit.html.erb +0 -1
- data/app/pb_kits/playbook/pb_icon/docs/_icon_fa_kit.jsx +0 -21
- data/app/pb_kits/playbook/pb_icon/docs/_icon_fa_kit.md +0 -7
- data/dist/chunks/_typeahead-B_Ac4z84.js +0 -1
|
@@ -34,11 +34,6 @@
|
|
|
34
34
|
"columnDefinitionsFile": "advanced_table_column_definitions_standard.json",
|
|
35
35
|
"tableDataFile": "advanced_table_mock_data_no_subrows.json"
|
|
36
36
|
},
|
|
37
|
-
"pagination": {
|
|
38
|
-
"label": "Pagination Example",
|
|
39
|
-
"columnDefinitionsFile": "advanced_table_column_definitions_standard.json",
|
|
40
|
-
"tableDataFile": "advanced_table_pagination_mock_data.json"
|
|
41
|
-
},
|
|
42
37
|
"with_ids": {
|
|
43
38
|
"label": "Data with row IDs",
|
|
44
39
|
"columnDefinitionsFile": "advanced_table_column_definitions_standard.json",
|
|
@@ -80,15 +75,15 @@
|
|
|
80
75
|
"sortControl",
|
|
81
76
|
"fullScreenControl",
|
|
82
77
|
"expandedControl",
|
|
83
|
-
"allowFullScreen"
|
|
78
|
+
"allowFullScreen",
|
|
79
|
+
"pagination",
|
|
80
|
+
"paginationProps"
|
|
84
81
|
],
|
|
85
82
|
"requiredProps": {
|
|
86
83
|
"columnDefinitionsFile": "advanced_table_column_definitions_standard.json",
|
|
87
84
|
"tableDataFile": "advanced_table_mock_data.json"
|
|
88
85
|
},
|
|
89
86
|
"propSyncOnEnable": {
|
|
90
|
-
"pagination": { "dataPreset": "pagination" },
|
|
91
|
-
"paginationProps": { "dataPreset": "pagination" },
|
|
92
87
|
"inlineRowLoading": { "dataPreset": "inline_loading" },
|
|
93
88
|
"selectableRows": { "dataPreset": "with_ids" },
|
|
94
89
|
"onRowSelectionChange": { "dataPreset": "with_ids" },
|
|
@@ -144,10 +139,8 @@
|
|
|
144
139
|
]
|
|
145
140
|
},
|
|
146
141
|
{
|
|
147
|
-
"name": "
|
|
142
|
+
"name": "Loading",
|
|
148
143
|
"props": [
|
|
149
|
-
"pagination",
|
|
150
|
-
"paginationProps",
|
|
151
144
|
"loading",
|
|
152
145
|
"inlineRowLoading",
|
|
153
146
|
"initialLoadingRowsCount"
|
|
@@ -215,12 +208,6 @@
|
|
|
215
208
|
"enableSorting": true
|
|
216
209
|
}
|
|
217
210
|
},
|
|
218
|
-
{
|
|
219
|
-
"name": "With Pagination",
|
|
220
|
-
"props": {
|
|
221
|
-
"pagination": true
|
|
222
|
-
}
|
|
223
|
-
},
|
|
224
211
|
{
|
|
225
212
|
"name": "Selectable Rows",
|
|
226
213
|
"props": {
|
|
@@ -260,11 +247,6 @@
|
|
|
260
247
|
}
|
|
261
248
|
],
|
|
262
249
|
"conditionals": {
|
|
263
|
-
"paginationProps": {
|
|
264
|
-
"requires": {
|
|
265
|
-
"pagination": true
|
|
266
|
-
}
|
|
267
|
-
},
|
|
268
250
|
"initialLoadingRowsCount": {
|
|
269
251
|
"requires": {
|
|
270
252
|
"loading": true
|
|
@@ -350,13 +332,6 @@
|
|
|
350
332
|
"message": "Header sorting UI is only applied in \"Subcomponent Structure\" mode (explicit Header and Body). For sorting by column, pass columnDefinitions with enableSort: true to the columnDefinitions array. Click 'sorting by column' to see an example.",
|
|
351
333
|
"type": "info"
|
|
352
334
|
},
|
|
353
|
-
"pagination_info": {
|
|
354
|
-
"when": {
|
|
355
|
-
"pagination": true
|
|
356
|
-
},
|
|
357
|
-
"message": "Use paginationProps to customize page size and appearance.",
|
|
358
|
-
"type": "info"
|
|
359
|
-
},
|
|
360
335
|
"selectable_info": {
|
|
361
336
|
"when": {
|
|
362
337
|
"selectableRows": true
|
|
@@ -396,7 +371,7 @@
|
|
|
396
371
|
},
|
|
397
372
|
"column_styling_info": {
|
|
398
373
|
"presetName": "Column Styling",
|
|
399
|
-
"message": "This sample uses columnStyling on column definitions.
|
|
374
|
+
"message": "This sample uses columnStyling on column definitions. Year uses width for a fixed hierarchy column; other columns show background colors. See the Column Styling Width doc for minWidth and min/pref/max bands.",
|
|
400
375
|
"type": "info"
|
|
401
376
|
}
|
|
402
377
|
}
|
|
@@ -3,6 +3,7 @@ examples:
|
|
|
3
3
|
- advanced_table_beta: Default (Required Props)
|
|
4
4
|
- advanced_table_loading: Loading State
|
|
5
5
|
- advanced_table_beta_subrow_headers: SubRow Headers
|
|
6
|
+
- advanced_table_enable_toggle_expansion_rails: Enable Toggle Expansion
|
|
6
7
|
- advanced_table_collapsible_trail_rails: Collapsible Trail
|
|
7
8
|
- advanced_table_table_props: Table Props
|
|
8
9
|
- advanced_table_sticky_header_rails: Sticky Header
|
|
@@ -52,6 +53,7 @@ examples:
|
|
|
52
53
|
- advanced_table_table_props_sticky_header: Sticky Header for Responsive Table
|
|
53
54
|
- advanced_table_sticky_columns: Sticky Columns
|
|
54
55
|
- advanced_table_sticky_columns_and_header: Sticky Columns with Sticky Header
|
|
56
|
+
- advanced_table_sticky_scroll_limitation: Sticky Header and Column Scroll Limitation
|
|
55
57
|
- advanced_table_responsive: Responsive Tables
|
|
56
58
|
- advanced_table_custom_cell: Custom Components for Cells
|
|
57
59
|
- advanced_table_with_custom_header: Custom Header Cell
|
|
@@ -80,6 +82,7 @@ examples:
|
|
|
80
82
|
- advanced_table_row_styling: Row Styling
|
|
81
83
|
- advanced_table_padding_control_per_row: Padding Control using Row Styling
|
|
82
84
|
- advanced_table_column_styling: Column Styling
|
|
85
|
+
- advanced_table_column_styling_width: Column Styling Width
|
|
83
86
|
- advanced_table_column_styling_column_headers: Column Styling with Multiple Headers
|
|
84
87
|
- advanced_table_column_styling_background: Column Styling Background Color
|
|
85
88
|
- advanced_table_column_styling_background_custom: Column Styling Background Color (Custom)
|
|
@@ -27,6 +27,7 @@ export { default as AdvancedTableFullscreen } from './_advanced_table_fullscreen
|
|
|
27
27
|
export { default as AdvancedTableStickyColumns } from './_advanced_table_sticky_columns.jsx'
|
|
28
28
|
export { default as AdvancedTableStickyHeader } from './_advanced_table_sticky_header.jsx'
|
|
29
29
|
export { default as AdvancedTableStickyColumnsAndHeader } from './_advanced_table_sticky_columns_and_header.jsx'
|
|
30
|
+
export { default as AdvancedTableStickyScrollLimitation } from './_advanced_table_sticky_scroll_limitation.jsx'
|
|
30
31
|
export { default as AdvancedTableExpandByDepth } from './_advanced_table_expand_by_depth.jsx'
|
|
31
32
|
export { default as AdvancedTableColumnBorderColor} from './_advanced_table_column_border_color.jsx'
|
|
32
33
|
export { default as AdvancedTableColumnVisibility } from './_advanced_table_column_visibility.jsx'
|
|
@@ -37,6 +38,7 @@ export { default as AdvancedTablePinnedRows } from './_advanced_table_pinned_row
|
|
|
37
38
|
export { default as AdvancedTableScrollbarNone} from './_advanced_table_scrollbar_none.jsx'
|
|
38
39
|
export { default as AdvancedTableRowStyling } from './_advanced_table_row_styling.jsx'
|
|
39
40
|
export { default as AdvancedTableColumnStyling } from './_advanced_table_column_styling.jsx'
|
|
41
|
+
export { default as AdvancedTableColumnStylingWidth } from './_advanced_table_column_styling_width.jsx'
|
|
40
42
|
export { default as AdvancedTableColumnStylingColumnHeaders } from './_advanced_table_column_styling_column_headers.jsx'
|
|
41
43
|
export { default as AdvancedTableInfiniteScroll} from './_advanced_table_infinite_scroll.jsx'
|
|
42
44
|
export {default as AdvancedTableWithCustomHeader} from './_advanced_table_with_custom_header.jsx'
|
|
@@ -162,7 +162,7 @@ const Card = (props: CardPropTypes): React.ReactElement => {
|
|
|
162
162
|
{
|
|
163
163
|
dragHandle ? (
|
|
164
164
|
<Flex>
|
|
165
|
-
<span className="card_draggable_handle">
|
|
165
|
+
<span className="card_draggable_handle pb_draggable_handle">
|
|
166
166
|
<Icon
|
|
167
167
|
icon="grip-dots-vertical"
|
|
168
168
|
paddingRight="xs"
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<% if object.draggable_item %>
|
|
5
5
|
<%= pb_rails("flex", props: { align: "center" }) do %>
|
|
6
6
|
<% if object.drag_handle %>
|
|
7
|
-
<span
|
|
7
|
+
<span class="card_draggable_handle pb_draggable_handle">
|
|
8
8
|
<%= pb_rails("icon", props: { icon: "grip-dots-vertical", padding_right: "xs" }) %>
|
|
9
9
|
</span>
|
|
10
10
|
<% end %>
|
|
@@ -59,12 +59,13 @@ const Currency = (props: CurrencyProps): React.ReactElement => {
|
|
|
59
59
|
commaSeparator = false,
|
|
60
60
|
} = props
|
|
61
61
|
|
|
62
|
+
const isAmountEmpty = (value: string | number): boolean => (
|
|
63
|
+
value === '' || value == null || (typeof value === 'string' && value.trim() === '')
|
|
64
|
+
)
|
|
65
|
+
|
|
62
66
|
// Convert numeric input to string format
|
|
63
67
|
const convertAmount = (input: string | number): string => {
|
|
64
68
|
if (typeof input === 'number') {
|
|
65
|
-
if (input === 0 && !nullDisplay) {
|
|
66
|
-
return ""
|
|
67
|
-
}
|
|
68
69
|
return input.toFixed(2)
|
|
69
70
|
}
|
|
70
71
|
return input
|
|
@@ -81,7 +82,9 @@ const Currency = (props: CurrencyProps): React.ReactElement => {
|
|
|
81
82
|
variantClass = '_bold'
|
|
82
83
|
}
|
|
83
84
|
|
|
84
|
-
const [
|
|
85
|
+
const [wholePart, decimalPart = '00'] = currencyAmount ? currencyAmount.split('.') : ['', '00']
|
|
86
|
+
const decimal = (decimalPart || '00').padEnd(2, '0').slice(0, 2)
|
|
87
|
+
const whole = currencyAmount === '' ? '' : (wholePart === '' ? '0' : wholePart)
|
|
85
88
|
const ariaProps = buildAriaProps(aria)
|
|
86
89
|
const dataProps = buildDataProps(data)
|
|
87
90
|
const htmlProps = buildHtmlProps(htmlOptions)
|
|
@@ -135,7 +138,7 @@ const Currency = (props: CurrencyProps): React.ReactElement => {
|
|
|
135
138
|
<Caption dark={dark}>{label}</Caption>
|
|
136
139
|
<div className={`pb_currency_wrapper${variantClass || emphasizedClass}`}>
|
|
137
140
|
{unstyled ? (
|
|
138
|
-
nullDisplay &&
|
|
141
|
+
nullDisplay && isAmountEmpty(amount) ? (
|
|
139
142
|
<div>{nullDisplay}</div>
|
|
140
143
|
) : (
|
|
141
144
|
<>
|
|
@@ -148,7 +151,7 @@ const Currency = (props: CurrencyProps): React.ReactElement => {
|
|
|
148
151
|
</>
|
|
149
152
|
)
|
|
150
153
|
) : (
|
|
151
|
-
nullDisplay &&
|
|
154
|
+
nullDisplay && isAmountEmpty(amount) ? (
|
|
152
155
|
<Title
|
|
153
156
|
className="pb_currency_value"
|
|
154
157
|
dark={dark}
|
|
@@ -68,7 +68,7 @@ module Playbook
|
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
def title_text
|
|
71
|
-
if null_display
|
|
71
|
+
if null_display && amount.blank?
|
|
72
72
|
null_display
|
|
73
73
|
elsif swap_negative
|
|
74
74
|
absolute_amount(abbr_or_format_amount)
|
|
@@ -125,14 +125,7 @@ module Playbook
|
|
|
125
125
|
# Convert numeric input to string format
|
|
126
126
|
def convert_amount(input)
|
|
127
127
|
if input.is_a?(Numeric)
|
|
128
|
-
|
|
129
|
-
""
|
|
130
|
-
else
|
|
131
|
-
format("%.2f", input)
|
|
132
|
-
end
|
|
133
|
-
# Handle string representations of zero
|
|
134
|
-
elsif input.to_s.strip.match?(/^-?0+(\.0+)?$/) && null_display.nil?
|
|
135
|
-
""
|
|
128
|
+
Kernel.format("%.2f", input)
|
|
136
129
|
else
|
|
137
130
|
input.to_s
|
|
138
131
|
end
|
|
@@ -142,6 +135,7 @@ module Playbook
|
|
|
142
135
|
return "" if currency_amount.blank?
|
|
143
136
|
|
|
144
137
|
value = currency_amount.split(".").first
|
|
138
|
+
value = "0" if value.blank?
|
|
145
139
|
if comma_separator
|
|
146
140
|
number_with_delimiter(value.gsub(",", ""))
|
|
147
141
|
else
|
|
@@ -152,7 +146,8 @@ module Playbook
|
|
|
152
146
|
def decimal_value
|
|
153
147
|
return "00" if currency_amount.blank?
|
|
154
148
|
|
|
155
|
-
currency_amount.split(".")[1] || "00"
|
|
149
|
+
fraction = currency_amount.split(".")[1] || "00"
|
|
150
|
+
fraction.ljust(2, "0")[0, 2]
|
|
156
151
|
end
|
|
157
152
|
|
|
158
153
|
def units_element
|
|
@@ -178,5 +178,48 @@ test('handles numeric amounts correctly', () => {
|
|
|
178
178
|
expect(screen.getByTestId('test-numeric-no-symbol')).toHaveTextContent('400.50')
|
|
179
179
|
expect(screen.getByTestId('test-numeric-medium-size')).toHaveTextContent('$500.55')
|
|
180
180
|
expect(screen.getByTestId('test-numeric-negative')).toHaveTextContent('-$600.70')
|
|
181
|
-
expect(screen.getByTestId('test-numeric-null')).toHaveTextContent('
|
|
181
|
+
expect(screen.getByTestId('test-numeric-null')).toHaveTextContent('$0.00')
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
test('renders zero values with leading digit', () => {
|
|
185
|
+
render(
|
|
186
|
+
<>
|
|
187
|
+
<Currency
|
|
188
|
+
amount="0"
|
|
189
|
+
data={{ testid: 'test-string-zero' }}
|
|
190
|
+
/>
|
|
191
|
+
<Currency
|
|
192
|
+
amount={0}
|
|
193
|
+
data={{ testid: 'test-numeric-zero' }}
|
|
194
|
+
/>
|
|
195
|
+
</>
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
expect(screen.getByTestId('test-string-zero')).toHaveTextContent('$0.00')
|
|
199
|
+
expect(screen.getByTestId('test-numeric-zero')).toHaveTextContent('$0.00')
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
test('normalizes string zero with single decimal digit to .00', () => {
|
|
203
|
+
render(
|
|
204
|
+
<Currency
|
|
205
|
+
amount="0.0"
|
|
206
|
+
commaSeparator
|
|
207
|
+
data={{ testid: 'test-string-zero-single-decimal' }}
|
|
208
|
+
/>
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
expect(screen.getByTestId('test-string-zero-single-decimal')).toHaveTextContent('$0.00')
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
test('nullDisplay only applies when amount is empty', () => {
|
|
215
|
+
render(
|
|
216
|
+
<Currency
|
|
217
|
+
amount="-.53"
|
|
218
|
+
data={{ testid: 'test-null-display-negative' }}
|
|
219
|
+
nullDisplay="$0.00"
|
|
220
|
+
/>
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
expect(screen.getByTestId('test-null-display-negative')).toHaveTextContent('-$')
|
|
224
|
+
expect(screen.getByTestId('test-null-display-negative')).not.toHaveTextContent('$0.00')
|
|
182
225
|
})
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"template": "<
|
|
2
|
+
"template": "<FormattedDate{{props}} />",
|
|
3
3
|
"propTargets": {},
|
|
4
4
|
"defaults": {
|
|
5
5
|
"alignment": "left",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
},
|
|
12
12
|
"groups": [
|
|
13
13
|
{
|
|
14
|
-
"name": "
|
|
14
|
+
"name": "Date Config",
|
|
15
15
|
"props": [
|
|
16
16
|
"value",
|
|
17
17
|
"showDayOfWeek",
|
|
@@ -32,21 +32,20 @@
|
|
|
32
32
|
{
|
|
33
33
|
"name": "Default",
|
|
34
34
|
"props": {
|
|
35
|
-
"value": "2026-04-
|
|
35
|
+
"value": "2026-04-09"
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
|
-
"name": "
|
|
39
|
+
"name": "centered",
|
|
40
40
|
"props": {
|
|
41
|
-
"value": "2026-04-
|
|
42
|
-
"size": "lg",
|
|
41
|
+
"value": "2026-04-09",
|
|
43
42
|
"alignment": "center"
|
|
44
43
|
}
|
|
45
44
|
},
|
|
46
45
|
{
|
|
47
46
|
"name": "Small with weekday",
|
|
48
47
|
"props": {
|
|
49
|
-
"value": "2026-06-
|
|
48
|
+
"value": "2026-06-18",
|
|
50
49
|
"size": "sm",
|
|
51
50
|
"showDayOfWeek": true
|
|
52
51
|
}
|
|
@@ -54,20 +53,17 @@
|
|
|
54
53
|
{
|
|
55
54
|
"name": "With icon & year",
|
|
56
55
|
"props": {
|
|
57
|
-
"value": "2024-11-
|
|
56
|
+
"value": "2024-11-02",
|
|
58
57
|
"showIcon": true,
|
|
59
58
|
"showCurrentYear": true
|
|
60
59
|
}
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
"name": "Unstyled",
|
|
64
|
-
"props": {
|
|
65
|
-
"value": "2026-04-09T15:30:00.000Z",
|
|
66
|
-
"unstyled": true,
|
|
67
|
-
"showDayOfWeek": true
|
|
68
|
-
}
|
|
69
60
|
}
|
|
70
61
|
],
|
|
71
62
|
"conditionals": {},
|
|
72
|
-
"hints": {
|
|
63
|
+
"hints": {
|
|
64
|
+
"default": {
|
|
65
|
+
"message": "Use as FormattedDate to avoid naming collisions with global Date object",
|
|
66
|
+
"type": "info"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
73
69
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
+
"template": "<FormattedDate{{props}} />",
|
|
2
3
|
"groups": [
|
|
3
4
|
{
|
|
4
|
-
"name": "
|
|
5
|
+
"name": "Date Config",
|
|
5
6
|
"props": ["value", "showDayOfWeek", "showCurrentYear", "showIcon"]
|
|
6
7
|
},
|
|
7
8
|
{
|
|
@@ -13,21 +14,20 @@
|
|
|
13
14
|
{
|
|
14
15
|
"name": "Default",
|
|
15
16
|
"props": {
|
|
16
|
-
"value": "2026-04-
|
|
17
|
+
"value": "2026-04-09"
|
|
17
18
|
}
|
|
18
19
|
},
|
|
19
20
|
{
|
|
20
|
-
"name": "
|
|
21
|
+
"name": "centered",
|
|
21
22
|
"props": {
|
|
22
|
-
"value": "2026-04-
|
|
23
|
-
"size": "lg",
|
|
23
|
+
"value": "2026-04-09",
|
|
24
24
|
"alignment": "center"
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
"name": "Small with weekday",
|
|
29
29
|
"props": {
|
|
30
|
-
"value": "2026-06-
|
|
30
|
+
"value": "2026-06-18",
|
|
31
31
|
"size": "sm",
|
|
32
32
|
"showDayOfWeek": true
|
|
33
33
|
}
|
|
@@ -35,20 +35,17 @@
|
|
|
35
35
|
{
|
|
36
36
|
"name": "With icon & year",
|
|
37
37
|
"props": {
|
|
38
|
-
"value": "2024-11-
|
|
38
|
+
"value": "2024-11-02",
|
|
39
39
|
"showIcon": true,
|
|
40
40
|
"showCurrentYear": true
|
|
41
41
|
}
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
"name": "Unstyled",
|
|
45
|
-
"props": {
|
|
46
|
-
"value": "2026-04-09T15:30:00.000Z",
|
|
47
|
-
"unstyled": true,
|
|
48
|
-
"showDayOfWeek": true
|
|
49
|
-
}
|
|
50
42
|
}
|
|
51
43
|
],
|
|
52
44
|
"conditionals": {},
|
|
53
|
-
"hints": {
|
|
45
|
+
"hints": {
|
|
46
|
+
"default": {
|
|
47
|
+
"message": "Use as FormattedDate to avoid naming collisions with global Date object",
|
|
48
|
+
"type": "info"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
54
51
|
}
|
|
@@ -180,6 +180,7 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => {
|
|
|
180
180
|
//@ts-ignore
|
|
181
181
|
globalProps(filteredProps),
|
|
182
182
|
error ? 'error' : null,
|
|
183
|
+
inLine && 'inline-date-picker',
|
|
183
184
|
className
|
|
184
185
|
)
|
|
185
186
|
|
|
@@ -262,7 +263,7 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => {
|
|
|
262
263
|
}
|
|
263
264
|
</div>
|
|
264
265
|
|
|
265
|
-
{!hideIcon &&
|
|
266
|
+
{!hideIcon && !inLine &&
|
|
266
267
|
<div
|
|
267
268
|
className={iconWrapperClass()}
|
|
268
269
|
id={`cal-icon-${pickerId}`}
|
|
@@ -274,7 +275,7 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => {
|
|
|
274
275
|
</div>
|
|
275
276
|
}
|
|
276
277
|
|
|
277
|
-
{
|
|
278
|
+
{inLine ?
|
|
278
279
|
<div>
|
|
279
280
|
<div
|
|
280
281
|
className={`${iconWrapperClass()} date-picker-inline-icon-plus`}
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
<input type="hidden" id="<%= "#{object.end_date_id}" %>" name="<%= "#{object.end_date_name}" %>">
|
|
40
40
|
<% end %>
|
|
41
41
|
|
|
42
|
-
<% if !object.hide_icon %>
|
|
42
|
+
<% if !object.hide_icon && !object.inline %>
|
|
43
43
|
<div
|
|
44
44
|
class="<%= object.icon_wrapper_class %>"
|
|
45
45
|
id="cal-icon-<%= object.picker_id %>"
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
<% end %>
|
|
53
53
|
|
|
54
54
|
<!-- Inline -->
|
|
55
|
-
<% if object.
|
|
55
|
+
<% if object.inline %>
|
|
56
56
|
<!-- Plus Icon -->
|
|
57
57
|
<div
|
|
58
58
|
class="<%= object.icon_wrapper_class %> date-picker-inline-icon-plus"
|
|
@@ -79,42 +79,57 @@
|
|
|
79
79
|
|
|
80
80
|
<%= javascript_tag do %>
|
|
81
81
|
(function() {
|
|
82
|
+
const initQuickPickChangeListener = (input) => {
|
|
83
|
+
if (!<%= object.selection_type == "quickpick" %>) return
|
|
84
|
+
if (input.dataset.quickpickInitialized) return
|
|
85
|
+
|
|
86
|
+
input.dataset.quickpickInitialized = "true"
|
|
87
|
+
input.addEventListener("change", ({ target }) => {
|
|
88
|
+
const startDate = document.getElementById("<%= object.start_date_id %>")
|
|
89
|
+
const endDate = document.getElementById("<%= object.end_date_id %>")
|
|
90
|
+
const splittedValue = target.value.split(" to ")
|
|
91
|
+
startDate.value = splittedValue[0]
|
|
92
|
+
endDate.value = splittedValue[1] ? splittedValue[1] : splittedValue[0]
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
|
|
82
96
|
const loadDatePicker = () => {
|
|
83
|
-
const input = document.getElementById("<%= object.picker_id %>")
|
|
84
|
-
|
|
85
|
-
|
|
97
|
+
const input = document.getElementById("<%= object.picker_id %>")
|
|
98
|
+
|
|
99
|
+
if (!input || input._flatpickr) return true
|
|
100
|
+
if (typeof window.datePickerHelper !== "function") return false
|
|
86
101
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
102
|
+
window.datePickerHelper(<%= object.date_picker_config %>, "<%= object.scroll_container %>")
|
|
103
|
+
initQuickPickChangeListener(input)
|
|
104
|
+
|
|
105
|
+
return true
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
let attempts = 0
|
|
109
|
+
const retryLoad = () => {
|
|
110
|
+
if (loadDatePicker()) return
|
|
111
|
+
|
|
112
|
+
if (attempts++ < 20) {
|
|
113
|
+
setTimeout(retryLoad, 100)
|
|
96
114
|
}
|
|
97
115
|
}
|
|
98
116
|
|
|
99
|
-
// Try to initialize immediately if DOM is ready
|
|
100
117
|
if (document.readyState === "loading") {
|
|
101
|
-
window.addEventListener("DOMContentLoaded",
|
|
118
|
+
window.addEventListener("DOMContentLoaded", retryLoad)
|
|
102
119
|
} else {
|
|
103
|
-
|
|
120
|
+
retryLoad()
|
|
104
121
|
}
|
|
105
122
|
|
|
106
123
|
// For dynamically added content (modals, etc.), check again after a brief delay
|
|
107
124
|
setTimeout(() => {
|
|
108
|
-
const input = document.getElementById("<%= object.picker_id %>")
|
|
125
|
+
const input = document.getElementById("<%= object.picker_id %>")
|
|
109
126
|
if (input && !input._flatpickr) {
|
|
110
|
-
|
|
127
|
+
retryLoad()
|
|
111
128
|
}
|
|
112
|
-
}, 100)
|
|
129
|
+
}, 100)
|
|
113
130
|
|
|
114
131
|
if (<%= !object.custom_event_type.empty? %>) {
|
|
115
|
-
window.addEventListener("<%= object.custom_event_type %>",
|
|
116
|
-
loadDatePicker()
|
|
117
|
-
})
|
|
132
|
+
window.addEventListener("<%= object.custom_event_type %>", retryLoad)
|
|
118
133
|
}
|
|
119
134
|
})()
|
|
120
135
|
<% end %>
|
|
@@ -92,7 +92,8 @@ module Playbook
|
|
|
92
92
|
|
|
93
93
|
def classname
|
|
94
94
|
default_margin_bottom = margin_bottom.present? ? "" : " mb_sm"
|
|
95
|
-
|
|
95
|
+
inline_class = inline ? " inline-date-picker" : ""
|
|
96
|
+
generate_classname("pb_date_picker_kit") + default_margin_bottom + inline_class
|
|
96
97
|
end
|
|
97
98
|
|
|
98
99
|
def date_picker_config
|
|
@@ -40,6 +40,37 @@ describe('DatePicker Kit', () => {
|
|
|
40
40
|
expect(kit).toHaveClass('pb_date_picker_kit mb_sm')
|
|
41
41
|
})
|
|
42
42
|
|
|
43
|
+
test('inLine alone adds inline-date-picker class and inline control icons, not the calendar icon', () => {
|
|
44
|
+
const testId = 'datepicker-inline-only'
|
|
45
|
+
render(
|
|
46
|
+
<DatePicker
|
|
47
|
+
data={{ testid: testId }}
|
|
48
|
+
inLine
|
|
49
|
+
pickerId="date-picker-inline-only"
|
|
50
|
+
/>
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
const kit = screen.getByTestId(testId)
|
|
54
|
+
expect(kit).toHaveClass('inline-date-picker')
|
|
55
|
+
expect(kit.querySelector('#cal-icon-date-picker-inline-only')).not.toBeInTheDocument()
|
|
56
|
+
expect(kit.querySelector('#date-picker-inline-only-icon-plus')).toBeInTheDocument()
|
|
57
|
+
expect(kit.querySelector('#date-picker-inline-only-angle-down')).toBeInTheDocument()
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
test('hideIcon without inLine does not render inline control icons', () => {
|
|
61
|
+
const testId = 'datepicker-hide-icon-only'
|
|
62
|
+
render(
|
|
63
|
+
<DatePicker
|
|
64
|
+
data={{ testid: testId }}
|
|
65
|
+
hideIcon
|
|
66
|
+
pickerId="date-picker-hide-icon-only"
|
|
67
|
+
/>
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
const kit = screen.getByTestId(testId)
|
|
71
|
+
expect(kit.querySelector('#date-picker-hide-icon-only-icon-plus')).not.toBeInTheDocument()
|
|
72
|
+
})
|
|
73
|
+
|
|
43
74
|
test('shows DatePicker date format m/d/Y', async () => {
|
|
44
75
|
const testId = 'datepicker-date'
|
|
45
76
|
render(
|
|
@@ -36,10 +36,10 @@ const DatePickerDialogSubmission = () => {
|
|
|
36
36
|
<Dialog.Body>
|
|
37
37
|
<DatePicker
|
|
38
38
|
defaultDate={dateFixed || undefined}
|
|
39
|
-
key={
|
|
39
|
+
key={"fixed-" + pickerInstance}
|
|
40
40
|
label="Date"
|
|
41
41
|
onChange={(dateStr) => setDateFixed(dateStr || "")}
|
|
42
|
-
pickerId={
|
|
42
|
+
pickerId={"datePickerFixed-" + pickerInstance}
|
|
43
43
|
staticPosition={false}
|
|
44
44
|
/>
|
|
45
45
|
</Dialog.Body>
|