diff --git a/.github/actions/mergeReleaseChangelog.mjs b/.github/actions/mergeReleaseChangelog.mjs new file mode 100644 index 000000000000..017ef61d04e2 --- /dev/null +++ b/.github/actions/mergeReleaseChangelog.mjs @@ -0,0 +1,113 @@ +import { promises as fs } from 'node:fs'; + +const extractChangelogSections = (releaseBody) => { + const fixes = []; + const features = []; + const fixesMatch = releaseBody.match(/## Bug Fixes([\s\S]*?)(?=##|$)/); + const featuresMatch = releaseBody.match(/## Features([\s\S]*?)(?=##|$)/); + + if (fixesMatch) { + // Split lines, trim whitespace, and remove any leading bullet point (like "*" or "-") + const fixEntries = fixesMatch[1].trim().split('\n').map(line => line.replace(/^[*-]\s*/, '').trim()); + fixes.push(...fixEntries); + } + if (featuresMatch) { + const featureEntries = featuresMatch[1].trim().split('\n').map(line => line.replace(/^[*-]\s*/, '').trim()); + features.push(...featureEntries); + } + + return { fixes, features }; +}; + +const mergeReleaseChangelogs = (minorRelease, rcReleases) => { + // Extract the existing changes from the minor release body + const { fixes: minorFixes, features: minorFeatures } = extractChangelogSections(minorRelease.body); + const fixes = [...minorFixes]; + const features = [...minorFeatures]; + + // Add changes from each RC release + rcReleases.forEach((release) => { + const { fixes: rcFixes, features: rcFeatures } = extractChangelogSections(release.body); + fixes.push(...rcFixes); + features.push(...rcFeatures); + }) + + // Sort fixes and features alphabetically + const sortedFixes = fixes.sort((a, b) => { + const contentA = a.match(/\*\*(.*?)\*\*/)?.[1] || ''; + const contentB = b.match(/\*\*(.*?)\*\*/)?.[1] || ''; + return contentA.localeCompare(contentB); + }); + + const sortedFeatures = features.sort((a, b) => { + const contentA = a.match(/\*\*(.*?)\*\*/)?.[1] || ''; + const contentB = b.match(/\*\*(.*?)\*\*/)?.[1] || ''; + return contentA.localeCompare(contentB); + }); + + return { fixes: sortedFixes, features: sortedFeatures }; +} + +const updateRelease = async (releaseContext) => { + const releaseId = releaseContext.minorRelease.id; + const releaseHeaderMatch = releaseContext.minorRelease.body.match(/^#\s\[.*?\]\(.*?\)\s\([\d-]+\)/); + const releaseHeader = releaseHeaderMatch ? `${releaseHeaderMatch[0]}\n\n` : ''; + const formattedFixes = releaseContext.fixes.length ? `### Fixes\n- ${releaseContext.fixes.join('\n- ')}` : ''; + const formattedFeatures = releaseContext.features.length ? `### Features\n- ${releaseContext.features.join('\n- ')}` : ''; + const body = `${releaseHeader}${formattedFixes}\n\n${formattedFeatures}`.trim(); + + try { + await releaseContext.github.request('PATCH /repos/{owner}/{repo}/releases/{releaseId}', { + owner: releaseContext.owner, + repo: releaseContext.repo, + body, + releaseId, + }); + + console.log(`Release ${releaseContext.version} updated successfully:`, releaseContext); + } catch (error) { + console.error(`Error updating release ${releaseContext.version}:`, error ); + } +}; + +/** + * Publishes comments to issues that are fixed and released. + * @param options {object} + * @param options.github {import("@octokit/rest/dist-types/index.d.ts").Octokit} + * @param options.context + */ +export default async function run({ github, context }) { + const lerna = await fs.readFile(new URL('../../lerna.json', import.meta.url), 'utf8'); + const { version } = JSON.parse(lerna); + + if (!version.startsWith("2")) { + console.warn('Skip: the task is relevant for version 2'); + return; + } + + try { + const { owner, repo } = context.repo; + const allReleases = (await github.request('GET /repos/{owner}/{repo}/releases', { owner, repo })).data; + const rcReleases = allReleases.filter((release) => release.tag_name.includes(`v${version}-rc`)); + const minorRelease = allReleases.find((release) => release.tag_name === `v${version}`); + + // Merge RC changelogs + const { fixes, features } = await mergeReleaseChangelogs(minorRelease, rcReleases); + + const minorReleaseContext = { + github, + version, + owner, + repo, + minorRelease, + fixes, + features + } + + // Update the minor release with aggregated changelog + await updateRelease(minorReleaseContext); + + } catch (error) { + console.error('Error:', error); + } +} diff --git a/.github/workflows/merge-release-changelog.yaml b/.github/workflows/merge-release-changelog.yaml new file mode 100644 index 000000000000..4593cff18673 --- /dev/null +++ b/.github/workflows/merge-release-changelog.yaml @@ -0,0 +1,34 @@ +name: Merge Release Changelog + +on: workflow_dispatch + +jobs: + merge-release-changelog: + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + issues: write + steps: + - uses: actions/checkout@v4 + with: + token: ${{ secrets.UI5_WEBCOMP_BOT_GH_TOKEN }} + fetch-depth: 0 + - uses: actions/setup-node@v4.1.0 + with: + node-version: 20 + cache: 'yarn' + + - name: Install + run: yarn --frozen-lockfile + + - name: Merge Release Changelog + uses: actions/github-script@v7 + env: + GH_TOKEN: ${{ secrets.UI5_WEBCOMP_BOT_GH_TOKEN }} + with: + github-token: ${{ secrets.UI5_WEBCOMP_BOT_GH_TOKEN }} + script: | + const mergeReleaseChangelog = (await import('${{ github.workspace }}/.github/actions/mergeReleaseChangelog.mjs')).default; + + await mergeReleaseChangelog({ github , context }); \ No newline at end of file diff --git a/.github/workflows/release-stable.yaml b/.github/workflows/release-stable.yaml index deda1c46e230..7f75fe0cb3b6 100644 --- a/.github/workflows/release-stable.yaml +++ b/.github/workflows/release-stable.yaml @@ -68,4 +68,15 @@ jobs: script: | const commentOnFixedIssues = (await import('${{ github.workspace }}/.github/actions/commentOnFixedIssues.mjs')).default; - await commentOnFixedIssues({ github, context }); \ No newline at end of file + await commentOnFixedIssues({ github, context }); + + - name: Merge Release Changelog + uses: actions/github-script@v7 + env: + GH_TOKEN: ${{ secrets.UI5_WEBCOMP_BOT_GH_TOKEN }} + with: + github-token: ${{ secrets.UI5_WEBCOMP_BOT_GH_TOKEN }} + script: | + const mergeReleaseChangelog = (await import('${{ github.workspace }}/.github/actions/mergeReleaseChangelog.mjs')).default; + + await mergeReleaseChangelog({ github , context }); diff --git a/CHANGELOG.md b/CHANGELOG.md index aaf093bc110e..8776c80c6cb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,98 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.5.0-rc.2](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.1...v2.5.0-rc.2) (2024-11-28) + + +### Bug Fixes + +* **ui5-input:** set value after preventDefault of input event ([#10196](https://github.com/SAP/ui5-webcomponents/issues/10196)) ([e2a6c94](https://github.com/SAP/ui5-webcomponents/commit/e2a6c94d6b4d88db61d85313f2776a092152478d)), closes [#9988](https://github.com/SAP/ui5-webcomponents/issues/9988) +* **ui5-radio-button:** fix aria-disabled and focus of the read-only radio buttons ([#10111](https://github.com/SAP/ui5-webcomponents/issues/10111)) ([3bcfd1d](https://github.com/SAP/ui5-webcomponents/commit/3bcfd1d26b8520b73be336558f590e1b89c4d0c3)), closes [#10025](https://github.com/SAP/ui5-webcomponents/issues/10025) +* **ui5-tokenizer:** adjust touch area for cozy and compact ([#10215](https://github.com/SAP/ui5-webcomponents/issues/10215)) ([ee90aea](https://github.com/SAP/ui5-webcomponents/commit/ee90aeaae00a3a888a8dafae73cb7dba1bf8e51f)) +* **ui5-wizard:** stacked Wizard Steps are aligned properly ([#10250](https://github.com/SAP/ui5-webcomponents/issues/10250)) ([3473fbf](https://github.com/SAP/ui5-webcomponents/commit/3473fbf7dd6f97d0de70a540d412c36901455926)), closes [#9779](https://github.com/SAP/ui5-webcomponents/issues/9779) + + +### Features + +* **ui5-combobox:** adjust arrow-down behavior ([#10166](https://github.com/SAP/ui5-webcomponents/issues/10166)) ([74616dc](https://github.com/SAP/ui5-webcomponents/commit/74616dc7ea533ecbd18265878c90339e10eb9d1b)) +* **ui5-form:** add new `emptySpan` property ([#10194](https://github.com/SAP/ui5-webcomponents/issues/10194)) ([48b0cc8](https://github.com/SAP/ui5-webcomponents/commit/48b0cc89b36dd859dd07c17021eedf7a99375150)), closes [#9963](https://github.com/SAP/ui5-webcomponents/issues/9963) +* **ui5-list:** add Home and End key handling for Load More button ([#10206](https://github.com/SAP/ui5-webcomponents/issues/10206)) ([7059e09](https://github.com/SAP/ui5-webcomponents/commit/7059e0987960f62cd5b8740594b907fa98e1f11c)) + + + + + +# [2.5.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.0...v2.5.0-rc.1) (2024-11-21) + + +### Bug Fixes + +* **ui5-dialog:** width on mobile is not bigger than the phone width ([#10199](https://github.com/SAP/ui5-webcomponents/issues/10199)) ([77af592](https://github.com/SAP/ui5-webcomponents/commit/77af592c238ad53502c09f142d33f7c66c6b0715)), closes [#10000](https://github.com/SAP/ui5-webcomponents/issues/10000) +* **ui5-table:** text cut due to column overflow ([#10193](https://github.com/SAP/ui5-webcomponents/issues/10193)) ([b59d718](https://github.com/SAP/ui5-webcomponents/commit/b59d718dca80bd9a8ee65993ddc2358ecd127024)), closes [#10168](https://github.com/SAP/ui5-webcomponents/issues/10168) + + +### Features + +* **ui5-form:** enable vertical alignment of form items ([#10165](https://github.com/SAP/ui5-webcomponents/issues/10165)) ([13b571b](https://github.com/SAP/ui5-webcomponents/commit/13b571baf0b225dfabc4739be64dd64a34cc5506)) +* **ui5-toolbar:** fixed spacer behavior ([#10177](https://github.com/SAP/ui5-webcomponents/issues/10177)) ([b3625ac](https://github.com/SAP/ui5-webcomponents/commit/b3625ac7426aa592b80f50e15147c18ccc7d2abd)), closes [#10104](https://github.com/SAP/ui5-webcomponents/issues/10104) + + + + + +# [2.5.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.1-rc.0...v2.5.0-rc.0) (2024-11-14) + + +### Bug Fixes + +* **ui5-card-header:** update interactive property documentation ([#10143](https://github.com/SAP/ui5-webcomponents/issues/10143)) ([23289d4](https://github.com/SAP/ui5-webcomponents/commit/23289d4d1696d0441823d98f71b5e21b617777c3)) +* **ui5-dynamic-page:** move subheading slot outside the title wrapper ([#10163](https://github.com/SAP/ui5-webcomponents/issues/10163)) ([6466b8a](https://github.com/SAP/ui5-webcomponents/commit/6466b8ad7f73c85a5c105dea3c196f6bfb78f27a)) +* **ui5-table-growing:** button is shown despite scroll type ([#10142](https://github.com/SAP/ui5-webcomponents/issues/10142)) ([950441b](https://github.com/SAP/ui5-webcomponents/commit/950441b7d272e8cd20499461f4cfa05ad3ac7510)), closes [#10045](https://github.com/SAP/ui5-webcomponents/issues/10045) + + +### Features + +* **ui5-color-picker:** add simplified display mode ([#10153](https://github.com/SAP/ui5-webcomponents/issues/10153)) ([bf9c0d6](https://github.com/SAP/ui5-webcomponents/commit/bf9c0d653be5af5473a7b616f2c91803db46beb3)), closes [#9979](https://github.com/SAP/ui5-webcomponents/issues/9979) +* **ui5-combobox/multi-combobox:** physical items ([#10051](https://github.com/SAP/ui5-webcomponents/issues/10051)) ([73f82ab](https://github.com/SAP/ui5-webcomponents/commit/73f82abe5e9a61d88919f4c45df9435be850eb2f)) +* **ui5-form:** update to latest accessibility spec ([#10152](https://github.com/SAP/ui5-webcomponents/issues/10152)) ([4382d4e](https://github.com/SAP/ui5-webcomponents/commit/4382d4e280ffcf01a924163b9b719887c17f529a)), closes [#9952](https://github.com/SAP/ui5-webcomponents/issues/9952) +* **ui5-list, ui5-tree:** support accessible description ([#10131](https://github.com/SAP/ui5-webcomponents/issues/10131)) ([45f0ffe](https://github.com/SAP/ui5-webcomponents/commit/45f0ffeafb2da0ffcaf425649c7440b604e359a3)), closes [#6445](https://github.com/SAP/ui5-webcomponents/issues/6445) +* **ui5-tokenizer:** enable multiline mode ([#9964](https://github.com/SAP/ui5-webcomponents/issues/9964)) ([1071746](https://github.com/SAP/ui5-webcomponents/commit/107174616b5b3b96c174160488eba18b9cdb9cae)) + + + + + +## [2.4.1-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0...v2.4.1-rc.0) (2024-11-07) + + +### Bug Fixes + +* **ui5-menu:** make close event non-bubbling ([#10133](https://github.com/SAP/ui5-webcomponents/issues/10133)) ([e7ccce9](https://github.com/SAP/ui5-webcomponents/commit/e7ccce968cab25a07837c41f36d94603c31e007e)), closes [#10041](https://github.com/SAP/ui5-webcomponents/issues/10041) +* **ui5-select:** add support for Vue.js v-model ([#10149](https://github.com/SAP/ui5-webcomponents/issues/10149)) ([14947a7](https://github.com/SAP/ui5-webcomponents/commit/14947a7bbcf3272f56888bb466696784095b574f)), closes [#9971](https://github.com/SAP/ui5-webcomponents/issues/9971) + + + + + +# [2.4.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.4...v2.4.0) (2024-11-03) + + +### Bug Fixes + +* **ui5-dynamic-page:** improve scrolling smoothness ([#10093](https://github.com/SAP/ui5-webcomponents/issues/10093)) ([d1420b0](https://github.com/SAP/ui5-webcomponents/commit/d1420b0be2c40ca649503cca0715e4c529929f8f)), closes [#10011](https://github.com/SAP/ui5-webcomponents/issues/10011) +* **ui5-dynamic-page:** prevent unwanted header toggle from scroll ([#10007](https://github.com/SAP/ui5-webcomponents/issues/10007)) ([7a7d00c](https://github.com/SAP/ui5-webcomponents/commit/7a7d00c0d615283d1a86d775b6c51db7feadfb42)) +* **ui5-media-gallery:** clear selected thumbnail on item removal ([#10087](https://github.com/SAP/ui5-webcomponents/issues/10087)) ([af4cadb](https://github.com/SAP/ui5-webcomponents/commit/af4cadbfb637c1a6440aa0bd1fc516629ae332ae)) +* **ui5-toolbar-*:** ensure getDomRef() returns the actual DOM reference ([#10009](https://github.com/SAP/ui5-webcomponents/issues/10009)) ([747244d](https://github.com/SAP/ui5-webcomponents/commit/747244d93fee5ee0d1ac54863de5e3573f4d6248)) + + +### Features + +* **ui5-date-picker:** introduce open and close events ([#10118](https://github.com/SAP/ui5-webcomponents/issues/10118)) ([819730a](https://github.com/SAP/ui5-webcomponents/commit/819730afbec336ad04e1207b8fee24bcd69f7c2d)) + + + + + # [2.4.0-rc.4](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.3...v2.4.0-rc.4) (2024-10-31) diff --git a/docs/08-Releases.md b/docs/08-Releases.md index 37016593ac3c..94310d789f5d 100644 --- a/docs/08-Releases.md +++ b/docs/08-Releases.md @@ -9,12 +9,12 @@ and produce the following type of releases: - **Patch releases** -Includes backward compatible bug fixes and increments the third digit, e.g. 1.0.1. +Includes backward compatible bug fixes and increments the third digit, e.g. 2.0.1. - **Minor releases** -Includes backward compatible new features and increments the middle digit and resets the last digit to zero, e.g. 1.1.0. +Includes backward compatible new features and increments the middle digit and resets the last digit to zero, e.g. 2.1.0, 2.2.0, 2.3.0, etc. - **Major releases** @@ -26,20 +26,30 @@ Includes changes that break backward compatibility and increments the first digi Here is the established release process of UI5 Web Components: -- **Monthly Stable Releases** - 1.11.0, 1.12.0....1.18.0 +### Version 2 -Every start of the month, a new minor version is released, which we consider stable and recommended for consumers. -Check the [Release Timelines](https://github.com/SAP/ui5-webcomponents/projects?type=classic) for up-to-date information (the related content is at the bottom of the page). +The UI5 Web Components version 2 is the latest major and recommended for usage. -- **Weekly Preview Releases** - 1.13.0-rc.0, 1.13.0-rc.1, 1.13.0-rc.2 (preview of 1.13) +- **Monthly Stable Releases** - 2.1.0, 2.2.0....2.x.0. + +Every start of the month, a new minor version is released - stable and recommended for consumers. +Check the [Release Timelines](https://github.com/orgs/SAP/projects/91?pane=info) for up-to-date information (the related content is at the bottom of the page). + +- **Weekly Preview Releases** - 2.x.0-rc.0, 2.x.0-rc.1....2.x.0-rc.z. Every week on Thursday, a new release candidate version is released, considered a preview of the upcoming minor version. It's more up-to-date with the latest development and it's useful for consumers that would like to get frequent updates and test upcoming features in the minor version. - -- **On-demand Patch Releases** - 1.13.1, 1.13.2, 1.13.3 +- **On-demand Patch Releases** - 2.x.1, 2.x.2....2.x.y. Patches are released on-demand for high-priority issues. +### Version 1 + +The UI5 Web Components version 1 is in maintenance until 30 June 2025. + +- **Monthly Patch Releases** - 1.24.1, 1.24.2....1.24.y. + +Every start of the month, a new patch of 1.24 version is released - stable and recommended for consumers that still rely on version 1. **Note:** The changelog of all releases can be found on the [GitHub Release](https://github.com/SAP/ui5-webcomponents/releases) page. diff --git a/docs/1-getting-started/01-first-steps.md b/docs/1-getting-started/01-first-steps.md index 1098a1d3e634..58b6bbb638c0 100644 --- a/docs/1-getting-started/01-first-steps.md +++ b/docs/1-getting-started/01-first-steps.md @@ -108,3 +108,38 @@ dist/assets/vendor.c05c7785.js 114.92kb / brotli: 24.30kb The content of the `dist` folder is ready to be deployed for productive usage. The hashes in the file names make them safe for caching and the produced bundle is optimized for production. #### 4. Enjoy UI5 Web Components. + +### Code Completion + +#### Visual Studio Code (VS Code) + +UI5 Web Components packages include a vscode.html-custom-data.json file that describes their custom elements. This enables advanced code completion features, such as “code hinting” or “IntelliSense,” in Visual Studio Code. + +Steps to Enable Code Completion in VS Code: + +1. Install UI5 Web Components locally + Use your package manager to add the required UI5 Web Components packages to your project. + +2. Create or update `.vscode/settings.json`: + - Ensure a folder named `.vscode` exists at the root of your project. + - Inside `.vscode`, create or update a file named `settings.json`. + +3. Configure the Settings File: + Add the following configuration to `settings.json`: + + ```json + { + "html.customData": [ + "./node_modules/@ui5/webcomponents/dist/vscode.html-custom-data.json" + // Add entries for other installed @ui5/webcomponents packages as needed + ] + } + ``` + + If `settings.json` already exists, append the `html.customData` property to the root object. + +4. Restart VS Code: + Restart the editor to apply the changes. + +#### JetBrains IDEs +For JetBrains IDEs, such as WebStorm or IntelliJ IDEA, no additional setup is required when using UI5 Web Components installed from your package manager. The IDE will automatically detect the `web-types.json` file provided by the packages, enabling code completion and displaying relevant component information without further configuration. diff --git a/docs/2-advanced/09-accessibility.md b/docs/2-advanced/09-accessibility.md index b77b078dc379..59923bb3c2bf 100644 --- a/docs/2-advanced/09-accessibility.md +++ b/docs/2-advanced/09-accessibility.md @@ -141,6 +141,8 @@ The mapping of the accessibility APIs to ARIA attributes is described in the fol | ------------------------------ | ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `accessibleName` | `aria-label` | Defines the text alternative of the component. If not provided, a default text alternative is set, if present. | | `accessibleNameRef` | `aria-label` | Alternative for `aria-labelledby`. Receives ID (or many IDs) of the elements that serve as labels of the component. Those labels are passed as a concatenated string to the `aria-label` attribute. | +| `accessibleDescription` | `aria-description` | Defines the description of the component. | +| `accessibleDescriptionRef` | `aria-description` | Alternative for `aria-describedby`. Receives ID (or many IDs) of the elements that serve as descriptions of the component. Those descriptions are passed as a concatenated string to the `aria-describedby` attribute. | | `accessibleRole` | `role` | Sets the accessible aria role of the component. | | `accessibilityAttributes` | `aria-expanded`, `aria-haspopup`, `aria-controls`, etc. | An object of strings that defines several additional accessibility attribute values for customization depending on the use case.
For composite components the object provides a way to enrich the accessibility of the different elements inside the component (for example in the `ui5-shellbar`). | | | `required` | `aria-required` | Defines whether the component is required. | @@ -187,6 +189,53 @@ The `accessibleNameRef` property is currently supported in most of the available --- +### accessibleDescription + +Setting the property on the custom element as: +```html + + Item 1 + Item 2 + +``` + +Will result in the shadow DOM as: +```html + +``` + +The `accessibleDescription` property is currently supported in: +* [List](https://sap.github.io/ui5-webcomponents/nightly/components/List/) +* [Tree](https://sap.github.io/ui5-webcomponents/nightly/components/Tree/) + +--- + +### accessibleDescriptionRef + +Setting the property on the custom element as: +```html +

List of items

+ + Item 1 + Item 2 + +``` + +Will result in the shadow DOM as: +```html + +``` + +The `accessibleDescriptionRef` property is currently supported in: +* [List](https://sap.github.io/ui5-webcomponents/nightly/components/List/) +* [Tree](https://sap.github.io/ui5-webcomponents/nightly/components/Tree/) + +--- + ### accessibleRole Setting the property on the custom element as: diff --git a/lerna.json b/lerna.json index 7f5008c88492..6dd06cfea728 100644 --- a/lerna.json +++ b/lerna.json @@ -14,7 +14,7 @@ "packages/create-package", "packages/compat" ], - "version": "2.4.0-rc.4", + "version": "2.5.0-rc.2", "command": { "publish": { "allowBranch": "*", diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index a2d4c5f82946..f5e169d4a5b5 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -3,6 +3,46 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.5.0-rc.2](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.1...v2.5.0-rc.2) (2024-11-28) + +**Note:** Version bump only for package @ui5/webcomponents-ai + + + + + +# [2.5.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.0...v2.5.0-rc.1) (2024-11-21) + +**Note:** Version bump only for package @ui5/webcomponents-ai + + + + + +# [2.5.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.1-rc.0...v2.5.0-rc.0) (2024-11-14) + +**Note:** Version bump only for package @ui5/webcomponents-ai + + + + + +## [2.4.1-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0...v2.4.1-rc.0) (2024-11-07) + +**Note:** Version bump only for package @ui5/webcomponents-ai + + + + + +# [2.4.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.4...v2.4.0) (2024-11-03) + +**Note:** Version bump only for package @ui5/webcomponents-ai + + + + + # [2.4.0-rc.4](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.3...v2.4.0-rc.4) (2024-10-31) **Note:** Version bump only for package @ui5/webcomponents-ai diff --git a/packages/ai/README.md b/packages/ai/README.md index 157e124d5d41..2459ecdbf61a 100644 --- a/packages/ai/README.md +++ b/packages/ai/README.md @@ -10,9 +10,10 @@ Provides web components implementing AI-related visual and interaction. ## Provided components -| Web Component | Tag name | Module import | -|--------------------------|-----------------------------|------------------------------------------------------------| - +| Web Component | Tag name | Module import | +|--------------------------|--------------------------------|---------------------------------------------------------| +| Button | `ui5-ai-button` | `import "@ui5/webcomponents-ai/dist/Button.js";` | +| PromptInput | `ui5-ai-prompt-input` | `import "@ui5/webcomponents-ai/dist/PromptInput.js";` | ## Provided assets diff --git a/packages/ai/package.json b/packages/ai/package.json index a7d16f3c27b1..2f0a9b2395db 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "@ui5/webcomponents-ai", - "version": "2.4.0-rc.4", + "version": "2.5.0-rc.2", "description": "UI5 Web Components: webcomponents.ai", "ui5": { "webComponentsPackage": true @@ -45,13 +45,13 @@ "directory": "packages/ai" }, "dependencies": { - "@ui5/webcomponents": "2.4.0-rc.4", - "@ui5/webcomponents-base": "2.4.0-rc.4", - "@ui5/webcomponents-icons": "2.4.0-rc.4", - "@ui5/webcomponents-theming": "2.4.0-rc.4" + "@ui5/webcomponents": "2.5.0-rc.2", + "@ui5/webcomponents-base": "2.5.0-rc.2", + "@ui5/webcomponents-icons": "2.5.0-rc.2", + "@ui5/webcomponents-theming": "2.5.0-rc.2" }, "devDependencies": { - "@ui5/webcomponents-tools": "2.4.0-rc.4", - "chromedriver": "^129.0.0" + "@ui5/webcomponents-tools": "2.5.0-rc.2", + "chromedriver": "^131.0.0" } } diff --git a/packages/ai/test/pages/Button.html b/packages/ai/test/pages/Button.html index eb6bf48fa1ec..d4ada3f6c79b 100644 --- a/packages/ai/test/pages/Button.html +++ b/packages/ai/test/pages/Button.html @@ -100,7 +100,7 @@ - + @@ -266,7 +266,7 @@ case "Rephrase": startTextGeneration(button, "reviseGenerating", predefinedTextsRephrased); break; - case "Summarise": + case "Summarize": startTextGeneration(button, "reviseGenerating", predefinedTextsSummarized); break; case "Bulgarian": diff --git a/packages/base/CHANGELOG.md b/packages/base/CHANGELOG.md index 164090effc12..8fec5c49844a 100644 --- a/packages/base/CHANGELOG.md +++ b/packages/base/CHANGELOG.md @@ -3,6 +3,50 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.5.0-rc.2](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.1...v2.5.0-rc.2) (2024-11-28) + +**Note:** Version bump only for package @ui5/webcomponents-base + + + + + +# [2.5.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.0...v2.5.0-rc.1) (2024-11-21) + +**Note:** Version bump only for package @ui5/webcomponents-base + + + + + +# [2.5.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.1-rc.0...v2.5.0-rc.0) (2024-11-14) + + +### Features + +* **ui5-form:** update to latest accessibility spec ([#10152](https://github.com/SAP/ui5-webcomponents/issues/10152)) ([4382d4e](https://github.com/SAP/ui5-webcomponents/commit/4382d4e280ffcf01a924163b9b719887c17f529a)), closes [#9952](https://github.com/SAP/ui5-webcomponents/issues/9952) +* **ui5-list, ui5-tree:** support accessible description ([#10131](https://github.com/SAP/ui5-webcomponents/issues/10131)) ([45f0ffe](https://github.com/SAP/ui5-webcomponents/commit/45f0ffeafb2da0ffcaf425649c7440b604e359a3)), closes [#6445](https://github.com/SAP/ui5-webcomponents/issues/6445) + + + + + +## [2.4.1-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0...v2.4.1-rc.0) (2024-11-07) + +**Note:** Version bump only for package @ui5/webcomponents-base + + + + + +# [2.4.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.4...v2.4.0) (2024-11-03) + +**Note:** Version bump only for package @ui5/webcomponents-base + + + + + # [2.4.0-rc.4](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.3...v2.4.0-rc.4) (2024-10-31) **Note:** Version bump only for package @ui5/webcomponents-base diff --git a/packages/base/package.json b/packages/base/package.json index 3b06dfaa4d2c..2b8df043cf77 100644 --- a/packages/base/package.json +++ b/packages/base/package.json @@ -1,6 +1,6 @@ { "name": "@ui5/webcomponents-base", - "version": "2.4.0-rc.4", + "version": "2.5.0-rc.2", "description": "UI5 Web Components: webcomponents.base", "author": "SAP SE (https://www.sap.com)", "license": "Apache-2.0", @@ -52,8 +52,8 @@ }, "devDependencies": { "@openui5/sap.ui.core": "1.120.17", - "@ui5/webcomponents-tools": "2.4.0-rc.4", - "chromedriver": "^129.0.0", + "@ui5/webcomponents-tools": "2.5.0-rc.2", + "chromedriver": "^131.0.0", "clean-css": "^5.2.2", "copy-and-watch": "^0.1.5", "cross-env": "^7.0.3", diff --git a/packages/base/src/MarkedEvents.ts b/packages/base/src/MarkedEvents.ts deleted file mode 100644 index 7c4e2e7eb26b..000000000000 --- a/packages/base/src/MarkedEvents.ts +++ /dev/null @@ -1,20 +0,0 @@ -const markedEvents = new WeakMap(); - -/** - * Marks the given event with random marker. - */ -const markEvent = (event: Event, value: string) => { - markedEvents.set(event, value); -}; - -/** - * Returns the marker for the given event. - */ -const getEventMark = (event: Event): string | undefined => { - return markedEvents.get(event); -}; - -export { - markEvent, - getEventMark, -}; diff --git a/packages/base/src/features/F6Navigation.ts b/packages/base/src/features/F6Navigation.ts index a67b65eb95c2..0d9ccd1bf0aa 100644 --- a/packages/base/src/features/F6Navigation.ts +++ b/packages/base/src/features/F6Navigation.ts @@ -39,7 +39,11 @@ class F6Navigation { } async groupElementToFocus(nextElement: HTMLElement) { - const nextElementDomRef = instanceOfUI5Element(nextElement) ? nextElement.getDomRef() : nextElement; + let nextElementDomRef = nextElement; + + if (instanceOfUI5Element(nextElement)) { + nextElementDomRef = nextElement.getDomRef() || nextElement.firstElementChild as HTMLElement; + } if (nextElementDomRef) { if (isElementClickable(nextElementDomRef)) { diff --git a/packages/base/src/util/AriaLabelHelper.ts b/packages/base/src/util/AccessibilityTextsHelper.ts similarity index 79% rename from packages/base/src/util/AriaLabelHelper.ts rename to packages/base/src/util/AccessibilityTextsHelper.ts index dbf687fa4113..89e11d9e0cba 100644 --- a/packages/base/src/util/AriaLabelHelper.ts +++ b/packages/base/src/util/AccessibilityTextsHelper.ts @@ -20,6 +20,8 @@ const registeredElements = new WeakMap(); type AccessibleElement = HTMLElement & { accessibleNameRef?: string; accessibleName?: string; + accessibleDescriptionRef?: string; + accessibleDescription?: string; }; const observerOptions = { @@ -49,11 +51,10 @@ const getEffectiveAriaLabelText = (el: HTMLElement) => { */ const getAllAccessibleNameRefTexts = (el: HTMLElement) => { const ids = (el as AccessibleElement).accessibleNameRef?.split(" ") ?? []; - const owner = el.getRootNode() as HTMLElement; let result = ""; ids.forEach((elementId: string, index: number) => { - const element = owner.querySelector(`[id='${elementId}']`); + const element = _getReferencedElementById(el, elementId); const text = `${element && element.textContent ? element.textContent : ""}`; if (text) { result += text; @@ -74,8 +75,12 @@ const _getAllAssociatedElementsFromDOM = (el: UI5Element): Array => set.add(itm); }); // adding other elements that id is the same as accessibleNameRef value - const value = el["accessibleNameRef" as keyof typeof el] as string; - const ids = value?.split(" ") ?? []; + const ariaLabelledBy = el["accessibleNameRef" as keyof typeof el] as string; + const ariaDescribedBy = el["accessibleDescriptionRef" as keyof typeof el] as string; + + const value = [ariaLabelledBy, ariaDescribedBy].filter(Boolean).join(" "); + + const ids = value ? value.split(" ") : []; ids.forEach(id => { const refEl = _getReferencedElementById(el, id); if (refEl) { @@ -91,7 +96,7 @@ const _getAssociatedLabels = (el: HTMLElement): Array => { }; const _getReferencedElementById = (el: HTMLElement, elementId: string): HTMLElement | null => { - return (el.getRootNode() as HTMLElement).querySelector(`[id='${elementId}']`); + return (el.getRootNode() as HTMLElement).querySelector(`[id='${elementId}']`) || document.getElementById(elementId); }; /** @@ -115,7 +120,9 @@ const getAssociatedLabelForTexts = (el: HTMLElement) => { const _createInvalidationCallback = (el: UI5Element) => { const invalidationCallback = (changeInfo: ChangeInfo) => { - if (!(changeInfo && changeInfo.type === "property" && changeInfo.name === "accessibleNameRef")) { + const isAccessibleNameRefChange = changeInfo && changeInfo.type === "property" && changeInfo.name === "accessibleNameRef"; + const isAccessibleDescriptionRefChange = changeInfo && changeInfo.type === "property" && changeInfo.name === "accessibleDescriptionRef"; + if (!isAccessibleNameRefChange && !isAccessibleDescriptionRefChange) { return; } const registeredElement = registeredElements.get(el); @@ -210,10 +217,44 @@ const deregisterUI5Element = (el: UI5Element) => { registeredElements.delete(el); }; +const getEffectiveAriaDescriptionText = (el: HTMLElement) => { + const accessibleEl = el as AccessibleElement; + + if (!accessibleEl.accessibleDescriptionRef) { + if (accessibleEl.accessibleDescription) { + return accessibleEl.accessibleDescription; + } + + return undefined; + } + + return getAllAccessibleDescriptionRefTexts(el); +}; + +const getAllAccessibleDescriptionRefTexts = (el: HTMLElement) => { + const ids = (el as AccessibleElement).accessibleDescriptionRef?.split(" ") ?? []; + let result = ""; + + ids.forEach((elementId: string, index: number) => { + const element = _getReferencedElementById(el, elementId); + const text = `${element && element.textContent ? element.textContent : ""}`; + if (text) { + result += text; + if (index < ids.length - 1) { + result += " "; + } + } + }); + + return result; +}; + export { getEffectiveAriaLabelText, getAssociatedLabelForTexts, registerUI5Element, deregisterUI5Element, getAllAccessibleNameRefTexts, + getEffectiveAriaDescriptionText, + getAllAccessibleDescriptionRefTexts, }; diff --git a/packages/compat/CHANGELOG.md b/packages/compat/CHANGELOG.md index 1a67ffda08af..03ce12491566 100644 --- a/packages/compat/CHANGELOG.md +++ b/packages/compat/CHANGELOG.md @@ -3,6 +3,52 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.5.0-rc.2](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.1...v2.5.0-rc.2) (2024-11-28) + +**Note:** Version bump only for package @ui5/webcomponents-compat + + + + + +# [2.5.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.0...v2.5.0-rc.1) (2024-11-21) + + +### Bug Fixes + +* **ui5-table:** text cut due to column overflow ([#10193](https://github.com/SAP/ui5-webcomponents/issues/10193)) ([b59d718](https://github.com/SAP/ui5-webcomponents/commit/b59d718dca80bd9a8ee65993ddc2358ecd127024)), closes [#10168](https://github.com/SAP/ui5-webcomponents/issues/10168) + + + + + +# [2.5.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.1-rc.0...v2.5.0-rc.0) (2024-11-14) + + +### Features + +* **ui5-list, ui5-tree:** support accessible description ([#10131](https://github.com/SAP/ui5-webcomponents/issues/10131)) ([45f0ffe](https://github.com/SAP/ui5-webcomponents/commit/45f0ffeafb2da0ffcaf425649c7440b604e359a3)), closes [#6445](https://github.com/SAP/ui5-webcomponents/issues/6445) + + + + + +## [2.4.1-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0...v2.4.1-rc.0) (2024-11-07) + +**Note:** Version bump only for package @ui5/webcomponents-compat + + + + + +# [2.4.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.4...v2.4.0) (2024-11-03) + +**Note:** Version bump only for package @ui5/webcomponents-compat + + + + + # [2.4.0-rc.4](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.3...v2.4.0-rc.4) (2024-10-31) **Note:** Version bump only for package @ui5/webcomponents-compat diff --git a/packages/compat/package.json b/packages/compat/package.json index 0c032574fe15..dc6ce65c2401 100644 --- a/packages/compat/package.json +++ b/packages/compat/package.json @@ -1,6 +1,6 @@ { "name": "@ui5/webcomponents-compat", - "version": "2.4.0-rc.4", + "version": "2.5.0-rc.2", "description": "UI5 Web Components: webcomponents.compat", "ui5": { "webComponentsPackage": true @@ -45,13 +45,13 @@ "directory": "packages/compat" }, "dependencies": { - "@ui5/webcomponents": "2.4.0-rc.4", - "@ui5/webcomponents-base": "2.4.0-rc.4", - "@ui5/webcomponents-icons": "2.4.0-rc.4", - "@ui5/webcomponents-theming": "2.4.0-rc.4" + "@ui5/webcomponents": "2.5.0-rc.2", + "@ui5/webcomponents-base": "2.5.0-rc.2", + "@ui5/webcomponents-icons": "2.5.0-rc.2", + "@ui5/webcomponents-theming": "2.5.0-rc.2" }, "devDependencies": { - "@ui5/webcomponents-tools": "2.4.0-rc.4", - "chromedriver": "^129.0.0" + "@ui5/webcomponents-tools": "2.5.0-rc.2", + "chromedriver": "^131.0.0" } } diff --git a/packages/compat/src/Table.ts b/packages/compat/src/Table.ts index 163000ca07b8..81f57ef019d2 100644 --- a/packages/compat/src/Table.ts +++ b/packages/compat/src/Table.ts @@ -30,7 +30,7 @@ import { import getNormalizedTarget from "@ui5/webcomponents-base/dist/util/getNormalizedTarget.js"; import getActiveElement from "@ui5/webcomponents-base/dist/util/getActiveElement.js"; import { getLastTabbableElement, getTabbableElements } from "@ui5/webcomponents-base/dist/util/TabbableElements.js"; -import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AriaLabelHelper.js"; +import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AccessibilityTextsHelper.js"; import debounce from "@ui5/webcomponents-base/dist/util/debounce.js"; import BusyIndicator from "@ui5/webcomponents/dist/BusyIndicator.js"; import CheckBox from "@ui5/webcomponents/dist/CheckBox.js"; diff --git a/packages/compat/src/themes/Table.css b/packages/compat/src/themes/Table.css index edeae057af64..1c17ab63aa21 100644 --- a/packages/compat/src/themes/Table.css +++ b/packages/compat/src/themes/Table.css @@ -10,13 +10,17 @@ border-bottom: var(--ui5_table_bottom_border); } -.ui5-table-root, -.ui5-table-busy-indicator { +.ui5-table-root { width: 100%; height: 100%; + display: flex; box-sizing: border-box; } +.ui5-table-busy-indicator { + flex-grow: 1; +} + table { width: 100%; border-spacing: 0; diff --git a/packages/create-package/CHANGELOG.md b/packages/create-package/CHANGELOG.md index 32bc61e45a5d..3b679f8be867 100644 --- a/packages/create-package/CHANGELOG.md +++ b/packages/create-package/CHANGELOG.md @@ -3,6 +3,46 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.5.0-rc.2](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.1...v2.5.0-rc.2) (2024-11-28) + +**Note:** Version bump only for package @ui5/create-webcomponents-package + + + + + +# [2.5.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.0...v2.5.0-rc.1) (2024-11-21) + +**Note:** Version bump only for package @ui5/create-webcomponents-package + + + + + +# [2.5.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.1-rc.0...v2.5.0-rc.0) (2024-11-14) + +**Note:** Version bump only for package @ui5/create-webcomponents-package + + + + + +## [2.4.1-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0...v2.4.1-rc.0) (2024-11-07) + +**Note:** Version bump only for package @ui5/create-webcomponents-package + + + + + +# [2.4.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.4...v2.4.0) (2024-11-03) + +**Note:** Version bump only for package @ui5/create-webcomponents-package + + + + + # [2.4.0-rc.4](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.3...v2.4.0-rc.4) (2024-10-31) **Note:** Version bump only for package @ui5/create-webcomponents-package diff --git a/packages/create-package/package.json b/packages/create-package/package.json index 7d5ab1f41de0..12c6e4ebe1d5 100644 --- a/packages/create-package/package.json +++ b/packages/create-package/package.json @@ -1,6 +1,6 @@ { "name": "@ui5/create-webcomponents-package", - "version": "2.4.0-rc.4", + "version": "2.5.0-rc.2", "description": "UI5 Web Components: create package", "author": "SAP SE (https://www.sap.com)", "license": "Apache-2.0", diff --git a/packages/fiori/CHANGELOG.md b/packages/fiori/CHANGELOG.md index 9dfa63508b4f..5853739908fa 100644 --- a/packages/fiori/CHANGELOG.md +++ b/packages/fiori/CHANGELOG.md @@ -3,6 +3,62 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.5.0-rc.2](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.1...v2.5.0-rc.2) (2024-11-28) + + +### Bug Fixes + +* **ui5-wizard:** stacked Wizard Steps are aligned properly ([#10250](https://github.com/SAP/ui5-webcomponents/issues/10250)) ([3473fbf](https://github.com/SAP/ui5-webcomponents/commit/3473fbf7dd6f97d0de70a540d412c36901455926)), closes [#9779](https://github.com/SAP/ui5-webcomponents/issues/9779) + + + + + +# [2.5.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.0...v2.5.0-rc.1) (2024-11-21) + +**Note:** Version bump only for package @ui5/webcomponents-fiori + + + + + +# [2.5.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.1-rc.0...v2.5.0-rc.0) (2024-11-14) + + +### Bug Fixes + +* **ui5-dynamic-page:** move subheading slot outside the title wrapper ([#10163](https://github.com/SAP/ui5-webcomponents/issues/10163)) ([6466b8a](https://github.com/SAP/ui5-webcomponents/commit/6466b8ad7f73c85a5c105dea3c196f6bfb78f27a)) + + +### Features + +* **ui5-list, ui5-tree:** support accessible description ([#10131](https://github.com/SAP/ui5-webcomponents/issues/10131)) ([45f0ffe](https://github.com/SAP/ui5-webcomponents/commit/45f0ffeafb2da0ffcaf425649c7440b604e359a3)), closes [#6445](https://github.com/SAP/ui5-webcomponents/issues/6445) + + + + + +## [2.4.1-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0...v2.4.1-rc.0) (2024-11-07) + +**Note:** Version bump only for package @ui5/webcomponents-fiori + + + + + +# [2.4.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.4...v2.4.0) (2024-11-03) + + +### Bug Fixes + +* **ui5-dynamic-page:** improve scrolling smoothness ([#10093](https://github.com/SAP/ui5-webcomponents/issues/10093)) ([d1420b0](https://github.com/SAP/ui5-webcomponents/commit/d1420b0be2c40ca649503cca0715e4c529929f8f)), closes [#10011](https://github.com/SAP/ui5-webcomponents/issues/10011) +* **ui5-dynamic-page:** prevent unwanted header toggle from scroll ([#10007](https://github.com/SAP/ui5-webcomponents/issues/10007)) ([7a7d00c](https://github.com/SAP/ui5-webcomponents/commit/7a7d00c0d615283d1a86d775b6c51db7feadfb42)) +* **ui5-media-gallery:** clear selected thumbnail on item removal ([#10087](https://github.com/SAP/ui5-webcomponents/issues/10087)) ([af4cadb](https://github.com/SAP/ui5-webcomponents/commit/af4cadbfb637c1a6440aa0bd1fc516629ae332ae)) + + + + + # [2.4.0-rc.4](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.3...v2.4.0-rc.4) (2024-10-31) diff --git a/packages/fiori/global.d.ts b/packages/fiori/global.d.ts index 086bbcda9800..28c472a4133f 100644 --- a/packages/fiori/global.d.ts +++ b/packages/fiori/global.d.ts @@ -1,5 +1,4 @@ -// eslint-disable-next-line -import type { BrowserMultiFormatReader, NotFoundException } from "@zxing/library/esm5/index.js"; +import type { BrowserMultiFormatReader, NotFoundException } from "@zxing/library"; export {}; diff --git a/packages/fiori/package.json b/packages/fiori/package.json index d6331774b73d..c3fd2eb9eb38 100644 --- a/packages/fiori/package.json +++ b/packages/fiori/package.json @@ -1,6 +1,6 @@ { "name": "@ui5/webcomponents-fiori", - "version": "2.4.0-rc.4", + "version": "2.5.0-rc.2", "description": "UI5 Web Components: webcomponents.fiori", "ui5": { "webComponentsPackage": true @@ -53,15 +53,15 @@ "directory": "packages/fiori" }, "dependencies": { - "@ui5/webcomponents": "2.4.0-rc.4", - "@ui5/webcomponents-base": "2.4.0-rc.4", - "@ui5/webcomponents-icons": "2.4.0-rc.4", - "@ui5/webcomponents-theming": "2.4.0-rc.4", - "@zxing/library": "^0.17.1" + "@ui5/webcomponents": "2.5.0-rc.2", + "@ui5/webcomponents-base": "2.5.0-rc.2", + "@ui5/webcomponents-icons": "2.5.0-rc.2", + "@ui5/webcomponents-theming": "2.5.0-rc.2", + "@zxing/library": "^0.21.3" }, "devDependencies": { - "@ui5/webcomponents-tools": "2.4.0-rc.4", - "chromedriver": "^129.0.0", + "@ui5/webcomponents-tools": "2.5.0-rc.2", + "chromedriver": "^131.0.0", "lit": "^2.0.0" } } diff --git a/packages/fiori/src/BarcodeScannerDialog-zxing.d.ts b/packages/fiori/src/BarcodeScannerDialog-zxing.d.ts index 9c36669472f9..25f3cb9a4a9b 100644 --- a/packages/fiori/src/BarcodeScannerDialog-zxing.d.ts +++ b/packages/fiori/src/BarcodeScannerDialog-zxing.d.ts @@ -1,5 +1,5 @@ declare module "@zxing/library/umd/index.min.js" { - import type { BrowserMultiFormatReader as BrowserMultiFormatReaderT, NotFoundException as NotFoundExceptionT } from "@zxing/library/esm5/index.js"; + import type { BrowserMultiFormatReader as BrowserMultiFormatReaderT, NotFoundException as NotFoundExceptionT } from "@zxing/library"; export const BrowserMultiFormatReader: typeof BrowserMultiFormatReaderT; export const NotFoundException: typeof NotFoundExceptionT; diff --git a/packages/fiori/src/BarcodeScannerDialog.ts b/packages/fiori/src/BarcodeScannerDialog.ts index 63253391eef6..db1610138b64 100644 --- a/packages/fiori/src/BarcodeScannerDialog.ts +++ b/packages/fiori/src/BarcodeScannerDialog.ts @@ -10,7 +10,7 @@ import property from "@ui5/webcomponents-base/dist/decorators/property.js"; import event from "@ui5/webcomponents-base/dist/decorators/event.js"; import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js"; import { getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; -import type { Result, Exception } from "@zxing/library/esm5/index.js"; +import type { Result, Exception } from "@zxing/library"; import type { Interval } from "@ui5/webcomponents-base/dist/types.js"; // eslint-disable-next-line import/no-extraneous-dependencies import ZXing from "@ui5/webcomponents-fiori/dist/ssr-zxing.js"; diff --git a/packages/fiori/src/DynamicPage.ts b/packages/fiori/src/DynamicPage.ts index 44b71c969420..2c536f9f09e7 100644 --- a/packages/fiori/src/DynamicPage.ts +++ b/packages/fiori/src/DynamicPage.ts @@ -195,6 +195,7 @@ class DynamicPage extends UI5Element { skipSnapOnScroll = false; showHeaderInStickArea = false; + isToggled = false; @property({ type: Boolean }) _headerSnapped = false; @@ -226,6 +227,7 @@ class DynamicPage extends UI5Element { this.dynamicPageTitle.snapped = this._headerSnapped; this.dynamicPageTitle.interactive = this.hasHeading; this.dynamicPageTitle.hasSnappedTitleOnMobile = !!this.hasSnappedTitleOnMobile; + this.dynamicPageTitle.removeAttribute("hovered"); } } @@ -246,7 +248,7 @@ class DynamicPage extends UI5Element { } get headerInContent(): boolean { - return !this.showHeaderInStickArea && !this.headerInTitle; + return !this.showHeaderInStickArea && !this.headerInTitle && !this.hasSnappedTitleOnMobile; } get _headerLabel() { @@ -307,29 +309,48 @@ class DynamicPage extends UI5Element { return; } - const scrollTop = this.scrollContainer!.scrollTop; - const lastHeaderSnapped = this._headerSnapped; + if (this.isToggled) { + this.isToggled = false; + return; + } if (this.skipSnapOnScroll) { this.skipSnapOnScroll = false; return; } - if (scrollTop > this.dynamicPageHeader.getBoundingClientRect().height) { + const scrollTop = this.scrollContainer!.scrollTop; + const headerHeight = this.dynamicPageHeader.getBoundingClientRect().height; + const lastHeaderSnapped = this._headerSnapped; + + const shouldSnap = !this._headerSnapped && scrollTop > headerHeight + SCROLL_THRESHOLD; + const shouldExpand = this._headerSnapped && (scrollTop < headerHeight - SCROLL_THRESHOLD + || (!scrollTop && !headerHeight)); + + if (shouldSnap) { this.showHeaderInStickArea = false; this._headerSnapped = true; - } else { + + //* snappedTitleOnMobile + // If the header is snapped and the scroll is at the top, scroll down a bit + // to avoid ending in an endless loop of snapping and unsnapping + requestAnimationFrame(() => { + if (this.scrollContainer!.scrollTop === 0) { + this.scrollContainer!.scrollTop = SCROLL_THRESHOLD; + } + }); + } else if (shouldExpand) { this._headerSnapped = false; } + // Fire event if snapped state changed if (lastHeaderSnapped !== this._headerSnapped) { this.fireDecoratorEvent("title-toggle"); } - - this.dynamicPageTitle.snapped = this._headerSnapped; } async onExpandClick() { + this.isToggled = true; this._toggleHeader(); this.fireDecoratorEvent("title-toggle"); await renderFinished(); @@ -353,6 +374,7 @@ class DynamicPage extends UI5Element { if (!this.hasHeading) { return; } + this.isToggled = true; this._toggleHeader(); this.fireDecoratorEvent("title-toggle"); await renderFinished(); @@ -360,6 +382,21 @@ class DynamicPage extends UI5Element { } async _toggleHeader() { + const headerHeight = this.dynamicPageHeader?.getBoundingClientRect().height || 0; + const currentScrollTop = this.scrollContainer!.scrollTop; + + if (currentScrollTop > SCROLL_THRESHOLD && currentScrollTop < headerHeight) { + if (!this._headerSnapped) { + this._headerSnapped = true; + this.showHeaderInStickArea = true; + this.scrollContainer!.scrollTop = 0; + } else { + this.showHeaderInStickArea = false; + this._headerSnapped = false; + } + return; + } + if (this.scrollContainer!.scrollTop === SCROLL_THRESHOLD) { this.scrollContainer!.scrollTop = 0; } diff --git a/packages/fiori/src/DynamicPageTitle.hbs b/packages/fiori/src/DynamicPageTitle.hbs index 1eb5cb334f2a..7ff15ce277ea 100644 --- a/packages/fiori/src/DynamicPageTitle.hbs +++ b/packages/fiori/src/DynamicPageTitle.hbs @@ -28,7 +28,6 @@ @ui5-_min-content-width-change={{onMinContentWidthChange}}>
-
{{#if hasContent}} @@ -49,7 +48,7 @@ {{/unless}} - + {{/if}} {{_ariaDescribedbyText}} diff --git a/packages/fiori/src/IllustratedMessage.ts b/packages/fiori/src/IllustratedMessage.ts index 0e51b6e9c2eb..20a5fa04f6f4 100644 --- a/packages/fiori/src/IllustratedMessage.ts +++ b/packages/fiori/src/IllustratedMessage.ts @@ -6,7 +6,7 @@ import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js"; import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js"; import type { ResizeObserverCallback } from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js"; import { getIllustrationDataSync, getIllustrationData } from "@ui5/webcomponents-base/dist/asset-registries/Illustrations.js"; -import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AriaLabelHelper.js"; +import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AccessibilityTextsHelper.js"; import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js"; import Title from "@ui5/webcomponents/dist/Title.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; diff --git a/packages/fiori/src/NotificationListGroupList.ts b/packages/fiori/src/NotificationListGroupList.ts index 96822f360f6e..49d2d555a390 100644 --- a/packages/fiori/src/NotificationListGroupList.ts +++ b/packages/fiori/src/NotificationListGroupList.ts @@ -31,6 +31,10 @@ class NotificationListGroupList extends List { onItemFocused() { } + _onfocusin(e: FocusEvent) { + e.stopImmediatePropagation(); + } + focusItem(item: ListItemBase) { item.focus(); } diff --git a/packages/fiori/src/SideNavigation.ts b/packages/fiori/src/SideNavigation.ts index c5c88e399805..09e5c1391dd2 100644 --- a/packages/fiori/src/SideNavigation.ts +++ b/packages/fiori/src/SideNavigation.ts @@ -82,6 +82,10 @@ type NavigationMenuClickEventDetail = MenuItemClickEventDetail & { * The items can consist of text only or an icon with text. The use or non-use of icons must be consistent for all items on one level. * You must not combine entries with and without icons on the same level. We strongly recommend that you do not use icons on the second level. * + * The `ui5-side-navigation` component is intended for use within an `ui5-navigation-layout` component. + * While it can function independently, it is recommended to use it with + * the `ui5-navigation-layout` for optimal user experience. + * * ### Keyboard Handling * * ### Fast Navigation @@ -146,25 +150,22 @@ class SideNavigation extends UI5Element { collapsed = false; /** - * Defines the main items of the `ui5-side-navigation`. Use the `ui5-side-navigation-item` component - * for the top-level items, and the `ui5-side-navigation-sub-item` component for second-level items, nested - * inside the items. + * Defines the main items of the component. * * @public */ @slot({ type: HTMLElement, invalidateOnChildChange: true, "default": true }) - items!: Array; + items!: Array; /** - * Defines the fixed items at the bottom of the `ui5-side-navigation`. Use the `ui5-side-navigation-item` component - * for the fixed items, and optionally the `ui5-side-navigation-sub-item` component to provide second-level items inside them. + * Defines the fixed items at the bottom of the component. * * **Note:** In order to achieve the best user experience, it is recommended that you keep the fixed items "flat" (do not pass sub-items) * * @public */ @slot({ type: HTMLElement, invalidateOnChildChange: true }) - fixedItems!: Array; + fixedItems!: Array; /** * Defines the header of the `ui5-side-navigation`. @@ -226,7 +227,7 @@ class SideNavigation extends UI5Element { onBeforeRendering() { super.onBeforeRendering(); - this._getAllItems(this.items as Array).concat(this._getAllItems(this.fixedItems as Array)).forEach(item => { + this._getAllItems(this.items).concat(this._getAllItems(this.fixedItems)).forEach(item => { item.sideNavCollapsed = this.collapsed; item.inPopover = this.inPopover; item.sideNavigation = this; @@ -238,7 +239,7 @@ class SideNavigation extends UI5Element { // item navigation index should be managed, because items are // dynamically recreated and tabIndexes are not updated const tree = this.getPickerTree(); - const selectedItem = tree._findSelectedItem(tree.items as Array); + const selectedItem = tree._findSelectedItem(tree.items); if (selectedItem) { selectedItem.focus(); } else { @@ -386,11 +387,11 @@ class SideNavigation extends UI5Element { } getEnabledFixedItems() : Array { - return this.getEnabledItems(this.fixedItems as Array); + return this.getEnabledItems(this.fixedItems); } getEnabledFlexibleItems() : Array { - const items = this.getEnabledItems(this.items as Array); + const items = this.getEnabledItems(this.items); if (this._overflowItem) { items.push(this._overflowItem); @@ -425,12 +426,12 @@ class SideNavigation extends UI5Element { onAfterRendering() { if (!this.getDomRef()?.matches(":focus-within")) { - let selectedItem = this._findSelectedItem(this.items as Array); + let selectedItem = this._findSelectedItem(this.items); if (selectedItem) { this._flexibleItemNavigation.setCurrentItem(selectedItem); } - selectedItem = this._findSelectedItem(this.fixedItems as Array); + selectedItem = this._findSelectedItem(this.fixedItems); if (selectedItem) { this._fixedItemNavigation.setCurrentItem(selectedItem); } @@ -549,7 +550,7 @@ class SideNavigation extends UI5Element { } get overflowItems() : Array { - return (this.items as Array).reduce((result, item) => { + return (this.items).reduce((result, item) => { return result.concat(item.overflowItems); }, new Array()); } @@ -609,8 +610,8 @@ class SideNavigation extends UI5Element { return; } - let items = this._getSelectableItems(this.items as Array); - items = items.concat(this._getSelectableItems(this.fixedItems as Array)); + let items = this._getSelectableItems(this.items); + items = items.concat(this._getSelectableItems(this.fixedItems)); items.forEach(current => { current.selected = false; diff --git a/packages/fiori/src/WizardTab.hbs b/packages/fiori/src/WizardTab.hbs index a944fd611b87..d523590c48d7 100644 --- a/packages/fiori/src/WizardTab.hbs +++ b/packages/fiori/src/WizardTab.hbs @@ -20,7 +20,9 @@ {{#if hasTexts}}
{{titleText}}
-
{{subtitleText}}
+ {{#if subtitleText}} +
{{subtitleText}}
+ {{/if}}
{{/if}} diff --git a/packages/fiori/src/themes/DynamicPage.css b/packages/fiori/src/themes/DynamicPage.css index c4415e41418b..93db2137cae4 100644 --- a/packages/fiori/src/themes/DynamicPage.css +++ b/packages/fiori/src/themes/DynamicPage.css @@ -126,11 +126,4 @@ :host([media-range="XL"]) ::slotted([slot="headerArea"]) { padding: var(--_ui5_dynamic_page_header_padding_XL); -} - -/* snappedTitleOnMobile */ -:host([_header-snapped]) ::slotted([slot="headerArea"]) { - height: 0; - padding: 0; - visibility: hidden; } \ No newline at end of file diff --git a/packages/fiori/test/pages/NavigationLayoutSubHeader.html b/packages/fiori/test/pages/NavigationLayoutSubHeader.html new file mode 100644 index 000000000000..7e8463bb6546 --- /dev/null +++ b/packages/fiori/test/pages/NavigationLayoutSubHeader.html @@ -0,0 +1,161 @@ + + + + + Navigation Layout + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+

Home

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+
+
+

Item 1

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+
+
+

Item 2

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+
+
+

Item 3

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+
+
+

Item 4

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+
+
+

Item 5

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+
+
+

Item 6

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+
+
+

Item 7

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+
+
+

Sub Item 1

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+
+
+

Sub Item 2

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+
+
+
+ + + + diff --git a/packages/fiori/test/pages/Wizard.html b/packages/fiori/test/pages/Wizard.html index 1e20df44fe81..627dc636f6c4 100644 --- a/packages/fiori/test/pages/Wizard.html +++ b/packages/fiori/test/pages/Wizard.html @@ -673,6 +673,80 @@

Wizard non-standard 3

+

Wizard steps with long titles

+ + +
+ Sed fermentum, mi et tristique ullamcorper, sapien sapien faucibus + sem, quis pretium nibh lorem malesuada diam. Nulla quis arcu aliquet, + feugiat massa semper, volutpat diam. Nam vitae ante posuere, molestie + neque sit amet, dapibus velit. Maecenas eleifend tempor lorem. Mauris + vitae elementum mi, sed eleifend ligula. Nulla tempor vulputate dolor, + nec dignissim quam convallis ut. Praesent vitae commodo felis, ut + iaculis felis. Fusce quis eleifend sapien, eget facilisis nibh. + Suspendisse est velit, scelerisque ut commodo eget, dignissim quis + metus. Cras faucibus consequat gravida. Curabitur vitae quam felis. + Phasellus ac leo eleifend, commodo tortor et, varius quam. Aliquam + erat volutpat. +
+
+ +
Content for Overview step.
+
+ + +
Content for Details step.
+
+ + +
Content for Specifications and Requirements step.
+
+ + +
+ Content for User Instructions and Guidelines for Installation step. +
+
+ + +
Content for Testing step.
+
+ + +
Content for Validation step.
+
+ + +
Content for Deployment Plan step.
+
+ + +
Content for Maintenance and Support Overview step.
+
+ + +
Content for Feedback and Improvements step.
+
+ + +
+ Content for Final Review and Conclusion for the Entire Process step. +
+
+
diff --git a/packages/main/test/pages/EventBubbling.html b/packages/main/test/pages/EventBubbling.html index a16ff10aaf29..a477ba761484 100644 --- a/packages/main/test/pages/EventBubbling.html +++ b/packages/main/test/pages/EventBubbling.html @@ -22,6 +22,12 @@ + Open Menu + + + + + @@ -53,8 +59,11 @@ mySelect.addEventListener("close", function(e) { console.log("Select on close") }); + myMenu.addEventListener("close", function(e) { + console.log("Menu on close") + }); myMcb.addEventListener("close", function(e) { - console.log("myMcb on close") + console.log("Mcb on close") }); myInput.addEventListener("close", function(e) { console.log("Input on close") @@ -65,5 +74,9 @@ myMsgStrip.addEventListener("close", function(e) { console.log("MessageStrip on close") }); + + btnOpen.addEventListener("click", function(e) { + myMenu.open = true; + }); diff --git a/packages/main/test/pages/Link.html b/packages/main/test/pages/Link.html index cf4c902c3e37..2f4444204131 100644 --- a/packages/main/test/pages/Link.html +++ b/packages/main/test/pages/Link.html @@ -86,9 +86,11 @@

Link designs

- - Go to - Go to +
+ Go to
+ Go to
+
+ Go to
diff --git a/packages/main/test/pages/List.html b/packages/main/test/pages/List.html index 339f1499df55..4735dc05c240 100644 --- a/packages/main/test/pages/List.html +++ b/packages/main/test/pages/List.html @@ -497,6 +497,23 @@

Items 3/3

+

+

With accessible description ref

+ Accessible description ref works + + Item 1 + Item 2 + Item 3 + + +

+

With accessible description

+ + Item 1 + Item 2 + Item 3 + +
diff --git a/packages/main/test/pages/RadioButton.html b/packages/main/test/pages/RadioButton.html index 59cc111a1264..11376127dcb4 100644 --- a/packages/main/test/pages/RadioButton.html +++ b/packages/main/test/pages/RadioButton.html @@ -27,6 +27,11 @@ + + + + +
diff --git a/packages/main/test/pages/TableHorizontal.html b/packages/main/test/pages/TableHorizontal.html index 1c3e51b9c292..253ac536b09f 100644 --- a/packages/main/test/pages/TableHorizontal.html +++ b/packages/main/test/pages/TableHorizontal.html @@ -16,7 +16,7 @@ - + Product diff --git a/packages/main/test/pages/Tokenizer-multi-line.html b/packages/main/test/pages/Tokenizer-multi-line.html new file mode 100644 index 000000000000..064f91562bb9 --- /dev/null +++ b/packages/main/test/pages/Tokenizer-multi-line.html @@ -0,0 +1,161 @@ + + + + + + + Tokenizer - multi-line + + + + + + + + + +
+

Multi Line

+ + + + + + + + + + + + + + + +

Multi Line with long token

+ + + + + + + + + + + + + + + + + +

Multi Line with long token and restricted height

+ + + + + + + + + + + + + + + + +

Multi Line with clear all

+ + + + + + + + + + + + + + + +

Multi Line with restricted height and clear all

+ + + + + + + + + + + + + + + + +

Multi Line with clear all - single token

+ + + + +

Multi Line in readonly mode

+ + + + + + + + + + + + + + + +

Multi Line in disabled mode

+ + + + + + + + + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/packages/main/test/pages/Toolbar.html b/packages/main/test/pages/Toolbar.html index 4625486e5c54..ad1a4b860972 100644 --- a/packages/main/test/pages/Toolbar.html +++ b/packages/main/test/pages/Toolbar.html @@ -13,6 +13,17 @@
+ + + + + + + + + + + Basic

@@ -21,7 +32,19 @@ + + + + + + + + + + + +

@@ -29,7 +52,7 @@ Standard Toolbar with ToolbarSelect
- + @@ -321,6 +344,13 @@ toolbarSlider.addEventListener("input", e => { document.getElementById("toolbars-container").setAttribute("style", "width:" + e.target.value + "%"); }) + + const btnOpenMenu = document.getElementById("btnOpenMenu"); + const menu = document.getElementById("menu"); + + btnOpenMenu.addEventListener("ui5-click", function(event) { + menu.open = !menu.open; + }); diff --git a/packages/main/test/pages/Tree.html b/packages/main/test/pages/Tree.html index afc5d5b22123..eeb2899ee481 100644 --- a/packages/main/test/pages/Tree.html +++ b/packages/main/test/pages/Tree.html @@ -206,6 +206,25 @@ + +

+ +

With accessible description ref

+ Tree with accessible description ref + + + + + + +

+

With accessible description

+ + + + + + diff --git a/packages/main/test/pages/form/Form.html b/packages/main/test/pages/form/Form.html new file mode 100644 index 000000000000..237e792fe1de --- /dev/null +++ b/packages/main/test/pages/form/Form.html @@ -0,0 +1,74 @@ + + + + + + + Form Basic + + + + + +
+ + + + + \ No newline at end of file diff --git a/packages/main/test/pages/form/FormEmptySpan.html b/packages/main/test/pages/form/FormEmptySpan.html new file mode 100644 index 000000000000..471e34a2f2d3 --- /dev/null +++ b/packages/main/test/pages/form/FormEmptySpan.html @@ -0,0 +1,736 @@ + + + + + + Form + + + + + + + + + + + +
+ + +
+ Label Span + + S12 M1 L1 XL1 + S12 M2 L2 XL2 + S12 M3 L3 XL3 + S12 M4 L4 XL4 + S12 M4 L4 XL5 + S12 M4 L4 XL6 + S12 M4 L5 XL6 + S12 M4 L6 XL6 + S12 M5 L6 XL6 + S12 M6 L6 XL6 + S12 M7 L7 XL7 + S12 M8 L8 XL8 + S12 M12 L12 XL12 + + + Empty Span + + S0 M0 L0 XL0 + S0 M1 L1 XL1 + S0 M1 L2 XL2 + S0 M2 L3 XL3 + S0 M2 L4 XL4 + S0 M2 L5 XL5 + S0 M2 L6 XL6 + S0 M2 L7 XL7 + S0 M2 L8 XL8 + S0 M2 L9 XL9 + S0 M2 L10 XL10 + + + + + Top + Side + +
+ +
+ + + Name: + Red Point Stores + + + + ZIP Code/City: + 411 Maintown + + + + Street: + Main St 1618 + + + + Country: + Germany + + + + WebSite: + sap.com + + + + Delivery address: + Newtown + + +
+ +
+ +


+ +
+ + + Name: + + + + + ZIP Code/City: + + + + + + Street: + + + + + + Country: + + Australia + Germany + England + + + + + WebSite: + + + + + Delivery address: + + + +
+ +
+ +


+ +
+ + + + + Name: + Red Point Stores + + + + ZIP Code/City: + 411 Maintown + + + + Street: + Main St 1618 + + + + Country: + Germany + + + + WebSite: + sap.com + + + + + + Twitter: + @sap + + + + Email: + john.smith@sap.com + + + + Tel: + +49 6227 747474 + + + + SMS: + +49 6227 747474 + + + + Mobile: + +49 6227 747474 + + + + Pager: + +49 6227 747474 + + + + Fax: + +49 6227 747474 + + + + + + + Name: + Red Point Stores + + + + ZIP Code/City: + 411 Maintown + + + + Street: + Main St 1618 + + + + Country: + Germany + + + + WebSite: + sap.com + + + +
+ +
+


+ +
+ + + + + Name: + Red Point Stores + + + + ZIP Code/City: + 411 Maintown + + + + Street: + Main St 1618 + + + + Country: + Germany + + + + WebSite: + sap.com + + + + + + Twitter: + @sap + + + + Email: + john.smith@sap.com + + + + Tel: + +49 6227 747474 + + + + SMS: + +49 6227 747474 + + + + Mobile: + +49 6227 747474 + + + + Pager: + +49 6227 747474 + + + + Fax: + +49 6227 747474 + + + + + + + Name: + Red Point Stores + + + + ZIP Code/City: + 411 Maintown + + + + Street: + Main St 1618 + + + + Country: + Germany + + + + WebSite: + sap.com + + + +
+ +
+


+ +
+

Label always Top

+ + + Name: + + + + + ZIP Code/City: + + + + + + Street: + + + + + + Country: + + Australia + Germany + England + + + + + WebSite: + + + + + Delivery address: + + + +
+
+ + + + diff --git a/packages/main/test/pages/form/FormF6.html b/packages/main/test/pages/form/FormF6.html new file mode 100644 index 000000000000..70a73b9b8f3d --- /dev/null +++ b/packages/main/test/pages/form/FormF6.html @@ -0,0 +1,192 @@ + + + + + + Form Basic + + + + + + + + + +
+ + +
+ + + + + Name: + + + + + ZIP Code/City: + + + + + + Street: + + + + + + Country: + + Australia + Germany + England + + + + + WebSite: + + + + + Delivery address: + + + + + + + Name: + + + + + ZIP Code/City: + + + + + + Street: + + + + + + Country: + + Australia + Germany + England + + + + + WebSite: + + + + + Delivery address: + + + + + + + + Name: + + + + + ZIP Code/City: + + + + + + Street: + + + + + + Country: + + Australia + Germany + England + + + + + WebSite: + + + + + Delivery address: + + + + +
+ +
+ + + Name: + + + + + ZIP Code/City: + + + + + + Street: + + + + + + Country: + + Australia + Germany + England + + + + + WebSite: + + + + + Delivery address: + + + +
+ +
+ + + + diff --git a/packages/main/test/specs/ComboBox.mobile.spec.js b/packages/main/test/specs/ComboBox.mobile.spec.js index ebf074971508..544f3bb87a36 100644 --- a/packages/main/test/specs/ComboBox.mobile.spec.js +++ b/packages/main/test/specs/ComboBox.mobile.spec.js @@ -1,7 +1,27 @@ import { assert } from "chai"; +const getVisibleItems = async (combo) => { + const items = await combo.$$("ui5-cb-item"); + const filteredItems = await Promise.all(items.map(async item => { + return (await item.getProperty("_isVisible")) ? item : null; + })); + + // filter out null values + return filteredItems.filter(item => item !== null); +}; + +const getVisibleGroupItems = async (combo) => { + const items = await combo.$$("ui5-cb-item-group"); + const filteredItems = await Promise.all(items.map(async item => { + return (await item.getProperty("_isVisible")) ? item : null; + })); + + // filter out null values + return filteredItems.filter(item => item !== null); +}; + describe("Basic mobile picker rendering and interaction", () => { - before(async () => { + beforeEach(async () => { await browser.url("test/pages/ComboBox.html"); await browser.emulateDevice('iPhone X'); }); @@ -23,10 +43,13 @@ describe("Basic mobile picker rendering and interaction", () => { }); it("Should close the mobile picker dialog when pressing the close button", async () => { - const combo = await browser.$("#combo2"); - const picker = await combo.shadow$("ui5-responsive-popover"); - const dialogCloseButton = await picker.$(".ui5-responsive-popover-close-btn"); + const combo = await $("#combo2"); + + await combo.click(); + const picker = await combo.shadow$("ui5-responsive-popover"); + const dialogCloseButton = await picker.$(".ui5-responsive-popover-close-btn"); + assert.ok(await picker.isDisplayed(), "Picker is still opened"); await dialogCloseButton.click(); @@ -95,7 +118,7 @@ describe("Eventing", () => { await combo.scrollIntoView(); await combo.click(); - const suggestionItem = await combo.shadow$("ui5-responsive-popover").$$("ui5-li")[1]; + const suggestionItem = (await getVisibleItems(combo))[1]; await suggestionItem.click(); assert.strictEqual(await combo.getAttribute("value"), "Bulgaria", "The combo box's value is updated properly"); @@ -264,11 +287,10 @@ describe("Picker filtering", () => { await combo.click(); const dialogInput = await combo.shadow$("ui5-responsive-popover").$("[ui5-input]"); - const dialogList = await combo.shadow$("ui5-responsive-popover").$('ui5-list') - assert.strictEqual(await dialogList.$$('ui5-li').length, 9, "All of the items are shown (8)"); + assert.strictEqual((await getVisibleItems(combo)).length, 9, "All of the items are shown (8)"); await dialogInput.keys("B"); - assert.strictEqual(await dialogList.$$('ui5-li').length, 4, "There are 4 filtered items"); + assert.strictEqual((await getVisibleItems(combo)).length, 4, "There are 4 filtered items"); }); it("Should filter group header list items", async () => { @@ -280,11 +302,10 @@ describe("Picker filtering", () => { await combo.click(); const dialogInput = await combo.shadow$("ui5-responsive-popover").$("[ui5-input]"); - const dialogList = await combo.shadow$("ui5-responsive-popover").$('ui5-list') - assert.strictEqual(await dialogList.$$('ui5-li-group').length, 3, "All of the group header list items are shown (3)"); + assert.strictEqual((await getVisibleGroupItems(combo)).length, 3, "All of the group header list items are shown (3)"); await dialogInput.keys("B"); - assert.strictEqual(await dialogList.$$('ui5-li-group').length, 2, "There is only 1 visible group"); + assert.strictEqual((await getVisibleGroupItems(combo)).length, 2, "There is only 1 visible group"); }); }); diff --git a/packages/main/test/specs/ComboBox.spec.js b/packages/main/test/specs/ComboBox.spec.js index 38883e51fab1..5e8cc90d76a0 100644 --- a/packages/main/test/specs/ComboBox.spec.js +++ b/packages/main/test/specs/ComboBox.spec.js @@ -1,5 +1,25 @@ import { assert } from "chai"; +const getVisibleItems = async (combo) => { + const items = await combo.$$("ui5-cb-item"); + const filteredItems = await Promise.all(items.map(async item => { + return (await item.getProperty("_isVisible")) ? item : null; + })); + + // filter out null values + return filteredItems.filter(item => item !== null); +}; + +const getVisibleGroupItems = async (combo) => { + const items = await combo.$$("ui5-cb-item-group"); + const filteredItems = await Promise.all(items.map(async item => { + return (await item.getProperty("_isVisible")) ? item : null; + })); + + // filter out null values + return filteredItems.filter(item => item !== null); +}; + describe("General interaction", () => { it ("Should open the popover when clicking on the arrow", async () => { @@ -31,33 +51,31 @@ describe("General interaction", () => { it ("Items filtration", async () => { await browser.url(`test/pages/ComboBox.html`); - const combo = await browser.$("#combo"); + const combo = await $("#combo"); const arrow = await combo.shadow$(".inputIcon"); const input = await combo.shadow$("#ui5-combobox-input"); - const popover = await combo.shadow$("ui5-responsive-popover"); - let listItems = await popover.$("ui5-list").$$("ui5-li"); + let listItems = await combo.$$("ui5-cb-item"); // act await arrow.click(); // assert - assert.strictEqual(listItems.length, 11, "All items are shown with selected item"); + assert.strictEqual((await getVisibleItems(combo)).length, 11, "All items are shown with selected item"); // act await input.click(); await browser.keys("Backspace"); // assert - listItems = await popover.$("ui5-list").$$("ui5-li"); - assert.strictEqual(listItems.length, 1, "Items are filtered on input value change"); - + listItems = await combo.$$("ui5-cb-item"); + assert.strictEqual((await getVisibleItems(combo)).length, 1, "Items are filtered on input value change"); }); it ("Should open the popover when typing a value", async () => { await browser.url(`test/pages/ComboBox.html`); - const combo = await browser.$("#combo"); - const lazy = await browser.$("#lazy"); + const combo = await $("#combo"); + const lazy = await $("#lazy"); const input = await combo.shadow$("#ui5-combobox-input"); const popover = await combo.shadow$("ui5-responsive-popover"); @@ -77,7 +95,7 @@ describe("General interaction", () => { }); assert.strictEqual(selection, "ahrain", "ahrain should be selected"); - const listItems = await popover.$("ui5-list").$$("ui5-li"); + const listItems = (await getVisibleItems(combo)); assert.ok(await listItems[0].getProperty("selected"), "List Item should be selected"); await lazy.click(); @@ -91,7 +109,7 @@ describe("General interaction", () => { const combo = await browser.$("#cb-filter-none"); const input = await combo.shadow$("#ui5-combobox-input"); const popover = await combo.shadow$("ui5-responsive-popover"); - let listItems = await popover.$("ui5-list").$$("ui5-li"); + let listItems = await combo.$$("ui5-cb-item"); // act await input.click(); @@ -100,7 +118,7 @@ describe("General interaction", () => { await input.keys("I"); setTimeout(async () => { - listItems = await popover.$("ui5-list").$$("ui5-li"); + listItems = await getVisibleItems(combo); const firstListItemText = await listItems[0].shadow$(".ui5-li-title").getText(); // assert @@ -116,7 +134,7 @@ describe("General interaction", () => { const arrow = await combo.shadow$(".inputIcon"); const input = await combo.shadow$("#ui5-combobox-input"); const popover = await combo.shadow$("ui5-responsive-popover"); - let listItems = await popover.$("ui5-list").$$("ui5-li"); + let listItems = await combo.$$("ui5-cb-item"); // act await arrow.click(); @@ -128,21 +146,21 @@ describe("General interaction", () => { await input.keys("a"); // assert - listItems = await popover.$("ui5-list").$$("ui5-li"); + listItems = await getVisibleItems(combo); assert.strictEqual(listItems.length, 5, "Items should be 5"); // act await input.keys("u"); // assert - listItems = await popover.$("ui5-list").$$("ui5-li"); + listItems = await getVisibleItems(combo); // assert.strictEqual(listItems.length, 2, "Items should be 2"); // act await input.keys("z"); await input.keys("z"); await input.keys("z"); - listItems = await popover.$("ui5-list").$$("ui5-li"); + listItems = await getVisibleItems(combo); // assert assert.notOk(listItems.some(item => item._isVisible), "Rendered items should be 0"); @@ -152,11 +170,11 @@ describe("General interaction", () => { it ("Should close popover on item click / change event", async () => { await browser.url(`test/pages/ComboBox.html`); - const combo = await browser.$("#combo2"); + const combo = await $("#combo2"); const arrow = await combo.shadow$(".inputIcon"); const input = await combo.shadow$("#ui5-combobox-input"); const popover = await combo.shadow$("ui5-responsive-popover"); - let listItems = await popover.$("ui5-list").$$("ui5-li"); + let listItems = await getVisibleItems(combo); // act await input.click(); @@ -176,8 +194,8 @@ describe("General interaction", () => { assert.ok(await popover.getProperty("open"), "Popover should be displayed") - listItems = await popover.$("ui5-list").$$("ui5-li"); - await listItems[0].click(); + listItems = await getVisibleItems(combo); + await (await listItems[0].shadow$("li")).click(); // assert assert.notOk(await popover.getProperty("open"), "Popover should be closed"); @@ -220,11 +238,11 @@ describe("General interaction", () => { const placeholder = await browser.$("#change-placeholder"); const arrow = await combo.shadow$(".inputIcon"); + await combo.scrollIntoView(); await arrow.click(); // click on first item - const popover = await combo.shadow$("ui5-responsive-popover"); - await (await popover.$("ui5-list").$$("ui5-li")[0]).click(); + await (await combo.$$("ui5-cb-item"))[0].click(); assert.strictEqual(await placeholder.getText(), "Argentina", "Text should not be empty"); assert.strictEqual(await counter.getText(), "1", "Call count should be 1"); @@ -233,7 +251,7 @@ describe("General interaction", () => { assert.strictEqual(await counter.getText(), "1", "Call count should be 1"); - await (await popover.$("ui5-list").$$("ui5-li"))[1].click(); + await (await combo.$$("ui5-cb-item"))[1].click(); assert.strictEqual(await counter.getText(), "2", "Call count should be 2"); }); @@ -263,7 +281,6 @@ describe("General interaction", () => { assert.strictEqual(await counter.getText(), "0", "Call count should be 0"); // click on first item - const popover = await combo.shadow$("ui5-responsive-popover"); const link = await combo.$("div[slot='valueStateMessage'] a"); await link.click(); @@ -306,27 +323,26 @@ describe("General interaction", () => { }); it("should fire change event after the user has typed in value, but also selects it from the popover", async () => { - await browser.url(`test/pages/ComboBox.html`); + await browser.url(`test/pages/ComboBox.html`); // Setup const changeValue = await browser.$("#change-placeholder"); - const counter = await browser.$("#change-count"); - const combo = await browser.$("#change-cb"); + const counter = await browser.$("#change-count"); + const combo = await browser.$("#change-cb"); const input = await combo.shadow$("[inner-input]"); + await combo.scrollIntoView(); // Type something which is in the list await input.click(); await input.keys("Bulgaria"); // Click on the item - const popover = await combo.shadow$("ui5-responsive-popover"); - await (await popover.$("ui5-list").$$("ui5-li")[0]).click(); - + await ((await getVisibleItems(combo))[0]).click(); assert.strictEqual(await counter.getText(), "1", "Call count should be 1"); assert.strictEqual(await changeValue.getText(), "Bulgaria", "The value should be changed accordingly"); - }); + }); it ("Value should be reset on ESC key", async () => { await browser.url(`test/pages/ComboBox.html`); @@ -370,8 +386,7 @@ describe("General interaction", () => { assert.strictEqual(await counter.getText(), "0", "Change event should not be fired on item navigation."); - const popover = await combo.shadow$("ui5-responsive-popover"); - await (await popover.$("ui5-list").$$("ui5-li"))[0].click(); + await (await combo.$$("ui5-cb-item"))[0].click(); assert.strictEqual(await counter.getText(), "1", "Change event should be fired on item selection."); }); @@ -400,17 +415,20 @@ describe("General interaction", () => { it ("Tests change event after type and item select", async () => { await browser.url(`test/pages/ComboBox.html`); - const counter = await browser.$("#change-count"); - const combo = await browser.$("#change-cb"); + const counter = await $("#change-count"); + const combo = await $("#change-cb"); const input = await combo.shadow$("[inner-input]"); - const placeholder = await browser.$("#change-placeholder"); + const placeholder = await $("#change-placeholder"); + + await combo.scrollIntoView(); await input.click(); await input.keys("a"); // click on first item - const popover = await combo.shadow$("ui5-responsive-popover"); - await (await popover.$("ui5-list").$$("ui5-li"))[0].click(); + const items = await getVisibleItems(combo); + + await items[0].click(); assert.strictEqual(await placeholder.getText(), "Argentina", "Text should correspond to item."); assert.strictEqual(await counter.getText(), "1", "Call count should be 1"); @@ -450,23 +468,22 @@ describe("General interaction", () => { const combo = await browser.$("#contains-cb"); const input = await combo.shadow$("#ui5-combobox-input"); const arrow = await combo.shadow$(".inputIcon"); - const popover = await combo.shadow$("ui5-responsive-popover"); - let listItems = await popover.$("ui5-list").$$("ui5-li"); - await arrow.click(); + let listItems = await getVisibleItems(combo); + assert.strictEqual(listItems.length, 4, "Items should be 4"); await input.keys("n"); - listItems = await popover.$("ui5-list").$$("ui5-li"); + listItems = await getVisibleItems(combo); assert.strictEqual(listItems.length, 3, "Items should be 3"); await input.keys("a"); - listItems = await popover.$("ui5-list").$$("ui5-li"); + listItems = await getVisibleItems(combo); assert.strictEqual(listItems.length, 2, "Items should be 2"); await input.keys("d"); - listItems = await popover.$("ui5-list").$$("ui5-li"); + listItems = await getVisibleItems(combo); const firstListItemText = await listItems[0].shadow$(".ui5-li-title").getText(); assert.strictEqual(listItems.length, 1, "Items should be 1"); @@ -478,21 +495,21 @@ describe("General interaction", () => { const input = await combo.shadow$("#ui5-combobox-input"); const arrow = await combo.shadow$(".inputIcon"); const popover = await combo.shadow$("ui5-responsive-popover"); - let listItems = await popover.$("ui5-list").$$("ui5-li"); await arrow.click(); + let listItems = await getVisibleItems(combo); assert.strictEqual(listItems.length, 4, "Items should be 4"); await input.keys("a"); - listItems = await popover.$("ui5-list").$$("ui5-li"); + listItems = await getVisibleItems(combo); const firstListItemText = await listItems[0].shadow$(".ui5-li-title").getText(); assert.strictEqual(listItems.length, 1, "Items should be 1"); assert.strictEqual(firstListItemText, "Argentina"); await input.keys("a"); - listItems = await popover.$("ui5-list").$$("ui5-li"); + listItems = await combo.$$("ui5-cb-item"); assert.notOk(popover.open, "Popover should be closed when no match"); }); @@ -501,7 +518,7 @@ describe("General interaction", () => { const label = await browser.$("#selection-change-event-result"); const arrow = await combo.shadow$(".inputIcon"); const popover = await combo.shadow$("ui5-responsive-popover"); - let listItems = await popover.$("ui5-list").$$("ui5-li"); + let listItems = await combo.$$("ui5-cb-item"); await arrow.click(); @@ -518,7 +535,7 @@ describe("General interaction", () => { let label = await browser.$("#selection-change-event-result"); const arrow = await combo.shadow$(".inputIcon"); const popover = await combo.shadow$("ui5-responsive-popover"); - let listItems = await popover.$("ui5-list").$$("ui5-li"); + let listItems = await combo.$$("ui5-cb-item"); await arrow.click(); await combo.keys("Backspace"); @@ -556,10 +573,9 @@ describe("General interaction", () => { }); it ("Tests Combo with two-column layout", async () => { - const combo = await browser.$("#combobox-two-column-layout"); + const combo = await $("#combobox-two-column-layout"); const arrow = await combo.shadow$(".inputIcon"); - const popover = await combo.shadow$("ui5-responsive-popover"); - const listItem = await popover.$("ui5-list").$$("ui5-li")[0]; + const listItem = (await getVisibleItems(combo))[0]; await arrow.click(); assert.strictEqual(await listItem.shadow$(".ui5-li-additional-text").getText(), "DZ", "Additional item text should be displayed"); @@ -585,11 +601,11 @@ describe("General interaction", () => { await btn.click(); await arrow.click(); - const initialListItems = await cb.shadow$("ui5-responsive-popover").$$("ui5-li"); + const initialListItems = await getVisibleItems(cb); await browser.pause(2000); - const updatedListItems = await cb.shadow$("ui5-responsive-popover").$$("ui5-li"); + const updatedListItems = await getVisibleItems(cb); assert.notEqual(initialListItems.length, updatedListItems.length, "item count should be updated"); }); @@ -638,8 +654,7 @@ describe("General interaction", () => { await input.keys("z"); await arrow.click(); - const popover = await cb.shadow$("ui5-responsive-popover"); - let listItems = await popover.$("ui5-list").$$("ui5-li"); + let listItems = await getVisibleItems(cb); // assert assert.strictEqual(listItems.length, 11, "All items are shown"); @@ -647,67 +662,59 @@ describe("General interaction", () => { }); describe("Grouping", () => { - - it ("Tests group filtering", async () => { + beforeEach(async () => { await browser.url(`test/pages/ComboBox.html`); + }); - const combo = await browser.$("#combo-grouping"); + it ("Tests group filtering", async () => { + const combo = await $("#combo-grouping"); const input = await combo.shadow$("#ui5-combobox-input"); const arrow = await combo.shadow$(".inputIcon"); - let popover = await combo.shadow$("ui5-responsive-popover"); let listItems; let groupItems; await arrow.click(); - groupItems = await popover.$("ui5-list").$$("ui5-li-group"); - listItems = await popover.$("ui5-list").$$("ui5-li-group ui5-li"); + groupItems = (await getVisibleGroupItems(combo)); + listItems = (await getVisibleItems(combo)); assert.strictEqual(groupItems.length, 4, "Group items should be 4"); assert.strictEqual(listItems.length, 13, "Items should be 13"); await input.keys("c"); - popover = await combo.shadow$("ui5-responsive-popover"); - groupItems = await popover.$("ui5-list").$$("ui5-li-group"); - listItems = await popover.$("ui5-list").$$("ui5-li"); + groupItems = (await getVisibleGroupItems(combo)); + listItems = (await getVisibleItems(combo)); assert.strictEqual(groupItems.length, 1, "Filtered group items should be 1"); assert.strictEqual(listItems.length, 2, "Filtered items should be 2"); }); it ("Tests group item focusability", async () => { - await browser.url(`test/pages/ComboBox.html`); - const combo = await browser.$("#combo-grouping"); const input = await combo.shadow$("#ui5-combobox-input"); const arrow = await combo.shadow$(".inputIcon"); - const popover = await combo.shadow$("ui5-responsive-popover"); - let groupItem; await arrow.click(); await input.keys("ArrowDown"); - groupItem = await popover.$("ui5-list").$("ui5-li-group").shadow$("ui5-li-group-header"); + const groupItem = (await getVisibleGroupItems(combo))[0]; assert.ok(await groupItem.getProperty("focused"), "The first group header should be focused"); }); it ("Tests input value while group item is focused", async () => { - const combo = await browser.$("#combo-grouping"); + const combo = await $("#combo-grouping"); const input = await combo.shadow$("#ui5-combobox-input"); - const popover = await combo.shadow$("ui5-responsive-popover"); - let groupItem; + await input.click(); await input.keys("a"); await input.keys("ArrowDown"); await input.keys("ArrowDown"); await input.keys("ArrowDown"); await input.keys("ArrowDown"); - await input.keys("ArrowDown"); - await input.keys("ArrowDown"); - groupItem = await popover.$("ui5-list").$$("ui5-li-group")[1]; + const groupItem = (await getVisibleGroupItems(combo))[1]; assert.ok(await groupItem.getProperty("focused"), "The second group header should be focused"); assert.strictEqual(await combo.getProperty("filterValue"), "a", "Filter value should be the initial one"); @@ -715,14 +722,12 @@ describe("Grouping", () => { }); it ("Pressing enter on a group item should not close the picker", async () => { - await browser.url(`test/pages/ComboBox.html`); - const combo = await browser.$("#combo-grouping"); + const arrow = await combo.shadow$(".inputIcon"); const input = await combo.shadow$("#ui5-combobox-input"); const popover = await combo.shadow$("ui5-responsive-popover"); - await input.click(); - await input.keys("a"); + await arrow.click(); await input.keys("ArrowDown"); await input.keys("Enter"); @@ -730,21 +735,20 @@ describe("Grouping", () => { }); it ("Grouped items should be filtered and with the correct role attributes", async () => { - await browser.url(`test/pages/ComboBox.html`); - - const combo = await browser.$("#combo-grouping"); + const combo = await $("#combo-grouping"); const input = await combo.shadow$("#ui5-combobox-input"); const popover = await combo.shadow$("ui5-responsive-popover"); const list = await popover.$("ui5-list"); - const listItem = await list.$("ui5-li"); await input.click(); await input.keys("a"); + const listItem = (await getVisibleItems(combo))[0]; + assert.ok(await listItem, "The filtered item is shown"); assert.strictEqual(await list.getAttribute("accessible-role"), "ListBox", "The list item has the correct role attribute"); - assert.strictEqual(await listItem.getAttribute("accessible-role"), "Option", "The list item has the correct role attribute"); - assert.strictEqual(await list.$$("ui5-li").length, 5, "Group items are filtered correctly"); + assert.strictEqual(await listItem.shadow$("li").getAttribute("role"), "option", "The list item has the correct role attribute"); + assert.strictEqual((await getVisibleItems(combo)).length, 5, "Group items are filtered correctly"); }); }); @@ -757,8 +761,8 @@ describe("Accessibility", async () => { const arrow = await combo.shadow$(".inputIcon"); const input = await combo.shadow$("#ui5-combobox-input"); const invisibleMessageSpan = await browser.$(".ui5-invisiblemessage-polite"); - const itemAnnouncement1 = "List item 1 of 11"; - const itemAnnouncement2 = "List item 2 of 11"; + const itemAnnouncement1 = "List item 10 of 11"; + const itemAnnouncement2 = "List item 11 of 11"; await arrow.click(); @@ -798,8 +802,8 @@ describe("Accessibility", async () => { const arrow = await combo.shadow$(".inputIcon"); const input = await combo.shadow$("#ui5-combobox-input"); const invisibleMessageSpan = await browser.$(".ui5-invisiblemessage-polite"); - const itemAnnouncement1 = "DZ List item 1 of 10"; - const itemAnnouncement2 = "AR List item 2 of 10"; + const itemAnnouncement1 = "CA List item 9 of 10"; + const itemAnnouncement2 = "CL List item 10 of 10"; await arrow.click(); @@ -934,27 +938,28 @@ describe("Accessibility", async () => { const combo = await browser.$("#combo"); const innerInput = await combo.shadow$("input"); const popover = await combo.shadow$("ui5-responsive-popover"); - + await combo.scrollIntoView(); - + assert.strictEqual(await innerInput.getAttribute("aria-controls"), await popover.getAttribute("id"), "aria-controls attribute is correct."); }); }); describe("Keyboard navigation", async () => { - it ("Should focus the first item on arrow down and then the input on arrow up", async () => { + beforeEach(async () => { await browser.url(`test/pages/ComboBox.html`); + }); - const combo = await browser.$("#combo-grouping"); + it ("Should focus the first item on arrow down and then the input on arrow up", async () => { + const combo = await $("#combo-grouping"); const input = await combo.shadow$("#ui5-combobox-input"); const arrow = await combo.shadow$(".inputIcon"); - const popover = await combo.shadow$("ui5-responsive-popover"); let groupItem, listItem; await arrow.click(); await input.keys("ArrowDown"); - groupItem = await popover.$("ui5-list").$$("ui5-li-group")[0]; + groupItem = (await getVisibleGroupItems(combo))[0]; assert.strictEqual(await groupItem.getProperty("focused"), true, "The first group header should be focused"); @@ -964,7 +969,7 @@ describe("Keyboard navigation", async () => { await input.keys("ArrowDown"); await input.keys("ArrowDown"); - listItem = await popover.$("ui5-list").$("ui5-li-group ui5-li"); + listItem = (await getVisibleItems(combo))[0]; assert.strictEqual(await listItem.getProperty("focused"), true, "The first list item after the group header should be focused"); @@ -976,7 +981,7 @@ describe("Keyboard navigation", async () => { it ("Should focus the value state header and then the input", async () => { await browser.url(`test/pages/ComboBox.html`); - const combo = await browser.$("#value-state-grouping"); + const combo = await $("#value-state-grouping"); const input = await combo.shadow$("#ui5-combobox-input"); const arrow = await combo.shadow$(".inputIcon"); const popover = await combo.shadow$("ui5-responsive-popover"); @@ -999,7 +1004,7 @@ describe("Keyboard navigation", async () => { await input.keys("ArrowDown"); await input.keys("ArrowDown"); - groupItem = await popover.$("ui5-list").$("ui5-li-group"); + groupItem = (await getVisibleGroupItems(combo))[0]; assert.strictEqual(await groupItem.getProperty("focused"), true, "The first group header should be focused"); }); @@ -1007,16 +1012,15 @@ describe("Keyboard navigation", async () => { it ("Previous focus should not remain on the item after reopening the picker and choosing another one", async () => { await browser.url(`test/pages/ComboBox.html`); - const combo = await browser.$("#value-state-grouping"); + const combo = await $("#value-state-grouping"); const input = await combo.shadow$("#ui5-combobox-input"); const arrow = await combo.shadow$(".inputIcon"); - const popover = await combo.shadow$("ui5-responsive-popover"); let listItem, prevListItem; await input.click(); await input.keys("A"); - listItem = await popover.$("ui5-list").$$("ui5-li")[1]; + listItem = (await getVisibleItems(combo))[1]; assert.strictEqual(await listItem.getProperty("focused"), false, "The selected item is not focused"); @@ -1034,12 +1038,12 @@ describe("Keyboard navigation", async () => { await arrow.click(); - listItem = await popover.$("ui5-list").$$("ui5-li")[3]; + listItem = (await getVisibleItems(combo))[3]; await listItem.click(); await arrow.click(); - prevListItem = await popover.$("ui5-list").$$("ui5-li")[5]; + prevListItem = (await getVisibleItems(combo))[5]; assert.strictEqual(await prevListItem.getProperty("focused"), false, "The previously focused item is no longer focused"); }); @@ -1050,7 +1054,6 @@ describe("Keyboard navigation", async () => { const combo = await browser.$("#value-state-grouping"); const input = await combo.shadow$("#ui5-combobox-input"); const arrow = await combo.shadow$(".inputIcon"); - const popover = await combo.shadow$("ui5-responsive-popover"); let prevListItem; await input.click(); @@ -1076,7 +1079,7 @@ describe("Keyboard navigation", async () => { await arrow.click(); - prevListItem = await popover.$("ui5-list").$$("ui5-li")[5]; + prevListItem = (await getVisibleItems(combo))[5]; assert.strictEqual(await prevListItem.getProperty("focused"), false, "The previously focused item is no longer focused"); }); @@ -1129,7 +1132,6 @@ describe("Keyboard navigation", async () => { const comboBox = await browser.$("#combo2"); const input = await comboBox.shadow$("#ui5-combobox-input"); const pickerIcon = await comboBox.shadow$(".inputIcon"); - const respPopover = await comboBox.shadow$("ui5-responsive-popover"); let listItem; // Opened picker @@ -1138,20 +1140,20 @@ describe("Keyboard navigation", async () => { await input.keys("ArrowDown"); await input.keys("Home"); - listItem = await respPopover.$("ui5-list").$("ui5-li"); + listItem = (await getVisibleItems(comboBox))[0]; assert.strictEqual(await listItem.getProperty("focused"), true, "The first item should be focused on HOME"); assert.strictEqual(await comboBox.getProperty("focused"), false, "The ComboBox should not be focused"); await input.keys("End"); - listItem = await respPopover.$("ui5-list").$$("ui5-li")[10]; + listItem = (await getVisibleItems(comboBox))[10]; assert.strictEqual(await listItem.getProperty("focused"), true, "The last item should be focused on END"); await input.keys("PageUp"); - listItem = await respPopover.$("ui5-list").$("ui5-li"); + listItem = (await getVisibleItems(comboBox))[0]; assert.strictEqual(await listItem.getProperty("focused"), true, "The -10 item should be focused on PAGEUP"); await input.keys("PageDown"); - listItem = await respPopover.$("ui5-list").$$("ui5-li")[10]; + listItem = (await getVisibleItems(comboBox))[10]; assert.strictEqual(await listItem.getProperty("focused"), true, "The +10 item should be focused on PAGEDOWN"); // Closed picker @@ -1224,7 +1226,7 @@ describe("Keyboard navigation", async () => { assert.strictEqual(await input.getProperty("value"), "Argentina", "Value should be Argentina"); - const listItems = await popover.$("ui5-list").$$("ui5-li"); + const listItems = await getVisibleItems(comboBox); assert.ok(await listItems[0].getProperty("selected"), "List Item should be selected"); assert.notOk(await listItems[1].getProperty("selected"), "List Item should not be selected"); @@ -1233,15 +1235,14 @@ describe("Keyboard navigation", async () => { it("Should select the matching item when input has matching value and F4 is pressed", async () => { await browser.url(`test/pages/ComboBox.html`); - const comboBox = await browser.$("#combo"); + const comboBox = await $("#combo"); const input = await comboBox.shadow$("#ui5-combobox-input"); const value = await input.getProperty("value"); await comboBox.click(); await comboBox.keys("F4"); - const popover = await comboBox.shadow$("ui5-responsive-popover"); - const selectedListItem = await popover.$("ui5-list").$("ui5-li[selected]"); + const selectedListItem = (await getVisibleItems(comboBox))[8]; assert.strictEqual(await selectedListItem.shadow$(".ui5-li-title").getText(), value, "Selected item is correct."); }); @@ -1257,6 +1258,7 @@ describe("Keyboard navigation", async () => { await comboBox.keys("F4"); + const popover = await comboBox.shadow$("ui5-responsive-popover"); const selectedListItems = await popover.$("ui5-list").$$("ui5-li[selected]"); @@ -1275,8 +1277,7 @@ describe("Keyboard navigation", async () => { await input.click(); await comboBox.keys("F4"); - const popover = await comboBox.shadow$("ui5-responsive-popover"); - const listItems = await popover.$("ui5-list").$$("ui5-li"); + const listItems = await getVisibleItems(comboBox); const firstListItemText = await listItems[0].shadow$(".ui5-li-title").getText(); value = await input.getProperty("value"); @@ -1295,8 +1296,7 @@ describe("Keyboard navigation", async () => { await input.click(); await comboBox.keys("F4"); - const popover = await comboBox.shadow$("ui5-responsive-popover"); - const listItems = await popover.$("ui5-list").$$("ui5-li"); + const listItems = await getVisibleItems(comboBox); const firstListItemText = await listItems[0].shadow$(".ui5-li-title").getText(); value = await input.getProperty("value"); @@ -1375,15 +1375,15 @@ describe("Keyboard navigation", async () => { const input = await combo.shadow$("#ui5-combobox-input"); const arrow = await combo.shadow$(".inputIcon"); - await combo.scrollIntoView(); + await combo.scrollIntoView(); await arrow.click(); let isInVisibleArea = await browser.executeAsync(async done => { const combobox = document.getElementById("combo-grouping"); const picker = await combobox._getPicker(); - const listItem = picker.querySelector(".ui5-combobox-items-list ui5-li-group:last-child ui5-li:last-child"); + const listItem = combobox.querySelector("ui5-cb-item-group:last-child ui5-cb-item:last-child"); const scrollableRect = picker.shadowRoot.querySelector(".ui5-popup-content").getBoundingClientRect(); const elementRect = listItem.getBoundingClientRect(); @@ -1406,13 +1406,15 @@ describe("Keyboard navigation", async () => { assert.notOk(isInVisibleArea, "Item should not be displayed in the viewport"); // click ArrowDown 16 times - await input.keys(["ArrowDown", "ArrowDown", "ArrowDown", "ArrowDown", "ArrowDown", "ArrowDown", "ArrowDown", "ArrowDown"]); - await input.keys(["ArrowDown", "ArrowDown", "ArrowDown", "ArrowDown", "ArrowDown", "ArrowDown", "ArrowDown", "ArrowDown"]); + for (let i = 0; i < 16; i++) { + await browser.keys("ArrowDown"), + await browser.pause(10); + } isInVisibleArea = await browser.executeAsync(async done => { const combobox = document.getElementById("combo-grouping"); const picker = await combobox._getPicker(); - const listItem = picker.querySelector(".ui5-combobox-items-list ui5-li-group:last-child ui5-li:last-child"); + const listItem = combobox.querySelector("ui5-cb-item-group:last-child ui5-cb-item:last-child"); const scrollableRect = picker.shadowRoot.querySelector(".ui5-popup-content").getBoundingClientRect(); const elementRect = listItem.getBoundingClientRect(); @@ -1439,7 +1441,7 @@ describe("Keyboard navigation", async () => { let isFirstItemInVisibleArea = await browser.executeAsync(async done => { const combobox = document.getElementById("combo-grouping"); const picker = await combobox._getPicker(); - const firstListItem = picker.querySelector(".ui5-combobox-items-list ui5-li-group:first-child ui5-li:first-child"); + const firstListItem = combobox.querySelector("ui5-cb-item-group:first-child ui5-cb-item:first-child"); const scrollableRect = picker.shadowRoot.querySelector(".ui5-popup-content").getBoundingClientRect(); const firstItemBoundingClientRect = firstListItem.getBoundingClientRect(); @@ -1457,14 +1459,14 @@ describe("Keyboard navigation", async () => { ); done(isFirstItemInVisibleArea); - }); + }); assert.ok(isFirstItemInVisibleArea, "The first item should be displayed in the viewport"); let isLastItemInVisibleArea = await browser.executeAsync(async done => { const combobox = document.getElementById("combo-grouping"); const picker = await combobox._getPicker(); - const lastListItem = picker.querySelector(".ui5-combobox-items-list ui5-li-group:first-child ui5-li:first-child"); + const lastListItem = combobox.querySelector("ui5-cb-item-group:first-child ui5-cb-item:first-child"); const scrollableRect = picker.shadowRoot.querySelector(".ui5-popup-content").getBoundingClientRect(); const lastItemBoundingClientRect = lastListItem.getBoundingClientRect(); @@ -1482,7 +1484,7 @@ describe("Keyboard navigation", async () => { ); done(isLastItemInVisibleArea); - }); + }); assert.ok(isLastItemInVisibleArea, "The first item should be displayed in the viewport"); }); diff --git a/packages/main/test/specs/MultiComboBox.mobile.spec.js b/packages/main/test/specs/MultiComboBox.mobile.spec.js index fa5f394f05e5..edc545397cc7 100644 --- a/packages/main/test/specs/MultiComboBox.mobile.spec.js +++ b/packages/main/test/specs/MultiComboBox.mobile.spec.js @@ -1,5 +1,15 @@ import { assert } from "chai"; +const getVisibleItems = async (id) => { + const slottedItems = await browser.executeAsync((mcbId, done) => { + const mcb = document.getElementById(mcbId); + + done(mcb.shadowRoot.querySelector(".ui5-multi-combobox-all-items-list").getSlottedNodes("items")); + }, id); + + return slottedItems; +}; + describe("Basic interaction", () => { before(async () => { await browser.url(`test/pages/MultiComboBox.html`); @@ -93,7 +103,7 @@ describe("Basic interaction", () => { const toggleSelectedButton = await multiCombo.shadow$("ui5-responsive-popover").$("ui5-toggle-button"); assert.strictEqual(await toggleSelectedButton.getAttribute("pressed"), "", "Toggle selected items button is pressed"); - const itemsCount = await multiCombo.shadow$("ui5-responsive-popover").$("ui5-list").$$("ui5-li") + const itemsCount = (await getVisibleItems("multi1")); assert.strictEqual(itemsCount.length, 3, "Only the selected items are shown"); }); @@ -104,7 +114,7 @@ describe("Basic interaction", () => { toggleSelectedButton.click(); - const itemsCount = await multiCombo.shadow$("ui5-responsive-popover").$("ui5-list").$$("ui5-li") + const itemsCount = await multiCombo.$$(`ui5-mcb-item`); assert.strictEqual(itemsCount.length, 4, "All items are shown"); const dialogCloseButton = await multiCombo.shadow$("ui5-responsive-popover").$(".ui5-responsive-popover-close-btn"); @@ -223,7 +233,7 @@ describe("Items selection", () => { await multiCombo.scrollIntoView(); await mcbInput.click(); - const listItem = await multiCombo.shadow$("ui5-responsive-popover").$$("ui5-li")[0]; + const listItem = await multiCombo.$$("ui5-mcb-item")[0]; await listItem.click(); const token = await multiCombo.shadow$("ui5-tokenizer").$("ui5-token"); @@ -237,7 +247,7 @@ describe("Items selection", () => { await multiCombo.scrollIntoView(); await mcbInput.click(); - const listItemCheckbox = await multiCombo.shadow$("ui5-responsive-popover").$$("ui5-li")[1].shadow$("ui5-checkbox"); + const listItemCheckbox = await multiCombo.$$("ui5-mcb-item")[1].shadow$("ui5-checkbox"); await listItemCheckbox.click(); const dialogOkButton = await multiCombo.shadow$("ui5-responsive-popover").$(".ui5-responsive-popover-footer").$("ui5-button"); @@ -254,7 +264,7 @@ describe("Items selection", () => { await multiCombo.scrollIntoView(); await mcbInput.click(); - const listItemCheckbox = await multiCombo.shadow$("ui5-responsive-popover").$$("ui5-li")[2].shadow$("ui5-checkbox"); + const listItemCheckbox = await multiCombo.$$("ui5-mcb-item")[2].shadow$("ui5-checkbox"); await listItemCheckbox.click(); const dialogCloseButton = await multiCombo.shadow$("ui5-responsive-popover").$(".ui5-responsive-popover-close-btn"); @@ -270,10 +280,10 @@ describe("Items selection", () => { await multiCombo.scrollIntoView(); await multiCombo.shadow$('ui5-tokenizer').shadow$(".ui5-tokenizer-more-text").click(); - const listItemCheckbox = await multiCombo.shadow$("ui5-responsive-popover").$$("ui5-li")[0].shadow$("ui5-checkbox"); + const listItemCheckbox = await multiCombo.$$("ui5-mcb-item")[0].shadow$("ui5-checkbox"); await listItemCheckbox.click(); - const listItem = await multiCombo.shadow$("ui5-responsive-popover").$$("ui5-li")[1]; + const listItem = await multiCombo.$$("ui5-mcb-item")[2]; await listItem.click(); const dialogOkButton = await multiCombo.shadow$("ui5-responsive-popover").$(".ui5-responsive-popover-footer").$("ui5-button"); @@ -294,7 +304,7 @@ describe("Items selection", () => { const toggleSelectedButton = await multiCombo.shadow$("ui5-responsive-popover").$("ui5-toggle-button"); await toggleSelectedButton.click(); - const listItem = await multiCombo.shadow$("ui5-responsive-popover").$$("ui5-li")[1]; + const listItem = await multiCombo.$$("ui5-mcb-item")[1]; await listItem.click(); const dialogOkButton = await multiCombo.shadow$("ui5-responsive-popover").$(".ui5-responsive-popover-footer").$("ui5-button"); @@ -341,12 +351,11 @@ describe("Items selection", () => { it("should not close the dialog on checkbox click", async () => { const mcb = await $("#mcb-select-all-vs"); - const popover = await mcb.shadow$("ui5-responsive-popover"); await mcb.scrollIntoView(); await mcb.click(); - const listItemCheckbox = await popover.$$("ui5-li")[0].shadow$("ui5-checkbox"); + const listItemCheckbox = await mcb.$("ui5-mcb-item").shadow$("ui5-checkbox"); await listItemCheckbox.click(); assert.strictEqual(await mcb.getProperty("open"), true, "Mobile dialog is not closed on checkbox click"); @@ -386,7 +395,7 @@ describe("Eventing", () => { await multiCombo.scrollIntoView(); await mcbInput.click(); - const listItem = await multiCombo.shadow$("ui5-responsive-popover").$$("ui5-li")[0]; + const listItem = await multiCombo.$$("ui5-mcb-item")[0]; await listItem.click(); assert.strictEqual(await browser.$("#events-input").getValue(), "selectionChange", "The correct event was fired"); @@ -401,7 +410,7 @@ describe("Eventing", () => { await multiCombo.scrollIntoView(); await mcbInput.click(); - const listItemCheckbox = await multiCombo.shadow$("ui5-responsive-popover").$$("ui5-li")[1].shadow$("ui5-checkbox"); + const listItemCheckbox = await multiCombo.$$("ui5-mcb-item")[1].shadow$("ui5-checkbox"); await listItemCheckbox.click(); const dialogOkButton = await multiCombo.shadow$("ui5-responsive-popover").$(".ui5-responsive-popover-footer").$("ui5-button"); @@ -421,7 +430,7 @@ describe("Eventing", () => { await multiCombo.scrollIntoView(); await multiCombo.shadow$("ui5-icon").click(); - const listItemCheckbox = await multiCombo.shadow$("ui5-responsive-popover").$$("ui5-li")[2].shadow$("ui5-checkbox"); + const listItemCheckbox = await multiCombo.$$("ui5-mcb-item")[2].shadow$("ui5-checkbox"); await listItemCheckbox.click(); const dialogCloseButton = await multiCombo.shadow$("ui5-responsive-popover").$(".ui5-responsive-popover-close-btn"); @@ -442,7 +451,7 @@ describe("Eventing", () => { let tokens = await multiCombo.shadow$("ui5-tokenizer").$$("ui5-token"); assert.strictEqual(tokens.length, 1, "There should be only one token."); - const listItemCheckbox = await multiCombo.shadow$("ui5-responsive-popover").$$("ui5-li")[0].shadow$("ui5-checkbox"); + const listItemCheckbox = await multiCombo.$$("ui5-mcb-item")[0].shadow$("ui5-checkbox"); await listItemCheckbox.click(); const dialogOkButton = await multiCombo.shadow$("ui5-responsive-popover").$(".ui5-responsive-popover-footer").$("ui5-button"); diff --git a/packages/main/test/specs/MultiComboBox.spec.js b/packages/main/test/specs/MultiComboBox.spec.js index d6e006156e76..18d13866bc94 100644 --- a/packages/main/test/specs/MultiComboBox.spec.js +++ b/packages/main/test/specs/MultiComboBox.spec.js @@ -1,8 +1,28 @@ import { assert } from "chai"; +const getVisibleItems = async (combo) => { + const items = await combo.$$("ui5-mcb-item"); + const filteredItems = await Promise.all(items.map(async item => { + return (await item.getProperty("_isVisible")) ? item : null; + })); + + // filter out null values + return filteredItems.filter(item => item !== null); +}; + +const getVisibleGroupItems = async (combo) => { + const items = await combo.$$("ui5-mcb-item-group"); + const assignedItems = await Promise.all(items.map(async item => { + return (await item.getProperty("assignedSlot")) ? item : null; + })); + + return assignedItems.filter(item => item !== null); +}; + describe("MultiComboBox general interaction", () => { - before(async () => { + beforeEach(async () => { await browser.url(`test/pages/MultiComboBox.html`); + await browser.setWindowSize(1920, 1080); }); describe("toggling", () => { @@ -41,8 +61,6 @@ describe("MultiComboBox general interaction", () => { }); it("Apply focus", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#multi1"); const focusBtn = await browser.$("#focus-mcb"); @@ -76,8 +94,6 @@ describe("MultiComboBox general interaction", () => { }); it("Opens selected items Popover", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - await browser.setWindowSize(400, 1250); const mcb = await browser.$("#multi1"); const showMore = await mcb.shadow$(".ui5-multi-combobox-tokenizer").shadow$(".ui5-tokenizer-more-text"); @@ -90,9 +106,6 @@ describe("MultiComboBox general interaction", () => { }); it("Checks if tokenizer is expanded when adding items dynamically", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - await browser.setWindowSize(1920, 1080); - const btn = await $("#add"); const mcb = await $("#mcb-dynamic-selection"); @@ -109,8 +122,7 @@ describe("MultiComboBox general interaction", () => { const tokenizer = await mcb.shadow$("ui5-tokenizer"); const body = await browser.$(".multicombobox1auto"); const nMoreText = await tokenizer.shadow$(".ui5-tokenizer-more-text"); - const popover = await mcb.shadow$(".ui5-multi-combobox-all-items-responsive-popover"); - const firstItemCheckbox = await popover.$("ui5-list > ui5-li").shadow$("ui5-checkbox"); + const firstItemCheckbox = await mcb.$("ui5-mcb-item").shadow$("ui5-checkbox"); await arrow.click(); await browser.keys("ArrowDown"); @@ -132,7 +144,6 @@ describe("MultiComboBox general interaction", () => { describe("selection and filtering", () => { beforeEach(async () => { - await browser.url(`test/pages/MultiComboBox.html`); await browser.setWindowSize(1920, 1080); }); @@ -140,8 +151,8 @@ describe("MultiComboBox general interaction", () => { const mcb = await browser.$("#mcb"); const icon = await mcb.shadow$(".inputIcon"); const popover = await mcb.shadow$(".ui5-multi-combobox-all-items-responsive-popover"); - const firstItem = await popover.$("ui5-list > ui5-li"); - const firstItemCheckbox = await firstItem.shadow$("ui5-checkbox"); + const firstItem = await mcb.$("ui5-mcb-item"); + const firstItemCheckbox = await mcb.$("ui5-mcb-item").shadow$("ui5-checkbox"); const eventInput = await browser.$("#events-input"); const paramsInput = await browser.$("#events-parameters"); const callCountInput = await browser.$("#events-call-count"); @@ -173,7 +184,7 @@ describe("MultiComboBox general interaction", () => { const mcb = await browser.$("#mcb-success"); const icon = await browser.$("#mcb-success").shadow$(".inputIcon"); const popover = await mcb.shadow$(".ui5-multi-combobox-all-items-responsive-popover"); - const firstItem = await popover.$(".ui5-multi-combobox-all-items-list > ui5-li"); + const firstItem = await mcb.$("ui5-mcb-item"); await icon.click(); @@ -283,7 +294,7 @@ describe("MultiComboBox general interaction", () => { const mcb = await browser.$("#another-mcb"); const input = await browser.$("#another-mcb").shadow$("#ui5-multi-combobox-input"); const popover = await mcb.shadow$(".ui5-multi-combobox-all-items-responsive-popover"); - const firstItem = await popover.$(".ui5-multi-combobox-all-items-list > ui5-li"); + const firstItem = await mcb.$("ui5-mcb-item"); await input.click(); await input.keys("c"); @@ -302,7 +313,7 @@ describe("MultiComboBox general interaction", () => { const mcb = await browser.$("#another-mcb"); const input = await browser.$("#another-mcb").shadow$("#ui5-multi-combobox-input"); const popover = await mcb.shadow$(".ui5-multi-combobox-all-items-responsive-popover"); - const firstItemCheckbox = await popover.$(".ui5-multi-combobox-all-items-list > ui5-li").shadow$("ui5-checkbox"); + const firstItemCheckbox = await mcb.$("ui5-mcb-item").shadow$("ui5-checkbox"); await input.click(); await input.keys("c"); @@ -326,7 +337,6 @@ describe("MultiComboBox general interaction", () => { }); it("tests if clicking n more will prefilter items before opening the popover", async () => { - await browser.url(`test/pages/MultiComboBox.html`); await browser.setWindowSize(1920, 1080); const mcb = await $("#more-mcb"); @@ -364,8 +374,6 @@ describe("MultiComboBox general interaction", () => { }); it("tests if tokenizer is scrolled to the end when expanded and to start when narrowed", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await $("#more-mcb"); const input = mcb.shadow$("input"); @@ -382,8 +390,6 @@ describe("MultiComboBox general interaction", () => { }); it("tests if tokenizer is not expanded/collapsed when the suggestions are opened from a selected token", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await $("#more-mcb"); let tokenizer = await mcb.shadow$("ui5-tokenizer") let tokens = await browser.$("#more-mcb").shadow$$(".ui5-multi-combobox-token"); @@ -400,7 +406,6 @@ describe("MultiComboBox general interaction", () => { }) it("tests filtering of items when nmore popover is open and user types in the input fueld", async () => { - await browser.url(`test/pages/MultiComboBox.html`); await browser.setWindowSize(1920, 1080); const mcb = await $("#more-mcb"); @@ -411,16 +416,16 @@ describe("MultiComboBox general interaction", () => { const input = await mcb.shadow$("input"); await nMoreText.click(); + await input.click(); + await input.keys("c"); const popover = await mcb.shadow$(".ui5-multi-combobox-all-items-responsive-popover"); const list = await popover.$(".ui5-multi-combobox-all-items-list"); - const lastListItem = await list.$("ui5-li:last-child"); - - await input.click(); - await input.keys("c"); + const items = (await getVisibleItems(mcb)) + const lastItem = items[items.length - 1]; assert.strictEqual((await list.getProperty("items")).length, 3, "3 items should be shown (all selected)"); - assert.notOk(await lastListItem.getProperty("selected"), "last item should not be selected"); + assert.notOk(await lastItem.getProperty("selected"), "last item should not be selected"); }) it("tests if tokenizer is collapsed after focusout of the Popover", async () => { @@ -428,19 +433,20 @@ describe("MultiComboBox general interaction", () => { const input = await mcb.shadow$("#ui5-multi-combobox-input"); const tokenizer = await mcb.shadow$("ui5-tokenizer"); const popover = await mcb.shadow$(".ui5-multi-combobox-all-items-responsive-popover"); - const firstItemCheckbox = await popover.$(".ui5-multi-combobox-all-items-list > ui5-li").shadow$("ui5-checkbox"); - + await input.click(); await input.keys("Comp"); - + assert.ok(await popover.getProperty("open"), "The popover should be opened"); + + const visibleItems = await getVisibleItems(mcb); + const firstItemCheckbox = await visibleItems[0].shadow$("ui5-checkbox"); await firstItemCheckbox.click(); await firstItemCheckbox.click(); await browser.keys("Tab"); assert.notOk(await popover.getProperty("open"), "The popover should not be opened."); - assert.notOk(await tokenizer.getProperty("expanded"), "The tokenizer should be collapsed."); }); @@ -473,8 +479,6 @@ describe("MultiComboBox general interaction", () => { }); it("Should make a selection on ENTER and discard on ESC", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - let tokens; const mcb = await browser.$("#mcb"); @@ -497,13 +501,10 @@ describe("MultiComboBox general interaction", () => { }); it("should reset typeahead on item navigation and restore it on focus input", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb"); const input = await mcb.shadow$("input"); const icon = await mcb.shadow$(".inputIcon"); - const popover = await mcb.shadow$("ui5-responsive-popover"); - const listItem = await popover.$("ui5-li"); + const listItem = await mcb.$("ui5-mcb-item"); await icon.click(); await mcb.keys("c"); @@ -522,7 +523,6 @@ describe("MultiComboBox general interaction", () => { }); it("tests if clicking delete icon of a token removes it from the selection", async () => { - await browser.url(`test/pages/MultiComboBox.html`); await browser.setWindowSize(1920, 1080); const mcb = $("#mcb-long-token"); @@ -542,8 +542,6 @@ describe("MultiComboBox general interaction", () => { }); it("tests if clicking delete icon of a token removes it from the selection (mcb with grouping)", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = $("#mcb-grouping"); const inner = mcb.shadow$("input"); @@ -551,8 +549,7 @@ describe("MultiComboBox general interaction", () => { await inner.click(); await inner.keys("a"); - const popover = await mcb.shadow$("ui5-responsive-popover"); - const firstItem = await popover.$(".ui5-multi-combobox-all-items-list > ui5-li"); + const firstItem = (await getVisibleItems(mcb))[0]; await firstItem.click(); let tokens = await mcb.shadow$$(".ui5-multi-combobox-token"); @@ -570,12 +567,10 @@ describe("MultiComboBox general interaction", () => { }); it("prevents selection change event when clicking an item", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = $("#mcb-prevent"); const input = mcb.shadow$("#ui5-multi-combobox-input"); const popover = await mcb.shadow$(".ui5-multi-combobox-all-items-responsive-popover"); - const firstItem = await popover.$(".ui5-multi-combobox-all-items-list > ui5-li"); + const firstItem = (await getVisibleItems(mcb))[0]; const mcbTokens = await mcb.shadow$$(".ui5-multi-combobox-token"); assert.equal(mcbTokens.length, 1, "1 token is created."); @@ -594,8 +589,6 @@ describe("MultiComboBox general interaction", () => { }); it("prevents selection change event when deleting a token", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = $("#mcb-prevent"); let tokens = await mcb.shadow$$(".ui5-multi-combobox-token"); @@ -610,8 +603,6 @@ describe("MultiComboBox general interaction", () => { }); it("should prevent selection-change on CTRL+A", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = $("#mcb-prevent"); const input = await mcb.shadow$("input"); @@ -707,10 +698,6 @@ describe("MultiComboBox general interaction", () => { }); describe("keyboard handling", () => { - before(async () => { - await browser.url(`test/pages/MultiComboBox.html`); - }); - it("tests backspace when combobox has an empty value", async () => { let tokens = await browser.$("#multi1").shadow$$(".ui5-multi-combobox-token"); const input = await browser.$("#multi1").shadow$("input"); @@ -728,8 +715,6 @@ describe("MultiComboBox general interaction", () => { }); it("Value should be reset on ESC key", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mCombo = await browser.$("#another-mcb"); const mCombo2 = await browser.$("#more-mcb"); const input = await mCombo.shadow$("#ui5-multi-combobox-input"); @@ -763,8 +748,6 @@ describe("MultiComboBox general interaction", () => { }); it("selects an item when enter is pressed and value matches a text of an item in the list", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb-with-placeholder"); const input = await mcb.shadow$("input"); @@ -790,13 +773,11 @@ describe("MultiComboBox general interaction", () => { }); it("focuses the value state header and item on arrow down then the value state and the input on arrow up", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb-error"); const input = await mcb.shadow$("input"); const icon = await mcb.shadow$(".inputIcon"); const popover = await mcb.shadow$("ui5-responsive-popover"); - const listItem = await popover.$("ui5-li"); + const listItem = (await getVisibleItems(mcb))[0]; await icon.click(); await input.keys("ArrowDown"); @@ -833,8 +814,7 @@ describe("MultiComboBox general interaction", () => { const mcb = await browser.$("#mcb-with-placeholder"); const input = await mcb.shadow$("input"); const icon = await mcb.shadow$(".inputIcon"); - const popover = await mcb.shadow$("ui5-responsive-popover"); - const listItem = await popover.$("ui5-li"); + const listItem = (await getVisibleItems(mcb))[0]; await icon.click(); await mcb.keys("ArrowDown"); @@ -853,8 +833,7 @@ describe("MultiComboBox general interaction", () => { const input = await mcb.shadow$("input"); const popover = await mcb.shadow$("ui5-responsive-popover"); const checkbox = await popover.$("ui5-checkbox"); - const listItemGroup = await popover.$("ui5-li-group"); - + const listItemGroup = await mcb.$("ui5-mcb-item-group"); await input.click(); await mcb.keys("F4"); @@ -902,8 +881,6 @@ describe("MultiComboBox general interaction", () => { }); it("should reset current navigation state on user input", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb"); await mcb.click(); @@ -928,8 +905,6 @@ describe("MultiComboBox general interaction", () => { }); it("arrow up when no item is selected should go to the last item", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb"); await mcb.click(); @@ -939,8 +914,6 @@ describe("MultiComboBox general interaction", () => { }); it("should focus input after all tokens are deleted", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb-compact"); const input = await mcb.shadow$("input"); @@ -953,8 +926,6 @@ describe("MultiComboBox general interaction", () => { }); it("first HOME should move caret to start of the input, second HOME should focus the first token, END should focus last token", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb-error"); const input = await mcb.shadow$("input"); const tokens = await mcb.shadow$$(".ui5-multi-combobox-token"); @@ -980,13 +951,10 @@ describe("MultiComboBox general interaction", () => { }); it("CTRL + HOME focus the first item, CTRL + END should focus last item", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb"); const input = await mcb.shadow$("input"); - const popover = await mcb.shadow$("ui5-responsive-popover"); - const firstItem = await popover.$("ui5-li"); - const lastItem = await popover.$("ui5-li:last-child"); + const firstItem = await mcb.$("ui5-mcb-item"); + const lastItem = await mcb.$("ui5-mcb-item:last-child"); await input.click(); await mcb.keys("F4"); @@ -1001,8 +969,6 @@ describe("MultiComboBox general interaction", () => { }); it("should close the picker and focus the next element on TAB", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb"); const mcb2 = await browser.$("#mcb-no-typeahead"); @@ -1029,8 +995,6 @@ describe("MultiComboBox general interaction", () => { }); it("should close the picker and focus the next element on TAB over an item or value state header", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb-warning"); const input = await mcb.shadow$("input"); const mcb2 = await browser.$("#mcb-error"); @@ -1061,8 +1025,6 @@ describe("MultiComboBox general interaction", () => { }); it("should select/unselect next/previous item on shift+arrow", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb"); await mcb.click(); @@ -1083,8 +1045,6 @@ describe("MultiComboBox general interaction", () => { }); it("should move focus to the previous token with arrow left", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb-error"); const input = await mcb.shadow$("input"); @@ -1103,8 +1063,6 @@ describe("MultiComboBox general interaction", () => { }); it("should navigate through the items with CTRL + arrow up/down keys when the picker is closed", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb"); await mcb.click(); @@ -1123,12 +1081,10 @@ describe("MultiComboBox general interaction", () => { }); it("focuses the value state header and item on CTRL + arrow down then the value state and the input on CTRL + arrow up", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb-error"); const icon = await mcb.shadow$(".inputIcon"); const popover = await mcb.shadow$("ui5-responsive-popover"); - const listItem = await popover.$("ui5-li"); + const listItem = mcb.$("ui5-mcb-item"); await icon.click(); await mcb.keys(["Control", "ArrowDown"]); @@ -1164,8 +1120,6 @@ describe("MultiComboBox general interaction", () => { }); it("should select all filtered items on CTRL+A", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb"); const input = await mcb.shadow$("input"); @@ -1199,8 +1153,6 @@ describe("MultiComboBox general interaction", () => { }); it("should copy a token with CTRL+C and paste it with CTRL+V", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#multi1"); const mcb2 = await browser.$("#mcb"); const input = await mcb2.shadow$("input"); @@ -1220,8 +1172,6 @@ describe("MultiComboBox general interaction", () => { }); it("should not be able to paste token with CTRL+V in read only multi combo box", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#multi1"); const mcb2 = await browser.$("#readonly-value-state-mcb"); const input = await mcb2.shadow$("input"); @@ -1238,8 +1188,6 @@ describe("MultiComboBox general interaction", () => { }); it("should cut a token with CTRL+X and paste it with CTRL+V", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#multi1"); const mcb2 = await browser.$("#mcb"); const input = await mcb2.shadow$("input"); @@ -1258,8 +1206,6 @@ describe("MultiComboBox general interaction", () => { }); it("should cut a token with SHIFT+DELETE and paste it with SHIFT+INSERT", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#multi1"); const mcb2 = await browser.$("#mcb"); const input = await mcb2.shadow$("input"); @@ -1278,8 +1224,6 @@ describe("MultiComboBox general interaction", () => { }); it("should copy a token with CTRL+INSERT and paste it with SHIFT+INSERT", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#multi1"); const mcb2 = await browser.$("#mcb"); const input = await mcb2.shadow$("input"); @@ -1294,8 +1238,6 @@ describe("MultiComboBox general interaction", () => { }); it("should select a token with CTRL+SPACE", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb-error"); const input = await mcb.shadow$("input"); @@ -1309,8 +1251,6 @@ describe("MultiComboBox general interaction", () => { }); it("CTRL+SPACE should do nothing when pressed in the input field", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb"); const input = await mcb.shadow$("input"); @@ -1321,13 +1261,9 @@ describe("MultiComboBox general interaction", () => { }); it("F4 should focus the selected item or the first one if there is no selected", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb"); - const popover = await mcb.shadow$("ui5-responsive-popover"); - const listItem = await popover.$("ui5-li"); - const listItem2 = await popover.$$("ui5-li")[1]; - + const listItem = await mcb.$$("ui5-mcb-item")[0]; + const listItem2 = await mcb.$$("ui5-mcb-item")[1]; await mcb.click(); await mcb.keys("F4"); @@ -1342,12 +1278,9 @@ describe("MultiComboBox general interaction", () => { }); it("Alt + Down should focus the corresponding item to the token from which the combination is pressed", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb-items"); - const popover = await mcb.shadow$("ui5-responsive-popover"); const tokens = await mcb.shadow$$(".ui5-multi-combobox-token"); - const listItem = await popover.$$("ui5-li")[3]; + const listItem = await mcb.$$("ui5-mcb-item")[3]; await tokens[2].click(); await tokens[2].keys(["Alt", "ArrowDown"]); @@ -1356,11 +1289,8 @@ describe("MultiComboBox general interaction", () => { }); it("Alt + Down should focus the first item if no selected items are present", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#multi-acv"); - const popover = await mcb.shadow$("ui5-responsive-popover"); - const listItem = await popover.$("ui5-li"); + const listItem = await mcb.$("ui5-mcb-item"); await mcb.click(); await mcb.keys(["Alt", "ArrowDown"]); @@ -1369,24 +1299,19 @@ describe("MultiComboBox general interaction", () => { }); it("Alt + Down should not filter items", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb"); const input = await mcb.shadow$("input"); - const popover = await mcb.shadow$("ui5-responsive-popover"); await input.click(); await input.keys(["a", "b"]); await input.keys(["Alt", "ArrowDown"]); - const listItem = await popover.$("ui5-li"); + const listItem = await mcb.$("ui5-mcb-item"); assert.ok(await listItem.matches(":focus"), "The items are not filtered and the first item is focused"); }); it("Alt + Down should focus the item corresponding to the text value", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb"); const input = await mcb.shadow$("input"); const popover = await mcb.shadow$("ui5-responsive-popover"); @@ -1396,14 +1321,12 @@ describe("MultiComboBox general interaction", () => { await input.keys("ArrowDown"); await input.keys(["Alt", "ArrowDown"]); - const listItem = await popover.$$("ui5-li")[1]; + const listItem = await mcb.$$("ui5-mcb-item")[1]; assert.ok(await listItem.matches(":focus"), "The second item is focused"); }); it("Backspace deletes token and forwards the focus to the last token without collapsing the tokenizer", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#n-more-many-items"); const inner = await mcb.shadow$("input"); let tokens = await mcb.shadow$$(".ui5-multi-combobox-token"); @@ -1422,8 +1345,6 @@ describe("MultiComboBox general interaction", () => { }); it("Backspace should not delete tokens, when MCB is readonly", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb-ro"); const inner = await mcb.shadow$("input"); let tokens = await mcb.shadow$$(".ui5-multi-combobox-token"); @@ -1466,13 +1387,9 @@ describe("MultiComboBox general interaction", () => { }); describe("General", () => { - before(async () => { - await browser.url(`test/pages/MultiComboBox.html`); - }); - it("tests text selection on focus", async () => { - const mcb = await browser.$("#multi-acv"); - const mcb2 = await browser.$("#mcb-with-placeholder"); + const mcb = await $("#multi-acv"); + const mcb2 = await $("#mcb-with-placeholder"); await mcb.click(); @@ -1497,8 +1414,7 @@ describe("MultiComboBox general interaction", () => { it("tests two-column layout", async () => { const mcb = await browser.$("#mcb-two-column-layout"); const icon = await mcb.shadow$(".inputIcon"); - const popover = await mcb.shadow$(".ui5-multi-combobox-all-items-responsive-popover"); - const listItem = await popover.$("ui5-li"); + const listItem = await mcb.$("ui5-mcb-item"); await icon.click(); assert.strictEqual(await listItem.shadow$(".ui5-li-additional-text").getText(), "DZ", "Additional item text should be displayed"); @@ -1599,8 +1515,6 @@ describe("MultiComboBox general interaction", () => { }); it("Should check clear icon availability", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const cb = await browser.$("#clear-icon-cb"); const inner = cb.shadow$("input"); const clearIcon = await cb.shadow$(".ui5-input-clear-icon-wrapper"); @@ -1614,8 +1528,6 @@ describe("MultiComboBox general interaction", () => { }); it("Should check clear icon events", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const cb = await browser.$("#clear-icon-cb"); await cb.shadow$("input").click(); @@ -1631,8 +1543,6 @@ describe("MultiComboBox general interaction", () => { }); it("Should not fire submit event when confirming selection", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const cb = await browser.$("#mcb-form"); await cb.shadow$("input").click(); @@ -1647,8 +1557,6 @@ describe("MultiComboBox general interaction", () => { }); it("Should remove header when value state is reset", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = $("#mcb-error"); // click on arrow @@ -1669,10 +1577,6 @@ describe("MultiComboBox general interaction", () => { }); describe("MultiComboBox Truncated Token", () => { - beforeEach(async () => { - await browser.url(`test/pages/MultiComboBox.html`); - }); - it("should truncate token when single token is in the multicombobox and open popover on click", async () => { const mcb = await browser.$("#truncated-token"); const token = await mcb.shadow$("ui5-token"); @@ -1729,10 +1633,6 @@ describe("MultiComboBox general interaction", () => { }); describe("ARIA attributes", () => { - before(async () => { - await browser.url(`test/pages/MultiComboBox.html`); - }); - it("aria-describedby value according to the tokens count and the value state", async () => { const mcb = await browser.$("#mcb-error"); const innerInput = await mcb.shadow$("input"); @@ -1753,8 +1653,6 @@ describe("MultiComboBox general interaction", () => { const innerInput = await mcb.shadow$("input"); let invisibleText = await mcb.shadow$(".ui5-hidden-text"); const inivisbleTextId = await invisibleText.getProperty("id"); - const popover = await mcb.shadow$("ui5-responsive-popover"); - let firstItem = await popover.$("ui5-list").$("ui5-li"); let tokens = await mcb.shadow$$(".ui5-multi-combobox-token"); let resourceBundleText = null; @@ -1796,8 +1694,11 @@ describe("MultiComboBox general interaction", () => { assert.strictEqual(tokens.length, 0, "should not have tokens"); assert.ok(await ariaHiddenText.includes(resourceBundleText), "aria-describedby text is correct"); + await innerInput.click(); await innerInput.keys("i"); + + const firstItem = (await getVisibleItems(mcb))[0]; await firstItem.click(); tokens = await mcb.shadow$$(".ui5-multi-combobox-token"); @@ -1845,8 +1746,6 @@ describe("MultiComboBox general interaction", () => { }); it("Value state type should be added to the screen readers default value states announcement", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mCbWarning = await browser.$("#mcb-warning"); const mCbSuccess = await browser.$("#mcb-success"); const mCbError = await browser.$("#mcb-error"); @@ -1898,25 +1797,24 @@ describe("MultiComboBox general interaction", () => { describe("Grouping", () => { it("Tests group filtering", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb-grouping"); const input = await mcb.shadow$("#ui5-multi-combobox-input"); const arrow = await mcb.shadow$(".inputIcon"); let popover = await mcb.shadow$("ui5-responsive-popover"); - let groupItems = await popover.$("ui5-list").$$("ui5-li-group"); - let listItems = await popover.$("ui5-list").$$("ui5-li"); - + await arrow.click(); + let groupItems = await getVisibleGroupItems(mcb); + let listItems = await getVisibleItems(mcb); + assert.strictEqual(groupItems.length, 3, "Group items should be 3"); assert.strictEqual(listItems.length, 12, "Items should be 12"); await input.keys("B"); popover = await mcb.shadow$("ui5-responsive-popover"); - groupItems = await popover.$("ui5-list").$$("ui5-li-group"); - listItems = await popover.$("ui5-list").$$("ui5-li"); + groupItems = await getVisibleGroupItems(mcb); + listItems = await getVisibleItems(mcb); assert.strictEqual(groupItems.length, 1, "Filtered group items should be 1"); assert.strictEqual(listItems.length, 1, "Filtered items should be 1"); @@ -1928,40 +1826,32 @@ describe("MultiComboBox general interaction", () => { }); it("Tests group item focusability", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb-grouping"); const input = await mcb.shadow$("#ui5-multi-combobox-input"); const arrow = await mcb.shadow$(".inputIcon"); - const popover = await mcb.shadow$("ui5-responsive-popover"); let groupItem; await arrow.click(); await input.keys("ArrowDown"); - groupItem = await popover.$("ui5-list").$("ui5-li-group").shadow$("ui5-li-group-header"); + groupItem = (await getVisibleGroupItems(mcb))[0]; assert.ok(await groupItem.matches(":focus"), "The first group header should be focused"); }); it("Tests group item focusability with keyboard", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb-grouping"); const input = await mcb.shadow$("#ui5-multi-combobox-input"); - const popover = await mcb.shadow$("ui5-responsive-popover"); await input.click(); await input.keys("F4"); - let firstItem = await popover.$("ui5-list").$("ui5-li"); + let firstItem = (await getVisibleItems(mcb))[0]; assert.ok(await firstItem.matches(":focus"), "The first item inside the first group should be focused"); }); it("Group header keyboard handling", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb-grouping"); const input = await mcb.shadow$("#ui5-multi-combobox-input"); const arrow = await mcb.shadow$(".inputIcon"); @@ -1971,7 +1861,7 @@ describe("MultiComboBox general interaction", () => { await arrow.click(); await input.keys("ArrowDown"); - groupItem = await popover.$("ui5-list").$("ui5-li-group").shadow$("ui5-li-group-header"); + groupItem = (await getVisibleGroupItems(mcb))[0]; await groupItem.keys("Enter"); @@ -1979,7 +1869,7 @@ describe("MultiComboBox general interaction", () => { assert.equal(await popover.getProperty("open"), true, "Popover should not be open"); assert.strictEqual(await input.getValue(), "", "The value is not updated"); - groupItem = await popover.$("ui5-list").$("ui5-li-group").shadow$("ui5-li-group-header"); + groupItem = (await getVisibleGroupItems(mcb))[0]; await groupItem.keys("Space"); @@ -1987,7 +1877,7 @@ describe("MultiComboBox general interaction", () => { assert.equal(await popover.getProperty("open"), true, "Popover should not be open"); assert.strictEqual(await input.getValue(), "", "The value is not updated)"); - groupItem = await popover.$("ui5-list").$("ui5-li-group").shadow$("ui5-li-group-header"); + groupItem = (await getVisibleGroupItems(mcb))[0]; await groupItem.keys("ArrowUp"); @@ -1996,8 +1886,6 @@ describe("MultiComboBox general interaction", () => { }); it("Should not select group headers", async () => { - await browser.url(`test/pages/MultiComboBox.html`); - const mcb = await browser.$("#mcb-grouping"); const input = await mcb.shadow$("#ui5-multi-combobox-input"); diff --git a/packages/main/test/specs/RadioButton.spec.js b/packages/main/test/specs/RadioButton.spec.js index cf4116e1fd38..b5999caa6f4c 100644 --- a/packages/main/test/specs/RadioButton.spec.js +++ b/packages/main/test/specs/RadioButton.spec.js @@ -23,6 +23,7 @@ describe("Rendering", () => { assert.notOk(await readOnlyRadioButtonRoot.getAttribute("aria-readonly"), "aria-readonly is not set to the root level"); assert.strictEqual(await readOnlyRadioButtonInput.getAttribute("readonly"), "true", "internal input is readonly"); + assert.strictEqual(await readOnlyRadioButtonRoot.getAttribute("aria-disabled"), "true", "aria-disabled = true"); }); }); @@ -87,6 +88,7 @@ describe("RadioButton general interaction", () => { const field = await browser.$("#tabField"); const radioButtonPreviouslySelected = await browser.$("#groupRb1"); const radioButtonToBeSelected = await browser.$("#groupRb3"); + const radioButtonToBeSelectedNext = await browser.$("#groupRbReadOnly"); await field.click(); await field.keys("Tab"); @@ -96,7 +98,14 @@ describe("RadioButton general interaction", () => { assert.notOk(await radioButtonPreviouslySelected.getProperty("checked"), "Previously selected item has been de-selected."); assert.ok(await radioButtonToBeSelected.getProperty("checked"), "Pressing ArrowRight selects the next (not disabled) radio in the group."); - await radioButtonToBeSelected.keys("Tab"); + await radioButtonToBeSelected.keys("ArrowRight"); + const activeElementId = await browser.$(await browser.getActiveElement()).getAttribute("id"); + + assert.ok(await radioButtonToBeSelected.getProperty("checked"), "Previously selected item is still selected"); + assert.notOk(await radioButtonToBeSelectedNext.getProperty("checked"), "Read-only radio button is not selected."); + assert.ok(activeElementId === "groupRbReadOnly", " Focus is on the last radio button, which is read-only"); + + await radioButtonToBeSelectedNext.keys("Tab"); }); it("tests radio buttons selection within group with ARROW-LEFT key", async () => { diff --git a/packages/main/test/specs/TableGrowing.spec.js b/packages/main/test/specs/TableGrowing.spec.js index 415639cd5b4c..fdf17638bdde 100644 --- a/packages/main/test/specs/TableGrowing.spec.js +++ b/packages/main/test/specs/TableGrowing.spec.js @@ -231,43 +231,4 @@ describe('Table - Growing with Scroll', async () => { await endRow.scrollIntoView(); assert.strictEqual(await loadMoreCounter.getProperty("value"), "2", "The load-more event is dispatched"); }); - - }); - -describe('Table - Growing with Scroll (Edge Cases)', async () => { - before(async () => { - await browser.url(`test/pages/TableGrowing.html`); - await browser.setWindowSize(2000, 2000); - - const tableGrowing = await browser.$("#growing"); - await tableGrowing.setAttribute("type", "Scroll"); - }); - - it('Check if growing button is rendered, when no scrollbar is visible', async () => { - const tableGrowing = await browser.$("#growing"); - - const table = await browser.$("#table0"); - - const growingButtonRow = await table.shadow$("#growing-row"); - assert.ok(await growingButtonRow.isExisting(), "Growing Button Row exists"); - - const growingButtonCell = await table.shadow$("#growing-cell"); - assert.ok(await growingButtonCell.isExisting(), "Growing Button Cell exists"); - - const growingButton = await tableGrowing.shadow$("#growing-button"); - assert.ok(await growingButton.isExisting(), "Growing Button exists"); - - await growingButton.click(); - assert.ok(await growingButtonRow.isExisting(), "Growing Button Row exists"); - await growingButton.click(); - assert.ok(await growingButtonRow.isExisting(), "Growing Button Row exists"); - await growingButton.click(); - assert.ok(await growingButtonRow.isExisting(), "Growing Button Row exists"); - - await growingButton.click(); - - assert.notOk(await growingButtonRow.isExisting(), "Growing Button Row is not rendered"); - assert.notOk(await growingButtonCell.isExisting(), "Growing Button Cell is not rendered"); - }); -}); \ No newline at end of file diff --git a/packages/main/test/specs/Tokenizer.spec.js b/packages/main/test/specs/Tokenizer.spec.js index 341ce4c763a6..d406b994179e 100644 --- a/packages/main/test/specs/Tokenizer.spec.js +++ b/packages/main/test/specs/Tokenizer.spec.js @@ -233,44 +233,45 @@ describe("Accessibility", () => { it("should test aria-readonly attribute", async () => { const tokenizer = await browser.$("#nmore-tokenizer"); - const tokenizerContent = await tokenizer.shadow$(".ui5-tokenizer--content"); + const tokenizerList = await tokenizer.shadow$(".ui5-tokenizer--list"); const readonlyTokenizer = await browser.$("#readonly-tokenizer"); - const readonlyTokenizerContent = await readonlyTokenizer.shadow$(".ui5-tokenizer--content"); + const readonlyTokenizerList = await readonlyTokenizer.shadow$(".ui5-tokenizer--list"); assert.notOk(await tokenizer.getAttribute("readonly"), "tokenizer should not be readonly"); - assert.notOk(await tokenizerContent.getAttribute("aria-readonly"), "aria-readonly should not be set on tokenizer"); + assert.notOk(await tokenizerList.getAttribute("aria-readonly"), "aria-readonly should not be set on tokenizer"); assert.ok(await readonlyTokenizer.getAttribute("readonly"), "tokenizer should be readonly"); - assert.ok(await readonlyTokenizerContent.getAttribute("aria-readonly"), "aria-readonly should be set on disabled tokenizer"); + assert.ok(await readonlyTokenizerList.getAttribute("aria-readonly"), "aria-readonly should be set on disabled tokenizer"); }); it("should test aria-disabled attribute", async () => { const tokenizer = await browser.$("#nmore-tokenizer"); - const tokenizerContent = await tokenizer.shadow$(".ui5-tokenizer--content"); + const tokenizerList = await tokenizer.shadow$(".ui5-tokenizer--list"); + const disabledTokenizer = await browser.$("#disabled-tokenizer"); - const disabledTokenizerContent = await disabledTokenizer.shadow$(".ui5-tokenizer--content"); + const disabledTokenizerList = await disabledTokenizer.shadow$(".ui5-tokenizer--list"); assert.notOk(await tokenizer.getAttribute("disabled"), "tokenizer should not be disabled"); - assert.notOk(await tokenizerContent.getAttribute("aria-disabled"), "aria-disabled should not be set on tokenizer"); + assert.notOk(await tokenizerList.getAttribute("aria-disabled"), "aria-disabled should not be set on tokenizer"); assert.ok(await disabledTokenizer.getAttribute("disabled"), "tokenizer should be disabled"); - assert.ok(await disabledTokenizerContent.getAttribute("aria-disabled"), "aria-disabled should be set on disabled tokenizer"); + assert.ok(await disabledTokenizerList.getAttribute("aria-disabled"), "aria-disabled should be set on disabled tokenizer"); }); it("should test tokenizer content aria attributes", async () => { const tokenizer = await browser.$("#nmore-tokenizer"); - const tokenizerContent = await tokenizer.shadow$(".ui5-tokenizer--content"); + const tokenizerList = await tokenizer.shadow$(".ui5-tokenizer--list"); const expandedTokenizer = await browser.$("#expanded-tokenizer"); - const expandedTokenizerContent = await expandedTokenizer.shadow$(".ui5-tokenizer--content"); + const expandedTokenizerList = await expandedTokenizer.shadow$(".ui5-tokenizer--list"); const keys = [ "TOKENIZER_ARIA_LABEL", ]; const texts = await getResourceBundleTexts(keys); - assert.strictEqual(await tokenizerContent.getAttribute("role"), "listbox", "tokenizer content should have correct role=listbox"); - assert.strictEqual(await tokenizerContent.getAttribute("aria-label"), texts.TOKENIZER_ARIA_LABEL, "tokenizer content should have correct aria-label"); - assert.strictEqual(await expandedTokenizerContent.getAttribute("aria-label"), 'Test label', "tokenizer content should have correct aria-label when accesible name is set"); - assert.strictEqual(await expandedTokenizerContent.getAttribute("aria-description"), texts.TOKENIZER_ARIA_LABEL, "tokenizer content should have correct aria-description when accesible name is set"); + assert.strictEqual(await tokenizerList.getAttribute("role"), "listbox", "tokenizer content should have correct role=listbox"); + assert.strictEqual(await tokenizerList.getAttribute("aria-label"), texts.TOKENIZER_ARIA_LABEL, "tokenizer content should have correct aria-label"); + assert.strictEqual(await expandedTokenizerList.getAttribute("aria-label"), 'Test label', "tokenizer content should have correct aria-label when accesible name is set"); + assert.strictEqual(await expandedTokenizerList.getAttribute("aria-description"), texts.TOKENIZER_ARIA_LABEL, "tokenizer content should have correct aria-description when accesible name is set"); }); it("should test nMore aria attributes", async () => { diff --git a/packages/main/test/specs/Toolbar.spec.js b/packages/main/test/specs/Toolbar.spec.js index 06b4842b085b..271e6f3e240e 100644 --- a/packages/main/test/specs/Toolbar.spec.js +++ b/packages/main/test/specs/Toolbar.spec.js @@ -72,6 +72,4 @@ describe("Toolbar general interaction", () => { assert.strictEqual(await input.getProperty("value"), "1", "Button click event only called once"); await input.setAttribute("value", "0"); }); - - }); diff --git a/packages/theming/CHANGELOG.md b/packages/theming/CHANGELOG.md index ea87b7497382..0ced87d97f9a 100644 --- a/packages/theming/CHANGELOG.md +++ b/packages/theming/CHANGELOG.md @@ -3,6 +3,46 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.5.0-rc.2](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.1...v2.5.0-rc.2) (2024-11-28) + +**Note:** Version bump only for package @ui5/webcomponents-theming + + + + + +# [2.5.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.0...v2.5.0-rc.1) (2024-11-21) + +**Note:** Version bump only for package @ui5/webcomponents-theming + + + + + +# [2.5.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.1-rc.0...v2.5.0-rc.0) (2024-11-14) + +**Note:** Version bump only for package @ui5/webcomponents-theming + + + + + +## [2.4.1-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0...v2.4.1-rc.0) (2024-11-07) + +**Note:** Version bump only for package @ui5/webcomponents-theming + + + + + +# [2.4.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.4...v2.4.0) (2024-11-03) + +**Note:** Version bump only for package @ui5/webcomponents-theming + + + + + # [2.4.0-rc.4](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.3...v2.4.0-rc.4) (2024-10-31) **Note:** Version bump only for package @ui5/webcomponents-theming diff --git a/packages/theming/package.json b/packages/theming/package.json index 8c3ca6e18394..dc0d89308213 100644 --- a/packages/theming/package.json +++ b/packages/theming/package.json @@ -1,6 +1,6 @@ { "name": "@ui5/webcomponents-theming", - "version": "2.4.0-rc.4", + "version": "2.5.0-rc.2", "description": "UI5 Web Components: webcomponents.theming", "author": "SAP SE (https://www.sap.com)", "license": "Apache-2.0", @@ -31,10 +31,10 @@ }, "dependencies": { "@sap-theming/theming-base-content": "11.17.1", - "@ui5/webcomponents-base": "2.4.0-rc.4" + "@ui5/webcomponents-base": "2.5.0-rc.2" }, "devDependencies": { - "@ui5/webcomponents-tools": "2.4.0-rc.4", + "@ui5/webcomponents-tools": "2.5.0-rc.2", "globby": "^13.1.1", "json-beautify": "^1.1.1", "nps": "^5.10.0", diff --git a/packages/tools/CHANGELOG.md b/packages/tools/CHANGELOG.md index e5363bb0b808..f28b4ff6239f 100644 --- a/packages/tools/CHANGELOG.md +++ b/packages/tools/CHANGELOG.md @@ -3,6 +3,46 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.5.0-rc.2](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.1...v2.5.0-rc.2) (2024-11-28) + +**Note:** Version bump only for package @ui5/webcomponents-tools + + + + + +# [2.5.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.0...v2.5.0-rc.1) (2024-11-21) + +**Note:** Version bump only for package @ui5/webcomponents-tools + + + + + +# [2.5.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.1-rc.0...v2.5.0-rc.0) (2024-11-14) + +**Note:** Version bump only for package @ui5/webcomponents-tools + + + + + +## [2.4.1-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0...v2.4.1-rc.0) (2024-11-07) + +**Note:** Version bump only for package @ui5/webcomponents-tools + + + + + +# [2.4.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.4...v2.4.0) (2024-11-03) + +**Note:** Version bump only for package @ui5/webcomponents-tools + + + + + # [2.4.0-rc.4](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.3...v2.4.0-rc.4) (2024-10-31) **Note:** Version bump only for package @ui5/webcomponents-tools diff --git a/packages/tools/lib/cem/event.mjs b/packages/tools/lib/cem/event.mjs index ee83381ebe3b..cfe39f37287b 100644 --- a/packages/tools/lib/cem/event.mjs +++ b/packages/tools/lib/cem/event.mjs @@ -104,7 +104,7 @@ function processEvent(ts, event, classNode, moduleDoc) { result.description = description; result._ui5Cancelable = eventCancelable !== undefined ? eventCancelable : false; result._ui5allowPreventDefault = result._ui5Cancelable; - result._ui5Bubbles = eventBubbles !== undefined ? eventBubbles : true; + result._ui5Bubbles = eventBubbles !== undefined ? eventBubbles : false; if (native) { result.type = { text: "Event" }; diff --git a/packages/tools/package.json b/packages/tools/package.json index 1728896e255a..b2b10d34c1e4 100644 --- a/packages/tools/package.json +++ b/packages/tools/package.json @@ -1,6 +1,6 @@ { "name": "@ui5/webcomponents-tools", - "version": "2.4.0-rc.4", + "version": "2.5.0-rc.2", "description": "UI5 Web Components: webcomponents.tools", "author": "SAP SE (https://www.sap.com)", "license": "Apache-2.0", diff --git a/packages/website/CHANGELOG.md b/packages/website/CHANGELOG.md index bcdb0d718b69..992b190be0ae 100644 --- a/packages/website/CHANGELOG.md +++ b/packages/website/CHANGELOG.md @@ -3,6 +3,61 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.5.0-rc.2](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.1...v2.5.0-rc.2) (2024-11-28) + + +### Features + +* **ui5-form:** add new `emptySpan` property ([#10194](https://github.com/SAP/ui5-webcomponents/issues/10194)) ([48b0cc8](https://github.com/SAP/ui5-webcomponents/commit/48b0cc89b36dd859dd07c17021eedf7a99375150)), closes [#9963](https://github.com/SAP/ui5-webcomponents/issues/9963) + + + + + +# [2.5.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v2.5.0-rc.0...v2.5.0-rc.1) (2024-11-21) + +**Note:** Version bump only for package @ui5/webcomponents-website + + + + + +# [2.5.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.1-rc.0...v2.5.0-rc.0) (2024-11-14) + + +### Bug Fixes + +* **ui5-dynamic-page:** move subheading slot outside the title wrapper ([#10163](https://github.com/SAP/ui5-webcomponents/issues/10163)) ([6466b8a](https://github.com/SAP/ui5-webcomponents/commit/6466b8ad7f73c85a5c105dea3c196f6bfb78f27a)) + + +### Features + +* **ui5-color-picker:** add simplified display mode ([#10153](https://github.com/SAP/ui5-webcomponents/issues/10153)) ([bf9c0d6](https://github.com/SAP/ui5-webcomponents/commit/bf9c0d653be5af5473a7b616f2c91803db46beb3)), closes [#9979](https://github.com/SAP/ui5-webcomponents/issues/9979) +* **ui5-tokenizer:** enable multiline mode ([#9964](https://github.com/SAP/ui5-webcomponents/issues/9964)) ([1071746](https://github.com/SAP/ui5-webcomponents/commit/107174616b5b3b96c174160488eba18b9cdb9cae)) + + + + + +## [2.4.1-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0...v2.4.1-rc.0) (2024-11-07) + + +### Bug Fixes + +* **ui5-menu:** make close event non-bubbling ([#10133](https://github.com/SAP/ui5-webcomponents/issues/10133)) ([e7ccce9](https://github.com/SAP/ui5-webcomponents/commit/e7ccce968cab25a07837c41f36d94603c31e007e)), closes [#10041](https://github.com/SAP/ui5-webcomponents/issues/10041) + + + + + +# [2.4.0](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.4...v2.4.0) (2024-11-03) + +**Note:** Version bump only for package @ui5/webcomponents-website + + + + + # [2.4.0-rc.4](https://github.com/SAP/ui5-webcomponents/compare/v2.4.0-rc.3...v2.4.0-rc.4) (2024-10-31) diff --git a/packages/website/build-scripts/local-cdn.mjs b/packages/website/build-scripts/local-cdn.mjs index 06f7624b5f7b..d19fe86859cc 100644 --- a/packages/website/build-scripts/local-cdn.mjs +++ b/packages/website/build-scripts/local-cdn.mjs @@ -24,7 +24,7 @@ await Promise.all([ cp("../localization/package.json", "local-cdn/local-cdn/localization/package.json"), cp("../../node_modules/@zxing/library/umd/index.min.js", "local-cdn/local-cdn/zxing/umd/index.min.js"), - cp("../../node_modules/@zxing/library/esm5/index.js", "local-cdn/local-cdn/zxing/esm5/index.js"), + cp("../../node_modules/@zxing/library/esm/index.js", "local-cdn/local-cdn/zxing/esm/index.js"), ]); const files = await readdir("local-cdn", {recursive: true, withFileTypes: true}); diff --git a/packages/website/docs/_components_pages/fiori/NavigationLayout/NavigationLayout.mdx b/packages/website/docs/_components_pages/fiori/NavigationLayout/NavigationLayout.mdx index 1de4d9dac80c..c3ba0a51727c 100644 --- a/packages/website/docs/_components_pages/fiori/NavigationLayout/NavigationLayout.mdx +++ b/packages/website/docs/_components_pages/fiori/NavigationLayout/NavigationLayout.mdx @@ -1,3 +1,7 @@ +--- +sidebar_class_name: newComponentBadge +--- + import Basic from "../../../_samples/fiori/NavigationLayout/Basic/Basic.md"; <%COMPONENT_OVERVIEW%> diff --git a/packages/website/docs/_components_pages/main/ColorPicker.mdx b/packages/website/docs/_components_pages/main/ColorPicker.mdx index b62193f76f92..075124d82e11 100644 --- a/packages/website/docs/_components_pages/main/ColorPicker.mdx +++ b/packages/website/docs/_components_pages/main/ColorPicker.mdx @@ -3,10 +3,16 @@ slug: ../ColorPicker --- import Basic from "../../_samples/main/ColorPicker/Basic/Basic.md"; +import Simplified from "../../_samples/main/ColorPicker/Simplified/Simplified.md"; <%COMPONENT_OVERVIEW%> ## Basic Sample -<%COMPONENT_METADATA%> \ No newline at end of file +<%COMPONENT_METADATA%> + +## More Samples + +### Simplified Picker + \ No newline at end of file diff --git a/packages/website/docs/_components_pages/main/Form/Form.mdx b/packages/website/docs/_components_pages/main/Form/Form.mdx index 1216bc9680fb..b0a6acfa2652 100644 --- a/packages/website/docs/_components_pages/main/Form/Form.mdx +++ b/packages/website/docs/_components_pages/main/Form/Form.mdx @@ -8,6 +8,7 @@ import Groups from "../../../_samples/main/Form/Groups/Groups.md"; import Edit from "../../../_samples/main/Form/Edit/Edit.md"; import Layout from "../../../_samples/main/Form/Layout/Layout.md"; import LabelSpan from "../../../_samples/main/Form/LabelSpan/LabelSpan.md"; +import EmptySpan from "../../../_samples/main/Form/EmptySpan/EmptySpan.md"; import LabelsOnTop from "../../../_samples/main/Form/LabelsOnTop/LabelsOnTop.md"; import GroupColumnSpan from "../../../_samples/main/Form/GroupColumnSpan/GroupColumnSpan.md"; import HeaderTextWrapping from "../../../_samples/main/Form/HeaderTextWrapping/HeaderTextWrapping.md"; @@ -44,7 +45,9 @@ You can define groups via the **ui5-form-group** web component. ### Label Span -Use the Form#**labelSpan** property to define the width proportion of the labels and fields of a FormItem by breakpoint. +Use the **labelSpan** property to define the width proportion of the labels and fields of a FormItem by breakpoint. + +For example: - S12 M4 L4 XL4 - the label takes 1/3 in M, L, XL - S12 M6 L6 XL6 - the label takes 1/2 in M, L, XL @@ -53,6 +56,16 @@ Use the Form#**labelSpan** property to define the width proportion of the labels +### Empty Span +Use the **emptySpan** property to define the empty space at the FormItem's end. + +For example: + +- emptySpan="S1 M1 L1 XL1" + labelSpan="S4 M4 L4 XL4" will define "4 | 7 | 1" proportion between the label, the field and the empty space +- emptySpan="S3 M3 L3 XL3" + labelSpan="S4 M4 L4 XL4" will define "4 | 5 | 3" proportion between the label, the field and the empty space + + + ### Labels On Top Force labels always on top Form#**labelSpan=S12 M12 L12 XL12**. diff --git a/packages/website/docs/_components_pages/main/Tokenizer.mdx b/packages/website/docs/_components_pages/main/Tokenizer.mdx index a39a0c15f524..82a521bcdc38 100644 --- a/packages/website/docs/_components_pages/main/Tokenizer.mdx +++ b/packages/website/docs/_components_pages/main/Tokenizer.mdx @@ -4,10 +4,19 @@ sidebar_class_name: newComponentBadge --- import Basic from "../../_samples/main/Tokenizer/Basic/Basic.md"; +import MultiLine from "../../_samples/main/Tokenizer/MultiLine/Basic.md"; <%COMPONENT_OVERVIEW%> ## Basic Sample +## More Samples + +### Multi-line and Clear All +With multiLine enabled, tokens are displayed across multiple lines for improved readability. +The showClearAll option adds a convenient 'Clear All' button, allowing users to remove all tokens at once. + + + <%COMPONENT_METADATA%> diff --git a/packages/website/docs/_samples/fiori/DynamicPage/Basic/main.css b/packages/website/docs/_samples/fiori/DynamicPage/Basic/main.css index a69b41156bab..889ecc1fa56c 100644 --- a/packages/website/docs/_samples/fiori/DynamicPage/Basic/main.css +++ b/packages/website/docs/_samples/fiori/DynamicPage/Basic/main.css @@ -61,6 +61,7 @@ } .snapped-title-heading [ui5-avatar] { position: absolute; + top: 0; } .snapped-title-heading [ui5-title] { font-family: var(--sapObjectHeader_Title_FontFamily); diff --git a/packages/website/docs/_samples/main/ColorPicker/Simplified/Simplified.md b/packages/website/docs/_samples/main/ColorPicker/Simplified/Simplified.md new file mode 100644 index 000000000000..17798ecc59ab --- /dev/null +++ b/packages/website/docs/_samples/main/ColorPicker/Simplified/Simplified.md @@ -0,0 +1,4 @@ +import html from '!!raw-loader!./sample.html'; +import js from '!!raw-loader!./main.js'; + + diff --git a/packages/website/docs/_samples/main/ColorPicker/Simplified/main.js b/packages/website/docs/_samples/main/ColorPicker/Simplified/main.js new file mode 100644 index 000000000000..cf4af63d9e43 --- /dev/null +++ b/packages/website/docs/_samples/main/ColorPicker/Simplified/main.js @@ -0,0 +1 @@ +import "@ui5/webcomponents/dist/ColorPicker.js"; \ No newline at end of file diff --git a/packages/website/docs/_samples/main/ColorPicker/Simplified/sample.html b/packages/website/docs/_samples/main/ColorPicker/Simplified/sample.html new file mode 100644 index 000000000000..1d89501b4cbf --- /dev/null +++ b/packages/website/docs/_samples/main/ColorPicker/Simplified/sample.html @@ -0,0 +1,20 @@ + + + + + + + + Sample + + + + + + Picker + + + + + + diff --git a/packages/website/docs/_samples/main/Form/EmptySpan/EmptySpan.md b/packages/website/docs/_samples/main/Form/EmptySpan/EmptySpan.md new file mode 100644 index 000000000000..ef4652628b4d --- /dev/null +++ b/packages/website/docs/_samples/main/Form/EmptySpan/EmptySpan.md @@ -0,0 +1,5 @@ +import html from '!!raw-loader!./sample.html'; +import js from '!!raw-loader!./main.js'; +import css from '!!raw-loader!./main.css'; + + diff --git a/packages/website/docs/_samples/main/Form/EmptySpan/main.css b/packages/website/docs/_samples/main/Form/EmptySpan/main.css new file mode 100644 index 000000000000..42918f8ede52 --- /dev/null +++ b/packages/website/docs/_samples/main/Form/EmptySpan/main.css @@ -0,0 +1,6 @@ +ui5-form-item::part(layout) { + background: var(--sapHoverColor); +} +ui5-form-item::part(content) { + background: var(--sapAvatar_1_Background); +} \ No newline at end of file diff --git a/packages/website/docs/_samples/main/Form/EmptySpan/main.js b/packages/website/docs/_samples/main/Form/EmptySpan/main.js new file mode 100644 index 000000000000..d2809c970324 --- /dev/null +++ b/packages/website/docs/_samples/main/Form/EmptySpan/main.js @@ -0,0 +1,32 @@ +import "@ui5/webcomponents/dist/Form.js"; +import "@ui5/webcomponents/dist/FormItem.js"; + + +// The following code is required only for the sample +import "@ui5/webcomponents/dist/Label.js"; +import "@ui5/webcomponents/dist/Text.js"; +import "@ui5/webcomponents/dist/Slider.js"; +import "@ui5/webcomponents/dist/Input.js"; +import "@ui5/webcomponents/dist/Select.js"; +import "@ui5/webcomponents/dist/Option.js"; + +const slider = document.getElementById("slider"); +const txtLayout = document.getElementById("txtLayout"); +const container = document.getElementById("container"); + +slider.addEventListener("ui5-input", () => { + const width = (slider.value / 100 * 1500); + container.style.width = `${width}px`; + txtLayout.innerHTML = getLayoutByWidth(width); +}); + +const getLayoutByWidth = (width) => { + if (width > 599 && width <= 1023) { + return "M"; + } else if (width >= 1024 && width <= 1439) { + return "L" + } else if (width >= 1440) { + return "XL" + } + return "S"; +}; diff --git a/packages/website/docs/_samples/main/Form/EmptySpan/sample.html b/packages/website/docs/_samples/main/Form/EmptySpan/sample.html new file mode 100644 index 000000000000..a15c4cfd7923 --- /dev/null +++ b/packages/website/docs/_samples/main/Form/EmptySpan/sample.html @@ -0,0 +1,104 @@ + + + + + + + + Form Label Span Sample + + + + + + + Page SizeL + + +
+ + + + Name: + + + + + Country: + + Australia + Germany + England + + + + + ZIP Code/City: + + + + + + WebSite: + + + + + Street: + + + + + + Delivery address: + + + + +

+ + + + Name: + + + + + Country: + + Australia + Germany + England + + + + + ZIP Code/City: + + + + + + WebSite: + + + + + Street: + + + + + + Delivery address: + + + +
+ + + + + + + diff --git a/packages/website/docs/_samples/main/Form/FreeStyleForm/FreeStyleForm.md b/packages/website/docs/_samples/main/Form/FreeStyleForm/FreeStyleForm.md index 17798ecc59ab..ef4652628b4d 100644 --- a/packages/website/docs/_samples/main/Form/FreeStyleForm/FreeStyleForm.md +++ b/packages/website/docs/_samples/main/Form/FreeStyleForm/FreeStyleForm.md @@ -1,4 +1,5 @@ import html from '!!raw-loader!./sample.html'; import js from '!!raw-loader!./main.js'; +import css from '!!raw-loader!./main.css'; - + diff --git a/packages/website/docs/_samples/main/Form/FreeStyleForm/main.css b/packages/website/docs/_samples/main/Form/FreeStyleForm/main.css new file mode 100644 index 000000000000..41c3fe254384 --- /dev/null +++ b/packages/website/docs/_samples/main/Form/FreeStyleForm/main.css @@ -0,0 +1,13 @@ +:root { + --my-margin: -0.6875rem; +} +.ui5-content-density-compact { + --my-margin: -0.5rem; +} + +.margin--density-aware { + margin-inline-start: var(--my-margin); +} +.margin--fixed { + margin-inline-start: -0.5rem; +} \ No newline at end of file diff --git a/packages/website/docs/_samples/main/Form/FreeStyleForm/sample.html b/packages/website/docs/_samples/main/Form/FreeStyleForm/sample.html index 4aae25886b75..c8ea0fdf29ce 100644 --- a/packages/website/docs/_samples/main/Form/FreeStyleForm/sample.html +++ b/packages/website/docs/_samples/main/Form/FreeStyleForm/sample.html @@ -6,6 +6,7 @@ Sample + @@ -59,13 +60,14 @@ - + Label: + Label: -
+
@@ -73,7 +75,7 @@ Label: - + diff --git a/packages/website/docs/_samples/main/Form/HeaderTextWrapping/sample.html b/packages/website/docs/_samples/main/Form/HeaderTextWrapping/sample.html index b2225aa4c488..cb8c19c8bae6 100644 --- a/packages/website/docs/_samples/main/Form/HeaderTextWrapping/sample.html +++ b/packages/website/docs/_samples/main/Form/HeaderTextWrapping/sample.html @@ -10,9 +10,6 @@ - - -
diff --git a/packages/website/docs/_samples/main/Tokenizer/MultiLine/Basic.md b/packages/website/docs/_samples/main/Tokenizer/MultiLine/Basic.md new file mode 100644 index 000000000000..ffccbf6dd13e --- /dev/null +++ b/packages/website/docs/_samples/main/Tokenizer/MultiLine/Basic.md @@ -0,0 +1,4 @@ +import html from '!!raw-loader!./sample.html'; +import js from '!!raw-loader!./main.js'; + + \ No newline at end of file diff --git a/packages/website/docs/_samples/main/Tokenizer/MultiLine/main.js b/packages/website/docs/_samples/main/Tokenizer/MultiLine/main.js new file mode 100644 index 000000000000..e7554d001aac --- /dev/null +++ b/packages/website/docs/_samples/main/Tokenizer/MultiLine/main.js @@ -0,0 +1,13 @@ +import "@ui5/webcomponents/dist/Token.js"; +import "@ui5/webcomponents/dist/Tokenizer.js"; + +const clearAllTokenizer = document.getElementById('clear-all'); + + +clearAllTokenizer.addEventListener("ui5-token-delete", event => { + const tokens = event.detail?.tokens; + + if (tokens) { + tokens.forEach(token => token.remove()); + } +}); \ No newline at end of file diff --git a/packages/website/docs/_samples/main/Tokenizer/MultiLine/sample.html b/packages/website/docs/_samples/main/Tokenizer/MultiLine/sample.html new file mode 100644 index 000000000000..3dd006c60105 --- /dev/null +++ b/packages/website/docs/_samples/main/Tokenizer/MultiLine/sample.html @@ -0,0 +1,31 @@ + + + + + + + Sample + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/website/docs/_samples/patterns/AIAcknowledgement/Basic/sample.html b/packages/website/docs/_samples/patterns/AIAcknowledgement/Basic/sample.html index 02f989aace43..b574c6a7919d 100644 --- a/packages/website/docs/_samples/patterns/AIAcknowledgement/Basic/sample.html +++ b/packages/website/docs/_samples/patterns/AIAcknowledgement/Basic/sample.html @@ -11,7 +11,7 @@
- SAP CX AI Toolkit now provides embedded AI services. For more information, see the SAP Help Portal. + [ <Application Help> ] now provides embedded AI ("Artificial Intelligence") services. For more information, see <link>.
Disclaimer @@ -19,8 +19,9 @@ Artificial Intelligence (AI) generates results based on multiple sources. Outputs may contain errors and inaccuracies. Consider reviewing all generated results and adjust as necessary.
-
+
OK + Cancel
diff --git a/packages/website/docs/_samples/patterns/AIGuidedPrompt/Dialog/main.js b/packages/website/docs/_samples/patterns/AIGuidedPrompt/Dialog/main.js index cc23c29159ae..27b2227e0686 100644 --- a/packages/website/docs/_samples/patterns/AIGuidedPrompt/Dialog/main.js +++ b/packages/website/docs/_samples/patterns/AIGuidedPrompt/Dialog/main.js @@ -51,8 +51,8 @@ let options = { let text; let dialogGenerationId; -function startGeneration() { - console.warn("startGeneration"); +function startGenerating() { + console.warn("startGenerating"); dialogOutput.value = ""; text = texts[options.structure][options.language][options.toneOfVoice]; let generatedWordIndex = 0; @@ -60,7 +60,7 @@ function startGeneration() { const words = text.split(" "); const maxWordIndex = words.length - 1; if (generatedWordIndex > maxWordIndex) { - stopGeneration(generationId); + stopGenerating(generationId); aiDialogButton.state = "revise"; openDialogButton.innerText = "Revise"; closeDialogButton.disabled = false; @@ -73,8 +73,8 @@ function startGeneration() { return generationId; } -function stopGeneration(generationId) { - console.warn("stopGeneration"); +function stopGenerating(generationId) { + console.warn("stopGenerating"); closeDialogButton.disabled = false; clearTimeout(generationId); } @@ -88,24 +88,24 @@ function aiDialogButtonClickHandler(evt) { switch (button.state) { case "": case "generate": - startGenerationFromDialog(); + startGeneratingFromDialog(); break; case "revise": - startGenerationFromDialog(); + startGeneratingFromDialog(); break; case "generating": button.state = "generate"; openDialogButton.innerText = "Generate"; closeDialogButton.disabled = false; - stopGeneration(dialogGenerationId, closeDialogButton); + stopGenerating(dialogGenerationId, closeDialogButton); break; } } -function startGenerationFromDialog() { +function startGeneratingFromDialog() { aiDialogButton.state = "generating"; closeDialogButton.disabled = true; - dialogGenerationId = startGeneration(); + dialogGenerationId = startGenerating(); } function openDialog() { diff --git a/packages/website/docs/_samples/patterns/AIGuidedPrompt/DynamicSideContent/main.css b/packages/website/docs/_samples/patterns/AIGuidedPrompt/DynamicSideContent/main.css index 1a10b01a8539..a72442d42dc3 100644 --- a/packages/website/docs/_samples/patterns/AIGuidedPrompt/DynamicSideContent/main.css +++ b/packages/website/docs/_samples/patterns/AIGuidedPrompt/DynamicSideContent/main.css @@ -43,6 +43,7 @@ [ui5-dynamic-side-content] .guidedPromptForm { margin-bottom: 1rem; + padding: 0 1rem; } .hidden { diff --git a/packages/website/docs/_samples/patterns/AIGuidedPrompt/DynamicSideContent/main.js b/packages/website/docs/_samples/patterns/AIGuidedPrompt/DynamicSideContent/main.js index 5145f90897ea..43bdd5dbd48a 100644 --- a/packages/website/docs/_samples/patterns/AIGuidedPrompt/DynamicSideContent/main.js +++ b/packages/website/docs/_samples/patterns/AIGuidedPrompt/DynamicSideContent/main.js @@ -50,8 +50,8 @@ let options = { let text; let sideContentGenerationId; -function startGeneration() { - console.warn('startGeneration'); +function startGenerating() { + console.warn('startGenerating'); output.value = ''; text = texts[options.structure][options.language][options.toneOfVoice]; let generatedWordIndex = 0; @@ -61,7 +61,7 @@ function startGeneration() { const maxWordIndex = words.length - 1; if (generatedWordIndex > maxWordIndex) { - stopGeneration(generationId); + stopGenerating(generationId); aiSideContentButton.state = 'revise'; openSideContentButton.innerText = 'Revise'; closeSideContentButton.disabled = false; @@ -73,8 +73,8 @@ function startGeneration() { return generationId; } -function stopGeneration(generationId) { - console.warn('stopGeneration'); +function stopGenerating(generationId) { + console.warn('stopGenerating'); closeSideContentButton.disabled = false; clearTimeout(generationId); } @@ -88,23 +88,23 @@ function aiSideContentButtonClickHandler(evt) { switch (button.state) { case '': case 'generate': - startGenerationFromSideContent(button); + startGeneratingFromSideContent(button); break; case 'revise': - startGenerationFromSideContent(button); + startGeneratingFromSideContent(button); break; case 'generating': button.state = 'generate'; openSideContentButton.innerText = 'Generate'; - stopGeneration(sideContentGenerationId); + stopGenerating(sideContentGenerationId); break; } } -function startGenerationFromSideContent(button) { +function startGeneratingFromSideContent(button) { button.state = 'generating'; closeSideContentButton.disabled = true; - sideContentGenerationId = startGeneration(); + sideContentGenerationId = startGenerating(); } function openSideContent() { diff --git a/packages/website/docs/_samples/patterns/AIGuidedPrompt/DynamicSideContent/sample.html b/packages/website/docs/_samples/patterns/AIGuidedPrompt/DynamicSideContent/sample.html index e01a8a2208a0..4f087c3a8ab6 100644 --- a/packages/website/docs/_samples/patterns/AIGuidedPrompt/DynamicSideContent/sample.html +++ b/packages/website/docs/_samples/patterns/AIGuidedPrompt/DynamicSideContent/sample.html @@ -37,7 +37,7 @@
- Improve Text + Improve Text Close @@ -51,7 +51,7 @@
- Length: + Choose the length: maxWordIndex) { - stopGeneration(generationId); + stopGenerating(generationId); aiButton.state = "revise"; sendButton.disabled = false; return; @@ -72,8 +72,8 @@ function startGeneration() { return generationId; } -function stopGeneration(generationId) { - console.warn("stopGeneration"); +function stopGenerating(generationId) { + console.warn("stopGenerating"); clearTimeout(generationId); } @@ -87,7 +87,7 @@ function aiButtonClickHandler(evt) { case "generating": button.state = "generate"; sendButton.disabled = false; - stopGeneration(popoverGenerationId); + stopGenerating(popoverGenerationId); break; case "revise": openPopover(); @@ -97,7 +97,7 @@ function aiButtonClickHandler(evt) { function applyButtonClickHandler(evt) { aiButton.state = "generating"; - popoverGenerationId = startGeneration(); + popoverGenerationId = startGenerating(); closePopover(); } diff --git a/packages/website/docs/components/patterns/AI CustomPrompt/Level 4/main.js b/packages/website/docs/components/patterns/AI CustomPrompt/Level 4/main.js index 391e37e34d44..19ea6b4c9a4a 100644 --- a/packages/website/docs/components/patterns/AI CustomPrompt/Level 4/main.js +++ b/packages/website/docs/components/patterns/AI CustomPrompt/Level 4/main.js @@ -65,7 +65,7 @@ myAiButtonIconOnly.addEventListener("click", aiButtonClickHandler); promptInput.addEventListener("ui5-change", function(evt) { promptCounter++; promptCount.textContent = promptCounter; - responseTextArea.value = "your response ot query " + evt.target.value + " is that."; + responseTextArea.value = "your response to query " + evt.target.value + " is that."; }) menu.addEventListener("item-click", function(evt) { diff --git a/packages/website/docs/components/patterns/AI QuickPrompt/main.js b/packages/website/docs/components/patterns/AI QuickPrompt/main.js index cb68b08cf695..85a5605f4fdb 100644 --- a/packages/website/docs/components/patterns/AI QuickPrompt/main.js +++ b/packages/website/docs/components/patterns/AI QuickPrompt/main.js @@ -111,7 +111,7 @@ menu1.addEventListener("item-click", function (e) { case "Clear Error": clearValueState(output); break; - case "Fix Spelling & Grammar": + case "Fix Spelling and Grammar": fixSpellingAndGrammar(button, output); break; case "Generate Error": @@ -126,7 +126,7 @@ menu1.addEventListener("item-click", function (e) { case "Rephrase": startTextGeneration(button, "reviseGenerating", predefinedTextsRephrased); break; - case "Summarise": + case "Summarize": startTextGeneration(button, "reviseGenerating", predefinedTextsSummarized); break; case "Bulgarian": @@ -166,7 +166,7 @@ function setNegativeValueState(output) { output.valueState = "Negative"; const div = document.createElement("div"); div.setAttribute("slot", "valueStateMessage"); - div.textContent = "Spelling or grammar issues found, please try again!"; + div.textContent = "Something went wrong during the generation process. Please try again."; if (!output.querySelector("[slot='valueStateMessage']")) { output.appendChild(div); diff --git a/packages/website/docs/components/patterns/AI QuickPrompt/sample.html b/packages/website/docs/components/patterns/AI QuickPrompt/sample.html index 7ffd9f2fb6e0..415f17258a93 100644 --- a/packages/website/docs/components/patterns/AI QuickPrompt/sample.html +++ b/packages/website/docs/components/patterns/AI QuickPrompt/sample.html @@ -42,12 +42,12 @@ - + - + diff --git a/packages/website/package.json b/packages/website/package.json index 4750710f08b9..4fd21b141f6c 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -1,6 +1,6 @@ { "name": "@ui5/webcomponents-website", - "version": "2.4.0-rc.4", + "version": "2.5.0-rc.2", "private": true, "scripts": { "generate-local-cdn": "rimraf ./local-cdn && node ./build-scripts/local-cdn.mjs", diff --git a/yarn.lock b/yarn.lock index c68e6f367ea1..1371888cd24a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4976,12 +4976,12 @@ dependencies: argparse "^2.0.1" -"@zxing/library@^0.17.1": - version "0.17.1" - resolved "https://registry.yarnpkg.com/@zxing/library/-/library-0.17.1.tgz#4c82bf401391c2b79bfbab0a6b1143da6d8feb1a" - integrity sha512-RuiBZuteGaFXCle/b0X+g3peN8UpDc3pGe/J7hZBzKWaMZLbjensR7ja3vy47xWhXU4e8MICGqegPMxc2V2sow== +"@zxing/library@^0.21.3": + version "0.21.3" + resolved "https://registry.yarnpkg.com/@zxing/library/-/library-0.21.3.tgz#0a4cb777701884131832b05922d7e88ef1b87ab4" + integrity sha512-hZHqFe2JyH/ZxviJZosZjV+2s6EDSY0O24R+FQmlWZBZXP9IqMo7S3nb3+2LBWxodJQkSurdQGnqE7KXqrYgow== dependencies: - ts-custom-error "^3.0.0" + ts-custom-error "^3.2.1" optionalDependencies: "@zxing/text-encoding" "~0.9.0" @@ -6292,10 +6292,10 @@ chrome-trace-event@^1.0.2: resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== -chromedriver@^129.0.0: - version "129.0.4" - resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-129.0.4.tgz#64e598061b74f0f65fae605242327af84ebbfd28" - integrity sha512-j5I55cQwodFJUaYa1tWUmj2ss9KcPRBWmUa5Qonq3X8kqv2ASPyTboFYb4YB/YLztkYTUUw2E43txXw0wYzT/A== +chromedriver@^131.0.0: + version "131.0.0" + resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-131.0.0.tgz#08bbc6d9fcd1c42abfe70ac7e3412fba96f44723" + integrity sha512-ukYmdCox2eRsjpCYUB4AOLV1fSfWQ1ZPfcUc0PIUWZKoyjyXKEl8i4DJ14bcNzNbEvaVx2Z2pnx/nLK2CM+ruQ== dependencies: "@testim/chrome-version" "^1.1.4" axios "^1.7.4" @@ -17098,7 +17098,7 @@ ts-api-utils@^1.0.1: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== -ts-custom-error@^3.0.0: +ts-custom-error@^3.2.1: version "3.3.1" resolved "https://registry.yarnpkg.com/ts-custom-error/-/ts-custom-error-3.3.1.tgz#8bd3c8fc6b8dc8e1cb329267c45200f1e17a65d1" integrity sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==