umberto 7.0.2 → 8.0.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/CHANGELOG.md +20 -1799
- package/LICENSE.md +44 -5
- package/README.md +194 -9
- package/package.json +4 -8
- package/scripts/filter/after-post-render/gloria/append-copy-heading-buttons.js +99 -0
- package/scripts/filter/after-post-render/gloria/apply-design-doc-classes.js +145 -0
- package/scripts/filter/after-post-render/gloria/wrap-table-into-wrappers.js +30 -0
- package/scripts/filter/after-post-render/img-linker.js +1 -1
- package/scripts/filter/after-post-render/insert-error-codes.js +1 -1
- package/scripts/filter/after-post-render/linker.js +1 -1
- package/scripts/filter/after-post-render/snippets.js +5 -1
- package/scripts/filter/after-render/gloria/inline-svg.js +14 -0
- package/scripts/filter/after-render/gloria/spritesheet-svg.js +14 -0
- package/scripts/filter/before-post-render/add-project-info-to-page.js +1 -1
- package/scripts/filter/before-post-render/code-switcher.js +4 -0
- package/scripts/filter/before-post-render/execute-and-insert-function-results.js +3 -1
- package/scripts/filter/before-post-render/gloria/add-breadcrumbs-data-to-page.js +269 -0
- package/scripts/filter/before-post-render/gloria/prerender-admonitions.js +27 -0
- package/scripts/filter/before-post-render/gloria/prerender-xml-pug-components.js +339 -0
- package/scripts/filter/before-post-render/gloria/render-post-render-pug-components.js +94 -0
- package/scripts/filter/before-post-render/set-layout.js +4 -2
- package/scripts/helper/parse-href.js +28 -0
- package/scripts/helper/u-capitalize.js +13 -0
- package/scripts/helper/u-random-id.js +16 -0
- package/scripts/helper/u-remove-indentation.js +13 -0
- package/scripts/helper/u-toc.js +2 -63
- package/scripts/utils/add-indention.js +16 -0
- package/scripts/utils/capitalize.js +17 -0
- package/scripts/utils/concat-url-parts.js +19 -0
- package/scripts/utils/decode-html-entities.js +25 -0
- package/scripts/utils/drop-init-slash.js +14 -0
- package/scripts/utils/drop-trailing-slash.js +14 -0
- package/scripts/utils/drop-url-protocol.js +10 -0
- package/scripts/utils/inline-svg.js +152 -0
- package/scripts/utils/measure-call.js +16 -0
- package/scripts/utils/parse-href.js +37 -0
- package/scripts/utils/parseicontag.js +1 -1
- package/scripts/utils/parselinks.js +27 -6
- package/scripts/utils/parser-cursor.js +280 -0
- package/scripts/utils/pipe.js +17 -0
- package/scripts/utils/pug-renderer/create-prerender-pug-template.js +172 -0
- package/scripts/utils/pug-renderer/render-pug-component.js +73 -0
- package/scripts/utils/pug-to-xml-binding/parser/walk-xml-tree.js +150 -0
- package/scripts/utils/pug-to-xml-binding/parser/xml-components-parser.js +414 -0
- package/scripts/utils/pug-to-xml-binding/render-xml-pug-components-in-markdown.js +193 -0
- package/scripts/utils/pug-to-xml-binding/transform-xml-tree-to-pug.js +144 -0
- package/scripts/utils/random-id.js +67 -0
- package/scripts/utils/remove-indentation.js +48 -0
- package/scripts/utils/spritesheet-svg.js +183 -0
- package/scripts/utils/toc.js +71 -0
- package/scripts/utils/transform-markdown-admonitions.js +98 -0
- package/scripts/utils/uniq-by-last.js +32 -0
- package/src/api-builder/api-builder.js +49 -18
- package/src/api-builder/classes/description-parser.js +61 -10
- package/src/api-builder/classes/doc-data-factory.js +2 -2
- package/src/helpers/github-url.js +1 -1
- package/src/helpers/templates/scripts/default.js +1 -1
- package/src/helpers/templates/scripts/group.js +1 -1
- package/src/hexo/filter/project-locals.js +9 -0
- package/src/hexo/get-repo-urls.js +1 -1
- package/src/hexo/project-globals.js +4 -0
- package/src/hexo-manager.js +7 -2
- package/src/sdk-builder/sdk-builder.js +4 -4
- package/src/tasks/build-api-docs.js +5 -5
- package/src/tasks/build-documentation.js +45 -22
- package/src/tasks/cache-files.js +2 -2
- package/src/tasks/compile-sass.js +12 -0
- package/src/tasks/copy-assets.js +4 -0
- package/src/tasks/copy-project-icons.js +1 -1
- package/src/tasks/get-extra-files.js +1 -1
- package/src/tasks/get-project-config.js +1 -1
- package/src/tasks/overwrite-api-guides.js +1 -1
- package/themes/umberto/layout/gloria/404.pug +25 -16
- package/themes/umberto/layout/gloria/_api-docs/_header/_style.scss +31 -0
- package/themes/umberto/layout/gloria/_api-docs/_header/index.pug +50 -0
- package/themes/umberto/layout/gloria/_api-docs/_mixin/_api-see-source.pug +1 -4
- package/themes/umberto/layout/gloria/_api-docs/_mixin/_api-tree-item.pug +34 -26
- package/themes/umberto/layout/gloria/_api-docs/_mixin/_class-item.pug +20 -13
- package/themes/umberto/layout/gloria/_api-docs/_mixin/_dev-names.pug +1 -1
- package/themes/umberto/layout/gloria/_api-docs/_mixin/_error.pug +10 -5
- package/themes/umberto/layout/gloria/_api-docs/_mixin/_hierarchy-list.pug +1 -1
- package/themes/umberto/layout/gloria/_api-docs/_mixin/_link-or-text.pug +1 -1
- package/themes/umberto/layout/gloria/_api-docs/_mixin/_method.pug +45 -39
- package/themes/umberto/layout/gloria/_api-docs/_mixin/_property.pug +26 -20
- package/themes/umberto/layout/gloria/_api-docs/_mixin/_related.pug +1 -1
- package/themes/umberto/layout/gloria/_api-docs/_mixin/_toc-list-item.pug +11 -0
- package/themes/umberto/layout/gloria/_api-docs/_partial/api-subheader.pug +0 -11
- package/themes/umberto/layout/gloria/_api-docs/_partial/api-toc.pug +33 -0
- package/themes/umberto/layout/gloria/_api-docs/_partial/classes.pug +5 -4
- package/themes/umberto/layout/gloria/_api-docs/_partial/config-options.pug +5 -4
- package/themes/umberto/layout/gloria/_api-docs/_partial/constants.pug +1 -1
- package/themes/umberto/layout/gloria/_api-docs/_partial/description.pug +2 -2
- package/themes/umberto/layout/gloria/_api-docs/_partial/events.pug +5 -4
- package/themes/umberto/layout/gloria/_api-docs/_partial/functions.pug +5 -4
- package/themes/umberto/layout/gloria/_api-docs/_partial/interfaces.pug +1 -1
- package/themes/umberto/layout/gloria/_api-docs/_partial/methods.pug +14 -13
- package/themes/umberto/layout/gloria/_api-docs/_partial/namespaces.pug +1 -1
- package/themes/umberto/layout/gloria/_api-docs/_partial/navtree.pug +4 -11
- package/themes/umberto/layout/gloria/_api-docs/_partial/properties.pug +14 -13
- package/themes/umberto/layout/gloria/_api-docs/_partial/type-parameters.pug +15 -12
- package/themes/umberto/layout/gloria/_api-docs/_partial/typedefs.pug +5 -4
- package/themes/umberto/layout/gloria/_api-docs/_subheader/_style.scss +5 -0
- package/themes/umberto/layout/gloria/_api-docs/_subheader/index.pug +10 -0
- package/themes/umberto/layout/gloria/_api-docs/_toc/_style.scss +227 -0
- package/themes/umberto/layout/gloria/_api-docs/_toc/index.pug +11 -0
- package/themes/umberto/layout/gloria/_api-docs/api-base.pug +24 -24
- package/themes/umberto/layout/gloria/_api-docs/class.pug +4 -4
- package/themes/umberto/layout/gloria/_api-docs/errors.pug +3 -3
- package/themes/umberto/layout/gloria/_api-docs/index.pug +3 -0
- package/themes/umberto/layout/gloria/_api-docs/interface.pug +4 -4
- package/themes/umberto/layout/gloria/_api-docs/mixin.pug +4 -4
- package/themes/umberto/layout/gloria/_api-docs/module.pug +4 -4
- package/themes/umberto/layout/gloria/_api-docs/namespace.pug +4 -4
- package/themes/umberto/layout/gloria/_api-docs/typedef.pug +22 -22
- package/themes/umberto/layout/gloria/_components/badge/_style.scss +27 -0
- package/themes/umberto/layout/gloria/_components/badge/index.pug +30 -0
- package/themes/umberto/layout/gloria/_components/banner/_style.scss +133 -0
- package/themes/umberto/layout/gloria/_components/banner/index.pug +3 -0
- package/themes/umberto/layout/gloria/_components/button/_style.scss +183 -0
- package/themes/umberto/layout/gloria/_components/button/index.pug +140 -0
- package/themes/umberto/layout/gloria/_components/callout/_style.scss +56 -0
- package/themes/umberto/layout/gloria/_components/callout/index.pug +87 -0
- package/themes/umberto/layout/gloria/_components/card/_style.scss +101 -0
- package/themes/umberto/layout/gloria/_components/card/index.pug +131 -0
- package/themes/umberto/layout/gloria/_components/card-learn-more-links/_style.scss +9 -0
- package/themes/umberto/layout/gloria/_components/card-learn-more-links/index.pug +56 -0
- package/themes/umberto/layout/gloria/_components/checkbox/_style.scss +117 -0
- package/themes/umberto/layout/gloria/_components/checkbox/index.pug +35 -0
- package/themes/umberto/layout/gloria/_components/cke5-code-switcher/index.pug +39 -0
- package/themes/umberto/layout/gloria/_components/code-block/_style.scss +111 -0
- package/themes/umberto/layout/gloria/_components/code-block/index.pug +67 -0
- package/themes/umberto/layout/gloria/_components/code-switcher/_style.scss +41 -0
- package/themes/umberto/layout/gloria/_components/code-switcher/index.pug +31 -0
- package/themes/umberto/layout/gloria/_components/columns/_style.scss +54 -0
- package/themes/umberto/layout/gloria/_components/columns/index.pug +30 -0
- package/themes/umberto/layout/gloria/_components/divider/_style.scss +6 -0
- package/themes/umberto/layout/gloria/_components/divider/index.pug +13 -0
- package/themes/umberto/layout/gloria/_components/dropdown/_style.scss +88 -0
- package/themes/umberto/layout/gloria/_components/dropdown/index.pug +77 -0
- package/themes/umberto/layout/gloria/_components/fake-devtools/_style.scss +233 -0
- package/themes/umberto/layout/gloria/_components/fake-devtools/index.pug +27 -0
- package/themes/umberto/layout/gloria/_components/heading-badge/index.pug +17 -0
- package/themes/umberto/layout/gloria/_components/heading-link/_style.scss +47 -0
- package/themes/umberto/layout/gloria/_components/heading-link/index.pug +26 -0
- package/themes/umberto/layout/gloria/_components/icon/_style.scss +12 -0
- package/themes/umberto/layout/gloria/_components/icon/index.pug +75 -0
- package/themes/umberto/layout/gloria/_components/icon-message/_style.scss +13 -0
- package/themes/umberto/layout/gloria/_components/icon-message/index.pug +17 -0
- package/themes/umberto/layout/gloria/_components/iframe/_style.scss +10 -0
- package/themes/umberto/layout/gloria/_components/iframe/index.pug +22 -0
- package/themes/umberto/layout/gloria/_components/img/index.pug +17 -0
- package/themes/umberto/layout/gloria/_components/index.pug +31 -0
- package/themes/umberto/layout/gloria/_components/input/_style.scss +82 -0
- package/themes/umberto/layout/gloria/_components/input/index.pug +34 -0
- package/themes/umberto/layout/gloria/_components/json-ld/index.pug +3 -0
- package/themes/umberto/layout/gloria/_components/keyboard-shortcut/_style.scss +49 -0
- package/themes/umberto/layout/gloria/_components/keyboard-shortcut/index.pug +23 -0
- package/themes/umberto/layout/gloria/_components/menu-dropdown/_style.scss +27 -0
- package/themes/umberto/layout/gloria/_components/menu-dropdown/index.pug +40 -0
- package/themes/umberto/layout/gloria/_components/mobile-overlay/_style.scss +70 -0
- package/themes/umberto/layout/gloria/_components/mobile-overlay/index.pug +37 -0
- package/themes/umberto/layout/gloria/_components/nav-tree/_style.scss +104 -0
- package/themes/umberto/layout/gloria/_components/nav-tree/index.pug +6 -0
- package/themes/umberto/layout/gloria/_components/nav-tree/nav-tree-item.pug +23 -0
- package/themes/umberto/layout/gloria/{_mixin → _components/nav-tree}/nav-tree-level.pug +31 -11
- package/themes/umberto/layout/gloria/_components/skeleton/_style.scss +22 -0
- package/themes/umberto/layout/gloria/_components/skeleton/index.pug +16 -0
- package/themes/umberto/layout/gloria/_components/spacer/_style.scss +9 -0
- package/themes/umberto/layout/gloria/_components/spacer/index.pug +19 -0
- package/themes/umberto/layout/gloria/_components/svg/index.pug +70 -0
- package/themes/umberto/layout/gloria/_components/tabs/_style.scss +80 -0
- package/themes/umberto/layout/gloria/_components/tabs/index.pug +81 -0
- package/themes/umberto/layout/gloria/_components/tag/_style.scss +79 -0
- package/themes/umberto/layout/gloria/_components/tag/index.pug +17 -0
- package/themes/umberto/layout/gloria/_components/tooltip-popover/_style.scss +194 -0
- package/themes/umberto/layout/gloria/_components/tooltip-popover/index.pug +38 -0
- package/themes/umberto/layout/gloria/_head/head-preloads.pug +32 -0
- package/themes/umberto/layout/gloria/{_partial → _head}/head.pug +8 -4
- package/themes/umberto/layout/gloria/_head/index.pug +1 -0
- package/themes/umberto/layout/gloria/_modules/algolia-search/_style.scss +202 -0
- package/themes/umberto/layout/gloria/_modules/algolia-search/_third-party.scss +1 -0
- package/themes/umberto/layout/gloria/_modules/algolia-search/index.pug +38 -0
- package/themes/umberto/layout/gloria/_modules/breadcrumbs/_style.scss +68 -0
- package/themes/umberto/layout/gloria/_modules/breadcrumbs/index.pug +18 -0
- package/themes/umberto/layout/gloria/_modules/footer/_style.scss +40 -0
- package/themes/umberto/layout/gloria/_modules/footer/index.pug +87 -0
- package/themes/umberto/layout/gloria/_modules/header/_style.scss +181 -0
- package/themes/umberto/layout/gloria/_modules/header/index.pug +70 -0
- package/themes/umberto/layout/gloria/_modules/header/nav-link.pug +19 -0
- package/themes/umberto/layout/gloria/_modules/header/nav-links.pug +11 -0
- package/themes/umberto/layout/gloria/_modules/header/nav-project-select-dropdown.pug +16 -0
- package/themes/umberto/layout/gloria/_modules/header/nav-suffix-links.pug +20 -0
- package/themes/umberto/layout/gloria/_modules/header-bar/_style.scss +56 -0
- package/themes/umberto/layout/gloria/_modules/header-bar/index.pug +40 -0
- package/themes/umberto/layout/gloria/_modules/header-legacy-warning/index.pug +11 -0
- package/themes/umberto/layout/gloria/_modules/header-nightly-info/index.pug +20 -0
- package/themes/umberto/layout/gloria/_modules/header-promobar/index.pug +18 -0
- package/themes/umberto/layout/gloria/_modules/index.pug +14 -0
- package/themes/umberto/layout/gloria/_modules/main/_style.scss +54 -0
- package/themes/umberto/layout/gloria/_modules/main/index.pug +10 -0
- package/themes/umberto/layout/gloria/_modules/mobile-nav/_style.scss +106 -0
- package/themes/umberto/layout/gloria/_modules/mobile-nav/index.pug +121 -0
- package/themes/umberto/layout/gloria/_modules/mobile-nav/slide-parts.pug +67 -0
- package/themes/umberto/layout/gloria/_modules/not-found/_style.scss +38 -0
- package/themes/umberto/layout/gloria/_modules/not-found/index.pug +16 -0
- package/themes/umberto/layout/gloria/_modules/sidebar/_style.scss +147 -0
- package/themes/umberto/layout/gloria/_modules/sidebar/index.pug +24 -0
- package/themes/umberto/layout/gloria/_modules/sidebar-api/_style.scss +2 -0
- package/themes/umberto/layout/gloria/_modules/sidebar-api/index.pug +6 -0
- package/themes/umberto/layout/gloria/_modules/toc/_style.scss +201 -0
- package/themes/umberto/layout/gloria/_modules/toc/index.pug +10 -0
- package/themes/umberto/layout/gloria/_trackers/google-tag-manager.pug +14 -0
- package/themes/umberto/layout/gloria/_trackers/index.pug +2 -0
- package/themes/umberto/layout/gloria/api.pug +43 -20
- package/themes/umberto/layout/gloria/base.pug +23 -32
- package/themes/umberto/layout/gloria/index.pug +19 -13
- package/themes/umberto/layout/gloria/page.pug +30 -11
- package/themes/umberto/layout/gloria/sdk.pug +1 -1
- package/themes/umberto/layout/gloria/theme.pug +304 -0
- package/themes/umberto/layout/umberto/404.pug +0 -1
- package/themes/umberto/layout/umberto/_partial/report-issue-widget.pug +0 -3
- package/themes/umberto/source/gloria/assets/_fonts/Menlo/Menlo-Regular.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Menlo/Menlo-Regular.woff +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/Mulish-Italic-VariableFont_wght.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/Mulish-Italic-VariableFont_wght.woff2 +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/Mulish-VariableFont_wght.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/Mulish-VariableFont_wght.woff2 +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/static/Mulish-Black.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/static/Mulish-BlackItalic.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/static/Mulish-Bold.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/static/Mulish-BoldItalic.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/static/Mulish-ExtraBold.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/static/Mulish-ExtraBoldItalic.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/static/Mulish-ExtraLight.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/static/Mulish-ExtraLightItalic.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/static/Mulish-Italic.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/static/Mulish-Light.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/static/Mulish-LightItalic.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/static/Mulish-Medium.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/static/Mulish-MediumItalic.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/static/Mulish-Regular.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/static/Mulish-SemiBold.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Mulish/static/Mulish-SemiBoldItalic.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/PublicSans-Italic-VariableFont_wght.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/PublicSans-Italic-VariableFont_wght.woff2 +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/PublicSans-VariableFont_wght.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/PublicSans-VariableFont_wght.woff2 +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-Black.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-BlackItalic.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-Bold.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-BoldItalic.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-ExtraBold.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-ExtraBoldItalic.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-ExtraLight.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-ExtraLightItalic.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-Italic.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-Light.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-LightItalic.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-Medium.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-MediumItalic.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-Regular.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-SemiBold.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-SemiBoldItalic.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-Thin.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_fonts/Public_Sans/static/PublicSans-ThinItalic.ttf +0 -0
- package/themes/umberto/source/gloria/assets/_img/404-billboard.svg +181 -0
- package/themes/umberto/source/gloria/assets/_img/ckeditor-logo.svg +15 -0
- package/themes/umberto/source/gloria/assets/_img/hex-bg-2.svg +10 -0
- package/themes/umberto/source/gloria/assets/_img/hex-bg.svg +10 -0
- package/themes/umberto/source/gloria/assets/_img/icons/api-class.svg +10 -0
- package/themes/umberto/source/gloria/assets/_img/icons/api-folder.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/api-interface.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/api-module.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/api-package.svg +4 -0
- package/themes/umberto/source/gloria/assets/_img/icons/api-typedef.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/bulb.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/check-circle.svg +4 -0
- package/themes/umberto/source/gloria/assets/_img/icons/check.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/chevron-down.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/chevron-right.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/close-circle.svg +4 -0
- package/themes/umberto/source/gloria/assets/_img/icons/close.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/copy.svg +10 -0
- package/themes/umberto/source/gloria/assets/_img/icons/dislike.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/download.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/edit.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/exclamation-circle.svg +4 -0
- package/themes/umberto/source/gloria/assets/_img/icons/experiment.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/export.svg +4 -0
- package/themes/umberto/source/gloria/assets/_img/icons/eye.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/filter.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/github.svg +10 -0
- package/themes/umberto/source/gloria/assets/_img/icons/info-circle.svg +4 -0
- package/themes/umberto/source/gloria/assets/_img/icons/like.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/link.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/lock.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/menu-fold.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/menu-list.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/menu.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/more.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/notification.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/number.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/premium.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/right.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/search.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/status.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/trash.svg +3 -0
- package/themes/umberto/source/gloria/assets/_img/icons/unordered-list.svg +5 -0
- package/themes/umberto/source/gloria/assets/_img/icons/warning.svg +10 -0
- package/themes/umberto/src/gloria/css/_fonts.scss +51 -0
- package/themes/umberto/src/gloria/css/_layers.scss +1 -0
- package/themes/umberto/src/gloria/css/_normalize.scss +118 -0
- package/themes/umberto/src/gloria/css/a11y/_focusable.scss +7 -0
- package/themes/umberto/src/gloria/css/a11y/_index.scss +4 -0
- package/themes/umberto/src/gloria/css/a11y/_mixins.scss +32 -0
- package/themes/umberto/src/gloria/css/a11y/_reduce-motion.scss +9 -0
- package/themes/umberto/src/gloria/css/a11y/_screen-reader.scss +15 -0
- package/themes/umberto/src/gloria/css/base/_buttons.scss +13 -0
- package/themes/umberto/src/gloria/css/base/_descriptions-list.scss +33 -0
- package/themes/umberto/src/gloria/css/base/_details.scss +7 -0
- package/themes/umberto/src/gloria/css/base/_headings.scss +111 -0
- package/themes/umberto/src/gloria/css/base/_iframes.scss +7 -0
- package/themes/umberto/src/gloria/css/base/_index.scss +12 -0
- package/themes/umberto/src/gloria/css/base/_inline-code.scss +15 -0
- package/themes/umberto/src/gloria/css/base/_links.scss +30 -0
- package/themes/umberto/src/gloria/css/base/_lists.scss +58 -0
- package/themes/umberto/src/gloria/css/base/_mixins.scss +3 -0
- package/themes/umberto/src/gloria/css/base/_paragraphs.scss +15 -0
- package/themes/umberto/src/gloria/css/base/_tables.scss +68 -0
- package/themes/umberto/src/gloria/css/base/_typography.scss +62 -0
- package/themes/umberto/src/gloria/css/components/_api-collapsing-list.scss +148 -0
- package/themes/umberto/src/gloria/css/components/_api-filter-dropdown.scss +17 -0
- package/themes/umberto/src/gloria/css/components/_api-item-heading.scss +58 -0
- package/themes/umberto/src/gloria/css/components/_api-tree.scss +202 -0
- package/themes/umberto/src/gloria/css/components/_hierarchy-list.scss +35 -0
- package/themes/umberto/src/gloria/css/components/_image-zoom.scss +13 -0
- package/themes/umberto/src/gloria/css/components/_index.scss +55 -0
- package/themes/umberto/src/gloria/css/components/_notification.scss +36 -0
- package/themes/umberto/src/gloria/css/components/_utils.scss +5 -0
- package/themes/umberto/src/gloria/css/doc/_details.scss +11 -0
- package/themes/umberto/src/gloria/css/doc/_editor-icons.scss +21 -0
- package/themes/umberto/src/gloria/css/doc/_images.scss +9 -0
- package/themes/umberto/src/gloria/css/doc/_index.scss +5 -0
- package/themes/umberto/src/gloria/css/doc/_snippets.scss +126 -0
- package/themes/umberto/src/gloria/css/doc/_typography.scss +5 -0
- package/themes/umberto/src/gloria/css/layout/_base.scss +27 -0
- package/themes/umberto/src/gloria/css/layout/_breakpoints.scss +88 -0
- package/themes/umberto/src/gloria/css/layout/_container.scss +38 -0
- package/themes/umberto/src/gloria/css/layout/_index.scss +6 -0
- package/themes/umberto/src/gloria/css/layout/_layout.scss +64 -0
- package/themes/umberto/src/gloria/css/layout/_mixins.scss +34 -0
- package/themes/umberto/src/gloria/css/layout/_zindex.scss +12 -0
- package/themes/umberto/src/gloria/css/modules/_index.scss +29 -0
- package/themes/umberto/src/gloria/css/modules/_utils.scss +7 -0
- package/themes/umberto/src/gloria/css/styles.scss +11 -117
- package/themes/umberto/src/gloria/css/theme/_light.scss +344 -0
- package/themes/umberto/src/gloria/css/utilities/_animation.scss +32 -0
- package/themes/umberto/src/gloria/css/utilities/_colors.scss +14 -0
- package/themes/umberto/src/gloria/css/utilities/_display.scss +13 -0
- package/themes/umberto/src/gloria/css/utilities/_flex.scss +33 -0
- package/themes/umberto/src/gloria/css/utilities/_gap.scss +8 -0
- package/themes/umberto/src/gloria/css/utilities/_index.scss +11 -0
- package/themes/umberto/src/gloria/css/utilities/_radius.scss +21 -0
- package/themes/umberto/src/gloria/css/utilities/_rotation.scss +8 -0
- package/themes/umberto/src/gloria/css/utilities/_shadows.scss +13 -0
- package/themes/umberto/src/gloria/css/utilities/_spacing.scss +96 -0
- package/themes/umberto/src/gloria/css/utilities/_stop-scrolling.scss +9 -0
- package/themes/umberto/src/gloria/css/utilities/_text.scss +42 -0
- package/themes/umberto/src/gloria/js/app.js +92 -54
- package/themes/umberto/src/gloria/js/components/api-nav-tree.js +171 -0
- package/themes/umberto/src/gloria/js/components/api-toggle.js +92 -0
- package/themes/umberto/src/gloria/js/components/base-component.js +41 -0
- package/themes/umberto/src/gloria/js/components/breadcrumbs.js +115 -0
- package/themes/umberto/src/gloria/js/components/code-block.js +226 -0
- package/themes/umberto/src/gloria/js/components/code-switcher.js +177 -0
- package/themes/umberto/src/gloria/js/components/dropdown.js +516 -0
- package/themes/umberto/src/gloria/js/components/expandable.js +79 -0
- package/themes/umberto/src/gloria/js/components/fake-devtools.js +722 -0
- package/themes/umberto/src/gloria/js/components/hash-link.js +60 -0
- package/themes/umberto/src/gloria/js/components/heading-link.js +135 -0
- package/themes/umberto/src/gloria/js/components/iframe.js +158 -0
- package/themes/umberto/src/gloria/js/{_imageModal.js → components/image-zoom.js} +1 -1
- package/themes/umberto/src/gloria/js/components/mobile-overlay.js +315 -0
- package/themes/umberto/src/gloria/js/components/nav-tree.js +164 -0
- package/themes/umberto/src/gloria/js/components/tabs.js +284 -0
- package/themes/umberto/src/gloria/js/components/tooltip-popover.js +576 -0
- package/themes/umberto/src/gloria/js/helpers/after-dom-ready.js +16 -0
- package/themes/umberto/src/gloria/js/helpers/animate-element.js +78 -0
- package/themes/umberto/src/gloria/js/helpers/body-scroll.js +22 -0
- package/themes/umberto/src/gloria/js/helpers/clamp.js +16 -0
- package/themes/umberto/src/gloria/js/helpers/classnames.js +64 -0
- package/themes/umberto/src/gloria/js/helpers/copy-to-clipboard.js +19 -0
- package/themes/umberto/src/gloria/js/helpers/create-anchor-positioning-watcher.js +46 -0
- package/themes/umberto/src/gloria/js/helpers/create-cleanup-registry.js +88 -0
- package/themes/umberto/src/gloria/js/helpers/create-hover-manager.js +93 -0
- package/themes/umberto/src/gloria/js/helpers/create-keyboard-blur-watcher.js +90 -0
- package/themes/umberto/src/gloria/js/helpers/create-keyboard-focus-cycler.js +251 -0
- package/themes/umberto/src/gloria/js/helpers/create-mutation-observer.js +49 -0
- package/themes/umberto/src/gloria/js/helpers/create-outside-click-watcher.js +39 -0
- package/themes/umberto/src/gloria/js/helpers/cubic-bezier.js +55 -0
- package/themes/umberto/src/gloria/js/helpers/date-time.js +21 -0
- package/themes/umberto/src/gloria/js/helpers/decode-html-entities.js +23 -0
- package/themes/umberto/src/gloria/js/helpers/escape-handler.js +59 -0
- package/themes/umberto/src/gloria/js/helpers/fetch-stylesheet.js +25 -0
- package/themes/umberto/src/gloria/js/helpers/find-code-lang.js +85 -0
- package/themes/umberto/src/gloria/js/helpers/focus-first-interactive.js +50 -0
- package/themes/umberto/src/gloria/js/helpers/format-html.js +181 -0
- package/themes/umberto/src/gloria/js/helpers/get-all-scrollable-parents.js +34 -0
- package/themes/umberto/src/gloria/js/helpers/get-parents-until.js +26 -0
- package/themes/umberto/src/gloria/js/helpers/highlight-code.js +18 -0
- package/themes/umberto/src/gloria/js/helpers/html-builder.js +69 -0
- package/themes/umberto/src/gloria/js/helpers/identity.js +8 -0
- package/themes/umberto/src/gloria/js/helpers/inject-resource-preload.js +51 -0
- package/themes/umberto/src/gloria/js/helpers/inject-script.js +79 -0
- package/themes/umberto/src/gloria/js/helpers/inject-stylesheet.js +108 -0
- package/themes/umberto/src/gloria/js/helpers/is-element-attached.js +28 -0
- package/themes/umberto/src/gloria/js/helpers/is-focusable.js +14 -0
- package/themes/umberto/src/gloria/js/helpers/is-hidden-element.js +8 -0
- package/themes/umberto/src/gloria/js/helpers/is-mobile.js +8 -0
- package/themes/umberto/src/gloria/js/helpers/is-unsafe-key.js +14 -0
- package/themes/umberto/src/gloria/js/helpers/lerp.js +27 -0
- package/themes/umberto/src/gloria/js/helpers/local-storage-helper.js +133 -0
- package/themes/umberto/src/gloria/js/helpers/pipe.js +8 -0
- package/themes/umberto/src/gloria/js/helpers/prefers-reduced-motion.js +13 -0
- package/themes/umberto/src/gloria/js/helpers/random-id.js +51 -0
- package/themes/umberto/src/gloria/js/helpers/sanitize-text.js +27 -0
- package/themes/umberto/src/gloria/js/helpers/scroll-to-hash.js +31 -0
- package/themes/umberto/src/gloria/js/helpers/take-last.js +19 -0
- package/themes/umberto/src/gloria/js/helpers/tap.js +11 -0
- package/themes/umberto/src/gloria/js/helpers/throttle.js +46 -0
- package/themes/umberto/src/gloria/js/helpers/timeout.js +14 -0
- package/themes/umberto/src/gloria/js/helpers/toggle-height.js +46 -0
- package/themes/umberto/src/gloria/js/helpers/tween.js +100 -0
- package/themes/umberto/src/gloria/js/helpers/wrap-around.js +39 -0
- package/themes/umberto/src/gloria/js/modules/algolia-search.js +168 -0
- package/themes/umberto/src/gloria/js/modules/api-filter.js +184 -0
- package/themes/umberto/src/gloria/js/modules/header-bar.js +154 -0
- package/themes/umberto/src/gloria/js/modules/header.js +242 -0
- package/themes/umberto/src/gloria/js/modules/links-prefetch.js +196 -0
- package/themes/umberto/src/gloria/js/modules/mobile-nav.js +327 -0
- package/themes/umberto/src/gloria/js/modules/sidebar.js +114 -0
- package/themes/umberto/src/gloria/js/modules/table-of-contents-api.js +214 -0
- package/themes/umberto/src/gloria/js/modules/table-of-contents.js +287 -0
- package/themes/umberto/src/gloria/js/public-api.js +75 -0
- package/themes/umberto/src/gloria/js/web-components/svg-icon.js +117 -0
- package/themes/umberto/src/umberto/js/_codeswitcherbuttons.js +1 -1
- package/themes/umberto/layout/gloria/_api-docs/_mixin/_api-title.pug +0 -17
- package/themes/umberto/layout/gloria/_mixin/nav-tree-item.pug +0 -13
- package/themes/umberto/layout/gloria/_partial/docsearch.pug +0 -21
- package/themes/umberto/layout/gloria/_partial/dropdown.pug +0 -12
- package/themes/umberto/layout/gloria/_partial/feedback-widget.pug +0 -20
- package/themes/umberto/layout/gloria/_partial/footer.pug +0 -6
- package/themes/umberto/layout/gloria/_partial/gh-contribute.pug +0 -8
- package/themes/umberto/layout/gloria/_partial/google-tag-manager.pug +0 -18
- package/themes/umberto/layout/gloria/_partial/header.pug +0 -64
- package/themes/umberto/layout/gloria/_partial/nav-tree.pug +0 -9
- package/themes/umberto/layout/gloria/_partial/report-issue-widget.pug +0 -26
- package/themes/umberto/layout/gloria/_partial/rwd-breadcrumbs.pug +0 -13
- package/themes/umberto/layout/gloria/_partial/search-box.pug +0 -6
- package/themes/umberto/layout/gloria/_partial/vwo.pug +0 -11
- package/themes/umberto/source/gloria/assets/_img/arrows.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/book.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/box-brown.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/box-orange.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/box-red.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/bulb.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/clipboard.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/cog.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/data.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/documentation.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/download.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/edit.svg +0 -2
- package/themes/umberto/source/gloria/assets/_img/exclamation-circle.svg +0 -2
- package/themes/umberto/source/gloria/assets/_img/eye.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/filter.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/filtering.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/folder.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/github.svg +0 -6
- package/themes/umberto/source/gloria/assets/_img/header-info-configs.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/header-info-events.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/header-info-methods.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/header-info-properties.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/heart.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/info-circle.svg +0 -4
- package/themes/umberto/source/gloria/assets/_img/info.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/list-nest.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/loupe.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/menu.svg +0 -4
- package/themes/umberto/source/gloria/assets/_img/plug.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/star-in-circle.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/tick.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/triangle-down.svg +0 -1
- package/themes/umberto/source/gloria/assets/_img/triangle-right.svg +0 -1
- package/themes/umberto/src/gloria/css/_api-content.scss +0 -32
- package/themes/umberto/src/gloria/css/_api-info-box.scss +0 -86
- package/themes/umberto/src/gloria/css/_api-props-filter.scss +0 -106
- package/themes/umberto/src/gloria/css/_api-see-source.scss +0 -35
- package/themes/umberto/src/gloria/css/_api-subheader.scss +0 -167
- package/themes/umberto/src/gloria/css/_api-tree.scss +0 -121
- package/themes/umberto/src/gloria/css/_badge.scss +0 -74
- package/themes/umberto/src/gloria/css/_code-switcher.scss +0 -61
- package/themes/umberto/src/gloria/css/_collapsinglist.scss +0 -262
- package/themes/umberto/src/gloria/css/_content.scss +0 -236
- package/themes/umberto/src/gloria/css/_docsearch.scss +0 -109
- package/themes/umberto/src/gloria/css/_dropdown.scss +0 -63
- package/themes/umberto/src/gloria/css/_editor-icon.scss +0 -26
- package/themes/umberto/src/gloria/css/_feedback-widget.scss +0 -11
- package/themes/umberto/src/gloria/css/_font-external.scss +0 -8
- package/themes/umberto/src/gloria/css/_footer.scss +0 -40
- package/themes/umberto/src/gloria/css/_formatted.scss +0 -285
- package/themes/umberto/src/gloria/css/_guide-content.scss +0 -37
- package/themes/umberto/src/gloria/css/_guide-sdk-tree.scss +0 -14
- package/themes/umberto/src/gloria/css/_loading-spinner.scss +0 -33
- package/themes/umberto/src/gloria/css/_main.scss +0 -59
- package/themes/umberto/src/gloria/css/_navigation.scss +0 -35
- package/themes/umberto/src/gloria/css/_notice.scss +0 -116
- package/themes/umberto/src/gloria/css/_print.scss +0 -20
- package/themes/umberto/src/gloria/css/_prism.scss +0 -223
- package/themes/umberto/src/gloria/css/_rwd-breadcrumbs.scss +0 -28
- package/themes/umberto/src/gloria/css/_rwd-menu.scss +0 -89
- package/themes/umberto/src/gloria/css/_secondary-navigation.scss +0 -152
- package/themes/umberto/src/gloria/css/_theme-dark.scss +0 -175
- package/themes/umberto/src/gloria/css/_toggler.scss +0 -46
- package/themes/umberto/src/gloria/css/_top.scss +0 -350
- package/themes/umberto/src/gloria/css/_tree.scss +0 -218
- package/themes/umberto/src/gloria/css/_warning-banner.scss +0 -46
- package/themes/umberto/src/gloria/css/components/_lightbox.scss +0 -12
- package/themes/umberto/src/gloria/css/helpers/_color.scss +0 -49
- package/themes/umberto/src/gloria/css/helpers/_font.scss +0 -60
- package/themes/umberto/src/gloria/css/helpers/_globals.scss +0 -129
- package/themes/umberto/src/gloria/css/helpers/_reset.scss +0 -52
- package/themes/umberto/src/gloria/css/helpers/_spacing.scss +0 -21
- package/themes/umberto/src/gloria/css/pages/_sdk.scss +0 -111
- package/themes/umberto/src/gloria/js/_anchors.js +0 -57
- package/themes/umberto/src/gloria/js/_apisearch.js +0 -126
- package/themes/umberto/src/gloria/js/_apitree.js +0 -67
- package/themes/umberto/src/gloria/js/_attachpermalinklistener.js +0 -50
- package/themes/umberto/src/gloria/js/_codeswitcherbuttons.js +0 -146
- package/themes/umberto/src/gloria/js/_collapsables.js +0 -135
- package/themes/umberto/src/gloria/js/_copymobileapinavigation.js +0 -26
- package/themes/umberto/src/gloria/js/_devnames.js +0 -37
- package/themes/umberto/src/gloria/js/_dropdowns.js +0 -55
- package/themes/umberto/src/gloria/js/_filtering.js +0 -139
- package/themes/umberto/src/gloria/js/_pagenavigation.js +0 -93
- package/themes/umberto/src/gloria/js/_prism.js +0 -104
- package/themes/umberto/src/gloria/js/_rwdmenu.js +0 -15
- package/themes/umberto/src/gloria/js/_samplecode.js +0 -23
- package/themes/umberto/src/gloria/js/_sidenavigation.js +0 -59
- package/themes/umberto/src/gloria/js/_toc.js +0 -93
- package/themes/umberto/src/gloria/js/_tooltips.js +0 -39
- package/themes/umberto/src/gloria/js/_warningbanner.js +0 -18
- package/themes/umberto/src/gloria/js/vendor/prism.js +0 -45
- /package/themes/umberto/layout/gloria/_api-docs/_partial/{api-info-box.pug → api-hierarchy.pug} +0 -0
- /package/themes/umberto/layout/gloria/{_partial → _trackers}/google-analytics.pug +0 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2017-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A simplified utility for conditionally joining class names together.
|
|
8
|
+
* Similar to clsx/classnames that accepts arrays and objects for convenience.
|
|
9
|
+
*
|
|
10
|
+
* @param args - Class names, arrays, objects, or conditional expressions
|
|
11
|
+
* @returns Filtered and joined class names
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* // Basic usage with array
|
|
15
|
+
* cx(['foo', 'bar']); // => 'foo bar'
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // Multiple arguments
|
|
19
|
+
* cx('foo', 'bar'); // => 'foo bar'
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* // Filtering out falsy values
|
|
23
|
+
* cx(['foo', null, 'bar', undefined, '', false, 0]); // => 'foo bar'
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* // With conditional expressions
|
|
27
|
+
* cx(['base', isActive && 'active', hasError && 'error']); // => returns 'base active' or 'base error' depending on conditions
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* // Object syntax
|
|
31
|
+
* cx({ foo: true, bar: false, baz: isCondition }); // => 'foo baz' if isCondition is true, otherwise just 'foo'
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* // Mixed arguments
|
|
35
|
+
* cx('base', { active: isActive, disabled: isDisabled }, ['extra', condition && 'conditional']); // => combines all formats
|
|
36
|
+
*/
|
|
37
|
+
export function cx( ...args ) {
|
|
38
|
+
return args
|
|
39
|
+
.flatMap( arg => {
|
|
40
|
+
if ( !arg ) {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if ( typeof arg === 'string' ) {
|
|
45
|
+
return arg;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if ( Array.isArray( arg ) ) {
|
|
49
|
+
return cx( ...arg );
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if ( typeof arg === 'object' ) {
|
|
53
|
+
return Object
|
|
54
|
+
.entries( arg )
|
|
55
|
+
.filter( ( [ , value ] ) => Boolean( value ) )
|
|
56
|
+
.map( ( [ key ] ) => key );
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return [];
|
|
60
|
+
} )
|
|
61
|
+
.filter( Boolean )
|
|
62
|
+
.join( ' ' )
|
|
63
|
+
.trim();
|
|
64
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2017-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Copies the provided text to clipboard.
|
|
8
|
+
*
|
|
9
|
+
* @param text - The text to copy to clipboard
|
|
10
|
+
* @returns Promise that resolves when text is copied or rejects on error
|
|
11
|
+
*/
|
|
12
|
+
export function copyToClipboard( text ) {
|
|
13
|
+
// Use the more modern navigator.clipboard API if available
|
|
14
|
+
if ( navigator.clipboard && navigator.clipboard.writeText ) {
|
|
15
|
+
return navigator.clipboard.writeText( text );
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
throw new Error( 'Clipboard API is not supported in this browser.' );
|
|
19
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2017-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { getAllScrollableParents } from './get-all-scrollable-parents';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Sets up positioning event listeners for an element.
|
|
10
|
+
*
|
|
11
|
+
* @param config - Configuration object
|
|
12
|
+
* @param config.element - The element to watch for positioning
|
|
13
|
+
* @param config.handler - The handler function to call when positioning events occur
|
|
14
|
+
* @returns A function that cleans up all event listeners when called
|
|
15
|
+
*/
|
|
16
|
+
export function createAnchorPositioningWatcher( { element, handler } ) {
|
|
17
|
+
const cleanupCallbacks = [];
|
|
18
|
+
|
|
19
|
+
// Get all scrollable parents of the element
|
|
20
|
+
const scrollableParents = getAllScrollableParents( element, true );
|
|
21
|
+
|
|
22
|
+
// Add event listeners to window for resize
|
|
23
|
+
window.addEventListener( 'resize', handler, { passive: true } );
|
|
24
|
+
cleanupCallbacks.push( () => {
|
|
25
|
+
window.removeEventListener( 'resize', handler );
|
|
26
|
+
} );
|
|
27
|
+
|
|
28
|
+
// Add wheel and scroll event listeners to all scrollable parents
|
|
29
|
+
for ( const parent of scrollableParents ) {
|
|
30
|
+
parent.addEventListener( 'wheel', handler, { passive: true } );
|
|
31
|
+
parent.addEventListener( 'scroll', handler, { passive: true } );
|
|
32
|
+
|
|
33
|
+
// Store cleanup callbacks
|
|
34
|
+
cleanupCallbacks.push( () => {
|
|
35
|
+
parent.removeEventListener( 'wheel', handler );
|
|
36
|
+
parent.removeEventListener( 'scroll', handler );
|
|
37
|
+
} );
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Return a single function that cleans up all event listeners
|
|
41
|
+
return () => {
|
|
42
|
+
for ( const cleanup of cleanupCallbacks ) {
|
|
43
|
+
cleanup();
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2017-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a cleanup registry that manages a collection of cleanup callbacks.
|
|
8
|
+
*
|
|
9
|
+
* @returns An object with methods to register and destroy callbacks
|
|
10
|
+
*/
|
|
11
|
+
export function createCleanupRegistry() {
|
|
12
|
+
const callbacks = [];
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
/**
|
|
16
|
+
* Registers a cleanup callback and returns it.
|
|
17
|
+
*
|
|
18
|
+
* @param callback - The cleanup callback to register
|
|
19
|
+
* @returns The registered callback
|
|
20
|
+
*/
|
|
21
|
+
register( callback ) {
|
|
22
|
+
if ( typeof callback === 'function' ) {
|
|
23
|
+
callbacks.push( callback );
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return callback;
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Executes all registered callbacks and clears the registry.
|
|
31
|
+
*/
|
|
32
|
+
destroy() {
|
|
33
|
+
while ( callbacks.length ) {
|
|
34
|
+
const callback = callbacks.pop();
|
|
35
|
+
if ( typeof callback === 'function' ) {
|
|
36
|
+
callback();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Attaches an event listener to an element and registers its cleanup.
|
|
43
|
+
*
|
|
44
|
+
* @param element - DOM element to attach the event to
|
|
45
|
+
* @param type - Event type (e.g., 'click', 'focus')
|
|
46
|
+
* @param handler - Event handler function
|
|
47
|
+
* @param [options] - Optional addEventListener options
|
|
48
|
+
* @returns The handler function for reference
|
|
49
|
+
*/
|
|
50
|
+
addEventListener( element, type, handler, options ) {
|
|
51
|
+
if ( !element || !type || typeof handler !== 'function' ) {
|
|
52
|
+
console.warn( 'Invalid parameters provided to addEventListener' );
|
|
53
|
+
return handler;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
element.addEventListener( type, handler, options );
|
|
57
|
+
|
|
58
|
+
this.register( () => {
|
|
59
|
+
element.removeEventListener( type, handler, options );
|
|
60
|
+
} );
|
|
61
|
+
|
|
62
|
+
return handler;
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Attaches multiple event listeners to an element and registers their cleanup.
|
|
67
|
+
*
|
|
68
|
+
* @param element - DOM element to attach the events to
|
|
69
|
+
* @param events - Map of event types to handler functions
|
|
70
|
+
* @param [options] - Optional addEventListener options
|
|
71
|
+
* @returns The provided element for chaining
|
|
72
|
+
*/
|
|
73
|
+
addEventListeners( element, events, options ) {
|
|
74
|
+
if ( !element || !events ) {
|
|
75
|
+
console.warn( 'Invalid parameters provided to addEventListeners' );
|
|
76
|
+
return element;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for ( const [ type, handler ] of Object.entries( events ) ) {
|
|
80
|
+
if ( typeof handler === 'function' ) {
|
|
81
|
+
this.addEventListener( element, type, handler, options );
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return element;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2017-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a hover manager that tracks hover state across multiple elements.
|
|
8
|
+
*
|
|
9
|
+
* @param options - The options for the hover manager.
|
|
10
|
+
* @param options.elements - The elements to track hover state for.
|
|
11
|
+
* @param options.onEnter - Callback function to call when an element is hovered.
|
|
12
|
+
* @param options.onLeave - Callback function to call when no elements are hovered.
|
|
13
|
+
* @param [options.debounceDelay=0] - Delay in milliseconds before triggering onEnter callback.
|
|
14
|
+
* @returns An object with destroy method to clean up event listeners
|
|
15
|
+
*/
|
|
16
|
+
export function createHoverManager( { elements, onEnter, onLeave, debounceDelay = 0 } ) {
|
|
17
|
+
const hoveredElements = new Set();
|
|
18
|
+
let leaveTimeoutId = null;
|
|
19
|
+
let enterTimeoutId = null;
|
|
20
|
+
const listenerPairs = [];
|
|
21
|
+
|
|
22
|
+
function handleMouseEnter( element ) {
|
|
23
|
+
clearTimeout( leaveTimeoutId );
|
|
24
|
+
leaveTimeoutId = null;
|
|
25
|
+
|
|
26
|
+
const isNewlyHovered = !hoveredElements.has( element );
|
|
27
|
+
hoveredElements.add( element );
|
|
28
|
+
|
|
29
|
+
if ( isNewlyHovered && onEnter ) {
|
|
30
|
+
clearTimeout( enterTimeoutId );
|
|
31
|
+
|
|
32
|
+
if ( debounceDelay > 0 ) {
|
|
33
|
+
// Use debounced enter if delay is specified
|
|
34
|
+
enterTimeoutId = setTimeout( () => {
|
|
35
|
+
onEnter?.( element );
|
|
36
|
+
}, debounceDelay );
|
|
37
|
+
} else {
|
|
38
|
+
// Call immediately if no debounce
|
|
39
|
+
onEnter?.( element );
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function handleMouseLeave( element ) {
|
|
45
|
+
hoveredElements.delete( element );
|
|
46
|
+
|
|
47
|
+
// Clear any existing timeouts
|
|
48
|
+
clearTimeout( leaveTimeoutId );
|
|
49
|
+
clearTimeout( enterTimeoutId );
|
|
50
|
+
|
|
51
|
+
leaveTimeoutId = null;
|
|
52
|
+
enterTimeoutId = null;
|
|
53
|
+
|
|
54
|
+
if ( hoveredElements.size === 0 ) {
|
|
55
|
+
leaveTimeoutId = setTimeout( () => {
|
|
56
|
+
// Double check size, in case an element was entered again quickly
|
|
57
|
+
if ( hoveredElements.size === 0 && onLeave ) {
|
|
58
|
+
onLeave?.();
|
|
59
|
+
}
|
|
60
|
+
}, 50 );
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Attach event listeners
|
|
65
|
+
elements.forEach( element => {
|
|
66
|
+
const enterHandler = () => handleMouseEnter( element );
|
|
67
|
+
const leaveHandler = () => handleMouseLeave( element );
|
|
68
|
+
|
|
69
|
+
element.addEventListener( 'mouseenter', enterHandler );
|
|
70
|
+
element.addEventListener( 'mouseleave', leaveHandler );
|
|
71
|
+
element.addEventListener( 'focus', enterHandler );
|
|
72
|
+
element.addEventListener( 'blur', leaveHandler );
|
|
73
|
+
|
|
74
|
+
listenerPairs.push(
|
|
75
|
+
{ element, type: 'mouseenter', handler: enterHandler },
|
|
76
|
+
{ element, type: 'mouseleave', handler: leaveHandler },
|
|
77
|
+
{ element, type: 'focus', handler: enterHandler },
|
|
78
|
+
{ element, type: 'blur', handler: leaveHandler }
|
|
79
|
+
);
|
|
80
|
+
} );
|
|
81
|
+
|
|
82
|
+
// Return an object with a destroy method
|
|
83
|
+
return {
|
|
84
|
+
destroy() {
|
|
85
|
+
clearTimeout( leaveTimeoutId );
|
|
86
|
+
clearTimeout( enterTimeoutId );
|
|
87
|
+
listenerPairs.forEach( pair => {
|
|
88
|
+
pair.element.removeEventListener( pair.type, pair.handler );
|
|
89
|
+
} );
|
|
90
|
+
hoveredElements.clear();
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2017-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a watcher that detects when all elements lose focus via keyboard navigation.
|
|
8
|
+
* It differentiates between blur caused by mouse clicks and keyboard navigation.
|
|
9
|
+
* Additionally monitors keyboard events to detect navigation away from elements.
|
|
10
|
+
* Only triggers when focus moves outside ALL of the monitored elements.
|
|
11
|
+
*
|
|
12
|
+
* @param config - Configuration object.
|
|
13
|
+
* @param config.elements - Element or array of elements to monitor for keyboard-based blur.
|
|
14
|
+
* @param config.callback - Function to call when keyboard blur occurs outside of all elements.
|
|
15
|
+
* @param [config.checkDelay=50] - Delay in ms to check focus after keyboard event.
|
|
16
|
+
* @returns Cleanup function to remove the listeners.
|
|
17
|
+
*/
|
|
18
|
+
export function createKeyboardBlurWatcher( { elements, callback, checkDelay = 50 } ) {
|
|
19
|
+
let isMouseDown = false;
|
|
20
|
+
|
|
21
|
+
// Convert single element to array for consistent handling
|
|
22
|
+
if ( !Array.isArray( elements ) ) {
|
|
23
|
+
elements = [ elements ];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Track if mouse is being used
|
|
27
|
+
const handleMouseDown = () => {
|
|
28
|
+
isMouseDown = true;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const handleMouseUp = () => {
|
|
32
|
+
isMouseDown = false;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Check if current focus is inside any of our elements
|
|
36
|
+
const isFocusWithinElements = () => {
|
|
37
|
+
return elements.some( element =>
|
|
38
|
+
element === document.activeElement || element.contains( document.activeElement )
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// Function to check focus state and call callback if needed
|
|
43
|
+
const checkFocusState = event => {
|
|
44
|
+
if ( !isFocusWithinElements() ) {
|
|
45
|
+
callback( event );
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// When any element loses focus
|
|
50
|
+
const handleBlur = event => {
|
|
51
|
+
if ( isMouseDown ) {
|
|
52
|
+
return; // Ignore blur from mouse interactions
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Use setTimeout to allow the next element to receive focus first
|
|
56
|
+
setTimeout( () => checkFocusState( event ), 0 );
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Handle keyboard navigation that might move focus away
|
|
60
|
+
const handleKeyDown = event => {
|
|
61
|
+
// Primary focus navigation keys
|
|
62
|
+
const navigationKeys = [ 'Tab', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Escape' ];
|
|
63
|
+
|
|
64
|
+
if ( navigationKeys.includes( event.key ) ) {
|
|
65
|
+
// Wait a short time after key press to check where focus landed
|
|
66
|
+
setTimeout( () => checkFocusState( event ), checkDelay );
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// Add event listeners
|
|
71
|
+
document.addEventListener( 'mousedown', handleMouseDown );
|
|
72
|
+
document.addEventListener( 'mouseup', handleMouseUp );
|
|
73
|
+
|
|
74
|
+
// Attach blur and keydown listeners to each element
|
|
75
|
+
elements.forEach( element => {
|
|
76
|
+
element.addEventListener( 'blur', handleBlur );
|
|
77
|
+
element.addEventListener( 'keydown', handleKeyDown );
|
|
78
|
+
} );
|
|
79
|
+
|
|
80
|
+
// Return cleanup function
|
|
81
|
+
return () => {
|
|
82
|
+
document.removeEventListener( 'mousedown', handleMouseDown );
|
|
83
|
+
document.removeEventListener( 'mouseup', handleMouseUp );
|
|
84
|
+
|
|
85
|
+
elements.forEach( element => {
|
|
86
|
+
element.removeEventListener( 'blur', handleBlur );
|
|
87
|
+
element.removeEventListener( 'keydown', handleKeyDown );
|
|
88
|
+
} );
|
|
89
|
+
};
|
|
90
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2017-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { clamp } from './clamp';
|
|
7
|
+
import { isFocusable } from './is-focusable';
|
|
8
|
+
import { wrapAround } from './wrap-around';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Creates a keyboard-based focus cycler for a list of elements.
|
|
12
|
+
*
|
|
13
|
+
* @param config - Configuration object
|
|
14
|
+
* @param config.items - Elements to cycle through
|
|
15
|
+
* @param config.keyMap - Key mappings for navigation
|
|
16
|
+
* @param [config.onFocusEnter] - Callback when focus enters an element (item, index) => {}
|
|
17
|
+
* @param [config.onFocusLeave] - Callback when focus leaves an element (item, index) => {}
|
|
18
|
+
* @param [config.focusElements=true] - Whether to automatically focus DOM elements
|
|
19
|
+
* @param [config.blurCheckDelay=15] - Delay in ms to check focus after blur events
|
|
20
|
+
* @returns Control object with activate, deactivate methods and unmount function
|
|
21
|
+
*/
|
|
22
|
+
export function createKeyboardFocusCycler( config ) {
|
|
23
|
+
return new KeyboardFocusCycler( config );
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Class that handles keyboard-based focus cycling for a list of elements.
|
|
28
|
+
*/
|
|
29
|
+
class KeyboardFocusCycler {
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new instance of KeyboardFocusCycler.
|
|
32
|
+
*/
|
|
33
|
+
constructor( {
|
|
34
|
+
items,
|
|
35
|
+
keyMap = getVerticalKeysMap(),
|
|
36
|
+
onFocusEnter = () => {},
|
|
37
|
+
onFocusLeave = () => {},
|
|
38
|
+
focusElements = true,
|
|
39
|
+
blurCheckDelay = 15
|
|
40
|
+
} ) {
|
|
41
|
+
this.items = items;
|
|
42
|
+
this.keyMap = keyMap;
|
|
43
|
+
this.onFocusEnter = onFocusEnter;
|
|
44
|
+
this.onFocusLeave = onFocusLeave;
|
|
45
|
+
this.focusElements = focusElements;
|
|
46
|
+
this.blurCheckDelay = blurCheckDelay;
|
|
47
|
+
|
|
48
|
+
this.currentIndex = -1;
|
|
49
|
+
this.isActive = false;
|
|
50
|
+
this.blurTimeout = null;
|
|
51
|
+
|
|
52
|
+
// Bind methods to preserve 'this' context
|
|
53
|
+
this._handleKeyDown = this._handleKeyDown.bind( this );
|
|
54
|
+
this._handleItemFocus = this._handleItemFocus.bind( this );
|
|
55
|
+
this._handleItemBlur = this._handleItemBlur.bind( this );
|
|
56
|
+
|
|
57
|
+
// Attach event listeners
|
|
58
|
+
window.addEventListener( 'keydown', this._handleKeyDown );
|
|
59
|
+
this.items.forEach( item => {
|
|
60
|
+
if ( isFocusable( item ) ) {
|
|
61
|
+
item.addEventListener( 'focus', this._handleItemFocus );
|
|
62
|
+
item.addEventListener( 'blur', this._handleItemBlur );
|
|
63
|
+
}
|
|
64
|
+
} );
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Activate focus cycling starting at specified index
|
|
69
|
+
*
|
|
70
|
+
* @param [startIndex=0] - Index to start focus at
|
|
71
|
+
*/
|
|
72
|
+
activate( startIndex = 0 ) {
|
|
73
|
+
const clampedIndex = clamp( 0, this.items.length - 1, startIndex );
|
|
74
|
+
|
|
75
|
+
this.isActive = true;
|
|
76
|
+
this._changeFocus( clampedIndex );
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Activate focus cycling starting at the first item
|
|
81
|
+
*/
|
|
82
|
+
activateFirst() {
|
|
83
|
+
this.activate( 0 );
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Activate focus cycling starting at the last item
|
|
88
|
+
*/
|
|
89
|
+
activateLast() {
|
|
90
|
+
this.activate( this.items.length - 1 );
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Deactivate focus cycling
|
|
95
|
+
*/
|
|
96
|
+
deactivate() {
|
|
97
|
+
if ( this.currentIndex !== -1 ) {
|
|
98
|
+
this.onFocusLeave( this.items[ this.currentIndex ], this.currentIndex );
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this.isActive = false;
|
|
102
|
+
this.currentIndex = -1;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Remove all event listeners and clean up
|
|
107
|
+
*/
|
|
108
|
+
unmount() {
|
|
109
|
+
window.removeEventListener( 'keydown', this._handleKeyDown );
|
|
110
|
+
|
|
111
|
+
// Remove focus and blur listeners
|
|
112
|
+
this.items.forEach( item => {
|
|
113
|
+
if ( isFocusable( item ) ) {
|
|
114
|
+
item.removeEventListener( 'focus', this._handleItemFocus );
|
|
115
|
+
item.removeEventListener( 'blur', this._handleItemBlur );
|
|
116
|
+
}
|
|
117
|
+
} );
|
|
118
|
+
|
|
119
|
+
clearTimeout( this.blurTimeout );
|
|
120
|
+
this.deactivate();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Change focus from one element to another
|
|
125
|
+
* @param newIndex - Index of the element to focus
|
|
126
|
+
* @private
|
|
127
|
+
*/
|
|
128
|
+
_changeFocus( newIndex ) {
|
|
129
|
+
const previousIndex = this.currentIndex;
|
|
130
|
+
|
|
131
|
+
// Call callbacks when focus changes
|
|
132
|
+
if ( previousIndex !== -1 ) {
|
|
133
|
+
this.onFocusLeave( this.items[ previousIndex ], previousIndex );
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
this.currentIndex = newIndex;
|
|
137
|
+
this.onFocusEnter( this.items[ this.currentIndex ], this.currentIndex );
|
|
138
|
+
|
|
139
|
+
// Focus the element if it's focusable and option is enabled
|
|
140
|
+
if ( this.focusElements && isFocusable( this.items[ this.currentIndex ] ) ) {
|
|
141
|
+
this.items[ this.currentIndex ].focus();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Check if any item has focus
|
|
147
|
+
* @returns True if any item has focus
|
|
148
|
+
* @private
|
|
149
|
+
*/
|
|
150
|
+
_hasAnyItemFocus() {
|
|
151
|
+
return this.items.some( item => document.activeElement === item );
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Handle keyboard navigation
|
|
156
|
+
* @param event - Keyboard event
|
|
157
|
+
* @private
|
|
158
|
+
*/
|
|
159
|
+
_handleKeyDown( event ) {
|
|
160
|
+
if ( !this.isActive ) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Destructure key mappings.
|
|
165
|
+
const { next, previous, first, last } = this.keyMap;
|
|
166
|
+
const pressedKey = event.key;
|
|
167
|
+
|
|
168
|
+
// Check if the pressed key is in our mapping.
|
|
169
|
+
if (
|
|
170
|
+
!next?.includes( pressedKey ) &&
|
|
171
|
+
!previous?.includes( pressedKey ) &&
|
|
172
|
+
!first?.includes( pressedKey ) &&
|
|
173
|
+
!last?.includes( pressedKey )
|
|
174
|
+
) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
event.preventDefault();
|
|
179
|
+
|
|
180
|
+
let newIndex = this.currentIndex;
|
|
181
|
+
|
|
182
|
+
// Determine the new index based on key pressed.
|
|
183
|
+
if ( next?.includes( pressedKey ) ) {
|
|
184
|
+
newIndex = wrapAround( 0, this.items.length - 1, this.currentIndex + 1 );
|
|
185
|
+
} else if ( previous?.includes( pressedKey ) ) {
|
|
186
|
+
newIndex = wrapAround( 0, this.items.length - 1, this.currentIndex - 1 );
|
|
187
|
+
} else if ( first?.includes( pressedKey ) ) {
|
|
188
|
+
newIndex = 0;
|
|
189
|
+
} else if ( last?.includes( pressedKey ) ) {
|
|
190
|
+
newIndex = this.items.length - 1;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
this._changeFocus( newIndex );
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Handle item focus
|
|
198
|
+
* @param event - Focus event
|
|
199
|
+
* @private
|
|
200
|
+
*/
|
|
201
|
+
_handleItemFocus( event ) {
|
|
202
|
+
clearTimeout( this.blurTimeout );
|
|
203
|
+
|
|
204
|
+
this.isActive = true;
|
|
205
|
+
|
|
206
|
+
// Find the index of the focused item
|
|
207
|
+
const index = this.items.indexOf( event.target );
|
|
208
|
+
if ( index !== -1 && index !== this.currentIndex ) {
|
|
209
|
+
this._changeFocus( index );
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Handle item blur
|
|
215
|
+
* @private
|
|
216
|
+
*/
|
|
217
|
+
_handleItemBlur() {
|
|
218
|
+
// Clear any existing timeout
|
|
219
|
+
clearTimeout( this.blurTimeout );
|
|
220
|
+
|
|
221
|
+
// Set a new timeout to check focus after a small delay
|
|
222
|
+
this.blurTimeout = setTimeout( () => {
|
|
223
|
+
if ( !this._hasAnyItemFocus() ) {
|
|
224
|
+
this.isActive = false;
|
|
225
|
+
|
|
226
|
+
if ( this.currentIndex !== -1 ) {
|
|
227
|
+
this.onFocusLeave( this.items[ this.currentIndex ], this.currentIndex );
|
|
228
|
+
this.currentIndex = -1;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}, this.blurCheckDelay );
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export function getVerticalKeysMap() {
|
|
236
|
+
return {
|
|
237
|
+
next: [ 'ArrowDown', 'Down' ],
|
|
238
|
+
previous: [ 'ArrowUp', 'Up' ],
|
|
239
|
+
first: [ 'Home' ],
|
|
240
|
+
last: [ 'End' ]
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export function getHorizontalKeysMap() {
|
|
245
|
+
return {
|
|
246
|
+
next: [ 'ArrowRight', 'Right' ],
|
|
247
|
+
previous: [ 'ArrowLeft', 'Left' ],
|
|
248
|
+
first: [ 'Home' ],
|
|
249
|
+
last: [ 'End' ]
|
|
250
|
+
};
|
|
251
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2017-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a mutation observer to detect content changes in the specified element.
|
|
8
|
+
*
|
|
9
|
+
* @param config - Configuration object
|
|
10
|
+
* @param config.element - The element to observe for changes
|
|
11
|
+
* @param config.callback - The function to call when mutations occur
|
|
12
|
+
* @param [config.attributeFilter] - Specific attributes to watch (optional)
|
|
13
|
+
* @param [config.options] - MutationObserver options (defaults to observing all changes)
|
|
14
|
+
* @returns A function that disconnects the observer when called
|
|
15
|
+
*/
|
|
16
|
+
export function createMutationObserver( { element, callback, attributeFilter, options = {} } ) {
|
|
17
|
+
// Create default options if none provided
|
|
18
|
+
const observerOptions = {
|
|
19
|
+
childList: options.childList ?? true,
|
|
20
|
+
characterData: options.characterData ?? true,
|
|
21
|
+
subtree: options.subtree ?? true,
|
|
22
|
+
attributes: options.attributes ?? true,
|
|
23
|
+
attributeFilter
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// Create a new mutation observer
|
|
27
|
+
const mutationObserver = new MutationObserver( mutations => {
|
|
28
|
+
// Check if any mutations affected the content
|
|
29
|
+
const contentChanged = mutations.some( mutation =>
|
|
30
|
+
mutation.type === 'characterData' ||
|
|
31
|
+
mutation.type === 'childList' ||
|
|
32
|
+
( mutation.type === 'attributes' &&
|
|
33
|
+
( !attributeFilter || attributeFilter.includes( mutation.attributeName ) ) )
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
// If content changed, call the callback with mutation information
|
|
37
|
+
if ( contentChanged ) {
|
|
38
|
+
callback( mutations );
|
|
39
|
+
}
|
|
40
|
+
} );
|
|
41
|
+
|
|
42
|
+
// Start observing the element
|
|
43
|
+
mutationObserver.observe( element, observerOptions );
|
|
44
|
+
|
|
45
|
+
// Return a function to disconnect the observer
|
|
46
|
+
return () => {
|
|
47
|
+
mutationObserver.disconnect();
|
|
48
|
+
};
|
|
49
|
+
}
|