@govbr-ds/webcomponents 2.1.3 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +146 -54
- package/cem/custom-elements.json +6496 -1141
- package/cem/webcomponents.html-custom-data.json +400 -287
- package/dist/cjs/br-avatar.cjs.entry.js +21 -14
- package/dist/cjs/br-breadcrumb-item.cjs.entry.js +2 -2
- package/dist/cjs/br-breadcrumb.cjs.entry.js +49 -22
- package/dist/cjs/br-button_2.cjs.entry.js +77 -35
- package/dist/cjs/br-card.cjs.entry.js +6 -5
- package/dist/cjs/br-carousel-page.cjs.entry.js +3 -3
- package/dist/cjs/br-carousel.cjs.entry.js +77 -21
- package/dist/cjs/br-checkbox-group.cjs.entry.js +157 -27
- package/dist/cjs/br-checkbox.cjs.entry.js +86 -16
- package/dist/cjs/br-checkgroup.cjs.entry.js +5 -2
- package/dist/cjs/br-collapse_2.cjs.entry.js +90 -27
- package/dist/cjs/br-cookiebar-cookie.cjs.entry.js +4 -4
- package/dist/cjs/br-cookiebar-group.cjs.entry.js +4 -4
- package/dist/cjs/br-cookiebar-header.cjs.entry.js +4 -4
- package/dist/cjs/br-cookiebar-link.cjs.entry.js +14 -6
- package/dist/cjs/br-cookiebar-note-group.cjs.entry.js +3 -5
- package/dist/cjs/br-cookiebar-note.cjs.entry.js +4 -4
- package/dist/cjs/br-cookiebar.cjs.entry.js +38 -25
- package/dist/cjs/br-crumb.cjs.entry.js +2 -2
- package/dist/cjs/br-date-picker_3.cjs.entry.js +246 -88
- package/dist/cjs/br-datetime-picker.cjs.entry.js +116 -528
- package/dist/cjs/br-divider.cjs.entry.js +70 -17
- package/dist/cjs/br-dropdown_2.cjs.entry.js +334 -163
- package/dist/cjs/br-footer-category.cjs.entry.js +10 -6
- package/dist/cjs/br-footer-item.cjs.entry.js +9 -4
- package/dist/cjs/br-footer-legal.cjs.entry.js +4 -4
- package/dist/cjs/br-footer-logo.cjs.entry.js +22 -10
- package/dist/cjs/br-footer-social.cjs.entry.js +14 -6
- package/dist/cjs/br-footer.cjs.entry.js +16 -7
- package/dist/cjs/br-header-function.cjs.entry.js +28 -7
- package/dist/cjs/br-header-link.cjs.entry.js +25 -4
- package/dist/cjs/br-header-list.cjs.entry.js +6 -17
- package/dist/cjs/br-header-logo.cjs.entry.js +18 -7
- package/dist/cjs/br-header.cjs.entry.js +96 -37
- package/dist/cjs/br-icon.cjs.entry.js +161 -53
- package/dist/cjs/br-input.cjs.entry.js +150 -40
- package/dist/cjs/br-item.cjs.entry.js +97 -48
- package/dist/cjs/br-link.cjs.entry.js +20 -7
- package/dist/cjs/br-loading.cjs.entry.js +100 -38
- package/dist/cjs/br-magic-button.cjs.entry.js +39 -9
- package/dist/cjs/br-menu-group.cjs.entry.js +14 -3
- package/dist/cjs/br-menu-header.cjs.entry.js +4 -4
- package/dist/cjs/br-menu-info.cjs.entry.js +4 -4
- package/dist/cjs/br-menu-item.cjs.entry.js +27 -5
- package/dist/cjs/br-menu-link.cjs.entry.js +14 -6
- package/dist/cjs/br-menu-list.cjs.entry.js +23 -27
- package/dist/cjs/br-menu-logo.cjs.entry.js +4 -4
- package/dist/cjs/br-menu-social.cjs.entry.js +16 -6
- package/dist/cjs/br-menu.cjs.entry.js +38 -57
- package/dist/cjs/br-modal.cjs.entry.js +44 -42
- package/dist/cjs/br-notification-body.cjs.entry.js +4 -4
- package/dist/cjs/br-notification-header.cjs.entry.js +4 -4
- package/dist/cjs/br-notification-item.cjs.entry.js +14 -8
- package/dist/cjs/br-notification.cjs.entry.js +23 -8
- package/dist/cjs/br-pagination.cjs.entry.js +120 -88
- package/dist/cjs/br-radio-group.cjs.entry.js +107 -58
- package/dist/cjs/br-radio.cjs.entry.js +62 -12
- package/dist/cjs/br-scrim.cjs.entry.js +161 -67
- package/dist/cjs/br-select-input_3.cjs.entry.js +286 -91
- package/dist/cjs/br-sign-in.cjs.entry.js +38 -15
- package/dist/cjs/br-skip-link-item.cjs.entry.js +39 -2
- package/dist/cjs/br-skip-link.cjs.entry.js +50 -33
- package/dist/cjs/br-skiplink-item.cjs.entry.js +22 -6
- package/dist/cjs/br-slider.cjs.entry.js +522 -100
- package/dist/cjs/br-step_2.cjs.entry.js +98 -44
- package/dist/cjs/br-switch.cjs.entry.js +21 -12
- package/dist/cjs/br-tab-item.cjs.entry.js +38 -14
- package/dist/cjs/br-tab.cjs.entry.js +89 -51
- package/dist/cjs/br-table-body.cjs.entry.js +3 -3
- package/dist/cjs/br-table-cell.cjs.entry.js +30 -13
- package/dist/cjs/br-table-header-cell.cjs.entry.js +23 -7
- package/dist/cjs/br-table-header.cjs.entry.js +3 -3
- package/dist/cjs/br-table-row.cjs.entry.js +17 -3
- package/dist/cjs/br-table.cjs.entry.js +67 -21
- package/dist/cjs/br-tag.cjs.entry.js +49 -31
- package/dist/cjs/br-textarea.cjs.entry.js +118 -13
- package/dist/cjs/br-tooltip.cjs.entry.js +87 -41
- package/dist/cjs/br-upload.cjs.entry.js +84 -25
- package/dist/cjs/br-wizard-panel.cjs.entry.js +16 -3
- package/dist/cjs/br-wizard.cjs.entry.js +52 -28
- package/dist/cjs/{isValid-Fu3kaWNn.js → datetime-picker-props-validation-DmNKSXsy.js} +481 -4
- package/dist/cjs/{floating-ui-MBI1osio.js → floating-ui-B6nsdYUU.js} +24 -1
- package/dist/cjs/{floating-ui.dom-BUSTaaxR.js → floating-ui.dom-wzdGZjyG.js} +201 -113
- package/dist/cjs/{focus-DuywwJPR.js → focus-BhfJnFgJ.js} +21 -0
- package/dist/cjs/header-context-CdawuLsH.js +17 -0
- package/dist/cjs/icon.utils-DF6kMskA.js +46 -0
- package/dist/cjs/id-DE4jSi-L.js +36 -0
- package/dist/cjs/{index-CRdcutym.js → index-Bc30P_6z.js} +88 -766
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/motion-CgIooxWS.js +29 -0
- package/dist/cjs/ownership-UnpufyCx.js +116 -0
- package/dist/cjs/prop-warning-xvEHQz8H.js +60 -0
- package/dist/cjs/props-D8dybmr0.js +124 -0
- package/dist/cjs/{swipe-BU8_XE9f.js → swipe-BGF-h9WY.js} +11 -1
- package/dist/cjs/{validator-CTCajtT9.js → validator-GkkueMOx.js} +18 -0
- package/dist/cjs/webcomponents.cjs.js +3 -3
- package/dist/collection/collection-manifest.json +1 -1
- package/dist/collection/components/avatar/avatar.css +1 -1
- package/dist/collection/components/avatar/avatar.js +48 -16
- package/dist/collection/components/breadcrumb/breadcrumb-item/breadcrumb-item.js +15 -3
- package/dist/collection/components/breadcrumb/breadcrumb.css +1 -1
- package/dist/collection/components/breadcrumb/breadcrumb.js +107 -22
- package/dist/collection/components/breadcrumb/crumb/crumb.js +14 -2
- package/dist/collection/components/button/button.css +1 -1
- package/dist/collection/components/button/button.js +93 -24
- package/dist/collection/components/card/card.css +1 -1
- package/dist/collection/components/card/card.js +33 -5
- package/dist/collection/components/carousel/carousel-page/carousel-page.css +1 -1
- package/dist/collection/components/carousel/carousel-page/carousel-page.js +11 -4
- package/dist/collection/components/carousel/carousel.css +1 -1
- package/dist/collection/components/carousel/carousel.js +107 -21
- package/dist/collection/components/checkbox/checkbox.css +1 -1
- package/dist/collection/components/checkbox/checkbox.js +134 -20
- package/dist/collection/components/checkbox-group/checkbox-group.css +1 -1
- package/dist/collection/components/checkbox-group/checkbox-group.js +210 -30
- package/dist/collection/components/checkgroup/checkgroup.js +42 -4
- package/dist/collection/components/collapse/collapse.css +1 -1
- package/dist/collection/components/collapse/collapse.js +55 -9
- package/dist/collection/components/cookiebar/cookiebar-cookie/cookiebar-cookie.css +1 -1
- package/dist/collection/components/cookiebar/cookiebar-cookie/cookiebar-cookie.js +17 -4
- package/dist/collection/components/cookiebar/cookiebar-group/cookiebar-group.css +1 -1
- package/dist/collection/components/cookiebar/cookiebar-group/cookiebar-group.js +16 -7
- package/dist/collection/components/cookiebar/cookiebar-header/cookiebar-header.css +1 -1
- package/dist/collection/components/cookiebar/cookiebar-header/cookiebar-header.js +15 -9
- package/dist/collection/components/cookiebar/cookiebar-link/cookiebar-link.css +1 -1
- package/dist/collection/components/cookiebar/cookiebar-link/cookiebar-link.js +24 -8
- package/dist/collection/components/cookiebar/cookiebar-note/cookiebar-note.css +1 -1
- package/dist/collection/components/cookiebar/cookiebar-note/cookiebar-note.js +14 -4
- package/dist/collection/components/cookiebar/cookiebar-note-group/cookiebar-note-group.css +1 -1
- package/dist/collection/components/cookiebar/cookiebar-note-group/cookiebar-note-group.js +13 -5
- package/dist/collection/components/cookiebar/cookiebar.css +1 -1
- package/dist/collection/components/cookiebar/cookiebar.js +67 -32
- package/dist/collection/components/datetime-picker/date-picker/date-picker.css +1 -1
- package/dist/collection/components/datetime-picker/date-picker/date-picker.js +134 -35
- package/dist/collection/components/datetime-picker/datetime-input/datetime-input.css +1 -1
- package/dist/collection/components/datetime-picker/datetime-input/datetime-input.js +112 -22
- package/dist/collection/components/datetime-picker/datetime-picker-props-validation.js +13 -5
- package/dist/collection/components/datetime-picker/datetime-picker.css +1 -1
- package/dist/collection/components/datetime-picker/datetime-picker.js +158 -42
- package/dist/collection/components/datetime-picker/time-picker/time-picker.css +1 -1
- package/dist/collection/components/datetime-picker/time-picker/time-picker.js +78 -9
- package/dist/collection/components/divider/divider.css +1 -1
- package/dist/collection/components/divider/divider.js +101 -26
- package/dist/collection/components/dropdown/dropdown.css +1 -1
- package/dist/collection/components/dropdown/dropdown.js +195 -51
- package/dist/collection/components/footer/footer-category/footer-category.css +1 -1
- package/dist/collection/components/footer/footer-category/footer-category.js +23 -4
- package/dist/collection/components/footer/footer-item/footer-item.css +1 -1
- package/dist/collection/components/footer/footer-item/footer-item.js +21 -2
- package/dist/collection/components/footer/footer-legal/footer-legal.css +1 -1
- package/dist/collection/components/footer/footer-legal/footer-legal.js +16 -2
- package/dist/collection/components/footer/footer-logo/footer-logo.css +1 -1
- package/dist/collection/components/footer/footer-logo/footer-logo.js +35 -9
- package/dist/collection/components/footer/footer-social/footer-social.css +1 -1
- package/dist/collection/components/footer/footer-social/footer-social.js +26 -6
- package/dist/collection/components/footer/footer.css +1 -1
- package/dist/collection/components/footer/footer.js +48 -7
- package/dist/collection/components/header/header-context.js +13 -0
- package/dist/collection/components/header/header-function/header-function.css +1 -1
- package/dist/collection/components/header/header-function/header-function.js +51 -8
- package/dist/collection/components/header/header-link/header-link.css +1 -1
- package/dist/collection/components/header/header-link/header-link.js +52 -2
- package/dist/collection/components/header/header-list/header-list.css +1 -1
- package/dist/collection/components/header/header-list/header-list.js +20 -23
- package/dist/collection/components/header/header-logo/header-logo.css +1 -1
- package/dist/collection/components/header/header-logo/header-logo.js +33 -8
- package/dist/collection/components/header/header.css +1 -1
- package/dist/collection/components/header/header.js +134 -44
- package/dist/collection/components/icon/default-icons-cache.js +111 -3
- package/dist/collection/components/icon/icon.css +1 -1
- package/dist/collection/components/icon/icon.js +80 -33
- package/dist/collection/components/icon/icon.utils.js +8 -0
- package/dist/collection/components/input/input.css +1 -1
- package/dist/collection/components/input/input.js +189 -55
- package/dist/collection/components/item/item.css +1 -1
- package/dist/collection/components/item/item.js +136 -52
- package/dist/collection/components/link/link.css +1 -1
- package/dist/collection/components/link/link.js +48 -15
- package/dist/collection/components/list/list.css +1 -1
- package/dist/collection/components/list/list.js +106 -25
- package/dist/collection/components/loading/loading.css +1 -1
- package/dist/collection/components/loading/loading.js +131 -43
- package/dist/collection/components/magic-button/magic-button.css +1 -1
- package/dist/collection/components/magic-button/magic-button.js +65 -9
- package/dist/collection/components/menu/menu-group/menu-group.css +1 -1
- package/dist/collection/components/menu/menu-group/menu-group.js +60 -2
- package/dist/collection/components/menu/menu-header/menu-header.css +1 -1
- package/dist/collection/components/menu/menu-header/menu-header.js +17 -2
- package/dist/collection/components/menu/menu-info/menu-info.css +1 -1
- package/dist/collection/components/menu/menu-info/menu-info.js +15 -2
- package/dist/collection/components/menu/menu-item/menu-item.css +1 -1
- package/dist/collection/components/menu/menu-item/menu-item.js +72 -8
- package/dist/collection/components/menu/menu-link/menu-link.css +1 -1
- package/dist/collection/components/menu/menu-link/menu-link.js +25 -4
- package/dist/collection/components/menu/menu-list/menu-list.css +1 -1
- package/dist/collection/components/menu/menu-list/menu-list.js +64 -29
- package/dist/collection/components/menu/menu-logo/menu-logo.css +1 -1
- package/dist/collection/components/menu/menu-logo/menu-logo.js +15 -2
- package/dist/collection/components/menu/menu-social/menu-social.css +1 -1
- package/dist/collection/components/menu/menu-social/menu-social.js +29 -7
- package/dist/collection/components/menu/menu.css +1 -1
- package/dist/collection/components/menu/menu.js +71 -60
- package/dist/collection/components/menu/menu.utils.js +8 -18
- package/dist/collection/components/message/message.css +1 -1
- package/dist/collection/components/message/message.js +50 -24
- package/dist/collection/components/modal/modal.css +1 -1
- package/dist/collection/components/modal/modal.js +72 -43
- package/dist/collection/components/notification/notification-body/notification-body.css +1 -1
- package/dist/collection/components/notification/notification-body/notification-body.js +13 -4
- package/dist/collection/components/notification/notification-header/notification-header.css +1 -1
- package/dist/collection/components/notification/notification-header/notification-header.js +13 -4
- package/dist/collection/components/notification/notification-item/notification-item.css +1 -1
- package/dist/collection/components/notification/notification-item/notification-item.js +23 -9
- package/dist/collection/components/notification/notification.css +1 -1
- package/dist/collection/components/notification/notification.js +54 -10
- package/dist/collection/components/pagination/pagination.css +1 -1
- package/dist/collection/components/pagination/pagination.js +164 -75
- package/dist/collection/components/radio/radio.css +1 -1
- package/dist/collection/components/radio/radio.js +109 -14
- package/dist/collection/components/radio-group/radio-group.css +1 -1
- package/dist/collection/components/radio-group/radio-group.js +153 -63
- package/dist/collection/components/scrim/scrim.css +1 -1
- package/dist/collection/components/scrim/scrim.js +215 -74
- package/dist/collection/components/scrim/scrim.utils.js +5 -51
- package/dist/collection/components/select/select-input/select-input.css +1 -1
- package/dist/collection/components/select/select-input/select-input.js +61 -6
- package/dist/collection/components/select/select-list/select-list.css +1 -1
- package/dist/collection/components/select/select-list/select-list.js +247 -52
- package/dist/collection/components/select/select-option/select-option.css +1 -1
- package/dist/collection/components/select/select-option/select-option.js +108 -46
- package/dist/collection/components/select/select.css +1 -1
- package/dist/collection/components/select/select.js +320 -124
- package/dist/collection/components/select/select.utils.js +3 -1
- package/dist/collection/components/sign-in/sign-in.css +1 -1
- package/dist/collection/components/sign-in/sign-in.js +60 -17
- package/dist/collection/components/skip-link/skip-link-item/skip-link-item-alias.js +112 -3
- package/dist/collection/components/skip-link/skip-link-item/skip-link-item.css +1 -1
- package/dist/collection/components/skip-link/skip-link-item/skip-link-item.js +58 -5
- package/dist/collection/components/skip-link/skip-link.css +1 -1
- package/dist/collection/components/skip-link/skip-link.js +78 -39
- package/dist/collection/components/slider/slider.css +1 -1
- package/dist/collection/components/slider/slider.js +530 -132
- package/dist/collection/components/slider/slider.utils.js +178 -0
- package/dist/collection/components/step/step-item/step-item.css +1 -1
- package/dist/collection/components/step/step-item/step-item.js +29 -12
- package/dist/collection/components/step/step.css +1 -1
- package/dist/collection/components/step/step.js +119 -44
- package/dist/collection/components/switch/switch.css +1 -1
- package/dist/collection/components/switch/switch.js +48 -15
- package/dist/collection/components/tab/tab-item/tab-item.css +1 -1
- package/dist/collection/components/tab/tab-item/tab-item.js +49 -14
- package/dist/collection/components/tab/tab.css +1 -1
- package/dist/collection/components/tab/tab.js +123 -53
- package/dist/collection/components/table/table-body/table-body.css +1 -1
- package/dist/collection/components/table/table-body/table-body.js +11 -7
- package/dist/collection/components/table/table-cell/table-cell.css +1 -1
- package/dist/collection/components/table/table-cell/table-cell.js +36 -17
- package/dist/collection/components/table/table-header/table-header.css +1 -1
- package/dist/collection/components/table/table-header/table-header.js +11 -7
- package/dist/collection/components/table/table-header-cell/table-header-cell.css +1 -1
- package/dist/collection/components/table/table-header-cell/table-header-cell.js +35 -13
- package/dist/collection/components/table/table-row/table-row.css +1 -1
- package/dist/collection/components/table/table-row/table-row.js +24 -7
- package/dist/collection/components/table/table.css +1 -1
- package/dist/collection/components/table/table.js +107 -31
- package/dist/collection/components/tag/tag.css +1 -1
- package/dist/collection/components/tag/tag.js +86 -36
- package/dist/collection/components/textarea/textarea.css +1 -1
- package/dist/collection/components/textarea/textarea.js +222 -19
- package/dist/collection/components/tooltip/tooltip.css +1 -1
- package/dist/collection/components/tooltip/tooltip.js +134 -45
- package/dist/collection/components/upload/upload.css +1 -1
- package/dist/collection/components/upload/upload.js +135 -33
- package/dist/collection/components/wizard/wizard-panel/wizard-panel.css +1 -1
- package/dist/collection/components/wizard/wizard-panel/wizard-panel.js +54 -3
- package/dist/collection/components/wizard/wizard.css +1 -1
- package/dist/collection/components/wizard/wizard.js +82 -28
- package/dist/collection/pages/components/select/remote.js +33 -0
- package/dist/collection/pages/components/select/virtualized.js +13 -0
- package/dist/collection/pages/components/upload/handler.js +25 -0
- package/dist/collection/pages/scripts/component-controls-core.js +95 -0
- package/dist/collection/pages/scripts/component-controls.js +221 -158
- package/dist/collection/pages/scripts/dev-event-console.js +5 -1
- package/dist/collection/pages/scripts/menu.js +90 -6
- package/dist/collection/pages/scripts/pageLoader.js +1570 -607
- package/dist/collection/pages/scripts/pageloader-preview.js +796 -0
- package/dist/collection/pages/scripts/playground-core.js +173 -0
- package/dist/collection/shared/utils/cssVariables.js +2 -0
- package/dist/collection/shared/utils/date.js +8 -4
- package/dist/collection/shared/utils/floating-ui.js +24 -1
- package/dist/collection/shared/utils/focus.js +31 -0
- package/dist/collection/shared/utils/form.js +17 -0
- package/dist/collection/shared/utils/getRandom.js +16 -1
- package/dist/collection/shared/utils/helpers.js +4 -11
- package/dist/collection/shared/utils/id.js +23 -7
- package/dist/collection/shared/utils/index.js +6 -1
- package/dist/collection/shared/utils/isEmpty.js +5 -3
- package/dist/collection/shared/utils/motion.js +25 -0
- package/dist/collection/shared/utils/ownership.js +113 -0
- package/dist/collection/shared/utils/prop-warning.js +47 -0
- package/dist/collection/shared/utils/props.js +79 -0
- package/dist/collection/shared/utils/swipe.js +11 -1
- package/dist/collection/shared/utils/transition.js +3 -0
- package/dist/collection/shared/utils/virtual-scroll.js +24 -0
- package/dist/components/br-avatar.d.ts +1 -1
- package/dist/components/br-avatar.js +1 -1
- package/dist/components/br-breadcrumb-item.d.ts +1 -1
- package/dist/components/br-breadcrumb-item.js +1 -1
- package/dist/components/br-breadcrumb.d.ts +1 -1
- package/dist/components/br-breadcrumb.js +1 -1
- package/dist/components/br-button.d.ts +1 -1
- package/dist/components/br-button.js +1 -1
- package/dist/components/br-card.d.ts +1 -1
- package/dist/components/br-card.js +1 -1
- package/dist/components/br-carousel-page.d.ts +1 -1
- package/dist/components/br-carousel-page.js +1 -1
- package/dist/components/br-carousel.d.ts +1 -1
- package/dist/components/br-carousel.js +1 -1
- package/dist/components/br-checkbox-group.d.ts +1 -1
- package/dist/components/br-checkbox-group.js +1 -1
- package/dist/components/br-checkbox.d.ts +1 -1
- package/dist/components/br-checkbox.js +1 -1
- package/dist/components/br-checkgroup.d.ts +1 -1
- package/dist/components/br-checkgroup.js +1 -1
- package/dist/components/br-collapse.d.ts +1 -1
- package/dist/components/br-collapse.js +1 -1
- package/dist/components/br-cookiebar-cookie.d.ts +1 -1
- package/dist/components/br-cookiebar-cookie.js +1 -1
- package/dist/components/br-cookiebar-group.d.ts +1 -1
- package/dist/components/br-cookiebar-group.js +1 -1
- package/dist/components/br-cookiebar-header.d.ts +1 -1
- package/dist/components/br-cookiebar-header.js +1 -1
- package/dist/components/br-cookiebar-link.d.ts +1 -1
- package/dist/components/br-cookiebar-link.js +1 -1
- package/dist/components/br-cookiebar-note-group.d.ts +1 -1
- package/dist/components/br-cookiebar-note-group.js +1 -1
- package/dist/components/br-cookiebar-note.d.ts +1 -1
- package/dist/components/br-cookiebar-note.js +1 -1
- package/dist/components/br-cookiebar.d.ts +1 -1
- package/dist/components/br-cookiebar.js +1 -1
- package/dist/components/br-crumb.d.ts +1 -1
- package/dist/components/br-crumb.js +1 -1
- package/dist/components/br-date-picker.d.ts +1 -1
- package/dist/components/br-date-picker.js +1 -1
- package/dist/components/br-datetime-input.d.ts +1 -1
- package/dist/components/br-datetime-input.js +1 -1
- package/dist/components/br-datetime-picker.d.ts +1 -1
- package/dist/components/br-datetime-picker.js +1 -1
- package/dist/components/br-divider.d.ts +1 -1
- package/dist/components/br-divider.js +1 -1
- package/dist/components/br-dropdown.d.ts +1 -1
- package/dist/components/br-dropdown.js +1 -1
- package/dist/components/br-footer-category.d.ts +1 -1
- package/dist/components/br-footer-category.js +1 -1
- package/dist/components/br-footer-item.d.ts +1 -1
- package/dist/components/br-footer-item.js +1 -1
- package/dist/components/br-footer-legal.d.ts +1 -1
- package/dist/components/br-footer-legal.js +1 -1
- package/dist/components/br-footer-logo.d.ts +1 -1
- package/dist/components/br-footer-logo.js +1 -1
- package/dist/components/br-footer-social.d.ts +1 -1
- package/dist/components/br-footer-social.js +1 -1
- package/dist/components/br-footer.d.ts +1 -1
- package/dist/components/br-footer.js +1 -1
- package/dist/components/br-header-function.d.ts +1 -1
- package/dist/components/br-header-function.js +1 -1
- package/dist/components/br-header-link.d.ts +1 -1
- package/dist/components/br-header-link.js +1 -1
- package/dist/components/br-header-list.d.ts +1 -1
- package/dist/components/br-header-list.js +1 -1
- package/dist/components/br-header-logo.d.ts +1 -1
- package/dist/components/br-header-logo.js +1 -1
- package/dist/components/br-header.d.ts +1 -1
- package/dist/components/br-header.js +1 -1
- package/dist/components/br-icon.d.ts +1 -1
- package/dist/components/br-icon.js +1 -1
- package/dist/components/br-input.d.ts +1 -1
- package/dist/components/br-input.js +1 -1
- package/dist/components/br-item.d.ts +1 -1
- package/dist/components/br-item.js +1 -1
- package/dist/components/br-link.d.ts +1 -1
- package/dist/components/br-link.js +1 -1
- package/dist/components/br-list.d.ts +1 -1
- package/dist/components/br-list.js +1 -1
- package/dist/components/br-loading.d.ts +1 -1
- package/dist/components/br-loading.js +1 -1
- package/dist/components/br-magic-button.d.ts +1 -1
- package/dist/components/br-magic-button.js +1 -1
- package/dist/components/br-menu-group.d.ts +1 -1
- package/dist/components/br-menu-group.js +1 -1
- package/dist/components/br-menu-header.d.ts +1 -1
- package/dist/components/br-menu-header.js +1 -1
- package/dist/components/br-menu-info.d.ts +1 -1
- package/dist/components/br-menu-info.js +1 -1
- package/dist/components/br-menu-item.d.ts +1 -1
- package/dist/components/br-menu-item.js +1 -1
- package/dist/components/br-menu-link.d.ts +1 -1
- package/dist/components/br-menu-link.js +1 -1
- package/dist/components/br-menu-list.d.ts +1 -1
- package/dist/components/br-menu-list.js +1 -1
- package/dist/components/br-menu-logo.d.ts +1 -1
- package/dist/components/br-menu-logo.js +1 -1
- package/dist/components/br-menu-social.d.ts +1 -1
- package/dist/components/br-menu-social.js +1 -1
- package/dist/components/br-menu.d.ts +1 -1
- package/dist/components/br-menu.js +1 -1
- package/dist/components/br-message.d.ts +1 -1
- package/dist/components/br-message.js +1 -1
- package/dist/components/br-modal.d.ts +1 -1
- package/dist/components/br-modal.js +1 -1
- package/dist/components/br-notification-body.d.ts +1 -1
- package/dist/components/br-notification-body.js +1 -1
- package/dist/components/br-notification-header.d.ts +1 -1
- package/dist/components/br-notification-header.js +1 -1
- package/dist/components/br-notification-item.d.ts +1 -1
- package/dist/components/br-notification-item.js +1 -1
- package/dist/components/br-notification.d.ts +1 -1
- package/dist/components/br-notification.js +1 -1
- package/dist/components/br-pagination.d.ts +1 -1
- package/dist/components/br-pagination.js +1 -1
- package/dist/components/br-radio-group.d.ts +1 -1
- package/dist/components/br-radio-group.js +1 -1
- package/dist/components/br-radio.d.ts +1 -1
- package/dist/components/br-radio.js +1 -1
- package/dist/components/br-scrim.d.ts +1 -1
- package/dist/components/br-scrim.js +1 -1
- package/dist/components/br-select-input.d.ts +1 -1
- package/dist/components/br-select-input.js +1 -1
- package/dist/components/br-select-list.d.ts +1 -1
- package/dist/components/br-select-list.js +1 -1
- package/dist/components/br-select-option.d.ts +1 -1
- package/dist/components/br-select-option.js +1 -1
- package/dist/components/br-select.d.ts +1 -1
- package/dist/components/br-select.js +1 -1
- package/dist/components/br-sign-in.d.ts +1 -1
- package/dist/components/br-sign-in.js +1 -1
- package/dist/components/br-skip-link-item.d.ts +1 -1
- package/dist/components/br-skip-link-item.js +1 -1
- package/dist/components/br-skip-link.d.ts +1 -1
- package/dist/components/br-skip-link.js +1 -1
- package/dist/components/br-skiplink-item.d.ts +1 -1
- package/dist/components/br-skiplink-item.js +1 -1
- package/dist/components/br-slider.d.ts +1 -1
- package/dist/components/br-slider.js +1 -1
- package/dist/components/br-step-item.d.ts +1 -1
- package/dist/components/br-step-item.js +1 -1
- package/dist/components/br-step.d.ts +1 -1
- package/dist/components/br-step.js +1 -1
- package/dist/components/br-switch.d.ts +1 -1
- package/dist/components/br-switch.js +1 -1
- package/dist/components/br-tab-item.d.ts +1 -1
- package/dist/components/br-tab-item.js +1 -1
- package/dist/components/br-tab.d.ts +1 -1
- package/dist/components/br-tab.js +1 -1
- package/dist/components/br-table-body.d.ts +1 -1
- package/dist/components/br-table-body.js +1 -1
- package/dist/components/br-table-cell.d.ts +1 -1
- package/dist/components/br-table-cell.js +1 -1
- package/dist/components/br-table-header-cell.d.ts +1 -1
- package/dist/components/br-table-header-cell.js +1 -1
- package/dist/components/br-table-header.d.ts +1 -1
- package/dist/components/br-table-header.js +1 -1
- package/dist/components/br-table-row.d.ts +1 -1
- package/dist/components/br-table-row.js +1 -1
- package/dist/components/br-table.d.ts +1 -1
- package/dist/components/br-table.js +1 -1
- package/dist/components/br-tag.d.ts +1 -1
- package/dist/components/br-tag.js +1 -1
- package/dist/components/br-textarea.d.ts +1 -1
- package/dist/components/br-textarea.js +1 -1
- package/dist/components/br-time-picker.d.ts +1 -1
- package/dist/components/br-time-picker.js +1 -1
- package/dist/components/br-tooltip.d.ts +1 -1
- package/dist/components/br-tooltip.js +1 -1
- package/dist/components/br-upload.d.ts +1 -1
- package/dist/components/br-upload.js +1 -1
- package/dist/components/br-wizard-panel.d.ts +1 -1
- package/dist/components/br-wizard-panel.js +1 -1
- package/dist/components/br-wizard.d.ts +1 -1
- package/dist/components/br-wizard.js +1 -1
- package/dist/components/index.d.ts +89 -89
- package/dist/components/index.js +1 -1
- package/dist/components/p-0qmYp77w.js +5 -0
- package/dist/components/p-5c3rNBXh.js +5 -0
- package/dist/components/p-B8oIvH3q.js +5 -0
- package/dist/components/p-BECz8XWJ.js +5 -0
- package/dist/components/p-BEJGB0Nd.js +5 -0
- package/dist/{webcomponents/p-Dmfk7eEe.js → components/p-BJZC_NuV.js} +1 -1
- package/dist/components/p-BJtdabsr.js +5 -0
- package/dist/components/p-BM4Ys6hX.js +5 -0
- package/dist/components/p-BXWh9s7p.js +5 -0
- package/dist/components/{p-DA5GS53D.js → p-BblZlUp2.js} +1 -1
- package/dist/components/{p-C1yRmdso.js → p-BcqVlof7.js} +1 -1
- package/dist/components/p-BeJxz5TQ.js +5 -0
- package/dist/components/p-Bezou5CQ.js +5 -0
- package/dist/components/p-BjeUETWJ.js +5 -0
- package/dist/components/p-CDTENPaP.js +5 -0
- package/dist/components/p-CDtFCbKp.js +5 -0
- package/dist/components/p-CNwZRgyL.js +5 -0
- package/dist/components/p-CZZVc2gK.js +5 -0
- package/dist/components/p-Cd6udSDt.js +5 -0
- package/dist/components/p-Ci0_RqAE.js +5 -0
- package/dist/components/p-CuBgClZm.js +5 -0
- package/dist/components/p-D0QYZSoP.js +5 -0
- package/dist/components/p-D4SWpW6-.js +5 -0
- package/dist/components/p-D579DS7x.js +5 -0
- package/dist/components/p-D8K7rhHd.js +5 -0
- package/dist/components/p-D9Zo6FlV.js +5 -0
- package/dist/components/p-D9nXlCuS.js +5 -0
- package/dist/components/p-DKFO6Q_g.js +5 -0
- package/dist/components/p-DNJSSCNi.js +5 -0
- package/dist/components/p-DOJ1vYOl.js +5 -0
- package/dist/components/p-DWhzxlCx.js +5 -0
- package/dist/components/p-DYI30IZL.js +5 -0
- package/dist/components/p-DcVldfL0.js +5 -0
- package/dist/components/p-DhvmHPp4.js +5 -0
- package/dist/components/p-DiLI514I.js +5 -0
- package/dist/components/p-DwgiHL0b.js +5 -0
- package/dist/components/p-Jk_KQE5V.js +5 -0
- package/dist/components/p-Nze3Utvd.js +5 -0
- package/dist/components/p-WxDB6Dk4.js +5 -0
- package/dist/components/p-ZLoeVagg.js +5 -0
- package/dist/components/p-gbYJ9sfc.js +5 -0
- package/dist/components/p-uc8ABlC_.js +5 -0
- package/dist/components/p-v60ypfxD.js +5 -0
- package/dist/esm/br-avatar.entry.js +21 -14
- package/dist/esm/br-breadcrumb-item.entry.js +2 -2
- package/dist/esm/br-breadcrumb.entry.js +49 -22
- package/dist/esm/br-button_2.entry.js +77 -35
- package/dist/esm/br-card.entry.js +6 -5
- package/dist/esm/br-carousel-page.entry.js +3 -3
- package/dist/esm/br-carousel.entry.js +78 -22
- package/dist/esm/br-checkbox-group.entry.js +157 -27
- package/dist/esm/br-checkbox.entry.js +87 -17
- package/dist/esm/br-checkgroup.entry.js +5 -2
- package/dist/esm/br-collapse_2.entry.js +91 -28
- package/dist/esm/br-cookiebar-cookie.entry.js +4 -4
- package/dist/esm/br-cookiebar-group.entry.js +4 -4
- package/dist/esm/br-cookiebar-header.entry.js +4 -4
- package/dist/esm/br-cookiebar-link.entry.js +14 -6
- package/dist/esm/br-cookiebar-note-group.entry.js +3 -5
- package/dist/esm/br-cookiebar-note.entry.js +4 -4
- package/dist/esm/br-cookiebar.entry.js +39 -26
- package/dist/esm/br-crumb.entry.js +2 -2
- package/dist/esm/br-date-picker_3.entry.js +207 -49
- package/dist/esm/br-datetime-picker.entry.js +83 -495
- package/dist/esm/br-divider.entry.js +70 -17
- package/dist/esm/br-dropdown_2.entry.js +335 -164
- package/dist/esm/br-footer-category.entry.js +10 -6
- package/dist/esm/br-footer-item.entry.js +9 -4
- package/dist/esm/br-footer-legal.entry.js +4 -4
- package/dist/esm/br-footer-logo.entry.js +22 -10
- package/dist/esm/br-footer-social.entry.js +14 -6
- package/dist/esm/br-footer.entry.js +16 -7
- package/dist/esm/br-header-function.entry.js +28 -7
- package/dist/esm/br-header-link.entry.js +25 -4
- package/dist/esm/br-header-list.entry.js +7 -18
- package/dist/esm/br-header-logo.entry.js +18 -7
- package/dist/esm/br-header.entry.js +96 -37
- package/dist/esm/br-icon.entry.js +160 -52
- package/dist/esm/br-input.entry.js +152 -42
- package/dist/esm/br-item.entry.js +97 -48
- package/dist/esm/br-link.entry.js +20 -7
- package/dist/esm/br-loading.entry.js +100 -38
- package/dist/esm/br-magic-button.entry.js +39 -9
- package/dist/esm/br-menu-group.entry.js +14 -3
- package/dist/esm/br-menu-header.entry.js +4 -4
- package/dist/esm/br-menu-info.entry.js +4 -4
- package/dist/esm/br-menu-item.entry.js +27 -5
- package/dist/esm/br-menu-link.entry.js +14 -6
- package/dist/esm/br-menu-list.entry.js +23 -27
- package/dist/esm/br-menu-logo.entry.js +4 -4
- package/dist/esm/br-menu-social.entry.js +16 -6
- package/dist/esm/br-menu.entry.js +39 -58
- package/dist/esm/br-modal.entry.js +44 -42
- package/dist/esm/br-notification-body.entry.js +4 -4
- package/dist/esm/br-notification-header.entry.js +4 -4
- package/dist/esm/br-notification-item.entry.js +14 -8
- package/dist/esm/br-notification.entry.js +24 -9
- package/dist/esm/br-pagination.entry.js +120 -88
- package/dist/esm/br-radio-group.entry.js +108 -59
- package/dist/esm/br-radio.entry.js +63 -13
- package/dist/esm/br-scrim.entry.js +161 -67
- package/dist/esm/br-select-input_3.entry.js +286 -91
- package/dist/esm/br-sign-in.entry.js +38 -15
- package/dist/esm/br-skip-link-item.entry.js +39 -2
- package/dist/esm/br-skip-link.entry.js +50 -33
- package/dist/esm/br-skiplink-item.entry.js +22 -6
- package/dist/esm/br-slider.entry.js +520 -98
- package/dist/esm/br-step_2.entry.js +98 -44
- package/dist/esm/br-switch.entry.js +22 -13
- package/dist/esm/br-tab-item.entry.js +38 -14
- package/dist/esm/br-tab.entry.js +89 -51
- package/dist/esm/br-table-body.entry.js +3 -3
- package/dist/esm/br-table-cell.entry.js +30 -13
- package/dist/esm/br-table-header-cell.entry.js +23 -7
- package/dist/esm/br-table-header.entry.js +3 -3
- package/dist/esm/br-table-row.entry.js +17 -3
- package/dist/esm/br-table.entry.js +68 -22
- package/dist/esm/br-tag.entry.js +50 -32
- package/dist/esm/br-textarea.entry.js +119 -14
- package/dist/esm/br-tooltip.entry.js +88 -42
- package/dist/esm/br-upload.entry.js +85 -26
- package/dist/esm/br-wizard-panel.entry.js +16 -3
- package/dist/esm/br-wizard.entry.js +52 -28
- package/dist/esm/{datetime-picker-constants-Bfm58jO6.js → datetime-picker-constants-BtRPYRvA.js} +1 -1
- package/dist/esm/{isValid-DIUZX1qS.js → datetime-picker-props-validation-BeTcUTnE.js} +476 -5
- package/dist/esm/{event-DFN_so7I.js → event-CfuJQ1DY.js} +1 -1
- package/dist/esm/{floating-ui-BavFwMnx.js → floating-ui-CskvaxD5.js} +24 -1
- package/dist/esm/{floating-ui.dom-DIK54tTj.js → floating-ui.dom-D9Zo6FlV.js} +201 -114
- package/dist/esm/{focus-DxZJrIyL.js → focus-CNwZRgyL.js} +20 -1
- package/dist/esm/header-context-BEJGB0Nd.js +15 -0
- package/dist/esm/icon.utils-zlORkiHQ.js +43 -0
- package/dist/esm/id-BeJxz5TQ.js +34 -0
- package/dist/esm/{index-Bo-2igoO.js → index-BQPOWxe5.js} +1 -1
- package/dist/esm/{index-C2RBydfd.js → index-ConyRdJe.js} +88 -766
- package/dist/esm/index.js +2 -2
- package/dist/esm/loader.js +3 -3
- package/dist/esm/motion-DWhzxlCx.js +27 -0
- package/dist/esm/ownership-CDtFCbKp.js +111 -0
- package/dist/esm/prop-warning-BlGV-x0w.js +56 -0
- package/dist/esm/props-D07GjR4_.js +116 -0
- package/dist/esm/{swipe-Dmfk7eEe.js → swipe-BJZC_NuV.js} +11 -1
- package/dist/esm/{validator-D3tVP32U.js → validator-BkWWrDEr.js} +18 -1
- package/dist/esm/webcomponents.js +4 -4
- package/dist/hydrate/index.js +7541 -2577
- package/dist/hydrate/index.mjs +7541 -2577
- package/dist/loader/index.d.ts +1 -1
- package/dist/types/components/avatar/avatar.d.ts +34 -4
- package/dist/types/components/breadcrumb/breadcrumb-item/breadcrumb-item.d.ts +14 -2
- package/dist/types/components/breadcrumb/breadcrumb.d.ts +66 -5
- package/dist/types/components/breadcrumb/crumb/crumb.d.ts +13 -1
- package/dist/types/components/button/button.d.ts +45 -8
- package/dist/types/components/card/card.d.ts +31 -3
- package/dist/types/components/carousel/carousel-page/carousel-page.d.ts +10 -3
- package/dist/types/components/carousel/carousel.d.ts +46 -3
- package/dist/types/components/checkbox/checkbox.d.ts +59 -6
- package/dist/types/components/checkbox-group/checkbox-group.d.ts +47 -5
- package/dist/types/components/checkgroup/checkgroup.d.ts +27 -5
- package/dist/types/components/collapse/collapse.d.ts +37 -4
- package/dist/types/components/cookiebar/cookiebar-cookie/cookiebar-cookie.d.ts +16 -3
- package/dist/types/components/cookiebar/cookiebar-group/cookiebar-group.d.ts +15 -6
- package/dist/types/components/cookiebar/cookiebar-header/cookiebar-header.d.ts +14 -8
- package/dist/types/components/cookiebar/cookiebar-link/cookiebar-link.d.ts +16 -5
- package/dist/types/components/cookiebar/cookiebar-note/cookiebar-note.d.ts +13 -3
- package/dist/types/components/cookiebar/cookiebar-note-group/cookiebar-note-group.d.ts +13 -3
- package/dist/types/components/cookiebar/cookiebar.d.ts +35 -10
- package/dist/types/components/datetime-picker/date-picker/date-picker.d.ts +63 -7
- package/dist/types/components/datetime-picker/datetime-input/datetime-input.d.ts +51 -9
- package/dist/types/components/datetime-picker/datetime-picker-props-validation.d.ts +4 -2
- package/dist/types/components/datetime-picker/datetime-picker.d.ts +118 -12
- package/dist/types/components/datetime-picker/time-picker/time-picker.d.ts +38 -4
- package/dist/types/components/divider/divider.d.ts +45 -8
- package/dist/types/components/dropdown/dropdown.d.ts +53 -7
- package/dist/types/components/footer/footer-category/footer-category.d.ts +16 -1
- package/dist/types/components/footer/footer-item/footer-item.d.ts +17 -1
- package/dist/types/components/footer/footer-legal/footer-legal.d.ts +15 -1
- package/dist/types/components/footer/footer-logo/footer-logo.d.ts +21 -2
- package/dist/types/components/footer/footer-social/footer-social.d.ts +20 -3
- package/dist/types/components/footer/footer.d.ts +39 -3
- package/dist/types/components/header/header-context.d.ts +1 -0
- package/dist/types/components/header/header-function/header-function.d.ts +24 -2
- package/dist/types/components/header/header-link/header-link.d.ts +22 -1
- package/dist/types/components/header/header-list/header-list.d.ts +16 -8
- package/dist/types/components/header/header-logo/header-logo.d.ts +20 -1
- package/dist/types/components/header/header.d.ts +47 -7
- package/dist/types/components/icon/icon.d.ts +44 -13
- package/dist/types/components/icon/icon.utils.d.ts +6 -0
- package/dist/types/components/input/input.d.ts +74 -15
- package/dist/types/components/item/item.d.ts +44 -6
- package/dist/types/components/link/link.d.ts +41 -9
- package/dist/types/components/list/list.d.ts +58 -8
- package/dist/types/components/loading/loading.d.ts +48 -8
- package/dist/types/components/magic-button/magic-button.d.ts +41 -3
- package/dist/types/components/menu/menu-group/menu-group.d.ts +19 -1
- package/dist/types/components/menu/menu-header/menu-header.d.ts +16 -1
- package/dist/types/components/menu/menu-info/menu-info.d.ts +14 -1
- package/dist/types/components/menu/menu-item/menu-item.d.ts +27 -3
- package/dist/types/components/menu/menu-link/menu-link.d.ts +17 -1
- package/dist/types/components/menu/menu-list/menu-list.d.ts +22 -4
- package/dist/types/components/menu/menu-logo/menu-logo.d.ts +14 -1
- package/dist/types/components/menu/menu-social/menu-social.d.ts +21 -2
- package/dist/types/components/menu/menu.d.ts +39 -6
- package/dist/types/components/menu/menu.utils.d.ts +2 -6
- package/dist/types/components/message/message.d.ts +38 -9
- package/dist/types/components/modal/modal.d.ts +40 -4
- package/dist/types/components/notification/notification-body/notification-body.d.ts +12 -3
- package/dist/types/components/notification/notification-header/notification-header.d.ts +12 -3
- package/dist/types/components/notification/notification-item/notification-item.d.ts +15 -3
- package/dist/types/components/notification/notification.d.ts +36 -5
- package/dist/types/components/pagination/pagination.d.ts +58 -20
- package/dist/types/components/radio/radio.d.ts +49 -4
- package/dist/types/components/radio-group/radio-group.d.ts +52 -10
- package/dist/types/components/scrim/scrim.d.ts +72 -11
- package/dist/types/components/scrim/scrim.utils.d.ts +2 -17
- package/dist/types/components/select/select-input/select-input.d.ts +22 -4
- package/dist/types/components/select/select-list/select-list.d.ts +51 -5
- package/dist/types/components/select/select-option/select-option.d.ts +31 -8
- package/dist/types/components/select/select.d.ts +152 -13
- package/dist/types/components/select/select.types.d.ts +5 -0
- package/dist/types/components/sign-in/sign-in.d.ts +32 -4
- package/dist/types/components/skip-link/skip-link-item/skip-link-item-alias.d.ts +15 -2
- package/dist/types/components/skip-link/skip-link-item/skip-link-item.d.ts +22 -1
- package/dist/types/components/skip-link/skip-link.d.ts +37 -3
- package/dist/types/components/slider/slider.d.ts +147 -21
- package/dist/types/components/slider/slider.types.d.ts +7 -2
- package/dist/types/components/slider/slider.utils.d.ts +27 -0
- package/dist/types/components/step/step-item/step-item.d.ts +15 -3
- package/dist/types/components/step/step.d.ts +47 -12
- package/dist/types/components/switch/switch.d.ts +39 -6
- package/dist/types/components/tab/tab-item/tab-item.d.ts +24 -4
- package/dist/types/components/tab/tab.d.ts +48 -11
- package/dist/types/components/table/table-body/table-body.d.ts +10 -6
- package/dist/types/components/table/table-cell/table-cell.d.ts +10 -6
- package/dist/types/components/table/table-header/table-header.d.ts +10 -6
- package/dist/types/components/table/table-header-cell/table-header-cell.d.ts +18 -6
- package/dist/types/components/table/table-row/table-row.d.ts +11 -6
- package/dist/types/components/table/table.d.ts +49 -11
- package/dist/types/components/tag/tag.d.ts +55 -7
- package/dist/types/components/textarea/textarea.d.ts +75 -5
- package/dist/types/components/textarea/textarea.types.d.ts +4 -0
- package/dist/types/components/tooltip/tooltip.d.ts +46 -8
- package/dist/types/components/upload/upload.d.ts +78 -10
- package/dist/types/components/wizard/wizard-panel/wizard-panel.d.ts +20 -2
- package/dist/types/components/wizard/wizard.d.ts +44 -7
- package/dist/types/components.d.ts +5827 -1354
- package/dist/types/shared/utils/floating-ui.d.ts +4 -0
- package/dist/types/shared/utils/focus.d.ts +14 -0
- package/dist/types/shared/utils/form.d.ts +8 -0
- package/dist/types/shared/utils/getRandom.d.ts +1 -0
- package/dist/types/shared/utils/id.d.ts +1 -1
- package/dist/types/shared/utils/index.d.ts +6 -1
- package/dist/types/shared/utils/motion.d.ts +14 -0
- package/dist/types/shared/utils/ownership.d.ts +33 -0
- package/dist/types/shared/utils/prop-warning.d.ts +7 -0
- package/dist/types/shared/utils/props.d.ts +38 -0
- package/dist/types/shared/utils/swipe.d.ts +5 -0
- package/dist/types/shared/utils/virtual-scroll.d.ts +25 -0
- package/dist/types/stencil-public-runtime.d.ts +73 -55
- package/dist/webcomponents/index.esm.js +1 -1
- package/dist/webcomponents/p-078bd760.entry.js +5 -0
- package/dist/webcomponents/p-07c2cdff.entry.js +5 -0
- package/dist/webcomponents/{p-7f7506f0.entry.js → p-09817344.entry.js} +1 -1
- package/dist/webcomponents/p-0b0cf355.entry.js +5 -0
- package/dist/webcomponents/p-0d2ca2f7.entry.js +5 -0
- package/dist/webcomponents/p-0d79ca44.entry.js +5 -0
- package/dist/webcomponents/p-0fe3c47b.entry.js +5 -0
- package/dist/webcomponents/p-116b53c9.entry.js +5 -0
- package/dist/webcomponents/p-1240dae7.entry.js +5 -0
- package/dist/webcomponents/p-14ff5865.entry.js +5 -0
- package/dist/webcomponents/p-15743a02.entry.js +5 -0
- package/dist/webcomponents/p-16cebf49.entry.js +5 -0
- package/dist/webcomponents/p-1884b9d3.entry.js +5 -0
- package/dist/webcomponents/p-19a38e20.entry.js +5 -0
- package/dist/webcomponents/p-1d36c8fa.entry.js +5 -0
- package/dist/webcomponents/p-1fa4b5b2.entry.js +5 -0
- package/dist/webcomponents/p-212c069b.entry.js +5 -0
- package/dist/webcomponents/p-23f37cd6.entry.js +5 -0
- package/dist/webcomponents/p-24502b63.entry.js +5 -0
- package/dist/webcomponents/p-27fb81f3.entry.js +5 -0
- package/dist/webcomponents/p-28844490.entry.js +5 -0
- package/dist/webcomponents/p-2b41bdcc.entry.js +5 -0
- package/dist/webcomponents/p-2cb1e09b.entry.js +5 -0
- package/dist/webcomponents/p-2fcda70b.entry.js +5 -0
- package/dist/webcomponents/p-3378300c.entry.js +5 -0
- package/dist/webcomponents/p-3ae9cf69.entry.js +5 -0
- package/dist/webcomponents/p-3b79cd49.entry.js +5 -0
- package/dist/webcomponents/p-3c1513ec.entry.js +5 -0
- package/dist/webcomponents/p-4118b878.entry.js +5 -0
- package/dist/webcomponents/p-4534a3c3.entry.js +5 -0
- package/dist/webcomponents/p-48abf568.entry.js +5 -0
- package/dist/webcomponents/p-4e5ea05c.entry.js +5 -0
- package/dist/webcomponents/p-513ee754.entry.js +5 -0
- package/dist/webcomponents/p-521a1076.entry.js +5 -0
- package/dist/webcomponents/p-59fc52c0.entry.js +5 -0
- package/dist/webcomponents/p-5a7c2031.entry.js +5 -0
- package/dist/webcomponents/p-5a9f4ea2.entry.js +5 -0
- package/dist/webcomponents/p-5f422a69.entry.js +5 -0
- package/dist/webcomponents/p-61977114.entry.js +5 -0
- package/dist/webcomponents/p-6850e98e.entry.js +5 -0
- package/dist/webcomponents/p-71853dfc.entry.js +5 -0
- package/dist/webcomponents/p-76d51654.entry.js +5 -0
- package/dist/webcomponents/p-77e242f3.entry.js +5 -0
- package/dist/webcomponents/p-7b849472.entry.js +5 -0
- package/dist/webcomponents/p-7dbfb875.entry.js +5 -0
- package/dist/webcomponents/p-7fa7f052.entry.js +5 -0
- package/dist/webcomponents/p-81c65747.entry.js +5 -0
- package/dist/webcomponents/p-82759002.entry.js +5 -0
- package/dist/webcomponents/p-91a5329f.entry.js +5 -0
- package/dist/webcomponents/p-94848046.entry.js +5 -0
- package/dist/webcomponents/p-966773a9.entry.js +5 -0
- package/dist/webcomponents/p-9abb5a53.entry.js +5 -0
- package/dist/webcomponents/p-9bf2e325.entry.js +5 -0
- package/dist/webcomponents/p-9c943b40.entry.js +5 -0
- package/dist/webcomponents/p-9ec3ca00.entry.js +5 -0
- package/dist/webcomponents/p-B0PbhaxL.js +5 -0
- package/dist/webcomponents/p-BEJGB0Nd.js +5 -0
- package/dist/{components/p-Dmfk7eEe.js → webcomponents/p-BJZC_NuV.js} +1 -1
- package/dist/webcomponents/p-BJtdabsr.js +5 -0
- package/dist/webcomponents/p-BeJxz5TQ.js +5 -0
- package/dist/webcomponents/p-BkWWrDEr.js +5 -0
- package/dist/webcomponents/p-BlGV-x0w.js +5 -0
- package/dist/webcomponents/{p-Bfm58jO6.js → p-BtRPYRvA.js} +1 -1
- package/dist/webcomponents/p-CDtFCbKp.js +5 -0
- package/dist/webcomponents/p-CNwZRgyL.js +5 -0
- package/dist/webcomponents/{p-DFN_so7I.js → p-CfuJQ1DY.js} +1 -1
- package/dist/webcomponents/p-ConyRdJe.js +7 -0
- package/dist/webcomponents/p-D9Zo6FlV.js +5 -0
- package/dist/webcomponents/{p-BhMVJQ4-.js → p-DV-iW9Aj.js} +1 -1
- package/dist/webcomponents/p-DWhzxlCx.js +5 -0
- package/dist/webcomponents/p-EbtQZm5s.js +5 -0
- package/dist/webcomponents/p-ad91f149.entry.js +5 -0
- package/dist/webcomponents/p-aeea1f17.entry.js +5 -0
- package/dist/webcomponents/p-b02a7218.entry.js +5 -0
- package/dist/webcomponents/p-b16590fc.entry.js +5 -0
- package/dist/webcomponents/{p-12286e73.entry.js → p-b55425b7.entry.js} +1 -1
- package/dist/webcomponents/p-c1dafd8d.entry.js +5 -0
- package/dist/webcomponents/p-c2ca0289.entry.js +5 -0
- package/dist/webcomponents/p-c8af334e.entry.js +5 -0
- package/dist/webcomponents/p-cac49c6a.entry.js +5 -0
- package/dist/webcomponents/p-cb9ebfbe.entry.js +5 -0
- package/dist/webcomponents/p-ce3d689c.entry.js +5 -0
- package/dist/webcomponents/p-d11f95a0.entry.js +5 -0
- package/dist/webcomponents/p-d5d2205c.entry.js +5 -0
- package/dist/webcomponents/p-dad03b49.entry.js +5 -0
- package/dist/webcomponents/p-db8e6322.entry.js +5 -0
- package/dist/webcomponents/p-dea8015f.entry.js +5 -0
- package/dist/webcomponents/p-e07e309d.entry.js +5 -0
- package/dist/webcomponents/p-e53d874b.entry.js +5 -0
- package/dist/webcomponents/p-e5540387.entry.js +5 -0
- package/dist/webcomponents/p-e94a52ac.entry.js +5 -0
- package/dist/webcomponents/p-e9be4d3f.entry.js +5 -0
- package/dist/webcomponents/p-e9db9381.entry.js +5 -0
- package/dist/webcomponents/p-edca5de1.entry.js +5 -0
- package/dist/webcomponents/p-ee5b9fc9.entry.js +5 -0
- package/dist/webcomponents/p-f4ef8c63.entry.js +5 -0
- package/dist/webcomponents/p-zlORkiHQ.js +5 -0
- package/dist/webcomponents/webcomponents.esm.js +1 -1
- package/package.json +18 -3
- package/dist/cjs/clamp-Co_hWptd.js +0 -25
- package/dist/cjs/id-CjRFMzf6.js +0 -20
- package/dist/cjs/props-CScmBvKd.js +0 -24
- package/dist/collection/pages/components/cookiebar/index.js +0 -26
- package/dist/collection/pages/components/link/index.js +0 -29
- package/dist/collection/pages/components/pagination/index.js +0 -12
- package/dist/collection/pages/components/slider/index.js +0 -18
- package/dist/components/p-6OdfnwnK.js +0 -5
- package/dist/components/p-AmOh1cks.js +0 -5
- package/dist/components/p-B4ylcipx.js +0 -5
- package/dist/components/p-BCv4PCOx.js +0 -5
- package/dist/components/p-BLOyd_iF.js +0 -5
- package/dist/components/p-BODem6tr.js +0 -5
- package/dist/components/p-Bb-nLtTG.js +0 -5
- package/dist/components/p-BeFK-82z.js +0 -5
- package/dist/components/p-BkS6ujyf.js +0 -5
- package/dist/components/p-BloE-KAN.js +0 -5
- package/dist/components/p-BoSc_kmY.js +0 -5
- package/dist/components/p-BrH3r7eL.js +0 -5
- package/dist/components/p-BsZ0Ny88.js +0 -5
- package/dist/components/p-ByHVf7zy.js +0 -5
- package/dist/components/p-CdDwqbBv.js +0 -5
- package/dist/components/p-CdF-gmk1.js +0 -5
- package/dist/components/p-CfyjGPGI.js +0 -5
- package/dist/components/p-CjF7pBVQ.js +0 -5
- package/dist/components/p-ClqtllDH.js +0 -5
- package/dist/components/p-CqW2Yh34.js +0 -5
- package/dist/components/p-DIK54tTj.js +0 -5
- package/dist/components/p-DLE5ioJN.js +0 -5
- package/dist/components/p-DQRSHR-D.js +0 -5
- package/dist/components/p-DRVMm1Py.js +0 -5
- package/dist/components/p-DRnCpVrL.js +0 -5
- package/dist/components/p-DVdlaP7z.js +0 -5
- package/dist/components/p-DeeF6ok0.js +0 -5
- package/dist/components/p-Dim2PnUm.js +0 -5
- package/dist/components/p-Dk8rfQjL.js +0 -5
- package/dist/components/p-DkmEpoef.js +0 -5
- package/dist/components/p-DwfAYaEv.js +0 -5
- package/dist/components/p-DxZJrIyL.js +0 -5
- package/dist/components/p-P2Z_MmH6.js +0 -5
- package/dist/components/p-Xa0Mj4pP.js +0 -5
- package/dist/components/p-_vsQvdxD.js +0 -5
- package/dist/components/p-aNjo4Alx.js +0 -5
- package/dist/components/p-gvnfuTjd.js +0 -5
- package/dist/components/p-rB-s1M3Q.js +0 -5
- package/dist/esm/clamp-gvnfuTjd.js +0 -23
- package/dist/esm/id-BkS6ujyf.js +0 -18
- package/dist/esm/props-DRVMm1Py.js +0 -22
- package/dist/webcomponents/p-00cc31f9.entry.js +0 -5
- package/dist/webcomponents/p-026475bd.entry.js +0 -5
- package/dist/webcomponents/p-0291ab28.entry.js +0 -5
- package/dist/webcomponents/p-03e5a7dc.entry.js +0 -5
- package/dist/webcomponents/p-060df8ee.entry.js +0 -5
- package/dist/webcomponents/p-09fce2a5.entry.js +0 -5
- package/dist/webcomponents/p-1002bbff.entry.js +0 -5
- package/dist/webcomponents/p-1124de33.entry.js +0 -5
- package/dist/webcomponents/p-12e97d80.entry.js +0 -5
- package/dist/webcomponents/p-1580beee.entry.js +0 -5
- package/dist/webcomponents/p-1b19b191.entry.js +0 -5
- package/dist/webcomponents/p-2baf353b.entry.js +0 -5
- package/dist/webcomponents/p-2eb9a42c.entry.js +0 -5
- package/dist/webcomponents/p-30c82805.entry.js +0 -5
- package/dist/webcomponents/p-31bd1c74.entry.js +0 -5
- package/dist/webcomponents/p-31db2313.entry.js +0 -5
- package/dist/webcomponents/p-33a3dc63.entry.js +0 -5
- package/dist/webcomponents/p-3889c51f.entry.js +0 -5
- package/dist/webcomponents/p-3f2c179a.entry.js +0 -5
- package/dist/webcomponents/p-470eb770.entry.js +0 -5
- package/dist/webcomponents/p-4ae387ae.entry.js +0 -5
- package/dist/webcomponents/p-4e65df84.entry.js +0 -5
- package/dist/webcomponents/p-51a62876.entry.js +0 -5
- package/dist/webcomponents/p-5860b96b.entry.js +0 -5
- package/dist/webcomponents/p-5b9c01e9.entry.js +0 -5
- package/dist/webcomponents/p-5df2f1dd.entry.js +0 -5
- package/dist/webcomponents/p-5f3f7b3f.entry.js +0 -5
- package/dist/webcomponents/p-5f6afb79.entry.js +0 -5
- package/dist/webcomponents/p-5f9c28a7.entry.js +0 -5
- package/dist/webcomponents/p-62511921.entry.js +0 -5
- package/dist/webcomponents/p-63b52947.entry.js +0 -5
- package/dist/webcomponents/p-67a8e0b7.entry.js +0 -5
- package/dist/webcomponents/p-6OdfnwnK.js +0 -5
- package/dist/webcomponents/p-7b2a5fec.entry.js +0 -5
- package/dist/webcomponents/p-7f95e2f5.entry.js +0 -5
- package/dist/webcomponents/p-8128833c.entry.js +0 -5
- package/dist/webcomponents/p-8200ccb1.entry.js +0 -5
- package/dist/webcomponents/p-82b100fd.entry.js +0 -5
- package/dist/webcomponents/p-8806df15.entry.js +0 -5
- package/dist/webcomponents/p-881eb81a.entry.js +0 -5
- package/dist/webcomponents/p-8bd3d541.entry.js +0 -5
- package/dist/webcomponents/p-90648343.entry.js +0 -5
- package/dist/webcomponents/p-9100a5f7.entry.js +0 -5
- package/dist/webcomponents/p-91313d77.entry.js +0 -5
- package/dist/webcomponents/p-946b2ac0.entry.js +0 -5
- package/dist/webcomponents/p-98e7ccb9.entry.js +0 -5
- package/dist/webcomponents/p-99f2bddb.entry.js +0 -5
- package/dist/webcomponents/p-9adbdb0a.entry.js +0 -5
- package/dist/webcomponents/p-9c260049.entry.js +0 -5
- package/dist/webcomponents/p-9ed51017.entry.js +0 -5
- package/dist/webcomponents/p-BkS6ujyf.js +0 -5
- package/dist/webcomponents/p-C2RBydfd.js +0 -6
- package/dist/webcomponents/p-CO5cOQQU.js +0 -5
- package/dist/webcomponents/p-D3tVP32U.js +0 -5
- package/dist/webcomponents/p-DIK54tTj.js +0 -5
- package/dist/webcomponents/p-DRVMm1Py.js +0 -5
- package/dist/webcomponents/p-DxZJrIyL.js +0 -5
- package/dist/webcomponents/p-a0b299dd.entry.js +0 -5
- package/dist/webcomponents/p-a2c5fad0.entry.js +0 -5
- package/dist/webcomponents/p-a3e044d7.entry.js +0 -5
- package/dist/webcomponents/p-a9f23aa7.entry.js +0 -5
- package/dist/webcomponents/p-a9f2fcbc.entry.js +0 -5
- package/dist/webcomponents/p-b6c68136.entry.js +0 -5
- package/dist/webcomponents/p-b6e9b8d1.entry.js +0 -5
- package/dist/webcomponents/p-c333eac6.entry.js +0 -5
- package/dist/webcomponents/p-c3732fd6.entry.js +0 -5
- package/dist/webcomponents/p-c458ed0e.entry.js +0 -5
- package/dist/webcomponents/p-c91000ff.entry.js +0 -5
- package/dist/webcomponents/p-c9c6ab2d.entry.js +0 -5
- package/dist/webcomponents/p-cd2550d6.entry.js +0 -5
- package/dist/webcomponents/p-cf42613f.entry.js +0 -5
- package/dist/webcomponents/p-d0b0b420.entry.js +0 -5
- package/dist/webcomponents/p-d1b32ee8.entry.js +0 -5
- package/dist/webcomponents/p-db65b083.entry.js +0 -5
- package/dist/webcomponents/p-de7c101d.entry.js +0 -5
- package/dist/webcomponents/p-dfb77dd0.entry.js +0 -5
- package/dist/webcomponents/p-e258da78.entry.js +0 -5
- package/dist/webcomponents/p-e31ddd42.entry.js +0 -5
- package/dist/webcomponents/p-e8d82227.entry.js +0 -5
- package/dist/webcomponents/p-e988cf1d.entry.js +0 -5
- package/dist/webcomponents/p-ed9122a1.entry.js +0 -5
- package/dist/webcomponents/p-ee347d2e.entry.js +0 -5
- package/dist/webcomponents/p-f1c01d52.entry.js +0 -5
- package/dist/webcomponents/p-f5baf8be.entry.js +0 -5
- package/dist/webcomponents/p-fb593739.entry.js +0 -5
- package/dist/webcomponents/p-fff9acd4.entry.js +0 -5
- package/dist/webcomponents/p-gvnfuTjd.js +0 -5
|
@@ -4,10 +4,77 @@ const CLEAR_COMPONENTS_FILTER = document.getElementById('clear-components-filter
|
|
|
4
4
|
|
|
5
5
|
let renderedFilesContent = {};
|
|
6
6
|
let currentLoadedPath = null;
|
|
7
|
+
let pageLoadGeneration = 0;
|
|
8
|
+
const activeExampleCleanups = new Set();
|
|
7
9
|
const markdownParser = window.marked;
|
|
8
|
-
const DEV_SERVER_CONNECTOR_IFRAME_RE =
|
|
9
|
-
/<iframe\b[^>]*title=["']Stencil Dev Server Connector[^"']*["'][\s\S]*?<\/iframe>/gi;
|
|
10
10
|
let lzStringPromise;
|
|
11
|
+
const MAX_PLAYGROUND_DRAFT_SIZE = 512 * 1024;
|
|
12
|
+
const DEV_VIEWPORTS = [
|
|
13
|
+
{ id: 'desktop', label: 'Desktop (100%)', icon: 'fas fa-desktop', mode: 'web', width: null, height: null },
|
|
14
|
+
{ id: 'tablet', label: 'Tablet - 768px', icon: 'fas fa-tablet-alt', mode: 'web', width: 768, height: 600 },
|
|
15
|
+
{ id: 'ios', label: 'iPhone (iOS) - 390x844', icon: 'fab fa-apple', mode: 'ios', width: 390, height: 844 },
|
|
16
|
+
{ id: 'android', label: 'Android - 360x800', icon: 'fab fa-android', mode: 'android', width: 360, height: 800 },
|
|
17
|
+
];
|
|
18
|
+
const DEV_PREVIEW_MIN_WIDTH = 200;
|
|
19
|
+
const DEV_PREVIEW_MIN_HEIGHT = 180;
|
|
20
|
+
const DEV_PREVIEW_RESIZE_STEP = 16;
|
|
21
|
+
|
|
22
|
+
function createPreviewResizeHandle(axis) {
|
|
23
|
+
const isWidthHandle = axis === 'vertical';
|
|
24
|
+
const handle = document.createElement('div');
|
|
25
|
+
handle.className = `wbc-example-preview-resize-handle wbc-example-preview-resize-handle--${axis}`;
|
|
26
|
+
handle.setAttribute('role', 'separator');
|
|
27
|
+
handle.setAttribute('tabindex', '0');
|
|
28
|
+
handle.setAttribute(
|
|
29
|
+
'aria-label',
|
|
30
|
+
isWidthHandle ? 'Redimensionar largura do preview' : 'Redimensionar altura do preview',
|
|
31
|
+
);
|
|
32
|
+
handle.setAttribute('aria-orientation', axis);
|
|
33
|
+
const line = document.createElement('span');
|
|
34
|
+
line.className = 'wbc-example-preview-resize-handle__line';
|
|
35
|
+
handle.appendChild(line);
|
|
36
|
+
return handle;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getPreviewResizeDelta(key, decreaseKey, increaseKey) {
|
|
40
|
+
if (key === decreaseKey) return -DEV_PREVIEW_RESIZE_STEP;
|
|
41
|
+
if (key === increaseKey) return DEV_PREVIEW_RESIZE_STEP;
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function getPlaygroundDraftKey(path, file) {
|
|
46
|
+
return `wbc-playground-draft:${path}/${file}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function readPlaygroundDraft(path, file) {
|
|
50
|
+
try {
|
|
51
|
+
const raw = window.localStorage.getItem(getPlaygroundDraftKey(path, file));
|
|
52
|
+
if (!raw || raw.length > MAX_PLAYGROUND_DRAFT_SIZE) return null;
|
|
53
|
+
const draft = JSON.parse(raw);
|
|
54
|
+
if (typeof draft?.html !== 'string') return null;
|
|
55
|
+
return draft;
|
|
56
|
+
} catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function writePlaygroundDraft(path, file, draft) {
|
|
62
|
+
try {
|
|
63
|
+
const serialized = JSON.stringify({ ...draft, updatedAt: Date.now() });
|
|
64
|
+
if (serialized.length > MAX_PLAYGROUND_DRAFT_SIZE) return false;
|
|
65
|
+
window.localStorage.setItem(getPlaygroundDraftKey(path, file), serialized);
|
|
66
|
+
return true;
|
|
67
|
+
} catch {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function getScrollBehavior() {
|
|
73
|
+
const prefersReducedMotion =
|
|
74
|
+
(typeof document !== 'undefined' && document.documentElement.dataset.wbcReducedMotion === 'true') ||
|
|
75
|
+
(typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches);
|
|
76
|
+
return prefersReducedMotion ? 'auto' : 'smooth';
|
|
77
|
+
}
|
|
11
78
|
|
|
12
79
|
function loadLzString() {
|
|
13
80
|
if (window.LZString) return Promise.resolve(window.LZString);
|
|
@@ -23,6 +90,13 @@ function loadLzString() {
|
|
|
23
90
|
return lzStringPromise;
|
|
24
91
|
}
|
|
25
92
|
|
|
93
|
+
function cleanupExamples() {
|
|
94
|
+
activeExampleCleanups.forEach((cleanup) => {
|
|
95
|
+
cleanup();
|
|
96
|
+
});
|
|
97
|
+
activeExampleCleanups.clear();
|
|
98
|
+
}
|
|
99
|
+
|
|
26
100
|
// Decode shared state from URL parameters on initialization
|
|
27
101
|
(() => {
|
|
28
102
|
const params = new URLSearchParams(window.location.search);
|
|
@@ -53,313 +127,7 @@ function getBaseUrl() {
|
|
|
53
127
|
return baseUrl === '' ? '' : baseUrl;
|
|
54
128
|
}
|
|
55
129
|
|
|
56
|
-
function
|
|
57
|
-
const frame = previewElement.querySelector('iframe');
|
|
58
|
-
if (!frame) return;
|
|
59
|
-
|
|
60
|
-
const baseUrl = getBaseUrl();
|
|
61
|
-
const componentBundleUrl = new URL(`${baseUrl}/build/webcomponents.esm.js`, window.location.href);
|
|
62
|
-
componentBundleUrl.searchParams.set('preview-version', String(Date.now()));
|
|
63
|
-
const componentBundle = componentBundleUrl.href;
|
|
64
|
-
const frameSource = stripDevServerConnector(source);
|
|
65
|
-
|
|
66
|
-
frame.srcdoc = `<!doctype html>
|
|
67
|
-
<html lang="pt-BR">
|
|
68
|
-
<head>
|
|
69
|
-
<meta charset="UTF-8">
|
|
70
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
71
|
-
<base href="${window.location.href}">
|
|
72
|
-
<link rel="stylesheet" href="${new URL(`${baseUrl}/assets/core.min.css`, window.location.href).href}">
|
|
73
|
-
<link rel="stylesheet" href="${new URL(`${baseUrl}/assets/fonts/rawline/400.css`, window.location.href).href}">
|
|
74
|
-
<link rel="stylesheet" href="${new URL(`${baseUrl}/assets/fonts/raleway/wght.css`, window.location.href).href}">
|
|
75
|
-
<link rel="stylesheet" href="${new URL(`${baseUrl}/assets/fonts/fontawesome/css/all.min.css`, window.location.href).href}">
|
|
76
|
-
<style>
|
|
77
|
-
* { font-family: Rawline, Raleway, sans-serif; }
|
|
78
|
-
html, body { margin: 0; min-height: 1px; overflow: visible; }
|
|
79
|
-
body { box-sizing: border-box; padding: 24px 16px; }
|
|
80
|
-
body.wbc-preview-edge-to-edge { padding: 0; }
|
|
81
|
-
br-cookiebar, br-scrim { inset: 0; position: absolute; pointer-events: none; z-index: 1000; }
|
|
82
|
-
br-scrim { --scrim-display-mode: parent; }
|
|
83
|
-
</style>
|
|
84
|
-
</head>
|
|
85
|
-
<body${edgeToEdge ? ' class="wbc-preview-edge-to-edge"' : ''}><main data-wbc-preview-content>${frameSource}</main>
|
|
86
|
-
<script type="module" src="${componentBundle}"></script>
|
|
87
|
-
<script>
|
|
88
|
-
(() => {
|
|
89
|
-
const overlayContentSelector =
|
|
90
|
-
'[part="open-panel"], [part="default-panel"], [part="body"], .cookiebar-body, .content, .br-modal';
|
|
91
|
-
const getOverlayHeight = (overlay) => {
|
|
92
|
-
const measuredHeight = Array.from(overlay.shadowRoot?.querySelectorAll(overlayContentSelector) || []).reduce(
|
|
93
|
-
(height, element) =>
|
|
94
|
-
Math.max(height, element.scrollHeight, element.clientHeight, element.getBoundingClientRect().height),
|
|
95
|
-
0,
|
|
96
|
-
);
|
|
97
|
-
if (measuredHeight > 0) return measuredHeight;
|
|
98
|
-
|
|
99
|
-
const modal = overlay.matches('br-scrim') ? overlay.querySelector('br-modal') : overlay;
|
|
100
|
-
return modal?.shadowRoot?.querySelector('.br-modal')?.getBoundingClientRect().height || 0;
|
|
101
|
-
};
|
|
102
|
-
const getElementsIncludingShadowRoots = (root = document) => {
|
|
103
|
-
const elements = [];
|
|
104
|
-
const visit = (tree) => {
|
|
105
|
-
tree.querySelectorAll('*').forEach((element) => {
|
|
106
|
-
elements.push(element);
|
|
107
|
-
if (element.shadowRoot) visit(element.shadowRoot);
|
|
108
|
-
});
|
|
109
|
-
};
|
|
110
|
-
visit(root);
|
|
111
|
-
return elements;
|
|
112
|
-
};
|
|
113
|
-
const getFloatingHeight = () => {
|
|
114
|
-
const bodyStyle = getComputedStyle(document.body);
|
|
115
|
-
const bottomPadding = parseFloat(bodyStyle.paddingBottom) || 0;
|
|
116
|
-
return getElementsIncludingShadowRoots().reduce((height, element) => {
|
|
117
|
-
if (element.matches('br-cookiebar, br-scrim, br-modal')) return height;
|
|
118
|
-
const style = getComputedStyle(element);
|
|
119
|
-
if (style.position !== 'absolute' && style.position !== 'fixed') return height;
|
|
120
|
-
if (style.display === 'none' || style.visibility === 'hidden') return height;
|
|
121
|
-
return Math.max(height, element.getBoundingClientRect().bottom + bottomPadding);
|
|
122
|
-
}, 0);
|
|
123
|
-
};
|
|
124
|
-
const sendHeight = () => {
|
|
125
|
-
const body = document.body;
|
|
126
|
-
const bodyStyle = getComputedStyle(body);
|
|
127
|
-
const overlayHeight = Array.from(document.querySelectorAll('br-cookiebar, br-scrim, br-modal')).reduce(
|
|
128
|
-
(height, overlay) => Math.max(height, getOverlayHeight(overlay)),
|
|
129
|
-
0,
|
|
130
|
-
);
|
|
131
|
-
const verticalPadding = parseFloat(bodyStyle.paddingTop) + parseFloat(bodyStyle.paddingBottom);
|
|
132
|
-
const height = Math.ceil(
|
|
133
|
-
Math.max(
|
|
134
|
-
body.scrollHeight,
|
|
135
|
-
body.offsetHeight,
|
|
136
|
-
body.getBoundingClientRect().height,
|
|
137
|
-
overlayHeight + verticalPadding,
|
|
138
|
-
getFloatingHeight(),
|
|
139
|
-
),
|
|
140
|
-
);
|
|
141
|
-
parent.postMessage({ type: 'wbc-preview-height', height }, '*');
|
|
142
|
-
};
|
|
143
|
-
document.querySelectorAll('br-cookiebar, br-scrim').forEach((overlay) => {
|
|
144
|
-
overlay.setAttribute('data-wbc-preview-contained', '');
|
|
145
|
-
if (overlay.matches('br-scrim')) overlay.setAttribute('display-mode', 'parent');
|
|
146
|
-
});
|
|
147
|
-
const serialize = (value, seen = new WeakSet()) => {
|
|
148
|
-
if (value instanceof Element) return '<' + value.localName + '>';
|
|
149
|
-
if (value instanceof Event) return { type: value.type };
|
|
150
|
-
if (value && typeof value === 'object') {
|
|
151
|
-
if (seen.has(value)) return '[Circular]';
|
|
152
|
-
seen.add(value);
|
|
153
|
-
if (Array.isArray(value)) return value.map((item) => serialize(item, seen));
|
|
154
|
-
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, serialize(item, seen)]));
|
|
155
|
-
}
|
|
156
|
-
return value;
|
|
157
|
-
};
|
|
158
|
-
const sendEvent = (event, dispatchedBy = event.target) => {
|
|
159
|
-
const target = dispatchedBy instanceof Element ? dispatchedBy : dispatchedBy?.host instanceof Element ? dispatchedBy.host : null;
|
|
160
|
-
parent.postMessage({
|
|
161
|
-
type: 'wbc-preview-event',
|
|
162
|
-
eventType: event.type,
|
|
163
|
-
custom: event instanceof CustomEvent,
|
|
164
|
-
detail: event instanceof CustomEvent ? serialize(event.detail) : undefined,
|
|
165
|
-
target: target ? target.localName + (target.id ? '#' + target.id : '') : 'window',
|
|
166
|
-
}, '*');
|
|
167
|
-
};
|
|
168
|
-
['change', 'click', 'input', 'submit'].forEach((name) => document.addEventListener(name, sendEvent, true));
|
|
169
|
-
document.addEventListener('brInternalEvent', sendEvent, true);
|
|
170
|
-
const originalDispatchEvent = EventTarget.prototype.dispatchEvent;
|
|
171
|
-
EventTarget.prototype.dispatchEvent = function dispatchEvent(event) {
|
|
172
|
-
if (event instanceof CustomEvent) sendEvent(event, this);
|
|
173
|
-
return originalDispatchEvent.call(this, event);
|
|
174
|
-
};
|
|
175
|
-
let heightFrame = 0;
|
|
176
|
-
const scheduleHeight = () => {
|
|
177
|
-
cancelAnimationFrame(heightFrame);
|
|
178
|
-
heightFrame = requestAnimationFrame(sendHeight);
|
|
179
|
-
};
|
|
180
|
-
const resizeObserver = new ResizeObserver(scheduleHeight);
|
|
181
|
-
const observeOverlayContent = () => {
|
|
182
|
-
document.querySelectorAll('br-cookiebar, br-scrim, br-modal').forEach((overlay) => {
|
|
183
|
-
overlay.shadowRoot?.querySelectorAll(overlayContentSelector).forEach((element) => {
|
|
184
|
-
resizeObserver.observe(element);
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
getElementsIncludingShadowRoots().forEach((element) => {
|
|
188
|
-
const position = getComputedStyle(element).position;
|
|
189
|
-
if (position === 'absolute' || position === 'fixed') resizeObserver.observe(element);
|
|
190
|
-
});
|
|
191
|
-
};
|
|
192
|
-
resizeObserver.observe(document.documentElement);
|
|
193
|
-
resizeObserver.observe(document.body);
|
|
194
|
-
new MutationObserver(() =>
|
|
195
|
-
requestAnimationFrame(() => {
|
|
196
|
-
observeOverlayContent();
|
|
197
|
-
scheduleHeight();
|
|
198
|
-
}),
|
|
199
|
-
).observe(document.body, { attributes: true, childList: true, subtree: true });
|
|
200
|
-
Promise.all(
|
|
201
|
-
[...document.querySelectorAll('*')]
|
|
202
|
-
.map((element) => element.localName)
|
|
203
|
-
.filter((tag, index, tags) => tag.includes('-') && tags.indexOf(tag) === index)
|
|
204
|
-
.map((tag) => customElements.whenDefined(tag)),
|
|
205
|
-
).then(() =>
|
|
206
|
-
requestAnimationFrame(() =>
|
|
207
|
-
requestAnimationFrame(() => {
|
|
208
|
-
observeOverlayContent();
|
|
209
|
-
scheduleHeight();
|
|
210
|
-
}),
|
|
211
|
-
),
|
|
212
|
-
);
|
|
213
|
-
addEventListener('load', scheduleHeight);
|
|
214
|
-
scheduleHeight();
|
|
215
|
-
})();
|
|
216
|
-
</script>
|
|
217
|
-
</body>
|
|
218
|
-
</html>`;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
function stripDevServerConnector(source) {
|
|
222
|
-
return String(source || '')
|
|
223
|
-
.replace(DEV_SERVER_CONNECTOR_IFRAME_RE, '')
|
|
224
|
-
.trim();
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
function getFrameworkCode(source, framework) {
|
|
228
|
-
const html = String(source || '').trim();
|
|
229
|
-
const components = Array.from(html.matchAll(/<\/?(br-[a-z0-9-]+)/gi), (match) => match[1]);
|
|
230
|
-
const imports = [...new Set(components)].map((tag) =>
|
|
231
|
-
tag
|
|
232
|
-
.split('-')
|
|
233
|
-
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
234
|
-
.join(''),
|
|
235
|
-
);
|
|
236
|
-
const importList = imports.length > 0 ? imports.join(', ') : 'BrButton';
|
|
237
|
-
const pascalMarkup = html.replace(/(<\/?)(br-[a-z0-9-]+)/gi, (_match, prefix, tag) => {
|
|
238
|
-
return `${prefix}${tag
|
|
239
|
-
.split('-')
|
|
240
|
-
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
241
|
-
.join('')}`;
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
if (framework === 'javascript') {
|
|
245
|
-
return `import { ${importList} } from '@govbr-ds/webcomponents';\n\nconst example = document.querySelector('${components[0] || 'br-button'}');\n\n// Use o exemplo renderizado para adicionar comportamento com JavaScript.\nconsole.log(example);`;
|
|
246
|
-
}
|
|
247
|
-
if (framework === 'css') {
|
|
248
|
-
return `/* Customize os componentes usando CSS Parts */
|
|
249
|
-
/* Exemplo:
|
|
250
|
-
br-${String(location.pathname).split('/').filter(Boolean).pop() || 'component'}::part(container) {
|
|
251
|
-
background-color: #f8f9fa;
|
|
252
|
-
}
|
|
253
|
-
*/`;
|
|
254
|
-
}
|
|
255
|
-
if (framework === 'angular') {
|
|
256
|
-
return `import { Component } from '@angular/core';\nimport { ${importList} } from '@govbr-ds/webcomponents-angular/standalone';\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [${importList}],\n template: \`${html.replace(/`/g, '\\`')}\`,\n})\nexport class AppComponent {}`;
|
|
257
|
-
}
|
|
258
|
-
if (framework === 'react') {
|
|
259
|
-
return `import { ${importList} } from '@govbr-ds/webcomponents-react';\n\nexport default function App() {\n return (\n <>\n ${pascalMarkup.replace(/\n/g, '\n ')}\n </>\n );\n}`;
|
|
260
|
-
}
|
|
261
|
-
return `<script setup lang="ts">\nimport { ${importList} } from '@govbr-ds/webcomponents-vue';\n</script>\n\n<template>\n ${pascalMarkup.replace(/\n/g, '\n ')}\n</template>`;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
function getFrameworkFiles(source, framework) {
|
|
265
|
-
if (framework !== 'angular') return null;
|
|
266
|
-
|
|
267
|
-
const html = String(source || '').trim();
|
|
268
|
-
const components = Array.from(html.matchAll(/<\/?(br-[a-z0-9-]+)/gi), (match) => match[1]);
|
|
269
|
-
const imports = [...new Set(components)].map((tag) =>
|
|
270
|
-
tag
|
|
271
|
-
.split('-')
|
|
272
|
-
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
273
|
-
.join(''),
|
|
274
|
-
);
|
|
275
|
-
const importList = imports.length > 0 ? imports.join(', ') : 'BrButton';
|
|
276
|
-
|
|
277
|
-
return [
|
|
278
|
-
{
|
|
279
|
-
filename: 'app.component.ts',
|
|
280
|
-
language: 'typescript',
|
|
281
|
-
code: `import { Component } from '@angular/core'\nimport { ${importList} } from '@govbr-ds/webcomponents-angular/standalone'\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [${importList}],\n templateUrl: './app.component.html',\n})\nexport class AppComponent {}`,
|
|
282
|
-
},
|
|
283
|
-
{ filename: 'app.component.html', language: 'html', code: html },
|
|
284
|
-
];
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
function createReadOnlyFrameworkTab(label, icon, tabId, source, framework) {
|
|
288
|
-
const tab = document.createElement('br-tab-item');
|
|
289
|
-
tab.setAttribute('label', label);
|
|
290
|
-
tab.setAttribute('icon', icon);
|
|
291
|
-
tab.setAttribute('icon-only', 'true');
|
|
292
|
-
tab.setAttribute('title', label);
|
|
293
|
-
tab.setAttribute('tab-item-id', tabId);
|
|
294
|
-
tab.dataset.framework = framework;
|
|
295
|
-
|
|
296
|
-
const files = getFrameworkFiles(source, framework);
|
|
297
|
-
tab._frameworkFiles = files;
|
|
298
|
-
|
|
299
|
-
if (files?.length > 1) {
|
|
300
|
-
const fileTabs = document.createElement('div');
|
|
301
|
-
fileTabs.className = 'wbc-framework-file-tabs';
|
|
302
|
-
fileTabs.setAttribute('role', 'tablist');
|
|
303
|
-
files.forEach((file, index) => {
|
|
304
|
-
const fileTab = document.createElement('button');
|
|
305
|
-
fileTab.className = `wbc-framework-file-tab${index === 0 ? ' is-active' : ''}`;
|
|
306
|
-
fileTab.type = 'button';
|
|
307
|
-
fileTab.dataset.filename = file.filename;
|
|
308
|
-
fileTab.setAttribute('aria-selected', String(index === 0));
|
|
309
|
-
fileTab.setAttribute('role', 'tab');
|
|
310
|
-
fileTab.textContent = file.filename;
|
|
311
|
-
fileTabs.appendChild(fileTab);
|
|
312
|
-
});
|
|
313
|
-
tab.appendChild(fileTabs);
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
const code = document.createElement('pre');
|
|
317
|
-
code.className = 'wbc-framework-code';
|
|
318
|
-
code.dataset.framework = framework;
|
|
319
|
-
code.dataset.filename = files?.[0]?.filename || '';
|
|
320
|
-
code.textContent = files?.[0]?.code || getFrameworkCode(source, framework);
|
|
321
|
-
tab.appendChild(code);
|
|
322
|
-
return tab;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
async function getPreviewAxeContext(previewFrame) {
|
|
326
|
-
const previewDocument = previewFrame.contentDocument;
|
|
327
|
-
const previewWindow = previewFrame.contentWindow;
|
|
328
|
-
if (!previewDocument?.body || !previewWindow) {
|
|
329
|
-
throw new Error('O conteúdo do preview ainda não está disponível.');
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
if (!previewWindow.axe) {
|
|
333
|
-
const axeScriptUrl = new URL(`${getBaseUrl()}/assets/axe-core.min.js`, window.location.href).href;
|
|
334
|
-
|
|
335
|
-
const response = await fetch(axeScriptUrl);
|
|
336
|
-
if (!response.ok) throw new Error('Não foi possível carregar o Axe-Core no preview.');
|
|
337
|
-
|
|
338
|
-
const axeScript = previewDocument.createElement('script');
|
|
339
|
-
axeScript.textContent = await response.text();
|
|
340
|
-
previewDocument.head.appendChild(axeScript);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
const previewContent = previewDocument.querySelector('[data-wbc-preview-content]');
|
|
344
|
-
if (!previewContent) throw new Error('Não foi possível localizar o conteúdo do exemplo.');
|
|
345
|
-
|
|
346
|
-
return { axe: previewWindow.axe, previewContent };
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
function getExampleHash(file) {
|
|
350
|
-
return `#${encodeURIComponent(file)}`;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
function getRequestedExampleFile() {
|
|
354
|
-
if (!window.location.hash) return null;
|
|
355
|
-
try {
|
|
356
|
-
return decodeURIComponent(window.location.hash.slice(1));
|
|
357
|
-
} catch {
|
|
358
|
-
return window.location.hash.slice(1);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
130
|
+
function createExampleElement(path, file, text, presets = [], defaultPreset = '', exampleLabel = '') {
|
|
363
131
|
text = stripDevServerConnector(text);
|
|
364
132
|
const contentDiv = document.createElement('br-item');
|
|
365
133
|
contentDiv.classList.add('file', 'wbc-example');
|
|
@@ -367,54 +135,84 @@ function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
|
367
135
|
contentDiv.dataset.exampleFile = file;
|
|
368
136
|
const controlsScope = `wbc-example-${path}-${file}`.replace(/[^a-zA-Z0-9_-]/g, '-');
|
|
369
137
|
contentDiv.dataset.controlsScope = controlsScope;
|
|
138
|
+
const previewChannelId = `${controlsScope}-preview`;
|
|
370
139
|
|
|
371
|
-
const
|
|
372
|
-
dropdown.className = 'wbc-example-dropdown';
|
|
373
|
-
if (isExpanded) dropdown.setAttribute('is-open', '');
|
|
140
|
+
const exampleAbortController = new AbortController();
|
|
374
141
|
let initializeExample;
|
|
375
142
|
let isInitialized = false;
|
|
376
143
|
|
|
377
144
|
const preview = document.createElement('div');
|
|
378
145
|
preview.className = 'wbc-example-preview';
|
|
146
|
+
const previewViewport = document.createElement('div');
|
|
147
|
+
previewViewport.className = 'wbc-example-preview-viewport';
|
|
379
148
|
let previewFrame;
|
|
149
|
+
const previewWidthResizeHandle = createPreviewResizeHandle('vertical');
|
|
150
|
+
const previewHeightResizeHandle = createPreviewResizeHandle('horizontal');
|
|
151
|
+
let previewResizeState = null;
|
|
152
|
+
let hasManualPreviewHeight = false;
|
|
153
|
+
let activeViewport = DEV_VIEWPORTS[0];
|
|
154
|
+
let darkThemeEnabled = false;
|
|
155
|
+
let reducedMotionEnabled =
|
|
156
|
+
typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
380
157
|
|
|
381
158
|
// --- EDITOR CONTAINER ---
|
|
382
159
|
const editorContainer = document.createElement('div');
|
|
383
160
|
editorContainer.className = 'wbc-example-editor-container';
|
|
384
161
|
|
|
162
|
+
// Ids nativos das abas, com o escopo do exemplo para não duplicar ids entre exemplos da página.
|
|
163
|
+
const tabIds = Object.fromEntries(
|
|
164
|
+
['code', 'events', 'controls', 'a11y', 'javascript', 'css', 'angular', 'react', 'vue'].map((name) => [
|
|
165
|
+
name,
|
|
166
|
+
`${controlsScope}-${name}-tab`,
|
|
167
|
+
]),
|
|
168
|
+
);
|
|
385
169
|
const tabComponent = document.createElement('br-tab');
|
|
386
170
|
tabComponent.setAttribute('density', 'small');
|
|
387
|
-
|
|
171
|
+
// Ícones por classe (Font Awesome) em light DOM, pelo slot `icon-{id}` do br-tab.
|
|
172
|
+
const setTabIcon = (tabItem, iconClass) => {
|
|
173
|
+
const icon = document.createElement('i');
|
|
174
|
+
icon.slot = `icon-${tabItem.id}`;
|
|
175
|
+
icon.className = iconClass;
|
|
176
|
+
icon.setAttribute('aria-hidden', 'true');
|
|
177
|
+
tabComponent.appendChild(icon);
|
|
178
|
+
};
|
|
179
|
+
tabComponent.setAttribute('active-tab-id', tabIds.code);
|
|
180
|
+
tabComponent.setAttribute('data-playground-badges', '');
|
|
388
181
|
|
|
389
182
|
const codeTabItem = document.createElement('br-tab-item');
|
|
390
183
|
codeTabItem.setAttribute('label', 'HTML');
|
|
391
|
-
codeTabItem.setAttribute('icon', 'fab fa-html5');
|
|
392
184
|
codeTabItem.setAttribute('icon-only', 'true');
|
|
393
|
-
codeTabItem.setAttribute('title', 'HTML');
|
|
394
|
-
codeTabItem.
|
|
185
|
+
codeTabItem.setAttribute('title', 'Editor HTML');
|
|
186
|
+
codeTabItem.id = tabIds.code;
|
|
395
187
|
codeTabItem.setAttribute('active', 'true');
|
|
396
|
-
codeTabItem.setAttribute('is-active', 'true');
|
|
397
188
|
|
|
398
189
|
const eventsTabItem = document.createElement('br-tab-item');
|
|
399
190
|
eventsTabItem.setAttribute('label', 'Console');
|
|
400
|
-
eventsTabItem.setAttribute('icon', 'fas fa-terminal');
|
|
401
191
|
eventsTabItem.setAttribute('icon-only', 'true');
|
|
402
|
-
eventsTabItem.setAttribute('title', 'Console');
|
|
403
|
-
eventsTabItem.
|
|
192
|
+
eventsTabItem.setAttribute('title', 'Console: eventos e mensagens de runtime');
|
|
193
|
+
eventsTabItem.id = tabIds.events;
|
|
404
194
|
|
|
405
195
|
const controlsTabItem = document.createElement('br-tab-item');
|
|
406
196
|
controlsTabItem.setAttribute('label', 'Controles');
|
|
407
|
-
controlsTabItem.setAttribute('icon', 'fas fa-sliders-h');
|
|
408
197
|
controlsTabItem.setAttribute('icon-only', 'true');
|
|
409
|
-
controlsTabItem.setAttribute('title', 'Controles');
|
|
410
|
-
controlsTabItem.
|
|
411
|
-
|
|
412
|
-
const javascriptTabItem =
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
const
|
|
416
|
-
const
|
|
198
|
+
controlsTabItem.setAttribute('title', 'Controles do componente');
|
|
199
|
+
controlsTabItem.id = tabIds.controls;
|
|
200
|
+
|
|
201
|
+
const javascriptTabItem = createFrameworkTab('JS', 'fab fa-js', tabIds.javascript, text, 'javascript', {
|
|
202
|
+
editable: true,
|
|
203
|
+
});
|
|
204
|
+
const cssTabItem = createFrameworkTab('CSS', 'fab fa-css3-alt', tabIds.css, text, 'css', { editable: true });
|
|
205
|
+
const angularTabItem = createFrameworkTab('Angular', 'fab fa-angular', tabIds.angular, text, 'angular');
|
|
206
|
+
const reactTabItem = createFrameworkTab('React', 'fab fa-react', tabIds.react, text, 'react');
|
|
207
|
+
const vueTabItem = createFrameworkTab('Vue', 'fab fa-vuejs', tabIds.vue, text, 'vue');
|
|
417
208
|
const frameworkTabItems = [javascriptTabItem, cssTabItem, angularTabItem, reactTabItem, vueTabItem];
|
|
209
|
+
// Depois de os ids estarem definidos: o nome do slot depende do id da aba.
|
|
210
|
+
setTabIcon(codeTabItem, 'fab fa-html5');
|
|
211
|
+
setTabIcon(eventsTabItem, 'fas fa-terminal');
|
|
212
|
+
setTabIcon(controlsTabItem, 'fas fa-sliders-h');
|
|
213
|
+
frameworkTabItems.forEach((tab) => {
|
|
214
|
+
setTabIcon(tab, tab.dataset.icon);
|
|
215
|
+
});
|
|
418
216
|
const frameworkEditors = new Map();
|
|
419
217
|
const refreshFrameworkEditors = () => {
|
|
420
218
|
requestAnimationFrame(() => {
|
|
@@ -424,6 +222,7 @@ function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
|
424
222
|
});
|
|
425
223
|
};
|
|
426
224
|
const getFrameworkEditorLanguage = (framework) => {
|
|
225
|
+
if (framework === 'javascript') return 'javascript';
|
|
427
226
|
if (framework === 'css') return 'css';
|
|
428
227
|
if (framework === 'angular') return 'typescript';
|
|
429
228
|
if (framework === 'react') return 'tsx';
|
|
@@ -478,6 +277,7 @@ function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
|
478
277
|
|
|
479
278
|
const button = document.createElement('br-button');
|
|
480
279
|
button.setAttribute('slot', 'trigger');
|
|
280
|
+
button.setAttribute('type', 'button');
|
|
481
281
|
button.setAttribute('shape', 'circle');
|
|
482
282
|
button.setAttribute('density', 'small');
|
|
483
283
|
button.setAttribute('emphasis', 'secondary');
|
|
@@ -499,164 +299,826 @@ function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
|
499
299
|
return { tooltip, button, icon, tooltipContent };
|
|
500
300
|
};
|
|
501
301
|
|
|
502
|
-
const
|
|
302
|
+
const localDraft =
|
|
303
|
+
window.SHARED_STATE?.p === path && window.SHARED_STATE?.f === file ? null : readPlaygroundDraft(path, file);
|
|
304
|
+
const presetOptions = presets;
|
|
305
|
+
const draftPreset = presetOptions.find(({ id }) => id === localDraft?.presetId);
|
|
306
|
+
const draftBaseline = typeof localDraft?.baselineHtml === 'string' ? localDraft.baselineHtml : null;
|
|
307
|
+
const currentDraftBaseline = draftPreset ? getPresetSource(draftPreset) : text;
|
|
308
|
+
const activeDraft = draftBaseline === currentDraftBaseline ? localDraft : null;
|
|
309
|
+
const editorState = { value: activeDraft?.html || text };
|
|
310
|
+
const vanillaSources = {
|
|
311
|
+
html: editorState.value,
|
|
312
|
+
css: getFrameworkCode(editorState.value, 'css'),
|
|
313
|
+
javascript: getFrameworkCode(editorState.value, 'javascript'),
|
|
314
|
+
};
|
|
315
|
+
let activeVanillaFile = 'html';
|
|
316
|
+
let isSwitchingVanillaFile = false;
|
|
317
|
+
let comparisonBaseline = text;
|
|
318
|
+
const editorHistory = { entries: [editorState.value], index: 0 };
|
|
319
|
+
const editorHistoryLimit = 50;
|
|
320
|
+
let isApplyingEditorValue = false;
|
|
321
|
+
let controlsApi = null;
|
|
322
|
+
let isUpdatingFromControls = false;
|
|
323
|
+
let undoAction;
|
|
324
|
+
let redoAction;
|
|
325
|
+
let diffAction;
|
|
326
|
+
let overflowUndo;
|
|
327
|
+
let overflowRedo;
|
|
328
|
+
let overflowDiff;
|
|
503
329
|
let editorApi = null;
|
|
504
|
-
|
|
330
|
+
// O editor é compartilhado pelas abas index.html/index.css/index.js; fora da
|
|
331
|
+
// aba HTML, o HTML vigente é o último valor aplicado.
|
|
332
|
+
const getEditorValue = () =>
|
|
333
|
+
activeVanillaFile === 'html' ? (editorApi?.getValue() ?? editorState.value) : editorState.value;
|
|
505
334
|
const refreshEditor = () => {
|
|
506
335
|
requestAnimationFrame(() => requestAnimationFrame(() => editorApi?.refresh?.()));
|
|
507
336
|
};
|
|
337
|
+
const updateHistoryActions = () => {
|
|
338
|
+
if (undoAction) undoAction.button.disabled = editorHistory.index === 0;
|
|
339
|
+
if (redoAction) redoAction.button.disabled = editorHistory.index === editorHistory.entries.length - 1;
|
|
340
|
+
if (overflowUndo) overflowUndo.item.disabled = editorHistory.index === 0;
|
|
341
|
+
if (overflowRedo) overflowRedo.item.disabled = editorHistory.index === editorHistory.entries.length - 1;
|
|
342
|
+
};
|
|
343
|
+
const recordEditorHistory = (source) => {
|
|
344
|
+
if (editorHistory.entries[editorHistory.index] === source) return;
|
|
345
|
+
editorHistory.entries = editorHistory.entries.slice(0, editorHistory.index + 1);
|
|
346
|
+
editorHistory.entries.push(source);
|
|
347
|
+
if (editorHistory.entries.length > editorHistoryLimit) editorHistory.entries.shift();
|
|
348
|
+
editorHistory.index = editorHistory.entries.length - 1;
|
|
349
|
+
};
|
|
350
|
+
const moveEditorHistory = (offset) => {
|
|
351
|
+
const nextIndex = editorHistory.index + offset;
|
|
352
|
+
if (nextIndex < 0 || nextIndex >= editorHistory.entries.length) return;
|
|
353
|
+
editorHistory.index = nextIndex;
|
|
354
|
+
setEditorValue(editorHistory.entries[nextIndex], { recordHistory: false });
|
|
355
|
+
};
|
|
356
|
+
const handleEditorKeydown = (event) => {
|
|
357
|
+
if (!(event.ctrlKey || event.metaKey) || event.altKey) return;
|
|
358
|
+
const key = event.key.toLowerCase();
|
|
359
|
+
if (key === 'z') {
|
|
360
|
+
event.preventDefault();
|
|
361
|
+
event.stopPropagation();
|
|
362
|
+
moveEditorHistory(event.shiftKey ? 1 : -1);
|
|
363
|
+
} else if (key === 'y') {
|
|
364
|
+
event.preventDefault();
|
|
365
|
+
event.stopPropagation();
|
|
366
|
+
moveEditorHistory(1);
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
undoAction = createActionButton('fas fa-undo', 'Desfazer alteração', 'Desfazer alteração', () =>
|
|
371
|
+
moveEditorHistory(-1),
|
|
372
|
+
);
|
|
373
|
+
redoAction = createActionButton('fas fa-redo', 'Refazer alteração', 'Refazer alteração', () => moveEditorHistory(1));
|
|
374
|
+
diffAction = createActionButton('fas fa-columns', 'Comparar alterações', 'Comparar alterações', () => {
|
|
375
|
+
diffPanel.hidden = !diffPanel.hidden;
|
|
376
|
+
});
|
|
377
|
+
undoAction.button.setAttribute('aria-keyshortcuts', 'Control+Z Meta+Z');
|
|
378
|
+
redoAction.button.setAttribute('aria-keyshortcuts', 'Control+Y Meta+Y Control+Shift+Z Meta+Shift+Z');
|
|
379
|
+
updateHistoryActions();
|
|
380
|
+
diffAction.button.disabled = true;
|
|
381
|
+
|
|
382
|
+
const presetSelect = document.createElement('br-select');
|
|
383
|
+
presetSelect.className = 'wbc-example-preset';
|
|
384
|
+
presetSelect.id = `${controlsScope}-preset`;
|
|
385
|
+
presetSelect.setAttribute('density', 'small');
|
|
386
|
+
presetSelect.setAttribute('inline', '');
|
|
387
|
+
presetSelect.setAttribute('label', 'Preset');
|
|
388
|
+
const initialPreset =
|
|
389
|
+
presets.find(({ id, source }) => id === activeDraft?.presetId && Boolean(source)) ??
|
|
390
|
+
presets.find(({ id, source }) => id === defaultPreset && Boolean(source)) ??
|
|
391
|
+
presets.find(({ source }) => Boolean(source));
|
|
392
|
+
const initialPresetId = initialPreset?.id || '';
|
|
393
|
+
const getPresetCss = (preset) => preset?.css || getFrameworkCode(editorState.value, 'css');
|
|
394
|
+
const getPresetJavascript = (preset) => preset?.javascript || '';
|
|
395
|
+
// Link compartilhado > rascunho local > arquivos do preset. O estado da URL não é confiável.
|
|
396
|
+
const sharedState = getSharedExampleState(path, file);
|
|
397
|
+
const pickSource = (...values) => values.find((value) => typeof value === 'string');
|
|
398
|
+
vanillaSources.css = pickSource(sharedState?.c, activeDraft?.css, getPresetCss(initialPreset));
|
|
399
|
+
vanillaSources.javascript = pickSource(sharedState?.j, activeDraft?.javascript, getPresetJavascript(initialPreset));
|
|
400
|
+
presetOptions.forEach(({ id, label, source }) => {
|
|
401
|
+
const option = document.createElement('br-select-option');
|
|
402
|
+
option.value = id;
|
|
403
|
+
option.setAttribute('label', label);
|
|
404
|
+
option.textContent = label;
|
|
405
|
+
if (id === initialPresetId) option.setAttribute('selected', '');
|
|
406
|
+
if (id && !source) option.setAttribute('disabled', '');
|
|
407
|
+
presetSelect.appendChild(option);
|
|
408
|
+
});
|
|
409
|
+
presetSelect.value = initialPresetId;
|
|
410
|
+
|
|
411
|
+
// Descrição do preset: linha de largura total entre o cabeçalho e o preview e, se houver,
|
|
412
|
+
// a explicação detalhada em <details>, recolhida a cada troca de preset. O parágrafo é uma
|
|
413
|
+
// região viva, então a troca é anunciada.
|
|
414
|
+
const presetDescription = document.createElement('div');
|
|
415
|
+
presetDescription.className = 'wbc-example-preset-description';
|
|
416
|
+
presetDescription.hidden = true;
|
|
417
|
+
const presetDescriptionText = document.createElement('p');
|
|
418
|
+
presetDescriptionText.className = 'wbc-example-preset-description__text';
|
|
419
|
+
presetDescriptionText.setAttribute('aria-live', 'polite');
|
|
420
|
+
const presetDetails = document.createElement('details');
|
|
421
|
+
presetDetails.className = 'wbc-example-preset-description__details';
|
|
422
|
+
const presetDetailsSummary = document.createElement('summary');
|
|
423
|
+
presetDetailsSummary.textContent = 'Explicação detalhada';
|
|
424
|
+
const presetDetailsBody = document.createElement('div');
|
|
425
|
+
presetDetailsBody.className = 'wbc-example-preset-description__body';
|
|
426
|
+
presetDetails.append(presetDetailsSummary, presetDetailsBody);
|
|
427
|
+
presetDescription.append(presetDescriptionText, presetDetails);
|
|
428
|
+
const updatePresetDescription = (preset) => {
|
|
429
|
+
presetDescription.hidden = !preset?.description;
|
|
430
|
+
presetDescriptionText.textContent = preset?.description ?? '';
|
|
431
|
+
presetDetails.open = false;
|
|
432
|
+
presetDetails.hidden = !preset?.details;
|
|
433
|
+
presetDetailsBody.textContent = preset?.details ?? '';
|
|
434
|
+
};
|
|
435
|
+
updatePresetDescription(initialPreset);
|
|
436
|
+
|
|
437
|
+
let isApplyingPresetFromUrl = false;
|
|
438
|
+
let title;
|
|
439
|
+
const updateExampleLabel = (presetId = presetSelect.value) => {
|
|
440
|
+
const selectedPreset = presetId ? presetOptions.find(({ id }) => id === presetId) : null;
|
|
441
|
+
if (title) title.textContent = selectedPreset?.label || exampleLabel || file;
|
|
442
|
+
};
|
|
443
|
+
if (initialPreset?.source) comparisonBaseline = initialPreset.source;
|
|
444
|
+
presetSelect.addEventListener('change', () => {
|
|
445
|
+
const selectedPreset = presetOptions.find(({ id }) => id === presetSelect.value);
|
|
446
|
+
updateExampleLabel(selectedPreset?.id);
|
|
447
|
+
updatePresetDescription(selectedPreset);
|
|
448
|
+
if (selectedPreset?.source) {
|
|
449
|
+
controlsCssSource = '';
|
|
450
|
+
controlsApi?.reset?.();
|
|
451
|
+
if (!isApplyingPresetFromUrl) updatePresetUrl(file, selectedPreset.id);
|
|
452
|
+
comparisonBaseline = selectedPreset.source;
|
|
453
|
+
vanillaSources.css = getPresetCss(selectedPreset);
|
|
454
|
+
vanillaSources.javascript = getPresetJavascript(selectedPreset);
|
|
455
|
+
activateVanillaFile('html');
|
|
456
|
+
// Presets com o mesmo HTML ainda podem trocar JS/CSS.
|
|
457
|
+
if (selectedPreset.source === editorState.value) {
|
|
458
|
+
renderCurrentPreview(editorState.value);
|
|
459
|
+
persistDraft();
|
|
460
|
+
} else setEditorValue(selectedPreset.source);
|
|
461
|
+
updateDiff(getEditorValue());
|
|
462
|
+
}
|
|
463
|
+
});
|
|
464
|
+
contentDiv._applyPresetFromUrl = (presetId) => {
|
|
465
|
+
const selectedPreset =
|
|
466
|
+
presetOptions.find(({ id, source }) => id === presetId && source) ||
|
|
467
|
+
presetOptions.find(({ id, source }) => id === contentDiv.dataset.defaultPreset && source) ||
|
|
468
|
+
presetOptions.find(({ source }) => source);
|
|
469
|
+
if (!selectedPreset || presetSelect.value === selectedPreset.id) {
|
|
470
|
+
updateExampleLabel(selectedPreset?.id);
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
isApplyingPresetFromUrl = true;
|
|
475
|
+
presetSelect.value = selectedPreset.id;
|
|
476
|
+
presetSelect.dispatchEvent(new Event('change'));
|
|
477
|
+
isApplyingPresetFromUrl = false;
|
|
478
|
+
};
|
|
479
|
+
const hasPresets = presets.length > 0;
|
|
480
|
+
presetSelect.hidden = !hasPresets;
|
|
508
481
|
|
|
509
482
|
// 1. Copy Action
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
483
|
+
const getCopyText = (target) => {
|
|
484
|
+
const source = getEditorValue();
|
|
485
|
+
if (target === 'vanilla') {
|
|
486
|
+
vanillaSources.html = source;
|
|
487
|
+
return `<!-- index.html -->\n${vanillaSources.html}\n\n/* index.css */\n${vanillaSources.css}\n\n// index.js\n${vanillaSources.javascript}`;
|
|
488
|
+
}
|
|
489
|
+
const files = getFrameworkFiles(source, target);
|
|
490
|
+
if (files?.length) {
|
|
491
|
+
return files
|
|
492
|
+
.map(
|
|
493
|
+
(file) => `${file.language === 'html' ? `<!-- ${file.filename} -->` : `// ${file.filename}`}\n${file.code}`,
|
|
494
|
+
)
|
|
495
|
+
.join('\n\n');
|
|
496
|
+
}
|
|
497
|
+
return getFrameworkCode(source, target);
|
|
498
|
+
};
|
|
499
|
+
const copyText = async (target) => {
|
|
500
|
+
const value = getCopyText(target);
|
|
501
|
+
if (navigator.clipboard?.writeText) {
|
|
502
|
+
await navigator.clipboard.writeText(value);
|
|
503
|
+
} else {
|
|
504
|
+
const fallback = document.createElement('textarea');
|
|
505
|
+
fallback.value = value;
|
|
506
|
+
fallback.setAttribute('readonly', '');
|
|
507
|
+
fallback.className = 'wbc-copy-fallback';
|
|
508
|
+
document.body.appendChild(fallback);
|
|
509
|
+
fallback.select();
|
|
510
|
+
document.execCommand('copy');
|
|
511
|
+
fallback.remove();
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
const copyMenu = document.createElement('div');
|
|
515
|
+
copyMenu.className = 'wbc-copy-menu';
|
|
516
|
+
copyMenu.setAttribute('role', 'menu');
|
|
517
|
+
copyMenu.setAttribute('aria-label', 'Formato para copiar');
|
|
518
|
+
copyMenu.hidden = true;
|
|
519
|
+
const copyOptions = [
|
|
520
|
+
['vanilla', 'HTML/CSS/JS'],
|
|
521
|
+
['angular', 'Angular'],
|
|
522
|
+
['react', 'React'],
|
|
523
|
+
['vue', 'Vue'],
|
|
524
|
+
];
|
|
525
|
+
let copyAction;
|
|
526
|
+
copyAction = createActionButton('fas fa-copy', 'Escolher formato para copiar', 'Copiar código', () => {
|
|
527
|
+
copyMenu.hidden = !copyMenu.hidden;
|
|
528
|
+
copyAction.button.setAttribute('aria-haspopup', 'menu');
|
|
529
|
+
copyAction.button.setAttribute('aria-expanded', String(!copyMenu.hidden));
|
|
530
|
+
});
|
|
531
|
+
copyAction.button.setAttribute('aria-haspopup', 'menu');
|
|
532
|
+
copyAction.button.setAttribute('aria-expanded', 'false');
|
|
533
|
+
copyOptions.forEach(([target, label]) => {
|
|
534
|
+
const option = document.createElement('button');
|
|
535
|
+
option.type = 'button';
|
|
536
|
+
option.setAttribute('role', 'menuitem');
|
|
537
|
+
option.textContent = label;
|
|
538
|
+
option.addEventListener('click', async () => {
|
|
539
|
+
try {
|
|
540
|
+
await copyText(target);
|
|
541
|
+
copyAction.icon.className = 'fas fa-check text-success';
|
|
542
|
+
copyAction.tooltipContent.textContent = 'Copiado!';
|
|
543
|
+
} catch {
|
|
544
|
+
copyAction.tooltipContent.textContent = 'Erro ao copiar';
|
|
524
545
|
}
|
|
525
|
-
|
|
526
|
-
copyAction.
|
|
527
|
-
|
|
528
|
-
|
|
546
|
+
copyMenu.hidden = true;
|
|
547
|
+
copyAction.button.setAttribute('aria-expanded', 'false');
|
|
548
|
+
setTimeout(() => {
|
|
549
|
+
copyAction.icon.className = 'fas fa-copy';
|
|
550
|
+
copyAction.tooltipContent.textContent = 'Escolher formato para copiar';
|
|
551
|
+
}, 2000);
|
|
552
|
+
});
|
|
553
|
+
copyMenu.appendChild(option);
|
|
554
|
+
});
|
|
555
|
+
const copyMenuContainer = document.createElement('div');
|
|
556
|
+
copyMenuContainer.className = 'wbc-copy-menu-container';
|
|
557
|
+
copyMenuContainer.append(copyAction.tooltip, copyMenu);
|
|
558
|
+
copyMenuContainer.addEventListener('keydown', (event) => {
|
|
559
|
+
if (event.key === 'Escape') {
|
|
560
|
+
copyMenu.hidden = true;
|
|
561
|
+
copyAction.button.setAttribute('aria-expanded', 'false');
|
|
529
562
|
}
|
|
530
|
-
setTimeout(() => {
|
|
531
|
-
copyAction.icon.className = 'fas fa-copy';
|
|
532
|
-
copyAction.tooltipContent.textContent = 'Copiar código';
|
|
533
|
-
}, 2000);
|
|
534
563
|
});
|
|
535
564
|
|
|
536
|
-
|
|
565
|
+
const setPreviewReducedMotion = (value) => {
|
|
566
|
+
reducedMotionEnabled = Boolean(value);
|
|
567
|
+
contentDiv.setAttribute('data-wbc-reduced-motion', String(reducedMotionEnabled));
|
|
568
|
+
reducedMotionAction.button.setAttribute('aria-pressed', String(reducedMotionEnabled));
|
|
569
|
+
reducedMotionAction.button.classList.toggle('wbc-reduced-motion-action--active', reducedMotionEnabled);
|
|
570
|
+
reducedMotionAction.tooltipContent.textContent = reducedMotionEnabled
|
|
571
|
+
? 'Desativar movimento reduzido'
|
|
572
|
+
: 'Ativar movimento reduzido';
|
|
573
|
+
if (previewFrame?.contentWindow) {
|
|
574
|
+
previewFrame.contentWindow.postMessage(
|
|
575
|
+
{
|
|
576
|
+
// biome-ignore lint/style/useNamingConvention: nome reservado do protocolo interno de postMessage.
|
|
577
|
+
__playgroundMode: 'reduced-motion',
|
|
578
|
+
value: reducedMotionEnabled,
|
|
579
|
+
// biome-ignore lint/style/useNamingConvention: nome reservado do protocolo interno de postMessage.
|
|
580
|
+
__playgroundChannelId: previewChannelId,
|
|
581
|
+
},
|
|
582
|
+
'*',
|
|
583
|
+
);
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
const reducedMotionAction = createActionButton(
|
|
587
|
+
'fas fa-running',
|
|
588
|
+
reducedMotionEnabled ? 'Desativar movimento reduzido' : 'Ativar movimento reduzido',
|
|
589
|
+
reducedMotionEnabled ? 'Desativar movimento reduzido' : 'Ativar movimento reduzido',
|
|
590
|
+
() => setPreviewReducedMotion(!reducedMotionEnabled),
|
|
591
|
+
);
|
|
592
|
+
reducedMotionAction.button.classList.add('wbc-reduced-motion-action');
|
|
593
|
+
reducedMotionAction.button.classList.toggle('wbc-reduced-motion-action--active', reducedMotionEnabled);
|
|
594
|
+
reducedMotionAction.button.setAttribute('aria-pressed', String(reducedMotionEnabled));
|
|
595
|
+
|
|
596
|
+
const setPreviewTheme = (dark) => {
|
|
597
|
+
darkThemeEnabled = Boolean(dark);
|
|
598
|
+
preview.style.background = darkThemeEnabled ? '#071d41' : '#fff';
|
|
599
|
+
themeAction.button.setAttribute('aria-pressed', String(darkThemeEnabled));
|
|
600
|
+
themeAction.button.classList.toggle('wbc-theme-action--active', darkThemeEnabled);
|
|
601
|
+
themeAction.tooltipContent.textContent = darkThemeEnabled ? 'Usar fundo claro' : 'Usar fundo escuro';
|
|
602
|
+
previewFrame?.contentWindow?.postMessage(
|
|
603
|
+
{
|
|
604
|
+
// biome-ignore lint/style/useNamingConvention: nome reservado do protocolo interno de postMessage.
|
|
605
|
+
__playgroundMode: 'dark',
|
|
606
|
+
value: darkThemeEnabled,
|
|
607
|
+
// biome-ignore lint/style/useNamingConvention: nome reservado do protocolo interno de postMessage.
|
|
608
|
+
__playgroundChannelId: previewChannelId,
|
|
609
|
+
},
|
|
610
|
+
'*',
|
|
611
|
+
);
|
|
612
|
+
};
|
|
613
|
+
const themeAction = createActionButton('fas fa-adjust', 'Usar fundo escuro', 'Mudar fundo', () =>
|
|
614
|
+
setPreviewTheme(!darkThemeEnabled),
|
|
615
|
+
);
|
|
616
|
+
themeAction.button.classList.add('wbc-theme-action');
|
|
617
|
+
themeAction.button.setAttribute('aria-pressed', 'false');
|
|
618
|
+
|
|
619
|
+
const getPreviewFrameSize = () => {
|
|
620
|
+
const frameRect = previewFrame?.getBoundingClientRect();
|
|
621
|
+
const viewportRect = previewViewport.getBoundingClientRect();
|
|
622
|
+
return {
|
|
623
|
+
width: Math.round(viewportRect.width || frameRect?.width || preview.clientWidth || DEV_PREVIEW_MIN_WIDTH),
|
|
624
|
+
height: Math.round(frameRect?.height || viewportRect.height || preview.clientHeight || DEV_PREVIEW_MIN_HEIGHT),
|
|
625
|
+
};
|
|
626
|
+
};
|
|
627
|
+
|
|
628
|
+
const getMaxPreviewWidth = () =>
|
|
629
|
+
Math.max(DEV_PREVIEW_MIN_WIDTH, Math.round(preview.clientWidth || preview.getBoundingClientRect().width));
|
|
630
|
+
|
|
631
|
+
const getMaxPreviewHeight = () => Math.max(DEV_PREVIEW_MIN_HEIGHT, Math.round(window.innerHeight * 0.75));
|
|
632
|
+
|
|
633
|
+
const updatePreviewResizeA11y = () => {
|
|
634
|
+
const { width, height } = getPreviewFrameSize();
|
|
635
|
+
previewWidthResizeHandle.setAttribute('aria-valuemin', String(DEV_PREVIEW_MIN_WIDTH));
|
|
636
|
+
previewWidthResizeHandle.setAttribute('aria-valuemax', String(Math.max(width, getMaxPreviewWidth())));
|
|
637
|
+
previewWidthResizeHandle.setAttribute('aria-valuenow', String(width));
|
|
638
|
+
previewHeightResizeHandle.setAttribute('aria-valuemin', String(DEV_PREVIEW_MIN_HEIGHT));
|
|
639
|
+
previewHeightResizeHandle.setAttribute('aria-valuemax', String(Math.max(height, getMaxPreviewHeight())));
|
|
640
|
+
previewHeightResizeHandle.setAttribute('aria-valuenow', String(height));
|
|
641
|
+
};
|
|
642
|
+
|
|
643
|
+
const updatePreviewWidth = (width, maximumWidth = getMaxPreviewWidth()) => {
|
|
644
|
+
if (!previewFrame) return;
|
|
645
|
+
const currentWidth = getPreviewFrameSize().width;
|
|
646
|
+
const maxWidth = Math.max(currentWidth, maximumWidth);
|
|
647
|
+
const nextWidth = Math.min(Math.max(Math.round(width), DEV_PREVIEW_MIN_WIDTH), maxWidth);
|
|
648
|
+
previewViewport.style.width = `${nextWidth}px`;
|
|
649
|
+
previewViewport.style.maxWidth = 'none';
|
|
650
|
+
updatePreviewResizeA11y();
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
const updatePreviewHeight = (height) => {
|
|
654
|
+
if (!previewFrame) return;
|
|
655
|
+
const currentHeight = getPreviewFrameSize().height;
|
|
656
|
+
const maxHeight = Math.max(currentHeight, getMaxPreviewHeight());
|
|
657
|
+
const nextHeight = Math.min(Math.max(Math.round(height), DEV_PREVIEW_MIN_HEIGHT), maxHeight);
|
|
658
|
+
previewFrame.style.height = `${nextHeight}px`;
|
|
659
|
+
previewFrame.style.maxHeight = 'none';
|
|
660
|
+
hasManualPreviewHeight = true;
|
|
661
|
+
updatePreviewResizeA11y();
|
|
662
|
+
};
|
|
663
|
+
|
|
664
|
+
const stopPreviewResize = () => {
|
|
665
|
+
previewResizeState = null;
|
|
666
|
+
preview.classList.remove('is-resizing');
|
|
667
|
+
previewWidthResizeHandle.classList.remove('is-active');
|
|
668
|
+
previewHeightResizeHandle.classList.remove('is-active');
|
|
669
|
+
window.removeEventListener('mousemove', handlePreviewResizeMove);
|
|
670
|
+
window.removeEventListener('mouseup', stopPreviewResize);
|
|
671
|
+
};
|
|
672
|
+
|
|
673
|
+
const handlePreviewResizeMove = (event) => {
|
|
674
|
+
if (previewResizeState?.axis === 'vertical') {
|
|
675
|
+
updatePreviewWidth(
|
|
676
|
+
previewResizeState.width + event.clientX - previewResizeState.clientX,
|
|
677
|
+
previewResizeState.maximumWidth,
|
|
678
|
+
);
|
|
679
|
+
} else if (previewResizeState?.axis === 'horizontal') {
|
|
680
|
+
updatePreviewHeight(previewResizeState.height + event.clientY - previewResizeState.clientY);
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
|
|
684
|
+
const startPreviewResize = (axis, event) => {
|
|
685
|
+
event.preventDefault();
|
|
686
|
+
event.stopPropagation();
|
|
687
|
+
stopPreviewResize();
|
|
688
|
+
const { width, height } = getPreviewFrameSize();
|
|
689
|
+
const previewRect = preview.getBoundingClientRect();
|
|
690
|
+
const viewportRect = previewViewport.getBoundingClientRect();
|
|
691
|
+
const viewportLeft = Math.max(0, Math.round(viewportRect.left - previewRect.left + preview.scrollLeft));
|
|
692
|
+
const maximumWidth = Math.max(DEV_PREVIEW_MIN_WIDTH, preview.clientWidth - viewportLeft);
|
|
693
|
+
previewResizeState = { axis, clientX: event.clientX, clientY: event.clientY, width, height, maximumWidth };
|
|
694
|
+
if (axis === 'vertical') {
|
|
695
|
+
previewViewport.style.margin = '0';
|
|
696
|
+
previewViewport.style.marginLeft = `${viewportLeft}px`;
|
|
697
|
+
}
|
|
698
|
+
preview.classList.add('is-resizing');
|
|
699
|
+
(axis === 'vertical' ? previewWidthResizeHandle : previewHeightResizeHandle).classList.add('is-active');
|
|
700
|
+
window.addEventListener('mousemove', handlePreviewResizeMove);
|
|
701
|
+
window.addEventListener('mouseup', stopPreviewResize);
|
|
702
|
+
};
|
|
703
|
+
|
|
704
|
+
const handlePreviewResizeKeydown = (axis, event) => {
|
|
705
|
+
const { width, height } = getPreviewFrameSize();
|
|
706
|
+
|
|
707
|
+
if (axis === 'vertical') {
|
|
708
|
+
const delta = getPreviewResizeDelta(event.key, 'ArrowLeft', 'ArrowRight');
|
|
709
|
+
if (!delta) return;
|
|
710
|
+
event.preventDefault();
|
|
711
|
+
updatePreviewWidth(width + delta);
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
const delta = getPreviewResizeDelta(event.key, 'ArrowUp', 'ArrowDown');
|
|
716
|
+
if (delta) {
|
|
717
|
+
event.preventDefault();
|
|
718
|
+
updatePreviewHeight(height + delta);
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
|
|
722
|
+
previewWidthResizeHandle.addEventListener('mousedown', (event) => startPreviewResize('vertical', event));
|
|
723
|
+
previewWidthResizeHandle.addEventListener('keydown', (event) => handlePreviewResizeKeydown('vertical', event));
|
|
724
|
+
previewHeightResizeHandle.addEventListener('mousedown', (event) => startPreviewResize('horizontal', event));
|
|
725
|
+
previewHeightResizeHandle.addEventListener('keydown', (event) => handlePreviewResizeKeydown('horizontal', event));
|
|
726
|
+
window.addEventListener('resize', updatePreviewResizeA11y, { signal: exampleAbortController.signal });
|
|
727
|
+
exampleAbortController.signal.addEventListener('abort', stopPreviewResize, { once: true });
|
|
728
|
+
|
|
729
|
+
const setViewport = (viewport) => {
|
|
730
|
+
activeViewport = viewport;
|
|
731
|
+
hasManualPreviewHeight = false;
|
|
732
|
+
stopPreviewResize();
|
|
733
|
+
const deviceMode = viewport.mode ?? 'web';
|
|
734
|
+
previewViewport.classList.toggle('wbc-example-preview-viewport--device', deviceMode !== 'web');
|
|
735
|
+
previewViewport.classList.toggle('wbc-example-preview-viewport--ios', deviceMode === 'ios');
|
|
736
|
+
previewViewport.classList.toggle('wbc-example-preview-viewport--android', deviceMode === 'android');
|
|
737
|
+
if (!previewFrame) return;
|
|
738
|
+
|
|
739
|
+
if (!viewport.width) {
|
|
740
|
+
preview.classList.remove('wbc-example-preview--viewport');
|
|
741
|
+
preview.style.removeProperty('max-height');
|
|
742
|
+
preview.style.removeProperty('overflow');
|
|
743
|
+
previewFrame.style.removeProperty('width');
|
|
744
|
+
previewFrame.style.removeProperty('height');
|
|
745
|
+
previewFrame.style.removeProperty('max-height');
|
|
746
|
+
previewFrame.style.removeProperty('max-width');
|
|
747
|
+
previewFrame.style.removeProperty('margin');
|
|
748
|
+
previewViewport.style.removeProperty('width');
|
|
749
|
+
previewViewport.style.removeProperty('max-width');
|
|
750
|
+
previewViewport.style.removeProperty('margin');
|
|
751
|
+
previewViewport.style.removeProperty('margin-left');
|
|
752
|
+
updatePreviewResizeA11y();
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
preview.classList.add('wbc-example-preview--viewport');
|
|
757
|
+
preview.style.maxHeight = '75vh';
|
|
758
|
+
preview.style.overflow = 'auto';
|
|
759
|
+
previewViewport.style.width = `${viewport.width}px`;
|
|
760
|
+
previewViewport.style.maxWidth = 'none';
|
|
761
|
+
previewViewport.style.removeProperty('margin-left');
|
|
762
|
+
previewViewport.style.margin = '0 auto';
|
|
763
|
+
previewFrame.style.width = '100%';
|
|
764
|
+
previewFrame.style.height = `${viewport.height}px`;
|
|
765
|
+
previewFrame.style.maxWidth = 'none';
|
|
766
|
+
previewFrame.style.maxHeight = 'none';
|
|
767
|
+
previewFrame.style.removeProperty('margin');
|
|
768
|
+
updatePreviewResizeA11y();
|
|
769
|
+
};
|
|
770
|
+
const viewportActions = DEV_VIEWPORTS.map((viewport) => {
|
|
771
|
+
const action = createActionButton(viewport.icon, viewport.label, viewport.label, () => {
|
|
772
|
+
setViewport(viewport);
|
|
773
|
+
viewportActions.forEach(({ viewport: item, action: itemAction }) => {
|
|
774
|
+
itemAction.button.classList.toggle('wbc-viewport-action--active', item.id === viewport.id);
|
|
775
|
+
});
|
|
776
|
+
});
|
|
777
|
+
action.viewport = viewport;
|
|
778
|
+
action.button.classList.add('wbc-viewport-action');
|
|
779
|
+
action.button.classList.toggle('wbc-viewport-action--active', viewport.id === activeViewport.id);
|
|
780
|
+
return { viewport, action };
|
|
781
|
+
});
|
|
782
|
+
|
|
783
|
+
let overflowShare;
|
|
784
|
+
const handleShare = async () => {
|
|
785
|
+
try {
|
|
786
|
+
await loadLzString();
|
|
787
|
+
} catch {
|
|
788
|
+
alert('Biblioteca de compartilhamento não carregada.');
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
const state = {
|
|
792
|
+
p: path,
|
|
793
|
+
f: file,
|
|
794
|
+
h: getEditorValue(),
|
|
795
|
+
j: vanillaSources.javascript,
|
|
796
|
+
c: vanillaSources.css,
|
|
797
|
+
// Mantém a associação do código compartilhado ao preset para links legados e edição posterior.
|
|
798
|
+
presetId: presetSelect.value || undefined,
|
|
799
|
+
};
|
|
800
|
+
try {
|
|
801
|
+
const json = JSON.stringify(state);
|
|
802
|
+
const encoded = window.LZString.compressToEncodedURIComponent(json);
|
|
803
|
+
const url = new URL(window.location.href);
|
|
804
|
+
url.searchParams.set('pg_state', encoded);
|
|
805
|
+
url.hash = getExampleHash(file, presetSelect.value || undefined);
|
|
806
|
+
|
|
807
|
+
await navigator.clipboard.writeText(url.toString());
|
|
808
|
+
|
|
809
|
+
shareAction.icon.className = 'fas fa-check text-success';
|
|
810
|
+
shareAction.tooltipContent.textContent = 'Link copiado!';
|
|
811
|
+
if (overflowShare) {
|
|
812
|
+
overflowShare.iconEl.className = 'fas fa-check text-success';
|
|
813
|
+
overflowShare.textEl.textContent = 'Link copiado!';
|
|
814
|
+
}
|
|
815
|
+
setTimeout(() => {
|
|
816
|
+
shareAction.icon.className = 'fas fa-share-alt';
|
|
817
|
+
shareAction.tooltipContent.textContent = 'Compartilhar exemplo';
|
|
818
|
+
if (overflowShare) {
|
|
819
|
+
overflowShare.iconEl.className = 'fas fa-share-alt';
|
|
820
|
+
overflowShare.textEl.textContent = 'Compartilhar exemplo';
|
|
821
|
+
}
|
|
822
|
+
}, 2000);
|
|
823
|
+
} catch (err) {
|
|
824
|
+
console.error(err);
|
|
825
|
+
shareAction.tooltipContent.textContent = 'Erro ao compartilhar';
|
|
826
|
+
if (overflowShare) overflowShare.textEl.textContent = 'Erro ao compartilhar';
|
|
827
|
+
setTimeout(() => {
|
|
828
|
+
shareAction.icon.className = 'fas fa-share-alt';
|
|
829
|
+
shareAction.tooltipContent.textContent = 'Compartilhar exemplo';
|
|
830
|
+
if (overflowShare) {
|
|
831
|
+
overflowShare.iconEl.className = 'fas fa-share-alt';
|
|
832
|
+
overflowShare.textEl.textContent = 'Compartilhar exemplo';
|
|
833
|
+
}
|
|
834
|
+
}, 2000);
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
|
|
537
838
|
const shareAction = createActionButton(
|
|
538
839
|
'fas fa-share-alt',
|
|
539
840
|
'Compartilhar exemplo',
|
|
540
841
|
'Compartilhar exemplo',
|
|
541
|
-
|
|
542
|
-
try {
|
|
543
|
-
await loadLzString();
|
|
544
|
-
} catch {
|
|
545
|
-
alert('Biblioteca de compartilhamento não carregada.');
|
|
546
|
-
return;
|
|
547
|
-
}
|
|
548
|
-
const state = {
|
|
549
|
-
p: path,
|
|
550
|
-
f: file,
|
|
551
|
-
h: getEditorValue(),
|
|
552
|
-
};
|
|
553
|
-
try {
|
|
554
|
-
const json = JSON.stringify(state);
|
|
555
|
-
const encoded = window.LZString.compressToEncodedURIComponent(json);
|
|
556
|
-
const url = new URL(window.location.href);
|
|
557
|
-
url.searchParams.set('pg_state', encoded);
|
|
558
|
-
url.hash = getExampleHash(file);
|
|
559
|
-
|
|
560
|
-
await navigator.clipboard.writeText(url.toString());
|
|
561
|
-
|
|
562
|
-
shareAction.icon.className = 'fas fa-check text-success';
|
|
563
|
-
shareAction.tooltipContent.textContent = 'Link copiado!';
|
|
564
|
-
setTimeout(() => {
|
|
565
|
-
shareAction.icon.className = 'fas fa-share-alt';
|
|
566
|
-
shareAction.tooltipContent.textContent = 'Compartilhar exemplo';
|
|
567
|
-
}, 2000);
|
|
568
|
-
} catch (err) {
|
|
569
|
-
console.error(err);
|
|
570
|
-
shareAction.tooltipContent.textContent = 'Erro ao compartilhar';
|
|
571
|
-
setTimeout(() => {
|
|
572
|
-
shareAction.icon.className = 'fas fa-share-alt';
|
|
573
|
-
shareAction.tooltipContent.textContent = 'Compartilhar exemplo';
|
|
574
|
-
}, 2000);
|
|
575
|
-
}
|
|
576
|
-
},
|
|
842
|
+
handleShare,
|
|
577
843
|
);
|
|
578
844
|
|
|
579
845
|
// 3. Fullscreen Action
|
|
846
|
+
let isClosingFullscreen = false;
|
|
847
|
+
const closeFullscreen = () => {
|
|
848
|
+
if (!contentDiv.classList.contains('is-fullscreen') || isClosingFullscreen) return;
|
|
849
|
+
isClosingFullscreen = true;
|
|
850
|
+
contentDiv.classList.add('is-fullscreen-exiting');
|
|
851
|
+
setTimeout(() => {
|
|
852
|
+
contentDiv.classList.remove('is-fullscreen');
|
|
853
|
+
contentDiv.classList.remove('is-fullscreen-exiting');
|
|
854
|
+
isClosingFullscreen = false;
|
|
855
|
+
fsAction.icon.className = 'fas fa-expand-arrows-alt';
|
|
856
|
+
fsAction.tooltipContent.textContent = 'Tela cheia';
|
|
857
|
+
fsAction.button.focus();
|
|
858
|
+
}, 200);
|
|
859
|
+
};
|
|
860
|
+
|
|
580
861
|
const fsAction = createActionButton('fas fa-expand-arrows-alt', 'Tela cheia', 'Tela cheia', () => {
|
|
581
|
-
|
|
582
|
-
|
|
862
|
+
if (contentDiv.classList.contains('is-fullscreen')) {
|
|
863
|
+
closeFullscreen();
|
|
864
|
+
} else {
|
|
865
|
+
contentDiv.classList.add('is-fullscreen');
|
|
583
866
|
fsAction.icon.className = 'fas fa-compress-arrows-alt';
|
|
584
867
|
fsAction.tooltipContent.textContent = 'Fechar tela cheia';
|
|
585
868
|
requestAnimationFrame(() => editorApi?.refresh?.());
|
|
586
|
-
} else {
|
|
587
|
-
fsAction.icon.className = 'fas fa-expand-arrows-alt';
|
|
588
|
-
fsAction.tooltipContent.textContent = 'Tela cheia';
|
|
589
869
|
}
|
|
590
870
|
});
|
|
871
|
+
document.addEventListener(
|
|
872
|
+
'keydown',
|
|
873
|
+
(event) => {
|
|
874
|
+
if (event.key !== 'Escape' || !contentDiv.classList.contains('is-fullscreen')) return;
|
|
875
|
+
event.preventDefault();
|
|
876
|
+
closeFullscreen();
|
|
877
|
+
},
|
|
878
|
+
{ signal: exampleAbortController.signal },
|
|
879
|
+
);
|
|
591
880
|
|
|
592
881
|
// --- EXAMPLE CARD HEADER ---
|
|
593
882
|
const header = document.createElement('div');
|
|
594
883
|
header.className = 'wbc-example-header';
|
|
595
884
|
|
|
596
|
-
|
|
597
|
-
|
|
885
|
+
title = document.createElement('h3');
|
|
886
|
+
updateExampleLabel();
|
|
598
887
|
header.appendChild(title);
|
|
599
888
|
|
|
600
|
-
// Group
|
|
889
|
+
// Group actions: expanded toolbar vs compact dropdown
|
|
601
890
|
const headerActions = document.createElement('div');
|
|
602
891
|
headerActions.className = 'wbc-example-header-actions';
|
|
603
892
|
|
|
604
|
-
const
|
|
605
|
-
|
|
893
|
+
const expandedActions = document.createElement('div');
|
|
894
|
+
expandedActions.className = 'wbc-example-header-actions-expanded';
|
|
895
|
+
expandedActions.append(
|
|
896
|
+
undoAction.tooltip,
|
|
897
|
+
redoAction.tooltip,
|
|
898
|
+
diffAction.tooltip,
|
|
899
|
+
...viewportActions.map(({ action }) => action.tooltip),
|
|
900
|
+
copyMenuContainer,
|
|
901
|
+
reducedMotionAction.tooltip,
|
|
902
|
+
shareAction.tooltip,
|
|
903
|
+
themeAction.tooltip,
|
|
904
|
+
);
|
|
905
|
+
|
|
906
|
+
// Overflow container for compact toolbar
|
|
907
|
+
const overflowContainer = document.createElement('div');
|
|
908
|
+
overflowContainer.className = 'wbc-toolbar-overflow-container';
|
|
606
909
|
|
|
607
|
-
const
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
exampleToggle.setAttribute('aria-label', isExpanded ? 'Recolher exemplo' : 'Expandir exemplo');
|
|
613
|
-
exampleToggle.setAttribute('slot', 'trigger');
|
|
910
|
+
const overflowMenu = document.createElement('div');
|
|
911
|
+
overflowMenu.className = 'wbc-toolbar-overflow-menu';
|
|
912
|
+
overflowMenu.setAttribute('role', 'menu');
|
|
913
|
+
overflowMenu.setAttribute('aria-label', 'Mais opções');
|
|
914
|
+
overflowMenu.hidden = true;
|
|
614
915
|
|
|
615
|
-
const
|
|
616
|
-
|
|
617
|
-
|
|
916
|
+
const closeOverflow = () => {
|
|
917
|
+
overflowMenu.hidden = true;
|
|
918
|
+
overflowAction.button.setAttribute('aria-expanded', 'false');
|
|
919
|
+
overflowAction.button.classList.remove('wbc-toolbar-overflow-action--active');
|
|
920
|
+
};
|
|
618
921
|
|
|
619
|
-
const
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
922
|
+
const createOverflowItem = ({ icon, label, onClick, isCheckbox = false }) => {
|
|
923
|
+
const item = document.createElement('button');
|
|
924
|
+
item.type = 'button';
|
|
925
|
+
item.className = 'wbc-toolbar-overflow-menu-item';
|
|
926
|
+
item.setAttribute('role', isCheckbox ? 'menuitemcheckbox' : 'menuitem');
|
|
623
927
|
|
|
624
|
-
|
|
928
|
+
const iconEl = document.createElement('i');
|
|
929
|
+
iconEl.className = icon;
|
|
930
|
+
iconEl.setAttribute('aria-hidden', 'true');
|
|
625
931
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
932
|
+
const textEl = document.createElement('span');
|
|
933
|
+
textEl.textContent = label;
|
|
934
|
+
|
|
935
|
+
item.append(iconEl, textEl);
|
|
936
|
+
item.addEventListener('click', (event) => {
|
|
937
|
+
onClick(event);
|
|
938
|
+
closeOverflow();
|
|
939
|
+
});
|
|
940
|
+
return { item, iconEl, textEl };
|
|
941
|
+
};
|
|
942
|
+
|
|
943
|
+
overflowUndo = createOverflowItem({
|
|
944
|
+
icon: 'fas fa-undo',
|
|
945
|
+
label: 'Desfazer alteração',
|
|
946
|
+
onClick: () => moveEditorHistory(-1),
|
|
947
|
+
});
|
|
948
|
+
|
|
949
|
+
overflowRedo = createOverflowItem({
|
|
950
|
+
icon: 'fas fa-redo',
|
|
951
|
+
label: 'Refazer alteração',
|
|
952
|
+
onClick: () => moveEditorHistory(1),
|
|
953
|
+
});
|
|
954
|
+
|
|
955
|
+
overflowDiff = createOverflowItem({
|
|
956
|
+
icon: 'fas fa-columns',
|
|
957
|
+
label: 'Comparar alterações',
|
|
958
|
+
onClick: () => {
|
|
959
|
+
diffPanel.hidden = !diffPanel.hidden;
|
|
960
|
+
},
|
|
961
|
+
});
|
|
962
|
+
|
|
963
|
+
const overflowCopy = createOverflowItem({
|
|
964
|
+
icon: 'fas fa-copy',
|
|
965
|
+
label: 'Copiar código',
|
|
966
|
+
onClick: async () => {
|
|
967
|
+
await copyText('vanilla');
|
|
968
|
+
},
|
|
969
|
+
});
|
|
970
|
+
|
|
971
|
+
const overflowViewports = DEV_VIEWPORTS.map((viewport) =>
|
|
972
|
+
createOverflowItem({
|
|
973
|
+
icon: viewport.icon,
|
|
974
|
+
label: viewport.label,
|
|
975
|
+
onClick: () => {
|
|
976
|
+
setViewport(viewport);
|
|
977
|
+
viewportActions.forEach(({ viewport: item, action: itemAction }) => {
|
|
978
|
+
itemAction.button.classList.toggle('wbc-viewport-action--active', item.id === viewport.id);
|
|
979
|
+
});
|
|
980
|
+
},
|
|
981
|
+
}),
|
|
982
|
+
);
|
|
983
|
+
|
|
984
|
+
const overflowReducedMotion = createOverflowItem({
|
|
985
|
+
icon: 'fas fa-running',
|
|
986
|
+
label: `Movimento reduzido (${reducedMotionEnabled ? 'Ativo' : 'Inativo'})`,
|
|
987
|
+
isCheckbox: true,
|
|
988
|
+
onClick: () => setPreviewReducedMotion(!reducedMotionEnabled),
|
|
989
|
+
});
|
|
990
|
+
|
|
991
|
+
overflowShare = createOverflowItem({
|
|
992
|
+
icon: 'fas fa-share-alt',
|
|
993
|
+
label: 'Compartilhar exemplo',
|
|
994
|
+
onClick: () => handleShare(),
|
|
995
|
+
});
|
|
996
|
+
|
|
997
|
+
const overflowTheme = createOverflowItem({
|
|
998
|
+
icon: 'fas fa-adjust',
|
|
999
|
+
label: `Alternar fundo (${darkThemeEnabled ? 'Escuro' : 'Claro'})`,
|
|
1000
|
+
onClick: () => setPreviewTheme(!darkThemeEnabled),
|
|
1001
|
+
});
|
|
1002
|
+
|
|
1003
|
+
const updateOverflowMenu = () => {
|
|
1004
|
+
overflowUndo.item.disabled = undoAction.button.disabled;
|
|
1005
|
+
overflowRedo.item.disabled = redoAction.button.disabled;
|
|
1006
|
+
overflowDiff.item.disabled = diffAction.button.disabled;
|
|
1007
|
+
DEV_VIEWPORTS.forEach((viewport, index) => {
|
|
1008
|
+
overflowViewports[index].item.classList.toggle('is-active', viewport.id === activeViewport.id);
|
|
1009
|
+
});
|
|
1010
|
+
overflowReducedMotion.item.classList.toggle('is-active', reducedMotionEnabled);
|
|
1011
|
+
overflowReducedMotion.item.setAttribute('aria-checked', String(reducedMotionEnabled));
|
|
1012
|
+
overflowReducedMotion.textEl.textContent = `Movimento reduzido (${reducedMotionEnabled ? 'Ativo' : 'Inativo'})`;
|
|
1013
|
+
overflowTheme.item.classList.toggle('is-active', darkThemeEnabled);
|
|
1014
|
+
overflowTheme.textEl.textContent = `Alternar fundo (${darkThemeEnabled ? 'Escuro' : 'Claro'})`;
|
|
1015
|
+
};
|
|
1016
|
+
|
|
1017
|
+
overflowMenu.append(
|
|
1018
|
+
overflowUndo.item,
|
|
1019
|
+
overflowRedo.item,
|
|
1020
|
+
overflowDiff.item,
|
|
1021
|
+
overflowCopy.item,
|
|
1022
|
+
...overflowViewports.map(({ item }) => item),
|
|
1023
|
+
overflowReducedMotion.item,
|
|
1024
|
+
overflowShare.item,
|
|
1025
|
+
overflowTheme.item,
|
|
1026
|
+
);
|
|
1027
|
+
|
|
1028
|
+
const overflowAction = createActionButton('fas fa-ellipsis-v', 'Mais opções', 'Mais opções', () => {
|
|
1029
|
+
const isHidden = !overflowMenu.hidden;
|
|
1030
|
+
if (isHidden) {
|
|
1031
|
+
closeOverflow();
|
|
1032
|
+
} else {
|
|
1033
|
+
updateOverflowMenu();
|
|
1034
|
+
overflowMenu.hidden = false;
|
|
1035
|
+
overflowAction.button.setAttribute('aria-expanded', 'true');
|
|
1036
|
+
overflowAction.button.classList.add('wbc-toolbar-overflow-action--active');
|
|
630
1037
|
}
|
|
631
1038
|
});
|
|
1039
|
+
overflowAction.button.classList.add('wbc-toolbar-overflow-action');
|
|
1040
|
+
overflowAction.button.setAttribute('aria-haspopup', 'menu');
|
|
1041
|
+
overflowAction.button.setAttribute('aria-expanded', 'false');
|
|
632
1042
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
1043
|
+
overflowContainer.append(overflowAction.tooltip, overflowMenu);
|
|
1044
|
+
|
|
1045
|
+
const handleOverflowOutsideClick = (event) => {
|
|
1046
|
+
if (!overflowContainer.contains(event.target)) {
|
|
1047
|
+
closeOverflow();
|
|
1048
|
+
}
|
|
1049
|
+
};
|
|
1050
|
+
document.addEventListener('click', handleOverflowOutsideClick);
|
|
1051
|
+
exampleAbortController.signal.addEventListener(
|
|
1052
|
+
'abort',
|
|
1053
|
+
() => {
|
|
1054
|
+
document.removeEventListener('click', handleOverflowOutsideClick);
|
|
1055
|
+
},
|
|
1056
|
+
{ once: true },
|
|
1057
|
+
);
|
|
1058
|
+
|
|
1059
|
+
overflowContainer.addEventListener('keydown', (event) => {
|
|
1060
|
+
if (event.key === 'Escape') {
|
|
1061
|
+
closeOverflow();
|
|
1062
|
+
overflowAction.button.focus();
|
|
652
1063
|
}
|
|
653
1064
|
});
|
|
654
1065
|
|
|
655
|
-
|
|
1066
|
+
const collapsedActions = document.createElement('div');
|
|
1067
|
+
collapsedActions.className = 'wbc-example-header-actions-collapsed';
|
|
1068
|
+
collapsedActions.append(overflowContainer);
|
|
1069
|
+
|
|
1070
|
+
headerActions.append(presetSelect, expandedActions, collapsedActions, fsAction.tooltip);
|
|
656
1071
|
header.appendChild(headerActions);
|
|
657
1072
|
|
|
1073
|
+
const updateToolbarLayout = () => {
|
|
1074
|
+
const isCompact = header.clientWidth > 0 && header.clientWidth < 840;
|
|
1075
|
+
header.classList.toggle('is-compact-toolbar', isCompact);
|
|
1076
|
+
header.classList.toggle('is-stacked-toolbar', header.clientWidth > 0 && header.clientWidth < 576);
|
|
1077
|
+
};
|
|
1078
|
+
const headerResizeObserver = new ResizeObserver(updateToolbarLayout);
|
|
1079
|
+
headerResizeObserver.observe(header);
|
|
1080
|
+
exampleAbortController.signal.addEventListener('abort', () => headerResizeObserver.disconnect(), { once: true });
|
|
1081
|
+
|
|
658
1082
|
const editorWrapper = document.createElement('div');
|
|
659
1083
|
editorWrapper.className = 'wbc-example-editor-wrapper';
|
|
1084
|
+
editorWrapper.addEventListener('keydown', handleEditorKeydown, true);
|
|
1085
|
+
|
|
1086
|
+
const diffPanel = document.createElement('section');
|
|
1087
|
+
diffPanel.className = 'wbc-example-diff';
|
|
1088
|
+
diffPanel.hidden = true;
|
|
1089
|
+
diffPanel.setAttribute('aria-label', 'Diff das alterações do exemplo');
|
|
1090
|
+
const diffTitle = document.createElement('h4');
|
|
1091
|
+
diffTitle.className = 'wbc-example-diff__title';
|
|
1092
|
+
diffTitle.textContent = 'Alterações (formatação ignorada)';
|
|
1093
|
+
const diffCode = document.createElement('pre');
|
|
1094
|
+
diffCode.className = 'wbc-example-diff__code';
|
|
1095
|
+
diffPanel.append(diffTitle, diffCode);
|
|
1096
|
+
|
|
1097
|
+
const renderDiff = (diff) => {
|
|
1098
|
+
const fragment = document.createDocumentFragment();
|
|
1099
|
+
diff.lines.forEach((line) => {
|
|
1100
|
+
const lineElement = document.createElement('span');
|
|
1101
|
+
lineElement.className = 'wbc-example-diff__line';
|
|
1102
|
+
if (line.startsWith('---') || line.startsWith('+++')) lineElement.classList.add('is-header');
|
|
1103
|
+
else if (line.startsWith('+')) lineElement.classList.add('is-added');
|
|
1104
|
+
else if (line.startsWith('-')) lineElement.classList.add('is-removed');
|
|
1105
|
+
else if (line.startsWith('@')) lineElement.classList.add('is-hunk');
|
|
1106
|
+
lineElement.textContent = line || ' ';
|
|
1107
|
+
fragment.appendChild(lineElement);
|
|
1108
|
+
});
|
|
1109
|
+
diffCode.replaceChildren(fragment);
|
|
1110
|
+
};
|
|
1111
|
+
const updateDiff = (source) => {
|
|
1112
|
+
const diff = window.WBCPlaygroundCore?.createUnifiedDiff(comparisonBaseline, source) || {
|
|
1113
|
+
changed: source !== comparisonBaseline,
|
|
1114
|
+
lines: source === comparisonBaseline ? [] : [`- ${comparisonBaseline}`, `+ ${source}`],
|
|
1115
|
+
};
|
|
1116
|
+
const hasChanges = diff.changed;
|
|
1117
|
+
diffAction.button.disabled = !hasChanges;
|
|
1118
|
+
if (overflowDiff) overflowDiff.item.disabled = !hasChanges;
|
|
1119
|
+
if (!hasChanges) diffPanel.hidden = true;
|
|
1120
|
+
renderDiff(diff);
|
|
1121
|
+
};
|
|
660
1122
|
|
|
661
1123
|
const eventsWrapper = document.createElement('div');
|
|
662
1124
|
eventsWrapper.className = 'wbc-example-events-wrapper';
|
|
@@ -666,34 +1128,57 @@ function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
|
666
1128
|
|
|
667
1129
|
const filterContainer = document.createElement('div');
|
|
668
1130
|
filterContainer.className = 'wbc-events-filter-container';
|
|
669
|
-
filterContainer.style.display = 'flex';
|
|
670
|
-
filterContainer.style.gap = '8px';
|
|
671
|
-
filterContainer.style.alignItems = 'flex-end';
|
|
672
|
-
filterContainer.style.marginBottom = '8px';
|
|
673
1131
|
|
|
674
1132
|
const eventFilterInput = document.createElement('br-input');
|
|
1133
|
+
eventFilterInput.className = 'wbc-events-filter-input';
|
|
675
1134
|
eventFilterInput.setAttribute('placeholder', 'Filtrar eventos...');
|
|
676
1135
|
eventFilterInput.setAttribute('density', 'small');
|
|
677
|
-
|
|
1136
|
+
const eventKindFilter = document.createElement('select');
|
|
1137
|
+
eventKindFilter.className = 'wbc-event-kind-filter';
|
|
1138
|
+
eventKindFilter.setAttribute('aria-label', 'Tipo de evento');
|
|
1139
|
+
[
|
|
1140
|
+
['all', 'Todos'],
|
|
1141
|
+
['native', 'Nativos'],
|
|
1142
|
+
['custom', 'Customizados'],
|
|
1143
|
+
['component', 'Por componente'],
|
|
1144
|
+
].forEach(([value, label]) => {
|
|
1145
|
+
eventKindFilter.add(new Option(label, value));
|
|
1146
|
+
});
|
|
678
1147
|
|
|
679
1148
|
const copyEventsAction = createActionButton(
|
|
680
1149
|
'fas fa-copy',
|
|
681
|
-
'
|
|
682
|
-
'
|
|
1150
|
+
'Exportar eventos capturados',
|
|
1151
|
+
'Exportar eventos capturados',
|
|
683
1152
|
async () => {
|
|
684
|
-
const
|
|
685
|
-
const
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
const
|
|
689
|
-
|
|
690
|
-
|
|
1153
|
+
const filter = String(eventFilterInput.value ?? '').toLowerCase();
|
|
1154
|
+
const kind = eventKindFilter.value;
|
|
1155
|
+
const textToCopy = eventEntries
|
|
1156
|
+
.filter((entry) => {
|
|
1157
|
+
const kindMatches =
|
|
1158
|
+
kind === 'all' ||
|
|
1159
|
+
(kind === 'native' && !entry.custom) ||
|
|
1160
|
+
(kind === 'custom' && entry.custom) ||
|
|
1161
|
+
(kind === 'component' && /br-[a-z0-9-]+/i.test(`${entry.target} ${entry.currentTarget || ''}`));
|
|
1162
|
+
return (
|
|
1163
|
+
kindMatches &&
|
|
1164
|
+
`${entry.eventType} ${entry.target} ${entry.currentTarget || ''}`.toLowerCase().includes(filter)
|
|
1165
|
+
);
|
|
691
1166
|
})
|
|
1167
|
+
.map((entry) => serialize(entry))
|
|
692
1168
|
.join('\n---\n');
|
|
693
1169
|
|
|
694
1170
|
try {
|
|
695
1171
|
if (navigator.clipboard?.writeText) {
|
|
696
1172
|
await navigator.clipboard.writeText(textToCopy);
|
|
1173
|
+
} else {
|
|
1174
|
+
const fallback = document.createElement('textarea');
|
|
1175
|
+
fallback.value = textToCopy;
|
|
1176
|
+
fallback.setAttribute('readonly', '');
|
|
1177
|
+
fallback.className = 'wbc-copy-fallback';
|
|
1178
|
+
document.body.appendChild(fallback);
|
|
1179
|
+
fallback.select();
|
|
1180
|
+
document.execCommand('copy');
|
|
1181
|
+
fallback.remove();
|
|
697
1182
|
}
|
|
698
1183
|
copyEventsAction.icon.className = 'fas fa-check text-success';
|
|
699
1184
|
copyEventsAction.tooltipContent.textContent = 'Copiado!';
|
|
@@ -702,28 +1187,28 @@ function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
|
702
1187
|
}
|
|
703
1188
|
setTimeout(() => {
|
|
704
1189
|
copyEventsAction.icon.className = 'fas fa-copy';
|
|
705
|
-
copyEventsAction.tooltipContent.textContent = '
|
|
1190
|
+
copyEventsAction.tooltipContent.textContent = 'Exportar eventos capturados';
|
|
706
1191
|
}, 2000);
|
|
707
1192
|
},
|
|
708
1193
|
);
|
|
709
1194
|
|
|
710
|
-
filterContainer.append(eventFilterInput, copyEventsAction.tooltip);
|
|
1195
|
+
filterContainer.append(eventFilterInput, eventKindFilter, copyEventsAction.tooltip);
|
|
711
1196
|
|
|
712
1197
|
const eventsHelp = document.createElement('p');
|
|
713
1198
|
eventsHelp.className = 'wbc-events-help';
|
|
714
|
-
eventsHelp.textContent = 'Eventos
|
|
1199
|
+
eventsHelp.textContent = 'Eventos e mensagens de runtime do preview aparecem abaixo.';
|
|
715
1200
|
|
|
716
1201
|
const eventsActions = document.createElement('div');
|
|
717
1202
|
eventsActions.className = 'wbc-events-actions';
|
|
718
|
-
eventsActions.style.display = 'flex';
|
|
719
|
-
eventsActions.style.gap = '5px';
|
|
720
1203
|
|
|
721
1204
|
const pauseBtn = document.createElement('br-button');
|
|
1205
|
+
pauseBtn.setAttribute('type', 'button');
|
|
722
1206
|
pauseBtn.setAttribute('density', 'small');
|
|
723
1207
|
pauseBtn.setAttribute('emphasis', 'secondary');
|
|
724
1208
|
pauseBtn.textContent = 'Pausar';
|
|
725
1209
|
|
|
726
1210
|
const clearBtn = document.createElement('br-button');
|
|
1211
|
+
clearBtn.setAttribute('type', 'button');
|
|
727
1212
|
clearBtn.setAttribute('density', 'small');
|
|
728
1213
|
clearBtn.setAttribute('emphasis', 'secondary');
|
|
729
1214
|
clearBtn.textContent = 'Limpar';
|
|
@@ -736,31 +1221,47 @@ function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
|
736
1221
|
|
|
737
1222
|
eventsWrapper.append(eventsHeader, eventsList);
|
|
738
1223
|
|
|
1224
|
+
const eventEntries = [];
|
|
1225
|
+
let eventCounter = 0;
|
|
1226
|
+
|
|
739
1227
|
const applyFilter = () => {
|
|
740
1228
|
const val = String(eventFilterInput.value ?? '').toLowerCase();
|
|
1229
|
+
const kind = eventKindFilter.value;
|
|
741
1230
|
Array.from(eventsList.children).forEach((li) => {
|
|
742
1231
|
const text = li.textContent.toLowerCase();
|
|
743
|
-
|
|
1232
|
+
const kindMatches =
|
|
1233
|
+
kind === 'all' ||
|
|
1234
|
+
li.dataset.eventKind === kind ||
|
|
1235
|
+
(kind === 'component' && /br-[a-z0-9-]+/i.test(li.dataset.eventTarget || ''));
|
|
1236
|
+
li.hidden = !kindMatches || !text.includes(val);
|
|
744
1237
|
});
|
|
745
1238
|
};
|
|
746
1239
|
|
|
747
1240
|
eventFilterInput.addEventListener('input', applyFilter);
|
|
748
|
-
|
|
1241
|
+
eventKindFilter.addEventListener('change', applyFilter);
|
|
749
1242
|
|
|
750
1243
|
let newEventsCount = 0;
|
|
751
1244
|
let isPaused = false;
|
|
1245
|
+
const updateConsoleCounter = () => {
|
|
1246
|
+
const count = eventEntries.length + runtimeEntries.length;
|
|
1247
|
+
if (count > 0) eventsTabItem.setAttribute('counter', count > 99 ? '99+' : String(count));
|
|
1248
|
+
else eventsTabItem.removeAttribute('counter');
|
|
1249
|
+
};
|
|
1250
|
+
|
|
1251
|
+
const markConsoleEntry = () => {
|
|
1252
|
+
const isActive = tabComponent.activeTabId === tabIds.events;
|
|
1253
|
+
if (!isActive) {
|
|
1254
|
+
newEventsCount++;
|
|
1255
|
+
eventsTabItem.setAttribute('label', `Console (${newEventsCount})`);
|
|
1256
|
+
}
|
|
1257
|
+
updateConsoleCounter();
|
|
1258
|
+
};
|
|
752
1259
|
|
|
753
1260
|
pauseBtn.addEventListener('click', () => {
|
|
754
1261
|
isPaused = !isPaused;
|
|
755
1262
|
pauseBtn.textContent = isPaused ? 'Continuar' : 'Pausar';
|
|
756
1263
|
});
|
|
757
1264
|
|
|
758
|
-
clearBtn.addEventListener('click', () => {
|
|
759
|
-
eventsList.replaceChildren();
|
|
760
|
-
eventsTabItem.setAttribute('label', 'Console');
|
|
761
|
-
newEventsCount = 0;
|
|
762
|
-
});
|
|
763
|
-
|
|
764
1265
|
const serialize = (value) => {
|
|
765
1266
|
if (value === undefined) return '';
|
|
766
1267
|
try {
|
|
@@ -789,97 +1290,306 @@ function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
|
789
1290
|
return `${target.localName}${id}${classes}`;
|
|
790
1291
|
};
|
|
791
1292
|
|
|
792
|
-
const
|
|
793
|
-
|
|
1293
|
+
const createEventEntry = (event, dispatchedBy, targetDescription, metadata = {}) => {
|
|
1294
|
+
eventCounter += 1;
|
|
1295
|
+
return {
|
|
1296
|
+
id: metadata.eventId || `event-${eventCounter}`,
|
|
1297
|
+
eventType: metadata.eventType || event.type,
|
|
1298
|
+
custom: Boolean(metadata.custom || event instanceof CustomEvent),
|
|
1299
|
+
detail: metadata.detail ?? (event instanceof CustomEvent ? event.detail : undefined),
|
|
1300
|
+
target: metadata.target || targetDescription || describeTarget(event.target || dispatchedBy),
|
|
1301
|
+
currentTarget: metadata.currentTarget,
|
|
1302
|
+
composedPath: metadata.composedPath || [],
|
|
1303
|
+
bubbles: metadata.bubbles ?? Boolean(event.bubbles),
|
|
1304
|
+
composed: metadata.composed ?? Boolean(event.composed),
|
|
1305
|
+
cancelable: metadata.cancelable ?? Boolean(event.cancelable),
|
|
1306
|
+
timeStamp: metadata.timeStamp ?? event.timeStamp,
|
|
1307
|
+
};
|
|
1308
|
+
};
|
|
1309
|
+
|
|
1310
|
+
const createEventDetails = (detail) => {
|
|
1311
|
+
const detailsEl = document.createElement('details');
|
|
1312
|
+
detailsEl.className = 'wbc-event-console-details-container';
|
|
1313
|
+
detailsEl.open = true;
|
|
1314
|
+
|
|
1315
|
+
const summaryEl = document.createElement('summary');
|
|
1316
|
+
summaryEl.textContent = 'Detalhes do evento';
|
|
794
1317
|
|
|
1318
|
+
const preEl = document.createElement('pre');
|
|
1319
|
+
preEl.className = 'wbc-event-console-detail';
|
|
1320
|
+
preEl.textContent = serialize(detail);
|
|
1321
|
+
detailsEl.append(summaryEl, preEl);
|
|
1322
|
+
return detailsEl;
|
|
1323
|
+
};
|
|
1324
|
+
|
|
1325
|
+
const createEventMetadata = (eventEntry) => {
|
|
1326
|
+
const metadataEl = document.createElement('dl');
|
|
1327
|
+
metadataEl.className = 'wbc-event-console-metadata';
|
|
1328
|
+
const metadataRows = [
|
|
1329
|
+
['target', eventEntry.target],
|
|
1330
|
+
['currentTarget', eventEntry.currentTarget || '—'],
|
|
1331
|
+
['bubbles', eventEntry.bubbles],
|
|
1332
|
+
['composed', eventEntry.composed],
|
|
1333
|
+
['cancelable', eventEntry.cancelable],
|
|
1334
|
+
];
|
|
1335
|
+
metadataRows.forEach(([label, value]) => {
|
|
1336
|
+
const term = document.createElement('dt');
|
|
1337
|
+
term.textContent = `${label}:`;
|
|
1338
|
+
const description = document.createElement('dd');
|
|
1339
|
+
description.textContent = String(value);
|
|
1340
|
+
metadataEl.append(term, description);
|
|
1341
|
+
});
|
|
1342
|
+
return metadataEl;
|
|
1343
|
+
};
|
|
1344
|
+
|
|
1345
|
+
const createEventItem = (eventEntry) => {
|
|
795
1346
|
const item = document.createElement('li');
|
|
796
1347
|
const name = document.createElement('span');
|
|
797
1348
|
const target = document.createElement('span');
|
|
798
1349
|
|
|
799
1350
|
name.className = 'wbc-event-console-event-name';
|
|
800
|
-
name.textContent =
|
|
1351
|
+
name.textContent = `${eventEntry.eventType}${eventEntry.custom ? ' (customizado)' : ''}`;
|
|
801
1352
|
target.className = 'wbc-event-console-target';
|
|
802
|
-
target.textContent = ` — ${
|
|
1353
|
+
target.textContent = ` — ${eventEntry.target}`;
|
|
1354
|
+
item.dataset.eventKind = eventEntry.custom ? 'custom' : 'native';
|
|
1355
|
+
item.dataset.eventTarget = eventEntry.target;
|
|
803
1356
|
item.append(name, target);
|
|
804
1357
|
|
|
805
|
-
if (
|
|
806
|
-
|
|
807
|
-
detailsEl.className = 'wbc-event-console-details-container';
|
|
808
|
-
|
|
809
|
-
const summaryEl = document.createElement('summary');
|
|
810
|
-
summaryEl.textContent = 'payload';
|
|
811
|
-
|
|
812
|
-
const preEl = document.createElement('pre');
|
|
813
|
-
preEl.className = 'wbc-event-console-detail';
|
|
814
|
-
preEl.textContent = serialize(event.detail);
|
|
815
|
-
|
|
816
|
-
detailsEl.append(summaryEl, preEl);
|
|
817
|
-
item.appendChild(detailsEl);
|
|
1358
|
+
if (eventEntry.detail !== undefined && eventEntry.detail !== null) {
|
|
1359
|
+
item.appendChild(createEventDetails(eventEntry.detail));
|
|
818
1360
|
}
|
|
819
1361
|
|
|
820
|
-
|
|
821
|
-
|
|
1362
|
+
item.appendChild(createEventMetadata(eventEntry));
|
|
1363
|
+
if (eventEntry.composedPath.length > 0) {
|
|
1364
|
+
const pathEl = document.createElement('small');
|
|
1365
|
+
pathEl.className = 'wbc-event-console-path';
|
|
1366
|
+
pathEl.textContent = `path=${eventEntry.composedPath.join(' → ')}`;
|
|
1367
|
+
item.appendChild(pathEl);
|
|
1368
|
+
}
|
|
1369
|
+
return item;
|
|
1370
|
+
};
|
|
822
1371
|
|
|
1372
|
+
const trimEventsList = () => {
|
|
823
1373
|
const maxEntries = 100;
|
|
824
1374
|
while (eventsList.children.length > maxEntries) {
|
|
825
1375
|
eventsList.lastElementChild?.remove();
|
|
826
1376
|
}
|
|
1377
|
+
};
|
|
827
1378
|
|
|
828
|
-
|
|
829
|
-
if (
|
|
830
|
-
|
|
831
|
-
|
|
1379
|
+
const addEventEntry = (event, dispatchedBy, targetDescription, metadata = {}) => {
|
|
1380
|
+
if (isPaused) return;
|
|
1381
|
+
|
|
1382
|
+
const eventEntry = createEventEntry(event, dispatchedBy, targetDescription, metadata);
|
|
1383
|
+
eventEntries.push(eventEntry);
|
|
1384
|
+
if (eventEntries.length > 100) eventEntries.shift();
|
|
1385
|
+
eventsList.prepend(createEventItem(eventEntry));
|
|
1386
|
+
applyFilter(); // Garante que novos eventos respeitem o filtro atual
|
|
1387
|
+
trimEventsList();
|
|
1388
|
+
|
|
1389
|
+
markConsoleEntry();
|
|
1390
|
+
};
|
|
1391
|
+
|
|
1392
|
+
const runtimeEntries = [];
|
|
1393
|
+
const createRuntimeEntryItem = (entry) => {
|
|
1394
|
+
const item = document.createElement('li');
|
|
1395
|
+
item.className = `wbc-runtime-entry wbc-runtime-entry--${entry.type}`;
|
|
1396
|
+
item.dataset.eventKind = 'runtime';
|
|
1397
|
+
item.dataset.eventTarget = entry.source || '';
|
|
1398
|
+
const heading = document.createElement('strong');
|
|
1399
|
+
heading.textContent = entry.type;
|
|
1400
|
+
item.appendChild(heading);
|
|
1401
|
+
if (entry.source) {
|
|
1402
|
+
const source = document.createElement('code');
|
|
1403
|
+
source.textContent = ` ${entry.source}${entry.line ? `:${entry.line}${entry.column ? `:${entry.column}` : ''}` : ''}`;
|
|
1404
|
+
item.appendChild(source);
|
|
832
1405
|
}
|
|
1406
|
+
const body = document.createElement('span');
|
|
1407
|
+
body.textContent = ` ${(entry.args || []).map((value) => (typeof value === 'string' ? value : serialize(value))).join(' ')}`;
|
|
1408
|
+
item.appendChild(body);
|
|
1409
|
+
return item;
|
|
1410
|
+
};
|
|
1411
|
+
|
|
1412
|
+
const addRuntimeEntry = (entry) => {
|
|
1413
|
+
if (isPaused) return;
|
|
1414
|
+
runtimeEntries.push(entry);
|
|
1415
|
+
if (runtimeEntries.length > 100) runtimeEntries.shift();
|
|
1416
|
+
eventsList.prepend(createRuntimeEntryItem(entry));
|
|
1417
|
+
applyFilter();
|
|
1418
|
+
trimEventsList();
|
|
1419
|
+
markConsoleEntry();
|
|
833
1420
|
};
|
|
1421
|
+
const clearConsole = () => {
|
|
1422
|
+
eventsList.replaceChildren();
|
|
1423
|
+
eventEntries.length = 0;
|
|
1424
|
+
runtimeEntries.length = 0;
|
|
1425
|
+
eventsTabItem.setAttribute('label', 'Console');
|
|
1426
|
+
eventsTabItem.removeAttribute('counter');
|
|
1427
|
+
newEventsCount = 0;
|
|
1428
|
+
};
|
|
1429
|
+
clearBtn.addEventListener('click', clearConsole);
|
|
834
1430
|
|
|
835
1431
|
window.WBCActiveRecorders = window.WBCActiveRecorders || [];
|
|
836
1432
|
const recorder = {
|
|
837
1433
|
preview,
|
|
838
1434
|
addEvent: addEventEntry,
|
|
839
1435
|
};
|
|
840
|
-
|
|
841
|
-
|
|
1436
|
+
|
|
1437
|
+
const applyPreviewHeight = (height) => {
|
|
1438
|
+
if (activeViewport.width || hasManualPreviewHeight) return;
|
|
1439
|
+
const maxHeight = contentDiv.classList.contains('is-fullscreen') ? Infinity : window.innerHeight * 0.75;
|
|
1440
|
+
const targetHeight = Math.max(1, Math.min(height, maxHeight));
|
|
1441
|
+
const currentHeight = parseFloat(previewFrame.style.height) || 0;
|
|
1442
|
+
if (Math.abs(targetHeight - currentHeight) > 1) {
|
|
1443
|
+
previewFrame.style.height = `${targetHeight}px`;
|
|
1444
|
+
updatePreviewResizeA11y();
|
|
1445
|
+
}
|
|
1446
|
+
};
|
|
1447
|
+
|
|
1448
|
+
const isPreviewMessage = (event) =>
|
|
1449
|
+
previewFrame &&
|
|
1450
|
+
event.source === previewFrame.contentWindow &&
|
|
1451
|
+
event.data?.__playgroundChannelId === previewChannelId &&
|
|
1452
|
+
event.data?.type?.startsWith('wbc-preview-');
|
|
1453
|
+
|
|
1454
|
+
const handlePreviewEventMessage = (data) => {
|
|
1455
|
+
const bridgedEvent = data.custom
|
|
1456
|
+
? new CustomEvent(data.eventType, {
|
|
1457
|
+
detail: data.detail,
|
|
1458
|
+
bubbles: data.bubbles,
|
|
1459
|
+
composed: data.composed,
|
|
1460
|
+
cancelable: data.cancelable,
|
|
1461
|
+
})
|
|
1462
|
+
: new Event(data.eventType, {
|
|
1463
|
+
bubbles: data.bubbles,
|
|
1464
|
+
composed: data.composed,
|
|
1465
|
+
cancelable: data.cancelable,
|
|
1466
|
+
});
|
|
1467
|
+
addEventEntry(bridgedEvent, previewFrame, data.target, data);
|
|
1468
|
+
};
|
|
1469
|
+
|
|
1470
|
+
const handlePreviewRuntimeMessage = (data) => {
|
|
1471
|
+
const runtimeTypes = ['log', 'warning', 'error', 'exception', 'unhandledrejection', 'component'];
|
|
1472
|
+
const runtimeType = runtimeTypes.includes(data.runtimeType) ? data.runtimeType : 'log';
|
|
1473
|
+
addRuntimeEntry({
|
|
1474
|
+
id: data.id,
|
|
1475
|
+
type: runtimeType,
|
|
1476
|
+
args: data.args || [],
|
|
1477
|
+
source: data.source,
|
|
1478
|
+
line: data.line,
|
|
1479
|
+
column: data.column,
|
|
1480
|
+
message: data.message,
|
|
1481
|
+
});
|
|
1482
|
+
};
|
|
1483
|
+
|
|
1484
|
+
const handlePreviewMessage = (event) => {
|
|
1485
|
+
if (!isPreviewMessage(event)) return;
|
|
1486
|
+
if (event.data.type === 'wbc-preview-exit-fullscreen') {
|
|
1487
|
+
closeFullscreen();
|
|
842
1488
|
return;
|
|
1489
|
+
}
|
|
843
1490
|
if (event.data.type === 'wbc-preview-height') {
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
} else if (event.data.type === 'wbc-preview-event') {
|
|
847
|
-
const bridgedEvent = event.data.custom
|
|
848
|
-
? new CustomEvent(event.data.eventType, { detail: event.data.detail })
|
|
849
|
-
: new Event(event.data.eventType);
|
|
850
|
-
addEventEntry(bridgedEvent, previewFrame, event.data.target);
|
|
1491
|
+
applyPreviewHeight(event.data.height);
|
|
1492
|
+
return;
|
|
851
1493
|
}
|
|
852
|
-
|
|
1494
|
+
if (event.data.type === 'wbc-preview-event') {
|
|
1495
|
+
handlePreviewEventMessage(event.data);
|
|
1496
|
+
return;
|
|
1497
|
+
}
|
|
1498
|
+
if (event.data.type === 'wbc-preview-runtime') {
|
|
1499
|
+
handlePreviewRuntimeMessage(event.data);
|
|
1500
|
+
}
|
|
1501
|
+
};
|
|
1502
|
+
|
|
1503
|
+
window.addEventListener('message', handlePreviewMessage, { signal: exampleAbortController.signal });
|
|
1504
|
+
recorder.cleanup = () => {
|
|
1505
|
+
exampleAbortController.abort();
|
|
1506
|
+
recorder.cleanupNativeEvents?.();
|
|
1507
|
+
const recorderIndex = window.WBCActiveRecorders?.indexOf(recorder) ?? -1;
|
|
1508
|
+
if (recorderIndex >= 0) window.WBCActiveRecorders.splice(recorderIndex, 1);
|
|
1509
|
+
};
|
|
853
1510
|
window.WBCActiveRecorders.push(recorder);
|
|
854
1511
|
window.WBCRegisterNativeEventRecorder?.(recorder);
|
|
1512
|
+
activeExampleCleanups.add(recorder.cleanup);
|
|
1513
|
+
|
|
1514
|
+
let runAccessibilityAudit;
|
|
1515
|
+
let accessibilityAuditTimer;
|
|
1516
|
+
const scheduleAccessibilityAudit = () => {
|
|
1517
|
+
window.clearTimeout(accessibilityAuditTimer);
|
|
1518
|
+
accessibilityAuditTimer = window.setTimeout(() => runAccessibilityAudit?.(), 650);
|
|
1519
|
+
};
|
|
1520
|
+
|
|
1521
|
+
let vanillaFileTabs;
|
|
1522
|
+
function activateVanillaFile(target) {
|
|
1523
|
+
if (target === activeVanillaFile) return;
|
|
1524
|
+
activeVanillaFile = target;
|
|
1525
|
+
vanillaFileTabs?.querySelectorAll('.wbc-framework-file-tab').forEach((item) => {
|
|
1526
|
+
const active = item.dataset.vanillaFile === target;
|
|
1527
|
+
item.classList.toggle('is-active', active);
|
|
1528
|
+
item.setAttribute('aria-selected', String(active));
|
|
1529
|
+
});
|
|
1530
|
+
if (!editorApi) return;
|
|
1531
|
+
isSwitchingVanillaFile = true;
|
|
1532
|
+
editorApi.setLanguage?.(target);
|
|
1533
|
+
editorApi.setValue(vanillaSources[target]);
|
|
1534
|
+
isSwitchingVanillaFile = false;
|
|
1535
|
+
}
|
|
855
1536
|
|
|
856
|
-
const setEditorValue = (value) => {
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
1537
|
+
const setEditorValue = (value, { recordHistory = true } = {}) => {
|
|
1538
|
+
const nextValue = String(value ?? '');
|
|
1539
|
+
if (nextValue === editorState.value) return;
|
|
1540
|
+
activateVanillaFile('html');
|
|
1541
|
+
isApplyingEditorValue = true;
|
|
1542
|
+
editorApi?.setValue(nextValue);
|
|
1543
|
+
isApplyingEditorValue = false;
|
|
1544
|
+
applyEditorValue(nextValue, { recordHistory });
|
|
860
1545
|
};
|
|
861
1546
|
|
|
862
1547
|
tabComponent.addEventListener('brTabChange', (event) => {
|
|
863
1548
|
const activeTabId = event.detail.tabId;
|
|
864
|
-
if (activeTabId !==
|
|
1549
|
+
if (activeTabId !== tabIds.code) {
|
|
865
1550
|
eventsTabItem.setAttribute('label', 'Console');
|
|
866
1551
|
newEventsCount = 0;
|
|
867
1552
|
}
|
|
868
|
-
if (frameworkTabItems.some((tab) => tab.
|
|
1553
|
+
if (frameworkTabItems.some((tab) => tab.id === activeTabId)) {
|
|
869
1554
|
refreshFrameworkEditors();
|
|
870
1555
|
}
|
|
871
1556
|
});
|
|
872
1557
|
|
|
873
|
-
|
|
1558
|
+
vanillaFileTabs = document.createElement('div');
|
|
1559
|
+
vanillaFileTabs.className = 'wbc-framework-file-tabs wbc-vanilla-file-tabs';
|
|
1560
|
+
vanillaFileTabs.setAttribute('role', 'tablist');
|
|
1561
|
+
vanillaFileTabs.setAttribute('aria-label', 'Arquivos HTML/CSS/JS');
|
|
1562
|
+
const vanillaFiles = [
|
|
1563
|
+
['html', 'index.html'],
|
|
1564
|
+
['css', 'index.css'],
|
|
1565
|
+
['javascript', 'index.js'],
|
|
1566
|
+
];
|
|
1567
|
+
vanillaFiles.forEach(([target, filename], index) => {
|
|
1568
|
+
const fileTab = document.createElement('button');
|
|
1569
|
+
fileTab.className = `wbc-framework-file-tab${index === 0 ? ' is-active' : ''}`;
|
|
1570
|
+
fileTab.type = 'button';
|
|
1571
|
+
fileTab.setAttribute('role', 'tab');
|
|
1572
|
+
fileTab.setAttribute('aria-selected', String(index === 0));
|
|
1573
|
+
fileTab.textContent = filename;
|
|
1574
|
+
fileTab.dataset.vanillaFile = target;
|
|
1575
|
+
fileTab.addEventListener('click', () => {
|
|
1576
|
+
if (target === activeVanillaFile) return;
|
|
1577
|
+
activateVanillaFile(target);
|
|
1578
|
+
refreshEditor();
|
|
1579
|
+
});
|
|
1580
|
+
vanillaFileTabs.appendChild(fileTab);
|
|
1581
|
+
});
|
|
1582
|
+
|
|
1583
|
+
codeTabItem.append(vanillaFileTabs, editorWrapper, diffPanel);
|
|
874
1584
|
eventsTabItem.appendChild(eventsWrapper);
|
|
875
1585
|
|
|
876
1586
|
// --- ACCESSIBILITY TAB ---
|
|
877
1587
|
const a11yTabItem = document.createElement('br-tab-item');
|
|
878
1588
|
a11yTabItem.setAttribute('label', 'Acessibilidade');
|
|
879
|
-
a11yTabItem.setAttribute('icon', 'fas fa-universal-access');
|
|
880
1589
|
a11yTabItem.setAttribute('icon-only', 'true');
|
|
881
|
-
a11yTabItem.setAttribute('title', '
|
|
882
|
-
a11yTabItem.
|
|
1590
|
+
a11yTabItem.setAttribute('title', 'Auditoria de acessibilidade');
|
|
1591
|
+
a11yTabItem.id = tabIds.a11y;
|
|
1592
|
+
setTabIcon(a11yTabItem, 'fas fa-universal-access');
|
|
883
1593
|
|
|
884
1594
|
const a11yWrapper = document.createElement('div');
|
|
885
1595
|
a11yWrapper.className = 'wbc-example-a11y-wrapper';
|
|
@@ -899,25 +1609,32 @@ function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
|
899
1609
|
a11yWrapper.append(a11yHeader, a11yResults);
|
|
900
1610
|
a11yTabItem.appendChild(a11yWrapper);
|
|
901
1611
|
|
|
902
|
-
const
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
1612
|
+
const showA11yMessage = (className, message, iconClass) => {
|
|
1613
|
+
const paragraph = document.createElement('p');
|
|
1614
|
+
paragraph.className = className;
|
|
1615
|
+
if (iconClass) {
|
|
1616
|
+
const icon = document.createElement('i');
|
|
1617
|
+
icon.className = `${iconClass} mr-2`;
|
|
1618
|
+
icon.setAttribute('aria-hidden', 'true');
|
|
1619
|
+
paragraph.appendChild(icon);
|
|
907
1620
|
}
|
|
1621
|
+
paragraph.appendChild(document.createTextNode(message));
|
|
1622
|
+
a11yResults.replaceChildren(paragraph);
|
|
1623
|
+
};
|
|
908
1624
|
|
|
909
|
-
|
|
910
|
-
|
|
1625
|
+
runAccessibilityAudit = async () => {
|
|
1626
|
+
showA11yMessage('mt-3', 'Analisando acessibilidade...', 'fas fa-spinner fa-spin');
|
|
911
1627
|
|
|
912
1628
|
try {
|
|
913
1629
|
const { axe, previewContent } = await getPreviewAxeContext(previewFrame);
|
|
914
1630
|
const results = await axe.run(previewContent);
|
|
915
1631
|
|
|
916
1632
|
if (results.violations.length === 0) {
|
|
917
|
-
|
|
918
|
-
|
|
1633
|
+
a11yTabItem.removeAttribute('counter');
|
|
1634
|
+
showA11yMessage('text-success mt-3', 'Nenhum problema de acessibilidade detectado!', 'fas fa-check-circle');
|
|
919
1635
|
} else {
|
|
920
|
-
|
|
1636
|
+
a11yTabItem.setAttribute('counter', String(results.violations.length));
|
|
1637
|
+
a11yResults.replaceChildren();
|
|
921
1638
|
|
|
922
1639
|
const violationsList = document.createElement('ul');
|
|
923
1640
|
violationsList.className = 'wbc-a11y-violations-list mt-3';
|
|
@@ -934,7 +1651,8 @@ function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
|
934
1651
|
impactBadge.textContent = violation.impact;
|
|
935
1652
|
|
|
936
1653
|
const helpText = document.createElement('span');
|
|
937
|
-
helpText.
|
|
1654
|
+
helpText.textContent = violation.help;
|
|
1655
|
+
helpText.style.fontWeight = '700';
|
|
938
1656
|
|
|
939
1657
|
title.append(helpText, impactBadge);
|
|
940
1658
|
|
|
@@ -955,21 +1673,23 @@ function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
|
955
1673
|
a11yResults.appendChild(violationsList);
|
|
956
1674
|
}
|
|
957
1675
|
} catch (err) {
|
|
1676
|
+
a11yTabItem.setAttribute('counter', '1');
|
|
958
1677
|
console.error(err);
|
|
959
|
-
|
|
1678
|
+
showA11yMessage(
|
|
1679
|
+
'text-danger mt-3',
|
|
1680
|
+
`Erro ao executar a análise: ${err instanceof Error ? err.message : String(err)}`,
|
|
1681
|
+
);
|
|
960
1682
|
}
|
|
961
1683
|
};
|
|
962
1684
|
|
|
963
1685
|
tabComponent.addEventListener('brTabChange', (event) => {
|
|
964
|
-
if (event.detail.tabId ===
|
|
965
|
-
if (event.detail.tabId ===
|
|
1686
|
+
if (event.detail.tabId === tabIds.a11y) runAccessibilityAudit();
|
|
1687
|
+
if (event.detail.tabId === tabIds.code) refreshEditor();
|
|
966
1688
|
});
|
|
967
1689
|
|
|
968
1690
|
tabComponent.append(
|
|
969
1691
|
codeTabItem,
|
|
970
1692
|
controlsTabItem,
|
|
971
|
-
javascriptTabItem,
|
|
972
|
-
cssTabItem,
|
|
973
1693
|
eventsTabItem,
|
|
974
1694
|
angularTabItem,
|
|
975
1695
|
reactTabItem,
|
|
@@ -979,27 +1699,76 @@ function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
|
979
1699
|
editorContainer.append(tabComponent);
|
|
980
1700
|
|
|
981
1701
|
let controlsCssSource = '';
|
|
1702
|
+
let vanillaAssetsPreviewTimer;
|
|
1703
|
+
const persistDraft = () => {
|
|
1704
|
+
writePlaygroundDraft(path, file, {
|
|
1705
|
+
html: editorState.value,
|
|
1706
|
+
css: vanillaSources.css,
|
|
1707
|
+
javascript: vanillaSources.javascript,
|
|
1708
|
+
baselineHtml: comparisonBaseline,
|
|
1709
|
+
presetId: presetSelect.value || undefined,
|
|
1710
|
+
});
|
|
1711
|
+
};
|
|
982
1712
|
const renderCurrentPreview = (source) => {
|
|
983
1713
|
const managedStyle = controlsCssSource ? `<style data-playground-controls-css>${controlsCssSource}</style>` : '';
|
|
984
|
-
|
|
1714
|
+
const exampleStyle = vanillaSources.css.trim()
|
|
1715
|
+
? `<style data-playground-css>${escapeInlineCode(vanillaSources.css, 'style')}</style>`
|
|
1716
|
+
: '';
|
|
1717
|
+
if (previewFrame) {
|
|
1718
|
+
previewFrame.classList.remove('wbc-preview-animate');
|
|
1719
|
+
void previewFrame.offsetWidth;
|
|
1720
|
+
previewFrame.classList.add('wbc-preview-animate');
|
|
1721
|
+
}
|
|
1722
|
+
renderExamplePreview(
|
|
1723
|
+
preview,
|
|
1724
|
+
`${source}${exampleStyle}${managedStyle}`,
|
|
1725
|
+
path === 'templates' || path === 'templates-ai',
|
|
1726
|
+
vanillaSources.javascript,
|
|
1727
|
+
previewChannelId,
|
|
1728
|
+
);
|
|
1729
|
+
updatePreviewResizeA11y();
|
|
985
1730
|
};
|
|
986
1731
|
|
|
987
|
-
const
|
|
1732
|
+
const handleEditorChange = (source) => {
|
|
1733
|
+
if (isSwitchingVanillaFile) return;
|
|
1734
|
+
vanillaSources[activeVanillaFile] = String(source ?? '');
|
|
1735
|
+
if (activeVanillaFile === 'html') {
|
|
1736
|
+
if (!isApplyingEditorValue) applyEditorValue(source);
|
|
1737
|
+
return;
|
|
1738
|
+
}
|
|
1739
|
+
// CSS/JS recriam o preview com debounce para não reexecutar o script a cada tecla.
|
|
1740
|
+
window.clearTimeout(vanillaAssetsPreviewTimer);
|
|
1741
|
+
vanillaAssetsPreviewTimer = window.setTimeout(() => {
|
|
1742
|
+
renderCurrentPreview(editorState.value);
|
|
1743
|
+
scheduleAccessibilityAudit();
|
|
1744
|
+
persistDraft();
|
|
1745
|
+
}, 600);
|
|
1746
|
+
};
|
|
1747
|
+
|
|
1748
|
+
const applyEditorValue = (source, { recordHistory = true } = {}) => {
|
|
1749
|
+
source = String(source ?? '');
|
|
1750
|
+
vanillaSources.html = source;
|
|
1751
|
+
if (recordHistory) recordEditorHistory(source);
|
|
988
1752
|
editorState.value = source;
|
|
989
1753
|
updateFrameworkCode(source);
|
|
990
1754
|
renderCurrentPreview(source);
|
|
1755
|
+
scheduleAccessibilityAudit();
|
|
991
1756
|
renderedFilesContent[file] = { content: source.toLowerCase(), element: contentDiv };
|
|
992
|
-
|
|
1757
|
+
persistDraft();
|
|
1758
|
+
updateHistoryActions();
|
|
1759
|
+
updateDiff(source);
|
|
1760
|
+
if (!isUpdatingFromControls) {
|
|
1761
|
+
controlsApi?.refresh?.();
|
|
1762
|
+
}
|
|
1763
|
+
// A remoção explícita ocorre antes da recriação do srcdoc para evitar que
|
|
1764
|
+
// o script específico do preset anterior permaneça no documento do iframe.
|
|
993
1765
|
};
|
|
994
1766
|
|
|
995
1767
|
const fullscreenBottomPanel = document.createElement('div');
|
|
996
1768
|
fullscreenBottomPanel.className = 'wbc-example-fullscreen-bottom-panel';
|
|
997
1769
|
fullscreenBottomPanel.appendChild(editorContainer);
|
|
998
1770
|
|
|
999
|
-
|
|
1000
|
-
fullscreenBottomPanel.setAttribute('slot', 'target');
|
|
1001
|
-
dropdown.appendChild(header);
|
|
1002
|
-
contentDiv.appendChild(dropdown);
|
|
1771
|
+
contentDiv.append(header, presetDescription, preview, fullscreenBottomPanel);
|
|
1003
1772
|
|
|
1004
1773
|
initializeExample = () => {
|
|
1005
1774
|
previewFrame = document.createElement('iframe');
|
|
@@ -1007,8 +1776,16 @@ function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
|
1007
1776
|
previewFrame.title = `Preview do exemplo ${file}`;
|
|
1008
1777
|
previewFrame.dataset.path = path;
|
|
1009
1778
|
previewFrame.setAttribute('loading', 'eager');
|
|
1010
|
-
|
|
1011
|
-
|
|
1779
|
+
previewFrame.addEventListener('load', () => {
|
|
1780
|
+
setPreviewReducedMotion(reducedMotionEnabled);
|
|
1781
|
+
setPreviewTheme(darkThemeEnabled);
|
|
1782
|
+
});
|
|
1783
|
+
previewViewport.append(previewFrame, previewWidthResizeHandle, previewHeightResizeHandle);
|
|
1784
|
+
preview.appendChild(previewViewport);
|
|
1785
|
+
preview.classList.add('wbc-example-preview--resizable');
|
|
1786
|
+
updatePreviewResizeA11y();
|
|
1787
|
+
renderCurrentPreview(editorState.value);
|
|
1788
|
+
scheduleAccessibilityAudit();
|
|
1012
1789
|
|
|
1013
1790
|
const editorReady = window.WBCCodeEditorReady || Promise.resolve(window.WBCCodeEditor);
|
|
1014
1791
|
editorReady.then(() => {
|
|
@@ -1016,7 +1793,7 @@ function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
|
1016
1793
|
editorWrapper.textContent = '';
|
|
1017
1794
|
editorApi = window.WBCCodeEditor.create({
|
|
1018
1795
|
ariaLabel: `Código fonte do exemplo ${file}`,
|
|
1019
|
-
onChange:
|
|
1796
|
+
onChange: handleEditorChange,
|
|
1020
1797
|
parent: editorWrapper,
|
|
1021
1798
|
value: editorState.value,
|
|
1022
1799
|
language: 'html',
|
|
@@ -1035,7 +1812,7 @@ function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
|
1035
1812
|
parent: editorContainer,
|
|
1036
1813
|
value: code.textContent || '',
|
|
1037
1814
|
language: getFrameworkEditorLanguage(framework),
|
|
1038
|
-
readOnly: true,
|
|
1815
|
+
readOnly: tab.dataset.editable !== 'true',
|
|
1039
1816
|
});
|
|
1040
1817
|
frameworkEditors.set(tab, editor);
|
|
1041
1818
|
tab.querySelectorAll('.wbc-framework-file-tab').forEach((fileTab) => {
|
|
@@ -1050,7 +1827,7 @@ function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
|
1050
1827
|
|
|
1051
1828
|
customElements.whenDefined('br-tab').then(() => {
|
|
1052
1829
|
requestAnimationFrame(async () => {
|
|
1053
|
-
await tabComponent.setActiveTab?.(
|
|
1830
|
+
await tabComponent.setActiveTab?.(tabIds.code);
|
|
1054
1831
|
refreshEditor();
|
|
1055
1832
|
});
|
|
1056
1833
|
});
|
|
@@ -1065,13 +1842,27 @@ function createExampleElement(path, file, text, isExpanded = false, onOpen) {
|
|
|
1065
1842
|
setCss: (value) => {
|
|
1066
1843
|
controlsCssSource = value;
|
|
1067
1844
|
renderCurrentPreview(getEditorValue());
|
|
1845
|
+
scheduleAccessibilityAudit();
|
|
1068
1846
|
},
|
|
1069
1847
|
setHtml: (value) => {
|
|
1070
|
-
|
|
1848
|
+
isUpdatingFromControls = true;
|
|
1849
|
+
try {
|
|
1850
|
+
setEditorValue(value);
|
|
1851
|
+
} finally {
|
|
1852
|
+
isUpdatingFromControls = false;
|
|
1853
|
+
}
|
|
1071
1854
|
},
|
|
1855
|
+
}).then((api) => {
|
|
1856
|
+
controlsApi = api;
|
|
1072
1857
|
});
|
|
1073
1858
|
};
|
|
1074
1859
|
|
|
1860
|
+
queueMicrotask(() => {
|
|
1861
|
+
if (isInitialized) return;
|
|
1862
|
+
initializeExample();
|
|
1863
|
+
isInitialized = true;
|
|
1864
|
+
});
|
|
1865
|
+
|
|
1075
1866
|
renderedFilesContent[file] = { content: text.toLowerCase(), element: contentDiv };
|
|
1076
1867
|
|
|
1077
1868
|
return contentDiv;
|
|
@@ -1083,7 +1874,13 @@ function createComponentTags(metadata) {
|
|
|
1083
1874
|
wrapper.setAttribute('aria-label', 'Classificação do componente');
|
|
1084
1875
|
const colors = { stable: 'var(--success)', beta: '#ffcd07', deprecated: 'var(--danger)' };
|
|
1085
1876
|
const labels = { stable: 'Estável', beta: 'Em testes', deprecated: 'Depreciado' };
|
|
1086
|
-
|
|
1877
|
+
const categories = Array.from(
|
|
1878
|
+
new Set([
|
|
1879
|
+
...(Array.isArray(metadata?.categories) ? metadata.categories : []),
|
|
1880
|
+
...(metadata?.category ? [metadata.category] : []),
|
|
1881
|
+
]),
|
|
1882
|
+
).filter((category) => typeof category === 'string' && category.trim());
|
|
1883
|
+
categories.forEach((category) => {
|
|
1087
1884
|
const tag = document.createElement('br-tag');
|
|
1088
1885
|
tag.setAttribute('label', category);
|
|
1089
1886
|
tag.setAttribute('bg-color', 'var(--interactive)');
|
|
@@ -1096,7 +1893,7 @@ function createComponentTags(metadata) {
|
|
|
1096
1893
|
statusTag.setAttribute('bg-color', colors[status] || colors.stable);
|
|
1097
1894
|
statusTag.className = `wbc-component-status wbc-component-status--${status}`;
|
|
1098
1895
|
if (status === 'beta') {
|
|
1099
|
-
statusTag.
|
|
1896
|
+
statusTag.classList.add('wbc-component-status--beta');
|
|
1100
1897
|
const tooltip = document.createElement('br-tooltip');
|
|
1101
1898
|
tooltip.setAttribute('position', 'top');
|
|
1102
1899
|
tooltip.setAttribute('aria-label', 'Status: Em testes');
|
|
@@ -1113,6 +1910,42 @@ function createComponentTags(metadata) {
|
|
|
1113
1910
|
return wrapper;
|
|
1114
1911
|
}
|
|
1115
1912
|
|
|
1913
|
+
function createComponentHeading(metadata) {
|
|
1914
|
+
const heading = document.createElement('h1');
|
|
1915
|
+
heading.className = 'wbc-component-title';
|
|
1916
|
+
heading.textContent = metadata?.name || 'Componente';
|
|
1917
|
+
return heading;
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1920
|
+
function getPresetSource(preset) {
|
|
1921
|
+
if (typeof preset?.source === 'string') return preset.source;
|
|
1922
|
+
return preset?.source?.text || '';
|
|
1923
|
+
}
|
|
1924
|
+
|
|
1925
|
+
function getSharedExampleState(path, file) {
|
|
1926
|
+
const sharedState = window.SHARED_STATE;
|
|
1927
|
+
if (sharedState?.p !== path || sharedState?.f !== file) return null;
|
|
1928
|
+
|
|
1929
|
+
const { presetId } = getHashState();
|
|
1930
|
+
if (presetId && sharedState.presetId && presetId !== sharedState.presetId) return null;
|
|
1931
|
+
return sharedState;
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1934
|
+
function getPresetForExample(path, example, presets) {
|
|
1935
|
+
const { file, presetId } = getHashState();
|
|
1936
|
+
const sharedState = getSharedExampleState(path, example.id);
|
|
1937
|
+
const candidateIds = [];
|
|
1938
|
+
|
|
1939
|
+
if (file === example.id && presetId) candidateIds.push(presetId);
|
|
1940
|
+
if (sharedState?.presetId) candidateIds.push(sharedState.presetId);
|
|
1941
|
+
candidateIds.push(example.defaultPreset, ...example.presets);
|
|
1942
|
+
|
|
1943
|
+
return candidateIds
|
|
1944
|
+
.filter(Boolean)
|
|
1945
|
+
.map((id) => presets.find((preset) => preset.id === id))
|
|
1946
|
+
.find((preset) => preset && example.presets.includes(preset.id) && getPresetSource(preset));
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1116
1949
|
function getInitialExampleFile(path, files) {
|
|
1117
1950
|
const requestedFile = getRequestedExampleFile();
|
|
1118
1951
|
if (files.includes(requestedFile)) return { initialFile: requestedFile, requestedFile };
|
|
@@ -1120,111 +1953,219 @@ function getInitialExampleFile(path, files) {
|
|
|
1120
1953
|
return { initialFile: 'default', requestedFile };
|
|
1121
1954
|
}
|
|
1122
1955
|
|
|
1123
|
-
function createExamplesList(path, results, initialFile) {
|
|
1956
|
+
function createExamplesList(path, results, presets = [], exampleConfigs = [], initialFile = 'default') {
|
|
1124
1957
|
let sharedElementToScroll = null;
|
|
1958
|
+
let initialPresetId = '';
|
|
1125
1959
|
const examples = document.createElement('br-list');
|
|
1126
1960
|
examples.className = 'wbc-examples-list';
|
|
1127
1961
|
examples.setAttribute('list-role', 'group');
|
|
1128
1962
|
examples.setAttribute('divider', '');
|
|
1963
|
+
const configById = new Map(exampleConfigs.map((example) => [example.id, example]));
|
|
1129
1964
|
results.sort((a, b) => Number(b.file === 'default') - Number(a.file === 'default'));
|
|
1130
|
-
results.forEach(({ file, text }
|
|
1965
|
+
results.forEach(({ file, text }) => {
|
|
1966
|
+
const config = configById.get(file);
|
|
1967
|
+
const availableIds = Array.isArray(config?.presets) ? new Set(config.presets) : new Set();
|
|
1968
|
+
const availablePresets = presets.filter(({ id }) => availableIds.has(id));
|
|
1969
|
+
const example = {
|
|
1970
|
+
id: file,
|
|
1971
|
+
presets: [...availableIds],
|
|
1972
|
+
defaultPreset: config?.defaultPreset,
|
|
1973
|
+
};
|
|
1974
|
+
const selectedPreset = getPresetForExample(path, example, availablePresets);
|
|
1975
|
+
const fallbackPreset = availablePresets.find(
|
|
1976
|
+
(preset) => preset.id === config?.defaultPreset && getPresetSource(preset),
|
|
1977
|
+
);
|
|
1978
|
+
const selectedPresetId =
|
|
1979
|
+
selectedPreset?.id || fallbackPreset?.id || availablePresets.find((preset) => getPresetSource(preset))?.id || '';
|
|
1131
1980
|
const element = createExampleElement(
|
|
1132
1981
|
path,
|
|
1133
1982
|
file,
|
|
1134
1983
|
text,
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
if (window.location.hash !== hash) {
|
|
1139
|
-
window.history.replaceState({}, '', `${window.location.pathname}${window.location.search}${hash}`);
|
|
1140
|
-
}
|
|
1141
|
-
examples.querySelectorAll('br-dropdown').forEach((other) => {
|
|
1142
|
-
if (other !== element.querySelector('br-dropdown') && other.isOpen) other.isOpen = false;
|
|
1143
|
-
});
|
|
1144
|
-
},
|
|
1984
|
+
availablePresets.map(({ source, ...preset }) => ({ ...preset, source: source?.text ?? null })),
|
|
1985
|
+
selectedPresetId,
|
|
1986
|
+
config?.label || file,
|
|
1145
1987
|
);
|
|
1988
|
+
element.dataset.defaultPreset =
|
|
1989
|
+
fallbackPreset?.id || availablePresets.find((preset) => getPresetSource(preset))?.id || '';
|
|
1146
1990
|
examples.appendChild(element);
|
|
1147
|
-
if (
|
|
1148
|
-
|
|
1149
|
-
return { examples, sharedElementToScroll };
|
|
1150
|
-
}
|
|
1151
|
-
|
|
1152
|
-
function openInitialDropdown(examples, initialFile) {
|
|
1153
|
-
const initialDropdown = initialFile
|
|
1154
|
-
? examples.querySelector(`[data-example-file="${CSS.escape(initialFile)}"] br-dropdown`)
|
|
1155
|
-
: null;
|
|
1156
|
-
if (!initialDropdown) return;
|
|
1157
|
-
customElements.whenDefined('br-dropdown').then(() => {
|
|
1158
|
-
initialDropdown.isOpen = false;
|
|
1159
|
-
initialDropdown.open();
|
|
1991
|
+
if (file === initialFile) initialPresetId = selectedPresetId;
|
|
1992
|
+
if (getSharedExampleState(path, file)) sharedElementToScroll = element;
|
|
1160
1993
|
});
|
|
1994
|
+
return { examples, initialPresetId, sharedElementToScroll };
|
|
1161
1995
|
}
|
|
1162
1996
|
|
|
1163
1997
|
function scrollToInitialExample(examples, requestedFile, sharedElementToScroll) {
|
|
1164
1998
|
const hashElement = requestedFile
|
|
1165
1999
|
? examples.querySelector(`[data-example-file="${CSS.escape(requestedFile)}"]`)
|
|
1166
2000
|
: null;
|
|
1167
|
-
if (hashElement)
|
|
2001
|
+
if (hashElement)
|
|
2002
|
+
setTimeout(() => hashElement.scrollIntoView({ behavior: getScrollBehavior(), block: 'center' }), 500);
|
|
1168
2003
|
if (sharedElementToScroll) {
|
|
1169
2004
|
setTimeout(() => {
|
|
1170
|
-
sharedElementToScroll.scrollIntoView({ behavior:
|
|
2005
|
+
sharedElementToScroll.scrollIntoView({ behavior: getScrollBehavior(), block: 'center' });
|
|
1171
2006
|
sharedElementToScroll.classList.add('wbc-example-shared-highlight');
|
|
1172
2007
|
}, 500);
|
|
1173
2008
|
}
|
|
1174
2009
|
}
|
|
1175
2010
|
|
|
1176
|
-
function renderLoadedPage(path,
|
|
2011
|
+
function renderLoadedPage(path, examples, results, presets = []) {
|
|
1177
2012
|
const metadata = window.MENU_ITEMS?.find((item) => item.path === path);
|
|
1178
|
-
if (metadata)
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
2013
|
+
if (metadata) {
|
|
2014
|
+
CONTENT_ELEMENT.appendChild(createComponentHeading(metadata));
|
|
2015
|
+
CONTENT_ELEMENT.appendChild(createComponentTags(metadata));
|
|
2016
|
+
}
|
|
2017
|
+
const exampleIds = examples.map(({ id }) => id);
|
|
2018
|
+
const { initialFile, requestedFile } = getInitialExampleFile(path, exampleIds);
|
|
2019
|
+
const {
|
|
2020
|
+
examples: examplesList,
|
|
2021
|
+
initialPresetId,
|
|
2022
|
+
sharedElementToScroll,
|
|
2023
|
+
} = createExamplesList(path, results, presets, examples, initialFile);
|
|
2024
|
+
CONTENT_ELEMENT.appendChild(examplesList);
|
|
2025
|
+
if (initialFile && exampleIds.includes(initialFile)) {
|
|
2026
|
+
const targetHash = getExampleHash(initialFile, initialPresetId || undefined);
|
|
2027
|
+
if (window.location.hash !== targetHash) {
|
|
2028
|
+
const url = new URL(window.location.href);
|
|
2029
|
+
url.hash = targetHash;
|
|
2030
|
+
const currentState = window.history.state;
|
|
2031
|
+
const nextState = currentState && typeof currentState === 'object' ? currentState : {};
|
|
2032
|
+
window.history.replaceState(nextState, '', url.href);
|
|
2033
|
+
}
|
|
1189
2034
|
}
|
|
1190
|
-
scrollToInitialExample(
|
|
2035
|
+
scrollToInitialExample(examplesList, requestedFile, sharedElementToScroll);
|
|
1191
2036
|
currentLoadedPath = path;
|
|
1192
2037
|
}
|
|
1193
2038
|
|
|
1194
|
-
function
|
|
2039
|
+
function normalizePageExample(example, presets) {
|
|
2040
|
+
const isLegacyExample = typeof example === 'string';
|
|
2041
|
+
const exampleConfig = isLegacyExample ? {} : example;
|
|
2042
|
+
const exampleId = isLegacyExample ? example : exampleConfig.id;
|
|
2043
|
+
const examplePresetIds = Array.isArray(exampleConfig.presets) ? exampleConfig.presets : [];
|
|
2044
|
+
const requestedPresetId = isLegacyExample ? exampleId : exampleConfig.defaultPreset;
|
|
2045
|
+
const fallbackPreset =
|
|
2046
|
+
presets.find(({ id }) => id === requestedPresetId) ??
|
|
2047
|
+
presets.find(({ id }) => id === `example-${exampleId}`) ??
|
|
2048
|
+
presets.find(({ id }) => examplePresetIds.includes(id)) ??
|
|
2049
|
+
presets[0];
|
|
2050
|
+
|
|
2051
|
+
return {
|
|
2052
|
+
...exampleConfig,
|
|
2053
|
+
id: exampleId,
|
|
2054
|
+
presets: examplePresetIds.length > 0 ? examplePresetIds : fallbackPreset ? [fallbackPreset.id] : [],
|
|
2055
|
+
defaultPreset: exampleConfig.defaultPreset || fallbackPreset?.id,
|
|
2056
|
+
};
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
function normalizePageExamples(examples, presets) {
|
|
2060
|
+
return examples.map((example) => normalizePageExample(example, presets));
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
const PLAYGROUND_SOURCE_FETCH_ATTEMPTS = 4;
|
|
2064
|
+
|
|
2065
|
+
function waitForPlaygroundSourceRetry(attempt) {
|
|
2066
|
+
return new Promise((resolve) => setTimeout(resolve, attempt * 150));
|
|
2067
|
+
}
|
|
2068
|
+
|
|
2069
|
+
async function fetchPlaygroundSource(path, source) {
|
|
2070
|
+
if (!source) throw new Error(`Fonte ausente para ${path}`);
|
|
2071
|
+
|
|
2072
|
+
let lastError;
|
|
2073
|
+
for (let attempt = 1; attempt <= PLAYGROUND_SOURCE_FETCH_ATTEMPTS; attempt += 1) {
|
|
2074
|
+
try {
|
|
2075
|
+
const response = await fetch(`${getBaseUrl()}/pages/components/${path}/${source}`, { cache: 'no-store' });
|
|
2076
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
2077
|
+
return stripDevServerConnector(await response.text());
|
|
2078
|
+
} catch (error) {
|
|
2079
|
+
lastError = error;
|
|
2080
|
+
if (attempt < PLAYGROUND_SOURCE_FETCH_ATTEMPTS) await waitForPlaygroundSourceRetry(attempt);
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
|
|
2084
|
+
throw lastError;
|
|
2085
|
+
}
|
|
2086
|
+
|
|
2087
|
+
function loadPage(path, examples, presets = [], baseScript = '', baseStyle = '') {
|
|
2088
|
+
const loadGeneration = ++pageLoadGeneration;
|
|
2089
|
+
cleanupExamples();
|
|
1195
2090
|
window.WBCActiveRecorders = [];
|
|
1196
2091
|
CONTENT_ELEMENT.innerHTML = '';
|
|
1197
2092
|
renderedFilesContent = {};
|
|
1198
2093
|
if (COMPONENTS_FILTER) COMPONENTS_FILTER.value = ''; // Limpa o campo de busca ao trocar de página
|
|
1199
|
-
if (CLEAR_COMPONENTS_FILTER) CLEAR_COMPONENTS_FILTER.
|
|
1200
|
-
|
|
1201
|
-
const
|
|
1202
|
-
const
|
|
1203
|
-
|
|
1204
|
-
|
|
2094
|
+
if (CLEAR_COMPONENTS_FILTER) CLEAR_COMPONENTS_FILTER.hidden = true;
|
|
2095
|
+
|
|
2096
|
+
const pageExamples = normalizePageExamples(examples, presets);
|
|
2097
|
+
const presetSources = new Map();
|
|
2098
|
+
const uniquePresetSources = [...new Set(presets.map(({ source }) => source).filter(Boolean))];
|
|
2099
|
+
const presetPromises = uniquePresetSources.map((source) =>
|
|
2100
|
+
fetchPlaygroundSource(path, source)
|
|
2101
|
+
.then((text) => {
|
|
2102
|
+
presetSources.set(source, text);
|
|
2103
|
+
})
|
|
2104
|
+
.catch((error) => {
|
|
2105
|
+
console.warn(`Não foi possível carregar o preset ${path}/${source}:`, error);
|
|
2106
|
+
}),
|
|
2107
|
+
);
|
|
2108
|
+
// JS e CSS do preset ficam em arquivos irmãos do HTML; `index.js`/`index.css`
|
|
2109
|
+
// valem para todos os presets do componente e vêm antes do arquivo do preset.
|
|
2110
|
+
const assetSources = new Map();
|
|
2111
|
+
const uniqueAssetSources = [
|
|
2112
|
+
...new Set([baseScript, baseStyle, ...presets.flatMap(({ script, style }) => [script, style])].filter(Boolean)),
|
|
2113
|
+
];
|
|
2114
|
+
const assetPromises = uniqueAssetSources.map((source) =>
|
|
2115
|
+
fetchPlaygroundSource(path, source)
|
|
2116
|
+
.then((text) => {
|
|
2117
|
+
assetSources.set(source, text.trim());
|
|
2118
|
+
})
|
|
2119
|
+
.catch((error) => {
|
|
2120
|
+
console.warn(`Não foi possível carregar ${path}/${source}:`, error);
|
|
2121
|
+
}),
|
|
2122
|
+
);
|
|
2123
|
+
const joinAssets = (...sources) =>
|
|
2124
|
+
sources
|
|
2125
|
+
.map((source) => assetSources.get(source))
|
|
2126
|
+
.filter(Boolean)
|
|
2127
|
+
.join('\n\n');
|
|
2128
|
+
const promises = pageExamples.map((example) => {
|
|
2129
|
+
const selectedPreset = getPresetForExample(path, example, presets);
|
|
2130
|
+
const source = getPresetSource(selectedPreset);
|
|
2131
|
+
const sharedState = getSharedExampleState(path, example.id);
|
|
2132
|
+
if (sharedState) {
|
|
2133
|
+
return Promise.resolve({ file: example.id, text: stripDevServerConnector(window.SHARED_STATE.h) });
|
|
1205
2134
|
}
|
|
1206
|
-
return
|
|
1207
|
-
response.text().then((text) => ({ file, text: stripDevServerConnector(text) })),
|
|
1208
|
-
);
|
|
2135
|
+
return fetchPlaygroundSource(path, source).then((text) => ({ file: example.id, text }));
|
|
1209
2136
|
});
|
|
1210
2137
|
|
|
1211
|
-
Promise.all(promises)
|
|
1212
|
-
.then((results) =>
|
|
2138
|
+
Promise.all([Promise.all(promises), Promise.all(presetPromises), Promise.all(assetPromises)])
|
|
2139
|
+
.then(([results]) => {
|
|
2140
|
+
if (loadGeneration !== pageLoadGeneration) return;
|
|
2141
|
+
const loadedPresets = presets.map((preset) => ({
|
|
2142
|
+
...preset,
|
|
2143
|
+
source: presetSources.has(preset.source)
|
|
2144
|
+
? { text: presetSources.get(preset.source), path: preset.source }
|
|
2145
|
+
: null,
|
|
2146
|
+
javascript: joinAssets(baseScript, preset.script),
|
|
2147
|
+
css: joinAssets(baseStyle, preset.style),
|
|
2148
|
+
}));
|
|
2149
|
+
renderLoadedPage(path, pageExamples, results, loadedPresets);
|
|
2150
|
+
})
|
|
1213
2151
|
.catch((error) => {
|
|
1214
2152
|
console.log('Erro ao carregar a página:', error);
|
|
1215
2153
|
});
|
|
1216
2154
|
}
|
|
1217
2155
|
|
|
1218
2156
|
function loadMarkdown(path) {
|
|
2157
|
+
const loadGeneration = ++pageLoadGeneration;
|
|
2158
|
+
cleanupExamples();
|
|
1219
2159
|
CONTENT_ELEMENT.innerHTML = '';
|
|
1220
2160
|
renderedFilesContent = {};
|
|
1221
2161
|
if (COMPONENTS_FILTER) COMPONENTS_FILTER.value = ''; // Limpa o campo de busca ao trocar de página
|
|
1222
|
-
if (CLEAR_COMPONENTS_FILTER) CLEAR_COMPONENTS_FILTER.
|
|
2162
|
+
if (CLEAR_COMPONENTS_FILTER) CLEAR_COMPONENTS_FILTER.hidden = true;
|
|
1223
2163
|
|
|
1224
2164
|
const baseUrl = getBaseUrl();
|
|
1225
2165
|
fetch(`${baseUrl}/assets/stencil-generated-docs/${path}.md`)
|
|
1226
2166
|
.then((response) => response.text())
|
|
1227
2167
|
.then((text) => {
|
|
2168
|
+
if (loadGeneration !== pageLoadGeneration) return;
|
|
1228
2169
|
const contentDiv = document.createElement('div');
|
|
1229
2170
|
contentDiv.classList.add('file', 'mt-2', 'mb-5');
|
|
1230
2171
|
const parsedMarkdown = typeof markdownParser?.parse === 'function' ? markdownParser.parse(text) : text;
|
|
@@ -1280,26 +2221,26 @@ function filterContent() {
|
|
|
1280
2221
|
const rows = element.querySelectorAll('table tr');
|
|
1281
2222
|
rows.forEach((row, index) => {
|
|
1282
2223
|
if (index === 0) {
|
|
1283
|
-
row.
|
|
2224
|
+
row.hidden = false;
|
|
1284
2225
|
} else {
|
|
1285
2226
|
const rowText = row.textContent
|
|
1286
2227
|
.toLowerCase()
|
|
1287
2228
|
.normalize('NFD')
|
|
1288
2229
|
.replace(/[\u0300-\u036f]/g, '');
|
|
1289
|
-
row.
|
|
2230
|
+
row.hidden = !rowText.includes(normalizedFilterValue);
|
|
1290
2231
|
}
|
|
1291
2232
|
});
|
|
1292
2233
|
} else if (
|
|
1293
2234
|
normalizedFilterValue &&
|
|
1294
2235
|
(combinedContent.includes(normalizedFilterValue) || normalizedTitleText.includes(normalizedFilterValue))
|
|
1295
2236
|
) {
|
|
1296
|
-
element.
|
|
2237
|
+
element.hidden = false;
|
|
1297
2238
|
} else {
|
|
1298
|
-
element.
|
|
2239
|
+
element.hidden = Boolean(normalizedFilterValue);
|
|
1299
2240
|
}
|
|
1300
2241
|
});
|
|
1301
2242
|
|
|
1302
|
-
if (CLEAR_COMPONENTS_FILTER) CLEAR_COMPONENTS_FILTER.
|
|
2243
|
+
if (CLEAR_COMPONENTS_FILTER) CLEAR_COMPONENTS_FILTER.hidden = !filterValue;
|
|
1303
2244
|
}
|
|
1304
2245
|
|
|
1305
2246
|
function processMenuItems(menuItems, menuBody, currentPath) {
|
|
@@ -1314,7 +2255,8 @@ function processMenuItems(menuItems, menuBody, currentPath) {
|
|
|
1314
2255
|
link.active = true;
|
|
1315
2256
|
link.classList.add('active');
|
|
1316
2257
|
}
|
|
1317
|
-
if (Array.isArray(page.
|
|
2258
|
+
if (Array.isArray(page.examples))
|
|
2259
|
+
loadPage(page.path, page.examples, page.presets, page.baseScript, page.baseStyle);
|
|
1318
2260
|
}
|
|
1319
2261
|
});
|
|
1320
2262
|
}
|
|
@@ -1336,6 +2278,20 @@ function processStaticItems(staticItems, menuBody, currentPath) {
|
|
|
1336
2278
|
});
|
|
1337
2279
|
}
|
|
1338
2280
|
|
|
2281
|
+
function requestActiveMenuScroll() {
|
|
2282
|
+
if (typeof window.scrollActiveMenuItemIntoView === 'function') {
|
|
2283
|
+
window.scrollActiveMenuItemIntoView();
|
|
2284
|
+
}
|
|
2285
|
+
}
|
|
2286
|
+
|
|
2287
|
+
function syncRenderedPresetFromLocation() {
|
|
2288
|
+
const { file, presetId } = getHashState();
|
|
2289
|
+
const targetFile = file || 'default';
|
|
2290
|
+
|
|
2291
|
+
const example = CONTENT_ELEMENT?.querySelector(`[data-example-file="${CSS.escape(targetFile)}"]`);
|
|
2292
|
+
example?._applyPresetFromUrl?.(presetId);
|
|
2293
|
+
}
|
|
2294
|
+
|
|
1339
2295
|
// Liga eventos apenas se os elementos existirem
|
|
1340
2296
|
if (COMPONENTS_FILTER) {
|
|
1341
2297
|
COMPONENTS_FILTER.addEventListener('input', filterContent);
|
|
@@ -1354,6 +2310,8 @@ function loadPageFromURL() {
|
|
|
1354
2310
|
|
|
1355
2311
|
// Evita recarregar a mesma rota em chamadas repetidas
|
|
1356
2312
|
if (currentPath === currentLoadedPath) {
|
|
2313
|
+
syncRenderedPresetFromLocation();
|
|
2314
|
+
requestActiveMenuScroll();
|
|
1357
2315
|
return;
|
|
1358
2316
|
}
|
|
1359
2317
|
|
|
@@ -1372,9 +2330,9 @@ function loadPageFromURL() {
|
|
|
1372
2330
|
processStaticItems(window.MENU_STATIC_ITEMS, menuBody, currentPath);
|
|
1373
2331
|
|
|
1374
2332
|
if (currentPath.trim().length === 0 && menuItems.length > 0) {
|
|
1375
|
-
const firstPage = menuItems.find((p) => p?.path && Array.isArray(p.
|
|
2333
|
+
const firstPage = menuItems.find((p) => p?.path && Array.isArray(p.examples));
|
|
1376
2334
|
if (firstPage) {
|
|
1377
|
-
loadPage(firstPage.path, firstPage.
|
|
2335
|
+
loadPage(firstPage.path, firstPage.examples, firstPage.presets, firstPage.baseScript, firstPage.baseStyle);
|
|
1378
2336
|
const firstLink = menuBody
|
|
1379
2337
|
? Array.from(menuBody.children).find((item) => item.getAttribute('href') === `/${firstPage.path}`)
|
|
1380
2338
|
: null;
|
|
@@ -1385,6 +2343,8 @@ function loadPageFromURL() {
|
|
|
1385
2343
|
window.history.pushState({}, '', `${baseUrl}/${firstPage.path}`);
|
|
1386
2344
|
}
|
|
1387
2345
|
}
|
|
2346
|
+
|
|
2347
|
+
requestActiveMenuScroll();
|
|
1388
2348
|
}
|
|
1389
2349
|
|
|
1390
2350
|
// Aguarda DOM e dados do menu antes de tentar carregar a rota atual
|
|
@@ -1422,15 +2382,18 @@ if (document.readyState === 'loading') {
|
|
|
1422
2382
|
// Garante atualização ao navegar com back/forward
|
|
1423
2383
|
window.addEventListener('popstate', () => bootstrapRouting());
|
|
1424
2384
|
|
|
2385
|
+
// O gerador do playground atualiza o índice enquanto o servidor permanece aberto.
|
|
2386
|
+
// Invalida a rota carregada para que os presets do JSON sejam lidos novamente.
|
|
2387
|
+
window.addEventListener('wbcMenuItemsUpdated', () => {
|
|
2388
|
+
currentLoadedPath = null;
|
|
2389
|
+
bootstrapRouting();
|
|
2390
|
+
});
|
|
2391
|
+
|
|
1425
2392
|
window.addEventListener('hashchange', () => {
|
|
2393
|
+
syncRenderedPresetFromLocation();
|
|
1426
2394
|
const file = getRequestedExampleFile();
|
|
1427
2395
|
const example = file ? document.querySelector(`br-item[data-example-file="${CSS.escape(file)}"]`) : null;
|
|
1428
2396
|
if (!example) return;
|
|
1429
2397
|
|
|
1430
|
-
|
|
1431
|
-
if (dropdown) dropdown.isOpen = true;
|
|
1432
|
-
document.querySelectorAll('.wbc-example-dropdown').forEach((other) => {
|
|
1433
|
-
if (other !== dropdown) other.isOpen = false;
|
|
1434
|
-
});
|
|
1435
|
-
setTimeout(() => example.scrollIntoView({ behavior: 'smooth', block: 'center' }), 100);
|
|
2398
|
+
setTimeout(() => example.scrollIntoView({ behavior: getScrollBehavior(), block: 'center' }), 100);
|
|
1436
2399
|
});
|