diff --git a/.github/actions/release.js b/.github/actions/release.js index a0abc7ff4648..1adc243c2d50 100755 --- a/.github/actions/release.js +++ b/.github/actions/release.js @@ -20,7 +20,7 @@ const OTP = options.otp; const run = async () => { const { globby } = await import("globby"); - let FILES = await globby(["packages/*/package.json", "!packages/playground/package.json"]); + let FILES = await globby(["packages/*/package.json", "!packages/playground/package.json", "!packages/website/package.json"]); // Step 1: process package.json files const pkgs = await Promise.all(FILES.map(processPackageJSON)); diff --git a/.github/workflows/ci-test-website.yaml b/.github/workflows/ci-test-website.yaml new file mode 100644 index 000000000000..fe46c30f23b5 --- /dev/null +++ b/.github/workflows/ci-test-website.yaml @@ -0,0 +1,23 @@ +name: CI - Website + +on: + pull_request: + push: + branches: + - 'main' +jobs: + check: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4.0.1 + with: + node-version: 18 + cache: 'yarn' + + - name: Install and Build + run: | + export NODE_OPTIONS="--max_old_space_size=4096" + yarn install + yarn ci:deploy:nightly diff --git a/.github/workflows/deploy-latest-playground-on-release.yaml b/.github/workflows/deploy-storybook-on-release.yaml similarity index 90% rename from .github/workflows/deploy-latest-playground-on-release.yaml rename to .github/workflows/deploy-storybook-on-release.yaml index fd6f8ae67372..ef6eb97deac1 100644 --- a/.github/workflows/deploy-latest-playground-on-release.yaml +++ b/.github/workflows/deploy-storybook-on-release.yaml @@ -1,4 +1,4 @@ -name: Deploy Latest Playground [on release] +name: Deploy Storybook [on latest release] on: release: @@ -31,5 +31,5 @@ jobs: with: branch: gh-pages # The branch the action should deploy to. folder: packages/playground/dist # The folder the action should deploy. + target-folder: storybook-latest clean: true - clean-exclude: nightly diff --git a/.github/workflows/deploy-main-playground.yaml b/.github/workflows/deploy-storybook.yaml similarity index 75% rename from .github/workflows/deploy-main-playground.yaml rename to .github/workflows/deploy-storybook.yaml index a7cf4de42498..b5462356ec9f 100644 --- a/.github/workflows/deploy-main-playground.yaml +++ b/.github/workflows/deploy-storybook.yaml @@ -1,4 +1,4 @@ -name: Deploy Main Playground [manual] +name: Deploy Storybook [manual] on: workflow_dispatch: @@ -18,14 +18,12 @@ jobs: run: | export NODE_OPTIONS="--max_old_space_size=4096" yarn install - yarn build:playground - - name: Write version.md - run: git log -1 &> packages/playground/dist/main/version.md + yarn ci:deploybuild - name: Deploy uses: JamesIves/github-pages-deploy-action@v4.3.3 with: branch: gh-pages # The branch the action should deploy to. folder: packages/playground/dist # The folder the action should deploy. - target-folder: nightly + target-folder: storybook clean: true diff --git a/.github/workflows/deploy-main-playground-on-push.yaml b/.github/workflows/deploy-website-on-push.yaml similarity index 60% rename from .github/workflows/deploy-main-playground-on-push.yaml rename to .github/workflows/deploy-website-on-push.yaml index 3382c7811dd0..225ac269c739 100644 --- a/.github/workflows/deploy-main-playground-on-push.yaml +++ b/.github/workflows/deploy-website-on-push.yaml @@ -1,8 +1,9 @@ -name: Deploy Main Playground [on push] +name: Deploy Website [on push] on: push: branches: [ main ] + jobs: deploy: runs-on: ubuntu-latest @@ -18,14 +19,20 @@ jobs: run: | export NODE_OPTIONS="--max_old_space_size=4096" yarn install - yarn ci:deploybuild - - name: Write version.md - run: git log -1 &>> packages/playground/dist/version.md + + - name: Update version.md + run: | + touch packages/website/static/version.md + git log -1 &>> packages/website/static/version.md + + - name: Build + run: | + yarn ci:deploy:nightly - name: Deploy uses: JamesIves/github-pages-deploy-action@v4.3.3 with: branch: gh-pages # The branch the action should deploy to. - folder: packages/playground/dist # The folder the action should deploy. + folder: packages/website/build # The folder the action should deploy. target-folder: nightly - clean: true \ No newline at end of file + clean: true diff --git a/.github/workflows/deploy-website-on-release.yaml b/.github/workflows/deploy-website-on-release.yaml new file mode 100644 index 000000000000..f96bcf408968 --- /dev/null +++ b/.github/workflows/deploy-website-on-release.yaml @@ -0,0 +1,40 @@ +name: Deploy Website [on latest release] + +on: + release: + types: + - 'released' + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4.0.1 + with: + node-version: 18 + cache: 'yarn' + + - name: Install and Build + run: | + export NODE_OPTIONS="--max_old_space_size=4096" + yarn install + + - name: Update version.md + run: | + touch packages/website/static/version.md + git log -1 &>> packages/website/static/version.md + + - name: Build + run: | + yarn ci:deploy + + - name: Deploy + uses: JamesIves/github-pages-deploy-action@v4.3.3 + with: + branch: gh-pages # The branch the action should deploy to. + folder: packages/website/build # The folder the action should deploy. + clean: true + clean-exclude: nightly diff --git a/.github/workflows/deploy-latest-playground-on-push.yaml b/.github/workflows/deploy-website.yaml similarity index 54% rename from .github/workflows/deploy-latest-playground-on-push.yaml rename to .github/workflows/deploy-website.yaml index 1b316799c373..777c9773afd5 100644 --- a/.github/workflows/deploy-latest-playground-on-push.yaml +++ b/.github/workflows/deploy-website.yaml @@ -1,8 +1,8 @@ -name: Deploy Latest Playground [on push] +name: Deploy Website [manual] on: - push: - branches: [ latest-release-website ] + workflow_dispatch: + jobs: deploy: runs-on: ubuntu-latest @@ -18,15 +18,20 @@ jobs: run: | export NODE_OPTIONS="--max_old_space_size=4096" yarn install - yarn ci:deploybuild - - name: Write version.md - run: git log -1 &> packages/playground/dist/version.md + - name: Update version.md + run: | + touch packages/website/static/version.md + git log -1 &>> packages/website/static/version.md + + - name: Build + run: | + yarn ci:deploy:nightly - name: Deploy uses: JamesIves/github-pages-deploy-action@v4.3.3 with: branch: gh-pages # The branch the action should deploy to. - folder: packages/playground/dist # The folder the action should deploy. - clean: true - clean-exclude: nightly \ No newline at end of file + folder: packages/website/build # The folder the action should deploy. + target-folder: nightly + clean: true \ No newline at end of file diff --git a/.github/workflows/release-rc-auto.yaml b/.github/workflows/release-rc-auto.yaml index 5fc10fcb8c96..e13ba826f9d8 100644 --- a/.github/workflows/release-rc-auto.yaml +++ b/.github/workflows/release-rc-auto.yaml @@ -20,6 +20,18 @@ jobs: - name: Install run: yarn --frozen-lockfile + - name: Version Bump + env: + NPM_USERNAME: ${{ secrets.NPM_USER }} + NPM_EMAIL: ${{ secrets.NPM_EMAIL }} + NPM_AUTH_TOKEN: ${{ secrets.NPM_RELEASE_AUTH_TOKEN }} + GH_TOKEN: ${{ secrets.UI5_WEBCOMP_BOT_GH_TOKEN }} + run: | + npm config set //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN} + git config user.name "${{ secrets.UI5_WEBCOMP_BOT_NAME }}" + git config user.email "${{ secrets.UI5_WEBCOMP_BOT_EMAIL }}" + yarn lerna version --conventional-prerelease --force-publish --yes --exact --create-release github + - name: Build run: yarn ci:releasebuild @@ -29,9 +41,4 @@ jobs: NPM_EMAIL: ${{ secrets.NPM_EMAIL }} NPM_AUTH_TOKEN: ${{ secrets.NPM_RELEASE_AUTH_TOKEN }} GH_TOKEN: ${{ secrets.UI5_WEBCOMP_BOT_GH_TOKEN }} - run: | - npm config set //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN} - git config user.name "${{ secrets.UI5_WEBCOMP_BOT_NAME }}" - git config user.email "${{ secrets.UI5_WEBCOMP_BOT_EMAIL }}" - yarn lerna version --conventional-prerelease --force-publish --yes --exact --create-release github - yarn lerna publish from-git --yes + run: yarn lerna publish from-git --yes \ No newline at end of file diff --git a/.github/workflows/release-rc.yaml b/.github/workflows/release-rc.yaml index da831dfff081..d221adb553bb 100644 --- a/.github/workflows/release-rc.yaml +++ b/.github/workflows/release-rc.yaml @@ -19,6 +19,18 @@ jobs: - name: Install run: yarn --frozen-lockfile + - name: Version Bump + env: + NPM_USERNAME: ${{ secrets.NPM_USER }} + NPM_EMAIL: ${{ secrets.NPM_EMAIL }} + NPM_AUTH_TOKEN: ${{ secrets.NPM_RELEASE_AUTH_TOKEN }} + GH_TOKEN: ${{ secrets.UI5_WEBCOMP_BOT_GH_TOKEN }} + run: | + npm config set //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN} + git config user.name "${{ secrets.UI5_WEBCOMP_BOT_NAME }}" + git config user.email "${{ secrets.UI5_WEBCOMP_BOT_EMAIL }}" + yarn lerna version --conventional-prerelease --force-publish --yes --exact --create-release github + - name: Build run: yarn ci:releasebuild @@ -28,9 +40,4 @@ jobs: NPM_EMAIL: ${{ secrets.NPM_EMAIL }} NPM_AUTH_TOKEN: ${{ secrets.NPM_RELEASE_AUTH_TOKEN }} GH_TOKEN: ${{ secrets.UI5_WEBCOMP_BOT_GH_TOKEN }} - run: | - npm config set //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN} - git config user.name "${{ secrets.UI5_WEBCOMP_BOT_NAME }}" - git config user.email "${{ secrets.UI5_WEBCOMP_BOT_EMAIL }}" - yarn lerna version --conventional-prerelease --force-publish --yes --exact --create-release github - yarn lerna publish from-git --yes + run: yarn lerna publish from-git --yes diff --git a/.github/workflows/release-stable.yaml b/.github/workflows/release-stable.yaml index bdd2b1b9f690..f66597ea11f2 100644 --- a/.github/workflows/release-stable.yaml +++ b/.github/workflows/release-stable.yaml @@ -29,10 +29,7 @@ jobs: - name: Install run: yarn --frozen-lockfile - - name: Release Build - run: yarn ci:releasebuild - - - name: Publish + - name: Version Bump env: NPM_USERNAME: ${{ secrets.NPM_USER }} NPM_EMAIL: ${{ secrets.NPM_EMAIL }} @@ -45,4 +42,14 @@ jobs: yarn lerna version ${{ github.event.inputs.release_type }}\ ${{ (github.event.inputs.prerelease == 'true' && '--conventional-prerelease') || '--conventional-graduate' }} \ --force-publish --yes --exact --create-release github - yarn lerna publish from-git --yes + + - name: Build + run: yarn ci:releasebuild + + - name: Publish + env: + NPM_USERNAME: ${{ secrets.NPM_USER }} + NPM_EMAIL: ${{ secrets.NPM_EMAIL }} + NPM_AUTH_TOKEN: ${{ secrets.NPM_RELEASE_AUTH_TOKEN }} + GH_TOKEN: ${{ secrets.UI5_WEBCOMP_BOT_GH_TOKEN }} + run: yarn lerna publish from-git --yes diff --git a/.gitignore b/.gitignore index 5f6ccc114b03..cb02f5b69700 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Ignore .gitignore, target, dist and tmp folders .gitignore !packages/create-package/template/.gitignore +!packages/website/.gitignore tmp temp target @@ -84,6 +85,8 @@ packages/playground/docs/FAQ.md # Ignore the generated storybook related files packages/playground/_stories/**/*/argTypes.ts packages/playground/_stories/**/*/*Overview.mdx +packages/playground/_stories/**/Enums.mdx +packages/playground/_stories/**/Interfaces.mdx packages/playground/.storybook/custom-elements.json packages/playground/docs/storybook/**/* packages/playground/docs/storybook-pages/**/* diff --git a/.vscode/settings.json b/.vscode/settings.json index af9dc2e363fa..444d5bf4a118 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,5 +4,10 @@ "./packages/localization", "./packages/main", "./packages/fiori", - ] + ], + "html.customData": [ + "./packages/base/dist/vscode.html-custom-data.json", + "./packages/main/dist/vscode.html-custom-data.json", + "./packages/fiori/dist/vscode.html-custom-data.json" + ], } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c4a4a75305c..78a5330532d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,207 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.24.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v1.24.0-rc.0...v1.24.0-rc.1) (2024-03-15) + + +### Bug Fixes + +* **ui5-multi-combobox:** pasting content should not be prevented ([#8413](https://github.com/SAP/ui5-webcomponents/issues/8413)) ([db0b63c](https://github.com/SAP/ui5-webcomponents/commit/db0b63c8e745db23fb44816fcbfe999257071353)), closes [#8275](https://github.com/SAP/ui5-webcomponents/issues/8275) + + +### Features + +* **ui5-li:** highlight property added ([#8421](https://github.com/SAP/ui5-webcomponents/issues/8421)) ([1a3fa61](https://github.com/SAP/ui5-webcomponents/commit/1a3fa617199e5599b5beeebc503121ca3112f0a0)), closes [#8317](https://github.com/SAP/ui5-webcomponents/issues/8317) +* **ui5-side-navigation:** add navigation groups ([#8261](https://github.com/SAP/ui5-webcomponents/issues/8261)) ([8678dc0](https://github.com/SAP/ui5-webcomponents/commit/8678dc0ec8f017a41ac5bdcd7720bc055d28891c)) +* **ui5-tabcontainer, ui5-list:** add events for reordering items by mouse ([#8265](https://github.com/SAP/ui5-webcomponents/issues/8265)) ([c4383ea](https://github.com/SAP/ui5-webcomponents/commit/c4383eaaa3b5588658f13a9c468d778e9c6abf57)) + + + + + +# [1.24.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v1.23.1...v1.24.0-rc.0) (2024-03-14) + + +### Bug Fixes + +* **ui5-avatar:** fix default size appearance and font-family ([#8415](https://github.com/SAP/ui5-webcomponents/issues/8415)) ([22826f0](https://github.com/SAP/ui5-webcomponents/commit/22826f05c11f8be6b4ce037d6488e78fec634f99)) +* **ui5-bar:** align subheader style ([#8412](https://github.com/SAP/ui5-webcomponents/issues/8412)) ([e42a976](https://github.com/SAP/ui5-webcomponents/commit/e42a976162314251b4c13d7b6850a80fcc2faffb)), closes [#8079](https://github.com/SAP/ui5-webcomponents/issues/8079) +* **ui5-button:** remove bold font of emphasized button in safari and chrome ([#8422](https://github.com/SAP/ui5-webcomponents/issues/8422)) ([19ca981](https://github.com/SAP/ui5-webcomponents/commit/19ca981b9a18f938416083659043f49d7b57aeda)) +* **ui5-date/time-picker, ui5-step-input:** prevent text selection ([#8397](https://github.com/SAP/ui5-webcomponents/issues/8397)) ([220eac4](https://github.com/SAP/ui5-webcomponents/commit/220eac4000ef995703f4fe32ac1b7faadc7539f7)) +* **ui5-message-strip:** remove aria-live ([#8398](https://github.com/SAP/ui5-webcomponents/issues/8398)) ([9dc902e](https://github.com/SAP/ui5-webcomponents/commit/9dc902ecfc24c8e23feb87370e74851c277e657d)), closes [#8394](https://github.com/SAP/ui5-webcomponents/issues/8394) +* **ui5-multi-combobox:** rename togglePopover method ([#8418](https://github.com/SAP/ui5-webcomponents/issues/8418)) ([d1d6f7e](https://github.com/SAP/ui5-webcomponents/commit/d1d6f7ee71534251fc7d9f98b10adc8c736b607a)) +* **ui5-panel:** prevent border cut on horizon themes ([#8400](https://github.com/SAP/ui5-webcomponents/issues/8400)) ([fc2421f](https://github.com/SAP/ui5-webcomponents/commit/fc2421feb2de3c8301293f6e303738b8c0e20269)), closes [#8369](https://github.com/SAP/ui5-webcomponents/issues/8369) +* **ui5-shellbar:** fix volatile test ([#8411](https://github.com/SAP/ui5-webcomponents/issues/8411)) ([7e6bf4b](https://github.com/SAP/ui5-webcomponents/commit/7e6bf4b15a437f2795d5fa791f1df07122bc0121)), closes [#8409](https://github.com/SAP/ui5-webcomponents/issues/8409) + + +### Features + +* **ui5-barcode-scanner-dialog:** add 'open' property ([#8316](https://github.com/SAP/ui5-webcomponents/issues/8316)) ([8f59d16](https://github.com/SAP/ui5-webcomponents/commit/8f59d166c55af5f692520ff3b88b09aca28738c3)), closes [#8072](https://github.com/SAP/ui5-webcomponents/issues/8072) +* **ui5-checkbox:** csspart icon added ([#8423](https://github.com/SAP/ui5-webcomponents/issues/8423)) ([ab97c02](https://github.com/SAP/ui5-webcomponents/commit/ab97c02cdcfe2d9f9b823eb007d67bd22fe8faf5)), closes [#8326](https://github.com/SAP/ui5-webcomponents/issues/8326) +* **ui5-list:** growintButtonText property added ([#8349](https://github.com/SAP/ui5-webcomponents/issues/8349)) ([3ad5a90](https://github.com/SAP/ui5-webcomponents/commit/3ad5a908d5cb64143102ceda03ea60e2238b791b)), closes [#7028](https://github.com/SAP/ui5-webcomponents/issues/7028) + + + + + +## [1.23.1](https://github.com/SAP/ui5-webcomponents/compare/v1.23.1-rc.0...v1.23.1) (2024-03-08) + + +### Bug Fixes + +* **ui5-icon:** default icon color aligned with specification ([#8376](https://github.com/SAP/ui5-webcomponents/issues/8376)) ([7915a8c](https://github.com/SAP/ui5-webcomponents/commit/7915a8cf7416da70244bf5e8e959a5cee8e25624)), closes [#8375](https://github.com/SAP/ui5-webcomponents/issues/8375) +* **ui5-progress-indicator:** visual fix ([#8333](https://github.com/SAP/ui5-webcomponents/issues/8333)) ([012fc4d](https://github.com/SAP/ui5-webcomponents/commit/012fc4d070daab7c6851bbf3abb5bc0d718c7465)), closes [#8306](https://github.com/SAP/ui5-webcomponents/issues/8306) + + + + + +## [1.23.1-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v1.23.0...v1.23.1-rc.0) (2024-03-07) + +**Note:** Version bump only for package ui5-webcomponents + + + + + +# [1.23.0](https://github.com/SAP/ui5-webcomponents/compare/v1.23.0-rc.5...v1.23.0) (2024-03-06) + + +### Bug Fixes + +* **ui5-breadcrumbs:** fixed not working separators ([#8383](https://github.com/SAP/ui5-webcomponents/issues/8383)) ([ca733c1](https://github.com/SAP/ui5-webcomponents/commit/ca733c1c7034b03edcc51bbaf3153385e1b70d22)) +* **ui5-combobox:** show all items upon arrow click ([#8373](https://github.com/SAP/ui5-webcomponents/issues/8373)) ([c9dab87](https://github.com/SAP/ui5-webcomponents/commit/c9dab87ebfad72a784c7115dd8ef983e35c022b1)), closes [#8267](https://github.com/SAP/ui5-webcomponents/issues/8267) +* **ui5-date-picker:** open correct picker ([#8371](https://github.com/SAP/ui5-webcomponents/issues/8371)) ([78b98a5](https://github.com/SAP/ui5-webcomponents/commit/78b98a546cdff7569ff716f63b4daf434678837a)), closes [#8218](https://github.com/SAP/ui5-webcomponents/issues/8218) +* **ui5-side-navigation:** fix private types ([#8158](https://github.com/SAP/ui5-webcomponents/issues/8158)) ([a03921c](https://github.com/SAP/ui5-webcomponents/commit/a03921cc4ad90418d3ca9dd2241a3cafe24e4fff)) +* **ui5-switch:** align icon on iOS devices ([#8356](https://github.com/SAP/ui5-webcomponents/issues/8356)) ([f373305](https://github.com/SAP/ui5-webcomponents/commit/f373305cbb5ace38afd002c34e134d5a40b02efe)) +* **ui5-table:** highlight popined selected rows ([#8372](https://github.com/SAP/ui5-webcomponents/issues/8372)) ([5c6af14](https://github.com/SAP/ui5-webcomponents/commit/5c6af14feff211b9bb9c66056e45f51cbc13da06)) + + +### Features + +* **ui5-illustrated-message:** introduced "Dot" size ([#8343](https://github.com/SAP/ui5-webcomponents/issues/8343)) ([9c88f36](https://github.com/SAP/ui5-webcomponents/commit/9c88f36112888c1a766875611eb2a0aecbbc6f23)), closes [#8328](https://github.com/SAP/ui5-webcomponents/issues/8328) +* **ui5-textarea:** select and scroll events ([#8340](https://github.com/SAP/ui5-webcomponents/issues/8340)) ([5565a53](https://github.com/SAP/ui5-webcomponents/commit/5565a53460b5acbc379e09322b91d8b06b538b85)) + + + + + +# [1.23.0-rc.5](https://github.com/SAP/ui5-webcomponents/compare/v1.23.0-rc.4...v1.23.0-rc.5) (2024-02-29) + + +### Bug Fixes + +* remove sap.ui.require call from unused openui5 module ([#8359](https://github.com/SAP/ui5-webcomponents/issues/8359)) ([50219ac](https://github.com/SAP/ui5-webcomponents/commit/50219ac23add7b86fe26d8ca51e2181f01404992)) +* **ui5-avatar:** resolve initial flickering during fallback to icon ([#8351](https://github.com/SAP/ui5-webcomponents/issues/8351)) ([845b6f7](https://github.com/SAP/ui5-webcomponents/commit/845b6f75e93c25d475ba5a43aaae5c109f9b27f2)) +* **ui5-button:** correct focus outline colors in active/focus state ([#8325](https://github.com/SAP/ui5-webcomponents/issues/8325)) ([32385a7](https://github.com/SAP/ui5-webcomponents/commit/32385a7eada38aa248d1339ea52313491f1e5206)) +* **ui5-illustrated-message:** title subtitle aligned with visual spec ([#8344](https://github.com/SAP/ui5-webcomponents/issues/8344)) ([84fb0d9](https://github.com/SAP/ui5-webcomponents/commit/84fb0d94d0bf9597f10147ca4dff0fcbfc0570ff)), closes [#7879](https://github.com/SAP/ui5-webcomponents/issues/7879) +* **ui5-menu:** improve focus handling ([#8348](https://github.com/SAP/ui5-webcomponents/issues/8348)) ([bd33dc5](https://github.com/SAP/ui5-webcomponents/commit/bd33dc527ed2d96224f5dbef03d87506defa227f)) +* **ui5-side-navigation:** fix broken storybook example ([57e1eb9](https://github.com/SAP/ui5-webcomponents/commit/57e1eb96691a9d2712f43539c27c8e9f14e0c9d3)), closes [#8305](https://github.com/SAP/ui5-webcomponents/issues/8305) +* **ui5-time-picker:** remove redundant aria attributes ([#8350](https://github.com/SAP/ui5-webcomponents/issues/8350)) ([0d0a592](https://github.com/SAP/ui5-webcomponents/commit/0d0a5920617fd1532ef1260b24c80bf7fbc103e0)), closes [#6931](https://github.com/SAP/ui5-webcomponents/issues/6931) + + +### Features + +* **ui5-button:** add accessible-role api ([#8366](https://github.com/SAP/ui5-webcomponents/issues/8366)) ([18a5370](https://github.com/SAP/ui5-webcomponents/commit/18a5370eee92a2874398fee5d4852f4072d08283)), closes [#7612](https://github.com/SAP/ui5-webcomponents/issues/7612) + + + + + +# [1.23.0-rc.4](https://github.com/SAP/ui5-webcomponents/compare/v1.23.0-rc.3...v1.23.0-rc.4) (2024-02-26) + + +### Bug Fixes + +* **ui5-li-notification-group:** expand arrow visible ([#8329](https://github.com/SAP/ui5-webcomponents/issues/8329)) ([b2ca2a2](https://github.com/SAP/ui5-webcomponents/commit/b2ca2a299ebde195c5c16902a00969b6ada85f26)), closes [#8302](https://github.com/SAP/ui5-webcomponents/issues/8302) +* **ui5-popup:** move popup registry to shared resource ([#8338](https://github.com/SAP/ui5-webcomponents/issues/8338)) ([8c53a18](https://github.com/SAP/ui5-webcomponents/commit/8c53a180fd1945847cbc59439a5ed31e3b7f12e4)) +* **ui5-tab-container:** correct inline mode visualization ([#8335](https://github.com/SAP/ui5-webcomponents/issues/8335)) ([60b5b2c](https://github.com/SAP/ui5-webcomponents/commit/60b5b2cd08ce4e72508d25e69a50e4184c865d9e)), closes [#8274](https://github.com/SAP/ui5-webcomponents/issues/8274) + + +### Features + +* **ui5-radio-button:** expose new Css shadow parts ([#8347](https://github.com/SAP/ui5-webcomponents/issues/8347)) ([eca19da](https://github.com/SAP/ui5-webcomponents/commit/eca19dac3d22d4a6667dde1019e6ff5bf1c13410)), closes [#8105](https://github.com/SAP/ui5-webcomponents/issues/8105) + + + + + +# [1.23.0-rc.3](https://github.com/SAP/ui5-webcomponents/compare/v1.23.0-rc.2...v1.23.0-rc.3) (2024-02-22) + + +### Bug Fixes + +* **ui5-timeline-item:** correct content check ([#8295](https://github.com/SAP/ui5-webcomponents/issues/8295)) ([414087f](https://github.com/SAP/ui5-webcomponents/commit/414087f676d83ba1a0e62e1bd929fcd9f9718e4d)) + + +### Features + +* **ui5-color-palette:** implement mobile view ([#8315](https://github.com/SAP/ui5-webcomponents/issues/8315)) ([eea8317](https://github.com/SAP/ui5-webcomponents/commit/eea8317b0b8342f0ecb23ecb2a880cf3071c2c92)) +* **ui5-menu:** enable navigation over disabled items ([#8312](https://github.com/SAP/ui5-webcomponents/issues/8312)) ([fe9d1dc](https://github.com/SAP/ui5-webcomponents/commit/fe9d1dce999a9ab0c0c4413882bba246cc283126)), closes [#7096](https://github.com/SAP/ui5-webcomponents/issues/7096) [#8214](https://github.com/SAP/ui5-webcomponents/issues/8214) + + + + + +# [1.23.0-rc.2](https://github.com/SAP/ui5-webcomponents/compare/v1.23.0-rc.1...v1.23.0-rc.2) (2024-02-20) + + +### Features + +* **ui5-li:** add tooltip support to list items ([#8301](https://github.com/SAP/ui5-webcomponents/issues/8301)) ([1bbf381](https://github.com/SAP/ui5-webcomponents/commit/1bbf38134dde26257bf95847ca9ab416ba7ab7ee)), closes [#7372](https://github.com/SAP/ui5-webcomponents/issues/7372) + + + + + +# [1.23.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v1.23.0-rc.0...v1.23.0-rc.1) (2024-02-19) + + +### Bug Fixes + +* **tools:** fix usage of require in mjs ([#8258](https://github.com/SAP/ui5-webcomponents/issues/8258)) ([cbca059](https://github.com/SAP/ui5-webcomponents/commit/cbca059b926a8a5473d1f13690b6670239aafb8e)) +* **ui5-illustrated-message:** improved story and documentation ([#8294](https://github.com/SAP/ui5-webcomponents/issues/8294)) ([9740fe2](https://github.com/SAP/ui5-webcomponents/commit/9740fe21baa34233a66a4aea02f261fe1f5992f2)) + + + + + +# [1.23.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v1.22.1-rc.0...v1.23.0-rc.0) (2024-02-15) + + +### Bug Fixes + +* setting configuration before boot ([#8246](https://github.com/SAP/ui5-webcomponents/issues/8246)) ([d73834b](https://github.com/SAP/ui5-webcomponents/commit/d73834bd06516d5f663f14ecb516e92624191300)) +* **ui5-card-header:** truncate long single-word description ([#8247](https://github.com/SAP/ui5-webcomponents/issues/8247)) ([b79aef7](https://github.com/SAP/ui5-webcomponents/commit/b79aef7751bc4e562fd38ebc006c74bd93c1b33e)), closes [#8245](https://github.com/SAP/ui5-webcomponents/issues/8245) +* **ui5-illustrated-message:** aligned with visual specification ([#8266](https://github.com/SAP/ui5-webcomponents/issues/8266)) ([143d4af](https://github.com/SAP/ui5-webcomponents/commit/143d4afccfa1046f08c17e591e2749304afcac49)) +* **ui5-tree-item:** fix background color on hover ([#8278](https://github.com/SAP/ui5-webcomponents/issues/8278)) ([1a28393](https://github.com/SAP/ui5-webcomponents/commit/1a2839351d0af3badc4331409b13f4ef67ebba50)) + + +### Features + +* **ui5-calendar-legend:** introduce ui5-calendar-legend component ([#7706](https://github.com/SAP/ui5-webcomponents/issues/7706)) ([909a602](https://github.com/SAP/ui5-webcomponents/commit/909a6028362b55e26fdb5ca7a1ed68c8c6197a6b)) +* **ui5-rating-indicator:** introduced "remaining-bar" CSS part ([#8276](https://github.com/SAP/ui5-webcomponents/issues/8276)) ([7f46b0b](https://github.com/SAP/ui5-webcomponents/commit/7f46b0b9a6f91b52f466b0c617d6ece9a541e950)), closes [#8213](https://github.com/SAP/ui5-webcomponents/issues/8213) +* **ui5-side-navigation:** add external link icon ([#8199](https://github.com/SAP/ui5-webcomponents/issues/8199)) ([47e28c5](https://github.com/SAP/ui5-webcomponents/commit/47e28c5c50c824dfb743b79998c4d98f56be4beb)) +* **ui5-step-input:** add value-state-change event ([#8225](https://github.com/SAP/ui5-webcomponents/issues/8225)) ([8ab3ad1](https://github.com/SAP/ui5-webcomponents/commit/8ab3ad160d27bec5f9a77a41f534f480ec6481d0)), closes [#4791](https://github.com/SAP/ui5-webcomponents/issues/4791) [#5130](https://github.com/SAP/ui5-webcomponents/issues/5130) + + + + + +## [1.22.1-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v1.22.0...v1.22.1-rc.0) (2024-02-08) + + +### Bug Fixes + +* cast ariaHasPopup acc attribute to lowercase ([#8239](https://github.com/SAP/ui5-webcomponents/issues/8239)) ([6692284](https://github.com/SAP/ui5-webcomponents/commit/66922847d6cbc545c500c661d18facac7c2f609c)) +* **ui5-shellbar:** fixed secondaryTitle visual presentation ([#8221](https://github.com/SAP/ui5-webcomponents/issues/8221)) ([b3e0a80](https://github.com/SAP/ui5-webcomponents/commit/b3e0a80157615c22b89d7fb0857d22275cb83710)), closes [#8189](https://github.com/SAP/ui5-webcomponents/issues/8189) +* **ui5-table:** prevent load-more event on initial load ([#8240](https://github.com/SAP/ui5-webcomponents/issues/8240)) ([3ea5c66](https://github.com/SAP/ui5-webcomponents/commit/3ea5c664aaf20908ab04a933a7587c35206aebf6)) +* **ui5-tree-item:** fix double announcement ([#8139](https://github.com/SAP/ui5-webcomponents/issues/8139)) ([5af60a2](https://github.com/SAP/ui5-webcomponents/commit/5af60a2d4e5196b94a842f1adadfb4aa2d6672a7)), closes [#6878](https://github.com/SAP/ui5-webcomponents/issues/6878) + + + + + # [1.22.0](https://github.com/SAP/ui5-webcomponents/compare/v1.22.0-rc.3...v1.22.0) (2024-02-05) diff --git a/README.md b/README.md index a65efb7ec7b3..231ae434b4c7 100644 --- a/README.md +++ b/README.md @@ -113,8 +113,8 @@ Edge | Latest This section might be of interest to you mainly if you need to run or build the project locally ### Requirements -- [Node.js](https://nodejs.org/) (**version 14 or higher**) -- [Yarn](https://yarnpkg.com/en) +- [Node.js](https://nodejs.org/) (**version 20 or higher**) +- [Yarn](https://yarnpkg.com/en) (**version 1.22 or higher**) **Note:** The UI5 Web Components project is set up with the [Yarn](https://yarnpkg.com/) node package manager. This is because it offers functionality that the otherwise preferred [npm](https://www.npmjs.com/) package manager is currently lacking. Namely, the [workspace](https://yarnpkg.com/lang/en/docs/workspaces/) setting which is currently used in the [UI5 Web Components (mono-)repository](https://github.com/SAP/ui5-webcomponents). Note that npm [might add](https://github.com/npm/npm/pull/15900#issuecomment-315335381) this feature in the future. @@ -145,18 +145,19 @@ yarn start # to serve the project A dev server will be started and the browser will open its index URL with a listing of all test pages. -You can start the Playground app with the following commands: +### How to start Website (Docs & Samples): +You can start the website app with the following commands: ```sh yarn # to install all dependencies # start the playground from the project root -yarn start:playground +yarn start:website -# open http://localhost:6006/ +# open http://localhost:3000/ui5-webcomponents/nightly/ ``` -**Note:** If you wish to manually install dependencies & run the Playground you can check out our [in depth tutorial](./docs/6-contributing/03-playground-app.md) +**Note:** If you wish to manually install dependencies & run the Playground you can check out our [in depth tutorial](./docs/6-contributing/03-website.md) ### Production Build To build the UI5 Web Components project, run the following commands: diff --git a/docs/1-getting-started/01-first-steps.md b/docs/1-getting-started/01-first-steps.md index 6fd93d0d6100..5ea43a577a01 100644 --- a/docs/1-getting-started/01-first-steps.md +++ b/docs/1-getting-started/01-first-steps.md @@ -59,7 +59,7 @@ This command downloads the published source code of the UI5 Web Components to th ### Documentation -Take a look at the available UI5 Web Components documentation in the [playground](./playground/docs/). +Take a look at the available UI5 Web Components documentation in the [playground](https://sap.github.io/ui5-webcomponents/playground). ### Usage @@ -108,5 +108,3 @@ dist/assets/vendor.c05c7785.js 114.92kb / brotli: 24.30kb The contents 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. - -Next: [Importing UI5 Web Components](./02-importing-components.md) diff --git a/docs/1-getting-started/02-importing-components.md b/docs/1-getting-started/02-importing-components.md index af1c31948c6f..6a4085a686e7 100644 --- a/docs/1-getting-started/02-importing-components.md +++ b/docs/1-getting-started/02-importing-components.md @@ -54,5 +54,3 @@ For example: **Note:** For most components the name of the module (f.e. `Button.js`, `Icon.js`) coincides with the name of the tag (`ui5-button`, `ui5-icon`), whereas for others this is not the case (f.e. `StandardListItem.js` and `ui5-li`). Always consult the documentation when in doubt. - -Next: [Understanding UI5 Web Components APIs](./03-understanding-components-apis.md) diff --git a/docs/1-getting-started/03-understanding-components-APIs.md b/docs/1-getting-started/03-understanding-components-APIs.md index 3fbc62baa751..49ff3863a348 100644 --- a/docs/1-getting-started/03-understanding-components-APIs.md +++ b/docs/1-getting-started/03-understanding-components-APIs.md @@ -222,7 +222,7 @@ Please, note, however that some frameworks (e.g. React) cannot use their standar for binding to custom events (such as `close`), but only for standard ones (such as `click`). So, for custom events in React you'd have to get a reference to the element and call `addEventListener` manually. -For more information, please check our [React tutorial](React-tutorial.md). +For more information, please check our [React tutorial](../4-frameworks/01-React.md). ## 5. How do I call public methods? @@ -242,5 +242,3 @@ Consult the documentation for the available public methods for each UI5 Web Comp As you can see from this article, UI5 Web Components, being HTML elements in the first place, comply with the same rules. There are some novelties that come with the Web Components standard, such as `slot`, but otherwise everything else is what you already know and use from HTML. - -Next: [Using Icons](./04-using-icons.md) diff --git a/docs/1-getting-started/04-using-icons.md b/docs/1-getting-started/04-using-icons.md index d936b39253f7..4611dbc878b1 100644 --- a/docs/1-getting-started/04-using-icons.md +++ b/docs/1-getting-started/04-using-icons.md @@ -171,5 +171,3 @@ Tip: for multi-colored icons, you can specify multiple SVG elements and put a fi ``` - -Next: [Using Additional Assets](./05-using-assets.md) diff --git a/docs/1-getting-started/05-using-assets.md b/docs/1-getting-started/05-using-assets.md index 638e46190e6d..aba008fa3dc1 100644 --- a/docs/1-getting-started/05-using-assets.md +++ b/docs/1-getting-started/05-using-assets.md @@ -55,4 +55,3 @@ The `ui5-date-picker` component will have all translatable texts in Spanish, and Additional assets are `.json` files with the respective data. When you import the `dist/Assets.js` file of a given package, assets are only **registered**, but not yet fetched. When they are needed, they are loaded on the fly with **dymamic imports**, and then used. -Next: [Using Additional Features](./06-using-features.md) diff --git a/docs/1-getting-started/06-using-features.md b/docs/1-getting-started/06-using-features.md index 2f48a83032af..cd9d677d991e 100644 --- a/docs/1-getting-started/06-using-features.md +++ b/docs/1-getting-started/06-using-features.md @@ -65,5 +65,3 @@ import "@ui5/webcomponents/dist/Button.js"; import "@ui5/webcomponents/dist/Link.js"; import "@ui5/webcomponents/dist/Input.js"; ``` - -Next: [Typescript Support](./07-typescript-support) diff --git a/docs/1-getting-started/07-typescript-support.md b/docs/1-getting-started/07-typescript-support.md index 502f1ca5812d..7d21a9a89786 100644 --- a/docs/1-getting-started/07-typescript-support.md +++ b/docs/1-getting-started/07-typescript-support.md @@ -39,6 +39,3 @@ You will get a TypeScript error: ```html Argument of type 'boolean' is not assignable to parameter of type 'string'. ``` - - -Next: [Wrapping Up](./08-wrapping-up) diff --git a/docs/2-advanced/01-configuration.md b/docs/2-advanced/01-configuration.md index 82790cf57395..66e41afa9e52 100644 --- a/docs/2-advanced/01-configuration.md +++ b/docs/2-advanced/01-configuration.md @@ -297,5 +297,3 @@ import { getFirstDayOfWeek } from "@ui5/webcomponents-base/dist/config/FormatSet ```js import { getFetchDefaultLanguage, setFetchDefaultLanguage } from "@ui5/webcomponents-base/dist/config/Language.js"; ``` - -Next: [Right-To-Left (RTL) And Compact Mode](./02-rtl-and-compact-mode.md) diff --git a/docs/2-advanced/02-RTL-and-compact-mode.md b/docs/2-advanced/02-RTL-and-compact-mode.md index 9f6fc53d8adf..a46a2b0f7d93 100644 --- a/docs/2-advanced/02-RTL-and-compact-mode.md +++ b/docs/2-advanced/02-RTL-and-compact-mode.md @@ -82,5 +82,3 @@ Example 2: (Compact mode will be set for Button 2 and Button 3.) Unlike RTL, compact mode does not require additional APIs when its markers are changed dynamically. - -Next: [Micro-Frontends and Custom Elements Scoping](./03-scoping.md) diff --git a/docs/2-advanced/03-scoping.md b/docs/2-advanced/03-scoping.md index ec22e205c9f6..3f17cf4d6d0b 100644 --- a/docs/2-advanced/03-scoping.md +++ b/docs/2-advanced/03-scoping.md @@ -89,5 +89,3 @@ having the word `-test-` in their name are not scoped. Setting scoping rules is handy if, for example, your library uses both standard and custom UI5 Web Components and you don't want to scope the custom ones (as no disambiguation will be necessary for them). - -Next: [OpenUI5 Integration](./04-openui5-integration.md) diff --git a/docs/2-advanced/04-OpenUI5-integration.md b/docs/2-advanced/04-OpenUI5-integration.md index 76c9de33676f..85b16298ae06 100644 --- a/docs/2-advanced/04-OpenUI5-integration.md +++ b/docs/2-advanced/04-OpenUI5-integration.md @@ -30,5 +30,3 @@ When you import the above module: Therefore, if you intend to run both frameworks in the same browser window, it is highly recommended to enable OpenUI5 support and benefit from these optimizations. - -Next: [Using the Framework](./05-other-framework-level-apis.md) diff --git a/docs/2-advanced/05-other-framework-level-APIs.md b/docs/2-advanced/05-other-framework-level-APIs.md index f314cbeeaca9..58e91038949c 100644 --- a/docs/2-advanced/05-other-framework-level-APIs.md +++ b/docs/2-advanced/05-other-framework-level-APIs.md @@ -21,5 +21,3 @@ attachBoot(() => { console.log("Framework booted"); }); ``` - -Next: [UI5 Web Components i18n for Apps](./06-using-i18n-for-apps.md) diff --git a/docs/2-advanced/06-using-i18n-for-apps.md b/docs/2-advanced/06-using-i18n-for-apps.md index 9ee90eb055bc..4b081413da5b 100644 --- a/docs/2-advanced/06-using-i18n-for-apps.md +++ b/docs/2-advanced/06-using-i18n-for-apps.md @@ -6,7 +6,7 @@ None of the code below implies or requires the usage of UI5 Web Components, and The `@ui5/webcomponents-base` package allows the usage of `i18n` functionality not just for UI5 Web Components, but for apps as well. -*Note:* This section is dedicated to apps. For information on how to set up `i18n` for your custom components, please see [Developing Web Components](../5-development/02-custom-ui5-web-components.md). +*Note:* This section is dedicated to apps. For information on how to set up `i18n` for your custom components, please see [Developing Web Components](../5-development/02-custom-UI5-Web-Components.md). ## Step-by-Step Tutorial @@ -116,5 +116,3 @@ and return the data directly in `.json` format if you want to load a little bit | `assets/messagebundle_es.json` | `{"PLEASE_WAIT": "Espere"}` | | `assets/messagebundle_en.json` | `{"PLEASE_WAIT": "Please wait"}` | - -Next: [Accessibility](./07-accessibility.md) diff --git a/docs/2-advanced/07-accessibility.md b/docs/2-advanced/07-accessibility.md index a86deee708f9..7a958f9b59b6 100644 --- a/docs/2-advanced/07-accessibility.md +++ b/docs/2-advanced/07-accessibility.md @@ -341,5 +341,3 @@ In order to process the issues correctly, we would like to have the following in Have in mind that UI5 Web Components is optimized for the High Contrast mode of Windows when using Chrome and Edge. If you have enabled both the Windows High Contrast setting and the SAPUI5 High Contrast theme and you are using browser different than Chrome and Edge this may cause conflicts, and deficiencies in the theme can occur. In such cases, please switch off the Windows High Contrast setting or use different browser. - -Next: [CSP](./08-csp.md) diff --git a/docs/2-advanced/08-CSP.md b/docs/2-advanced/08-CSP.md index af924c97dac6..e68f391e2b2c 100644 --- a/docs/2-advanced/08-CSP.md +++ b/docs/2-advanced/08-CSP.md @@ -99,4 +99,3 @@ that support them (Chrome, Edge) out of the box. For the other browsers (Firefox achieve CSP-compliance, you must instruct the framework to use `` instead of ` +``` + +- Most of the modern build tools know how to handle CSS imports and could add the imported CSS file content as `style` tag for us: + +```ts +import "/mytheme.css"; +``` + + +### 2. Configuring the Custom Theme + +In the previous step we loaded the CSS, now we only need to set it to the UI5 Web Components. +To do so, you can use one of the standard APIs for setting a theme: + +- With URL parameter: `index.html?sap-ui-theme=mytheme` + +- With JS API: +```ts +import { getTheme, setTheme } from "@ui5/webcomponents-base/dist/config/Theme.js"; + +setTheme("mytheme"); +``` + +# Resources + +Everything said so far is implemented in the following demo project - [ui5-webcomponents-custom-theme](https://github.com/ilhan007/ui5-webcomponents-custom-theme/). +The project implements the script for producing the custom CSS vars and provides a simple test page to demonstrate the custom theme usage. diff --git a/docs/3-customizing/03-fonts.md b/docs/3-customizing/04-fonts.md similarity index 97% rename from docs/3-customizing/03-fonts.md rename to docs/3-customizing/04-fonts.md index 6064b9951242..9d18f744a8bd 100644 --- a/docs/3-customizing/03-fonts.md +++ b/docs/3-customizing/04-fonts.md @@ -1,6 +1,6 @@ # Custom Fonts -## The `data-ui5-font-face` Font-Face `style` Tag +## The data-ui5-font-face style tag Upon `boot`, the UI5 Web Components framework creates a ` + \ No newline at end of file diff --git a/packages/main/test/pages/kitchen-scripts.js b/packages/main/test/pages/kitchen-scripts.js index 500f6d782936..89bc1a5f341d 100644 --- a/packages/main/test/pages/kitchen-scripts.js +++ b/packages/main/test/pages/kitchen-scripts.js @@ -5,7 +5,6 @@ document.addEventListener("DOMContentLoaded", function(event) { var mainContent = document.getElementById("main-content"); var Configuration = window["sap-ui-webcomponents-bundle"].configuration; var COMPACT_CLASS = "ui5-content-density-compact"; - var RTL = Configuration.getRTL(); var THEME = Configuration.getTheme(); var HCB = "sap_belize_hcb"; var FIORI3 = "sap_fiori_3"; @@ -15,12 +14,6 @@ document.addEventListener("DOMContentLoaded", function(event) { var btnTheme = document.getElementById("btnTheme"); var btnLightDark = document.getElementById("btnLightDark"); - if (RTL) { - document.body.setAttribute("dir", "rtl"); - } else { - document.body.removeAttribute("dir"); - } - /* SideNav */ function toggleSideNav(toggle) { if (toggle) { @@ -45,12 +38,16 @@ document.addEventListener("DOMContentLoaded", function(event) { return currentURL.slice(0, currentURL.indexOf(".html")) + params; } - btnRTL.pressed = !!RTL; btnTheme.pressed = !!(THEME === HCB); btnLightDark.pressed = !!(THEME === FIORI3_DARK); btnRTL.addEventListener('click', function(e) { - window.location.href = buildURL(e.target.pressed, btnRTL.pressed, THEME); + if (e.target.pressed) { + document.body.setAttribute("dir", "rtl"); + } else { + document.body.removeAttribute("dir"); + } + window['sap-ui-webcomponents-bundle'].applyDirection(); }, false); btnCompact.addEventListener('click', function(e) { diff --git a/packages/main/test/pages/styles/List.css b/packages/main/test/pages/styles/List.css index e3f47ec2d579..9ee70c8e7d01 100644 --- a/packages/main/test/pages/styles/List.css +++ b/packages/main/test/pages/styles/List.css @@ -22,3 +22,7 @@ align-items: center; justify-content: space-between } + +.largeTopMargin { + margin-top: 2rem; +} \ No newline at end of file diff --git a/packages/main/test/pages/styles/RadioButton.css b/packages/main/test/pages/styles/RadioButton.css index 98dc33d1c0bd..9ef5c1249b18 100644 --- a/packages/main/test/pages/styles/RadioButton.css +++ b/packages/main/test/pages/styles/RadioButton.css @@ -22,3 +22,18 @@ div { .radiobutton2auto { width: 300px } + +div.customStyling{ + width: 100%; +} + +.customStyling #customRb1:hover::part(inner-ring) { + fill: #20b7d5; +} + +.customStyling ui5-radio-button[value-state="Error"]::part(outer-ring) { + stroke: rgb(212 56 247); +} +.customStyling ui5-radio-button[value-state="Success"]::part(outer-ring) { + stroke: rgb(12 223 147); +} \ No newline at end of file diff --git a/packages/main/test/specs/Button.spec.js b/packages/main/test/specs/Button.spec.js index ac807c903cc2..e7600d440431 100644 --- a/packages/main/test/specs/Button.spec.js +++ b/packages/main/test/specs/Button.spec.js @@ -143,4 +143,15 @@ describe("Button general interaction", () => { assert.strictEqual(await nativeButton.getAttribute("title"), "Download", "Icon tooltip is shown"); }); + + it("setting accessible-role on the host is reflected on the button tag", async () => { + const button = await browser.$("#button-role-link").shadow$("button"); + + assert.strictEqual(await button.getAttribute("role"), "link", "Attribute is reflected"); + }); + it("not setting accessible-role on the host keeps the correct role on the button tag", async () => { + const button = await browser.$("#button1").shadow$("button"); + + assert.strictEqual(await button.getAttribute("role"), "button", "Attribute is reflected"); + }); }); diff --git a/packages/main/test/specs/CalendarLegend.spec.js b/packages/main/test/specs/CalendarLegend.spec.js new file mode 100644 index 000000000000..fd2bbdd9f78b --- /dev/null +++ b/packages/main/test/specs/CalendarLegend.spec.js @@ -0,0 +1,85 @@ +import { assert } from "chai"; + +describe("Calendar Legend with standard items", () => { + before(async () => { + await browser.url(`test/pages/CalendarLegend.html`); + }) + + it("Calendar Legend is rendered", async () => { + const legend = await browser.$("#calendarLegend").shadow$(".ui5-calendar-legend-root"); + + assert.ok(legend, "Calendar Legend is rendered"); + }); + + it("Calendar Legend items are rendered", async () => { + const legend = await browser.$("#calendarLegend").shadow$(".ui5-calendar-legend-root"); + const items = await legend.$$("ui5-calendar-legend-item"); + + assert.strictEqual(items.length, 4, "Calendar Legend items are rendered"); + }); + + + it("Calendar legend hides Today, when hideToday property provided", async () => { + const legend = await browser.$("#calendarLegend"); + let items = await legend.shadow$(".ui5-calendar-legend-root").$$("ui5-calendar-legend-item"); + + legend.setProperty("hideToday", true); + + // get the items again + items = await legend.shadow$(".ui5-calendar-legend-root").$$("ui5-calendar-legend-item"); + + assert.strictEqual(items.length, 3, "Today item in Calendar Legend is hidden"); + }); + + it("Calendar legend hides Selected, when hideSelectedDay property provided", async () => { + const legend = await browser.$("#calendarLegend"); + let items = await legend.shadow$(".ui5-calendar-legend-root").$$("ui5-calendar-legend-item"); + + legend.setProperty("hideSelectedDay", true); + + // get the items again + items = await legend.shadow$(".ui5-calendar-legend-root").$$("ui5-calendar-legend-item"); + + assert.strictEqual(items.length, 2, "Selected item in Calendar Legend is hidden"); + }); + + it("Focusing item in Calendar Legend filter the corresponding days in Calendar", async () => { + const legend = await browser.$("#calendarLegend"); + const items = await legend.shadow$(".ui5-calendar-legend-root").$$("ui5-calendar-legend-item"); + const calendar = await browser.$("#calendar1").shadow$(".ui5-cal-root"); + + await items[0].click(); + await browser.keys("ArrowDown"); + await browser.keys("ArrowDown"); + await browser.keys("ArrowDown"); + + const dayPicker = await calendar.$("#ui5wc_22-daypicker"); + const filteredDays = await dayPicker.shadow$$("[special-day]"); + + assert.strictEqual(filteredDays.length, 1, "Only one day is filtered"); + }); + + it("Focusing item in the legend and then focus out, reset filtered days", async () => { + const legend = await browser.$("#calendarLegend"); + const items = await legend.shadow$(".ui5-calendar-legend-root").$$("ui5-calendar-legend-item"); + const calendar = await browser.$("#calendar1").shadow$(".ui5-cal-root"); + + await items[0].click(); + await browser.keys("ArrowDown"); + await browser.keys("ArrowDown"); + await browser.keys("ArrowDown"); + await browser.keys("ArrowDown"); + + const dayPicker = await calendar.$("#ui5wc_22-daypicker"); + let filteredDays = await dayPicker.shadow$$("[special-day]"); + + assert.strictEqual(filteredDays.length, 1, "Days are filtered"); + + await calendar.click(); + + // get the items again + filteredDays = await dayPicker.shadow$$("[special-day]"); + + assert.strictEqual(filteredDays.length, 20, "Days are un-filtered") + }); +}) \ No newline at end of file diff --git a/packages/main/test/specs/ComboBox.spec.js b/packages/main/test/specs/ComboBox.spec.js index b5cc6c0a3947..c4bf7f6925d7 100644 --- a/packages/main/test/specs/ComboBox.spec.js +++ b/packages/main/test/specs/ComboBox.spec.js @@ -604,6 +604,25 @@ describe("General interaction", () => { assert.strictEqual(await $("#clear-icon-change-count").getText(), "1", "change event is fired once"); assert.strictEqual(await $("#clear-icon-input-count").getText(), "1", "input event is fired once"); }); + + it ("Should show all items if value does not match any item and arrow is pressed", async () => { + await browser.url(`test/pages/ComboBox.html`); + + const cb = await $("#combo"); + const arrow = await cb.shadow$("[input-icon]"); + const input = cb.shadow$("input"); + + await input.click(); + await input.keys("z"); + await arrow.click(); + + const staticAreaItemClassName = await browser.getStaticAreaItemClassName("#combo"); + const popover = await browser.$(`.${staticAreaItemClassName}`).shadow$("ui5-responsive-popover"); + let listItems = await popover.$("ui5-list").$$("ui5-li"); + + // assert + assert.strictEqual(listItems.length, 11, "All items are shown"); + }); }); describe("Grouping", () => { diff --git a/packages/main/test/specs/DatePicker.spec.js b/packages/main/test/specs/DatePicker.spec.js index e2d55fce74f9..4fb1f80d6def 100644 --- a/packages/main/test/specs/DatePicker.spec.js +++ b/packages/main/test/specs/DatePicker.spec.js @@ -15,7 +15,7 @@ describe("Date Picker Tests", () => { assert.ok(await input.isDisplayedInViewport(), "input is rendered"); assert.ok(await innerInput.isDisplayedInViewport(), "inner input is rendered"); assert.strictEqual(await innerInput.getAttribute("aria-roledescription"), "Date Input", "aria-roledescription attribute is added."); - assert.strictEqual(await innerInput.getAttribute("aria-haspopup"), "Grid", "aria-haspopup attribute is added."); + assert.strictEqual(await innerInput.getAttribute("aria-haspopup"), "grid", "aria-haspopup attribute is added."); assert.notOk(await innerInput.getAttribute("aria-controls"), "aria-controls attribute isn't rendered."); assert.notOk(await innerInput.getAttribute("aria-expanded"), "aria-expanded attribute isn't rendered."); }); @@ -1345,4 +1345,28 @@ describe("Date Picker Tests", () => { assert.strictEqual(await input.getProperty("valueState"), valueState, "value state is not changed"); }); + + it("should open date picker in daypicker", async () => { + datepicker.id = "#dpCalendarModeMonths"; + + const calendar = await datepicker.getCalendar(); + const datepickerRoot = await datepicker.getRoot(); + await datepicker.openPicker(); + + let currentPicker = await calendar.getProperty("_currentPicker"); + assert.equal(currentPicker, "month", "calendar is opened on months"); + + await datepickerRoot.setAttribute("format-pattern", "yyyy, dd/MM"); + await datepicker.openPicker(); + currentPicker = await calendar.getProperty("_currentPicker"); + + assert.equal(currentPicker, "day", "calendar is opened on days"); + + const dayPicker = await calendar.shadow$("ui5-daypicker"); + const monthPicker = await calendar.shadow$("ui5-monthpicker"); + const yearPicker = await calendar.shadow$("ui5-yearpicker"); + assert.notOk(await dayPicker.getAttribute("hidden")); + assert.ok(await monthPicker.getAttribute("hidden")); + assert.ok(await yearPicker.getAttribute("hidden")); + }); }); diff --git a/packages/main/test/specs/Link.spec.js b/packages/main/test/specs/Link.spec.js index d2f731078165..25f8e75ebad2 100644 --- a/packages/main/test/specs/Link.spec.js +++ b/packages/main/test/specs/Link.spec.js @@ -83,7 +83,7 @@ describe("General API", () => { it("Open dialog link has propper aria-haspopup attribute", async () => { const link = await browser.$("#signInLink"); - assert.strictEqual(await link.shadow$("a").getAttribute("aria-haspopup"), "Dialog", "Proper aria-haspopup attribute is set"); + assert.strictEqual(await link.shadow$("a").getAttribute("aria-haspopup"), "dialog", "Proper aria-haspopup attribute is set"); }); it("setting accessible-name applied on the host element is reflected on the anchor tag", async () => { diff --git a/packages/main/test/specs/List.spec.js b/packages/main/test/specs/List.spec.js index db8c7e0d6e30..cf1d582d95eb 100644 --- a/packages/main/test/specs/List.spec.js +++ b/packages/main/test/specs/List.spec.js @@ -581,12 +581,12 @@ describe("List Tests", () => { const innerElement = await browser.$("#effectiveTabindexChange #country11 button"); const listItem = await browser.$("#effectiveTabindexChange #country11"); const rootItemElement = await listItem.shadow$(".ui5-li-root"); - + // Focus on the target list item await innerElement.click(); - + const newTabIndex = await rootItemElement.getAttribute("tabindex"); - + assert.equal(newTabIndex , "0", "The tabIndex of the list item root should be '0' when inner element receives focus."); }); @@ -597,4 +597,154 @@ describe("List Tests", () => { assert.strictEqual(display.value, 'inline-block', "The end marker is displayed"); }); + + it("Checks if tooltip property value equals the title of li element", async () => { + const listItem = await browser.$("#myList7 ui5-li"); + + let rootTooltip = await listItem.getProperty("tooltip"); + let innerTooltip = await listItem.shadow$("li").getAttribute("title"); + + assert.strictEqual(rootTooltip, innerTooltip, "Tooltip of root element and title of inner li element are equal."); + + const newTooltip = "Updated tooltip"; + await listItem.setProperty("tooltip", newTooltip); + + rootTooltip = await listItem.getProperty("tooltip"); + innerTooltip = await listItem.shadow$("li").getAttribute("title"); + + assert.strictEqual(rootTooltip, newTooltip, "Tooltip of root element is updated correctly at runtime."); + assert.strictEqual(rootTooltip, innerTooltip, "Tooltip of root element and title of inner li element are equal after runtime change."); + }); + + it("Tests the highlight property", async () => { + const listItem = await browser.$("#highlight ui5-li:nth-child(1)"); + const initialValueState = "Error"; + let highlightValue = await listItem.getProperty("highlight"); + + assert.strictEqual(highlightValue, initialValueState, "Highlight property is correctly set to the list item."); + + const newValueState = "Information"; + await listItem.setProperty("highlight", "Information"); + highlightValue = await listItem.getProperty("highlight"); + + assert.strictEqual(highlightValue, newValueState, "Highlight property is correctly changed."); + + }); + + it("Tests the growingButtonText property", async () => { + const list = await browser.$("#infiniteScrollEx2"); + const btnText = "Custom text" + let growingBtnText = await list.getProperty("growingButtonText"); + + assert.strictEqual(growingBtnText, btnText, "GrowingButtonText property is correctly set to the list."); + + const newBtnText = "New custom text"; + await list.setProperty("growingButtonText", newBtnText); + growingBtnText = await list.getProperty("growingButtonText"); + + assert.strictEqual(growingBtnText, newBtnText, "GrowingButtonText property is correctly changed."); + + }); +}); + +describe("List drag and drop tests", () => { + const getDragOffset = async (draggedElement, dropTargetElement, targetPosition) => { + const EXTRA_OFFSET = 5; + const draggedRectangle = { + ...await draggedElement.getLocation(), + ...await draggedElement.getSize() + }; + + const dropTargetElementRectangle = { + ...await dropTargetElement.getLocation(), + ...await dropTargetElement.getSize() + } + + const draggedElementCenter = (draggedRectangle.y + draggedRectangle.height / 2); + const droppedElementCenter = (dropTargetElementRectangle.y + dropTargetElementRectangle.height / 2); + + let offsetToCenter = Math.round(droppedElementCenter - draggedElementCenter); + + if (targetPosition === "Before") { + offsetToCenter -= EXTRA_OFFSET + } else if (targetPosition === "After") { + offsetToCenter += EXTRA_OFFSET; + } + + return offsetToCenter; + }; + + const compareItemsOrder = async (listId, expectedItems) => { + const listItems = await browser.$$(`#${listId} > *`); + const results = await Promise.all(expectedItems.map((item, i) => item.isEqual(listItems[i]))); + + return results.every(value => value); + } + + before(async () => { + await browser.url(`test/pages/ListDragAndDrop.html`); + }); + + it("Moving item After another", async () => { + const [firstItem, secondItem, thirdItem] = await browser.$$("#listDnd1 [ui5-li]"); + + let dragOffset = await getDragOffset(firstItem, secondItem, "After"); + await firstItem.dragAndDrop({ x: 0, y: dragOffset}); + assert.ok(await compareItemsOrder("listDnd1", [secondItem, firstItem, thirdItem]), "Items order has changed"); + + dragOffset = await getDragOffset(firstItem, thirdItem, "After"); + await firstItem.dragAndDrop({ x: 0, y: dragOffset}); + assert.ok(await compareItemsOrder("listDnd1", [secondItem, thirdItem, firstItem]), "Items order has changed"); + }); + + it("Moving item Before another", async () => { + const [secondItem, thirdItem, firstItem] = await browser.$$("#listDnd1 [ui5-li]"); + + let dragOffset = await getDragOffset(firstItem, thirdItem, "Before"); + await firstItem.dragAndDrop({ x: 0, y: dragOffset}); + assert.ok(await compareItemsOrder("listDnd1", [secondItem, firstItem, thirdItem]), "Items order has changed"); + + dragOffset = await getDragOffset(firstItem, secondItem, "Before") + await firstItem.dragAndDrop({ x: 0, y: dragOffset}); + assert.ok(await compareItemsOrder("listDnd1", [firstItem, secondItem, thirdItem]), "Items order has changed"); + }); + + it("Moving item ON another", async () => { + const [firstItem, secondItem, thirdItem] = await browser.$$("#listDnd2 [ui5-li]"); + + await firstItem.dragAndDrop({ x: 0, y: 0 }); + assert.ok(await compareItemsOrder("listDnd2", [firstItem, secondItem, thirdItem]), "Items order has NOT changed"); + + const dragOffset = await getDragOffset(firstItem, secondItem); + await firstItem.dragAndDrop({ x: 0, y: dragOffset}); + assert.ok(await compareItemsOrder("listDnd2", [secondItem, thirdItem]), "Items order has changed"); + assert.ok(await secondItem.$("[ui5-li]").isEqual(firstItem), "First item is nested in second item"); + }); + + it("Moving item from one list to another", async () => { + const [listOneFirstItem, listOneSecondItem, listOneThirdItem] = await browser.$$("#listDnd1 [ui5-li]"); + const listTwoItem = await browser.$("#bg2") + + const dragOffset = await getDragOffset(listTwoItem, listOneFirstItem, "After"); + await listTwoItem.dragAndDrop({ x: 0, y: dragOffset}); + assert.ok(await compareItemsOrder("listDnd1", [listOneFirstItem, listTwoItem, listOneSecondItem, listOneThirdItem]), "Items order has changed"); + }); + + it("Moving link to list that doesn't accept it", async () => { + const [firstItem, secondItem, thirdItem] = await browser.$$("#listDnd1 [ui5-li]"); + const link = await browser.$("#link") + + const dragOffset = await getDragOffset(link, firstItem, "After"); + await link.dragAndDrop({ x: 0, y: dragOffset}); + assert.ok(await compareItemsOrder("listDnd1", [firstItem, secondItem, thirdItem]), "Items order has NOT changed"); + }); + + it("Moving link to list that accepts it", async () => { + const [firstItem, secondItem] = await browser.$$("#listDnd2 [ui5-li]"); + const link = await browser.$("#link") + + const dragOffset = await getDragOffset(link, secondItem, "Before"); + await link.dragAndDrop({ x: 0, y: dragOffset}); + assert.ok(await compareItemsOrder("listDnd2", [firstItem, link, secondItem]), "Items order has changed"); + }); }); diff --git a/packages/main/test/specs/Menu.spec.js b/packages/main/test/specs/Menu.spec.js index 69d255036728..b9d6eebacdd6 100644 --- a/packages/main/test/specs/Menu.spec.js +++ b/packages/main/test/specs/Menu.spec.js @@ -28,13 +28,13 @@ describe("Menu interaction", () => { it("Top level menu items appearance", async () => { await browser.url(`test/pages/Menu.html`); const openButton = await browser.$("#btnOpen"); - const menuItems = await browser.$$("ui5-menu>ui5-menu-item"); + const menuItems = await browser.$$("ui5-menu[id='menu']>ui5-menu-item"); openButton.click(); const staticAreaItemClassName = await browser.getStaticAreaItemClassName("#menu"); const popover = await browser.$(`.${staticAreaItemClassName}`).shadow$("ui5-responsive-popover"); - const listItems = await popover.$("ui5-list").$$("ui5-li"); + const listItems = await popover.$("ui5-list").$$("ui5-menu-li"); assert.strictEqual(await menuItems.length, 7, "There are proper count of menu items in the top level menu"); assert.strictEqual(await listItems.length, 7, "There are proper count of list items in the top level menu popover list"); @@ -54,7 +54,7 @@ describe("Menu interaction", () => { const staticAreaItemClassName = await browser.getStaticAreaItemClassName("#menu"); const staticAreaItem = await browser.$(`.${staticAreaItemClassName}`); const popover = staticAreaItem.shadow$("ui5-responsive-popover"); - const listItems = await popover.$("ui5-list").$$("ui5-li"); + const listItems = await popover.$("ui5-list").$$("ui5-menu-li"); const submenuList = await staticAreaItem.shadow$(".ui5-menu-submenus"); listItems[3].click(); // open sub-menu @@ -87,7 +87,7 @@ describe("Menu interaction", () => { const staticAreaItemClassName = await browser.getStaticAreaItemClassName("#menu"); const popover = await browser.$(`.${staticAreaItemClassName}`).shadow$("ui5-responsive-popover"); - const listItems = await popover.$("ui5-list").$$("ui5-li"); + const listItems = await popover.$("ui5-list").$$("ui5-menu-li"); const selectionInput = await browser.$("#selectionInput"); await listItems[0].click({x: 1, y: 1}); @@ -103,7 +103,6 @@ describe("Menu interaction", () => { const staticAreaItemClassName = await browser.getStaticAreaItemClassName("#menu"); const popover = await browser.$(`.${staticAreaItemClassName}`).shadow$("ui5-responsive-popover"); - const listItems = await popover.$("ui5-list").$$("ui5-li"); const selectionInput = await browser.$("#selectionInput"); await browser.keys("Space"); @@ -119,7 +118,6 @@ describe("Menu interaction", () => { const staticAreaItemClassName = await browser.getStaticAreaItemClassName("#menu"); const popover = await browser.$(`.${staticAreaItemClassName}`).shadow$("ui5-responsive-popover"); - const listItems = await popover.$("ui5-list").$$("ui5-li"); const selectionInput = await browser.$("#selectionInput"); await browser.keys("Enter"); @@ -182,29 +180,45 @@ describe("Menu interaction", () => { await browser.pause(100); const menuPopover = await browser.$("ui5-static-area-item:last-of-type").shadow$("ui5-responsive-popover"); - const newFileItem = await menuPopover.$("ui5-li[accessible-name='New File']"); + const newFileItem = await menuPopover.$("ui5-menu-li[accessible-name='New File']"); newFileItem.click(); await browser.pause(100); assert.ok(await menuPopover.getProperty("open"), "Menu is still opened."); }); + + it("Enable navigaion over disabled items", async () => { + await browser.url(`test/pages/Menu.html`); + const openButton = await browser.$("#btnOpen"); + openButton.click(); + await browser.pause(100); + + const menuPopover = await browser.$("ui5-static-area-item:last-of-type").shadow$("ui5-responsive-popover"); + const listItem = await menuPopover.$("ui5-menu-li[accessible-name='Preferences']"); + listItem.click(); + await browser.pause(100); + + assert.ok(await listItem.getProperty("disabled"), "The menu item is disabled"); + assert.ok(await listItem.getProperty("focused"), "The menu item is focused"); + }); }); describe("Menu Accessibility", () => { it("Menu and Menu items accessibility attributes", async () => { await browser.url(`test/pages/Menu.html`); const openButton = await browser.$("#btnOpen"); - const menuItems = await browser.$$("ui5-menu>ui5-menu-item"); openButton.click(); const staticAreaItemClassName = await browser.getStaticAreaItemClassName("#menu"); const popover = await browser.$(`.${staticAreaItemClassName}`).shadow$("ui5-responsive-popover"); const list = await popover.$("ui5-list"); - const listItems = await popover.$("ui5-list").$$("ui5-li"); + const listItems = await popover.$("ui5-list").$$("ui5-menu-li"); assert.strictEqual(await list.getAttribute("accessible-role"), "menu", "There is proper 'menu' role for the menu list"); assert.strictEqual(await listItems[0].getAttribute("accessible-role"), "menuitem", "There is proper 'menuitem' role for the menu list items"); + assert.strictEqual(await listItems[0].getAttribute("tooltip"), "Select a file", "There is a tooltip"); + assert.strictEqual(await listItems[2].shadow$(".ui5-li-root").getAttribute("aria-haspopup"), "menu", "There is an aria-haspopup attribute"); assert.strictEqual( await listItems[0].getAttribute("accessible-name"), "New File Opens a file explorer", diff --git a/packages/main/test/specs/MultiComboBox.spec.js b/packages/main/test/specs/MultiComboBox.spec.js index eabd12529884..18590e4acf59 100644 --- a/packages/main/test/specs/MultiComboBox.spec.js +++ b/packages/main/test/specs/MultiComboBox.spec.js @@ -1354,10 +1354,15 @@ describe("MultiComboBox general interaction", () => { await input.click(); await input.keys(["Control", "v"]); - assert.equal(await mcb2.getProperty("value"), "Condensed", "Token is pasted into the second control"); + assert.strictEqual(await mcb2.getProperty("value"), "Condensed", "Token is pasted into the second control"); + assert.ok(await mcb2.getProperty("open"), "Condensed", "Popover should be open"); + + await input.keys(["Control", "v"]); + + assert.equal(await mcb2.getProperty("value"), "CondensedCondensed", "Pasting second time should append the as text"); }); - it ("should not be able to paste tokenwith CTRL+V in read only multi combo box", async () => { + 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"); diff --git a/packages/main/test/specs/RTL.spec.js b/packages/main/test/specs/RTL.spec.js index 5a2469c997c2..6256afd64294 100644 --- a/packages/main/test/specs/RTL.spec.js +++ b/packages/main/test/specs/RTL.spec.js @@ -1,24 +1,10 @@ import { assert } from "chai"; describe("RTL", () => { - it("language forces RTL, if RTL not specified", async () => { - await browser.url(`test/pages/Switch.html?sap-ui-language=he`); + it("tests effectiveDir", async () => { + await browser.url(`test/pages/RTL.html`); - const swRoot = await browser.$("#switchAccName").shadow$(".ui5-switch-root"); - assert.strictEqual(await swRoot.getProperty("dir"), "rtl", "dir is correctly set"); - }); - - it("config forces RTL", async () => { - await browser.url(`test/pages/Switch.html?sap-ui-rtl=true`); - - const swRoot = await browser.$("#switchAccName").shadow$(".ui5-switch-root"); - assert.strictEqual(await swRoot.getProperty("dir"), "rtl", "dir is correctly set"); - }); - - it("config unsets RTL, although rtl language is used", async () => { - await browser.url(`test/pages/Switch.html?sap-ui-rtl=false&sap-ui-language=he`); - - const swRoot = await browser.$("#switchAccName").shadow$(".ui5-switch-root"); - assert.notOk(await swRoot.getProperty("dir"), "dir is not present"); + assert.strictEqual(await browser.$("#cbRTL").getProperty("effectiveDir"), "rtl", "effectiveDir correctly returns 'rtl'"); + assert.strictEqual(await browser.$("#cbLTR").getProperty("effectiveDir"), "ltr", "effectiveDir correctly returns 'ltr'"); }); }); diff --git a/packages/main/test/specs/StepInput.spec.js b/packages/main/test/specs/StepInput.spec.js index 936059676c4b..82ca2a1546c8 100644 --- a/packages/main/test/specs/StepInput.spec.js +++ b/packages/main/test/specs/StepInput.spec.js @@ -456,6 +456,18 @@ describe("'change' event firing", () => { assert.strictEqual(Number(await changeResult.getProperty("value")), 2, "'change' event is fired 2 times"); }); + it("Value state is not changed, when value-state-change is prevented", async () => { + await browser.url(`test/pages/StepInput.html`); + const input = await browser.$("#stepInputValueStateChange").shadow$("ui5-input").shadow$("input"); + + const valueState = await input.getProperty("valueState"); + await input.click(); + await browser.keys("2"); + await browser.keys("Enter"); + + assert.strictEqual(await input.getProperty("valueState"), valueState, "value state is not changed"); + }); + }); describe("Accessibility related parameters", async () => { diff --git a/packages/main/test/specs/TabContainer.spec.js b/packages/main/test/specs/TabContainer.spec.js index bfc68b1aa6ca..72b22dcfc43b 100644 --- a/packages/main/test/specs/TabContainer.spec.js +++ b/packages/main/test/specs/TabContainer.spec.js @@ -1,4 +1,5 @@ import { assert } from "chai"; +import tabContainer from "../pageobjects/TabContainerTestPage.js"; describe("TabContainer general interaction", () => { before(async () => { @@ -55,6 +56,20 @@ describe("TabContainer general interaction", () => { await cbPrevent.click(); }); + it("tests custom media ranges", async () => { + await browser.setWindowSize(520, 1080); + assert.strictEqual(await browser.$("#tabContainerIconOnly").getAttribute("media-range"), "S", "media-range=S"); + + await browser.setWindowSize(650, 1080); + assert.strictEqual(await browser.$("#tabContainerIconOnly").getAttribute("media-range"), "M", "media-range=M"); + + await browser.setWindowSize(1350, 1080); + assert.strictEqual(await browser.$("#tabContainerIconOnly").getAttribute("media-range"), "L", "media-range=L"); + + await browser.setWindowSize(1650, 1080); + assert.strictEqual(await browser.$("#tabContainerIconOnly").getAttribute("media-range"), "XL", "media-range=XL"); + }); + it("tests if content is scrollable when tabcontainer takes limited height by its parent", async () => { const { tcHeight, tcScrollHeight } = await browser.executeAsync(done => { const scrollableContent = document.getElementById("tc-scrollable-child"); @@ -321,4 +336,258 @@ describe("TabContainer general interaction", () => { // Assert assert.ok(productsTabDomRefInStrip.isEqual(productsTabDomRefInStripExpected) , "Tab dom ref in strip should be the first child of the tab container's strip"); }); + + it("tests inline visualization", async () => { + const tabContainer = await browser.$("#tabContainerInlineTab"); + const firstTabItemText = await tabContainer.shadow$(".ui5-tab-strip-itemText"); + + // Assert + assert.notOk(await tabContainer.shadow$(".ui5-tab-strip-itemAdditionalText").isExisting(), "There is no additional text."); + assert.strictEqual(await firstTabItemText.getProperty("innerText"), "Tab 1 (123)" , "The inline number is added to the text."); + }); + +}); + +describe("TabContainer keyboard handling", () => { + before(async () => { + await browser.url(`test/pages/TabContainer.html`); + }); + + it("[Arrow Down] on two-click area tab", async () => { + const tabcontainer = await browser.$("#tabContainerNestedTabs"); + const item = tabcontainer.shadow$$(".ui5-tab-strip-item")[3]; + + assert.strictEqual(await item.getProperty("innerText"), "Four", "Correct tab is found"); + + await item.click(); + await item.keys("ArrowDown"); + + const staticAreaItemClassName = await browser.getStaticAreaItemClassName("#tabContainerNestedTabs"); + const popover = await browser.$(`.${staticAreaItemClassName}`).shadow$("ui5-responsive-popover"); + + assert.ok(await popover.isDisplayed(), "Popover is opened"); + }); +}); + +describe("TabContainer popover", () => { + before(async () => { + await browser.url(`test/pages/TabContainer.html`); + await browser.setWindowSize(860, 1000); + }); + + it("tests popover after new tab is inserted", async () => { + const tabcontainer = await browser.$("#tabContainerEndOverflow"); + const endOverflow = await tabcontainer.shadow$(".ui5-tc__overflow--end"); + await endOverflow.click(); + const staticAreaItemClassName = await browser.getStaticAreaItemClassName("#tabContainerEndOverflow"); + const popover = await browser.$(`.${staticAreaItemClassName}`).shadow$("ui5-responsive-popover"); + const listItemsCount = await popover.$$("[ui5-li-custom]").length; + + assert.ok(listItemsCount > 0, "There are items in the overflow"); + + // Act + await browser.executeAsync((done) => { + const newTab = document.createElement("ui5-tab"); + newTab.setAttribute("text", "New Tab"); + document.getElementById("tabContainerEndOverflow").insertBefore(newTab, null); + done(); + }); + + const newListItemsCount = await popover.$$("[ui5-li-custom]").length; + + assert.strictEqual(newListItemsCount, listItemsCount + 1, "Overflow list displays all its items"); + }); + + it("tests popover items indentation", async () => { + const tabcontainer = await browser.$("#tabContainerNestedTabs"); + const endOverflow = await tabcontainer.shadow$(".ui5-tc__overflow--end"); + await endOverflow.click(); + const staticAreaItemClassName = await browser.getStaticAreaItemClassName("#tabContainerNestedTabs"); + const popover = await browser.$(`.${staticAreaItemClassName}`).shadow$("ui5-responsive-popover"); + + const tabAssertions = [ + { tabText: "Ten", expectedIndent: 0 }, + { tabText: "Ten 1", expectedIndent: 8 }, + { tabText: "Ten 1.1", expectedIndent: 16 }, + { tabText: "Ten 1.1.1", expectedIndent: 24 }, + { tabText: "Ten 1.1.1.1", expectedIndent: 32 } + ].map(async ({ tabText, expectedIndent}) => { + const tab = await popover.$(`[ui5-li-custom]=${tabText}`) + const wrapper = await tab.$(".ui5-tab-overflow-itemContent-wrapper") + const paddingLeft = await wrapper.getCSSProperty("padding-left"); + + assert.strictEqual(paddingLeft.parsed.value, expectedIndent, "Tab indentation is correct"); + + return paddingLeft.parsed.value; + }); + + const paddings = await Promise.all(tabAssertions); + const sortedPaddings = [...paddings].sort((a, b) => a - b); + + assert.deepEqual(paddings, sortedPaddings, "Indentation hierarchy is correct"); + }); +}); + +describe("TabContainer drag and drop tests", () => { + const getDragOffset = async (draggedElement, dropTargetElement, targetPosition) => { + const OFFSET = 5; + const draggedRectangle = { + ...await draggedElement.getLocation(), + ...await draggedElement.getSize() + }; + + const dropTargetElementRectangle = { + ...await dropTargetElement.getLocation(), + ...await dropTargetElement.getSize() + }; + + const draggedElementXCenter = draggedRectangle.x + draggedRectangle.width / 2; + const draggedElementYCenter = draggedRectangle.y + draggedRectangle.height / 2; + + let dropTargetX; + let dropTargetY; + + if (targetPosition === "Before") { + dropTargetX = dropTargetElementRectangle.x + OFFSET; + dropTargetY = dropTargetElementRectangle.y + OFFSET; + } else if (targetPosition === "After") { + dropTargetX = dropTargetElementRectangle.x + dropTargetElementRectangle.width - OFFSET; + dropTargetY = dropTargetElementRectangle.y + dropTargetElementRectangle.height - OFFSET; + } else { // "On" + dropTargetX = dropTargetElementRectangle.x + dropTargetElementRectangle.width / 2; + dropTargetY = dropTargetElementRectangle.y + dropTargetElementRectangle.height / 2; + } + + const offsetToX = Math.round(dropTargetX - draggedElementXCenter); + const offsetToY = Math.round(dropTargetY - draggedElementYCenter); + + return { + x: offsetToX, + y: offsetToY + }; + }; + + const moveElementById = (arr, id1, id2) => { + const newArr = [...arr]; + const index1 = newArr.indexOf(id1); + const index2 = newArr.indexOf(id2); + + const [item] = newArr.splice(index1, 1); + newArr.splice(index2, 0, item); + + return newArr; + }; + + const dragAndDropInStrip = async (stripItemToDrag, stripDropTarget, placement) => { + const dragOffset = await getDragOffset(stripItemToDrag, stripDropTarget, placement); + + await stripItemToDrag.dragAndDrop({ x: dragOffset.x, y: 0 }); + } + + const dragAndDropInPopover = async (popoverItemToDrag, popoverDropTarget, placement) => { + const dragOffset = await getDragOffset(popoverItemToDrag, popoverDropTarget, placement); + console.error("DRAG IN DROP IN POPOVER ", dragOffset.y) + await popoverItemToDrag.dragAndDrop({ x: 0, y: dragOffset.y }); + } + + before(async () => { + await browser.url(`test/pages/TabContainerDragAndDrop.html`); + await browser.setWindowSize(1024, 1000); + }); + + it("Moving item After another", async () => { + await browser.$("#tabContainerDnd") + await tabContainer.getStartOverflow("tabContainerDnd") + await tabContainer.getEndOverflow("tabContainerDnd") + let displayedStripItems = await tabContainer.getDisplayedTabStripItems("tabContainerDnd"); + let draggedStripItem = displayedStripItems[0]; + let dropTargetStripItem = displayedStripItems[1]; + let currentOrder = await tabContainer.getItemsIds("tabContainerDnd"); + + await dragAndDropInStrip(draggedStripItem, dropTargetStripItem, "After"); + let expectedOrder = moveElementById(currentOrder, await tabContainer.getRealTabId(draggedStripItem), await tabContainer.getRealTabId(dropTargetStripItem)); + currentOrder = await tabContainer.getItemsIds("tabContainerDnd"); + assert.deepEqual(currentOrder, expectedOrder, "Items order has changed"); + + displayedStripItems = await tabContainer.getDisplayedTabStripItems("tabContainerDnd"); + draggedStripItem = displayedStripItems[1]; + dropTargetStripItem = displayedStripItems[displayedStripItems.length - 1]; + await dragAndDropInStrip(draggedStripItem, dropTargetStripItem, "After"); + expectedOrder = moveElementById(currentOrder, await tabContainer.getRealTabId(draggedStripItem), await tabContainer.getRealTabId(dropTargetStripItem)); + currentOrder = await tabContainer.getItemsIds("tabContainerDnd"); + assert.deepEqual(currentOrder, expectedOrder, "Items order has changed"); + }); + + it("Moving item Before another", async () => { + let displayedStripItems = await tabContainer.getDisplayedTabStripItems("tabContainerDnd"); + let draggedStripItem = displayedStripItems[displayedStripItems.length - 1]; + let dropTargetStripItem = displayedStripItems[displayedStripItems.length - 2]; + let currentOrder = await tabContainer.getItemsIds("tabContainerDnd"); + + await dragAndDropInStrip(draggedStripItem, dropTargetStripItem, "Before"); + let expectedOrder = moveElementById(currentOrder, await tabContainer.getRealTabId(draggedStripItem), await tabContainer.getRealTabId(dropTargetStripItem)); + currentOrder = await tabContainer.getItemsIds("tabContainerDnd"); + assert.deepEqual(currentOrder, expectedOrder, "Items order has changed"); + + displayedStripItems = await tabContainer.getDisplayedTabStripItems("tabContainerDnd"); + draggedStripItem = displayedStripItems[displayedStripItems.length - 1]; + dropTargetStripItem = displayedStripItems[0]; + await dragAndDropInStrip(draggedStripItem, dropTargetStripItem, "Before"); + expectedOrder = moveElementById(expectedOrder, await tabContainer.getRealTabId(draggedStripItem), await tabContainer.getRealTabId(dropTargetStripItem)); + currentOrder = await tabContainer.getItemsIds("tabContainerDnd"); + assert.deepEqual(currentOrder, expectedOrder, "Items order has changed"); + }); + + it ("Moving item On another", async () => { + let displayedStripItems = await tabContainer.getDisplayedTabStripItems("tabContainerDnd"); + let draggedStripItem = displayedStripItems[5]; + let draggedStripItemId = await tabContainer.getRealTabId(draggedStripItem); + let dropTargetStripItem = displayedStripItems[6]; + let currentOrder = await tabContainer.getItemsIds("tabContainerDnd"); + + await dragAndDropInStrip(draggedStripItem, draggedStripItem, "On"); + let expectedOrder = currentOrder; + currentOrder = await tabContainer.getItemsIds("tabContainerDnd"); + assert.deepEqual(currentOrder, expectedOrder, "Items order has NOT changed"); + + await dragAndDropInStrip(draggedStripItem, dropTargetStripItem, "On"); + expectedOrder = currentOrder.filter(id => id !== draggedStripItemId); + currentOrder = await tabContainer.getItemsIds("tabContainerDnd"); + assert.deepEqual(currentOrder, expectedOrder, "Items order has changed"); + }); + + it("Moving item After another in end overflow popover", async () => { + await tabContainer.getEndOverflow("tabContainerDnd").click(); + + let displayedPopoverItems = await tabContainer.getCurrentPopoverItems("tabContainerDnd"); + let draggedPopoverItem = displayedPopoverItems[0]; + let dropTargetPopoverItem = displayedPopoverItems[2]; + let currentOrder = await tabContainer.getItemsIds("tabContainerDnd"); + + await dragAndDropInPopover(draggedPopoverItem, dropTargetPopoverItem, "After"); + console.error(currentOrder); + let expectedOrder = moveElementById(currentOrder, await tabContainer.getRealTabId(draggedPopoverItem), await tabContainer.getRealTabId(dropTargetPopoverItem)); + currentOrder = await tabContainer.getItemsIds("tabContainerDnd"); + console.error(currentOrder); + console.error(expectedOrder); + + assert.deepEqual(currentOrder, expectedOrder, "Items order has changed"); + }); + + it("Moving item Before another in end overflow popover", async () => { + let displayedPopoverItems = await tabContainer.getCurrentPopoverItems("tabContainerDnd"); + let draggedPopoverItem = displayedPopoverItems[2]; + let dropTargetPopoverItem = displayedPopoverItems[1]; + let currentOrder = await tabContainer.getItemsIds("tabContainerDnd"); + + await dragAndDropInPopover(draggedPopoverItem, dropTargetPopoverItem, "Before"); + await browser.pause(10000); // TODO: this workaround avoids test crash. Find way to avoid it + + let expectedOrder = moveElementById(currentOrder, await tabContainer.getRealTabId(draggedPopoverItem), await tabContainer.getRealTabId(dropTargetPopoverItem)); + currentOrder = await tabContainer.getItemsIds("tabContainerDnd"); + assert.deepEqual(currentOrder, expectedOrder, "Items order has changed"); + + // close the popover + await tabContainer.getEndOverflow("tabContainerDnd").click(); + }); }); diff --git a/packages/main/test/specs/Table.spec.js b/packages/main/test/specs/Table.spec.js index 410721d1d8da..31f95bf76eab 100644 --- a/packages/main/test/specs/Table.spec.js +++ b/packages/main/test/specs/Table.spec.js @@ -195,6 +195,16 @@ describe("Table general interaction", () => { timeoutMsg: "The load-more event must be fired." }); }); + + it("tests 'loadMore' event not fired initially when the table does not overflow", async () => { + await browser.url(`test/pages/TableGrowingWithScroll.html`); + + await browser.pause(300); + + const inputResult = await browser.$("#inputLoadMoreInitialCounter"); + + assert.strictEqual(await inputResult.getAttribute("value"), "0", "The event load-more has not been fired."); + }); }); describe("Table selection modes", async () => { diff --git a/packages/main/test/specs/TextArea.spec.js b/packages/main/test/specs/TextArea.spec.js index 34d03b7cb52b..f74aeb487ec1 100644 --- a/packages/main/test/specs/TextArea.spec.js +++ b/packages/main/test/specs/TextArea.spec.js @@ -374,3 +374,29 @@ describe("Value update", () => { assert.strictEqual(count, selectionLength, "14 symbols should exceed"); }); }); + +describe("selection events", () => { + beforeEach(async () => { + await browser.url(`test/pages/TextArea-selection.html`); + }); + + it("fires select event", async () => { + const textAreaInner = await browser.$("#button-area").shadow$("textarea"); + const selectResult = await browser.$("#select-event-counter"); + + await textAreaInner.doubleClick(); + + assert.strictEqual(await selectResult.getText(), "1", "select is called"); + }); + + it("fires scroll event", async () => { + const scrollResult = await browser.$("#scroll-event-counter"); + + await browser.executeAsync(async (done) => { + document.getElementById("button-area").shadowRoot.querySelector("textarea").scrollTop = 100; + done(); + }); + + assert.strictEqual(await scrollResult.getText(), "1", "scroll event is called"); + }); +}); diff --git a/packages/playground/.storybook/decorators/useOptions.ts b/packages/playground/.storybook/decorators/useOptions.ts index 2da3c9eb2128..c716b40443c0 100644 --- a/packages/playground/.storybook/decorators/useOptions.ts +++ b/packages/playground/.storybook/decorators/useOptions.ts @@ -20,12 +20,14 @@ export const useOptions: DecoratorFunction = (StoryFn) => { const [{ theme, rtl, density }] = useGlobals(); useEffect(() => { - const Conf = window["sap-ui-webcomponents-bundle"].configuration; + const Bundle = window["sap-ui-webcomponents-bundle"]; + const Conf = Bundle.configuration; const currentTheme = themes[theme]; Conf.setTheme(currentTheme); document.body.setAttribute("dir", rtl === "RTL" ? "rtl" : "ltr"); + Bundle.applyDirection(); document.body.setAttribute("data-ui5-theme", currentTheme); document.body.classList.remove("sapUiSizeCozy"); diff --git a/packages/playground/.storybook/preview.ts b/packages/playground/.storybook/preview.ts index 1b63ac32170e..4f8accf4e163 100644 --- a/packages/playground/.storybook/preview.ts +++ b/packages/playground/.storybook/preview.ts @@ -103,7 +103,7 @@ export const globalTypes: GlobalTypes = { rtl: { name: "Direction", description: "Global rtl mode for components", - defaultValue: window["sap-ui-webcomponents-bundle"].configuration.getRTL(), + defaultValue: "LTR", toolbar: { icon: "", items: ["LTR", "RTL"], diff --git a/packages/playground/CHANGELOG.md b/packages/playground/CHANGELOG.md index 3800c3dc352e..bd879a1c370b 100644 --- a/packages/playground/CHANGELOG.md +++ b/packages/playground/CHANGELOG.md @@ -3,6 +3,123 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.24.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v1.24.0-rc.0...v1.24.0-rc.1) (2024-03-15) + + +### Features + +* **ui5-li:** highlight property added ([#8421](https://github.com/SAP/ui5-webcomponents/issues/8421)) ([1a3fa61](https://github.com/SAP/ui5-webcomponents/commit/1a3fa617199e5599b5beeebc503121ca3112f0a0)), closes [#8317](https://github.com/SAP/ui5-webcomponents/issues/8317) +* **ui5-side-navigation:** add navigation groups ([#8261](https://github.com/SAP/ui5-webcomponents/issues/8261)) ([8678dc0](https://github.com/SAP/ui5-webcomponents/commit/8678dc0ec8f017a41ac5bdcd7720bc055d28891c)) + + + + + +# [1.24.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v1.23.1...v1.24.0-rc.0) (2024-03-14) + + +### Features + +* **ui5-barcode-scanner-dialog:** add 'open' property ([#8316](https://github.com/SAP/ui5-webcomponents/issues/8316)) ([8f59d16](https://github.com/SAP/ui5-webcomponents/commit/8f59d166c55af5f692520ff3b88b09aca28738c3)), closes [#8072](https://github.com/SAP/ui5-webcomponents/issues/8072) +* **ui5-list:** growintButtonText property added ([#8349](https://github.com/SAP/ui5-webcomponents/issues/8349)) ([3ad5a90](https://github.com/SAP/ui5-webcomponents/commit/3ad5a908d5cb64143102ceda03ea60e2238b791b)), closes [#7028](https://github.com/SAP/ui5-webcomponents/issues/7028) + + + + + +## [1.23.1](https://github.com/SAP/ui5-webcomponents/compare/v1.23.1-rc.0...v1.23.1) (2024-03-08) + +**Note:** Version bump only for package @ui5/webcomponents-playground + + + + + +## [1.23.1-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v1.23.0...v1.23.1-rc.0) (2024-03-07) + +**Note:** Version bump only for package @ui5/webcomponents-playground + + + + + +# [1.23.0](https://github.com/SAP/ui5-webcomponents/compare/v1.23.0-rc.5...v1.23.0) (2024-03-06) + +**Note:** Version bump only for package @ui5/webcomponents-playground + + + + + +# [1.23.0-rc.5](https://github.com/SAP/ui5-webcomponents/compare/v1.23.0-rc.4...v1.23.0-rc.5) (2024-02-29) + + +### Bug Fixes + +* **ui5-side-navigation:** fix broken storybook example ([57e1eb9](https://github.com/SAP/ui5-webcomponents/commit/57e1eb96691a9d2712f43539c27c8e9f14e0c9d3)), closes [#8305](https://github.com/SAP/ui5-webcomponents/issues/8305) + + + + + +# [1.23.0-rc.4](https://github.com/SAP/ui5-webcomponents/compare/v1.23.0-rc.3...v1.23.0-rc.4) (2024-02-26) + +**Note:** Version bump only for package @ui5/webcomponents-playground + + + + + +# [1.23.0-rc.3](https://github.com/SAP/ui5-webcomponents/compare/v1.23.0-rc.2...v1.23.0-rc.3) (2024-02-22) + +**Note:** Version bump only for package @ui5/webcomponents-playground + + + + + +# [1.23.0-rc.2](https://github.com/SAP/ui5-webcomponents/compare/v1.23.0-rc.1...v1.23.0-rc.2) (2024-02-20) + + +### Features + +* **ui5-li:** add tooltip support to list items ([#8301](https://github.com/SAP/ui5-webcomponents/issues/8301)) ([1bbf381](https://github.com/SAP/ui5-webcomponents/commit/1bbf38134dde26257bf95847ca9ab416ba7ab7ee)), closes [#7372](https://github.com/SAP/ui5-webcomponents/issues/7372) + + + + + +# [1.23.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v1.23.0-rc.0...v1.23.0-rc.1) (2024-02-19) + + +### Bug Fixes + +* **ui5-illustrated-message:** improved story and documentation ([#8294](https://github.com/SAP/ui5-webcomponents/issues/8294)) ([9740fe2](https://github.com/SAP/ui5-webcomponents/commit/9740fe21baa34233a66a4aea02f261fe1f5992f2)) + + + + + +# [1.23.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v1.22.1-rc.0...v1.23.0-rc.0) (2024-02-15) + + +### Features + +* **ui5-calendar-legend:** introduce ui5-calendar-legend component ([#7706](https://github.com/SAP/ui5-webcomponents/issues/7706)) ([909a602](https://github.com/SAP/ui5-webcomponents/commit/909a6028362b55e26fdb5ca7a1ed68c8c6197a6b)) +* **ui5-side-navigation:** add external link icon ([#8199](https://github.com/SAP/ui5-webcomponents/issues/8199)) ([47e28c5](https://github.com/SAP/ui5-webcomponents/commit/47e28c5c50c824dfb743b79998c4d98f56be4beb)) + + + + + +## [1.22.1-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v1.22.0...v1.22.1-rc.0) (2024-02-08) + +**Note:** Version bump only for package @ui5/webcomponents-playground + + + + + # [1.22.0](https://github.com/SAP/ui5-webcomponents/compare/v1.22.0-rc.3...v1.22.0) (2024-02-05) **Note:** Version bump only for package @ui5/webcomponents-playground diff --git a/packages/playground/_stories/fiori/BarcodeScannerDialog/BarcodeScannerDialog.stories.ts b/packages/playground/_stories/fiori/BarcodeScannerDialog/BarcodeScannerDialog.stories.ts index 8492d3720e4d..9d0dcd6dac4a 100644 --- a/packages/playground/_stories/fiori/BarcodeScannerDialog/BarcodeScannerDialog.stories.ts +++ b/packages/playground/_stories/fiori/BarcodeScannerDialog/BarcodeScannerDialog.stories.ts @@ -8,45 +8,44 @@ import type { UI5StoryArgs } from "../../../types.js"; import type BarcodeScannerDialog from "@ui5/webcomponents-fiori/dist/BarcodeScannerDialog.js"; export default { - title: "Fiori/Barcode Scanner Dialog", - component: "BarcodeScannerDialog", - argTypes, + title: "Fiori/Barcode Scanner Dialog", + component: "BarcodeScannerDialog", + argTypes, } as Meta; const Template: UI5StoryArgs = ( - args + args ) => html` - + `; export const Basic = Template.bind({}); Basic.decorators = [ - (story) => html` ${story()} - Scan -
- - -
- `, + (story) => html` ${story()} +Scan +
+ + +
+ +`, ]; diff --git a/packages/playground/_stories/fiori/IllustratedMessage/IllustratedMessage.stories.ts b/packages/playground/_stories/fiori/IllustratedMessage/IllustratedMessage.stories.ts index 37a28a082afd..3151d74d240f 100644 --- a/packages/playground/_stories/fiori/IllustratedMessage/IllustratedMessage.stories.ts +++ b/packages/playground/_stories/fiori/IllustratedMessage/IllustratedMessage.stories.ts @@ -80,3 +80,7 @@ CustomTitle.args = { default: ` Try again`, }; + +CustomTitle.parameters = { + controls: { exclude: ['titleLevel'] }, +}; diff --git a/packages/playground/_stories/fiori/SideNavigation/SideNavigation.stories.ts b/packages/playground/_stories/fiori/SideNavigation/SideNavigation.stories.ts index eadba7a07174..c0df03703ee6 100644 --- a/packages/playground/_stories/fiori/SideNavigation/SideNavigation.stories.ts +++ b/packages/playground/_stories/fiori/SideNavigation/SideNavigation.stories.ts @@ -35,17 +35,26 @@ ${story()}`; export const Basic = Template.bind({}); Basic.args = { default: ` - - - + + + + + + + + + + + + + + + + `, + fixedItems: ` + - - - - - `, - fixedItems: ` - ` + `, }; Basic.decorators = [setHeight]; Basic.parameters = { @@ -61,17 +70,23 @@ Basic.parameters = { export const ToolLayout = Template.bind({}); ToolLayout.args = { default: ` - - - + + + + + + + + + + + + + `, + fixedItems: ` + - - - - - `, - fixedItems: ` - ` + `, }; ToolLayout.decorators = [ setHeight, @@ -95,10 +110,6 @@ ToolLayout.decorators = [ grid-template-columns: auto 1fr; } - .tool-layout > * { - z-index: 1; - } - ui5-shellbar { grid-column: 1 / span 2; grid-row: 1 / 2; diff --git a/packages/playground/_stories/fiori/SideNavigation/SideNavigationGroup/SideNavigationGroup.stories.ts b/packages/playground/_stories/fiori/SideNavigation/SideNavigationGroup/SideNavigationGroup.stories.ts new file mode 100644 index 000000000000..b2a8286cc587 --- /dev/null +++ b/packages/playground/_stories/fiori/SideNavigation/SideNavigationGroup/SideNavigationGroup.stories.ts @@ -0,0 +1,37 @@ +import { html } from "lit"; +import { unsafeHTML } from "lit/directives/unsafe-html.js"; +import { ifDefined } from "lit/directives/if-defined.js"; +import type { Meta } from "@storybook/web-components"; +import argTypes from "./argTypes.js"; +import type { StoryArgsSlots } from "./argTypes.js"; +import type { UI5StoryArgs } from "../../../../types.js"; + +import type SideNavigationGroup from "@ui5/webcomponents-fiori/dist/SideNavigationGroup.js"; + +export default { + title: "Fiori/Side Navigation/Side Navigation Group", + component: "SideNavigationGroup", + argTypes, +} as Meta; + +const Template: UI5StoryArgs = (args) => { + return html` + + + ${unsafeHTML(args.default)} + +`; +}; + +export const Basic = Template.bind({}); +Basic.tags = ["_hidden_"]; +Basic.args = { + text: "Group", + expanded: true, + disabled: false, + default: `` +}; \ No newline at end of file diff --git a/packages/playground/_stories/fiori/SideNavigation/SideNavigationItem/SideNavigationItem.stories.ts b/packages/playground/_stories/fiori/SideNavigation/SideNavigationItem/SideNavigationItem.stories.ts index 24feb168a25c..88dab865d31d 100644 --- a/packages/playground/_stories/fiori/SideNavigation/SideNavigationItem/SideNavigationItem.stories.ts +++ b/packages/playground/_stories/fiori/SideNavigation/SideNavigationItem/SideNavigationItem.stories.ts @@ -21,6 +21,7 @@ const Template: UI5StoryArgs = (args) => { text="${ifDefined(args.text)}" icon="${ifDefined(args.icon)}" ?expanded="${ifDefined(args.expanded)}" + ?disabled="${ifDefined(args.disabled)}" ?whole-item-toggleable="${ifDefined(args.wholeItemToggleable)}" href="${ifDefined(args.href)}" ?selected="${ifDefined(args.selected)}" diff --git a/packages/playground/_stories/fiori/SideNavigation/SideNavigationSubItem/SideNavigationSubItem.stories.ts b/packages/playground/_stories/fiori/SideNavigation/SideNavigationSubItem/SideNavigationSubItem.stories.ts index 45949fb827e7..34faf44fc79a 100644 --- a/packages/playground/_stories/fiori/SideNavigation/SideNavigationSubItem/SideNavigationSubItem.stories.ts +++ b/packages/playground/_stories/fiori/SideNavigation/SideNavigationSubItem/SideNavigationSubItem.stories.ts @@ -19,9 +19,9 @@ const Template: UI5StoryArgs = (args) => diff --git a/packages/playground/_stories/fiori/UploadCollection/UploadCollectionItem/UploadCollectionItem.stories.ts b/packages/playground/_stories/fiori/UploadCollection/UploadCollectionItem/UploadCollectionItem.stories.ts index 24d254747646..44eded6c5d0b 100644 --- a/packages/playground/_stories/fiori/UploadCollection/UploadCollectionItem/UploadCollectionItem.stories.ts +++ b/packages/playground/_stories/fiori/UploadCollection/UploadCollectionItem/UploadCollectionItem.stories.ts @@ -29,6 +29,7 @@ const Template: UI5StoryArgs = (args) => { ?hide-delete-button="${ifDefined(args.hideDeleteButton)}" ?hide-retry-button="${ifDefined(args.hideRetryButton)}" ?hide-terminate-button="${ifDefined(args.hideTerminateButton)}" + tooltip="${ifDefined(args.tooltip)}" > ${unsafeHTML(args.default)} ${unsafeHTML(args.thumbnail)} diff --git a/packages/playground/_stories/main/Calendar/Calendar.stories.ts b/packages/playground/_stories/main/Calendar/Calendar.stories.ts index 32dd7efe3249..5b59deddffc6 100644 --- a/packages/playground/_stories/main/Calendar/Calendar.stories.ts +++ b/packages/playground/_stories/main/Calendar/Calendar.stories.ts @@ -43,4 +43,63 @@ CalendarTypes.storyName = "Primary and Secondary Calendar Types"; CalendarTypes.args = { primaryCalendarType: CalendarType.Japanese, secondaryCalendarType: CalendarType.Islamic, -}; \ No newline at end of file +}; + +export const CalendarWithLegend = Template.bind({}); +CalendarWithLegend.storyName = "Calendar with Calendar Legend"; +CalendarWithLegend.args = { + default: ` + + + + + + + + + + + + + + + `, +}; +CalendarWithLegend.decorators = [ + (story) => html` + ${story()} + +`, +]; \ No newline at end of file diff --git a/packages/playground/_stories/main/Calendar/SpecialCalendarDate/SpecialCalendarDate.stories.ts b/packages/playground/_stories/main/Calendar/SpecialCalendarDate/SpecialCalendarDate.stories.ts new file mode 100644 index 000000000000..621352ad862b --- /dev/null +++ b/packages/playground/_stories/main/Calendar/SpecialCalendarDate/SpecialCalendarDate.stories.ts @@ -0,0 +1,30 @@ +import { html } from "lit"; +import { ifDefined } from "lit/directives/if-defined.js"; +import { unsafeHTML } from "lit/directives/unsafe-html.js"; +import type { Meta } from "@storybook/web-components"; + +import argTypes from "./argTypes.js"; +import type { StoryArgsSlots } from "./argTypes.js"; +import type { UI5StoryArgs } from "../../../../types.js"; + +import type SpecialCalendarDate from "@ui5/webcomponents/dist/SpecialCalendarDate.js"; + + +export default { + title: "Main/Calendar/Special Calendar Date", + component: "SpecialCalendarDate", + argTypes, +} as Meta; + +const Template: UI5StoryArgs = (args) => html` + +`; + +var date = new Date(); + +export const Basic = Template.bind({}); +Basic.tags = ["_hidden_"]; +Basic.args = { + type: "Type01", + value: `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate() - 1}`, +} \ No newline at end of file diff --git a/packages/playground/_stories/main/CalendarLegend/CalendarLegend.stories.ts b/packages/playground/_stories/main/CalendarLegend/CalendarLegend.stories.ts new file mode 100644 index 000000000000..ce0e266da329 --- /dev/null +++ b/packages/playground/_stories/main/CalendarLegend/CalendarLegend.stories.ts @@ -0,0 +1,85 @@ +import { html } from "lit"; +import { ifDefined } from "lit/directives/if-defined.js"; +import { unsafeHTML } from "lit/directives/unsafe-html.js"; +import type { Meta } from "@storybook/web-components"; + +import argTypes from "./argTypes.js"; +import type { StoryArgsSlots } from "./argTypes.js"; +import type { UI5StoryArgs } from "../../../types.js"; + +import type CalendarLegend from "@ui5/webcomponents/dist/CalendarLegend.js"; + +export default { + title: "Main/Calendar Legend", + component: "CalendarLegend", + argTypes, +} as Meta; + +const Template: UI5StoryArgs = (args) => html` + + ${unsafeHTML(args.default)} + +`; + +export const Basic = Template.bind({}); + +Basic.decorators = [ + (story) => { + return html` + + + + + + + + + + ${story()} + + + + `; + }, +]; + +Basic.args = { + default: ` + + + + `, +}; \ No newline at end of file diff --git a/packages/playground/_stories/main/CalendarLegend/CalendarLegendItem/CalendarLegendItem.stories.ts b/packages/playground/_stories/main/CalendarLegend/CalendarLegendItem/CalendarLegendItem.stories.ts new file mode 100644 index 000000000000..6237b90b7282 --- /dev/null +++ b/packages/playground/_stories/main/CalendarLegend/CalendarLegendItem/CalendarLegendItem.stories.ts @@ -0,0 +1,55 @@ +import { html } from "lit"; +import { unsafeHTML } from "lit/directives/unsafe-html.js"; +import { ifDefined } from "lit/directives/if-defined.js"; +import type { Meta } from "@storybook/web-components"; + +import argTypes from "./argTypes.js"; +import type { StoryArgsSlots } from "./argTypes.js"; +import type { UI5StoryArgs } from "../../../../types.js"; + +import type CalendarLegendItem from "@ui5/webcomponents/dist/CalendarLegendItem.js"; + +export default { + title: "Main/Calendar Legend/Calendar Legend Item", + component: "CalendarLegendItem", + argTypes, +} as Meta; + +const Template: UI5StoryArgs = (args) => html` + + + + + + + + +`; + +export const Basic = Template.bind({}); +Basic.tags = ["_hidden_"]; +Basic.args = { + type: "Type01", + text: "Placeholder 01", +} \ No newline at end of file diff --git a/packages/playground/_stories/main/CheckBox/CheckBox.stories.ts b/packages/playground/_stories/main/CheckBox/CheckBox.stories.ts index 10f51a0f0eab..96c6d483876f 100644 --- a/packages/playground/_stories/main/CheckBox/CheckBox.stories.ts +++ b/packages/playground/_stories/main/CheckBox/CheckBox.stories.ts @@ -23,6 +23,7 @@ const Template: UI5StoryArgs = (args) => ?required="${ifDefined(args.required)}" ?indeterminate="${ifDefined(args.indeterminate)}" ?checked="${ifDefined(args.checked)}" + ?display-only="${ifDefined(args.displayOnly)}" text="${ifDefined(args.text)}" value-state="${ifDefined(args.valueState)}" wrapping-type="${ifDefined(args.wrappingType)}" diff --git a/packages/playground/_stories/main/List/CustomListItem/CustomListItem.stories.ts b/packages/playground/_stories/main/List/CustomListItem/CustomListItem.stories.ts index ed40c97be931..fabbf13cf2f5 100644 --- a/packages/playground/_stories/main/List/CustomListItem/CustomListItem.stories.ts +++ b/packages/playground/_stories/main/List/CustomListItem/CustomListItem.stories.ts @@ -23,6 +23,7 @@ const Template: UI5StoryArgs = (args) => { ?navigated="${ifDefined(args.navigated)}" type="${ifDefined(args.type)}" ?selected="${ifDefined(args.selected)}" + tooltip="${ifDefined(args.tooltip)}" > ${unsafeHTML(args.default)} ${unsafeHTML(args.deleteButton)} diff --git a/packages/playground/_stories/main/List/List.stories.ts b/packages/playground/_stories/main/List/List.stories.ts index 0988a8f479e7..34d4afc9a49a 100644 --- a/packages/playground/_stories/main/List/List.stories.ts +++ b/packages/playground/_stories/main/List/List.stories.ts @@ -22,6 +22,7 @@ const Template: UI5StoryArgs = (args) => { ?busy="${ifDefined(args.busy)}" ?indent="${ifDefined(args.indent)}" ?growing="${ifDefined(args.growing)}" + growing-button-text="${ifDefined(args.growingButtonText)}" busy-delay="${ifDefined(args.busyDelay)}" separators="${ifDefined(args.separators)}" header-text="${ifDefined(args.headerText)}" @@ -220,3 +221,16 @@ export const SeparationTypes: StoryFn = () => Pending Declined `; + +export const HighlightTypes: StoryFn = () => + html` + None + Success + Warning + Error + Information + `; diff --git a/packages/playground/_stories/main/List/StandardListItem/StandardListItem.stories.ts b/packages/playground/_stories/main/List/StandardListItem/StandardListItem.stories.ts index d70445ef6b22..5b164041c9a9 100644 --- a/packages/playground/_stories/main/List/StandardListItem/StandardListItem.stories.ts +++ b/packages/playground/_stories/main/List/StandardListItem/StandardListItem.stories.ts @@ -29,6 +29,7 @@ const Template: UI5StoryArgs = (args) => { ?navigated="${ifDefined(args.navigated)}" type="${ifDefined(args.type)}" ?selected="${ifDefined(args.selected)}" + tooltip="${ifDefined(args.tooltip)}" > ${unsafeHTML(args.default)} ${unsafeHTML(args.imageContent)} diff --git a/packages/playground/_stories/main/Tree/TreeItem/TreeItem.stories.ts b/packages/playground/_stories/main/Tree/TreeItem/TreeItem.stories.ts index 6a956e2825b5..1e0a345df042 100644 --- a/packages/playground/_stories/main/Tree/TreeItem/TreeItem.stories.ts +++ b/packages/playground/_stories/main/Tree/TreeItem/TreeItem.stories.ts @@ -29,6 +29,7 @@ const Template: UI5StoryArgs = (args) => html` ${unsafeHTML(args.default)} ${unsafeHTML(args.deleteButton)} diff --git a/packages/playground/_stories/main/Tree/TreeItemCustom/TreeItemCustom.stories.ts b/packages/playground/_stories/main/Tree/TreeItemCustom/TreeItemCustom.stories.ts index d76faa5a1aaa..5e2d11798c12 100644 --- a/packages/playground/_stories/main/Tree/TreeItemCustom/TreeItemCustom.stories.ts +++ b/packages/playground/_stories/main/Tree/TreeItemCustom/TreeItemCustom.stories.ts @@ -28,6 +28,7 @@ const Template: UI5StoryArgs = (args) => html` ${unsafeHTML(args.content)} ${unsafeHTML(args.default)} diff --git a/packages/playground/build-scripts-storybook/samples-prepare.ts b/packages/playground/build-scripts-storybook/samples-prepare.ts index 7e5d7a902db4..dcae0d2af00f 100644 --- a/packages/playground/build-scripts-storybook/samples-prepare.ts +++ b/packages/playground/build-scripts-storybook/samples-prepare.ts @@ -7,13 +7,9 @@ import type { Parameter, Type, ClassField, + Declaration, ClassMethod, EnumDeclaration, - InterfaceDeclaration, - FunctionDeclaration, - CustomElementMixinDeclaration, - MixinDeclaration, - VariableDeclaration } from "@ui5/webcomponents-tools/lib/cem/types-internal"; const STORIES_ROOT_FOLDER_NAME = '../_stories'; @@ -22,7 +18,7 @@ const isCustomElementDeclaration = (object: any): object is CustomElementDeclara return "customElement" in object && object.customElement; }; -type Declaration = CustomElementDeclaration | EnumDeclaration | ClassDeclaration | InterfaceDeclaration | FunctionDeclaration | MixinDeclaration | VariableDeclaration | CustomElementMixinDeclaration +type DeclarationT = Declaration & { _ui5package: string } type ControlType = "text" | "select" | "multi-select" | boolean; @@ -114,10 +110,10 @@ export type StoryArgsSlots = { }; const getAPIData = (api: Package, module: string, componentPackage: string): APIData | undefined => { - const moduleAPI = api.modules?.find(currModule => currModule.declarations?.find(s => s.name === module && s._ui5package === `@ui5/webcomponents${componentPackage !== 'main' ? `-${componentPackage}` : ''}`)); - const declaration = moduleAPI?.declarations?.find(s => s.name === module && s._ui5package === `@ui5/webcomponents${componentPackage !== 'main' ? `-${componentPackage}` : ''}`); + const moduleAPI = api.modules?.find(currModule => currModule.declarations?.find(s => s.name === module && (s as DeclarationT)._ui5package === `@ui5/webcomponents${componentPackage !== 'main' ? `-${componentPackage}` : ''}`)); + const declaration = moduleAPI?.declarations?.find(s => s.name === module && (s as DeclarationT)._ui5package === `@ui5/webcomponents${componentPackage !== 'main' ? `-${componentPackage}` : ''}`); const exportedAs = moduleAPI?.exports?.find(s => s.kind === "custom-element-definition"); - + if (!declaration) { return; } @@ -151,7 +147,7 @@ const getArgsTypes = (api: Package, moduleAPI: CustomElementDeclaration | ClassD } for (const s of currModule.declarations) { - if (s.name === prop.type?.references[0].name && s._ui5package === prop.type?.references[0].package && s.kind === "enum") { + if (s.name === prop.type?.references[0].name && (s as DeclarationT)._ui5package === prop.type?.references[0].package && s.kind === "enum") { typeEnum = s; break; } @@ -240,11 +236,11 @@ const getArgsTypes = (api: Package, moduleAPI: CustomElementDeclaration | ClassD continue; } - moduleAPIBeingExtended = findReference(currModule.declarations, moduleAPI.superclass?.name, moduleAPI.superclass.package); + moduleAPIBeingExtended = findReference(currModule.declarations as Array, moduleAPI.superclass?.name, moduleAPI.superclass.package); } } - const referencePackage = moduleAPIBeingExtended?._ui5package; + const referencePackage = (moduleAPIBeingExtended as DeclarationT)?._ui5package; if (moduleAPIBeingExtended && referencePackage && packages.includes(referencePackage)) { const { args: nextArgs, slotNames: nextSlotNames } = getArgsTypes(api, moduleAPIBeingExtended as ClassDeclaration); @@ -258,8 +254,8 @@ const getArgsTypes = (api: Package, moduleAPI: CustomElementDeclaration | ClassD }; }; -const findReference = (something: Array, componentName: string, componentPackage: string): Declaration | undefined => { - return something.find(s => s.name === componentName && s._ui5package === componentPackage) +const findReference = (something: Array, componentName: string, componentPackage: string): DeclarationT | undefined => { + return something.find(s => s.name === componentName && (s as DeclarationT)._ui5package === componentPackage) } main(); diff --git a/packages/playground/build-scripts-storybook/types-prepare.ts b/packages/playground/build-scripts-storybook/types-prepare.ts new file mode 100644 index 000000000000..5fdf0b26c477 --- /dev/null +++ b/packages/playground/build-scripts-storybook/types-prepare.ts @@ -0,0 +1,165 @@ +import fs from "fs/promises"; +import path from "path"; +import type { + ClassDeclaration, + Package, + EnumDeclaration, + InterfaceDeclaration, + Reference, +} from "@ui5/webcomponents-tools/lib/cem/types-internal"; + +const FIORI_INTERFACES_FILE_NAME = '../_stories/fiori/Interfaces.mdx'; +const MAIN_INTERFACES_FILE_NAME = '../_stories/main/Interfaces.mdx'; +const FIORI_ENUM_FILE_NAME = '../_stories/fiori/Enums.mdx'; +const MAIN_ENUM_FILE_NAME = '../_stories/main/Enums.mdx'; + +type StorybookInterfaceDeclaration = InterfaceDeclaration & { _ui5package: string }; +type StorybookEnumDeclaration = EnumDeclaration & { _ui5package: string }; +type StorybookClassDeclaration = ClassDeclaration & { _ui5package: string }; + +type EnhancedInterfaceDeclartion = StorybookInterfaceDeclaration & { implementations: string[] }; +const interfaceDeclarations: Map = new Map(); +const enumDeclarations: Array = []; + +const generateFileContent = (content: string, kind: string) => { + return `import { Meta } from "@storybook/blocks"; + +import { Footer } from "@sb/components/footer/Footer.tsx"; +import { + Title +} from "@storybook/addon-docs"; + + + +
+ + ${kind} + +
+ +${content} + +