playbook_ui 15.0.0.pre.alpha.PLAY2467contactkitinternational10329 → 15.0.0.pre.alpha.PLAY2473rowhighlightfix10512
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/_playbook.scss +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +12 -11
- data/app/pb_kits/playbook/pb_advanced_table/Components/VirtualizedTableView.tsx +7 -7
- data/app/pb_kits/playbook/pb_advanced_table/Utilities/RowUtils.ts +7 -2
- data/app/pb_kits/playbook/pb_bar_graph/docs/example.yml +0 -1
- data/app/pb_kits/playbook/pb_circle_icon_button/_circle_icon_button.tsx +2 -0
- data/app/pb_kits/playbook/pb_circle_icon_button/circle_icon_button.html.erb +1 -0
- data/app/pb_kits/playbook/pb_collapsible/__snapshots__/collapsible.test.js.snap +1 -0
- data/app/pb_kits/playbook/pb_contact/_contact.tsx +0 -5
- data/app/pb_kits/playbook/pb_contact/contact.rb +0 -4
- data/app/pb_kits/playbook/pb_contact/contact.test.js +1 -21
- data/app/pb_kits/playbook/pb_contact/docs/_contact_default.html.erb +1 -16
- data/app/pb_kits/playbook/pb_contact/docs/_contact_default.jsx +0 -15
- data/app/pb_kits/playbook/pb_contact/docs/_contact_with_detail.html.erb +0 -6
- data/app/pb_kits/playbook/pb_contact/docs/_contact_with_detail.jsx +0 -6
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +6 -4
- data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +48 -4
- data/app/pb_kits/playbook/pb_dialog/_close_icon.tsx +5 -1
- data/app/pb_kits/playbook/pb_dialog/_dialog.tsx +6 -8
- data/app/pb_kits/playbook/pb_dialog/dialog.html.erb +1 -1
- data/app/pb_kits/playbook/pb_dialog/dialog_header.html.erb +2 -2
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.tsx +9 -0
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/fixed_confirmation_toast.html.erb +3 -3
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with.html.erb +1 -0
- data/app/pb_kits/playbook/pb_icon/_icon.tsx +13 -2
- data/app/pb_kits/playbook/pb_icon/icon.rb +9 -1
- data/app/pb_kits/playbook/pb_icon_circle/icon_circle.html.erb +1 -1
- data/app/pb_kits/playbook/pb_loading_inline/_loading_inline.tsx +3 -1
- data/app/pb_kits/playbook/pb_loading_inline/docs/_loading_inline_variant.html.erb +5 -0
- data/app/pb_kits/playbook/pb_loading_inline/docs/_loading_inline_variant.jsx +24 -0
- data/app/pb_kits/playbook/pb_loading_inline/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_loading_inline/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_loading_inline/loading_inline.html.erb +1 -1
- data/app/pb_kits/playbook/pb_loading_inline/loading_inline.rb +11 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/_pb_bar_graph.scss +0 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/_pb_bar_graph.tsx +62 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_colors.html.erb +35 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_colors.jsx +49 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_colors_rails.md +1 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_colors_react.md +2 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_default.html.erb +38 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_default.jsx +51 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_height.html.erb +46 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_height.jsx +62 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_height.md +3 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_horizontal.html.erb +47 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_horizontal.jsx +60 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_legend.html.erb +25 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_legend.jsx +36 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_legend_non_clickable.jsx +44 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_legend_position.html.erb +100 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_legend_position.jsx +126 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_negative_numbers.html.erb +32 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_negative_numbers.jsx +48 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_secondary_y_axis.html.erb +68 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_secondary_y_axis.jsx +81 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_spline.html.erb +31 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_spline.jsx +42 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_spline.md +2 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_stacked.html.erb +35 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_pb_bar_graph_stacked.jsx +51 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/example.yml +27 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/index.js +11 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/pbBarGraphTheme.ts +106 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/pb_bar_graph.html.erb +1 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/pb_bar_graph.rb +28 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/pbbargraph.test.jsx +31 -0
- data/app/pb_kits/playbook/pb_text_input/_text_input.tsx +3 -0
- data/app/pb_kits/playbook/pb_text_input/docs/_text_input_autocomplete.html.erb +41 -0
- data/app/pb_kits/playbook/pb_text_input/docs/_text_input_autocomplete.jsx +80 -0
- data/app/pb_kits/playbook/pb_text_input/docs/_text_input_autocomplete.md +1 -0
- data/app/pb_kits/playbook/pb_text_input/docs/example.yml +3 -0
- data/app/pb_kits/playbook/pb_text_input/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_text_input/text_input.rb +2 -3
- data/app/pb_kits/playbook/pb_text_input/text_input.test.js +38 -0
- data/dist/chunks/{_line_graph-CApw7aQD.js → _line_graph-BBny-YYZ.js} +1 -1
- data/dist/chunks/_typeahead-CeyJ6-GF.js +6 -0
- data/dist/chunks/_weekday_stacked-BZw0f9oB.js +37 -0
- data/dist/chunks/{lib-CY5ZPzic.js → lib-BTs5acfO.js} +1 -1
- data/dist/chunks/{pb_form_validation-D3b0JKHH.js → pb_form_validation-CKkaQFX3.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/menu.yml +9 -1
- data/dist/playbook-doc.js +2 -2
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/lib/playbook/forms/builder/form_field_builder.rb +9 -1
- data/lib/playbook/version.rb +1 -1
- metadata +45 -9
- data/app/pb_kits/playbook/pb_contact/docs/_contact_default.md +0 -5
- data/app/pb_kits/playbook/pb_dialog/dialogHelper.js +0 -65
- data/dist/chunks/_typeahead-J1_avqdO.js +0 -6
- data/dist/chunks/_weekday_stacked-BSRRJewP.js +0 -37
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 982344fe138179bc21bb46402ac4d6e897531ab4a6ed64d34177f0be9aa9d577
         | 
| 4 | 
            +
              data.tar.gz: df3971a42e4036f06a4f704bb8ef50d78365b666344b19b1aacda4679443bca9
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: ee369ee9ccf522bbc8fa3c57e6b0022801088391b8cac6663840ca9497e56acf5a1aaded868b0075edf27eb52c27525fa9848ccc6ad0b74882920571c369344c
         | 
| 7 | 
            +
              data.tar.gz: e15b63750ce6b4bce43d5e4a729b5d6791389c769af14fb46e2bd037ff7e8c647bb70c4ed0d05445fc71e76bcb8f2f93dcfbb21008e515b1f29edd6e08cfcfb6
         | 
| @@ -108,6 +108,7 @@ | |
| 108 108 | 
             
            @import 'pb_user_badge/user_badge';
         | 
| 109 109 | 
             
            @import 'pb_weekday_stacked/weekday_stacked';
         | 
| 110 110 | 
             
            @import 'pb_empty_state/empty_state';
         | 
| 111 | 
            +
            @import 'pb_pb_bar_graph/pb_bar_graph';
         | 
| 111 112 | 
             
            @import 'utilities/mixins';
         | 
| 112 113 | 
             
            @import 'utilities/spacing';
         | 
| 113 114 | 
             
            @import 'utilities/cursor';
         | 
| @@ -5,6 +5,7 @@ import { flexRender, Row, Cell } from "@tanstack/react-table" | |
| 5 5 | 
             
            import { GenericObject } from "../../types"
         | 
| 6 6 | 
             
            import { isChrome } from "../Utilities/BrowserCheck"
         | 
| 7 7 | 
             
            import { findColumnDefByAccessor } from "../Utilities/ColumnStylingHelper"
         | 
| 8 | 
            +
            import { getRowColorClass, shouldShowLoadingIndicator } from "../Utilities/RowUtils"
         | 
| 8 9 |  | 
| 9 10 | 
             
            import LoadingInline from "../../pb_loading_inline/_loading_inline"
         | 
| 10 11 | 
             
            import Checkbox from "../../pb_checkbox/_checkbox"
         | 
| @@ -60,7 +61,7 @@ const TableCellRenderer = ({ | |
| 60 61 | 
             
                    const cellAlignment = colDef?.columnStyling?.cellAlignment ?? "right"
         | 
| 61 62 | 
             
                    const paddingValue = colDef?.columnStyling?.cellPadding ?? customRowStyle?.cellPadding
         | 
| 62 63 | 
             
                    const paddingClass = paddingValue ? `p_${paddingValue}` : undefined
         | 
| 63 | 
            -
             | 
| 64 | 
            +
             | 
| 64 65 | 
             
                    return (
         | 
| 65 66 | 
             
                      <td
         | 
| 66 67 | 
             
                          align={cellAlignment}
         | 
| @@ -132,6 +133,7 @@ export const RegularTableView = ({ | |
| 132 133 |  | 
| 133 134 | 
             
              const columnPinning = table.getState().columnPinning || { left: [] };
         | 
| 134 135 | 
             
              const columnDefinitions = table.options.meta?.columnDefinitions || [];
         | 
| 136 | 
            +
             | 
| 135 137 | 
             
              // Row pinning
         | 
| 136 138 | 
             
              function PinnedRow({ row }: { row: Row<any> }) {
         | 
| 137 139 | 
             
                const customRowStyle = rowStyling?.length > 0 && rowStyling?.find((s: GenericObject) => s?.rowId === row.id);
         | 
| @@ -144,7 +146,7 @@ export const RegularTableView = ({ | |
| 144 146 | 
             
                        backgroundColor: customRowStyle?.backgroundColor ? customRowStyle?.backgroundColor : 'white',
         | 
| 145 147 | 
             
                        color: customRowStyle?.fontColor,
         | 
| 146 148 | 
             
                        position: 'sticky',
         | 
| 147 | 
            -
                        top: | 
| 149 | 
            +
                        top:
         | 
| 148 150 | 
             
                          row.getIsPinned() === 'top'
         | 
| 149 151 | 
             
                              ? `${row.getPinnedIndex() * rowHeight + headerHeight}px`
         | 
| 150 152 | 
             
                              : undefined,
         | 
| @@ -169,21 +171,20 @@ export const RegularTableView = ({ | |
| 169 171 | 
             
              return (
         | 
| 170 172 | 
             
                <>
         | 
| 171 173 | 
             
                  {pinnedRows && table.getTopRows().map((row: Row<GenericObject>) => (
         | 
| 172 | 
            -
                    <PinnedRow key={row.id} | 
| 173 | 
            -
                        row={row} | 
| 174 | 
            +
                    <PinnedRow key={row.id}
         | 
| 175 | 
            +
                        row={row}
         | 
| 174 176 | 
             
                    />
         | 
| 175 177 | 
             
                  ))}
         | 
| 176 178 | 
             
                  {totalRows.map((row: Row<GenericObject>, rowIndex: number) => {
         | 
| 177 | 
            -
                    const isExpandable = row.getIsExpanded();
         | 
| 178 179 | 
             
                    const isFirstChildofSubrow = row.depth > 0 && row.index === 0;
         | 
| 179 | 
            -
                    const rowHasNoChildren = row.original?.children && !row.original.children.length ? true : false;
         | 
| 180 180 | 
             
                    const numberOfColumns = table.getAllFlatColumns().length;
         | 
| 181 | 
            -
                    const isDataLoading = isExpandable && (inlineRowLoading && rowHasNoChildren) && (row.depth < columnDefinitions[0]?.cellAccessors?.length);
         | 
| 182 | 
            -
                    const rowBackground = isExpandable && ((!inlineRowLoading && row.getCanExpand()) || (inlineRowLoading && rowHasNoChildren));
         | 
| 183 | 
            -
                    const rowColor = row.getIsSelected() ? "bg-row-selection" : rowBackground ? "bg-silver" : "bg-white";
         | 
| 184 181 | 
             
                    const isFirstRegularRow = rowIndex === 0 && !row.getIsPinned();
         | 
| 185 182 | 
             
                    const customRowStyle = rowStyling?.length > 0 && rowStyling?.find((s: GenericObject) => s?.rowId === row.id);
         | 
| 186 183 |  | 
| 184 | 
            +
                    // Use functions from RowUtils for consistent cell coloring
         | 
| 185 | 
            +
                    const rowColor = getRowColorClass(row, inlineRowLoading || false);
         | 
| 186 | 
            +
                    const isDataLoading = shouldShowLoadingIndicator(row, inlineRowLoading || false, columnDefinitions[0]?.cellAccessors?.length || 0);
         | 
| 187 | 
            +
             | 
| 187 188 | 
             
                    return (
         | 
| 188 189 | 
             
                      <React.Fragment key={`${row.index}-${row.id}-${row.depth}-row`}>
         | 
| 189 190 | 
             
                        {isFirstChildofSubrow && subRowHeaders && (
         | 
| @@ -228,7 +229,7 @@ export const RegularTableView = ({ | |
| 228 229 |  | 
| 229 230 | 
             
                        {/* Display LoadingInline if Row Data is querying and there are no children already */}
         | 
| 230 231 | 
             
                        {isDataLoading && (
         | 
| 231 | 
            -
                          <tr key={`${row.id}-row`}>
         | 
| 232 | 
            +
                          <tr key={`${row.id}-loading-row`}>
         | 
| 232 233 | 
             
                            <td colSpan={numberOfColumns}
         | 
| 233 234 | 
             
                                style={{ paddingLeft: `${row.depth === 0 ? 0.5 : (row.depth * 2)}em` }}
         | 
| 234 235 | 
             
                            >
         | 
| @@ -243,4 +244,4 @@ export const RegularTableView = ({ | |
| 243 244 | 
             
              );
         | 
| 244 245 | 
             
            }
         | 
| 245 246 |  | 
| 246 | 
            -
            export default RegularTableView;
         | 
| 247 | 
            +
            export default RegularTableView;
         | 
| @@ -7,6 +7,7 @@ import { GenericObject } from "../../types" | |
| 7 7 |  | 
| 8 8 | 
             
            import { isChrome } from "../Utilities/BrowserCheck"
         | 
| 9 9 | 
             
            import { getVirtualizedRowStyle } from "../Utilities/TableContainerStyles"
         | 
| 10 | 
            +
            import { getRowColorClass } from "../Utilities/RowUtils"
         | 
| 10 11 |  | 
| 11 12 | 
             
            import LoadingInline from "../../pb_loading_inline/_loading_inline"
         | 
| 12 13 | 
             
            import Checkbox from "../../pb_checkbox/_checkbox"
         | 
| @@ -45,10 +46,10 @@ export const VirtualizedTableView = ({ | |
| 45 46 |  | 
| 46 47 | 
             
              const columnPinning = table.getState().columnPinning || { left: [] };
         | 
| 47 48 | 
             
              const sortingState = JSON.stringify(table.getState().sorting || []);
         | 
| 48 | 
            -
             | 
| 49 | 
            +
             | 
| 49 50 | 
             
              // Store column widths extracted from header
         | 
| 50 51 | 
             
              const [columnWidths, setColumnWidths] = useState<{[key: string]: string}>({});
         | 
| 51 | 
            -
             | 
| 52 | 
            +
             | 
| 52 53 | 
             
              // Function to get header cell widths
         | 
| 53 54 | 
             
              const getHeaderCellWidths = () => {
         | 
| 54 55 | 
             
                const widths: {[key: string]: string} = {};
         | 
| @@ -136,7 +137,7 @@ export const VirtualizedTableView = ({ | |
| 136 137 | 
             
                  </tr>
         | 
| 137 138 | 
             
                );
         | 
| 138 139 | 
             
              }
         | 
| 139 | 
            -
             | 
| 140 | 
            +
             | 
| 140 141 | 
             
              // Establish # of Parent Rows (so that Footer count does not include every single row)
         | 
| 141 142 | 
             
              const topLevelRowCount = table.getRowModel().flatRows.filter((row: Row<GenericObject>) => row.depth === 0).length;
         | 
| 142 143 |  | 
| @@ -172,10 +173,9 @@ export const VirtualizedTableView = ({ | |
| 172 173 |  | 
| 173 174 | 
             
                    if (item.type === 'row') {
         | 
| 174 175 | 
             
                      const row = item.row;
         | 
| 175 | 
            -
             | 
| 176 | 
            -
                       | 
| 177 | 
            -
                      const  | 
| 178 | 
            -
                      const rowColor = row.getIsSelected() ? "bg-row-selection" : rowBackground ? "bg-silver" : "bg-white";
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                      // Use the utility function to get consistent row color
         | 
| 178 | 
            +
                      const rowColor = getRowColorClass(row, inlineRowLoading || false);
         | 
| 179 179 |  | 
| 180 180 | 
             
                      return (
         | 
| 181 181 | 
             
                        <tr
         | 
| @@ -10,9 +10,14 @@ export const getRowColorClass = ( | |
| 10 10 | 
             
            ): string => {
         | 
| 11 11 | 
             
              const isExpandable = row.getIsExpanded();
         | 
| 12 12 | 
             
              const rowHasNoChildren = row.original?.children && !row.original.children.length ? true : false;
         | 
| 13 | 
            -
              const rowBackground = isExpandable && ((!inlineRowLoading && row.getCanExpand()) || (inlineRowLoading && rowHasNoChildren));
         | 
| 14 13 |  | 
| 15 | 
            -
               | 
| 14 | 
            +
              // Check if row can expand or is currently expanded
         | 
| 15 | 
            +
              const shouldShowExpandedBackground = isExpandable && (
         | 
| 16 | 
            +
                (!inlineRowLoading && row.getCanExpand()) ||
         | 
| 17 | 
            +
                (inlineRowLoading && (rowHasNoChildren || row.getCanExpand()))
         | 
| 18 | 
            +
              );
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              return row.getIsSelected() ? "bg-row-selection" : shouldShowExpandedBackground ? "bg-silver" : "bg-white";
         | 
| 16 21 | 
             
            }
         | 
| 17 22 |  | 
| 18 23 | 
             
            /**
         | 
| @@ -4,7 +4,6 @@ examples: | |
| 4 4 | 
             
              - bar_graph_default: Default
         | 
| 5 5 | 
             
              - bar_graph_legend: Legend
         | 
| 6 6 | 
             
              - bar_graph_legend_position: Legend Position
         | 
| 7 | 
            -
              - bar_graph_legend_non_clickable: Legend Non Clickable
         | 
| 8 7 | 
             
              - bar_graph_height: Height
         | 
| 9 8 | 
             
              - bar_graph_spline: Spline
         | 
| 10 9 | 
             
              - bar_graph_colors: Color Overrides
         | 
| @@ -65,6 +65,7 @@ const CircleIconButton = (props: CircleIconButtonProps): React.ReactElement => { | |
| 65 65 | 
             
                    id={id}
         | 
| 66 66 | 
             
                >
         | 
| 67 67 | 
             
                  <Button
         | 
| 68 | 
            +
                      aria={aria}
         | 
| 68 69 | 
             
                      dark={dark}
         | 
| 69 70 | 
             
                      disabled={disabled}
         | 
| 70 71 | 
             
                      htmlType={type}
         | 
| @@ -78,6 +79,7 @@ const CircleIconButton = (props: CircleIconButtonProps): React.ReactElement => { | |
| 78 79 | 
             
                  >
         | 
| 79 80 | 
             
                    <Icon
         | 
| 80 81 | 
             
                        fixedWidth
         | 
| 82 | 
            +
                        htmlOptions={{'aria-hidden': true}}
         | 
| 81 83 | 
             
                        icon={icon}
         | 
| 82 84 | 
             
                    />
         | 
| 83 85 | 
             
                  </Button>
         | 
| @@ -17,7 +17,6 @@ const contactTypeMap: { [key: string]: string } = { | |
| 17 17 | 
             
              'work': 'phone-office',
         | 
| 18 18 | 
             
              'work-cell': 'phone-laptop',
         | 
| 19 19 | 
             
              'wrong-phone': 'phone-slash',
         | 
| 20 | 
            -
              'international': 'globe',
         | 
| 21 20 | 
             
            }
         | 
| 22 21 |  | 
| 23 22 | 
             
            const envelopeIcon = getAllIcons()["envelope"].icon as unknown as { [key: string]: SVGElement }
         | 
| @@ -25,10 +24,6 @@ const envelopeIcon = getAllIcons()["envelope"].icon as unknown as { [key: string | |
| 25 24 | 
             
            const formatContact = (contactString: string, contactType: string) => {
         | 
| 26 25 | 
             
              if (contactType === 'email') return contactString
         | 
| 27 26 |  | 
| 28 | 
            -
              // International phone numbers are unformatted
         | 
| 29 | 
            -
              if (contactType === 'international') return contactString
         | 
| 30 | 
            -
              
         | 
| 31 | 
            -
              // Format US numbers
         | 
| 32 27 | 
             
              const cleaned = contactString.replace(/\D/g, '')
         | 
| 33 28 | 
             
              const phoneNumber = cleaned.match(/^(1|)?(\d{3})(\d{3})(\d{4})$/)
         | 
| 34 29 |  | 
| @@ -29,8 +29,6 @@ module Playbook | |
| 29 29 | 
             
                      "phone-slash"
         | 
| 30 30 | 
             
                    when "extension"
         | 
| 31 31 | 
             
                      "phone-plus"
         | 
| 32 | 
            -
                    when "international"
         | 
| 33 | 
            -
                      "globe"
         | 
| 34 32 | 
             
                    else # "unknown" || "other"
         | 
| 35 33 | 
             
                      "phone"
         | 
| 36 34 | 
             
                    end
         | 
| @@ -41,8 +39,6 @@ module Playbook | |
| 41 39 | 
             
                      contact_value
         | 
| 42 40 | 
             
                    elsif contact_type == "extension" && contact_value.match(/^\d{4}$/)
         | 
| 43 41 | 
             
                      contact_value
         | 
| 44 | 
            -
                    elsif contact_type == "international"
         | 
| 45 | 
            -
                      contact_value
         | 
| 46 42 | 
             
                    else
         | 
| 47 43 | 
             
                      number_to_phone(formatted_value, area_code: true)
         | 
| 48 44 | 
             
                    end
         | 
| @@ -66,12 +66,6 @@ test('returns correct icon', () => { | |
| 66 66 | 
             
                      contactValue="1234"
         | 
| 67 67 | 
             
                      data={{ testid: 'test-extension' }}
         | 
| 68 68 | 
             
                  />
         | 
| 69 | 
            -
                  <Contact
         | 
| 70 | 
            -
                      contactDetail="International"
         | 
| 71 | 
            -
                      contactType="international"
         | 
| 72 | 
            -
                      contactValue="+44 20 7946 0958"
         | 
| 73 | 
            -
                      data={{ testid: 'test-international' }}
         | 
| 74 | 
            -
                  />
         | 
| 75 69 | 
             
                  <Contact
         | 
| 76 70 | 
             
                      contactDetail=""
         | 
| 77 71 | 
             
                      contactType=""
         | 
| @@ -89,11 +83,10 @@ test('returns correct icon', () => { | |
| 89 83 | 
             
              expect(screen.getByTestId('test-wrong-phone').querySelector('.pb_custom_icon')).toBeInTheDocument()
         | 
| 90 84 | 
             
              expect(screen.getByTestId('test-wrong-type').querySelector('.pb_custom_icon')).toBeInTheDocument()
         | 
| 91 85 | 
             
              expect(screen.getByTestId('test-extension').querySelector('.pb_custom_icon')).toBeInTheDocument()
         | 
| 92 | 
            -
              expect(screen.getByTestId('test-international').querySelector('.pb_custom_icon')).toBeInTheDocument()
         | 
| 93 86 | 
             
              expect(screen.getByTestId('test-empty').querySelector('.pb_custom_icon')).toBeInTheDocument()
         | 
| 94 87 | 
             
            })
         | 
| 95 88 |  | 
| 96 | 
            -
            test("not compliant values return null in  | 
| 89 | 
            +
            test("not compliant values return null in phone related contact types", () => {
         | 
| 97 90 | 
             
              const notCompliantValues = [
         | 
| 98 91 | 
             
                "349-185-998223",
         | 
| 99 92 | 
             
                "349-1858",
         | 
| @@ -136,16 +129,3 @@ test("not compliant values return null in US phone related contact types", () => | |
| 136 129 | 
             
                )
         | 
| 137 130 | 
             
              })
         | 
| 138 131 | 
             
            })
         | 
| 139 | 
            -
             | 
| 140 | 
            -
            test('international contact type preserves original format', () => {
         | 
| 141 | 
            -
              render(
         | 
| 142 | 
            -
                <Contact
         | 
| 143 | 
            -
                    contactType="international"
         | 
| 144 | 
            -
                    contactValue="+44 20 7946 0958"
         | 
| 145 | 
            -
                    data={{ testid: 'test-international-format' }}
         | 
| 146 | 
            -
                />
         | 
| 147 | 
            -
              )
         | 
| 148 | 
            -
             | 
| 149 | 
            -
              const kit = screen.getByTestId('test-international-format')
         | 
| 150 | 
            -
              expect(kit).toHaveTextContent('+44 20 7946 0958')
         | 
| 151 | 
            -
            })
         | 
| @@ -13,7 +13,7 @@ | |
| 13 13 | 
             
            }) %>
         | 
| 14 14 |  | 
| 15 15 | 
             
            <%= pb_rails("contact", props: {
         | 
| 16 | 
            -
              contact_type: " | 
| 16 | 
            +
              contact_type: "wrong number",
         | 
| 17 17 | 
             
              contact_value: "3245627482",
         | 
| 18 18 | 
             
            }) %>
         | 
| 19 19 |  | 
| @@ -21,18 +21,3 @@ | |
| 21 21 | 
             
              contact_type: "work-cell",
         | 
| 22 22 | 
             
              contact_value: "349-185-9988",
         | 
| 23 23 | 
             
            }) %>
         | 
| 24 | 
            -
             | 
| 25 | 
            -
            <%= pb_rails("contact", props: {
         | 
| 26 | 
            -
              contact_type: "wrong-phone",
         | 
| 27 | 
            -
              contact_value: "2124396666",
         | 
| 28 | 
            -
            }) %>
         | 
| 29 | 
            -
             | 
| 30 | 
            -
            <%= pb_rails("contact", props: {
         | 
| 31 | 
            -
              contact_type: "extension",
         | 
| 32 | 
            -
              contact_value: "1233",
         | 
| 33 | 
            -
            }) %>
         | 
| 34 | 
            -
             | 
| 35 | 
            -
            <%= pb_rails("contact", props: {
         | 
| 36 | 
            -
              contact_type: "international",
         | 
| 37 | 
            -
              contact_value: "+44 7700 900461",
         | 
| 38 | 
            -
            }) %>
         | 
| @@ -28,21 +28,6 @@ const ContactDefault = (props) => { | |
| 28 28 | 
             
                      contactValue="3245627482"
         | 
| 29 29 | 
             
                      {...props}
         | 
| 30 30 | 
             
                  />
         | 
| 31 | 
            -
                  <Contact
         | 
| 32 | 
            -
                      contactType="wrong-phone"
         | 
| 33 | 
            -
                      contactValue="2124396666"
         | 
| 34 | 
            -
                      {...props}
         | 
| 35 | 
            -
                  />
         | 
| 36 | 
            -
                  <Contact
         | 
| 37 | 
            -
                      contactType='extension'
         | 
| 38 | 
            -
                      contactValue="1234"
         | 
| 39 | 
            -
                      {...props}
         | 
| 40 | 
            -
                  />
         | 
| 41 | 
            -
                  <Contact
         | 
| 42 | 
            -
                      contactType="international"
         | 
| 43 | 
            -
                      contactValue="+44 7700 900461"
         | 
| 44 | 
            -
                      {...props}
         | 
| 45 | 
            -
                  />
         | 
| 46 31 | 
             
                </div>
         | 
| 47 32 | 
             
              )
         | 
| 48 33 | 
             
            }
         | 
| @@ -210,10 +210,12 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => { | |
| 210 210 | 
             
                      className="input_wrapper"
         | 
| 211 211 | 
             
                  >
         | 
| 212 212 |  | 
| 213 | 
            -
                     | 
| 214 | 
            -
             | 
| 215 | 
            -
             | 
| 216 | 
            -
             | 
| 213 | 
            +
                    {!hideLabel && (
         | 
| 214 | 
            +
                      <Caption
         | 
| 215 | 
            +
                          className="pb_date_picker_kit_label"
         | 
| 216 | 
            +
                          text={label}
         | 
| 217 | 
            +
                      />
         | 
| 218 | 
            +
                    )}
         | 
| 217 219 | 
             
                      <>
         | 
| 218 220 | 
             
                        <div className="date_picker_input_wrapper">
         | 
| 219 221 | 
             
                          <input
         | 
| @@ -89,6 +89,48 @@ const datePickerHelper = (config: DatePickerConfig, scrollContainer: string | HT | |
| 89 89 | 
             
                }
         | 
| 90 90 | 
             
              }
         | 
| 91 91 |  | 
| 92 | 
            +
              // Helper function to get min/max years based on yearRange. If minDate/maxDate provided, grab year from those values
         | 
| 93 | 
            +
              const getMinMaxYears = () => {
         | 
| 94 | 
            +
                const [minYear, maxYear] = yearRange;
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                const extractYear = (dateOption: typeof minDate | typeof maxDate): number | null => {
         | 
| 97 | 
            +
                  if (!dateOption) return null;
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                  // If it's already a number, assume it's a year
         | 
| 100 | 
            +
                  if (typeof dateOption === 'number') {
         | 
| 101 | 
            +
                    return dateOption;
         | 
| 102 | 
            +
                  }
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                  // If it's a string, extract year with regex
         | 
| 105 | 
            +
                  if (typeof dateOption === 'string') {
         | 
| 106 | 
            +
                    const match = dateOption.match(/\b(19|20)\d{2}\b/);
         | 
| 107 | 
            +
                    return match ? parseInt(match[0], 10) : null;
         | 
| 108 | 
            +
                  }
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                  // If it's a Date object, get the year directly
         | 
| 111 | 
            +
                  if (dateOption instanceof Date) {
         | 
| 112 | 
            +
                    return dateOption.getFullYear();
         | 
| 113 | 
            +
                  }
         | 
| 114 | 
            +
             | 
| 115 | 
            +
                  return null;
         | 
| 116 | 
            +
                };
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                const setMinYear = minDate ? (extractYear(minDate) ?? minYear) : minYear;
         | 
| 119 | 
            +
                const setMaxYear = maxDate ? (extractYear(maxDate) ?? maxYear) : maxYear;
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                return { setMinYear, setMaxYear };
         | 
| 122 | 
            +
              };
         | 
| 123 | 
            +
             | 
| 124 | 
            +
              const { setMinYear, setMaxYear } = getMinMaxYears()
         | 
| 125 | 
            +
             | 
| 126 | 
            +
              // Helper function to get min/max dates based on yearRange
         | 
| 127 | 
            +
              const getMinMaxDates = () => {
         | 
| 128 | 
            +
                const setMinDate = minDate || `01/01/${setMinYear}`
         | 
| 129 | 
            +
                const setMaxDate = maxDate || `12/31/${setMaxYear}`
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                return { setMinDate, setMaxDate }
         | 
| 132 | 
            +
              }
         | 
| 133 | 
            +
             | 
| 92 134 | 
             
              const disabledWeekDays = () => {
         | 
| 93 135 | 
             
                return (
         | 
| 94 136 | 
             
                  [
         | 
| @@ -201,6 +243,8 @@ const datePickerHelper = (config: DatePickerConfig, scrollContainer: string | HT | |
| 201 243 | 
             
              // |             Flatpickr initializer w/ config             |
         | 
| 202 244 | 
             
              // ===========================================================
         | 
| 203 245 |  | 
| 246 | 
            +
              const { setMinDate, setMaxDate } = getMinMaxDates()
         | 
| 247 | 
            +
             | 
| 204 248 | 
             
              flatpickr(`#${pickerId}`, {
         | 
| 205 249 | 
             
                allowInput,
         | 
| 206 250 | 
             
                closeOnSelect,
         | 
| @@ -212,8 +256,8 @@ const datePickerHelper = (config: DatePickerConfig, scrollContainer: string | HT | |
| 212 256 | 
             
                locale: {
         | 
| 213 257 | 
             
                  rangeSeparator: ' to '
         | 
| 214 258 | 
             
                },
         | 
| 215 | 
            -
                maxDate,
         | 
| 216 | 
            -
                minDate,
         | 
| 259 | 
            +
                maxDate: setMaxDate,
         | 
| 260 | 
            +
                minDate: setMinDate,
         | 
| 217 261 | 
             
                mode,
         | 
| 218 262 | 
             
                nextArrow: '<i class="far fa-angle-right"></i>',
         | 
| 219 263 | 
             
                onOpen: [() => {
         | 
| @@ -250,7 +294,7 @@ const datePickerHelper = (config: DatePickerConfig, scrollContainer: string | HT | |
| 250 294 |  | 
| 251 295 | 
             
              // create html option tags for desired years
         | 
| 252 296 | 
             
              let years = ''
         | 
| 253 | 
            -
              for (let year =  | 
| 297 | 
            +
              for (let year = setMaxYear; year >= setMinYear; year--) {
         | 
| 254 298 | 
             
                years += `<option value="${year}">${year}</option>`
         | 
| 255 299 | 
             
              }
         | 
| 256 300 |  | 
| @@ -323,7 +367,7 @@ const datePickerHelper = (config: DatePickerConfig, scrollContainer: string | HT | |
| 323 367 | 
             
              }
         | 
| 324 368 | 
             
            // === End of Automatic Sync Logic ===
         | 
| 325 369 |  | 
| 326 | 
            -
             | 
| 370 | 
            +
             | 
| 327 371 | 
             
              // Adding dropdown icons to year and month select
         | 
| 328 372 | 
             
              dropdown.insertAdjacentHTML('afterend', `<i class="year-dropdown-icon">${angleDown}</i>`)
         | 
| 329 373 | 
             
              if (picker.monthElements[0].parentElement) {
         | 
| @@ -12,10 +12,14 @@ export const CloseIcon = (props: CloseIconProps): React.ReactElement => { | |
| 12 12 | 
             
              const timesIcon = getAllIcons()["times"]
         | 
| 13 13 | 
             
              return (
         | 
| 14 14 | 
             
                <div
         | 
| 15 | 
            +
                    aria-label="Close Dialog"
         | 
| 15 16 | 
             
                    className="pb_dialog_close_icon"
         | 
| 16 | 
            -
                    onClick={onClose}
         | 
| 17 | 
            +
                    onClick={onClose}          
         | 
| 18 | 
            +
                    role="button"    
         | 
| 19 | 
            +
                    tabIndex={0}
         | 
| 17 20 | 
             
                >
         | 
| 18 21 | 
             
                  <Icon
         | 
| 22 | 
            +
                      aria={{ "hidden": true }} 
         | 
| 19 23 | 
             
                      className="svg-inline--fa"
         | 
| 20 24 | 
             
                      customIcon={timesIcon.icon as unknown as { [key: string]: SVGElement }}
         | 
| 21 25 | 
             
                      fixedWidth
         | 
| @@ -73,8 +73,8 @@ const Dialog = (props: DialogProps): React.ReactElement => { | |
| 73 73 | 
             
              const ariaProps = buildAriaProps(aria);
         | 
| 74 74 | 
             
               const dataProps = buildDataProps(data)
         | 
| 75 75 | 
             
               const htmlProps = buildHtmlProps(htmlOptions);
         | 
| 76 | 
            -
              const  | 
| 77 | 
            -
                base: classnames("pb_dialog", buildCss("pb_dialog", size, placement)),
         | 
| 76 | 
            +
              const classes = {
         | 
| 77 | 
            +
                base: classnames("pb_dialog", buildCss("pb_dialog", size, placement), globalProps(props), className),
         | 
| 78 78 | 
             
                afterOpen: "pb_dialog_after_open",
         | 
| 79 79 | 
             
                beforeClose: "pb_dialog_before_close",
         | 
| 80 80 | 
             
              };
         | 
| @@ -93,10 +93,8 @@ const Dialog = (props: DialogProps): React.ReactElement => { | |
| 93 93 |  | 
| 94 94 | 
             
              const dynamicInlineProps = globalInlineProps(props); 
         | 
| 95 95 |  | 
| 96 | 
            -
              const  | 
| 96 | 
            +
              const wrapperClasses = classnames(
         | 
| 97 97 | 
             
                buildCss("pb_dialog_wrapper"),
         | 
| 98 | 
            -
                globalProps(props),
         | 
| 99 | 
            -
                className
         | 
| 100 98 | 
             
              );
         | 
| 101 99 |  | 
| 102 100 | 
             
              const [triggerOpened, setTriggerOpened] = useState(false),
         | 
| @@ -173,13 +171,13 @@ const Dialog = (props: DialogProps): React.ReactElement => { | |
| 173 171 | 
             
                      {...ariaProps} 
         | 
| 174 172 | 
             
                      {...dataProps}
         | 
| 175 173 | 
             
                      {...htmlProps} 
         | 
| 176 | 
            -
                      className={ | 
| 174 | 
            +
                      className={wrapperClasses}
         | 
| 177 175 | 
             
                  >
         | 
| 178 176 | 
             
                    <Modal
         | 
| 179 177 | 
             
                        ariaHideApp={false}
         | 
| 180 | 
            -
                        className={ | 
| 178 | 
            +
                        className={classes}
         | 
| 181 179 | 
             
                        closeTimeoutMS={200}
         | 
| 182 | 
            -
                        contentLabel=" | 
| 180 | 
            +
                        contentLabel="Dialog"
         | 
| 183 181 | 
             
                        id={id}
         | 
| 184 182 | 
             
                        isOpen={modalIsOpened}
         | 
| 185 183 | 
             
                        onRequestClose={onClose}
         | 
| @@ -12,7 +12,7 @@ | |
| 12 12 | 
             
                    data-cancel-button-id="<%= object.cancel_button_id %>"
         | 
| 13 13 | 
             
                <% end %>
         | 
| 14 14 | 
             
            >
         | 
| 15 | 
            -
                <%= pb_content_tag(:dialog) do %>
         | 
| 15 | 
            +
                <%= pb_content_tag(:dialog, role: "dialog", "aria-modal": "true", "aria-label": "Dialog") do %>
         | 
| 16 16 | 
             
                        <% if object.status === "" && object.title %>
         | 
| 17 17 | 
             
                            <%= pb_rails("dialog/dialog_header", props: { title: object.title, id: object.id }) %>
         | 
| 18 18 | 
             
                        <% end %>
         | 
| @@ -2,8 +2,8 @@ | |
| 2 2 | 
             
                    <%= pb_rails("flex", props: {classname:object.classname, spacing:"between", padding:"sm", align:"center"}) do %>
         | 
| 3 3 | 
             
                        <%= content.presence || object.title %>
         | 
| 4 4 |  | 
| 5 | 
            -
                        <button class="dialog-button-class pb_dialog_close_icon" type="button" data-close-dialog= <%= object.id %> >
         | 
| 6 | 
            -
                            <%= pb_rails("icon", props: { custom_icon: Playbook::Engine::root.join(times_icon) }) %>
         | 
| 5 | 
            +
                        <button class="dialog-button-class pb_dialog_close_icon" type="button" data-close-dialog= <%= object.id %> aria-label="Close Dialog" >
         | 
| 6 | 
            +
                            <%= pb_rails("icon", props: { custom_icon: Playbook::Engine::root.join(times_icon), aria: { hidden: true } }) %>
         | 
| 7 7 | 
             
                        </button>
         | 
| 8 8 | 
             
                    <% end %>
         | 
| 9 9 | 
             
                    <%= pb_rails("section_separator") %>
         | 
| @@ -35,6 +35,7 @@ type FixedConfirmationToastProps = { | |
| 35 35 |  | 
| 36 36 | 
             
            const FixedConfirmationToast = (props: FixedConfirmationToastProps): React.ReactElement => {
         | 
| 37 37 | 
             
              const [showToast, toggleToast] = useState(true);
         | 
| 38 | 
            +
             | 
| 38 39 | 
             
              const {
         | 
| 39 40 | 
             
                autoClose = 0,
         | 
| 40 41 | 
             
                children,
         | 
| @@ -87,8 +88,15 @@ const FixedConfirmationToast = (props: FixedConfirmationToastProps): React.React | |
| 87 88 | 
             
                <>
         | 
| 88 89 | 
             
                  {showToast && (
         | 
| 89 90 | 
             
                    <div
         | 
| 91 | 
            +
                        aria-atomic="true"
         | 
| 92 | 
            +
                        aria-live="polite"
         | 
| 90 93 | 
             
                        className={css}
         | 
| 91 94 | 
             
                        onClick={handleClick}
         | 
| 95 | 
            +
                        onKeyDown={(e) => {
         | 
| 96 | 
            +
                          if (e.key === "Enter" || e.key === " ") handleClick();
         | 
| 97 | 
            +
                        }}
         | 
| 98 | 
            +
                        role="status"
         | 
| 99 | 
            +
                        tabIndex={0}
         | 
| 92 100 | 
             
                        {...htmlProps}
         | 
| 93 101 | 
             
                    >
         | 
| 94 102 | 
             
                      {returnedIcon && icon !== "none" && (
         | 
| @@ -111,6 +119,7 @@ const FixedConfirmationToast = (props: FixedConfirmationToastProps): React.React | |
| 111 119 |  | 
| 112 120 | 
             
                      {closeable && (
         | 
| 113 121 | 
             
                        <Icon
         | 
| 122 | 
            +
                            aria={{ "label": "Close Toast" }}
         | 
| 114 123 | 
             
                            className="pb_icon"
         | 
| 115 124 | 
             
                            cursor="pointer"
         | 
| 116 125 | 
             
                            fixedWidth={false}
         | 
| @@ -1,6 +1,6 @@ | |
| 1 | 
            -
            <%= pb_content_tag do %>
         | 
| 1 | 
            +
            <%= pb_content_tag(:div, "aria-atomic": "true", "aria-live": "polite", role: "status", tabindex: 0, onkeydown: "if(event.key==='Enter'||event.key===' '){ this.remove(); }" ) do %>
         | 
| 2 2 | 
             
                <% if object.icon_value && object.icon_value != "none" %>
         | 
| 3 | 
            -
                <%= pb_rails("icon", props: { icon: object.icon_value, classname: "pb_icon", fixed_width: true }) %>
         | 
| 3 | 
            +
                <%= pb_rails("icon", props: { icon: object.icon_value, classname: "pb_icon", fixed_width: true, aria: { "aria-label": "#{object.icon_value} icon" } }) %>
         | 
| 4 4 | 
             
                <% end %>
         | 
| 5 5 | 
             
                <% if content %>
         | 
| 6 6 | 
             
                    <%= content %>
         | 
| @@ -8,5 +8,5 @@ | |
| 8 8 | 
             
                    <%= pb_rails("title", props: { text: object.text, size: 4, flex: "1", classname: "pb_fixed_confirmation_toast_text" }) %>
         | 
| 9 9 | 
             
                <% end %>
         | 
| 10 10 |  | 
| 11 | 
            -
                <%= pb_rails("icon", props: { icon: "times", classname: "pb_icon", cursor: "pointer", fixed_width: true }) if object.closeable %>
         | 
| 11 | 
            +
                <%= pb_rails("icon", props: { icon: "times", classname: "pb_icon", cursor: "pointer", fixed_width: true, aria: { "aria-label": "Close Toast" } }) if object.closeable %>
         | 
| 12 12 | 
             
            <% end %>
         | 
| @@ -91,6 +91,7 @@ | |
| 91 91 | 
             
            <%= pb_form_with(scope: :example, url: "", method: :get) do |form| %>
         | 
| 92 92 | 
             
              <%= form.typeahead :example_typeahead, props: { data: { typeahead_example1: true, user: {} }, label: true, placeholder: "Search for a user" } %>
         | 
| 93 93 | 
             
              <%= form.text_field :example_text_field, props: { label: true } %>
         | 
| 94 | 
            +
              <%= form.text_field :example_text_field_2, props: { label: "Text Field Custom Label" } %>
         | 
| 94 95 | 
             
              <%= form.phone_number_field :example_phone_number_field, props: { label: "Example phone field", hidden_inputs: true } %>
         | 
| 95 96 | 
             
              <%= form.email_field :example_email_field, props: { label: true } %>
         | 
| 96 97 | 
             
              <%= form.number_field :example_number_field, props: { label: true } %>
         | 
| @@ -20,7 +20,7 @@ export type IconSizes = "lg" | |
| 20 20 | 
             
            | ""
         | 
| 21 21 |  | 
| 22 22 | 
             
            type IconProps = {
         | 
| 23 | 
            -
              aria?: {[key: string]: string} | 
| 23 | 
            +
              aria?: { [key: string]: string | boolean }
         | 
| 24 24 | 
             
              border?: string,
         | 
| 25 25 | 
             
              className?: string,
         | 
| 26 26 | 
             
              color?: string,
         | 
| @@ -211,7 +211,15 @@ const Icon = (props: IconProps) => { | |
| 211 211 | 
             
              )
         | 
| 212 212 |  | 
| 213 213 | 
             
              aria.label ? null : aria.label = `${icon} icon`
         | 
| 214 | 
            -
             | 
| 214 | 
            +
             | 
| 215 | 
            +
              const normalizedAria: { [key: string]: string } = Object.fromEntries(
         | 
| 216 | 
            +
                Object.entries(aria).map(([key, value]) => [
         | 
| 217 | 
            +
                  key,
         | 
| 218 | 
            +
                  typeof value === "boolean" ? String(value) : value,
         | 
| 219 | 
            +
                ])
         | 
| 220 | 
            +
              )
         | 
| 221 | 
            +
              
         | 
| 222 | 
            +
              const ariaProps = buildAriaProps(normalizedAria)
         | 
| 215 223 | 
             
              const dataProps: {[key: string]: any} = buildDataProps(data)
         | 
| 216 224 | 
             
              const htmlProps = buildHtmlProps(htmlOptions)
         | 
| 217 225 |  | 
| @@ -222,6 +230,7 @@ const Icon = (props: IconProps) => { | |
| 222 230 | 
             
                    <>
         | 
| 223 231 | 
             
                      {
         | 
| 224 232 | 
             
                        React.cloneElement(iconElement || customIcon, {
         | 
| 233 | 
            +
                          ...ariaProps,
         | 
| 225 234 | 
             
                          ...dataProps,
         | 
| 226 235 | 
             
                          ...htmlProps,
         | 
| 227 236 | 
             
                          className: classes,
         | 
| @@ -237,6 +246,7 @@ const Icon = (props: IconProps) => { | |
| 237 246 | 
             
                  return (
         | 
| 238 247 | 
             
                    <>
         | 
| 239 248 | 
             
                      <span
         | 
| 249 | 
            +
                          {...ariaProps}
         | 
| 240 250 | 
             
                          {...dataProps}
         | 
| 241 251 | 
             
                          {...htmlProps}
         | 
| 242 252 | 
             
                          className={classesEmoji}
         | 
| @@ -250,6 +260,7 @@ const Icon = (props: IconProps) => { | |
| 250 260 | 
             
                  return (
         | 
| 251 261 | 
             
                    <>
         | 
| 252 262 | 
             
                      <i
         | 
| 263 | 
            +
                          {...ariaProps}
         | 
| 253 264 | 
             
                          {...dataProps}
         | 
| 254 265 | 
             
                          {...htmlProps}
         | 
| 255 266 | 
             
                          className={classes}
         |