playbook_ui 15.0.0.pre.alpha.PLAY2426textfieldaccessibility10330 → 15.0.0.pre.alpha.PLAY236510413
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 +3 -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_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_form/docs/_form_form_with.html.erb +0 -1
- 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_circle_chart/_pb_circle_chart.scss +3 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/_pb_circle_chart.tsx +62 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_block_content.html.erb +31 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_block_content.jsx +81 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_color_overrides.html.erb +25 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_color_overrides.jsx +40 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_color_overrides.md +5 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_custom_tooltip.html.erb +27 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_custom_tooltip.jsx +39 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_custom_tooltip.md +5 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_data_legend_position.html.erb +93 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_data_legend_position.jsx +131 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_data_legend_position.md +14 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_data_with_labels.html.erb +42 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_data_with_labels.jsx +58 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_data_with_legend.html.erb +24 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_data_with_legend.jsx +38 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_default.html.erb +22 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_default.jsx +33 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_inner_sizes.html.erb +118 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_inner_sizes.jsx +144 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_live_data.jsx +60 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_rounded.html.erb +24 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_rounded.jsx +42 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_with_title.html.erb +38 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_with_title.jsx +52 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/example.yml +29 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/index.js +11 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/pbCircleChartTheme.ts +88 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/pb_circle_chart.html.erb +1 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/pb_circle_chart.rb +28 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/pb_circle_chart.test.jsx +51 -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-B5Dr0Huy.js} +1 -1
- data/dist/chunks/_typeahead-GbjDoSSQ.js +6 -0
- data/dist/chunks/_weekday_stacked-DjQv3Sok.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 +6 -0
- data/dist/playbook-doc.js +2 -2
- 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 +1 -9
- data/lib/playbook/version.rb +1 -1
- metadata +44 -8
- 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-C3QAjEFv.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: c2160795c8e7884b53baf24a0caf41501a31484abfc2558b1cda1eb92c78e156
         | 
| 4 | 
            +
              data.tar.gz: 0bd79d78760dc7617e1ab5a232a703ebb5c20fda537b2bcc8e45d0f69dc36260
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: '079e5354e33efd02c223d772f6ea1a0d4d16f1ac7631231e2ca5a841acc7178ab7e89f3475e6572999e6ed52a35288d3bffce23770d0321392ed532de27468a8'
         | 
| 7 | 
            +
              data.tar.gz: 54c89d7d1eeae1d607b9df1a03aa4820dce84333731b67421b57be5e935b6170953929f86c4ebe8cf79b2029bc57b5d8bebf6ce1d0a92981d460f948b2eea5b5
         | 
| @@ -1,5 +1,6 @@ | |
| 1 1 |  | 
| 2 2 |  | 
| 3 | 
            +
             | 
| 3 4 | 
             
            @import 'pb_advanced_table/advanced_table';
         | 
| 4 5 | 
             
            @import 'pb_avatar/avatar';
         | 
| 5 6 | 
             
            @import 'pb_background/background';
         | 
| @@ -32,6 +33,7 @@ | |
| 32 33 | 
             
            @import 'pb_distribution_bar/distribution_bar';
         | 
| 33 34 | 
             
            @import 'pb_draggable/draggable';
         | 
| 34 35 | 
             
            @import 'pb_dropdown/dropdown';
         | 
| 36 | 
            +
            @import 'pb_empty_state/empty_state';
         | 
| 35 37 | 
             
            @import 'pb_file_upload/file_upload';
         | 
| 36 38 | 
             
            @import 'pb_filter/filter';
         | 
| 37 39 | 
             
            @import 'pb_fixed_confirmation_toast/fixed_confirmation_toast';
         | 
| @@ -107,7 +109,7 @@ | |
| 107 109 | 
             
            @import 'pb_user/user';
         | 
| 108 110 | 
             
            @import 'pb_user_badge/user_badge';
         | 
| 109 111 | 
             
            @import 'pb_weekday_stacked/weekday_stacked';
         | 
| 110 | 
            -
            @import ' | 
| 112 | 
            +
            @import 'pb_pb_circle_chart/pb_circle_chart';
         | 
| 111 113 | 
             
            @import 'utilities/mixins';
         | 
| 112 114 | 
             
            @import 'utilities/spacing';
         | 
| 113 115 | 
             
            @import 'utilities/cursor';
         | 
| @@ -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>
         | 
| @@ -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") %>
         | 
| @@ -91,7 +91,6 @@ | |
| 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" } %>
         | 
| 95 94 | 
             
              <%= form.phone_number_field :example_phone_number_field, props: { label: "Example phone field", hidden_inputs: true } %>
         | 
| 96 95 | 
             
              <%= form.email_field :example_email_field, props: { label: true } %>
         | 
| 97 96 | 
             
              <%= 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}
         | 
| @@ -110,12 +110,20 @@ module Playbook | |
| 110 110 | 
             
                    svg["class"] = %w[pb_custom_icon svg-inline--fa].concat([object.custom_icon_classname]).join(" ")
         | 
| 111 111 | 
             
                    svg["id"] = object.id
         | 
| 112 112 | 
             
                    svg["data"] = object.data
         | 
| 113 | 
            -
                    svg["aria"] = object.aria
         | 
| 114 113 | 
             
                    svg["height"] = "auto"
         | 
| 115 114 | 
             
                    svg["width"] = "auto"
         | 
| 116 115 | 
             
                    svg["tabindex"] = object.tabindex
         | 
| 117 116 | 
             
                    fill_color = object.color || "currentColor"
         | 
| 118 117 | 
             
                    doc.at_css("path")["fill"] = fill_color
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                    if object.aria.present?
         | 
| 120 | 
            +
                      object.aria.each do |key, value|
         | 
| 121 | 
            +
                        k = key.to_s
         | 
| 122 | 
            +
                        attr = k.start_with?("aria-") ? k : "aria-#{k.tr('_', '-')}"
         | 
| 123 | 
            +
                        svg[attr] = value
         | 
| 124 | 
            +
                      end
         | 
| 125 | 
            +
                    end
         | 
| 126 | 
            +
             | 
| 119 127 | 
             
                    raw doc
         | 
| 120 128 | 
             
                  rescue OpenURI::HTTPError, StandardError
         | 
| 121 129 | 
             
                    # Handle any exceptions and return an empty string
         | 
| @@ -16,6 +16,7 @@ type LoadingInlineProps = { | |
| 16 16 | 
             
              htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
         | 
| 17 17 | 
             
              id?: string,
         | 
| 18 18 | 
             
              text?: string,
         | 
| 19 | 
            +
              variant?: "dotted" | "solid" ,
         | 
| 19 20 | 
             
            }
         | 
| 20 21 |  | 
| 21 22 | 
             
            const LoadingInline = (props: LoadingInlineProps) => {
         | 
| @@ -28,6 +29,7 @@ const LoadingInline = (props: LoadingInlineProps) => { | |
| 28 29 | 
             
                htmlOptions = {},
         | 
| 29 30 | 
             
                id,
         | 
| 30 31 | 
             
                text = ' Loading',
         | 
| 32 | 
            +
                variant = 'dotted',
         | 
| 31 33 | 
             
              } = props
         | 
| 32 34 |  | 
| 33 35 | 
             
              const ariaProps = buildAriaProps(aria)
         | 
| @@ -54,7 +56,7 @@ const LoadingInline = (props: LoadingInlineProps) => { | |
| 54 56 | 
             
                    <Icon
         | 
| 55 57 | 
             
                        aria={{ label: 'loading icon' }}
         | 
| 56 58 | 
             
                        fixedWidth
         | 
| 57 | 
            -
                        icon= | 
| 59 | 
            +
                        icon={variant === 'dotted' ? 'spinner' : variant === 'solid' ? 'spinner-solid' : undefined}
         | 
| 58 60 | 
             
                        pulse
         | 
| 59 61 | 
             
                    />
         | 
| 60 62 | 
             
                    {text}
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            import React from 'react'
         | 
| 2 | 
            +
            import { LoadingInline } from 'playbook-ui'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            const LoadingInlineVariant = (props) => {
         | 
| 5 | 
            +
              return (
         | 
| 6 | 
            +
                <div>
         | 
| 7 | 
            +
                  <LoadingInline 
         | 
| 8 | 
            +
                      text=" Dotted Spinner" 
         | 
| 9 | 
            +
                      variant="dotted" 
         | 
| 10 | 
            +
                      {...props}
         | 
| 11 | 
            +
                  />
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  <br />
         | 
| 14 | 
            +
              
         | 
| 15 | 
            +
                  <LoadingInline
         | 
| 16 | 
            +
                      text=" Solid Spinner"
         | 
| 17 | 
            +
                      variant="solid"
         | 
| 18 | 
            +
                      {...props}
         | 
| 19 | 
            +
                  />
         | 
| 20 | 
            +
                </div>
         | 
| 21 | 
            +
              )
         | 
| 22 | 
            +
            }
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            export default LoadingInlineVariant
         | 
| @@ -3,9 +3,11 @@ examples: | |
| 3 3 | 
             
              rails:
         | 
| 4 4 | 
             
              - loading_inline_default: Default
         | 
| 5 5 | 
             
              - loading_inline_custom: Custom Text
         | 
| 6 | 
            +
              - loading_inline_variant: Variant
         | 
| 6 7 |  | 
| 7 8 |  | 
| 8 9 |  | 
| 9 10 | 
             
              react:
         | 
| 10 11 | 
             
              - loading_inline_default: Default
         | 
| 11 12 | 
             
              - loading_inline_custom: Custom Text
         | 
| 13 | 
            +
              - loading_inline_variant: Variant
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            <%= pb_content_tag do %>
         | 
| 2 2 |  | 
| 3 3 | 
             
              <%= pb_rails("body", props: { color: "light", dark: object.dark }) do %>
         | 
| 4 | 
            -
                <%= pb_rails("icon", props: { aria: { label: "loading icon" }, fixed_width: true, icon:  | 
| 4 | 
            +
                <%= pb_rails("icon", props: { aria: { label: "loading icon" }, fixed_width: true, icon: object.spinner_icon, pulse: true }) %> <%= object.text %>
         | 
| 5 5 | 
             
              <% end %>
         | 
| 6 6 | 
             
            <% end %>
         | 
| @@ -8,10 +8,21 @@ module Playbook | |
| 8 8 | 
             
                               default: "left"
         | 
| 9 9 | 
             
                  prop :dark, type: Playbook::Props::Boolean, default: false
         | 
| 10 10 | 
             
                  prop :text, type: Playbook::Props::String, default: "Loading"
         | 
| 11 | 
            +
                  prop :variant, type: Playbook::Props::Enum,
         | 
| 12 | 
            +
                                 values: %w[dotted solid],
         | 
| 13 | 
            +
                                 default: "dotted"
         | 
| 11 14 |  | 
| 12 15 | 
             
                  def classname
         | 
| 13 16 | 
             
                    generate_classname("pb_loading_inline_kit", align)
         | 
| 14 17 | 
             
                  end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  def spinner_icon
         | 
| 20 | 
            +
                    if variant == "dotted"
         | 
| 21 | 
            +
                      "spinner"
         | 
| 22 | 
            +
                    elsif variant == "solid"
         | 
| 23 | 
            +
                      "spinner-solid"
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
                  end
         | 
| 15 26 | 
             
                end
         | 
| 16 27 | 
             
              end
         | 
| 17 28 | 
             
            end
         | 
| @@ -0,0 +1,62 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            import React, { useMemo } from 'react'
         | 
| 3 | 
            +
            import classnames from 'classnames'
         | 
| 4 | 
            +
            import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
         | 
| 5 | 
            +
            import Highcharts from "highcharts"
         | 
| 6 | 
            +
            import HighchartsReact from "highcharts-react-official"
         | 
| 7 | 
            +
            import pbCircleGraphTheme from './pbCircleChartTheme'
         | 
| 8 | 
            +
            import { globalProps } from '../utilities/globalProps'
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            type PbCircleChartProps = {
         | 
| 11 | 
            +
              aria?: { [key: string]: string },
         | 
| 12 | 
            +
              className?: string,
         | 
| 13 | 
            +
              data?: { [key: string]: string },
         | 
| 14 | 
            +
              id?: string,
         | 
| 15 | 
            +
              htmlOptions?: { [key: string]: string | number | boolean | (() => void) };
         | 
| 16 | 
            +
              options: Record<string, unknown>
         | 
| 17 | 
            +
            }
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            const PbCircleChart = (props: PbCircleChartProps) => {
         | 
| 20 | 
            +
              const {
         | 
| 21 | 
            +
                aria = {},
         | 
| 22 | 
            +
              className,
         | 
| 23 | 
            +
              data = {},
         | 
| 24 | 
            +
              id,
         | 
| 25 | 
            +
              htmlOptions = {},
         | 
| 26 | 
            +
              options
         | 
| 27 | 
            +
              } = props
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              const ariaProps = buildAriaProps(aria)
         | 
| 30 | 
            +
              const dataProps = buildDataProps(data)
         | 
| 31 | 
            +
              const htmlProps = buildHtmlProps(htmlOptions);
         | 
| 32 | 
            +
              const classes = classnames(buildCss('pb_pb_circle_chart'), globalProps(props), className)
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              const mergedOptions = useMemo(() => {
         | 
| 35 | 
            +
                if (!options || typeof options !== "object") {
         | 
| 36 | 
            +
                  // eslint-disable-next-line no-console
         | 
| 37 | 
            +
                  console.error("❌ Invalid options passed to <PbCircleChart />", options)
         | 
| 38 | 
            +
                  return {}
         | 
| 39 | 
            +
                }
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                return Highcharts.merge({}, pbCircleGraphTheme, options)
         | 
| 42 | 
            +
              }, [options])
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              return (
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                <div>
         | 
| 47 | 
            +
                  <HighchartsReact
         | 
| 48 | 
            +
                      containerProps={{
         | 
| 49 | 
            +
                              className: classnames(globalProps, className),
         | 
| 50 | 
            +
                              id: id,
         | 
| 51 | 
            +
                              ...ariaProps,
         | 
| 52 | 
            +
                              ...dataProps,
         | 
| 53 | 
            +
                              ...htmlProps
         | 
| 54 | 
            +
                            }}
         | 
| 55 | 
            +
                      highcharts={Highcharts}
         | 
| 56 | 
            +
                      options={mergedOptions}
         | 
| 57 | 
            +
                  />
         | 
| 58 | 
            +
                </div>
         | 
| 59 | 
            +
              )
         | 
| 60 | 
            +
            }
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            export default PbCircleChart
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            <% data = [
         | 
| 2 | 
            +
                    {
         | 
| 3 | 
            +
                      name: "Waiting for Calls",
         | 
| 4 | 
            +
                      y: 41,
         | 
| 5 | 
            +
                    },
         | 
| 6 | 
            +
                    {
         | 
| 7 | 
            +
                      name: "On Call",
         | 
| 8 | 
            +
                      y: 49,
         | 
| 9 | 
            +
                    },
         | 
| 10 | 
            +
                    {
         | 
| 11 | 
            +
                      name: "After Call",
         | 
| 12 | 
            +
                      y: 10,
         | 
| 13 | 
            +
                    },
         | 
| 14 | 
            +
                  ] %>
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            <% chart_options = {
         | 
| 17 | 
            +
                series: [{
         | 
| 18 | 
            +
                  data: data,
         | 
| 19 | 
            +
                  innerSize: '100%',
         | 
| 20 | 
            +
                  borderWidth: '20',
         | 
| 21 | 
            +
                }],
         | 
| 22 | 
            +
              } %>
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            <div style="position: relative;">
         | 
| 25 | 
            +
              <%= pb_rails("pb_circle_chart", props: { options: chart_options }) %>
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              <div class="pb-circle-chart-block"
         | 
| 28 | 
            +
                   style="position: absolute; inset: 0; display: flex; justify-content: center; align-items: center; z-index: 1; text-align: center; pointer-events: none;">
         | 
| 29 | 
            +
                <%= pb_rails("title", props: { size: 1, tag: "div", text: "83" }) %>
         | 
| 30 | 
            +
              </div>
         | 
| 31 | 
            +
            </div>
         | 
| @@ -0,0 +1,81 @@ | |
| 1 | 
            +
            import React from "react";
         | 
| 2 | 
            +
            import { PbCircleChart, Title } from "playbook-ui";
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            const data= [
         | 
| 5 | 
            +
                    {
         | 
| 6 | 
            +
                      name: "Waiting for Calls",
         | 
| 7 | 
            +
                      y: 41,
         | 
| 8 | 
            +
                    },
         | 
| 9 | 
            +
                    {
         | 
| 10 | 
            +
                      name: "On Call",
         | 
| 11 | 
            +
                      y: 49,
         | 
| 12 | 
            +
                    },
         | 
| 13 | 
            +
                    {
         | 
| 14 | 
            +
                      name: "After Call",
         | 
| 15 | 
            +
                      y: 10,
         | 
| 16 | 
            +
                    },
         | 
| 17 | 
            +
                  ]
         | 
| 18 | 
            +
             | 
| 19 | 
            +
             | 
| 20 | 
            +
            const PbCircleChartBlockContent = (props) => {
         | 
| 21 | 
            +
            const chartOptions = {
         | 
| 22 | 
            +
                series: [{
         | 
| 23 | 
            +
                  data: data,
         | 
| 24 | 
            +
                  innerSize: '100%',
         | 
| 25 | 
            +
                  borderWidth: 20,
         | 
| 26 | 
            +
                  borderColor: null,
         | 
| 27 | 
            +
                }],
         | 
| 28 | 
            +
                chart: {
         | 
| 29 | 
            +
                  events: {
         | 
| 30 | 
            +
                    render: function() {
         | 
| 31 | 
            +
                      const chart = this;
         | 
| 32 | 
            +
                      const blockElement = document.querySelector('.pb-circle-chart-block');
         | 
| 33 | 
            +
                      if (blockElement) {
         | 
| 34 | 
            +
                        blockElement.style.width = chart.chartWidth + 'px';
         | 
| 35 | 
            +
                        blockElement.style.height = chart.chartHeight + 'px';
         | 
| 36 | 
            +
                      }
         | 
| 37 | 
            +
                    },
         | 
| 38 | 
            +
                    redraw: function() {
         | 
| 39 | 
            +
                      const chart = this;
         | 
| 40 | 
            +
                      const blockElement = document.querySelector('.pb-circle-chart-block');
         | 
| 41 | 
            +
                      if (blockElement) {
         | 
| 42 | 
            +
                        blockElement.style.width = chart.chartWidth + 'px';
         | 
| 43 | 
            +
                        blockElement.style.height = chart.chartHeight + 'px';
         | 
| 44 | 
            +
                      }
         | 
| 45 | 
            +
                    }
         | 
| 46 | 
            +
                  }
         | 
| 47 | 
            +
                }
         | 
| 48 | 
            +
              }
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              return (
         | 
| 51 | 
            +
                <div style={{ position: 'relative' }}>
         | 
| 52 | 
            +
                  <PbCircleChart
         | 
| 53 | 
            +
                      options={chartOptions}
         | 
| 54 | 
            +
                      {...props}
         | 
| 55 | 
            +
                  />
         | 
| 56 | 
            +
                  <div 
         | 
| 57 | 
            +
                      className="pb-circle-chart-block"
         | 
| 58 | 
            +
                      style={{
         | 
| 59 | 
            +
                        position: 'absolute',
         | 
| 60 | 
            +
                        top: 0,
         | 
| 61 | 
            +
                        left: 0,
         | 
| 62 | 
            +
                        display: 'flex',
         | 
| 63 | 
            +
                        justifyContent: 'center',
         | 
| 64 | 
            +
                        alignItems: 'center',
         | 
| 65 | 
            +
                        zIndex: 1,
         | 
| 66 | 
            +
                        textAlign: 'center',
         | 
| 67 | 
            +
                        pointerEvents: 'none'
         | 
| 68 | 
            +
                      }}
         | 
| 69 | 
            +
                  >
         | 
| 70 | 
            +
                    <Title
         | 
| 71 | 
            +
                        size={1}
         | 
| 72 | 
            +
                        tag="div"
         | 
| 73 | 
            +
                    >
         | 
| 74 | 
            +
                      {'83'}
         | 
| 75 | 
            +
                    </Title>
         | 
| 76 | 
            +
                  </div>
         | 
| 77 | 
            +
                </div>
         | 
| 78 | 
            +
              );
         | 
| 79 | 
            +
            };
         | 
| 80 | 
            +
             | 
| 81 | 
            +
            export default PbCircleChartBlockContent;
         | 
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            <% data = [
         | 
| 2 | 
            +
                    {
         | 
| 3 | 
            +
                      name: "Waiting for Calls",
         | 
| 4 | 
            +
                      y: 41,
         | 
| 5 | 
            +
                    },
         | 
| 6 | 
            +
                    {
         | 
| 7 | 
            +
                      name: "On Call",
         | 
| 8 | 
            +
                      y: 49,
         | 
| 9 | 
            +
                    },
         | 
| 10 | 
            +
                    {
         | 
| 11 | 
            +
                      name: "After Call",
         | 
| 12 | 
            +
                      y: 10,
         | 
| 13 | 
            +
                    },
         | 
| 14 | 
            +
                  ] %>
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            <% chart_options = {
         | 
| 17 | 
            +
                series: [{ data: data }],
         | 
| 18 | 
            +
                plotOptions: {
         | 
| 19 | 
            +
                  pie: {
         | 
| 20 | 
            +
                    colors: ["#144075", "#1CA05C", "#F9BB00"],
         | 
| 21 | 
            +
                  },
         | 
| 22 | 
            +
                },
         | 
| 23 | 
            +
              } %>
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            <%= pb_rails("pb_circle_chart", props: { options: chart_options }) %>
         |