From 767525a777a331ea1bf93700828d1df09625e565 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Mon, 26 Aug 2019 14:05:48 +0300 Subject: [PATCH 01/57] feat: implement create control script --- .../create-new-component.js | 65 +++++++++++++++++++ packages/main/package.json | 1 + 2 files changed, 66 insertions(+) create mode 100644 packages/main/lib/create-new-component/create-new-component.js diff --git a/packages/main/lib/create-new-component/create-new-component.js b/packages/main/lib/create-new-component/create-new-component.js new file mode 100644 index 000000000000..718a175ee4ea --- /dev/null +++ b/packages/main/lib/create-new-component/create-new-component.js @@ -0,0 +1,65 @@ +const jsFileContentTemplate = sComponentName => { + return `import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; +import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; +import ${sComponentName}Template from "./generated/templates/${sComponentName}Template.lit.js"; + +// Styles +import ${sComponentName}Css from "./generated/themes/${sComponentName}.css.js"; + + +const metadata = { + tag: "ui5-${sComponentName.toLowerCase()}", + properties: { + // + }, + slots: { + // + }, + events: { + // + }, +}; + +class ${sComponentName} extends UI5Element { + static get metadata() { + return metadata; + } + + static get render() { + return litRender; + } + + static get styles() { + return ${sComponentName}Css; + } + + static get template() { + return ${sComponentName}Template; + } + + static async define(...params) { + super.define(...params); + } +} + +${sComponentName}.define(); + +export default ${sComponentName}; +`; +}; + +const fs = require("fs"); + + +const aArgs = process.argv.slice(2); +const sComponentName = aArgs[0]; +const oPaths = { + "js": `./src/${sComponentName}.js`, + "css": `./src/themes/${sComponentName}.css`, + "hbs": `./src/${sComponentName}.hbs`, +}; +const sJsFileContentTemplate = jsFileContentTemplate(sComponentName); + +fs.writeFileSync(oPaths.js, sJsFileContentTemplate, { flag: "wx+" }); +fs.writeFileSync(oPaths.css, "", { flag: "wx+" }); +fs.writeFileSync(oPaths.hbs, "
Hello World
", { flag: "wx+" }); diff --git a/packages/main/package.json b/packages/main/package.json index 3204efbce21e..8cef87f6029d 100644 --- a/packages/main/package.json +++ b/packages/main/package.json @@ -66,6 +66,7 @@ "copy:qunit": "cpx \"test/**/qunit/*.*\" dist/test-resources", "copy:webcomponents-polyfill": "cpx \"../../node_modules/@webcomponents/webcomponentsjs/**/*.*\" dist/webcomponentsjs/", "dev": "npm-run-all --sequential build:i18n watch:all", + "generate-new-component" : "node ./lib/create-new-component/create-new-component.js", "start": "npm-run-all --parallel serve:static dev", "lint": "eslint .", "test:wdio": "npm-run-all --parallel --race serve:static test:wdio-run", From 2f2ba11662b9cb24b28faf3374ac2e39eb901156 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Mon, 26 Aug 2019 16:21:44 +0300 Subject: [PATCH 02/57] fix: create control script pr notes fix --- .../{create-new-component.js => index.js} | 10 +++++++--- packages/main/package.json | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) rename packages/main/lib/create-new-component/{create-new-component.js => index.js} (97%) diff --git a/packages/main/lib/create-new-component/create-new-component.js b/packages/main/lib/create-new-component/index.js similarity index 97% rename from packages/main/lib/create-new-component/create-new-component.js rename to packages/main/lib/create-new-component/index.js index 718a175ee4ea..7c641d464cf0 100644 --- a/packages/main/lib/create-new-component/create-new-component.js +++ b/packages/main/lib/create-new-component/index.js @@ -48,11 +48,13 @@ export default ${sComponentName}; `; }; -const fs = require("fs"); - - const aArgs = process.argv.slice(2); const sComponentName = aArgs[0]; + +if (!sComponentName){ + return; +} + const oPaths = { "js": `./src/${sComponentName}.js`, "css": `./src/themes/${sComponentName}.css`, @@ -60,6 +62,8 @@ const oPaths = { }; const sJsFileContentTemplate = jsFileContentTemplate(sComponentName); +const fs = require("fs"); + fs.writeFileSync(oPaths.js, sJsFileContentTemplate, { flag: "wx+" }); fs.writeFileSync(oPaths.css, "", { flag: "wx+" }); fs.writeFileSync(oPaths.hbs, "
Hello World
", { flag: "wx+" }); diff --git a/packages/main/package.json b/packages/main/package.json index 8cef87f6029d..099808bf7248 100644 --- a/packages/main/package.json +++ b/packages/main/package.json @@ -66,7 +66,7 @@ "copy:qunit": "cpx \"test/**/qunit/*.*\" dist/test-resources", "copy:webcomponents-polyfill": "cpx \"../../node_modules/@webcomponents/webcomponentsjs/**/*.*\" dist/webcomponentsjs/", "dev": "npm-run-all --sequential build:i18n watch:all", - "generate-new-component" : "node ./lib/create-new-component/create-new-component.js", + "generate-new-component" : "node ./lib/create-new-component/index.js", "start": "npm-run-all --parallel serve:static dev", "lint": "eslint .", "test:wdio": "npm-run-all --parallel --race serve:static test:wdio-run", From f722bb6af126862f92a7334efe8204fc59dc70c2 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Wed, 28 Aug 2019 09:59:33 +0300 Subject: [PATCH 03/57] add console error on empty string for a name of component --- packages/main/lib/create-new-component/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/main/lib/create-new-component/index.js b/packages/main/lib/create-new-component/index.js index 7c641d464cf0..73e1c5d036e4 100644 --- a/packages/main/lib/create-new-component/index.js +++ b/packages/main/lib/create-new-component/index.js @@ -52,6 +52,7 @@ const aArgs = process.argv.slice(2); const sComponentName = aArgs[0]; if (!sComponentName){ + console.error("Please enter component name.") return; } From 1357c13de27baf04686ffea392ccbea4a9025713 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Wed, 28 Aug 2019 13:04:55 +0300 Subject: [PATCH 04/57] solve conflict --- packages/main/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/main/package.json b/packages/main/package.json index 099808bf7248..44a703fac6f8 100644 --- a/packages/main/package.json +++ b/packages/main/package.json @@ -50,7 +50,7 @@ "build:templates": "mkdirp dist/generated/templates && node ./lib/hbs2ui5/index.js -d src/ -o dist/generated/templates", "build:i18n": "npm-run-all --sequential build:i18n-defaults build:i18n-JSON", "build:i18n-defaults": "mkdirp dist/generated/i18n && node ./lib/i18n/defaults.js src/i18n dist/generated/i18n", - "build:i18n-JSON": "mkdirp dist/generated/i18n && node ./lib/i18n/toJSON.js src/i18n dist/generated/i18n", + "build:i18n-JSON": "mkdirp dist/assets/i18n && node ./lib/i18n/toJSON.js src/i18n dist/assets/i18n", "build:samples": "npm run copy:test --scripts-prepend-node-path && npm run build:api --scripts-prepend-node-path && npm run build:docs --scripts-prepend-node-path && node lib/playground/index.js", "build:pages": "npm run copy:pages", "build:qunit": "npm run copy:qunit", @@ -155,4 +155,4 @@ "dir-glob": "2.0.0", "wdio-chromedriver-service/chromedriver": "^76.0.0" } -} +} \ No newline at end of file From bd9bf4881c2834427face9a49216b206f8d30f7a Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Wed, 28 Aug 2019 13:16:15 +0300 Subject: [PATCH 05/57] removed hungarian notation --- .../main/lib/create-new-component/index.js | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/main/lib/create-new-component/index.js b/packages/main/lib/create-new-component/index.js index 73e1c5d036e4..7cb978302bea 100644 --- a/packages/main/lib/create-new-component/index.js +++ b/packages/main/lib/create-new-component/index.js @@ -1,14 +1,14 @@ -const jsFileContentTemplate = sComponentName => { +const jsFileContentTemplate = componentName => { return `import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; -import ${sComponentName}Template from "./generated/templates/${sComponentName}Template.lit.js"; +import ${componentName}Template from "./generated/templates/${componentName}Template.lit.js"; // Styles -import ${sComponentName}Css from "./generated/themes/${sComponentName}.css.js"; +import ${componentName}Css from "./generated/themes/${componentName}.css.js"; const metadata = { - tag: "ui5-${sComponentName.toLowerCase()}", + tag: "ui5-${componentName.toLowerCase()}", properties: { // }, @@ -20,7 +20,7 @@ const metadata = { }, }; -class ${sComponentName} extends UI5Element { +class ${componentName} extends UI5Element { static get metadata() { return metadata; } @@ -30,11 +30,11 @@ class ${sComponentName} extends UI5Element { } static get styles() { - return ${sComponentName}Css; + return ${componentName}Css; } static get template() { - return ${sComponentName}Template; + return ${componentName}Template; } static async define(...params) { @@ -42,26 +42,26 @@ class ${sComponentName} extends UI5Element { } } -${sComponentName}.define(); +${componentName}.define(); -export default ${sComponentName}; +export default ${componentName}; `; }; -const aArgs = process.argv.slice(2); -const sComponentName = aArgs[0]; +const consoleArguments = process.argv.slice(2); +const componentName = consoleArguments[0]; -if (!sComponentName){ +if (!componentName){ console.error("Please enter component name.") return; } const oPaths = { - "js": `./src/${sComponentName}.js`, - "css": `./src/themes/${sComponentName}.css`, - "hbs": `./src/${sComponentName}.hbs`, + "js": `./src/${componentName}.js`, + "css": `./src/themes/${componentName}.css`, + "hbs": `./src/${componentName}.hbs`, }; -const sJsFileContentTemplate = jsFileContentTemplate(sComponentName); +const sJsFileContentTemplate = jsFileContentTemplate(componentName); const fs = require("fs"); From 4b82ba52111460b19c2be7d34665fcf65aae4af5 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Wed, 28 Aug 2019 13:23:31 +0300 Subject: [PATCH 06/57] removed old component creation snippet file --- .../create-new-component.js | 65 ------------------- .../main/lib/create-new-component/index.js | 8 +-- 2 files changed, 4 insertions(+), 69 deletions(-) delete mode 100644 packages/main/lib/create-new-component/create-new-component.js diff --git a/packages/main/lib/create-new-component/create-new-component.js b/packages/main/lib/create-new-component/create-new-component.js deleted file mode 100644 index 718a175ee4ea..000000000000 --- a/packages/main/lib/create-new-component/create-new-component.js +++ /dev/null @@ -1,65 +0,0 @@ -const jsFileContentTemplate = sComponentName => { - return `import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; -import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; -import ${sComponentName}Template from "./generated/templates/${sComponentName}Template.lit.js"; - -// Styles -import ${sComponentName}Css from "./generated/themes/${sComponentName}.css.js"; - - -const metadata = { - tag: "ui5-${sComponentName.toLowerCase()}", - properties: { - // - }, - slots: { - // - }, - events: { - // - }, -}; - -class ${sComponentName} extends UI5Element { - static get metadata() { - return metadata; - } - - static get render() { - return litRender; - } - - static get styles() { - return ${sComponentName}Css; - } - - static get template() { - return ${sComponentName}Template; - } - - static async define(...params) { - super.define(...params); - } -} - -${sComponentName}.define(); - -export default ${sComponentName}; -`; -}; - -const fs = require("fs"); - - -const aArgs = process.argv.slice(2); -const sComponentName = aArgs[0]; -const oPaths = { - "js": `./src/${sComponentName}.js`, - "css": `./src/themes/${sComponentName}.css`, - "hbs": `./src/${sComponentName}.hbs`, -}; -const sJsFileContentTemplate = jsFileContentTemplate(sComponentName); - -fs.writeFileSync(oPaths.js, sJsFileContentTemplate, { flag: "wx+" }); -fs.writeFileSync(oPaths.css, "", { flag: "wx+" }); -fs.writeFileSync(oPaths.hbs, "
Hello World
", { flag: "wx+" }); diff --git a/packages/main/lib/create-new-component/index.js b/packages/main/lib/create-new-component/index.js index 7cb978302bea..4711b4ac01b7 100644 --- a/packages/main/lib/create-new-component/index.js +++ b/packages/main/lib/create-new-component/index.js @@ -56,7 +56,7 @@ if (!componentName){ return; } -const oPaths = { +const filePaths = { "js": `./src/${componentName}.js`, "css": `./src/themes/${componentName}.css`, "hbs": `./src/${componentName}.hbs`, @@ -65,6 +65,6 @@ const sJsFileContentTemplate = jsFileContentTemplate(componentName); const fs = require("fs"); -fs.writeFileSync(oPaths.js, sJsFileContentTemplate, { flag: "wx+" }); -fs.writeFileSync(oPaths.css, "", { flag: "wx+" }); -fs.writeFileSync(oPaths.hbs, "
Hello World
", { flag: "wx+" }); +fs.writeFileSync(filePaths.js, sJsFileContentTemplate, { flag: "wx+" }); +fs.writeFileSync(filePaths.css, "", { flag: "wx+" }); +fs.writeFileSync(filePaths.hbs, "
Hello World
", { flag: "wx+" }); From f77bfb624d1acd1625df1226aef7efce8c0b629d Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Fri, 30 Aug 2019 08:59:15 +0300 Subject: [PATCH 07/57] feat(ui5-tabcontainer): acc update --- packages/main/src/TabContainer.hbs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/main/src/TabContainer.hbs b/packages/main/src/TabContainer.hbs index 498e0ad70bd0..65409a69954a 100644 --- a/packages/main/src/TabContainer.hbs +++ b/packages/main/src/TabContainer.hbs @@ -3,7 +3,7 @@ dir="{{rtl}}" >
- +
@@ -45,7 +45,7 @@
- + {{#if showOverflow}} @@ -54,6 +54,7 @@ class="{{classes.overflowButton}}" icon="sap-icon://slim-arrow-down" type="Transparent" + title="Overflow Menu" > {{/if}}
@@ -62,7 +63,7 @@
{{#each renderItems}} {{#unless this.isSeparator}} -
+
{{/unless}} From a9235f717a933722a6f7da290a9ded874be42f59 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Fri, 30 Aug 2019 09:05:41 +0300 Subject: [PATCH 08/57] merge conflict tags solve --- packages/main/package.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/main/package.json b/packages/main/package.json index 67e4a99b2850..0208e201dfb2 100644 --- a/packages/main/package.json +++ b/packages/main/package.json @@ -65,13 +65,7 @@ "copy:pages": "cpx \"test/**/pages/*.*\" dist/test-resources", "copy:qunit": "cpx \"test/**/qunit/*.*\" dist/test-resources", "copy:webcomponents-polyfill": "cpx \"../../node_modules/@webcomponents/webcomponentsjs/**/*.*\" dist/webcomponentsjs/", -<<<<<<< HEAD - "dev": "npm-run-all --sequential build:i18n watch:all", "generate-new-component" : "node ./lib/create-new-component/index.js", - "start": "npm-run-all --parallel serve:static dev", -======= - "generate-new-component" : "node ./lib/create-new-component/index.js", ->>>>>>> upstream/master "lint": "eslint .", "start": "npm-run-all --parallel serve:static start:prepare", "start:prepare": "npm-run-all --sequential build:i18n watch:all", From fdd2118a4ecdd676290ab3d65f771a0ebbf5574d Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Fri, 30 Aug 2019 11:04:48 +0300 Subject: [PATCH 09/57] feat(ui5-tabcontainer): update ACC of header and content --- packages/main/src/TabContainer.hbs | 6 +++--- packages/main/src/TabContainer.js | 17 +++++++++++++++++ packages/main/src/i18n/messagebundle.properties | 9 +++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/packages/main/src/TabContainer.hbs b/packages/main/src/TabContainer.hbs index 65409a69954a..826f2c581d88 100644 --- a/packages/main/src/TabContainer.hbs +++ b/packages/main/src/TabContainer.hbs @@ -3,7 +3,7 @@ dir="{{rtl}}" >
- +
@@ -45,7 +45,7 @@
- + {{#if showOverflow}} @@ -54,7 +54,7 @@ class="{{classes.overflowButton}}" icon="sap-icon://slim-arrow-down" type="Transparent" - title="Overflow Menu" + title="{{overflowMenuTitle}}" > {{/if}}
diff --git a/packages/main/src/TabContainer.js b/packages/main/src/TabContainer.js index f5bb73bb51c3..5354c2bc21da 100644 --- a/packages/main/src/TabContainer.js +++ b/packages/main/src/TabContainer.js @@ -5,6 +5,8 @@ import ScrollEnablement from "@ui5/webcomponents-base/dist/delegate/ScrollEnable import ItemNavigation from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js"; import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/events/PseudoEvents.js"; import { getRTL } from "@ui5/webcomponents-base/dist/config/RTL.js"; +import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; +import { TABCONTAINER_PREVIOUS_ACC_NAME, TABCONTAINER_NEXT_ICON_ACC_NAME, TABCONTAINER_OVERFLOW_MENU_TITLE } from "./generated/i18n/i18n-defaults.js"; import TabContainerTemplate from "./generated/templates/TabContainerTemplate.lit.js"; import Button from "./Button.js"; import CustomListItem from "./CustomListItem.js"; @@ -176,6 +178,8 @@ class TabContainer extends UI5Element { // Init ItemNavigation this._initItemNavigation(); + + this.i18nBundle = getI18nBundle("@ui5/webcomponents"); } onBeforeRendering() { @@ -391,6 +395,18 @@ class TabContainer extends UI5Element { return this.items.some(item => item.icon) && this.items.some(item => item.text); } + get previousIconACCName() { + return this.i18nBundle.getText(TABCONTAINER_PREVIOUS_ACC_NAME); + } + + get nextIconACCName() { + return this.i18nBundle.getText(TABCONTAINER_NEXT_ICON_ACC_NAME); + } + + get overflowMenuTitle() { + return this.i18nBundle.getText(TABCONTAINER_OVERFLOW_MENU_TITLE); + } + get rtl() { return getRTL() ? "rtl" : undefined; } @@ -402,6 +418,7 @@ class TabContainer extends UI5Element { Icon.define(), List.define(), Popover.define(), + fetchI18nBundle("@ui5/webcomponents"), ]); super.define(...params); diff --git a/packages/main/src/i18n/messagebundle.properties b/packages/main/src/i18n/messagebundle.properties index 8e1ff1f1294c..52af05c1c07c 100644 --- a/packages/main/src/i18n/messagebundle.properties +++ b/packages/main/src/i18n/messagebundle.properties @@ -229,6 +229,15 @@ SWITCH_ON=On #XACT: ARIA announcement for the switch off SWITCH_OFF=Off +#XACT: ACC next icon name in tab container +TABCONTAINER_NEXT_ICON_ACC_NAME=Next + +#XACT: ACC previous icon name in tab container +TABCONTAINER_PREVIOUS_ACC_NAME=Previous + +#XACT: ACC overflow menu title in tab container +TABCONTAINER_OVERFLOW_MENU_TITLE=Overflow Menu + #XTXT: Text for characters left TEXTAREA_CHARACTERS_LEFT={0} characters remaining From af2422cf2eeb7aa2a25ef5851c20758d51d3449a Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Fri, 30 Aug 2019 11:04:48 +0300 Subject: [PATCH 10/57] feat(ui5-tabcontainer): update ACC of header and content --- packages/main/src/TabContainer.hbs | 6 +++--- packages/main/src/TabContainer.js | 17 +++++++++++++++++ packages/main/src/i18n/messagebundle.properties | 9 +++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/packages/main/src/TabContainer.hbs b/packages/main/src/TabContainer.hbs index 65409a69954a..aa1e158b60a6 100644 --- a/packages/main/src/TabContainer.hbs +++ b/packages/main/src/TabContainer.hbs @@ -3,7 +3,7 @@ dir="{{rtl}}" >
- +
@@ -45,7 +45,7 @@
- + {{#if showOverflow}} @@ -54,7 +54,7 @@ class="{{classes.overflowButton}}" icon="sap-icon://slim-arrow-down" type="Transparent" - title="Overflow Menu" + title="{{overflowMenuTitle}}" > {{/if}}
diff --git a/packages/main/src/TabContainer.js b/packages/main/src/TabContainer.js index f5bb73bb51c3..5354c2bc21da 100644 --- a/packages/main/src/TabContainer.js +++ b/packages/main/src/TabContainer.js @@ -5,6 +5,8 @@ import ScrollEnablement from "@ui5/webcomponents-base/dist/delegate/ScrollEnable import ItemNavigation from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js"; import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/events/PseudoEvents.js"; import { getRTL } from "@ui5/webcomponents-base/dist/config/RTL.js"; +import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; +import { TABCONTAINER_PREVIOUS_ACC_NAME, TABCONTAINER_NEXT_ICON_ACC_NAME, TABCONTAINER_OVERFLOW_MENU_TITLE } from "./generated/i18n/i18n-defaults.js"; import TabContainerTemplate from "./generated/templates/TabContainerTemplate.lit.js"; import Button from "./Button.js"; import CustomListItem from "./CustomListItem.js"; @@ -176,6 +178,8 @@ class TabContainer extends UI5Element { // Init ItemNavigation this._initItemNavigation(); + + this.i18nBundle = getI18nBundle("@ui5/webcomponents"); } onBeforeRendering() { @@ -391,6 +395,18 @@ class TabContainer extends UI5Element { return this.items.some(item => item.icon) && this.items.some(item => item.text); } + get previousIconACCName() { + return this.i18nBundle.getText(TABCONTAINER_PREVIOUS_ACC_NAME); + } + + get nextIconACCName() { + return this.i18nBundle.getText(TABCONTAINER_NEXT_ICON_ACC_NAME); + } + + get overflowMenuTitle() { + return this.i18nBundle.getText(TABCONTAINER_OVERFLOW_MENU_TITLE); + } + get rtl() { return getRTL() ? "rtl" : undefined; } @@ -402,6 +418,7 @@ class TabContainer extends UI5Element { Icon.define(), List.define(), Popover.define(), + fetchI18nBundle("@ui5/webcomponents"), ]); super.define(...params); diff --git a/packages/main/src/i18n/messagebundle.properties b/packages/main/src/i18n/messagebundle.properties index 8e1ff1f1294c..52af05c1c07c 100644 --- a/packages/main/src/i18n/messagebundle.properties +++ b/packages/main/src/i18n/messagebundle.properties @@ -229,6 +229,15 @@ SWITCH_ON=On #XACT: ARIA announcement for the switch off SWITCH_OFF=Off +#XACT: ACC next icon name in tab container +TABCONTAINER_NEXT_ICON_ACC_NAME=Next + +#XACT: ACC previous icon name in tab container +TABCONTAINER_PREVIOUS_ACC_NAME=Previous + +#XACT: ACC overflow menu title in tab container +TABCONTAINER_OVERFLOW_MENU_TITLE=Overflow Menu + #XTXT: Text for characters left TEXTAREA_CHARACTERS_LEFT={0} characters remaining From 067dbaa0c0184a8642fcf2cba7d6b808b2aaa99b Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Tue, 3 Sep 2019 11:35:56 +0300 Subject: [PATCH 11/57] feat:(ui5-datepicker): update ACC of the component and input included --- packages/main/src/DatePicker.hbs | 7 +++- packages/main/src/DatePicker.js | 24 +++++++++++++ packages/main/src/Input.hbs | 3 ++ packages/main/src/Input.js | 34 +++++++++++++++++++ .../main/src/i18n/messagebundle.properties | 6 ++++ packages/main/src/themes/DatePicker.css | 2 ++ 6 files changed, 75 insertions(+), 1 deletion(-) diff --git a/packages/main/src/DatePicker.hbs b/packages/main/src/DatePicker.hbs index 56657d2b8627..273e1adecfe2 100644 --- a/packages/main/src/DatePicker.hbs +++ b/packages/main/src/DatePicker.hbs @@ -11,9 +11,12 @@ ?disabled="{{disabled}}" ?readonly="{{readonly}}" value-state="{{valueState}}" + aria-autocomplete="none" + aria-haspopup @ui5-change="{{_handleInputChange}}" @ui5-input="{{_handleInputLiveChange}}" data-sap-focus-ref + ._accInfo ="{{accInfo}}" > {{#unless readonly}} {{/unless}} @@ -46,6 +51,6 @@ @ui5-selectedDatesChange="{{_calendar.onSelectedDatesChange}}" > - + {{dateAriaDescriber}}
diff --git a/packages/main/src/DatePicker.js b/packages/main/src/DatePicker.js index 8e14d0c70dd3..f3350f97612b 100644 --- a/packages/main/src/DatePicker.js +++ b/packages/main/src/DatePicker.js @@ -13,6 +13,8 @@ import CalendarDate from "@ui5/webcomponents-base/dist/dates/CalendarDate.js"; import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js"; import { isShow } from "@ui5/webcomponents-base/dist/events/PseudoEvents.js"; import "./icons/appointment-2.js"; +import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; +import { DATEPICKER_OPEN_ICON_TITLE, DATEPICKER_DATE_TYPE } from "./generated/i18n/i18n-defaults.js"; import Icon from "./Icon.js"; import Popover from "./Popover.js"; import Calendar from "./Calendar.js"; @@ -285,6 +287,8 @@ class DatePicker extends UI5Element { onSelectedDatesChange: this._handleCalendarSelectedDatesChange.bind(this), selectedDates: [], }; + + this.i18nBundle = getI18nBundle("@ui5/webcomponents"); } onBeforeRendering() { @@ -397,6 +401,25 @@ class DatePicker extends UI5Element { return this._oDateFormat; } + get accInfo() { + return { + "ariaDescribedBy": `${this._id}-date`, + "ariaHasPopup": "true", + "ariaAutoComplete": "none", + "roleAttribute": "combobox", + "ariaOwns": `${this._id}-popover`, + "ariaExpanded": this.isOpen(), + }; + } + + get openIconTitle() { + return this.i18nBundle.getText(DATEPICKER_OPEN_ICON_TITLE); + } + + get dateAriaDescriber() { + return this.i18nBundle.getText(DATEPICKER_DATE_TYPE); + } + _getPopover() { return this.shadowRoot.querySelector("ui5-popover"); } @@ -544,6 +567,7 @@ class DatePicker extends UI5Element { Popover.define(), Calendar.define(), Input.define(), + fetchI18nBundle("@ui5/webcomponents"), ]); super.define(...params); diff --git a/packages/main/src/Input.hbs b/packages/main/src/Input.hbs index e362d20dee33..15808fe495ec 100644 --- a/packages/main/src/Input.hbs +++ b/packages/main/src/Input.hbs @@ -16,10 +16,13 @@ ?required="{{required}}" .value="{{value}}" placeholder="{{inputPlaceholder}}" + role="{{roleAttribute}}" + aria-owns="{{ariaOwns}}" aria-invalid="{{ariaInvalid}}" aria-haspopup="{{ariaHasPopup}}" aria-describedby="{{ariaDescribedBy}}" aria-autocomplete="{{ariaAutoComplete}}" + aria-expanded="{{ariaExpanded}}" @input="{{_handleInput}}" @change="{{_handleChange}}" data-sap-no-tab-ref diff --git a/packages/main/src/Input.js b/packages/main/src/Input.js index bb53179d0b0b..3a0795f556e8 100644 --- a/packages/main/src/Input.js +++ b/packages/main/src/Input.js @@ -214,6 +214,10 @@ const metadata = { _popover: { type: Object, }, + + _accInfo: { + type: Object, + }, }, events: /** @lends sap.ui.webcomponents.main.Input.prototype */ { /** @@ -575,17 +579,47 @@ class Input extends UI5Element { } get ariaDescribedBy() { + if (this._accInfo && this._accInfo.ariaDescribedBy) { + return `${this.suggestionsTextId} ${this.valueStateTextId} ${this._accInfo.ariaDescribedBy}`.trim(); + } return `${this.suggestionsTextId} ${this.valueStateTextId}`.trim(); } get ariaHasPopup() { + if (this._accInfo && this._accInfo.ariaHasPopup) { + return this._accInfo.ariaHasPopup; + } return this.showSuggestions ? "true" : undefined; } get ariaAutoComplete() { + if (this._accInfo && this._accInfo.ariaAutoComplete) { + return this._accInfo.ariaAutoComplete; + } return this.showSuggestions ? "list" : undefined; } + get roleAttribute() { + if (this._accInfo && this._accInfo.roleAttribute) { + return this._accInfo.roleAttribute; + } + return ""; + } + + get ariaOwns() { + if (this._accInfo && this._accInfo.ariaOwns) { + return this._accInfo.ariaOwns; + } + return ""; + } + + get ariaExpanded() { + if (this._accInfo && this._accInfo.ariaExpanded !== undefined) { + return this._accInfo.ariaExpanded; + } + return ""; + } + get hasValueState() { return this.valueState !== ValueState.None; } diff --git a/packages/main/src/i18n/messagebundle.properties b/packages/main/src/i18n/messagebundle.properties index 85ef7abbc110..eee8d0f170fc 100644 --- a/packages/main/src/i18n/messagebundle.properties +++ b/packages/main/src/i18n/messagebundle.properties @@ -25,6 +25,12 @@ BUTTON_ARIA_TYPE_REJECT=Negative Action #XACT: ARIA announcement for the emphasized button BUTTON_ARIA_TYPE_EMPHASIZED=Emphasized +#XACT: Aria information for the Date Picker +DATEPICKER_DATE_TYPE=Date + +#XACT: DatePicker 'Open Picker' icon title +DATEPICKER_OPEN_ICON_TITLE=Open Picker + #XTXT ICON_ACTION_SETTINGS=Settings diff --git a/packages/main/src/themes/DatePicker.css b/packages/main/src/themes/DatePicker.css index a99da7fde36f..2d47a667550f 100644 --- a/packages/main/src/themes/DatePicker.css +++ b/packages/main/src/themes/DatePicker.css @@ -1,3 +1,5 @@ +@import "./InvisibleTextStyles.css"; + :host(:not([hidden])) { display: inline-block; } From 874d752e5116fafdb7008d41d8c78c7ed0488019 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Tue, 3 Sep 2019 14:12:37 +0300 Subject: [PATCH 12/57] Updating with comments from PR --- packages/main/src/DatePicker.hbs | 2 +- packages/main/src/DatePicker.js | 8 ++++---- packages/main/src/Input.hbs | 2 +- packages/main/src/Input.js | 17 ++++------------- packages/main/src/i18n/messagebundle.properties | 4 ++-- 5 files changed, 12 insertions(+), 21 deletions(-) diff --git a/packages/main/src/DatePicker.hbs b/packages/main/src/DatePicker.hbs index 273e1adecfe2..f60b5773ce29 100644 --- a/packages/main/src/DatePicker.hbs +++ b/packages/main/src/DatePicker.hbs @@ -51,6 +51,6 @@ @ui5-selectedDatesChange="{{_calendar.onSelectedDatesChange}}" > - {{dateAriaDescriber}} + {{dateAriaDescription}}
diff --git a/packages/main/src/DatePicker.js b/packages/main/src/DatePicker.js index f3350f97612b..8e56c5ef6374 100644 --- a/packages/main/src/DatePicker.js +++ b/packages/main/src/DatePicker.js @@ -14,7 +14,7 @@ import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js"; import { isShow } from "@ui5/webcomponents-base/dist/events/PseudoEvents.js"; import "./icons/appointment-2.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; -import { DATEPICKER_OPEN_ICON_TITLE, DATEPICKER_DATE_TYPE } from "./generated/i18n/i18n-defaults.js"; +import { DATEPICKER_OPEN_ICON_TITLE, DATEPICKER_DATE_ACC_TEXT } from "./generated/i18n/i18n-defaults.js"; import Icon from "./Icon.js"; import Popover from "./Popover.js"; import Calendar from "./Calendar.js"; @@ -406,7 +406,7 @@ class DatePicker extends UI5Element { "ariaDescribedBy": `${this._id}-date`, "ariaHasPopup": "true", "ariaAutoComplete": "none", - "roleAttribute": "combobox", + "role": "combobox", "ariaOwns": `${this._id}-popover`, "ariaExpanded": this.isOpen(), }; @@ -416,8 +416,8 @@ class DatePicker extends UI5Element { return this.i18nBundle.getText(DATEPICKER_OPEN_ICON_TITLE); } - get dateAriaDescriber() { - return this.i18nBundle.getText(DATEPICKER_DATE_TYPE); + get dateAriaDescription() { + return this.i18nBundle.getText(DATEPICKER_DATE_ACC_TEXT); } _getPopover() { diff --git a/packages/main/src/Input.hbs b/packages/main/src/Input.hbs index 15808fe495ec..c3cb6ff71b32 100644 --- a/packages/main/src/Input.hbs +++ b/packages/main/src/Input.hbs @@ -16,7 +16,7 @@ ?required="{{required}}" .value="{{value}}" placeholder="{{inputPlaceholder}}" - role="{{roleAttribute}}" + role="{{role}}" aria-owns="{{ariaOwns}}" aria-invalid="{{ariaInvalid}}" aria-haspopup="{{ariaHasPopup}}" diff --git a/packages/main/src/Input.js b/packages/main/src/Input.js index 03c50d935e2b..99ecdfa87aee 100644 --- a/packages/main/src/Input.js +++ b/packages/main/src/Input.js @@ -605,25 +605,16 @@ class Input extends UI5Element { return this.showSuggestions ? "list" : undefined; } - get roleAttribute() { - if (this._accInfo && this._accInfo.roleAttribute) { - return this._accInfo.roleAttribute; - } - return ""; + get role() { + return this._accInfo && this._accInfo.role; } get ariaOwns() { - if (this._accInfo && this._accInfo.ariaOwns) { - return this._accInfo.ariaOwns; - } - return ""; + return this._accInfo && this._accInfo.ariaOwns; } get ariaExpanded() { - if (this._accInfo && this._accInfo.ariaExpanded !== undefined) { - return this._accInfo.ariaExpanded; - } - return ""; + return this._accInfo && this._accInfo.ariaExpanded; } get hasValueState() { diff --git a/packages/main/src/i18n/messagebundle.properties b/packages/main/src/i18n/messagebundle.properties index eee8d0f170fc..29f343b711b6 100644 --- a/packages/main/src/i18n/messagebundle.properties +++ b/packages/main/src/i18n/messagebundle.properties @@ -25,8 +25,8 @@ BUTTON_ARIA_TYPE_REJECT=Negative Action #XACT: ARIA announcement for the emphasized button BUTTON_ARIA_TYPE_EMPHASIZED=Emphasized -#XACT: Aria information for the Date Picker -DATEPICKER_DATE_TYPE=Date +#XACT: Date +DATEPICKER_DATE_ACC_TEXT=Date #XACT: DatePicker 'Open Picker' icon title DATEPICKER_OPEN_ICON_TITLE=Open Picker From 6d1dc16b3a71d1dba50182732cdb6952e6569dc9 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Wed, 4 Sep 2019 13:30:51 +0300 Subject: [PATCH 13/57] Update with notes from PR --- packages/main/src/Input.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/main/src/Input.js b/packages/main/src/Input.js index 99ecdfa87aee..d50c3003c473 100644 --- a/packages/main/src/Input.js +++ b/packages/main/src/Input.js @@ -592,14 +592,14 @@ class Input extends UI5Element { } get ariaHasPopup() { - if (this._accInfo && this._accInfo.ariaHasPopup) { + if (this._accInfo) { return this._accInfo.ariaHasPopup; } return this.showSuggestions ? "true" : undefined; } get ariaAutoComplete() { - if (this._accInfo && this._accInfo.ariaAutoComplete) { + if (this._accInfo) { return this._accInfo.ariaAutoComplete; } return this.showSuggestions ? "list" : undefined; From 5ed53a2d531e7f2295f57d0607d00797825d5890 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Thu, 5 Sep 2019 13:37:30 +0300 Subject: [PATCH 14/57] Improve of get methods for acc in input --- packages/main/src/DatePicker.hbs | 2 +- packages/main/src/Input.hbs | 14 ++++---- packages/main/src/Input.js | 57 +++++++++++--------------------- 3 files changed, 28 insertions(+), 45 deletions(-) diff --git a/packages/main/src/DatePicker.hbs b/packages/main/src/DatePicker.hbs index f60b5773ce29..0cd9c9e00131 100644 --- a/packages/main/src/DatePicker.hbs +++ b/packages/main/src/DatePicker.hbs @@ -16,7 +16,7 @@ @ui5-change="{{_handleInputChange}}" @ui5-input="{{_handleInputLiveChange}}" data-sap-focus-ref - ._accInfo ="{{accInfo}}" + ._inputAccInfo ="{{accInfo}}" > {{#unless readonly}} { return this.showSuggestions ? "true" : undefined; }, + "ariaAutoComplete": this._inputAccInfo ? this._inputAccInfo.ariaAutoComplete : () => { return this.showSuggestions ? "list" : undefined; }, + "role": this._inputAccInfo && this._inputAccInfo.role, + "ariaOwns": this._inputAccInfo && this._inputAccInfo.ariaOwns, + "ariaExpanded": this._inputAccInfo && this._inputAccInfo.ariaExpanded, + }, + }; } get hasValueState() { From 70b510447e159c412e0bb2e5b3d0530a08c8d46a Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Thu, 5 Sep 2019 16:20:33 +0300 Subject: [PATCH 15/57] update with comments from pr --- packages/main/src/Input.hbs | 14 +++++++------- packages/main/src/Input.js | 10 ++++++---- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/main/src/Input.hbs b/packages/main/src/Input.hbs index 5a36c59e3949..be700e7ada3c 100644 --- a/packages/main/src/Input.hbs +++ b/packages/main/src/Input.hbs @@ -16,13 +16,13 @@ ?required="{{required}}" .value="{{value}}" placeholder="{{inputPlaceholder}}" - role="{{accInfo.inputAccInfo.role}}" - aria-owns="{{accInfo.inputAccInfo.ariaOwns}}" - aria-invalid="{{accInfo.inputAccInfo.ariaInvalid}}" - aria-haspopup="{{accInfo.inputAccInfo.ariaHasPopup}}" - aria-describedby="{{accInfo.inputAccInfo.ariaDescribedBy}}" - aria-autocomplete="{{accInfo.inputAccInfo.ariaAutoComplete}}" - aria-expanded="{{accInfo.inputAccInfo.ariaExpanded}}" + role="{{accInfo.input.role}}" + aria-owns="{{accInfo.input.ariaOwns}}" + aria-invalid="{{accInfo.input.ariaInvalid}}" + aria-haspopup="{{accInfo.input.ariaHasPopup}}" + aria-describedby="{{accInfo.input.ariaDescribedBy}}" + aria-autocomplete="{{accInfo.input.ariaAutoComplete}}" + aria-expanded="{{accInfo.input.ariaExpanded}}" @input="{{_handleInput}}" @change="{{_handleChange}}" data-sap-no-tab-ref diff --git a/packages/main/src/Input.js b/packages/main/src/Input.js index d88b5dc514ae..a0ab586fc456 100644 --- a/packages/main/src/Input.js +++ b/packages/main/src/Input.js @@ -585,14 +585,16 @@ class Input extends UI5Element { } get accInfo() { + const ariaHasPopupDefault = this.showSuggestions ? "true" : undefined; + const ariaAutoCompleteDefault = this.showSuggestions ? "list" : undefined; return { - "wrapperAccInfo": { + "wrapper": { }, - "inputAccInfo": { + "input": { "ariaDescribedBy": this._inputAccInfo ? `${this.suggestionsTextId} ${this.valueStateTextId} ${this._inputAccInfo.ariaDescribedBy}`.trim() : `${this.suggestionsTextId} ${this.valueStateTextId}`.trim(), "ariaInvalid": this.valueState === ValueState.Error ? "true" : undefined, - "ariaHasPopup": this._inputAccInfo ? this._inputAccInfo.ariaHasPopup : () => { return this.showSuggestions ? "true" : undefined; }, - "ariaAutoComplete": this._inputAccInfo ? this._inputAccInfo.ariaAutoComplete : () => { return this.showSuggestions ? "list" : undefined; }, + "ariaHasPopup": this._inputAccInfo ? this._inputAccInfo.ariaHasPopup : ariaHasPopupDefault, + "ariaAutoComplete": this._inputAccInfo ? this._inputAccInfo.ariaAutoComplete : ariaAutoCompleteDefault, "role": this._inputAccInfo && this._inputAccInfo.role, "ariaOwns": this._inputAccInfo && this._inputAccInfo.ariaOwns, "ariaExpanded": this._inputAccInfo && this._inputAccInfo.ariaExpanded, From d6598dae6aafa5b42337d8223c9d4d2919869228 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Tue, 10 Sep 2019 11:27:35 +0300 Subject: [PATCH 16/57] changing the place of input parent information --- packages/main/src/DatePicker.hbs | 3 --- packages/main/src/DatePicker.js | 4 ++++ packages/main/src/Input.hbs | 4 ++++ packages/main/src/Input.js | 1 + 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/main/src/DatePicker.hbs b/packages/main/src/DatePicker.hbs index 0cd9c9e00131..a1f1dc8eddac 100644 --- a/packages/main/src/DatePicker.hbs +++ b/packages/main/src/DatePicker.hbs @@ -11,8 +11,6 @@ ?disabled="{{disabled}}" ?readonly="{{readonly}}" value-state="{{valueState}}" - aria-autocomplete="none" - aria-haspopup @ui5-change="{{_handleInputChange}}" @ui5-input="{{_handleInputLiveChange}}" data-sap-focus-ref @@ -51,6 +49,5 @@ @ui5-selectedDatesChange="{{_calendar.onSelectedDatesChange}}" > - {{dateAriaDescription}} diff --git a/packages/main/src/DatePicker.js b/packages/main/src/DatePicker.js index 8e56c5ef6374..24a6cfa0535d 100644 --- a/packages/main/src/DatePicker.js +++ b/packages/main/src/DatePicker.js @@ -409,6 +409,10 @@ class DatePicker extends UI5Element { "role": "combobox", "ariaOwns": `${this._id}-popover`, "ariaExpanded": this.isOpen(), + "parentInfo": { + "id": this._id, + "ariaDescription": this.dateAriaDescription, + }, }; } diff --git a/packages/main/src/Input.hbs b/packages/main/src/Input.hbs index be700e7ada3c..78029bfb7b74 100644 --- a/packages/main/src/Input.hbs +++ b/packages/main/src/Input.hbs @@ -38,6 +38,10 @@ {{suggestionsText}} {{/if}} + {{#if accInfo.input.parentInfo}} + {{accInfo.input.parentInfo.ariaDescription}} + {{/if}} + {{#if hasValueState}} {{valueStateText}} {{/if}} diff --git a/packages/main/src/Input.js b/packages/main/src/Input.js index a0ab586fc456..95e5106923b1 100644 --- a/packages/main/src/Input.js +++ b/packages/main/src/Input.js @@ -598,6 +598,7 @@ class Input extends UI5Element { "role": this._inputAccInfo && this._inputAccInfo.role, "ariaOwns": this._inputAccInfo && this._inputAccInfo.ariaOwns, "ariaExpanded": this._inputAccInfo && this._inputAccInfo.ariaExpanded, + "parentInfo": this._inputAccInfo && this._inputAccInfo.parentInfo, }, }; } From 0c842f7ea25a77be8907cc763f13067029d44763 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Tue, 10 Sep 2019 14:29:00 +0300 Subject: [PATCH 17/57] update escaping information repeating --- packages/main/src/DatePicker.js | 5 +---- packages/main/src/Input.hbs | 4 ++-- packages/main/src/Input.js | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/main/src/DatePicker.js b/packages/main/src/DatePicker.js index 24a6cfa0535d..7a95672407b9 100644 --- a/packages/main/src/DatePicker.js +++ b/packages/main/src/DatePicker.js @@ -409,10 +409,7 @@ class DatePicker extends UI5Element { "role": "combobox", "ariaOwns": `${this._id}-popover`, "ariaExpanded": this.isOpen(), - "parentInfo": { - "id": this._id, - "ariaDescription": this.dateAriaDescription, - }, + "ariaDescription": this.dateAriaDescription, }; } diff --git a/packages/main/src/Input.hbs b/packages/main/src/Input.hbs index 78029bfb7b74..eaf02bd056e0 100644 --- a/packages/main/src/Input.hbs +++ b/packages/main/src/Input.hbs @@ -38,8 +38,8 @@ {{suggestionsText}} {{/if}} - {{#if accInfo.input.parentInfo}} - {{accInfo.input.parentInfo.ariaDescription}} + {{#if accInfo.input.ariaDescribedBy}} + {{accInfo.input.ariaDescription}} {{/if}} {{#if hasValueState}} diff --git a/packages/main/src/Input.js b/packages/main/src/Input.js index 95e5106923b1..dfa4bab1efa1 100644 --- a/packages/main/src/Input.js +++ b/packages/main/src/Input.js @@ -598,7 +598,7 @@ class Input extends UI5Element { "role": this._inputAccInfo && this._inputAccInfo.role, "ariaOwns": this._inputAccInfo && this._inputAccInfo.ariaOwns, "ariaExpanded": this._inputAccInfo && this._inputAccInfo.ariaExpanded, - "parentInfo": this._inputAccInfo && this._inputAccInfo.parentInfo, + "ariaDescription": this._inputAccInfo && this._inputAccInfo.ariaDescription, }, }; } From cf56bf0c0166a5c5ace358c8aa81e5a1ad2324b3 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Mon, 28 Oct 2019 11:25:26 +0200 Subject: [PATCH 18/57] merge commit --- packages/main/src/Input.js | 16 ---------------- packages/main/src/themes/DatePicker.css | 3 --- 2 files changed, 19 deletions(-) diff --git a/packages/main/src/Input.js b/packages/main/src/Input.js index 9f978e2cab60..edcb1ef80661 100644 --- a/packages/main/src/Input.js +++ b/packages/main/src/Input.js @@ -590,21 +590,12 @@ class Input extends UI5Element { get suggestionsTextId() { return this.showSuggestions ? `${this._id}-suggestionsText` : ""; -<<<<<<< HEAD - } - - get valueStateTextId() { - return this.hasValueState ? `${this._id}-descr` : ""; - } - -======= } get valueStateTextId() { return this.hasValueState ? `${this._id}-valueStateDesc` : ""; } ->>>>>>> upstream/master get accInfo() { const ariaHasPopupDefault = this.showSuggestions ? "true" : undefined; const ariaAutoCompleteDefault = this.showSuggestions ? "list" : undefined; @@ -612,17 +603,10 @@ class Input extends UI5Element { "wrapper": { }, "input": { -<<<<<<< HEAD - "ariaDescribedBy": this._inputAccInfo ? `${this.suggestionsTextId} ${this.valueStateTextId} ${this._inputAccInfo.ariaDescribedBy}`.trim() : `${this.suggestionsTextId} ${this.valueStateTextId}`.trim(), - "ariaInvalid": this.valueState === ValueState.Error ? "true" : undefined, - "ariaHasPopup": this._inputAccInfo ? this._inputAccInfo.ariaHasPopup : ariaHasPopupDefault, - "ariaAutoComplete": this._inputAccInfo ? this._inputAccInfo.ariaAutoComplete : ariaAutoCompleteDefault, -======= "ariaDescribedBy": this._inputAccInfo.ariaDescribedBy ? `${this.suggestionsTextId} ${this.valueStateTextId} ${this._inputAccInfo.ariaDescribedBy}`.trim() : `${this.suggestionsTextId} ${this.valueStateTextId}`.trim(), "ariaInvalid": this.valueState === ValueState.Error ? "true" : undefined, "ariaHasPopup": this._inputAccInfo.ariaHasPopup ? this._inputAccInfo.ariaHasPopup : ariaHasPopupDefault, "ariaAutoComplete": this._inputAccInfo.ariaAutoComplete ? this._inputAccInfo.ariaAutoComplete : ariaAutoCompleteDefault, ->>>>>>> upstream/master "role": this._inputAccInfo && this._inputAccInfo.role, "ariaOwns": this._inputAccInfo && this._inputAccInfo.ariaOwns, "ariaExpanded": this._inputAccInfo && this._inputAccInfo.ariaExpanded, diff --git a/packages/main/src/themes/DatePicker.css b/packages/main/src/themes/DatePicker.css index 1cc7c600aafd..fe6e0fc97485 100644 --- a/packages/main/src/themes/DatePicker.css +++ b/packages/main/src/themes/DatePicker.css @@ -1,8 +1,5 @@ @import "./InvisibleTextStyles.css"; -<<<<<<< HEAD -======= @import "./InputIcon.css"; ->>>>>>> upstream/master :host(:not([hidden])) { display: inline-block; From 4e329fa188b3d513638803a05bfe1d19d19b1a1f Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Mon, 28 Oct 2019 14:57:25 +0200 Subject: [PATCH 19/57] fix(ui5-daypicker): Separating datepicker click handling to mousedown/up handlers(#872) --- packages/main/src/DayPicker.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/main/src/DayPicker.js b/packages/main/src/DayPicker.js index 66d71d8d7fb8..ff8a7abbe6d8 100644 --- a/packages/main/src/DayPicker.js +++ b/packages/main/src/DayPicker.js @@ -244,7 +244,7 @@ class DayPicker extends UI5Element { this._dayNames[0].classes += " ui5-dp-firstday"; } - onclick(event) { + onmousedown(event) { const target = getShadowDOMTarget(event); const dayPressed = this._isDayPressed(target); @@ -264,7 +264,13 @@ class DayPicker extends UI5Element { } } - this._modifySelectionAndNotifySubscribers(targetDate, event.ctrlKey); + this.targetDate = targetDate; + } + } + + onmouseup(event) { + if (this.targetDate) { + this._modifySelectionAndNotifySubscribers(this.targetDate, event.ctrlKey); } } From 49a4436f7699510157285a4bae92bd47f2b7e3dd Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Mon, 28 Oct 2019 16:49:35 +0200 Subject: [PATCH 20/57] On press between date cells the pop up no longer closes --- packages/main/src/DayPicker.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/main/src/DayPicker.js b/packages/main/src/DayPicker.js index ff8a7abbe6d8..08a50e81d7b9 100644 --- a/packages/main/src/DayPicker.js +++ b/packages/main/src/DayPicker.js @@ -271,6 +271,7 @@ class DayPicker extends UI5Element { onmouseup(event) { if (this.targetDate) { this._modifySelectionAndNotifySubscribers(this.targetDate, event.ctrlKey); + this.targetDate = null; } } From 9207a479e7adbb09666705d3ed0a8b901fd9c91f Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Thu, 23 Jan 2020 14:32:48 +0200 Subject: [PATCH 21/57] alpha timepicker and sliders version --- .../base/src/delegate/ScrollEnablement.js | 49 ++ packages/main/bundle.esm.js | 2 + packages/main/src/Slider.hbs | 32 ++ packages/main/src/Slider.js | 275 +++++++++++ packages/main/src/TimePicker.hbs | 70 +++ packages/main/src/TimePicker.js | 459 ++++++++++++++++++ packages/main/src/themes/Slider.css | 140 ++++++ packages/main/src/themes/TimePicker.css | 0 packages/main/test/pages/TimePicker.html | 24 + 9 files changed, 1051 insertions(+) create mode 100644 packages/main/src/Slider.hbs create mode 100644 packages/main/src/Slider.js create mode 100644 packages/main/src/TimePicker.hbs create mode 100644 packages/main/src/TimePicker.js create mode 100644 packages/main/src/themes/Slider.css create mode 100644 packages/main/src/themes/TimePicker.css create mode 100644 packages/main/test/pages/TimePicker.html diff --git a/packages/base/src/delegate/ScrollEnablement.js b/packages/base/src/delegate/ScrollEnablement.js index 75fb87e45576..f2224131f3df 100644 --- a/packages/base/src/delegate/ScrollEnablement.js +++ b/packages/base/src/delegate/ScrollEnablement.js @@ -75,6 +75,55 @@ class ScrollEnablement extends EventProvider { this._prevDragX = dragX; this._prevDragY = dragY; } + + // scrollToElement (element, animationTime, offsets) { + // aOffset = aOffset || [0, 0]; + + // // do nothing if _$Container is not a (grand)parent of oElement + // if (!this._container[0].contains(oElement) || + // oElement.style.display === "none" || + // oElement.offsetParent.nodeName.toUpperCase() === "HTML") { + // return this; + // } + + // var $Element = jQuery(oElement), + // oScrollPosition = this.getChildPosition($Element), + // iLeftScroll = this.getScrollLeft() + oScrollPosition.left + aOffset[0], + // iTopScroll = this.getScrollTop() + oScrollPosition.top + aOffset[1]; + + // if (this._bFlipX) { + // // in IE RTL scrollLeft goes opposite direction + // iLeftScroll = this.getScrollLeft() - (oScrollPosition.left - this._container.width()) - $Element.width(); + // } + + // // scroll to destination + // this._scrollTo(iLeftScroll, iTopScroll , animationTime); + + // return this; + // } + + + // _scrollTo(x, y, animationTime) { + // if (this._container.length > 0) { + // if (time > 0) { + // this._container.finish().animate({ scrollTop: y, scrollLeft: x }, animationTime, jQuery.proxy(this._readActualScrollPosition, this)); + // } else { + // this._container.scrollTop(y); + // this._container.scrollLeft(x); + // this._readActualScrollPosition(); // if container is too large no scrolling is possible + // } + // } + // } + + // _readActualScrollPosition() { + // // if container has a size, this method reads the current scroll position and stores it as desired position + // if (this._container.width() > 0) { + // this._scrollX = this._container.scrollLeft(); + // } + // if (this._container.height() > 0) { + // this._scrollY = this._container.scrollTop(); + // } + // } } export default ScrollEnablement; diff --git a/packages/main/bundle.esm.js b/packages/main/bundle.esm.js index f3a4dfc5872b..806c66bef043 100644 --- a/packages/main/bundle.esm.js +++ b/packages/main/bundle.esm.js @@ -32,6 +32,7 @@ import Panel from "./dist/Panel.js"; import RadioButton from "./dist/RadioButton.js"; import Select from "./dist/Select.js"; import Option from "./dist/Option.js"; +import Slider from "./dist/Slider.js" import Switch from "./dist/Switch.js"; import MessageStrip from "./dist/MessageStrip.js"; import MultiComboBox from "./dist/MultiComboBox.js"; @@ -45,6 +46,7 @@ import TableCell from "./dist/TableCell.js"; import TextArea from "./dist/TextArea.js"; import Timeline from "./dist/Timeline.js"; import TimelineItem from "./dist/TimelineItem.js"; +import TimePicker from "./dist/TimePicker.js"; import Title from "./dist/Title.js"; import Toast from "./dist/Toast.js"; import ToggleButton from "./dist/ToggleButton.js"; diff --git a/packages/main/src/Slider.hbs b/packages/main/src/Slider.hbs new file mode 100644 index 000000000000..f0007007a5f8 --- /dev/null +++ b/packages/main/src/Slider.hbs @@ -0,0 +1,32 @@ +
+
{{label}}
+
+ +
+
+
+ {{#if expanded}} +
+
    + {{#each items}} +
  • {{this}}
  • + {{/each}} +
+
+ {{else}} +
+
    +
  • {{value}}
  • +
+
+ {{/if}} +
+ +
\ No newline at end of file diff --git a/packages/main/src/Slider.js b/packages/main/src/Slider.js new file mode 100644 index 000000000000..308feeb2a639 --- /dev/null +++ b/packages/main/src/Slider.js @@ -0,0 +1,275 @@ +import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; +import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; +import SliderTemplate from "./generated/templates/SliderTemplate.lit.js"; + +// Styles +import SliderCss from "./generated/themes/Slider.css.js"; +import ScrollEnablement from "@ui5/webcomponents-base/dist/delegate/ScrollEnablement.js"; + +/** + * @private + */ +const metadata = { + tag: "ui5-slider", + properties: /** @lends sap.ui.webcomponents.main.Slider.prototype */ { + /** + * Defines whether the ui5-slider is disabled + * (default is set to false). + * A disabled ui5-slider can't be pressed or + * focused, and it is not in the tab chain. + * + * @type {boolean} + * @defaultvalue false + * @public + */ + disabled: { + type: Boolean + }, + + /** + * Defines the currently selected value + * @type {string} + * @defaultvalue "" + * @public + */ + value: { + type: String + }, + + /** + * Indicates if the slider will support cyclic scrolling. + * @type {boolean} + * @defaultvalue false + * @public + */ + isCyclic: { + type: Boolean + }, + + /** + * Defines the label of the slider. + * @type {string} + * @defaultvalue "" + * @public + */ + label: { + type: String, + defaultValue: "" + }, + + /** + * Indicates if the slider is expanded. + * @type {boolean} + * @defaultvalue false + * @public + */ + isExpanded: { + type: Boolean + }, + + _items: { + type: Object + } + }, + slots: /** @lends sap.ui.webcomponents.main.Slider.prototype */ { + // /** + // * Defines the ui5-slider items. + // * + // * @type {HTMLElement[]} + // * @slot + // * @public + // */ + // items: { + // "default": { + // propertyName: "items", + // type: HTMLElement, + // listenFor: { include: ["*"] }, + // } + // } + }, + events: /** @lends sap.ui.webcomponents.main.Slider.prototype */ { + /** + * Fires when the slider is expanded. + */ + expanded: {}, + + /** + * Fires when the slider is collapsed. + */ + collapsed: {}, + + /** + * Fires when new value is selected. + */ + valueSelect: { + value: { + type: String + } + } + }, +}; + +/** + * @class + * + *

Overview

+ * + * + *

Usage

+ * + * For the ui5-slider + *

ES6 Module Import

+ * + * import @ui5/webcomponents/dist/Slider.js"; + * + * @constructor + * @author SAP SE + * @alias sap.ui.webcomponents.main.Slider + * @extends UI5Element + * @tagname ui5-slider + * @public + */ +class Slider extends UI5Element { + static get metadata() { + return metadata; + } + + static get render() { + return litRender; + } + + static get styles() { + return SliderCss; + } + + static get template() { + return SliderTemplate; + } + + static async define(...params) { + super.define(...params); + } + + constructor() { + super(); + + this._items = ["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"]; + this.value = this._items[0]; + //this.i18nBundle = getI18nBundle("@ui5/webcomponents"); + this._scroller = new ScrollEnablement(this); + this.prevElement = 0; + } + + _findSelectedElement(){ + let itemsList = this.shadowRoot.querySelector(`#${this._id}--items-list`), + parentOffset = itemsList.parentElement.parentElement.offsetTop, + itemsListArray = [].slice.call(itemsList.children), + firstVisibleElementIndex = 0; + + while ((itemsListArray[firstVisibleElementIndex].getBoundingClientRect().y - parentOffset) < 0){ + firstVisibleElementIndex++; + } + + return itemsListArray[firstVisibleElementIndex + 5]; + } + + _updateScrolling(e){ + let sizeInRems = this._items.length * 3, // the size of one element in rems (16px = 1rem) + sizeOfOneElementInPixels = 48, + indexForOffset; + const elements = this.shadowRoot.querySelectorAll(".sapMWSItem"); + + //console.log(this.value + " " + this._findSelectedElement().textContent); + if (this.value === this._findSelectedElement().textContent) { + return; + } + + if ( (e.scroll / sizeOfOneElementInPixels) / 0.5 > 1) { + indexForOffset = Math.ceil(e.scroll / sizeOfOneElementInPixels); + } else { + indexForOffset = Math.floor(e.scroll / sizeOfOneElementInPixels); + } + + this._selectElement(this._findSelectedElement()); + this.value = this._findSelectedElement().textContent; + //console.log(this._findSelectedElement()); + } + + onAfterRendering() { + this._scroller.scrollContainer = this.shadowRoot.querySelector(`#${this._id}--wrapper`); + this._scroller.attachEvent("scroll", this._updateScrolling.bind(this)); + if (this.expanded) { + const elements = this.shadowRoot.querySelectorAll(".sapMWSItem"); + for (var i = 0; i < elements.length; i++){ + if (elements[i].textContent === this.value){ + this._selectElement(elements[i]); + return true; + } + } + + this._selectElement(elements[0]); + } + } + + get items() {; + return this._items; + } + + get isExpandedClass(){ + if (this.expanded){ + return " sapMWSExpanded"; + } + + return ""; + } + + get isDisabledClass(){ + if (this.disabled){ + return " sapMWSDisabled"; + } + + return ""; + } + + _onelementclick(e) { + if(e.target.classList.contains("sapMWSItem")) { + this.value = e.target.textContent; + } + + if (!this.expanded) { + this.expanded = true; + this._invalidate(); + } + + this._selectElement(e.target); + } + + expandSlider(){ + this.expanded = true; + this._invalidate(); + this.fireEvent("expanded",{}); + } + + collapseSlider(){ + this.expanded = false; + this._invalidate(); + this.fireEvent("collapsed",{}); + } + + _selectElement(element){ + if (this._items.indexOf(element.textContent) > - 1) { + let offsetSelectedElement = 15 - (this._items.indexOf(element.textContent) * 3); + element.parentElement.setAttribute("style",`top:${offsetSelectedElement}rem`); + } + } + + _onbuttonclick(e) { + debugger; + + return true; + } +} + +Slider.define(); + +export default Slider; diff --git a/packages/main/src/TimePicker.hbs b/packages/main/src/TimePicker.hbs new file mode 100644 index 000000000000..07f4f0b73285 --- /dev/null +++ b/packages/main/src/TimePicker.hbs @@ -0,0 +1,70 @@ +
+ + + + + {{#if shouldBuildHoursSlider}} + + + {{/if}} + {{#if shouldBuildMinutesSlider}} + + + {{/if}} + {{#if shouldBuildSecondsSlider}} + + + {{/if}} + {{#if shouldBuildPeriodsSlider}} + + + {{/if}} +
+ Submit + Close +
+
+
\ No newline at end of file diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js new file mode 100644 index 000000000000..ebe6b5992be9 --- /dev/null +++ b/packages/main/src/TimePicker.js @@ -0,0 +1,459 @@ +import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; +import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; +import TimePickerTemplate from "./generated/templates/TimePickerTemplate.lit.js"; +import Popover from "./Popover.js"; +import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js"; +import PopoverPlacementType from "./types/PopoverPlacementType.js"; +import PopoverHorizontalAlign from "./types/PopoverHorizontalAlign.js"; +import DateFormat from "@ui5/webcomponents-utils/dist/sap/ui/core/format/DateFormat.js"; +import { fetchCldr } from "@ui5/webcomponents-base/dist/asset-registries/LocaleData.js"; +import { getLocale } from "@ui5/webcomponents-base/dist/LocaleProvider.js"; + +// Styles +import TimePickerCss from "./generated/themes/TimePicker.css.js"; + +/** + * @public + */ +const metadata = { + tag: "ui5-time-picker", + properties: /** @lends sap.ui.webcomponents.main.TimePicker.prototype */ { + /** + * Defines a formatted time value. + * + * @type {string} + * @defaultvalue "" + * @public + */ + value: { + type: String, + defaultValue: "" + }, + + /** + * Visualizes the validation state of the Web Component, for example + * Error, Warning and + * Success. + * + * @type {string} + * @defaultvalue "None" + * @public + */ + valueState: { + type: ValueState, + defaultValue: ValueState.None, + }, + + /** + * Determines the format, displayed in the input field. + * + * @type {string} + * @defaultvalue "" + * @public + */ + formatPattern: { + type: String, + defaultValue: "HH:mm:ss" + }, + + /** + * Visualizes the validation state of the Web Component, for example + * Error, Warning and + * Success. + * + * @type {string} + * @defaultvalue "None" + * @public + */ + valueState: { + type: ValueState, + defaultValue: ValueState.None, + }, + + /** + * Defines a short hint, intended to aid the user with data entry when the + * ui5-datepicker has no value. + * + * Note: When no placeholder is set, the format pattern is displayed as a placeholder. + * Passing an empty string as the value of this property will make the ui5-time-picker appear empty - without placeholder or format pattern. + * + * @type {string} + * @defaultvalue undefined + * @public + */ + placeholder: { + type: String, + defaultValue: undefined, + }, + + /** + * Determines whether the ui5-datepicker is displayed as disabled. + * + * @type {boolean} + * @defaultvalue false + * @public + */ + disabled: { + type: Boolean, + }, + + /** + * Determines whether the ui5-datepicker is displayed as readonly. + * + * @type {boolean} + * @defaultvalue false + * @public + */ + readonly: { + type: Boolean, + }, + + _isPickerOpen: { + type: Boolean, + noAttribute: true, + }, + + _popover: { + type: Object, + }, + + _hours: { + type: String, + }, + + _minutes: { + type: String, + }, + + _seconds: { + type: String, + }, + + isTwelveHoursFormat: { + type: Boolean, + } + }, + slots: /** @lends sap.ui.webcomponents.main.TimePicker.prototype */ { + // + }, + events: /** @lends sap.ui.webcomponents.main.TimePicker.prototype */ { + // + }, +}; + +/** + * @class + * + *

Overview

+ * + * + *

Usage

+ * + * For the ui5-time-picker + *

ES6 Module Import

+ * + * import @ui5/webcomponents/dist/TimePicker.js"; + * + * @constructor + * @author SAP SE + * @alias sap.ui.webcomponents.main.TimePicker + * @extends UI5Element + * @tagname ui5-time-picker + * @public + */ +class TimePicker extends UI5Element { + static get metadata() { + return metadata; + } + + static get render() { + return litRender; + } + + static get styles() { + return TimePickerCss; + } + + static get template() { + return TimePickerTemplate; + } + + static async define(...params) { + await Promise.all([ + fetchCldr(getLocale().getLanguage(), getLocale().getRegion(), getLocale().getScript()), + ]); + + super.define(...params); + } + + constructor() { + super(); + + this.readonly = false; + this.disabled = false; + this._isPickerOpen = false; + //this.i18nBundle = getI18nBundle("@ui5/webcomponents"); + //this._scroller = new ScrollEnablement(this); + + this._popover = { + placementType: PopoverPlacementType.Bottom, + horizontalAlign: PopoverHorizontalAlign.Left, + allowTargetOverlap: true, + stayOpenOnScroll: true, + afterClose: () => { + this._isPickerOpen = false; + } + }; + } + + onAfterRendering() { + let sliders = this._getPopover().default.filter(x => x.isUI5Element), + slidersEnablementArray = this._getSlidersContained(this.formatPattern); + + for (let i = 0; i < sliders.length; i++) { + sliders[i].disabled = !slidersEnablementArray[i]; + } + + this.setSlidersValue(); + } + + _handleInputChange() { + let nextValue = this._getInput().getInputValue(); + const isValid = this.isValid(nextValue); + + if (isValid) { + nextValue = this.normalizeValue(nextValue); + } + + this.value = nextValue; + this.fireEvent("change", { value: nextValue, valid: isValid }); + this.fireEvent("value-changed", { value: nextValue, valid: isValid }); + } + + _handleInputLiveChange() { + const nextValue = this._getInput().getInputValue(), + isValid = this.isValid(nextValue); + + this.value = nextValue; + this.fireEvent("input", { value: nextValue, valid: isValid }); + } + + setSlidersValue(){ + let currentDate = this._getInput ? this.getFormat().parse(this._getInput().value) : null, + sliders = this._getPopover().default.filter(x => x.isUI5Element); + + if (currentDate){ + for (let i = 0; i < sliders.length; i++) { + if (sliders[i].label === "Hours") { + sliders[i].value = currentDate.getHours(); + } else if (sliders[i].label === "Minutes") { + sliders[i].value = currentDate.getMinutes(); + } else if (sliders[i].label === "Seconds") { + sliders[i].value = currentDate.getSeconds(); + } + } + } + } + + closePicker() { + let sliders = this._getPopover().default.filter(x => x.isUI5Element); + + this._getPopover().close(); + + for (let i = 0; i < sliders.length; i++){ + sliders[i].collapseSlider(); + } + } + + openPicker() { + this._getPopover().openBy(this); + this._isPickerOpen = true; + } + + togglePicker() { + if (this.isOpen()) { + this.closePicker(); + } else if (this._canOpenPicker()) { + this.openPicker(); + } + } + /** + * Checks if the picker is open. + * @returns {Boolean} true if the picker is open, false otherwise + * @public + */ + isOpen() { + return !!this._isPickerOpen; + } + + _canOpenPicker() { + return !this.disabled && !this.readonly; + } + + _getPopover() { + return this.shadowRoot.querySelector("ui5-popover"); + } + + generateTimeItemsArray(x) { + let array = [...Array(x).keys()]; + + array = array.map(i => '' + i); + + return array; + } + + get secondsArray() { + return this.generateTimeItemsArray(60); + } + + get minutesArray() { + return this.generateTimeItemsArray(60); + } + + get hoursArray() { + if (this.isTwelveHoursFormat){ + return this.generateTimeItemsArray(12); + } + return this.generateTimeItemsArray(24); + } + + get periodsArray() { + return ["AM", "PM"]; + } + + _getInput() { + return this.shadowRoot.querySelector("ui5-input"); + } + + submitPickers() { + let sliders = this._getPopover().default.filter(x => x.isUI5Element), + selectedDate = new Date(), + hours = "0", + minutes = "0", + seconds = "0"; + + for (let i = 0; i < sliders.length; i++) { + if (sliders[i].label === "Hours") { + hours = sliders[i].value; + } else if (sliders[i].label === "Minutes") { + minutes = sliders[i].value; + } else if (sliders[i].label === "Seconds") { + seconds = sliders[i].value; + } + } + + selectedDate.setHours(hours); + selectedDate.setMinutes(minutes); + selectedDate.setSeconds(seconds); + + //Add check if it's 12 hours format to add 12 hours in PM+ + this.setValue(this.getFormat().format(selectedDate)); + + this.closePicker(); + } + + /** + * Checks if a value is valid against the current time format of the TimePicker + * @param {string} value A value to be tested against the current time format + * @public + */ + isValid(value = "") { + return !!(value && this.getFormat().parse(value)); + } + + // because the parser understands more than one format + // but we need values in one format + normalizeValue(sValue) { + return this.getFormat().format(this.getFormat().parse(sValue)); + } + + get _formatPattern() { + return this.formatPattern || "medium"; // get from config + } + + get _isPattern() { + return this._formatPattern !== "medium" && this._formatPattern !== "short" && this._formatPattern !== "long"; + } + + get _displayFormat() { + return this.getFormat().oFormatOptions.pattern; + } + + get _placeholder() { + return this.placeholder !== undefined ? this.placeholder : this._displayFormat; + } + + handleSliderClicked(event){ + let sliders = this._getPopover().default.filter(x => x.isUI5Element); + if (event.target.expanded){ + for (var i = 0; i < sliders.length; i++){ + if (sliders[i].label !== event.target.label){ + sliders[i].collapseSlider(); + } + } + } + } + + getFormat() { + if (this._isPattern) { + this._oDateFormat = DateFormat.getInstance({ + pattern: this._formatPattern, + }); + } else { + this._oDateFormat = DateFormat.getInstance({ + style: this._formatPattern, + }); + } + + return this._oDateFormat; + } + + + setValue(value){ + if (this.isValid(value)){ + this.value = this.normalizeValue(value); + } else { + this.valueState = ValueState.Error; + } + } + + _getSlidersContained (){ + let formatArray = this.getFormat().aFormatArray, + slidersBuildArray = [false, false, false, false]; // hours minutes seconds am/pm + + for (var i = 0; i < formatArray.length; i++){ + if (formatArray[i].type === "hour0_23"){ + slidersBuildArray[0] = true; + } + if (formatArray[i].type === "hour1_12"){ + slidersBuildArray[3] = true; + slidersBuildArray[0] = true; + } + if (formatArray[i].type === "minute"){ + slidersBuildArray[1] = true; + } + if (formatArray[i].type === "second"){ + slidersBuildArray[2] = true; + } + } + + return slidersBuildArray; + } + + get shouldBuildHoursSlider(){ + return this._getSlidersContained()[0]; + } + get shouldBuildMinutesSlider(){ + return this._getSlidersContained()[1]; + } + get shouldBuildSecondsSlider(){ + return this._getSlidersContained()[2]; + } + get shouldBuildPeriodsSlider(){ + return this._getSlidersContained()[3]; + } +} + +TimePicker.define(); + +export default TimePicker; diff --git a/packages/main/src/themes/Slider.css b/packages/main/src/themes/Slider.css new file mode 100644 index 000000000000..ac115883e87c --- /dev/null +++ b/packages/main/src/themes/Slider.css @@ -0,0 +1,140 @@ +.sapMWS { + display: inline-block; + overflow: hidden; + height: 100%; + vertical-align: middle; + text-align: center; + box-sizing: border-box; + cursor: pointer; +} +.sapMWS .sapMWSLabel { + box-sizing: border-box; + height: 2rem; + line-height: 2rem; + width: 4.5rem; + text-align: center; + font-size: 20x; + color: gray; + text-align: center; + vertical-align: middle; +} +.sapMWS .sapMWSArrows { + display: none; + box-sizing: border-box; +} +.sapMWS .sapMWSInner { + overflow: hidden; + height: 100%; + box-sizing: border-box; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + list-style: none; +} +.sapMWS .sapMWSInner .sapMWSItem { + height: 3rem; + line-height: 3rem; + width: 4.5rem; + box-sizing: border-box; + background: darkblue; + border: 1px solid white; + font-size: 15px; + color: lightgray; + text-align: center; + border-radius: 5px; +} +.sapMWS .sapMWSInner .sapMWSItem:hover { + background: orange; + color: red; +} +.sapMWS .sapMWSInner .sapMWSItem:active { + background: yellow; + color: pink; +} +.sapMWS .sapMWSInner .sapMWSItem:focus { + outline: 1px dotted black; + outline-offset: -3px; +} +.sapMWS .sapMWSInner .sapMWSSelectionFrame { + width: 4.5rem; + height: 3rem; + position: absolute; + box-sizing: border-box; + display: none; + z-index: 1; +} +.sapMWS .sapMWSInner .sapMWrapper > ul { + transition: all 400ms; + margin: 0; + padding: 0; + position: absolute; + top: 15rem; +} + +.sapMWS.sapMWSExpanded .sapMWSInner .sapMWrapper > ul { + top: 0; +} + +.sapMWS .sapMWSInner .sapMWrapper { + height: 27rem; + position: relative; +} + +.sapMWS.sapMWSExpanded { + height: 100%; + cursor: default; + margin: 0; +} + +.sapMWS.sapMWSExpanded .sapMWSLabel { + display: block; +} +.sapMWS .sapMWSArrows { + display: none; +} + +.sapMWS .sapMWSInner { + max-height: 100%; + height: 27rem; +} + +.sapMWS.sapMWSExpanded .sapMWSInner .sapMWSItem { + background:lightgray; + color: black; + border: 1px solid white; + border-radius: 5px; + offset-position: auto; +} + +.sapMWS.sapMWSExpanded .sapMWSInner .sapMWSItem:hover { + background: rgba(211,211,211,0.5); +} + +.sapMWS.sapMWSExpanded .sapMWSInner .sapMWSItem:active { + background: darkblue; + color: lightgray; +} + +.sapMWS.sapMWSExpanded .sapMWSInner .sapMWSItem:focus { + outline: 1px dotted black; + outline-offset: -3px; +} + +.sapMWS.sapMWSExpanded .sapMWSInner .sapMWSSelectionFrame { + display: block; + outline: 0.125rem solid darkblue; + outline-offset: -0.313rem; + top: 20.5rem; +} + +.sapMWS.sapMWSExpanded .sapMWSInner .sapMWSSelectionFrame:hover + ul > li.sapMWSItem.sapMWSItemSelected { + background: darkblue; +} +.sapMWS.sapMWSExpanded .sapMWSInner .sapMWSSelectionFrame:active + ul > li.sapMWSItem.sapMWSItemSelected { + background: darkblue; + color: lightgray; +} +.sapMWS:focus { + outline: none; +} \ No newline at end of file diff --git a/packages/main/src/themes/TimePicker.css b/packages/main/src/themes/TimePicker.css new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/main/test/pages/TimePicker.html b/packages/main/test/pages/TimePicker.html new file mode 100644 index 000000000000..d3358ca0a130 --- /dev/null +++ b/packages/main/test/pages/TimePicker.html @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + From 053db11a865a06c65cdae622ee02a154559b0277 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Fri, 31 Jan 2020 13:44:06 +0200 Subject: [PATCH 22/57] Arrows added to sliders --- packages/main/src/Slider.hbs | 4 +- packages/main/src/Slider.js | 29 ++++++--- packages/main/src/TimePicker.js | 79 ++++++++++++------------ packages/main/src/themes/Slider.css | 26 ++++++-- packages/main/test/pages/TimePicker.html | 2 +- 5 files changed, 85 insertions(+), 55 deletions(-) diff --git a/packages/main/src/Slider.hbs b/packages/main/src/Slider.hbs index f0007007a5f8..2541d4df810b 100644 --- a/packages/main/src/Slider.hbs +++ b/packages/main/src/Slider.hbs @@ -8,7 +8,7 @@ class = "sapMWS{{isExpandedClass}}{{isDisabledClass}}">
{{label}}
- +
@@ -28,5 +28,5 @@
{{/if}} - + \ No newline at end of file diff --git a/packages/main/src/Slider.js b/packages/main/src/Slider.js index 308feeb2a639..0064e66bece5 100644 --- a/packages/main/src/Slider.js +++ b/packages/main/src/Slider.js @@ -158,6 +158,7 @@ class Slider extends UI5Element { //this.i18nBundle = getI18nBundle("@ui5/webcomponents"); this._scroller = new ScrollEnablement(this); this.prevElement = 0; + this._currentElementIndex = 0; } _findSelectedElement(){ @@ -192,7 +193,6 @@ class Slider extends UI5Element { this._selectElement(this._findSelectedElement()); this.value = this._findSelectedElement().textContent; - //console.log(this._findSelectedElement()); } onAfterRendering() { @@ -257,16 +257,31 @@ class Slider extends UI5Element { } _selectElement(element){ - if (this._items.indexOf(element.textContent) > - 1) { - let offsetSelectedElement = 15 - (this._items.indexOf(element.textContent) * 3); - element.parentElement.setAttribute("style",`top:${offsetSelectedElement}rem`); + if (this._items.indexOf(element.textContent) > -1){ + this._currentElementIndex = this._items.indexOf(element.textContent); + this._selectElementByIndex(this._currentElementIndex); } } - _onbuttonclick(e) { - debugger; + _selectElementByIndex(index){ + const sliderElement = this.shadowRoot.getElementById(`${this._id}--items-list`); + if (index > - 1) { + let offsetSelectedElement = 12 - (index * 3); + sliderElement.setAttribute("style",`top:${offsetSelectedElement}rem`); + this.value = this._items[index] + } + } + + _onArrowDown(){ + const nextElementIndex = this._currentElementIndex + 1; + this._selectElementByIndex(nextElementIndex); + this._currentElementIndex = nextElementIndex; + } - return true; + _onArrowUp(){ + const nextElementIndex = this._currentElementIndex - 1; + this._selectElementByIndex(nextElementIndex); + this._currentElementIndex = nextElementIndex; } } diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index ebe6b5992be9..62bbd1bc0cc5 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -16,15 +16,15 @@ import TimePickerCss from "./generated/themes/TimePicker.css.js"; * @public */ const metadata = { - tag: "ui5-time-picker", + tag: "ui5-timepicker", properties: /** @lends sap.ui.webcomponents.main.TimePicker.prototype */ { - /** - * Defines a formatted time value. - * - * @type {string} - * @defaultvalue "" - * @public - */ + /** + * Defines a formatted time value. + * + * @type {string} + * @defaultvalue "" + * @public + */ value: { type: String, defaultValue: "" @@ -149,7 +149,7 @@ const metadata = { * *

Usage

* - * For the ui5-time-picker + * For the ui5-timepicker *

ES6 Module Import

* * import @ui5/webcomponents/dist/TimePicker.js"; @@ -158,7 +158,7 @@ const metadata = { * @author SAP SE * @alias sap.ui.webcomponents.main.TimePicker * @extends UI5Element - * @tagname ui5-time-picker + * @tagname ui5-timepicker * @public */ class TimePicker extends UI5Element { @@ -207,7 +207,7 @@ class TimePicker extends UI5Element { } onAfterRendering() { - let sliders = this._getPopover().default.filter(x => x.isUI5Element), + let sliders = this._getPopover().default.filter(x => x.isUI5Element), slidersEnablementArray = this._getSlidersContained(this.formatPattern); for (let i = 0; i < sliders.length; i++) { @@ -238,11 +238,11 @@ class TimePicker extends UI5Element { this.fireEvent("input", { value: nextValue, valid: isValid }); } - setSlidersValue(){ + setSlidersValue() { let currentDate = this._getInput ? this.getFormat().parse(this._getInput().value) : null, - sliders = this._getPopover().default.filter(x => x.isUI5Element); + sliders = this._getPopover().default.filter(x => x.isUI5Element); - if (currentDate){ + if (currentDate) { for (let i = 0; i < sliders.length; i++) { if (sliders[i].label === "Hours") { sliders[i].value = currentDate.getHours(); @@ -256,11 +256,11 @@ class TimePicker extends UI5Element { } closePicker() { - let sliders = this._getPopover().default.filter(x => x.isUI5Element); + let sliders = this._getPopover().default.filter(x => x.isUI5Element); this._getPopover().close(); - for (let i = 0; i < sliders.length; i++){ + for (let i = 0; i < sliders.length; i++) { sliders[i].collapseSlider(); } } @@ -311,7 +311,7 @@ class TimePicker extends UI5Element { } get hoursArray() { - if (this.isTwelveHoursFormat){ + if (this.isTwelveHoursFormat) { return this.generateTimeItemsArray(12); } return this.generateTimeItemsArray(24); @@ -326,7 +326,7 @@ class TimePicker extends UI5Element { } submitPickers() { - let sliders = this._getPopover().default.filter(x => x.isUI5Element), + let sliders = this._getPopover().default.filter(x => x.isUI5Element), selectedDate = new Date(), hours = "0", minutes = "0", @@ -347,6 +347,7 @@ class TimePicker extends UI5Element { selectedDate.setSeconds(seconds); //Add check if it's 12 hours format to add 12 hours in PM+ + //TODO this.setValue(this.getFormat().format(selectedDate)); this.closePicker(); @@ -383,13 +384,13 @@ class TimePicker extends UI5Element { return this.placeholder !== undefined ? this.placeholder : this._displayFormat; } - handleSliderClicked(event){ - let sliders = this._getPopover().default.filter(x => x.isUI5Element); - if (event.target.expanded){ - for (var i = 0; i < sliders.length; i++){ - if (sliders[i].label !== event.target.label){ + handleSliderClicked(event) { + let sliders = this._getPopover().default.filter(x => x.isUI5Element); + if (event.target.expanded) { + for (var i = 0; i < sliders.length; i++) { + if (sliders[i].label !== event.target.label) { sliders[i].collapseSlider(); - } + } } } } @@ -409,47 +410,47 @@ class TimePicker extends UI5Element { } - setValue(value){ - if (this.isValid(value)){ + setValue(value) { + if (this.isValid(value)) { this.value = this.normalizeValue(value); } else { this.valueState = ValueState.Error; } } - _getSlidersContained (){ + _getSlidersContained() { let formatArray = this.getFormat().aFormatArray, slidersBuildArray = [false, false, false, false]; // hours minutes seconds am/pm - - for (var i = 0; i < formatArray.length; i++){ - if (formatArray[i].type === "hour0_23"){ + + for (var i = 0; i < formatArray.length; i++) { + if (formatArray[i].type === "hour0_23") { slidersBuildArray[0] = true; } - if (formatArray[i].type === "hour1_12"){ + if (formatArray[i].type === "hour1_12") { slidersBuildArray[3] = true; slidersBuildArray[0] = true; } - if (formatArray[i].type === "minute"){ + if (formatArray[i].type === "minute") { slidersBuildArray[1] = true; - } - if (formatArray[i].type === "second"){ + } + if (formatArray[i].type === "second") { slidersBuildArray[2] = true; - } + } } return slidersBuildArray; } - get shouldBuildHoursSlider(){ + get shouldBuildHoursSlider() { return this._getSlidersContained()[0]; } - get shouldBuildMinutesSlider(){ + get shouldBuildMinutesSlider() { return this._getSlidersContained()[1]; } - get shouldBuildSecondsSlider(){ + get shouldBuildSecondsSlider() { return this._getSlidersContained()[2]; } - get shouldBuildPeriodsSlider(){ + get shouldBuildPeriodsSlider() { return this._getSlidersContained()[3]; } } diff --git a/packages/main/src/themes/Slider.css b/packages/main/src/themes/Slider.css index ac115883e87c..af597d846850 100644 --- a/packages/main/src/themes/Slider.css +++ b/packages/main/src/themes/Slider.css @@ -13,15 +13,25 @@ line-height: 2rem; width: 4.5rem; text-align: center; - font-size: 20x; + font-size: 20px; color: gray; text-align: center; vertical-align: middle; } + .sapMWS .sapMWSArrows { display: none; box-sizing: border-box; } + +.sapMWS.sapMWSExpanded .sapMWSArrows { + display: block; + box-sizing: border-box; + width: 100%; + border-color: transparent; + height: 1.5rem; +} + .sapMWS .sapMWSInner { overflow: hidden; height: 100%; @@ -31,7 +41,13 @@ -ms-user-select: none; user-select: none; list-style: none; + margin-top: 4.5rem; } + +.sapMWS.sapMWSExpanded .sapMWSInner { + margin-top: 0; +} + .sapMWS .sapMWSInner .sapMWSItem { height: 3rem; line-height: 3rem; @@ -69,7 +85,7 @@ margin: 0; padding: 0; position: absolute; - top: 15rem; + top: 9rem; } .sapMWS.sapMWSExpanded .sapMWSInner .sapMWrapper > ul { @@ -85,14 +101,12 @@ height: 100%; cursor: default; margin: 0; + margin-top: -1.5rem; } .sapMWS.sapMWSExpanded .sapMWSLabel { display: block; } -.sapMWS .sapMWSArrows { - display: none; -} .sapMWS .sapMWSInner { max-height: 100%; @@ -125,7 +139,7 @@ display: block; outline: 0.125rem solid darkblue; outline-offset: -0.313rem; - top: 20.5rem; + top: 47.9%;; } .sapMWS.sapMWSExpanded .sapMWSInner .sapMWSSelectionFrame:hover + ul > li.sapMWSItem.sapMWSItemSelected { diff --git a/packages/main/test/pages/TimePicker.html b/packages/main/test/pages/TimePicker.html index d3358ca0a130..852e5766a3c9 100644 --- a/packages/main/test/pages/TimePicker.html +++ b/packages/main/test/pages/TimePicker.html @@ -19,6 +19,6 @@ - + From 7e496c850ca1df26bc60fa601120c77b2a0ad64a Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Fri, 31 Jan 2020 14:55:32 +0200 Subject: [PATCH 23/57] the input now works with am pm --- packages/main/src/Slider.js | 7 +++---- packages/main/src/TimePicker.js | 17 +++++++++++++---- packages/main/test/pages/TimePicker.html | 2 +- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/main/src/Slider.js b/packages/main/src/Slider.js index 0064e66bece5..2f70412ac3ec 100644 --- a/packages/main/src/Slider.js +++ b/packages/main/src/Slider.js @@ -265,23 +265,22 @@ class Slider extends UI5Element { _selectElementByIndex(index){ const sliderElement = this.shadowRoot.getElementById(`${this._id}--items-list`); - if (index > - 1) { + if ( index < this._items.length && index > - 1) { let offsetSelectedElement = 12 - (index * 3); sliderElement.setAttribute("style",`top:${offsetSelectedElement}rem`); - this.value = this._items[index] + this.value = this._items[index]; + this._currentElementIndex = index; } } _onArrowDown(){ const nextElementIndex = this._currentElementIndex + 1; this._selectElementByIndex(nextElementIndex); - this._currentElementIndex = nextElementIndex; } _onArrowUp(){ const nextElementIndex = this._currentElementIndex - 1; this._selectElementByIndex(nextElementIndex); - this._currentElementIndex = nextElementIndex; } } diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index 62bbd1bc0cc5..48d06dd71a58 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -250,6 +250,8 @@ class TimePicker extends UI5Element { sliders[i].value = currentDate.getMinutes(); } else if (sliders[i].label === "Seconds") { sliders[i].value = currentDate.getSeconds(); + } else if (this.isTwelveHoursFormat && sliders[i].label === "AM/PM") { + sliders[i].value = currentDate.getHours() > 11 ? "PM" : "AM"; } } } @@ -330,7 +332,8 @@ class TimePicker extends UI5Element { selectedDate = new Date(), hours = "0", minutes = "0", - seconds = "0"; + seconds = "0", + period = "AM"; for (let i = 0; i < sliders.length; i++) { if (sliders[i].label === "Hours") { @@ -339,15 +342,19 @@ class TimePicker extends UI5Element { minutes = sliders[i].value; } else if (sliders[i].label === "Seconds") { seconds = sliders[i].value; + } else if (sliders[i].label === "AM/PM"){ + period = sliders[i].value; } } - selectedDate.setHours(hours); + if (period === "PM") { + selectedDate.setHours(hours*1 + 12); + } else { + selectedDate.setHours(hours); + } selectedDate.setMinutes(minutes); selectedDate.setSeconds(seconds); - //Add check if it's 12 hours format to add 12 hours in PM+ - //TODO this.setValue(this.getFormat().format(selectedDate)); this.closePicker(); @@ -425,10 +432,12 @@ class TimePicker extends UI5Element { for (var i = 0; i < formatArray.length; i++) { if (formatArray[i].type === "hour0_23") { slidersBuildArray[0] = true; + this.isTwelveHoursFormat = false; } if (formatArray[i].type === "hour1_12") { slidersBuildArray[3] = true; slidersBuildArray[0] = true; + this.isTwelveHoursFormat = true; } if (formatArray[i].type === "minute") { slidersBuildArray[1] = true; diff --git a/packages/main/test/pages/TimePicker.html b/packages/main/test/pages/TimePicker.html index 852e5766a3c9..51d78b36c51b 100644 --- a/packages/main/test/pages/TimePicker.html +++ b/packages/main/test/pages/TimePicker.html @@ -19,6 +19,6 @@ - + From f5f0f465a6175217890930f3e33feb1f717362b2 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Tue, 11 Feb 2020 13:53:20 +0200 Subject: [PATCH 24/57] Added theme support and minor slider fixes --- .../base/src/delegate/ScrollEnablement.js | 1 - packages/main/src/Slider.hbs | 10 ++- packages/main/src/Slider.js | 57 ++++++------ packages/main/src/themes/Slider.css | 90 +++++++++---------- .../src/themes/base/Slider-parameters.css | 10 +++ .../main/src/themes/base/sizes-parameters.css | 3 + .../themes/sap_belize/Slider-parameters.css | 20 +++++ .../themes/sap_belize/parameters-bundle.css | 1 + .../sap_belize_hcb/Slider-parameters.css | 20 +++++ .../sap_belize_hcb/parameters-bundle.css | 1 + .../themes/sap_fiori_3/Slider-parameters.css | 20 +++++ .../themes/sap_fiori_3/parameters-bundle.css | 1 + .../sap_fiori_3_dark/Slider-parameters.css | 20 +++++ .../sap_fiori_3_dark/parameters-bundle.css | 1 + .../main/test/pages/Slider_Test_Page.html | 24 +++++ packages/main/test/specs/Slider.spec.js | 54 +++++++++++ packages/tools/components-package/wdio.js | 2 +- 17 files changed, 258 insertions(+), 77 deletions(-) create mode 100644 packages/main/src/themes/base/Slider-parameters.css create mode 100644 packages/main/src/themes/sap_belize/Slider-parameters.css create mode 100644 packages/main/src/themes/sap_belize_hcb/Slider-parameters.css create mode 100644 packages/main/src/themes/sap_fiori_3/Slider-parameters.css create mode 100644 packages/main/src/themes/sap_fiori_3_dark/Slider-parameters.css create mode 100644 packages/main/test/pages/Slider_Test_Page.html create mode 100644 packages/main/test/specs/Slider.spec.js diff --git a/packages/base/src/delegate/ScrollEnablement.js b/packages/base/src/delegate/ScrollEnablement.js index f2224131f3df..70d8a3f51e06 100644 --- a/packages/base/src/delegate/ScrollEnablement.js +++ b/packages/base/src/delegate/ScrollEnablement.js @@ -69,7 +69,6 @@ class ScrollEnablement extends EventProvider { container.scrollLeft += this._prevDragX - dragX; container.scrollTop += this._prevDragY - dragY; - this.fireEvent(scrollEventName, {}); this._prevDragX = dragX; diff --git a/packages/main/src/Slider.hbs b/packages/main/src/Slider.hbs index 2541d4df810b..6589efbd338f 100644 --- a/packages/main/src/Slider.hbs +++ b/packages/main/src/Slider.hbs @@ -5,10 +5,14 @@ label = "{{label}}" expanded= "{{expanded}}" @click = {{_onelementclick}} - class = "sapMWS{{isExpandedClass}}{{isDisabledClass}}"> + @keydown={{_onkeydown}} + class = "sapMWS{{isExpandedClass}}{{isDisabledClass}}" + data-sap-focus-ref + tabindex="0" + >
{{label}}
- +
@@ -28,5 +32,5 @@
{{/if}} - + \ No newline at end of file diff --git a/packages/main/src/Slider.js b/packages/main/src/Slider.js index 2f70412ac3ec..fb49f8df4b40 100644 --- a/packages/main/src/Slider.js +++ b/packages/main/src/Slider.js @@ -33,7 +33,7 @@ const metadata = { * @public */ value: { - type: String + type: String }, /** @@ -63,7 +63,7 @@ const metadata = { * @defaultvalue false * @public */ - isExpanded: { + expanded: { type: Boolean }, @@ -72,20 +72,7 @@ const metadata = { } }, slots: /** @lends sap.ui.webcomponents.main.Slider.prototype */ { - // /** - // * Defines the ui5-slider items. - // * - // * @type {HTMLElement[]} - // * @slot - // * @public - // */ - // items: { - // "default": { - // propertyName: "items", - // type: HTMLElement, - // listenFor: { include: ["*"] }, - // } - // } + }, events: /** @lends sap.ui.webcomponents.main.Slider.prototype */ { /** @@ -159,6 +146,7 @@ class Slider extends UI5Element { this._scroller = new ScrollEnablement(this); this.prevElement = 0; this._currentElementIndex = 0; + this._itemCellHeight = 0; } _findSelectedElement(){ @@ -176,11 +164,13 @@ class Slider extends UI5Element { _updateScrolling(e){ let sizeInRems = this._items.length * 3, // the size of one element in rems (16px = 1rem) - sizeOfOneElementInPixels = 48, + sizeOfOneElementInPixels = _itemCellHeight * 16, indexForOffset; const elements = this.shadowRoot.querySelectorAll(".sapMWSItem"); - //console.log(this.value + " " + this._findSelectedElement().textContent); + if (!this._findSelectedElement()){ + return; + } if (this.value === this._findSelectedElement().textContent) { return; } @@ -200,13 +190,14 @@ class Slider extends UI5Element { this._scroller.attachEvent("scroll", this._updateScrolling.bind(this)); if (this.expanded) { const elements = this.shadowRoot.querySelectorAll(".sapMWSItem"); - for (var i = 0; i < elements.length; i++){ + this._itemCellHeight = elements[0].offsetHeight / 16; + for (let i = 0; i < elements.length; i++){ if (elements[i].textContent === this.value){ this._selectElement(elements[i]); return true; } } - + this._selectElement(elements[0]); } } @@ -232,16 +223,15 @@ class Slider extends UI5Element { } _onelementclick(e) { - if(e.target.classList.contains("sapMWSItem")) { + if(e.target.classList.contains("sapMWSItem") && this.expanded) { this.value = e.target.textContent; + this._selectElement(e.target); } - if (!this.expanded) { + if (!this.expanded && e.target.classList.contains("sapMWSItem")) { this.expanded = true; this._invalidate(); } - - this._selectElement(e.target); } expandSlider(){ @@ -256,17 +246,18 @@ class Slider extends UI5Element { this.fireEvent("collapsed",{}); } - _selectElement(element){ - if (this._items.indexOf(element.textContent) > -1){ + _selectElement(element){ + if ( element && this._items.indexOf(element.textContent) > -1) { this._currentElementIndex = this._items.indexOf(element.textContent); this._selectElementByIndex(this._currentElementIndex); + this._scroller.scrollContainer.scrollTo(0,0); } } _selectElementByIndex(index){ const sliderElement = this.shadowRoot.getElementById(`${this._id}--items-list`); if ( index < this._items.length && index > - 1) { - let offsetSelectedElement = 12 - (index * 3); + let offsetSelectedElement = 4 * this._itemCellHeight - (index * this._itemCellHeight); sliderElement.setAttribute("style",`top:${offsetSelectedElement}rem`); this.value = this._items[index]; this._currentElementIndex = index; @@ -282,6 +273,18 @@ class Slider extends UI5Element { const nextElementIndex = this._currentElementIndex - 1; this._selectElementByIndex(nextElementIndex); } + + //Arrow Up 38 + //Arrow Down 40 + _onkeydown(event){ + if (event.keyCode === 38) { + this._onArrowUp(); + } + + if (event.keyCode === 40) { + this._onArrowDown(); + } + } } Slider.define(); diff --git a/packages/main/src/themes/Slider.css b/packages/main/src/themes/Slider.css index af597d846850..82ad3db2c067 100644 --- a/packages/main/src/themes/Slider.css +++ b/packages/main/src/themes/Slider.css @@ -5,31 +5,31 @@ vertical-align: middle; text-align: center; box-sizing: border-box; - cursor: pointer; + font-family: "72","72full",Arial,Helvetica,sans-serif; } .sapMWS .sapMWSLabel { box-sizing: border-box; - height: 2rem; - line-height: 2rem; - width: 4.5rem; - text-align: center; - font-size: 20px; - color: gray; - text-align: center; - vertical-align: middle; + height: 2rem; + line-height: 2rem; + width: var(--_ui5_slider_item_width); + font-size: var(--_ui5_slider_label_text_size); + color: var(--_ui5_slider_label_text_color); + text-align: center; + vertical-align: middle; } .sapMWS .sapMWSArrows { - display: none; + visibility: hidden; box-sizing: border-box; + height: 1.5rem; } .sapMWS.sapMWSExpanded .sapMWSArrows { - display: block; + visibility: visible; box-sizing: border-box; width: 100%; border-color: transparent; - height: 1.5rem; + cursor: pointer; } .sapMWS .sapMWSInner { @@ -41,7 +41,7 @@ -ms-user-select: none; user-select: none; list-style: none; - margin-top: 4.5rem; + margin-top: 0rem; } .sapMWS.sapMWSExpanded .sapMWSInner { @@ -49,35 +49,31 @@ } .sapMWS .sapMWSInner .sapMWSItem { - height: 3rem; - line-height: 3rem; - width: 4.5rem; + height: var(--_ui5_slider_item_height); + line-height: var(--_ui5_slider_item_height); + width: var(--_ui5_slider_item_width); box-sizing: border-box; - background: darkblue; - border: 1px solid white; - font-size: 15px; - color: lightgray; + background: var(--_ui5_slider_selected_item_background_color); + border: 0.625px solid var(--_ui5_slider_item_border_color); + font-size: var(--_ui5_slider_item_text_size); + color: var(--_ui5_slider_collapsed_item_text_color); text-align: center; - border-radius: 5px; + border-radius: var(--_ui_slider_item_border_radius); } .sapMWS .sapMWSInner .sapMWSItem:hover { - background: orange; - color: red; -} -.sapMWS .sapMWSInner .sapMWSItem:active { - background: yellow; - color: pink; + background: var(--_ui5_slider_selected_item_hover_background_color); } + .sapMWS .sapMWSInner .sapMWSItem:focus { outline: 1px dotted black; outline-offset: -3px; } .sapMWS .sapMWSInner .sapMWSSelectionFrame { - width: 4.5rem; - height: 3rem; + width: var(--_ui5_slider_item_width); + height: var(--_ui5_slider_item_height); position: absolute; box-sizing: border-box; - display: none; + visibility: hidden; z-index: 1; } .sapMWS .sapMWSInner .sapMWrapper > ul { @@ -85,7 +81,8 @@ margin: 0; padding: 0; position: absolute; - top: 9rem; + top: var(--_ui5_slider_selection_frame_margin_top); + cursor: pointer; } .sapMWS.sapMWSExpanded .sapMWSInner .sapMWrapper > ul { @@ -101,7 +98,6 @@ height: 100%; cursor: default; margin: 0; - margin-top: -1.5rem; } .sapMWS.sapMWSExpanded .sapMWSLabel { @@ -114,20 +110,20 @@ } .sapMWS.sapMWSExpanded .sapMWSInner .sapMWSItem { - background:lightgray; - color: black; - border: 1px solid white; - border-radius: 5px; + background: var(--_ui5_slider_item_background_color); + color: var(--_ui5_slider_item_text_color); + border: 1px solid var(--_ui5_slider_item_border_color); + border-radius: var(--_ui_slider_item_border_radius); offset-position: auto; } .sapMWS.sapMWSExpanded .sapMWSInner .sapMWSItem:hover { - background: rgba(211,211,211,0.5); + background: var(--_ui_slider_item_hover_color); } .sapMWS.sapMWSExpanded .sapMWSInner .sapMWSItem:active { - background: darkblue; - color: lightgray; + background: var(--_ui5_slider_selected_item_background_color); + color: var(--_ui5_slider_item_background_color); } .sapMWS.sapMWSExpanded .sapMWSInner .sapMWSItem:focus { @@ -136,17 +132,21 @@ } .sapMWS.sapMWSExpanded .sapMWSInner .sapMWSSelectionFrame { - display: block; - outline: 0.125rem solid darkblue; - outline-offset: -0.313rem; - top: 47.9%;; + visibility: visible; + /* box-shadow: 0.125rem solid var(--_ui5_slider_selected_item_background_color); */ + /* outline-offset: -0.2rem; */ + -webkit-box-shadow: inset 0px 0px 0px 2px var(--_ui5_slider_selection_frame_color); + -moz-box-shadow: inset 0px 0px 0px 2px var(--_ui5_slider_selection_frame_color); + box-shadow: inset 0px 0px 0px 2px var(--_ui5_slider_selection_frame_color); + border-radius: var(--_ui_slider_item_border_radius); + margin-top: var(--_ui5_slider_selection_frame_margin_top); } .sapMWS.sapMWSExpanded .sapMWSInner .sapMWSSelectionFrame:hover + ul > li.sapMWSItem.sapMWSItemSelected { - background: darkblue; + background: var(--_ui5_slider_selected_item_background_color); } .sapMWS.sapMWSExpanded .sapMWSInner .sapMWSSelectionFrame:active + ul > li.sapMWSItem.sapMWSItemSelected { - background: darkblue; + background: var(--_ui5_slider_selected_item_background_color); color: lightgray; } .sapMWS:focus { diff --git a/packages/main/src/themes/base/Slider-parameters.css b/packages/main/src/themes/base/Slider-parameters.css new file mode 100644 index 000000000000..458fa5e6a3f6 --- /dev/null +++ b/packages/main/src/themes/base/Slider-parameters.css @@ -0,0 +1,10 @@ +:root{ + --_ui5_slider_item_background_color: #f2f2f2; + --_ui5_slider_item_text_color: #fff; + --_ui5_slider_active_item_text_color: #29313a; + --_ui5_slider_item_text_size: .875rem; + --_ui5_slider_label_text_size: .75rem; + --_ui5_slider_label_text_color: #666; + --_ui5_slider_item_width: 4.5rem; + --_ui5_slider_item_height: 3rem; +} \ No newline at end of file diff --git a/packages/main/src/themes/base/sizes-parameters.css b/packages/main/src/themes/base/sizes-parameters.css index 05305990c938..a54708f1d2e8 100644 --- a/packages/main/src/themes/base/sizes-parameters.css +++ b/packages/main/src/themes/base/sizes-parameters.css @@ -131,6 +131,9 @@ --_ui5_rb_label_width: calc(100% - 2rem + 1px); --_ui5_rb_rtl_focus_right: 0.375rem; + --_ui5_slider_item_width: 4rem; + --_ui5_slider_item_height: 2rem; + --_ui5_switch_height: var(--_ui5_switch_compact_height); --_ui5_switch_width: var(--_ui5_switch_compact_width); --_ui5_switch_handle_height: var(--_ui5_switch_handle_compact_height); diff --git a/packages/main/src/themes/sap_belize/Slider-parameters.css b/packages/main/src/themes/sap_belize/Slider-parameters.css new file mode 100644 index 000000000000..b032e5121f83 --- /dev/null +++ b/packages/main/src/themes/sap_belize/Slider-parameters.css @@ -0,0 +1,20 @@ +@import "../base/Slider-parameters.css"; + +:root{ + --_ui5_slider_item_background_color: #f7f7f7; + --_ui5_slider_item_text_color: #32363а; + --_ui_slider_item_hover_color: #f0f0f0; + --_ui5_slider_item_border_color: #fff; + --_ui5_slider_collapsed_item_text_color: var(--_ui5_slider_item_border_color); + --_ui5_slider_active_item_text_color: #29313a; + --_ui5_slider_item_text_size: .875rem; + --_ui5_slider_label_text_size: .75rem; + --_ui5_slider_label_text_color: #666; + --_ui5_slider_selected_item_background_color: #427cac; + --_ui5_slider_selected_item_hover_background_color: #244866; + --_ui5_slider_item_width: 4.5rem; + --_ui5_slider_item_height: 3rem; + --_ui5_slider_selection_frame_margin_top: calc(var(--_ui5_slider_item_height) * 4); + --_ui5_slider_selection_frame_color: var(--_ui5_slider_selected_item_background_color); + --_ui_slider_item_border_radius: 0; +} \ No newline at end of file diff --git a/packages/main/src/themes/sap_belize/parameters-bundle.css b/packages/main/src/themes/sap_belize/parameters-bundle.css index 82bd384cc09b..fc9f0965a184 100644 --- a/packages/main/src/themes/sap_belize/parameters-bundle.css +++ b/packages/main/src/themes/sap_belize/parameters-bundle.css @@ -19,6 +19,7 @@ @import "../base/Popover-parameters.css"; @import "../base/RadioButton-parameters.css"; @import "../base/Select-parameters.css"; +@import "./Slider-parameters.css"; @import "../base/Switch-parameters.css"; @import "./TabContainer-parameters.css"; @import "../base/Table-parameters.css"; diff --git a/packages/main/src/themes/sap_belize_hcb/Slider-parameters.css b/packages/main/src/themes/sap_belize_hcb/Slider-parameters.css new file mode 100644 index 000000000000..8a3e60c0010c --- /dev/null +++ b/packages/main/src/themes/sap_belize_hcb/Slider-parameters.css @@ -0,0 +1,20 @@ +@import "../base/Slider-parameters.css"; + +:root{ + --_ui5_slider_item_background_color: #000; + --_ui5_slider_item_text_color: #fff; + --_ui_slider_item_hover_color: #7a5100; + --_ui5_slider_active_item_text_color: #29313a; + --_ui5_slider_collapsed_item_text_color: var(--_ui5_slider_item_text_color); + --_ui5_slider_item_border_color: #999; + --_ui5_slider_item_text_size: .875rem; + --_ui5_slider_label_text_size: .75rem; + --_ui5_slider_label_text_color: #666; + --_ui5_slider_selected_item_background_color: #0f5d94; + --_ui5_slider_selected_item_hover_background_color: #7a5100; + --_ui5_slider_item_width: 4.5rem; + --_ui5_slider_item_height: 3rem; + --_ui5_slider_selection_frame_margin_top: calc(var(--_ui5_slider_item_height) * 4); + --_ui5_slider_selection_frame_color: var(--_ui5_slider_item_text_color); + --_ui_slider_item_border_radius: 0; +} \ No newline at end of file diff --git a/packages/main/src/themes/sap_belize_hcb/parameters-bundle.css b/packages/main/src/themes/sap_belize_hcb/parameters-bundle.css index 3876850b2bfb..68c0f8f46ec2 100644 --- a/packages/main/src/themes/sap_belize_hcb/parameters-bundle.css +++ b/packages/main/src/themes/sap_belize_hcb/parameters-bundle.css @@ -19,6 +19,7 @@ @import "./Popover-parameters.css"; @import "./RadioButton-parameters.css"; @import "./Select-parameters.css"; +@import "./Slider-parameters.css"; @import "./Switch-parameters.css"; @import "./TabContainer-parameters.css"; @import "./Table-parameters.css"; diff --git a/packages/main/src/themes/sap_fiori_3/Slider-parameters.css b/packages/main/src/themes/sap_fiori_3/Slider-parameters.css new file mode 100644 index 000000000000..69b06ace7c46 --- /dev/null +++ b/packages/main/src/themes/sap_fiori_3/Slider-parameters.css @@ -0,0 +1,20 @@ +@import "../base/Slider-parameters.css"; + +:root{ + --_ui5_slider_item_background_color: #f7f7f7; + --_ui5_slider_item_text_color: #32363а; + --_ui_slider_item_hover_color: #f0f0f0; + --_ui5_slider_item_border_color: #fff; + --_ui5_slider_collapsed_item_text_color: var(--_ui5_slider_item_border_color); + --_ui5_slider_active_item_text_color: #29313a; + --_ui5_slider_item_text_size: .875rem; + --_ui5_slider_label_text_size: .75rem; + --_ui5_slider_label_text_color: #666; + --_ui5_slider_selected_item_background_color: #0854a0; + --_ui5_slider_selected_item_hover_background_color: #053b70; + --_ui5_slider_item_width: 3rem; + --_ui5_slider_item_height: 2.875rem; + --_ui5_slider_selection_frame_margin_top: calc(var(--_ui5_slider_item_height) * 4); + --_ui5_slider_selection_frame_color: var(--_ui5_slider_selected_item_background_color); + --_ui_slider_item_border_radius: 5px; +} \ No newline at end of file diff --git a/packages/main/src/themes/sap_fiori_3/parameters-bundle.css b/packages/main/src/themes/sap_fiori_3/parameters-bundle.css index 375c07640555..f0224311d018 100644 --- a/packages/main/src/themes/sap_fiori_3/parameters-bundle.css +++ b/packages/main/src/themes/sap_fiori_3/parameters-bundle.css @@ -18,6 +18,7 @@ @import "../base/Popover-parameters.css"; @import "../base/RadioButton-parameters.css"; @import "../base/Select-parameters.css"; +@import "./Slider-parameters.css"; @import "../base/Switch-parameters.css"; @import "./TabContainer-parameters.css"; @import "../base/TextArea-parameters.css"; diff --git a/packages/main/src/themes/sap_fiori_3_dark/Slider-parameters.css b/packages/main/src/themes/sap_fiori_3_dark/Slider-parameters.css new file mode 100644 index 000000000000..632432e96ddc --- /dev/null +++ b/packages/main/src/themes/sap_fiori_3_dark/Slider-parameters.css @@ -0,0 +1,20 @@ +@import "../base/Slider-parameters.css"; + +:root{ + --_ui5_slider_item_background_color: #2f3943; + --_ui5_slider_item_text_color: #fff; + --_ui_slider_item_hover_color: #36404c; + --_ui5_slider_item_border_color: #29313a; + --_ui5_slider_collapsed_item_text_color: var(--_ui5_slider_item_border_color); + --_ui5_slider_active_item_text_color: #29313a; + --_ui5_slider_item_text_size: .875rem; + --_ui5_slider_label_text_size: .75rem; + --_ui5_slider_label_text_color: #666; + --_ui5_slider_selected_item_background_color: #91c8f6; + --_ui5_slider_selected_item_hover_background_color: #62b0f2; + --_ui5_slider_item_width: 3rem; + --_ui5_slider_item_height: 2.875rem; + --_ui5_slider_selection_frame_margin_top: calc(var(--_ui5_slider_item_height) * 4); + --_ui5_slider_selection_frame_color: var(--_ui5_slider_selected_item_background_color); + --_ui_slider_item_border_radius: 5px; +} \ No newline at end of file diff --git a/packages/main/src/themes/sap_fiori_3_dark/parameters-bundle.css b/packages/main/src/themes/sap_fiori_3_dark/parameters-bundle.css index 31f69d81bbe3..9c7a128441d1 100644 --- a/packages/main/src/themes/sap_fiori_3_dark/parameters-bundle.css +++ b/packages/main/src/themes/sap_fiori_3_dark/parameters-bundle.css @@ -18,6 +18,7 @@ @import "../base/Popover-parameters.css"; @import "../base/RadioButton-parameters.css"; @import "../base/Select-parameters.css"; +@import "./Slider-parameters.css"; @import "../base/Switch-parameters.css"; @import "./TabContainer-parameters.css"; @import "../base/TextArea-parameters.css"; diff --git a/packages/main/test/pages/Slider_Test_Page.html b/packages/main/test/pages/Slider_Test_Page.html new file mode 100644 index 000000000000..05a500119a4d --- /dev/null +++ b/packages/main/test/pages/Slider_Test_Page.html @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/packages/main/test/specs/Slider.spec.js b/packages/main/test/specs/Slider.spec.js new file mode 100644 index 000000000000..b22d15030084 --- /dev/null +++ b/packages/main/test/specs/Slider.spec.js @@ -0,0 +1,54 @@ +const assert = require("chai").assert; + +describe("Button general interaction", () => { + browser.url("http://localhost:8080/test-resources/pages/Slider_Test_Page.html"); + + it("tests slider's label rendering", () => { + const textValue = browser.$("#slider").shadow$$(".sapMWSLabel")[0].getText(); + + assert.strictEqual(textValue, "Test", "Slider text is rendered"); + }); + + it("Arrow down button is working", () => { + const slider = browser.$("#slider"); + console.log(slider); + const button = slider.shadow$$(".sapMWSArrows")[1]; + button.click(); + + assert.strictEqual(slider.getValue(), "2", "Slider button arrow down is working"); + }); + + it("Arrow up button is working", () => { + const slider = browser.$("#slider"); + const button = slider.shadow$$(".sapMWSArrows")[0]; + + button.click(); + + assert.strictEqual(slider.getValue(), "1", "Slider button arrow up is working"); + }); + + it("Keyboard arrow down is working", () => { + const slider = browser.$("#slider"); + + slider.keys("ArrowDown"); + + assert.strictEqual(slider.getValue(), "2", "Slider keyboard handling for arrow down is working"); + }); + + it("Keyboard Arrow up is working", () => { + const slider = browser.$("#slider"); + + slider.keys("ArrowUp"); + + assert.strictEqual(slider.getValue(), "1", "Slider keyboard handling for arrow up is working"); + }); + + it("Click on element selects element", () => { + const slider = browser.$("#slider"); + const sliderElements = slider.shadow$$(".sapMWSItem"); + + sliderElements[5].click(); + + assert.strictEqual(slider.getValue(), "6", "Slider pick elements with click works"); + }); +}); \ No newline at end of file diff --git a/packages/tools/components-package/wdio.js b/packages/tools/components-package/wdio.js index c5f595e55c11..05cd3abb4c4a 100644 --- a/packages/tools/components-package/wdio.js +++ b/packages/tools/components-package/wdio.js @@ -57,7 +57,7 @@ exports.config = { // to run chrome headless the following flags are required // (see https://developers.google.com/web/updates/2017/04/headless-chrome) args: ['--headless', '--disable-gpu'], - //args: ['--disable-gpu'], + // args: ['--disable-gpu'], } }], // From f27f4940683292311ec1310965b34fc2399f2bfb Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Thu, 13 Feb 2020 17:26:58 +0200 Subject: [PATCH 25/57] Code cleaning, theming separation, colors using vars --- packages/main/src/Slider.hbs | 40 +++---- packages/main/src/Slider.js | 112 +++++++++--------- packages/main/src/TimePicker.hbs | 27 +++-- packages/main/src/TimePicker.js | 65 +++++----- packages/main/src/themes/Slider.css | 62 +++++----- .../src/themes/base/Slider-parameters.css | 8 +- .../themes/sap_belize/Slider-parameters.css | 20 ++-- .../sap_belize_hcb/Slider-parameters.css | 24 ++-- .../themes/sap_fiori_3/Slider-parameters.css | 22 ++-- .../sap_fiori_3_dark/Slider-parameters.css | 22 ++-- packages/main/test/specs/Slider.spec.js | 8 +- .../sap_belize/base-parameters-vars.less | 7 +- .../themes/sap_belize/base-parameters.less | 8 +- .../sap_fiori_3/base-parameters-vars.less | 6 +- .../themes/sap_fiori_3/base-parameters.less | 10 +- .../base-parameters-vars.less | 6 +- .../sap_fiori_3_dark/base-parameters.less | 8 +- packages/tools/components-package/wdio.js | 2 +- 18 files changed, 240 insertions(+), 217 deletions(-) diff --git a/packages/main/src/Slider.hbs b/packages/main/src/Slider.hbs index 6589efbd338f..e8a71bc34b35 100644 --- a/packages/main/src/Slider.hbs +++ b/packages/main/src/Slider.hbs @@ -3,34 +3,32 @@ ?disabled= "{{disabled}}" value = "{{value}}" label = "{{label}}" - expanded= "{{expanded}}" - @click = {{_onelementclick}} + ?expanded= "{{_expanded}}" + @click = {{_onclick}} @keydown={{_onkeydown}} - class = "sapMWS{{isExpandedClass}}{{isDisabledClass}}" + class = "ui5-slider" data-sap-focus-ref tabindex="0" - > -
{{label}}
-
- -
-
+> +
{{label}}
+
+ +
+
- {{#if expanded}} -
-
    +
    + {{#if _expanded}} +
      {{#each items}} -
    • {{this}}
    • +
    • {{this}}
    • {{/each}}
    -
    - {{else}} -
    -
      -
    • {{value}}
    • + {{else}} +
        +
      • {{value}}
      -
    - {{/if}} + {{/if}} +
- +
\ No newline at end of file diff --git a/packages/main/src/Slider.js b/packages/main/src/Slider.js index fb49f8df4b40..fe99627634d8 100644 --- a/packages/main/src/Slider.js +++ b/packages/main/src/Slider.js @@ -1,6 +1,10 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import SliderTemplate from "./generated/templates/SliderTemplate.lit.js"; +import { + isDown, + isUp, +} from "../../base/src/events/PseudoEvents"; // Styles import SliderCss from "./generated/themes/Slider.css.js"; @@ -42,7 +46,7 @@ const metadata = { * @defaultvalue false * @public */ - isCyclic: { + cyclic: { type: Boolean }, @@ -61,9 +65,9 @@ const metadata = { * Indicates if the slider is expanded. * @type {boolean} * @defaultvalue false - * @public + * @private */ - expanded: { + _expanded: { type: Boolean }, @@ -78,12 +82,12 @@ const metadata = { /** * Fires when the slider is expanded. */ - expanded: {}, + expand: {}, /** * Fires when the slider is collapsed. */ - collapsed: {}, + collapse: {}, /** * Fires when new value is selected. @@ -118,7 +122,7 @@ const metadata = { */ class Slider extends UI5Element { static get metadata() { - return metadata; + return metadata; } static get render() { @@ -139,20 +143,20 @@ class Slider extends UI5Element { constructor() { super(); - - this._items = ["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"]; - this.value = this._items[0]; //this.i18nBundle = getI18nBundle("@ui5/webcomponents"); - this._scroller = new ScrollEnablement(this); - this.prevElement = 0; + // this._scroller = new ScrollEnablement(this); this._currentElementIndex = 0; this._itemCellHeight = 0; } + onBeforeRendering(){ + this._itemCellHeight = this.shadowRoot.querySelectorAll(".ui5-slider-item").length && this.shadowRoot.querySelectorAll(".ui5-slider-item")[0].offsetHeight / 16; + } + _findSelectedElement(){ let itemsList = this.shadowRoot.querySelector(`#${this._id}--items-list`), parentOffset = itemsList.parentElement.parentElement.offsetTop, - itemsListArray = [].slice.call(itemsList.children), + itemsListArray = [...itemsList.children], firstVisibleElementIndex = 0; while ((itemsListArray[firstVisibleElementIndex].getBoundingClientRect().y - parentOffset) < 0){ @@ -166,12 +170,13 @@ class Slider extends UI5Element { let sizeInRems = this._items.length * 3, // the size of one element in rems (16px = 1rem) sizeOfOneElementInPixels = _itemCellHeight * 16, indexForOffset; - const elements = this.shadowRoot.querySelectorAll(".sapMWSItem"); + const elements = this.shadowRoot.querySelectorAll(".ui5-slider-item"), + selectedElement = this._findSelectedElement(); - if (!this._findSelectedElement()){ + if (!selectedElement){ return; } - if (this.value === this._findSelectedElement().textContent) { + if (this.value === selectedElement.textContent) { return; } @@ -181,16 +186,33 @@ class Slider extends UI5Element { indexForOffset = Math.floor(e.scroll / sizeOfOneElementInPixels); } - this._selectElement(this._findSelectedElement()); - this.value = this._findSelectedElement().textContent; + this._selectElement(selectedElement); + this.value = selectedElement.textContent; } onAfterRendering() { - this._scroller.scrollContainer = this.shadowRoot.querySelector(`#${this._id}--wrapper`); - this._scroller.attachEvent("scroll", this._updateScrolling.bind(this)); - if (this.expanded) { - const elements = this.shadowRoot.querySelectorAll(".sapMWSItem"); - this._itemCellHeight = elements[0].offsetHeight / 16; + // this._scroller.scrollContainer = this.shadowRoot.querySelector(`#${this._id}--wrapper`); + // this._scroller.attachEvent("scroll", this._updateScrolling.bind(this)); + + this.shadowRoot.querySelector(".ui5-slider-wrapper > ul").addEventListener("wheel", (e) => { + e.stopPropagation(); + e.preventDefault(); + + if (e.timeStamp === this._prevWheelTimestamp){ + return; + } + + if (e.deltaY > 0){ + this._onArrowUp(); + } else if (e.deltaY < 0) { + this._onArrowDown(); + } + + this._prevWheelTimestamp = e.timeStamp; + }); + + if (this._expanded) { + const elements = this.shadowRoot.querySelectorAll(".ui5-slider-item"); for (let i = 0; i < elements.length; i++){ if (elements[i].textContent === this.value){ this._selectElement(elements[i]); @@ -206,51 +228,33 @@ class Slider extends UI5Element { return this._items; } - get isExpandedClass(){ - if (this.expanded){ - return " sapMWSExpanded"; - } - - return ""; - } - - get isDisabledClass(){ - if (this.disabled){ - return " sapMWSDisabled"; + _onclick(e) { + if (!e.target.classList.contains("ui5-slider-item")){ + return; } - return ""; - } - - _onelementclick(e) { - if(e.target.classList.contains("sapMWSItem") && this.expanded) { + if(this._expanded) { this.value = e.target.textContent; this._selectElement(e.target); - } - - if (!this.expanded && e.target.classList.contains("sapMWSItem")) { - this.expanded = true; - this._invalidate(); + } else { + this._expanded = true; } } expandSlider(){ - this.expanded = true; - this._invalidate(); - this.fireEvent("expanded",{}); + this._expanded = true; + this.fireEvent("expand",{}); } collapseSlider(){ - this.expanded = false; - this._invalidate(); - this.fireEvent("collapsed",{}); + this._expanded = false; + this.fireEvent("collapse",{}); } _selectElement(element){ - if ( element && this._items.indexOf(element.textContent) > -1) { + if (element && this._items.indexOf(element.textContent) > -1) { this._currentElementIndex = this._items.indexOf(element.textContent); this._selectElementByIndex(this._currentElementIndex); - this._scroller.scrollContainer.scrollTo(0,0); } } @@ -274,14 +278,12 @@ class Slider extends UI5Element { this._selectElementByIndex(nextElementIndex); } - //Arrow Up 38 - //Arrow Down 40 _onkeydown(event){ - if (event.keyCode === 38) { + if (isUp(event)) { this._onArrowUp(); } - if (event.keyCode === 40) { + if (isDown(event)) { this._onArrowDown(); } } diff --git a/packages/main/src/TimePicker.hbs b/packages/main/src/TimePicker.hbs index 07f4f0b73285..0ea915a64e32 100644 --- a/packages/main/src/TimePicker.hbs +++ b/packages/main/src/TimePicker.hbs @@ -29,38 +29,39 @@ @ui5-afterOpen="{{_popover.afterOpen}}" header-text="Pick Time" class="sapMTimePickerPopover" - > + > {{#if shouldBuildHoursSlider}} - + @click="{{handleSliderClicked}}" + class="ui5-timepicker-hours-slider" + > {{/if}} {{#if shouldBuildMinutesSlider}} - + @click="{{handleSliderClicked}}" + class="ui5-timepicker-minutes-slider" + > {{/if}} {{#if shouldBuildSecondsSlider}} - + @click="{{handleSliderClicked}}" + class="ui5-timepicker-seconds-slider" + > {{/if}} {{#if shouldBuildPeriodsSlider}} - + @click="{{handleSliderClicked}}" + class="ui5-timepicker-period-slider" + > {{/if}}
Submit diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index 48d06dd71a58..e020f3bf459c 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -206,6 +206,12 @@ class TimePicker extends UI5Element { }; } + onBeforeRendering() { + if (!this.value) { + this.value = this.getFormat().format(new Date()); + } + } + onAfterRendering() { let sliders = this._getPopover().default.filter(x => x.isUI5Element), slidersEnablementArray = this._getSlidersContained(this.formatPattern); @@ -240,19 +246,27 @@ class TimePicker extends UI5Element { setSlidersValue() { let currentDate = this._getInput ? this.getFormat().parse(this._getInput().value) : null, - sliders = this._getPopover().default.filter(x => x.isUI5Element); + secondsSlider = this.shadowRoot.querySelector(".ui5-timepicker-seconds-slider"), + minutesSlider = this.shadowRoot.querySelector(".ui5-timepicker-minutes-slider"), + hoursSlider = this.shadowRoot.querySelector(".ui5-timepicker-hours-slider"), + periodsSlider = this.shadowRoot.querySelector(".ui5-timepicker-periods-slider"); if (currentDate) { - for (let i = 0; i < sliders.length; i++) { - if (sliders[i].label === "Hours") { - sliders[i].value = currentDate.getHours(); - } else if (sliders[i].label === "Minutes") { - sliders[i].value = currentDate.getMinutes(); - } else if (sliders[i].label === "Seconds") { - sliders[i].value = currentDate.getSeconds(); - } else if (this.isTwelveHoursFormat && sliders[i].label === "AM/PM") { - sliders[i].value = currentDate.getHours() > 11 ? "PM" : "AM"; - } + if (hoursSlider){ + if (this.isTwelveHoursFormat && currentDate.getHours() > 11){ + hoursSlider.value = currentDate.getHours() - 12; + } else { + hoursSlider.value = currentDate.getHours(); + } + } + if (minutesSlider) { + minutesSlider.value = currentDate.getMinutes(); + } + if (secondsSlider) { + secondsSlider.value = currentDate.getSeconds(); + } + if (this.isTwelveHoursFormat && periodsSlider) { + periodsSlider.value = currentDate.getHours() > 11 ? "PM" : "AM"; } } } @@ -328,24 +342,15 @@ class TimePicker extends UI5Element { } submitPickers() { - let sliders = this._getPopover().default.filter(x => x.isUI5Element), - selectedDate = new Date(), - hours = "0", - minutes = "0", - seconds = "0", - period = "AM"; - - for (let i = 0; i < sliders.length; i++) { - if (sliders[i].label === "Hours") { - hours = sliders[i].value; - } else if (sliders[i].label === "Minutes") { - minutes = sliders[i].value; - } else if (sliders[i].label === "Seconds") { - seconds = sliders[i].value; - } else if (sliders[i].label === "AM/PM"){ - period = sliders[i].value; - } - } + let selectedDate = new Date(), + secondsSlider = this.shadowRoot.querySelector(".ui5-timepicker-seconds-slider"), + minutesSlider = this.shadowRoot.querySelector(".ui5-timepicker-minutes-slider"), + hoursSlider = this.shadowRoot.querySelector(".ui5-timepicker-hours-slider"), + periodsSlider = this.shadowRoot.querySelector(".ui5-timepicker-periods-slider"), + hours = hoursSlider ? hoursSlider.value : "0", + minutes = minutesSlider ? minutesSlider.value : "0", + seconds = secondsSlider ? secondsSlider.value : "0", + period = periodsSlider ? periodsSlider.value : "AM"; if (period === "PM") { selectedDate.setHours(hours*1 + 12); @@ -393,7 +398,7 @@ class TimePicker extends UI5Element { handleSliderClicked(event) { let sliders = this._getPopover().default.filter(x => x.isUI5Element); - if (event.target.expanded) { + if (event.target._expanded) { for (var i = 0; i < sliders.length; i++) { if (sliders[i].label !== event.target.label) { sliders[i].collapseSlider(); diff --git a/packages/main/src/themes/Slider.css b/packages/main/src/themes/Slider.css index 82ad3db2c067..55d606f2c0b8 100644 --- a/packages/main/src/themes/Slider.css +++ b/packages/main/src/themes/Slider.css @@ -1,13 +1,13 @@ -.sapMWS { +.ui5-slider { display: inline-block; overflow: hidden; height: 100%; vertical-align: middle; text-align: center; box-sizing: border-box; - font-family: "72","72full",Arial,Helvetica,sans-serif; + font-family: var(--sapFontFamily); } -.sapMWS .sapMWSLabel { +.ui5-slider .ui5-slider-label { box-sizing: border-box; height: 2rem; line-height: 2rem; @@ -18,13 +18,13 @@ vertical-align: middle; } -.sapMWS .sapMWSArrows { +.ui5-slider .ui5-slider-arrow { visibility: hidden; box-sizing: border-box; height: 1.5rem; } -.sapMWS.sapMWSExpanded .sapMWSArrows { +.ui5-slider[expanded] .ui5-slider-arrow { visibility: visible; box-sizing: border-box; width: 100%; @@ -32,7 +32,7 @@ cursor: pointer; } -.sapMWS .sapMWSInner { +.ui5-slider .ui5-slider-inner { overflow: hidden; height: 100%; box-sizing: border-box; @@ -44,11 +44,11 @@ margin-top: 0rem; } -.sapMWS.sapMWSExpanded .sapMWSInner { +.ui5-slider[expanded] .ui5-slider-inner { margin-top: 0; } -.sapMWS .sapMWSInner .sapMWSItem { +.ui5-slider .ui5-slider-inner .ui5-slider-item { height: var(--_ui5_slider_item_height); line-height: var(--_ui5_slider_item_height); width: var(--_ui5_slider_item_width); @@ -59,16 +59,17 @@ color: var(--_ui5_slider_collapsed_item_text_color); text-align: center; border-radius: var(--_ui_slider_item_border_radius); + cursor: pointer; } -.sapMWS .sapMWSInner .sapMWSItem:hover { +.ui5-slider .ui5-slider-inner .ui5-slider-item:hover { background: var(--_ui5_slider_selected_item_hover_background_color); } -.sapMWS .sapMWSInner .sapMWSItem:focus { +.ui5-slider .ui5-slider-inner .ui5-slider-item:focus { outline: 1px dotted black; outline-offset: -3px; } -.sapMWS .sapMWSInner .sapMWSSelectionFrame { +.ui5-slider .ui5-slider-inner .ui5-slider-selection-frame { width: var(--_ui5_slider_item_width); height: var(--_ui5_slider_item_height); position: absolute; @@ -76,65 +77,68 @@ visibility: hidden; z-index: 1; } -.sapMWS .sapMWSInner .sapMWrapper > ul { +.ui5-slider .ui5-slider-inner .ui5-slider-wrapper > ul { transition: all 400ms; margin: 0; padding: 0; position: absolute; top: var(--_ui5_slider_selection_frame_margin_top); cursor: pointer; + list-style-type: none; } -.sapMWS.sapMWSExpanded .sapMWSInner .sapMWrapper > ul { +.ui5-slider[expanded] .ui5-slider-inner .ui5-slider-wrapper > ul { + list-style-type: none; top: 0; } -.sapMWS .sapMWSInner .sapMWrapper { +.ui5-slider .ui5-slider-inner .ui5-slider-wrapper { height: 27rem; position: relative; + overflow: hidden; + outline: none; } -.sapMWS.sapMWSExpanded { +.ui5-slider[expanded] { height: 100%; cursor: default; margin: 0; } -.sapMWS.sapMWSExpanded .sapMWSLabel { +.ui5-slider[expanded] .ui5-slider-label { display: block; } -.sapMWS .sapMWSInner { +.ui5-slider .ui5-slider-inner { max-height: 100%; height: 27rem; } -.sapMWS.sapMWSExpanded .sapMWSInner .sapMWSItem { +.ui5-slider[expanded] .ui5-slider-inner .ui5-slider-item { background: var(--_ui5_slider_item_background_color); color: var(--_ui5_slider_item_text_color); border: 1px solid var(--_ui5_slider_item_border_color); border-radius: var(--_ui_slider_item_border_radius); offset-position: auto; + cursor: pointer; } -.sapMWS.sapMWSExpanded .sapMWSInner .sapMWSItem:hover { +.ui5-slider[expanded] .ui5-slider-inner .ui5-slider-item:hover { background: var(--_ui_slider_item_hover_color); } -.sapMWS.sapMWSExpanded .sapMWSInner .sapMWSItem:active { - background: var(--_ui5_slider_selected_item_background_color); - color: var(--_ui5_slider_item_background_color); +.ui5-slider[expanded] .ui5-slider-inner .ui5-slider-item:active { + background: var(--_ui5_slider_active_item_background_color); + color: var(--_ui5_slider_active_item_text_color); } -.sapMWS.sapMWSExpanded .sapMWSInner .sapMWSItem:focus { +.ui5-slider[expanded] .ui5-slider-inner .ui5-slider-item:focus { outline: 1px dotted black; outline-offset: -3px; } -.sapMWS.sapMWSExpanded .sapMWSInner .sapMWSSelectionFrame { +.ui5-slider[expanded] .ui5-slider-inner .ui5-slider-selection-frame { visibility: visible; - /* box-shadow: 0.125rem solid var(--_ui5_slider_selected_item_background_color); */ - /* outline-offset: -0.2rem; */ -webkit-box-shadow: inset 0px 0px 0px 2px var(--_ui5_slider_selection_frame_color); -moz-box-shadow: inset 0px 0px 0px 2px var(--_ui5_slider_selection_frame_color); box-shadow: inset 0px 0px 0px 2px var(--_ui5_slider_selection_frame_color); @@ -142,13 +146,13 @@ margin-top: var(--_ui5_slider_selection_frame_margin_top); } -.sapMWS.sapMWSExpanded .sapMWSInner .sapMWSSelectionFrame:hover + ul > li.sapMWSItem.sapMWSItemSelected { +.ui5-slider[expanded] .ui5-slider-inner .ui5-slider-selection-frame:hover + ul > li.ui5-slider-item.ui5-slider-itemSelected { background: var(--_ui5_slider_selected_item_background_color); } -.sapMWS.sapMWSExpanded .sapMWSInner .sapMWSSelectionFrame:active + ul > li.sapMWSItem.sapMWSItemSelected { +.ui5-slider[expanded] .ui5-slider-inner .ui5-slider-selection-frame:active + ul > li.ui5-slider-item.ui5-slider-itemSelected { background: var(--_ui5_slider_selected_item_background_color); color: lightgray; } -.sapMWS:focus { +.ui5-slider:focus { outline: none; } \ No newline at end of file diff --git a/packages/main/src/themes/base/Slider-parameters.css b/packages/main/src/themes/base/Slider-parameters.css index 458fa5e6a3f6..7e01ce2878bd 100644 --- a/packages/main/src/themes/base/Slider-parameters.css +++ b/packages/main/src/themes/base/Slider-parameters.css @@ -1,10 +1,6 @@ :root{ - --_ui5_slider_item_background_color: #f2f2f2; - --_ui5_slider_item_text_color: #fff; - --_ui5_slider_active_item_text_color: #29313a; --_ui5_slider_item_text_size: .875rem; --_ui5_slider_label_text_size: .75rem; - --_ui5_slider_label_text_color: #666; - --_ui5_slider_item_width: 4.5rem; - --_ui5_slider_item_height: 3rem; + --_ui5_slider_selection_frame_margin_top: calc(var(--_ui5_slider_item_height) * 4); + --_ui5_slider_label_text_color: var(--sapContent_LabelColor); } \ No newline at end of file diff --git a/packages/main/src/themes/sap_belize/Slider-parameters.css b/packages/main/src/themes/sap_belize/Slider-parameters.css index b032e5121f83..be6cf53db2c4 100644 --- a/packages/main/src/themes/sap_belize/Slider-parameters.css +++ b/packages/main/src/themes/sap_belize/Slider-parameters.css @@ -1,20 +1,18 @@ @import "../base/Slider-parameters.css"; +@import "../../../../theme-base/src/themes/sap_belize/base-parameters.less"; :root{ - --_ui5_slider_item_background_color: #f7f7f7; - --_ui5_slider_item_text_color: #32363а; - --_ui_slider_item_hover_color: #f0f0f0; - --_ui5_slider_item_border_color: #fff; + --_ui5_slider_item_background_color: var(--sapTimePickerItemColor); + --_ui5_slider_item_text_color: var(--sapTextColor); + --_ui_slider_item_hover_color: var(--sapTimePickerItemHoverColor); + --_ui5_slider_item_border_color: var(--sapTimePickerItemBorderColor); --_ui5_slider_collapsed_item_text_color: var(--_ui5_slider_item_border_color); - --_ui5_slider_active_item_text_color: #29313a; - --_ui5_slider_item_text_size: .875rem; - --_ui5_slider_label_text_size: .75rem; - --_ui5_slider_label_text_color: #666; - --_ui5_slider_selected_item_background_color: #427cac; - --_ui5_slider_selected_item_hover_background_color: #244866; + --_ui5_slider_selected_item_background_color: var(--sapActiveColor); + --_ui5_slider_selected_item_hover_background_color: var(--sapTimePickerSelectedItemHoverColor); + --_ui5_slider_active_item_background_color: var(--sapActiveColor); + --_ui5_slider_active_item_text_color: var(--sapTimePickerItemColor); --_ui5_slider_item_width: 4.5rem; --_ui5_slider_item_height: 3rem; - --_ui5_slider_selection_frame_margin_top: calc(var(--_ui5_slider_item_height) * 4); --_ui5_slider_selection_frame_color: var(--_ui5_slider_selected_item_background_color); --_ui_slider_item_border_radius: 0; } \ No newline at end of file diff --git a/packages/main/src/themes/sap_belize_hcb/Slider-parameters.css b/packages/main/src/themes/sap_belize_hcb/Slider-parameters.css index 8a3e60c0010c..006bc4235a3a 100644 --- a/packages/main/src/themes/sap_belize_hcb/Slider-parameters.css +++ b/packages/main/src/themes/sap_belize_hcb/Slider-parameters.css @@ -1,20 +1,18 @@ @import "../base/Slider-parameters.css"; +@import "../../../../theme-base/src/themes/sap_belize/base-parameters.less"; :root{ - --_ui5_slider_item_background_color: #000; - --_ui5_slider_item_text_color: #fff; - --_ui_slider_item_hover_color: #7a5100; - --_ui5_slider_active_item_text_color: #29313a; - --_ui5_slider_collapsed_item_text_color: var(--_ui5_slider_item_text_color); - --_ui5_slider_item_border_color: #999; - --_ui5_slider_item_text_size: .875rem; - --_ui5_slider_label_text_size: .75rem; - --_ui5_slider_label_text_color: #666; - --_ui5_slider_selected_item_background_color: #0f5d94; - --_ui5_slider_selected_item_hover_background_color: #7a5100; + --_ui5_slider_item_background_color: var(--sapList_Background); + --_ui5_slider_item_text_color: var(--sapTextColor); + --_ui_slider_item_hover_color: var(--sapHighlightColor); + --_ui5_slider_item_border_color: var(--sapList_BorderColor); + --_ui5_slider_collapsed_item_text_color: var(--sapContent_ContrastTextColor); + --_ui5_slider_selected_item_background_color: var(--sapSelectedColor); + --_ui5_slider_selected_item_hover_background_color: var(--sapHighlightColor); + --_ui5_slider_active_item_background_color: var(--sapHighlightColor); + --_ui5_slider_active_item_text_color: var(--sapTextColor); --_ui5_slider_item_width: 4.5rem; --_ui5_slider_item_height: 3rem; - --_ui5_slider_selection_frame_margin_top: calc(var(--_ui5_slider_item_height) * 4); - --_ui5_slider_selection_frame_color: var(--_ui5_slider_item_text_color); + --_ui5_slider_selection_frame_color: var(--sapContent_ForegroundBorderColor); --_ui_slider_item_border_radius: 0; } \ No newline at end of file diff --git a/packages/main/src/themes/sap_fiori_3/Slider-parameters.css b/packages/main/src/themes/sap_fiori_3/Slider-parameters.css index 69b06ace7c46..909c777f48e3 100644 --- a/packages/main/src/themes/sap_fiori_3/Slider-parameters.css +++ b/packages/main/src/themes/sap_fiori_3/Slider-parameters.css @@ -1,20 +1,18 @@ @import "../base/Slider-parameters.css"; +@import "../../../../theme-base/src/themes/sap_fiori_3/base-parameters.less"; :root{ - --_ui5_slider_item_background_color: #f7f7f7; - --_ui5_slider_item_text_color: #32363а; - --_ui_slider_item_hover_color: #f0f0f0; - --_ui5_slider_item_border_color: #fff; + --_ui5_slider_item_background_color: var(--sapTimePickerItemColor); + --_ui5_slider_item_text_color: var(--sapTextColor); + --_ui_slider_item_hover_color: var(--sapTimePickerItemHoverColor); + --_ui5_slider_item_border_color: var(--sapTimePickerItemBorderColor); --_ui5_slider_collapsed_item_text_color: var(--_ui5_slider_item_border_color); - --_ui5_slider_active_item_text_color: #29313a; - --_ui5_slider_item_text_size: .875rem; - --_ui5_slider_label_text_size: .75rem; - --_ui5_slider_label_text_color: #666; - --_ui5_slider_selected_item_background_color: #0854a0; - --_ui5_slider_selected_item_hover_background_color: #053b70; + --_ui5_slider_selected_item_background_color: var(--sapActiveColor); + --_ui5_slider_selected_item_hover_background_color: var(--sapTimePickerSelectedItemHoverColor); + --_ui5_slider_active_item_background_color:var(--sapActiveColor); + --_ui5_slider_active_item_text_color: var(--sapTimePickerItemColor); --_ui5_slider_item_width: 3rem; --_ui5_slider_item_height: 2.875rem; - --_ui5_slider_selection_frame_margin_top: calc(var(--_ui5_slider_item_height) * 4); - --_ui5_slider_selection_frame_color: var(--_ui5_slider_selected_item_background_color); + --_ui5_slider_selection_frame_color: var(--sapSelectedColor); --_ui_slider_item_border_radius: 5px; } \ No newline at end of file diff --git a/packages/main/src/themes/sap_fiori_3_dark/Slider-parameters.css b/packages/main/src/themes/sap_fiori_3_dark/Slider-parameters.css index 632432e96ddc..e5156e73953c 100644 --- a/packages/main/src/themes/sap_fiori_3_dark/Slider-parameters.css +++ b/packages/main/src/themes/sap_fiori_3_dark/Slider-parameters.css @@ -1,20 +1,18 @@ @import "../base/Slider-parameters.css"; +@import "../../../../theme-base/src/themes/sap_fiori_3_dark/base-parameters.less"; :root{ - --_ui5_slider_item_background_color: #2f3943; - --_ui5_slider_item_text_color: #fff; - --_ui_slider_item_hover_color: #36404c; - --_ui5_slider_item_border_color: #29313a; + --_ui5_slider_item_background_color: var(--sapTimePickerItemColor); + --_ui5_slider_item_text_color: var(--sapTextColor); + --_ui_slider_item_hover_color: var(--sapTimePickerItemHoverColor); + --_ui5_slider_item_border_color: var(--sapTimePickerItemBorderColor); --_ui5_slider_collapsed_item_text_color: var(--_ui5_slider_item_border_color); - --_ui5_slider_active_item_text_color: #29313a; - --_ui5_slider_item_text_size: .875rem; - --_ui5_slider_label_text_size: .75rem; - --_ui5_slider_label_text_color: #666; - --_ui5_slider_selected_item_background_color: #91c8f6; - --_ui5_slider_selected_item_hover_background_color: #62b0f2; + --_ui5_slider_selected_item_background_color: var(--sapActiveColor); + --_ui5_slider_selected_item_hover_background_color: var(--sapTimePickerSelectedItemHoverColor); + --_ui5_slider_active_item_background_color: var(--sapActiveColor); + --_ui5_slider_active_item_text_color: var(--sapTimePickerItemColor); --_ui5_slider_item_width: 3rem; --_ui5_slider_item_height: 2.875rem; - --_ui5_slider_selection_frame_margin_top: calc(var(--_ui5_slider_item_height) * 4); - --_ui5_slider_selection_frame_color: var(--_ui5_slider_selected_item_background_color); + --_ui5_slider_selection_frame_color: var(--sapSelectedColor); --_ui_slider_item_border_radius: 5px; } \ No newline at end of file diff --git a/packages/main/test/specs/Slider.spec.js b/packages/main/test/specs/Slider.spec.js index b22d15030084..1d1995c85d20 100644 --- a/packages/main/test/specs/Slider.spec.js +++ b/packages/main/test/specs/Slider.spec.js @@ -4,7 +4,7 @@ describe("Button general interaction", () => { browser.url("http://localhost:8080/test-resources/pages/Slider_Test_Page.html"); it("tests slider's label rendering", () => { - const textValue = browser.$("#slider").shadow$$(".sapMWSLabel")[0].getText(); + const textValue = browser.$("#slider").shadow$$(".ui5-slider-label")[0].getText(); assert.strictEqual(textValue, "Test", "Slider text is rendered"); }); @@ -12,7 +12,7 @@ describe("Button general interaction", () => { it("Arrow down button is working", () => { const slider = browser.$("#slider"); console.log(slider); - const button = slider.shadow$$(".sapMWSArrows")[1]; + const button = slider.shadow$$(".ui5-slider-arrow")[1]; button.click(); assert.strictEqual(slider.getValue(), "2", "Slider button arrow down is working"); @@ -20,7 +20,7 @@ describe("Button general interaction", () => { it("Arrow up button is working", () => { const slider = browser.$("#slider"); - const button = slider.shadow$$(".sapMWSArrows")[0]; + const button = slider.shadow$$(".ui5-slider-arrow")[0]; button.click(); @@ -45,7 +45,7 @@ describe("Button general interaction", () => { it("Click on element selects element", () => { const slider = browser.$("#slider"); - const sliderElements = slider.shadow$$(".sapMWSItem"); + const sliderElements = slider.shadow$$(".ui5-slider-item"); sliderElements[5].click(); diff --git a/packages/theme-base/src/themes/sap_belize/base-parameters-vars.less b/packages/theme-base/src/themes/sap_belize/base-parameters-vars.less index 48b6411d3568..b125773ab0e3 100644 --- a/packages/theme-base/src/themes/sap_belize/base-parameters-vars.less +++ b/packages/theme-base/src/themes/sap_belize/base-parameters-vars.less @@ -253,8 +253,11 @@ --sapInfobar_Background: @sapInfobar_Background; --sapToolbar_SeparatorColor: @sapToolbar_SeparatorColor; --sapHighlightTextColor: @sapHighlightTextColor; - - // custom added params as no base ("sap" prefix) params equivalent exist --sapToggleButton_Pressed_HoverBackground: @sapToggleButton_Pressed_HoverBackground; --sapToggleButton_Pressed_HoverBorderColor: @sapToggleButton_Pressed_HoverBorderColor; + + --sapTimePickerItemBorderColor: @sapTimePicker_ItemBorderColor; + --sapTimePickerItemColor: @sapTimePicker_ItemColor; + --sapTimePickerItemHoverColor: @sapTimePicker_ItemHoverColor; + --sapTimePickerSelectedItemHoverColor: @sapTimePicker_SelectedItemHoverColor; } diff --git a/packages/theme-base/src/themes/sap_belize/base-parameters.less b/packages/theme-base/src/themes/sap_belize/base-parameters.less index 1def8d169d9e..e960937f5ea5 100644 --- a/packages/theme-base/src/themes/sap_belize/base-parameters.less +++ b/packages/theme-base/src/themes/sap_belize/base-parameters.less @@ -253,6 +253,10 @@ @sapToolbar_SeparatorColor: fade(@sapPrimary1, 20); @sapHighlightTextColor: contrast(@sapHighlightColor, @sapTextColor, @sapContent_ContrastTextColor, @sapContent_ContrastTextThreshold); -// custom added params as no base ("sap" prefix) params equivalent exist @sapToggleButton_Pressed_HoverBackground: lighten(@sapButton_Selected_Background, 10); -@sapToggleButton_Pressed_HoverBorderColor: @sapToggleButton_Pressed_HoverBackground; \ No newline at end of file +@sapToggleButton_Pressed_HoverBorderColor: @sapToggleButton_Pressed_HoverBackground; + +@sapTimePicker_ItemBorderColor: lighten(@sapList_BorderColor, 10); +@sapTimePicker_ItemColor: lighten(@sapContent_ForegroundColor, 5); +@sapTimePicker_ItemHoverColor: darken(@sapContent_ForegroundColor, 5); +@sapTimePicker_SelectedItemHoverColor: darken(@sapSelectedColor, 10); \ No newline at end of file diff --git a/packages/theme-base/src/themes/sap_fiori_3/base-parameters-vars.less b/packages/theme-base/src/themes/sap_fiori_3/base-parameters-vars.less index bb23faad041e..ca8c9ce28ef2 100644 --- a/packages/theme-base/src/themes/sap_fiori_3/base-parameters-vars.less +++ b/packages/theme-base/src/themes/sap_fiori_3/base-parameters-vars.less @@ -256,7 +256,11 @@ --sapTile_IconColor: @sapTile_IconColor; --sapToolbar_SeparatorColor: @sapToolbar_SeparatorColor; - // custom added params as no base ("sap" prefix) params equivalent exist --sapToggleButton_Pressed_HoverBackground: @sapToggleButton_Pressed_HoverBackground; --sapToggleButton_Pressed_HoverBorderColor: @sapToggleButton_Pressed_HoverBorderColor; + + --sapTimePickerItemBorderColor: @sapTimePicker_ItemBorderColor; + --sapTimePickerItemColor: @sapTimePicker_ItemColor; + --sapTimePickerItemHoverColor: @sapTimePicker_ItemHoverColor; + --sapTimePickerSelectedItemHoverColor: @sapTimePicker_SelectedItemHoverColor; } \ No newline at end of file diff --git a/packages/theme-base/src/themes/sap_fiori_3/base-parameters.less b/packages/theme-base/src/themes/sap_fiori_3/base-parameters.less index 9772708d4cbe..5d38c4a29949 100644 --- a/packages/theme-base/src/themes/sap_fiori_3/base-parameters.less +++ b/packages/theme-base/src/themes/sap_fiori_3/base-parameters.less @@ -254,6 +254,12 @@ @sapTile_IconColor: contrast(@sapTile_Background, lighten(@sapShellColor ,20), @sapContent_ContrastIconColor, @sapContent_ContrastTextThreshold); @sapToolbar_SeparatorColor: darken(@sapBaseColor, 15); -// custom added params as no base ("sap" prefix) params equivalent exist + @sapToggleButton_Pressed_HoverBackground: lighten(@sapSelectedColor, 3); -@sapToggleButton_Pressed_HoverBorderColor: @sapToggleButton_Pressed_HoverBackground; \ No newline at end of file +@sapToggleButton_Pressed_HoverBorderColor: @sapToggleButton_Pressed_HoverBackground; + + +@sapTimePicker_ItemBorderColor: @sapList_Background; +@sapTimePicker_ItemColor: darken(@sapList_Background, 3); +@sapTimePicker_ItemHoverColor: darken(@sapList_Background, 6); +@sapTimePicker_SelectedItemHoverColor: darken(@sapSelectedColor, 10); \ No newline at end of file diff --git a/packages/theme-base/src/themes/sap_fiori_3_dark/base-parameters-vars.less b/packages/theme-base/src/themes/sap_fiori_3_dark/base-parameters-vars.less index bea731f02e09..06a4ad66e2f6 100644 --- a/packages/theme-base/src/themes/sap_fiori_3_dark/base-parameters-vars.less +++ b/packages/theme-base/src/themes/sap_fiori_3_dark/base-parameters-vars.less @@ -258,7 +258,11 @@ --sapTile_IconColor: @sapTile_IconColor; --sapObjectHeader_BorderColor: @sapObjectHeader_BorderColor; - // custom added params as no base ("sap" prefix) params equivalent exist --sapToggleButton_Pressed_HoverBackground: @sapToggleButton_Pressed_HoverBackground; --sapToggleButton_Pressed_HoverBorderColor: @sapToggleButton_Pressed_HoverBorderColor; + + --sapTimePickerItemBorderColor: @sapTimePicker_ItemBorderColor; + --sapTimePickerItemColor: @sapTimePicker_ItemColor; + --sapTimePickerItemHoverColor: @sapTimePicker_ItemHoverColor; + --sapTimePickerSelectedItemHoverColor: @sapTimePicker_SelectedItemHoverColor; } diff --git a/packages/theme-base/src/themes/sap_fiori_3_dark/base-parameters.less b/packages/theme-base/src/themes/sap_fiori_3_dark/base-parameters.less index b7af7327a8ab..447839421624 100644 --- a/packages/theme-base/src/themes/sap_fiori_3_dark/base-parameters.less +++ b/packages/theme-base/src/themes/sap_fiori_3_dark/base-parameters.less @@ -252,6 +252,10 @@ @sapTile_IconColor: contrast(@sapTile_Background, lighten(@sapShellColor, 35), @sapContent_ContrastIconColor, @sapContent_ContrastTextThreshold); @sapObjectHeader_BorderColor: lighten(@sapObjectHeader_Background, 8); -// custom added params as no base ("sap" prefix) params equivalent exist @sapToggleButton_Pressed_HoverBackground: darken(@sapSelectedColor, 3); -@sapToggleButton_Pressed_HoverBorderColor: @sapToggleButton_Pressed_HoverBackground; \ No newline at end of file +@sapToggleButton_Pressed_HoverBorderColor: @sapToggleButton_Pressed_HoverBackground; + +@sapTimePicker_ItemBorderColor: @sapList_Background; +@sapTimePicker_ItemColor: lighten(@sapList_Background, 3); +@sapTimePicker_ItemHoverColor: lighten(@sapList_Background, 6); +@sapTimePicker_SelectedItemHoverColor: darken(@sapSelectedColor, 10); \ No newline at end of file diff --git a/packages/tools/components-package/wdio.js b/packages/tools/components-package/wdio.js index 05cd3abb4c4a..c5f595e55c11 100644 --- a/packages/tools/components-package/wdio.js +++ b/packages/tools/components-package/wdio.js @@ -57,7 +57,7 @@ exports.config = { // to run chrome headless the following flags are required // (see https://developers.google.com/web/updates/2017/04/headless-chrome) args: ['--headless', '--disable-gpu'], - // args: ['--disable-gpu'], + //args: ['--disable-gpu'], } }], // From a32ecf49d5afe4ee6809f88193c9617ec7b1e1ef Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Tue, 18 Feb 2020 15:51:59 +0200 Subject: [PATCH 26/57] minor fixes --- packages/main/src/Slider.js | 13 ++++++++++--- packages/main/src/TimePicker.hbs | 4 ++-- packages/main/src/TimePicker.js | 9 +++++++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/main/src/Slider.js b/packages/main/src/Slider.js index fe99627634d8..51da822f06e3 100644 --- a/packages/main/src/Slider.js +++ b/packages/main/src/Slider.js @@ -150,7 +150,11 @@ class Slider extends UI5Element { } onBeforeRendering(){ - this._itemCellHeight = this.shadowRoot.querySelectorAll(".ui5-slider-item").length && this.shadowRoot.querySelectorAll(".ui5-slider-item")[0].offsetHeight / 16; + this._updateItemCellHeight(); + } + + _updateItemCellHeight(){ + this._itemCellHeight = this.shadowRoot.querySelectorAll(".ui5-slider-item").length && Number(getComputedStyle(this.shadowRoot.querySelector(".ui5-slider-item")).getPropertyValue("--_ui5_slider_item_height").replace("rem","")); } _findSelectedElement(){ @@ -194,11 +198,11 @@ class Slider extends UI5Element { // this._scroller.scrollContainer = this.shadowRoot.querySelector(`#${this._id}--wrapper`); // this._scroller.attachEvent("scroll", this._updateScrolling.bind(this)); - this.shadowRoot.querySelector(".ui5-slider-wrapper > ul").addEventListener("wheel", (e) => { + this.shadowRoot.querySelector(".ui5-slider-wrapper").addEventListener("wheel", (e) => { e.stopPropagation(); e.preventDefault(); - if (e.timeStamp === this._prevWheelTimestamp){ + if (e.timeStamp === this._prevWheelTimestamp || !this._expanded){ return; } @@ -262,7 +266,10 @@ class Slider extends UI5Element { const sliderElement = this.shadowRoot.getElementById(`${this._id}--items-list`); if ( index < this._items.length && index > - 1) { let offsetSelectedElement = 4 * this._itemCellHeight - (index * this._itemCellHeight); + // let scrollToValue = index * 16 * this._itemCellHeight; + // console.log(scrollToValue); sliderElement.setAttribute("style",`top:${offsetSelectedElement}rem`); + // this.shadowRoot.getElementById(`${this._id}--wrapper`).scrollTo({top: scrollToValue, left: 0, behavior: 'smooth'}); this.value = this._items[index]; this._currentElementIndex = index; } diff --git a/packages/main/src/TimePicker.hbs b/packages/main/src/TimePicker.hbs index 0ea915a64e32..8364480b4fe4 100644 --- a/packages/main/src/TimePicker.hbs +++ b/packages/main/src/TimePicker.hbs @@ -64,8 +64,8 @@ > {{/if}}
- Submit - Close + Submit + Close
\ No newline at end of file diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index e020f3bf459c..e3152773918a 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -202,6 +202,11 @@ class TimePicker extends UI5Element { stayOpenOnScroll: true, afterClose: () => { this._isPickerOpen = false; + const sliders = this._getPopover().default.filter(x => x.isUI5Element); + + for (let i = 0; i < sliders.length; i++) { + sliders[i].collapseSlider(); + } } }; } @@ -272,7 +277,7 @@ class TimePicker extends UI5Element { } closePicker() { - let sliders = this._getPopover().default.filter(x => x.isUI5Element); + const sliders = this._getPopover().default.filter(x => x.isUI5Element); this._getPopover().close(); @@ -353,7 +358,7 @@ class TimePicker extends UI5Element { period = periodsSlider ? periodsSlider.value : "AM"; if (period === "PM") { - selectedDate.setHours(hours*1 + 12); + selectedDate.setHours(hours * 1 + 12); } else { selectedDate.setHours(hours); } From 7ecce83c651a6aa0760d9ae8748a86b2527480a5 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Mon, 24 Feb 2020 17:29:03 +0200 Subject: [PATCH 27/57] Responsive popover support added, mobile view fixed, more functionality added --- packages/main/src/Slider.hbs | 8 +- packages/main/src/Slider.js | 68 +++++++------- packages/main/src/TimePicker.hbs | 40 +++++---- packages/main/src/TimePicker.js | 114 +++++++++++++++++------- packages/main/src/themes/Slider.css | 7 +- packages/main/src/themes/TimePicker.css | 20 +++++ 6 files changed, 167 insertions(+), 90 deletions(-) diff --git a/packages/main/src/Slider.hbs b/packages/main/src/Slider.hbs index e8a71bc34b35..fc1c125e56d5 100644 --- a/packages/main/src/Slider.hbs +++ b/packages/main/src/Slider.hbs @@ -10,9 +10,11 @@ data-sap-focus-ref tabindex="0" > -
{{label}}
-
- +
+
{{label}}
+
+ +
diff --git a/packages/main/src/Slider.js b/packages/main/src/Slider.js index 51da822f06e3..75bbc2258f2f 100644 --- a/packages/main/src/Slider.js +++ b/packages/main/src/Slider.js @@ -4,7 +4,7 @@ import SliderTemplate from "./generated/templates/SliderTemplate.lit.js"; import { isDown, isUp, -} from "../../base/src/events/PseudoEvents"; +} from "../../base/src/events/PseudoEvents.js"; // Styles import SliderCss from "./generated/themes/Slider.css.js"; @@ -27,7 +27,7 @@ const metadata = { * @public */ disabled: { - type: Boolean + type: Boolean, }, /** @@ -37,7 +37,7 @@ const metadata = { * @public */ value: { - type: String + type: String, }, /** @@ -47,7 +47,7 @@ const metadata = { * @public */ cyclic: { - type: Boolean + type: Boolean, }, /** @@ -58,7 +58,7 @@ const metadata = { */ label: { type: String, - defaultValue: "" + defaultValue: "", }, /** @@ -68,11 +68,11 @@ const metadata = { * @private */ _expanded: { - type: Boolean + type: Boolean, }, _items: { - type: Object + type: Object, } }, slots: /** @lends sap.ui.webcomponents.main.Slider.prototype */ { @@ -94,9 +94,9 @@ const metadata = { */ valueSelect: { value: { - type: String + type: String, } - } + }, }, }; @@ -143,48 +143,48 @@ class Slider extends UI5Element { constructor() { super(); - //this.i18nBundle = getI18nBundle("@ui5/webcomponents"); + // this.i18nBundle = getI18nBundle("@ui5/webcomponents"); // this._scroller = new ScrollEnablement(this); this._currentElementIndex = 0; this._itemCellHeight = 0; } - onBeforeRendering(){ + onBeforeRendering() { this._updateItemCellHeight(); } - _updateItemCellHeight(){ - this._itemCellHeight = this.shadowRoot.querySelectorAll(".ui5-slider-item").length && Number(getComputedStyle(this.shadowRoot.querySelector(".ui5-slider-item")).getPropertyValue("--_ui5_slider_item_height").replace("rem","")); + _updateItemCellHeight() { + this._itemCellHeight = this.shadowRoot.querySelectorAll(".ui5-slider-item").length && Number(getComputedStyle(this.shadowRoot.querySelector(".ui5-slider-item")).getPropertyValue("--_ui5_slider_item_height").replace("rem", "")); } - _findSelectedElement(){ + _findSelectedElement() { let itemsList = this.shadowRoot.querySelector(`#${this._id}--items-list`), parentOffset = itemsList.parentElement.parentElement.offsetTop, itemsListArray = [...itemsList.children], firstVisibleElementIndex = 0; - while ((itemsListArray[firstVisibleElementIndex].getBoundingClientRect().y - parentOffset) < 0){ + while ((itemsListArray[firstVisibleElementIndex].getBoundingClientRect().y - parentOffset) < 0) { firstVisibleElementIndex++; } return itemsListArray[firstVisibleElementIndex + 5]; } - _updateScrolling(e){ + _updateScrolling(e) { let sizeInRems = this._items.length * 3, // the size of one element in rems (16px = 1rem) sizeOfOneElementInPixels = _itemCellHeight * 16, indexForOffset; const elements = this.shadowRoot.querySelectorAll(".ui5-slider-item"), selectedElement = this._findSelectedElement(); - if (!selectedElement){ + if (!selectedElement) { return; } if (this.value === selectedElement.textContent) { return; } - if ( (e.scroll / sizeOfOneElementInPixels) / 0.5 > 1) { + if ( (e.scroll / sizeOfOneElementInPixels) / 0.5 > 1) { indexForOffset = Math.ceil(e.scroll / sizeOfOneElementInPixels); } else { indexForOffset = Math.floor(e.scroll / sizeOfOneElementInPixels); @@ -202,14 +202,14 @@ class Slider extends UI5Element { e.stopPropagation(); e.preventDefault(); - if (e.timeStamp === this._prevWheelTimestamp || !this._expanded){ + if (e.timeStamp === this._prevWheelTimestamp || !this._expanded) { return; } if (e.deltaY > 0){ - this._onArrowUp(); + this._onArrowUp(e); } else if (e.deltaY < 0) { - this._onArrowDown(); + this._onArrowDown(e); } this._prevWheelTimestamp = e.timeStamp; @@ -233,7 +233,7 @@ class Slider extends UI5Element { } _onclick(e) { - if (!e.target.classList.contains("ui5-slider-item")){ + if (!e.target.classList.contains("ui5-slider-item")) { return; } @@ -245,24 +245,24 @@ class Slider extends UI5Element { } } - expandSlider(){ + expandSlider() { this._expanded = true; - this.fireEvent("expand",{}); + this.fireEvent("expand", {}); } - collapseSlider(){ + collapseSlider() { this._expanded = false; - this.fireEvent("collapse",{}); + this.fireEvent("collapse", {}); } - _selectElement(element){ + _selectElement(element) { if (element && this._items.indexOf(element.textContent) > -1) { this._currentElementIndex = this._items.indexOf(element.textContent); this._selectElementByIndex(this._currentElementIndex); } } - _selectElementByIndex(index){ + _selectElementByIndex(index) { const sliderElement = this.shadowRoot.getElementById(`${this._id}--items-list`); if ( index < this._items.length && index > - 1) { let offsetSelectedElement = 4 * this._itemCellHeight - (index * this._itemCellHeight); @@ -275,23 +275,25 @@ class Slider extends UI5Element { } } - _onArrowDown(){ + _onArrowDown(e) { + e.preventDefault(); const nextElementIndex = this._currentElementIndex + 1; this._selectElementByIndex(nextElementIndex); } - _onArrowUp(){ + _onArrowUp(e) { + e.preventDefault(); const nextElementIndex = this._currentElementIndex - 1; this._selectElementByIndex(nextElementIndex); } - _onkeydown(event){ + _onkeydown(event) { if (isUp(event)) { - this._onArrowUp(); + this._onArrowUp(event); } if (isDown(event)) { - this._onArrowDown(); + this._onArrowDown(event); } } } diff --git a/packages/main/src/TimePicker.hbs b/packages/main/src/TimePicker.hbs index 8364480b4fe4..580da9e0a95d 100644 --- a/packages/main/src/TimePicker.hbs +++ b/packages/main/src/TimePicker.hbs @@ -1,4 +1,4 @@ -
+
- +
{{#if shouldBuildHoursSlider}} {{/if}} {{#if shouldBuildMinutesSlider}} @@ -43,7 +44,7 @@ label = "Minutes" ._items="{{minutesArray}}" @click="{{handleSliderClicked}}" - class="ui5-timepicker-minutes-slider" + class="ui5-timepicker-slider ui5-timepicker-minutes-slider" > {{/if}} {{#if shouldBuildSecondsSlider}} @@ -51,7 +52,7 @@ label = "Seconds" ._items="{{secondsArray}}" @click="{{handleSliderClicked}}" - class="ui5-timepicker-seconds-slider" + class="ui5-timepicker-slider ui5-timepicker-seconds-slider" > {{/if}} {{#if shouldBuildPeriodsSlider}} @@ -60,12 +61,13 @@ value="AM" ._items="{{periodsArray}}" @click="{{handleSliderClicked}}" - class="ui5-timepicker-period-slider" + class="ui5-timepicker-slider ui5-timepicker-period-slider" > {{/if}} -
- Submit - Close -
- +
+ +
\ No newline at end of file diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index e3152773918a..a0de7794e122 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -1,7 +1,7 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import TimePickerTemplate from "./generated/templates/TimePickerTemplate.lit.js"; -import Popover from "./Popover.js"; +import ResponsivePopover from "./ResponsivePopover.js"; import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js"; import PopoverPlacementType from "./types/PopoverPlacementType.js"; import PopoverHorizontalAlign from "./types/PopoverHorizontalAlign.js"; @@ -11,6 +11,7 @@ import { getLocale } from "@ui5/webcomponents-base/dist/LocaleProvider.js"; // Styles import TimePickerCss from "./generated/themes/TimePicker.css.js"; +import ResponsivePopoverCommonCss from "./generated/themes/ResponsivePopoverCommon.css.js"; /** * @public @@ -113,7 +114,7 @@ const metadata = { noAttribute: true, }, - _popover: { + _respPopover: { type: Object, }, @@ -178,14 +179,18 @@ class TimePicker extends UI5Element { return TimePickerTemplate; } - static async define(...params) { + static async onDefine() { await Promise.all([ fetchCldr(getLocale().getLanguage(), getLocale().getRegion(), getLocale().getScript()), + ResponsivePopover.define(), ]); + } - super.define(...params); + static get staticAreaStyles() { + return [ResponsivePopoverCommonCss]; } + constructor() { super(); @@ -195,32 +200,39 @@ class TimePicker extends UI5Element { //this.i18nBundle = getI18nBundle("@ui5/webcomponents"); //this._scroller = new ScrollEnablement(this); - this._popover = { + this._respPopover = { placementType: PopoverPlacementType.Bottom, horizontalAlign: PopoverHorizontalAlign.Left, allowTargetOverlap: true, stayOpenOnScroll: true, afterClose: () => { this._isPickerOpen = false; - const sliders = this._getPopover().default.filter(x => x.isUI5Element); - + const sliders = this._getPopover().default.length ? [...this._getPopover().default[0].children].filter(x => x.isUI5Element) : this._getPopover().default; + for (let i = 0; i < sliders.length; i++) { sliders[i].collapseSlider(); } } }; + + this._hoursParameters = { + minHour: 0, + maxHour: 0, + isTwelveHoursFormat: false + }; } onBeforeRendering() { if (!this.value) { this.value = this.getFormat().format(new Date()); - } + } + this._initHoursFormatParameters(); } onAfterRendering() { - let sliders = this._getPopover().default.filter(x => x.isUI5Element), + let sliders = this._getPopover().default.length ? [...this._getPopover().default[0].children].filter(x => x.isUI5Element) : this._getPopover().default, slidersEnablementArray = this._getSlidersContained(this.formatPattern); - + for (let i = 0; i < sliders.length; i++) { sliders[i].disabled = !slidersEnablementArray[i]; } @@ -250,16 +262,18 @@ class TimePicker extends UI5Element { } setSlidersValue() { - let currentDate = this._getInput ? this.getFormat().parse(this._getInput().value) : null, + let currentDate = this._getInput() ? this.getFormat().parse(this._getInput().getAttribute("value")) : null, secondsSlider = this.shadowRoot.querySelector(".ui5-timepicker-seconds-slider"), minutesSlider = this.shadowRoot.querySelector(".ui5-timepicker-minutes-slider"), hoursSlider = this.shadowRoot.querySelector(".ui5-timepicker-hours-slider"), - periodsSlider = this.shadowRoot.querySelector(".ui5-timepicker-periods-slider"); + periodsSlider = this.shadowRoot.querySelector(".ui5-timepicker-period-slider"); if (currentDate) { if (hoursSlider){ - if (this.isTwelveHoursFormat && currentDate.getHours() > 11){ + if (this._hoursParameters.isTwelveHoursFormat && currentDate.getHours() > this._hoursParameters.maxHour){ hoursSlider.value = currentDate.getHours() - 12; + } else if (this._hoursParameters.isTwelveHoursFormat && currentDate.getHours() < this._hoursParameters.minHour) { + hoursSlider.value = currentDate.getHours() + 12; } else { hoursSlider.value = currentDate.getHours(); } @@ -270,15 +284,17 @@ class TimePicker extends UI5Element { if (secondsSlider) { secondsSlider.value = currentDate.getSeconds(); } - if (this.isTwelveHoursFormat && periodsSlider) { - periodsSlider.value = currentDate.getHours() > 11 ? "PM" : "AM"; + if (this._hoursParameters.isTwelveHoursFormat && periodsSlider && this._hoursParameters.minHour === 1) { + periodsSlider.value = currentDate.getHours() > this._hoursParameters.maxHour ? "PM" : "AM"; + } else if (this._hoursParameters.isTwelveHoursFormat && periodsSlider) { + periodsSlider.value = (currentDate.getHours() > this._hoursParameters.maxHour || currentDate.getHours() === this._hoursParameters.minHour)? "PM" : "AM"; } } } closePicker() { - const sliders = this._getPopover().default.filter(x => x.isUI5Element); - + const sliders = [...this._getPopover().default[0].children].filter(x => x.isUI5Element); + this._getPopover().close(); for (let i = 0; i < sliders.length; i++) { @@ -287,7 +303,7 @@ class TimePicker extends UI5Element { } openPicker() { - this._getPopover().openBy(this); + this._getPopover().open(this); this._isPickerOpen = true; } @@ -312,7 +328,7 @@ class TimePicker extends UI5Element { } _getPopover() { - return this.shadowRoot.querySelector("ui5-popover"); + return this.shadowRoot.querySelector("ui5-responsive-popover"); } generateTimeItemsArray(x) { @@ -332,14 +348,23 @@ class TimePicker extends UI5Element { } get hoursArray() { - if (this.isTwelveHoursFormat) { - return this.generateTimeItemsArray(12); + let hoursValueArray = []; + + if (this._hoursParameters.isTwelveHoursFormat) { + hoursValueArray = this.generateTimeItemsArray(12); + } else { + hoursValueArray = this.generateTimeItemsArray(24); + } + + if (this._hoursParameters.minHour === 1) { + hoursValueArray = hoursValueArray.map( x => (x * 1 + 1) + ""); } - return this.generateTimeItemsArray(24); + + return hoursValueArray; } get periodsArray() { - return ["AM", "PM"]; + return this.getFormat().aDayPeriods.map(x => x.toUpperCase()); } _getInput() { @@ -351,11 +376,11 @@ class TimePicker extends UI5Element { secondsSlider = this.shadowRoot.querySelector(".ui5-timepicker-seconds-slider"), minutesSlider = this.shadowRoot.querySelector(".ui5-timepicker-minutes-slider"), hoursSlider = this.shadowRoot.querySelector(".ui5-timepicker-hours-slider"), - periodsSlider = this.shadowRoot.querySelector(".ui5-timepicker-periods-slider"), - hours = hoursSlider ? hoursSlider.value : "0", - minutes = minutesSlider ? minutesSlider.value : "0", - seconds = secondsSlider ? secondsSlider.value : "0", - period = periodsSlider ? periodsSlider.value : "AM"; + periodsSlider = this.shadowRoot.querySelector(".ui5-timepicker-period-slider"), + hours = hoursSlider ? hoursSlider.getAttribute("value") : "0", + minutes = minutesSlider ? minutesSlider.getAttribute("value") : "0", + seconds = secondsSlider ? secondsSlider.getAttribute("value") : "0", + period = periodsSlider ? periodsSlider.getAttribute("value") : "AM"; if (period === "PM") { selectedDate.setHours(hours * 1 + 12); @@ -402,7 +427,8 @@ class TimePicker extends UI5Element { } handleSliderClicked(event) { - let sliders = this._getPopover().default.filter(x => x.isUI5Element); + let sliders = [...this._getPopover().default[0].children].filter(x => x.isUI5Element); + if (event.target._expanded) { for (var i = 0; i < sliders.length; i++) { if (sliders[i].label !== event.target.label) { @@ -436,18 +462,16 @@ class TimePicker extends UI5Element { } _getSlidersContained() { - let formatArray = this.getFormat().aFormatArray, + const formatArray = this.getFormat().aFormatArray, slidersBuildArray = [false, false, false, false]; // hours minutes seconds am/pm for (var i = 0; i < formatArray.length; i++) { - if (formatArray[i].type === "hour0_23") { + if (this._hoursParameters.maxHour !== 0) { slidersBuildArray[0] = true; - this.isTwelveHoursFormat = false; } - if (formatArray[i].type === "hour1_12") { + if (this._hoursParameters.maxHour !== 0 && this._hoursParameters.isTwelveHoursFormat) { slidersBuildArray[3] = true; slidersBuildArray[0] = true; - this.isTwelveHoursFormat = true; } if (formatArray[i].type === "minute") { slidersBuildArray[1] = true; @@ -460,6 +484,28 @@ class TimePicker extends UI5Element { return slidersBuildArray; } + _initHoursFormatParameters() { + const formatArray = this.getFormat().aFormatArray; + + if (formatArray[0].type === "hour0_23") { + this._hoursParameters.minHour = 0; + this._hoursParameters.maxHour = 23; + this._hoursParameters.isTwelveHoursFormat = false; + } else if (formatArray[0].type === "hour1_24") { + this._hoursParameters.minHour = 1; + this._hoursParameters.maxHour = 24; + this._hoursParameters.isTwelveHoursFormat = false; + } else if (formatArray[0].type === "hour0_11") { + this._hoursParameters.minHour = 0; + this._hoursParameters.maxHour = 11; + this._hoursParameters.isTwelveHoursFormat = true; + } else if (formatArray[0].type === "hour1_12") { + this._hoursParameters.minHour = 1; + this._hoursParameters.maxHour = 12; + this._hoursParameters.isTwelveHoursFormat = true; + } + } + get shouldBuildHoursSlider() { return this._getSlidersContained()[0]; } diff --git a/packages/main/src/themes/Slider.css b/packages/main/src/themes/Slider.css index 55d606f2c0b8..148b9a935302 100644 --- a/packages/main/src/themes/Slider.css +++ b/packages/main/src/themes/Slider.css @@ -1,11 +1,13 @@ .ui5-slider { - display: inline-block; overflow: hidden; height: 100%; vertical-align: middle; text-align: center; box-sizing: border-box; font-family: var(--sapFontFamily); + justify-content: space-between; + flex-direction: column; + display: inline-flex; } .ui5-slider .ui5-slider-label { box-sizing: border-box; @@ -103,6 +105,9 @@ height: 100%; cursor: default; margin: 0; + justify-content: space-between; + flex-direction: column; + display: inline-flex; } .ui5-slider[expanded] .ui5-slider-label { diff --git a/packages/main/src/themes/TimePicker.css b/packages/main/src/themes/TimePicker.css index e69de29bb2d1..d9d8625d8d05 100644 --- a/packages/main/src/themes/TimePicker.css +++ b/packages/main/src/themes/TimePicker.css @@ -0,0 +1,20 @@ +.ui5-timepicker{ + display: inline-block; +} + +.ui5-timepicker-sliders-container{ + display: flex; + justify-content: center; + align-items: stretch; +} + +.ui5-timepicker-footer{ + height: fit-content; + display: flex; + justify-content: flex-end; + width: 100%; +} + +.ui5-timepicker-footer *{ + margin: 1%; +} \ No newline at end of file From 03a264093c1e165bb2b6e18ca17c0675eed3d0bf Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Wed, 4 Mar 2020 15:48:25 +0200 Subject: [PATCH 28/57] prepare for review --- packages/main/src/Slider.hbs | 6 +- packages/main/src/Slider.js | 79 +++-------- packages/main/src/TimePicker.hbs | 10 +- packages/main/src/TimePicker.js | 127 +++++++++++++----- .../main/src/i18n/messagebundle.properties | 12 ++ packages/main/src/themes/Slider.css | 5 + .../sap_fiori_3_dark/Slider-parameters.css | 1 - packages/main/test/pages/TimePicker.html | 2 +- packages/main/test/specs/Slider.spec.js | 3 +- packages/main/test/specs/TimePicker.spec.js | 6 + 10 files changed, 147 insertions(+), 104 deletions(-) create mode 100644 packages/main/test/specs/TimePicker.spec.js diff --git a/packages/main/src/Slider.hbs b/packages/main/src/Slider.hbs index fc1c125e56d5..9b3a5ea02a2d 100644 --- a/packages/main/src/Slider.hbs +++ b/packages/main/src/Slider.hbs @@ -8,6 +8,8 @@ @keydown={{_onkeydown}} class = "ui5-slider" data-sap-focus-ref + @focusin="{{_onfocusin}}" + @focusout="{{_onfocusout}}" tabindex="0" >
@@ -18,7 +20,7 @@
-
+
{{#if _expanded}}
    {{#each items}} @@ -32,5 +34,5 @@ {{/if}}
- +
\ No newline at end of file diff --git a/packages/main/src/Slider.js b/packages/main/src/Slider.js index 75bbc2258f2f..1e66f1f746bf 100644 --- a/packages/main/src/Slider.js +++ b/packages/main/src/Slider.js @@ -4,11 +4,12 @@ import SliderTemplate from "./generated/templates/SliderTemplate.lit.js"; import { isDown, isUp, + isTabNext, + isTabPrevious, } from "../../base/src/events/PseudoEvents.js"; // Styles import SliderCss from "./generated/themes/Slider.css.js"; -import ScrollEnablement from "@ui5/webcomponents-base/dist/delegate/ScrollEnablement.js"; /** * @private @@ -40,16 +41,6 @@ const metadata = { type: String, }, - /** - * Indicates if the slider will support cyclic scrolling. - * @type {boolean} - * @defaultvalue false - * @public - */ - cyclic: { - type: Boolean, - }, - /** * Defines the label of the slider. * @type {string} @@ -137,14 +128,8 @@ class Slider extends UI5Element { return SliderTemplate; } - static async define(...params) { - super.define(...params); - } - constructor() { super(); - // this.i18nBundle = getI18nBundle("@ui5/webcomponents"); - // this._scroller = new ScrollEnablement(this); this._currentElementIndex = 0; this._itemCellHeight = 0; } @@ -157,46 +142,7 @@ class Slider extends UI5Element { this._itemCellHeight = this.shadowRoot.querySelectorAll(".ui5-slider-item").length && Number(getComputedStyle(this.shadowRoot.querySelector(".ui5-slider-item")).getPropertyValue("--_ui5_slider_item_height").replace("rem", "")); } - _findSelectedElement() { - let itemsList = this.shadowRoot.querySelector(`#${this._id}--items-list`), - parentOffset = itemsList.parentElement.parentElement.offsetTop, - itemsListArray = [...itemsList.children], - firstVisibleElementIndex = 0; - - while ((itemsListArray[firstVisibleElementIndex].getBoundingClientRect().y - parentOffset) < 0) { - firstVisibleElementIndex++; - } - - return itemsListArray[firstVisibleElementIndex + 5]; - } - - _updateScrolling(e) { - let sizeInRems = this._items.length * 3, // the size of one element in rems (16px = 1rem) - sizeOfOneElementInPixels = _itemCellHeight * 16, - indexForOffset; - const elements = this.shadowRoot.querySelectorAll(".ui5-slider-item"), - selectedElement = this._findSelectedElement(); - - if (!selectedElement) { - return; - } - if (this.value === selectedElement.textContent) { - return; - } - - if ( (e.scroll / sizeOfOneElementInPixels) / 0.5 > 1) { - indexForOffset = Math.ceil(e.scroll / sizeOfOneElementInPixels); - } else { - indexForOffset = Math.floor(e.scroll / sizeOfOneElementInPixels); - } - - this._selectElement(selectedElement); - this.value = selectedElement.textContent; - } - onAfterRendering() { - // this._scroller.scrollContainer = this.shadowRoot.querySelector(`#${this._id}--wrapper`); - // this._scroller.attachEvent("scroll", this._updateScrolling.bind(this)); this.shadowRoot.querySelector(".ui5-slider-wrapper").addEventListener("wheel", (e) => { e.stopPropagation(); @@ -266,10 +212,7 @@ class Slider extends UI5Element { const sliderElement = this.shadowRoot.getElementById(`${this._id}--items-list`); if ( index < this._items.length && index > - 1) { let offsetSelectedElement = 4 * this._itemCellHeight - (index * this._itemCellHeight); - // let scrollToValue = index * 16 * this._itemCellHeight; - // console.log(scrollToValue); sliderElement.setAttribute("style",`top:${offsetSelectedElement}rem`); - // this.shadowRoot.getElementById(`${this._id}--wrapper`).scrollTo({top: scrollToValue, left: 0, behavior: 'smooth'}); this.value = this._items[index]; this._currentElementIndex = index; } @@ -288,6 +231,14 @@ class Slider extends UI5Element { } _onkeydown(event) { + if (!this._expanded){ + return; + } + + if (isTabPrevious(event) || isTabNext(event)){ + event.preventDefault(); + } + if (isUp(event)) { this._onArrowUp(event); } @@ -296,6 +247,16 @@ class Slider extends UI5Element { this._onArrowDown(event); } } + + _onfocusin(e){ + e.preventDefault(); + this.expandSlider(); + } + + _onfocusout(e){ + e.preventDefault(); + this.collapseSlider(); + } } Slider.define(); diff --git a/packages/main/src/TimePicker.hbs b/packages/main/src/TimePicker.hbs index 580da9e0a95d..a4e53b57068f 100644 --- a/packages/main/src/TimePicker.hbs +++ b/packages/main/src/TimePicker.hbs @@ -30,10 +30,10 @@ header-text="Pick Time" class="ui5-timepicker-popover" > -
+
{{#if shouldBuildHoursSlider}} { this._isPickerOpen = false; - const sliders = this._getPopover().default.length ? [...this._getPopover().default[0].children].filter(x => x.isUI5Element) : this._getPopover().default; - - for (let i = 0; i < sliders.length; i++) { - sliders[i].collapseSlider(); - } + this.closePicker(); } }; @@ -220,6 +224,8 @@ class TimePicker extends UI5Element { maxHour: 0, isTwelveHoursFormat: false }; + + this._slidersDomRefs = []; } onBeforeRendering() { @@ -230,11 +236,11 @@ class TimePicker extends UI5Element { } onAfterRendering() { - let sliders = this._getPopover().default.length ? [...this._getPopover().default[0].children].filter(x => x.isUI5Element) : this._getPopover().default, - slidersEnablementArray = this._getSlidersContained(this.formatPattern); + let slidersEnablementArray = this._getSlidersContained(this.formatPattern); + this._slidersDomRefs = this._getPopover().default.length ? [...this._getPopover().default[0].children].filter(x => x.isUI5Element) : this._getPopover().default; - for (let i = 0; i < sliders.length; i++) { - sliders[i].disabled = !slidersEnablementArray[i]; + for (let i = 0; i < this._slidersDomRefs.length; i++) { + this._slidersDomRefs[i].disabled = !slidersEnablementArray[i]; } this.setSlidersValue(); @@ -293,12 +299,10 @@ class TimePicker extends UI5Element { } closePicker() { - const sliders = [...this._getPopover().default[0].children].filter(x => x.isUI5Element); - this._getPopover().close(); - for (let i = 0; i < sliders.length; i++) { - sliders[i].collapseSlider(); + for (let i = 0; i < this._slidersDomRefs.length; i++) { + this._slidersDomRefs[i].collapseSlider(); } } @@ -314,11 +318,7 @@ class TimePicker extends UI5Element { this.openPicker(); } } - /** - * Checks if the picker is open. - * @returns {Boolean} true if the picker is open, false otherwise - * @public - */ + isOpen() { return !!this._isPickerOpen; } @@ -377,7 +377,7 @@ class TimePicker extends UI5Element { minutesSlider = this.shadowRoot.querySelector(".ui5-timepicker-minutes-slider"), hoursSlider = this.shadowRoot.querySelector(".ui5-timepicker-hours-slider"), periodsSlider = this.shadowRoot.querySelector(".ui5-timepicker-period-slider"), - hours = hoursSlider ? hoursSlider.getAttribute("value") : "0", + hours = hoursSlider ? hoursSlider.getAttribute("value") : this._hoursParameters.minHour.toString(), minutes = minutesSlider ? minutesSlider.getAttribute("value") : "0", seconds = secondsSlider ? secondsSlider.getAttribute("value") : "0", period = periodsSlider ? periodsSlider.getAttribute("value") : "AM"; @@ -395,17 +395,10 @@ class TimePicker extends UI5Element { this.closePicker(); } - /** - * Checks if a value is valid against the current time format of the TimePicker - * @param {string} value A value to be tested against the current time format - * @public - */ isValid(value = "") { return !!(value && this.getFormat().parse(value)); } - // because the parser understands more than one format - // but we need values in one format normalizeValue(sValue) { return this.getFormat().format(this.getFormat().parse(sValue)); } @@ -427,14 +420,65 @@ class TimePicker extends UI5Element { } handleSliderClicked(event) { - let sliders = [...this._getPopover().default[0].children].filter(x => x.isUI5Element); - if (event.target._expanded) { - for (var i = 0; i < sliders.length; i++) { - if (sliders[i].label !== event.target.label) { - sliders[i].collapseSlider(); + this.openSlider(event.target.label); + } + } + + openSlider(label){ + for (var i = 0; i < this._slidersDomRefs.length; i++) { + if (this._slidersDomRefs[i].label !== label) { + this._slidersDomRefs[i].collapseSlider(); + } + } + } + + _onfocuscontainerin(e){ + if (e.target !== e.currentTarget){ + return; + } + let sliders = []; + if(this._slidersDomRefs.length){ + sliders = this._getPopover().default.length ? [...this._getPopover().default[0].children].filter(x => x.isUI5Element) : this._getPopover().default; + } else { + sliders = this._slidersDomRefs; + } + if (sliders[0]){ + sliders[0].focus(); + } + } + + _oncontainerkeydown(e){ + if (isLeft(e)){ + let expandedSliderIndex = 0; + for (let i = 0; i < this._slidersDomRefs.length; i++){ + if (this._slidersDomRefs[i]._expanded){ + expandedSliderIndex = i; + } + } + if (this._slidersDomRefs[expandedSliderIndex - 1]){ + this._slidersDomRefs[expandedSliderIndex - 1].focus(); + } else { + this._slidersDomRefs[this._slidersDomRefs.length - 1].focus(); + } + } else if (isRight(e)){ + let expandedSliderIndex = 0; + + for (let i = 0; i < this._slidersDomRefs.length; i++){ + if (this._slidersDomRefs[i]._expanded){ + expandedSliderIndex = i; } } + if (this._slidersDomRefs[expandedSliderIndex + 1]){ + this._slidersDomRefs[expandedSliderIndex + 1].focus(); + } else { + this._slidersDomRefs[0].focus(); + } + } + if (isTabNext(e)) { + this.shadowRoot.querySelector(".ui5-timepicker-footer").firstElementChild.focus(); + } else if (isTabPrevious(e)) { + this.shadowRoot.querySelector(`#${this._id}-inner`).focus(); } } @@ -452,7 +496,6 @@ class TimePicker extends UI5Element { return this._oDateFormat; } - setValue(value) { if (this.isValid(value)) { this.value = this.normalizeValue(value); @@ -518,6 +561,22 @@ class TimePicker extends UI5Element { get shouldBuildPeriodsSlider() { return this._getSlidersContained()[3]; } + + get hoursSliderTitle() { + return this.i18nBundle.getText(TIMEPICKER_HOURS_LABEL); + } + + get minutesSliderTitle() { + return this.i18nBundle.getText(TIMEPICKER_MINUTES_LABEL); + } + + get secondsSliderTitle() { + return this.i18nBundle.getText(TIMEPICKER_SECONDS_LABEL); + } + + get periodSliderTitle() { + return this.i18nBundle.getText(TIMEPICKER_PERIODS_LABEL); + } } TimePicker.define(); diff --git a/packages/main/src/i18n/messagebundle.properties b/packages/main/src/i18n/messagebundle.properties index a8be709d1e0f..aa684ee8558b 100644 --- a/packages/main/src/i18n/messagebundle.properties +++ b/packages/main/src/i18n/messagebundle.properties @@ -264,6 +264,18 @@ TEXTAREA_CHARACTERS_LEFT={0} characters remaining #XTXT: Text for characters over TEXTAREA_CHARACTERS_EXCEEDED={0} characters over limit +#XFLD: Timepicker slider header +TIMEPICKER_HOURS_LABEL=Hours + +#XFLD: Timepicker slider header +TIMEPICKER_MINUTES_LABEL=Minutes + +#XFLD: Timepicker slider header +TIMEPICKER_SECONDS_LABEL=Seconds + +#XFLD: Timepicker slider header +TIMEPICKER_PERIODS_LABEL=Period + #XACT: ARIA announcement for token deletable TOKEN_ARIA_DELETABLE=Deletable diff --git a/packages/main/src/themes/Slider.css b/packages/main/src/themes/Slider.css index 148b9a935302..c407418e9456 100644 --- a/packages/main/src/themes/Slider.css +++ b/packages/main/src/themes/Slider.css @@ -24,6 +24,11 @@ visibility: hidden; box-sizing: border-box; height: 1.5rem; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + outline: none } .ui5-slider[expanded] .ui5-slider-arrow { diff --git a/packages/main/src/themes/sap_fiori_3_dark/Slider-parameters.css b/packages/main/src/themes/sap_fiori_3_dark/Slider-parameters.css index e5156e73953c..3571ca67bac2 100644 --- a/packages/main/src/themes/sap_fiori_3_dark/Slider-parameters.css +++ b/packages/main/src/themes/sap_fiori_3_dark/Slider-parameters.css @@ -1,5 +1,4 @@ @import "../base/Slider-parameters.css"; -@import "../../../../theme-base/src/themes/sap_fiori_3_dark/base-parameters.less"; :root{ --_ui5_slider_item_background_color: var(--sapTimePickerItemColor); diff --git a/packages/main/test/pages/TimePicker.html b/packages/main/test/pages/TimePicker.html index 51d78b36c51b..6fa24ffda886 100644 --- a/packages/main/test/pages/TimePicker.html +++ b/packages/main/test/pages/TimePicker.html @@ -19,6 +19,6 @@ - + diff --git a/packages/main/test/specs/Slider.spec.js b/packages/main/test/specs/Slider.spec.js index 1d1995c85d20..1b75d962c8b5 100644 --- a/packages/main/test/specs/Slider.spec.js +++ b/packages/main/test/specs/Slider.spec.js @@ -1,6 +1,6 @@ const assert = require("chai").assert; -describe("Button general interaction", () => { +describe("Slider general interaction", () => { browser.url("http://localhost:8080/test-resources/pages/Slider_Test_Page.html"); it("tests slider's label rendering", () => { @@ -11,7 +11,6 @@ describe("Button general interaction", () => { it("Arrow down button is working", () => { const slider = browser.$("#slider"); - console.log(slider); const button = slider.shadow$$(".ui5-slider-arrow")[1]; button.click(); diff --git a/packages/main/test/specs/TimePicker.spec.js b/packages/main/test/specs/TimePicker.spec.js new file mode 100644 index 000000000000..c0718b6b6eaa --- /dev/null +++ b/packages/main/test/specs/TimePicker.spec.js @@ -0,0 +1,6 @@ +const assert = require("chai").assert; + +describe("TimePicker general interaction", () => { + browser.url("http://localhost:8080/test-resources/pages/TimePicker.html"); + +}); \ No newline at end of file From 4515cc2e179fdffe872812656f42f59dcd524ef6 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Wed, 4 Mar 2020 16:36:38 +0200 Subject: [PATCH 29/57] lint fixes --- packages/main/src/Slider.js | 65 +++++++++---------- packages/main/src/TimePicker.js | 108 +++++++++++++++----------------- 2 files changed, 84 insertions(+), 89 deletions(-) diff --git a/packages/main/src/Slider.js b/packages/main/src/Slider.js index 1e66f1f746bf..2960d121cd2e 100644 --- a/packages/main/src/Slider.js +++ b/packages/main/src/Slider.js @@ -64,7 +64,7 @@ const metadata = { _items: { type: Object, - } + }, }, slots: /** @lends sap.ui.webcomponents.main.Slider.prototype */ { @@ -86,7 +86,7 @@ const metadata = { valueSelect: { value: { type: String, - } + }, }, }, }; @@ -113,7 +113,7 @@ const metadata = { */ class Slider extends UI5Element { static get metadata() { - return metadata; + return metadata; } static get render() { @@ -143,28 +143,12 @@ class Slider extends UI5Element { } onAfterRendering() { - - this.shadowRoot.querySelector(".ui5-slider-wrapper").addEventListener("wheel", (e) => { - e.stopPropagation(); - e.preventDefault(); - - if (e.timeStamp === this._prevWheelTimestamp || !this._expanded) { - return; - } - - if (e.deltaY > 0){ - this._onArrowUp(e); - } else if (e.deltaY < 0) { - this._onArrowDown(e); - } - - this._prevWheelTimestamp = e.timeStamp; - }); + this.shadowRoot.querySelector(".ui5-slider-wrapper").addEventListener("wheel", this._handleWheel()); if (this._expanded) { const elements = this.shadowRoot.querySelectorAll(".ui5-slider-item"); - for (let i = 0; i < elements.length; i++){ - if (elements[i].textContent === this.value){ + for (let i = 0; i < elements.length; i++) { + if (elements[i].textContent === this.value) { this._selectElement(elements[i]); return true; } @@ -174,16 +158,33 @@ class Slider extends UI5Element { } } - get items() {; + get items() { return this._items; } + _handleWheel(e) { + e.stopPropagation(); + e.preventDefault(); + + if (e.timeStamp === this._prevWheelTimestamp || !this._expanded) { + return; + } + + if (e.deltaY > 0) { + this._onArrowUp(e); + } else if (e.deltaY < 0) { + this._onArrowDown(e); + } + + this._prevWheelTimestamp = e.timeStamp; + } + _onclick(e) { if (!e.target.classList.contains("ui5-slider-item")) { return; } - if(this._expanded) { + if (this._expanded) { this.value = e.target.textContent; this._selectElement(e.target); } else { @@ -201,7 +202,7 @@ class Slider extends UI5Element { this.fireEvent("collapse", {}); } - _selectElement(element) { + _selectElement(element) { if (element && this._items.indexOf(element.textContent) > -1) { this._currentElementIndex = this._items.indexOf(element.textContent); this._selectElementByIndex(this._currentElementIndex); @@ -210,9 +211,9 @@ class Slider extends UI5Element { _selectElementByIndex(index) { const sliderElement = this.shadowRoot.getElementById(`${this._id}--items-list`); - if ( index < this._items.length && index > - 1) { - let offsetSelectedElement = 4 * this._itemCellHeight - (index * this._itemCellHeight); - sliderElement.setAttribute("style",`top:${offsetSelectedElement}rem`); + if (index < this._items.length && index > -1) { + const offsetSelectedElement = 4 * this._itemCellHeight - (index * this._itemCellHeight); + sliderElement.setAttribute("style", `top:${offsetSelectedElement}rem`); this.value = this._items[index]; this._currentElementIndex = index; } @@ -231,11 +232,11 @@ class Slider extends UI5Element { } _onkeydown(event) { - if (!this._expanded){ + if (!this._expanded) { return; } - if (isTabPrevious(event) || isTabNext(event)){ + if (isTabPrevious(event) || isTabNext(event)) { event.preventDefault(); } @@ -248,12 +249,12 @@ class Slider extends UI5Element { } } - _onfocusin(e){ + _onfocusin(e) { e.preventDefault(); this.expandSlider(); } - _onfocusout(e){ + _onfocusout(e) { e.preventDefault(); this.collapseSlider(); } diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index edd01b9ab5f4..a491052b277e 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -1,15 +1,20 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; -import TimePickerTemplate from "./generated/templates/TimePickerTemplate.lit.js"; -import ResponsivePopover from "./ResponsivePopover.js"; +import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; +import { getLocale } from "@ui5/webcomponents-base/dist/LocaleProvider.js"; import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js"; -import PopoverPlacementType from "./types/PopoverPlacementType.js"; -import PopoverHorizontalAlign from "./types/PopoverHorizontalAlign.js"; import DateFormat from "@ui5/webcomponents-utils/dist/sap/ui/core/format/DateFormat.js"; import { fetchCldr } from "@ui5/webcomponents-base/dist/asset-registries/LocaleData.js"; -import { getLocale } from "@ui5/webcomponents-base/dist/LocaleProvider.js"; -import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; -import { TIMEPICKER_HOURS_LABEL, TIMEPICKER_MINUTES_LABEL, TIMEPICKER_SECONDS_LABEL, TIMEPICKER_PERIODS_LABEL } from "./generated/i18n/i18n-defaults.js"; +import PopoverHorizontalAlign from "./types/PopoverHorizontalAlign.js"; +import ResponsivePopover from "./ResponsivePopover.js"; +import PopoverPlacementType from "./types/PopoverPlacementType.js"; +import TimePickerTemplate from "./generated/templates/TimePickerTemplate.lit.js"; +import { + TIMEPICKER_HOURS_LABEL, + TIMEPICKER_MINUTES_LABEL, + TIMEPICKER_SECONDS_LABEL, + TIMEPICKER_PERIODS_LABEL, +} from "./generated/i18n/i18n-defaults.js"; import { isLeft, isRight, @@ -28,29 +33,15 @@ const metadata = { tag: "ui5-timepicker", properties: /** @lends sap.ui.webcomponents.main.TimePicker.prototype */ { /** - * Defines a formatted time value. - * - * @type {string} - * @defaultvalue "" - * @public - */ - value: { - type: String, - defaultValue: "" - }, - - /** - * Visualizes the validation state of the Web Component, for example - * Error, Warning and - * Success. + * Defines a formatted time value. * * @type {string} - * @defaultvalue "None" + * @defaultvalue "" * @public */ - valueState: { - type: ValueState, - defaultValue: ValueState.None, + value: { + type: String, + defaultValue: "", }, /** @@ -62,7 +53,7 @@ const metadata = { */ formatPattern: { type: String, - defaultValue: "HH:mm:ss" + defaultValue: "HH:mm:ss", }, /** @@ -140,7 +131,7 @@ const metadata = { isTwelveHoursFormat: { type: Boolean, - } + }, }, slots: /** @lends sap.ui.webcomponents.main.TimePicker.prototype */ { // @@ -216,13 +207,13 @@ class TimePicker extends UI5Element { afterClose: () => { this._isPickerOpen = false; this.closePicker(); - } + }, }; this._hoursParameters = { minHour: 0, maxHour: 0, - isTwelveHoursFormat: false + isTwelveHoursFormat: false, }; this._slidersDomRefs = []; @@ -236,9 +227,9 @@ class TimePicker extends UI5Element { } onAfterRendering() { - let slidersEnablementArray = this._getSlidersContained(this.formatPattern); + const slidersEnablementArray = this._getSlidersContained(this.formatPattern); this._slidersDomRefs = this._getPopover().default.length ? [...this._getPopover().default[0].children].filter(x => x.isUI5Element) : this._getPopover().default; - + for (let i = 0; i < this._slidersDomRefs.length; i++) { this._slidersDomRefs[i].disabled = !slidersEnablementArray[i]; } @@ -268,21 +259,21 @@ class TimePicker extends UI5Element { } setSlidersValue() { - let currentDate = this._getInput() ? this.getFormat().parse(this._getInput().getAttribute("value")) : null, + const currentDate = this._getInput() ? this.getFormat().parse(this._getInput().getAttribute("value")) : null, secondsSlider = this.shadowRoot.querySelector(".ui5-timepicker-seconds-slider"), minutesSlider = this.shadowRoot.querySelector(".ui5-timepicker-minutes-slider"), hoursSlider = this.shadowRoot.querySelector(".ui5-timepicker-hours-slider"), periodsSlider = this.shadowRoot.querySelector(".ui5-timepicker-period-slider"); if (currentDate) { - if (hoursSlider){ - if (this._hoursParameters.isTwelveHoursFormat && currentDate.getHours() > this._hoursParameters.maxHour){ + if (hoursSlider) { + if (this._hoursParameters.isTwelveHoursFormat && currentDate.getHours() > this._hoursParameters.maxHour) { hoursSlider.value = currentDate.getHours() - 12; } else if (this._hoursParameters.isTwelveHoursFormat && currentDate.getHours() < this._hoursParameters.minHour) { hoursSlider.value = currentDate.getHours() + 12; } else { hoursSlider.value = currentDate.getHours(); - } + } } if (minutesSlider) { minutesSlider.value = currentDate.getMinutes(); @@ -293,7 +284,7 @@ class TimePicker extends UI5Element { if (this._hoursParameters.isTwelveHoursFormat && periodsSlider && this._hoursParameters.minHour === 1) { periodsSlider.value = currentDate.getHours() > this._hoursParameters.maxHour ? "PM" : "AM"; } else if (this._hoursParameters.isTwelveHoursFormat && periodsSlider) { - periodsSlider.value = (currentDate.getHours() > this._hoursParameters.maxHour || currentDate.getHours() === this._hoursParameters.minHour)? "PM" : "AM"; + periodsSlider.value = (currentDate.getHours() > this._hoursParameters.maxHour || currentDate.getHours() === this._hoursParameters.minHour) ? "PM" : "AM"; } } } @@ -334,7 +325,7 @@ class TimePicker extends UI5Element { generateTimeItemsArray(x) { let array = [...Array(x).keys()]; - array = array.map(i => '' + i); + array = array.map(i => i.toString()); return array; } @@ -357,7 +348,7 @@ class TimePicker extends UI5Element { } if (this._hoursParameters.minHour === 1) { - hoursValueArray = hoursValueArray.map( x => (x * 1 + 1) + ""); + hoursValueArray = hoursValueArray.map(x => (x * 1 + 1).toString()); } return hoursValueArray; @@ -372,7 +363,7 @@ class TimePicker extends UI5Element { } submitPickers() { - let selectedDate = new Date(), + const selectedDate = new Date(), secondsSlider = this.shadowRoot.querySelector(".ui5-timepicker-seconds-slider"), minutesSlider = this.shadowRoot.querySelector(".ui5-timepicker-minutes-slider"), hoursSlider = this.shadowRoot.querySelector(".ui5-timepicker-hours-slider"), @@ -425,51 +416,51 @@ class TimePicker extends UI5Element { } } - openSlider(label){ - for (var i = 0; i < this._slidersDomRefs.length; i++) { + openSlider(label) { + for (let i = 0; i < this._slidersDomRefs.length; i++) { if (this._slidersDomRefs[i].label !== label) { this._slidersDomRefs[i].collapseSlider(); } } } - _onfocuscontainerin(e){ - if (e.target !== e.currentTarget){ + _onfocuscontainerin(e) { + if (e.target !== e.currentTarget) { return; } let sliders = []; - if(this._slidersDomRefs.length){ + if (this._slidersDomRefs.length) { sliders = this._getPopover().default.length ? [...this._getPopover().default[0].children].filter(x => x.isUI5Element) : this._getPopover().default; } else { sliders = this._slidersDomRefs; - } - if (sliders[0]){ + } + if (sliders[0]) { sliders[0].focus(); } } - _oncontainerkeydown(e){ - if (isLeft(e)){ + _oncontainerkeydown(e) { + if (isLeft(e)) { let expandedSliderIndex = 0; - for (let i = 0; i < this._slidersDomRefs.length; i++){ - if (this._slidersDomRefs[i]._expanded){ + for (let i = 0; i < this._slidersDomRefs.length; i++) { + if (this._slidersDomRefs[i]._expanded) { expandedSliderIndex = i; } } - if (this._slidersDomRefs[expandedSliderIndex - 1]){ + if (this._slidersDomRefs[expandedSliderIndex - 1]) { this._slidersDomRefs[expandedSliderIndex - 1].focus(); } else { this._slidersDomRefs[this._slidersDomRefs.length - 1].focus(); } - } else if (isRight(e)){ + } else if (isRight(e)) { let expandedSliderIndex = 0; - for (let i = 0; i < this._slidersDomRefs.length; i++){ - if (this._slidersDomRefs[i]._expanded){ + for (let i = 0; i < this._slidersDomRefs.length; i++) { + if (this._slidersDomRefs[i]._expanded) { expandedSliderIndex = i; } } - if (this._slidersDomRefs[expandedSliderIndex + 1]){ + if (this._slidersDomRefs[expandedSliderIndex + 1]) { this._slidersDomRefs[expandedSliderIndex + 1].focus(); } else { this._slidersDomRefs[0].focus(); @@ -508,7 +499,7 @@ class TimePicker extends UI5Element { const formatArray = this.getFormat().aFormatArray, slidersBuildArray = [false, false, false, false]; // hours minutes seconds am/pm - for (var i = 0; i < formatArray.length; i++) { + for (let i = 0; i < formatArray.length; i++) { if (this._hoursParameters.maxHour !== 0) { slidersBuildArray[0] = true; } @@ -552,12 +543,15 @@ class TimePicker extends UI5Element { get shouldBuildHoursSlider() { return this._getSlidersContained()[0]; } + get shouldBuildMinutesSlider() { return this._getSlidersContained()[1]; } + get shouldBuildSecondsSlider() { return this._getSlidersContained()[2]; } + get shouldBuildPeriodsSlider() { return this._getSlidersContained()[3]; } From 3a274514b2b6c77af83fb3fd70731e9cfcf49317 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Wed, 4 Mar 2020 16:37:34 +0200 Subject: [PATCH 30/57] removed redundant comments --- .../base/src/delegate/ScrollEnablement.js | 49 ------------------- 1 file changed, 49 deletions(-) diff --git a/packages/base/src/delegate/ScrollEnablement.js b/packages/base/src/delegate/ScrollEnablement.js index 4714a1092e21..8c24815ce5f4 100644 --- a/packages/base/src/delegate/ScrollEnablement.js +++ b/packages/base/src/delegate/ScrollEnablement.js @@ -101,55 +101,6 @@ class ScrollEnablement extends EventProvider { this._prevDragX = dragX; this._prevDragY = dragY; } - - // scrollToElement (element, animationTime, offsets) { - // aOffset = aOffset || [0, 0]; - - // // do nothing if _$Container is not a (grand)parent of oElement - // if (!this._container[0].contains(oElement) || - // oElement.style.display === "none" || - // oElement.offsetParent.nodeName.toUpperCase() === "HTML") { - // return this; - // } - - // var $Element = jQuery(oElement), - // oScrollPosition = this.getChildPosition($Element), - // iLeftScroll = this.getScrollLeft() + oScrollPosition.left + aOffset[0], - // iTopScroll = this.getScrollTop() + oScrollPosition.top + aOffset[1]; - - // if (this._bFlipX) { - // // in IE RTL scrollLeft goes opposite direction - // iLeftScroll = this.getScrollLeft() - (oScrollPosition.left - this._container.width()) - $Element.width(); - // } - - // // scroll to destination - // this._scrollTo(iLeftScroll, iTopScroll , animationTime); - - // return this; - // } - - - // _scrollTo(x, y, animationTime) { - // if (this._container.length > 0) { - // if (time > 0) { - // this._container.finish().animate({ scrollTop: y, scrollLeft: x }, animationTime, jQuery.proxy(this._readActualScrollPosition, this)); - // } else { - // this._container.scrollTop(y); - // this._container.scrollLeft(x); - // this._readActualScrollPosition(); // if container is too large no scrolling is possible - // } - // } - // } - - // _readActualScrollPosition() { - // // if container has a size, this method reads the current scroll position and stores it as desired position - // if (this._container.width() > 0) { - // this._scrollX = this._container.scrollLeft(); - // } - // if (this._container.height() > 0) { - // this._scrollY = this._container.scrollTop(); - // } - // } } export default ScrollEnablement; From d73d28babc371fbe1866af2191b00d4aed2b6de4 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Wed, 4 Mar 2020 17:12:44 +0200 Subject: [PATCH 31/57] fixed wheel handler --- packages/main/src/Slider.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/main/src/Slider.js b/packages/main/src/Slider.js index 2960d121cd2e..7f21057e3d55 100644 --- a/packages/main/src/Slider.js +++ b/packages/main/src/Slider.js @@ -143,7 +143,9 @@ class Slider extends UI5Element { } onAfterRendering() { - this.shadowRoot.querySelector(".ui5-slider-wrapper").addEventListener("wheel", this._handleWheel()); + this.shadowRoot.querySelector(".ui5-slider-wrapper").addEventListener("wheel", e => { + this._handleWheel(e); + }); if (this._expanded) { const elements = this.shadowRoot.querySelectorAll(".ui5-slider-item"); @@ -163,6 +165,10 @@ class Slider extends UI5Element { } _handleWheel(e) { + if (!e){ + return; + } + e.stopPropagation(); e.preventDefault(); From 8fc1227069e0d05901d1d778293ae2a80cbe03f7 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Thu, 5 Mar 2020 10:54:11 +0200 Subject: [PATCH 32/57] Slider before test fix --- packages/main/test/specs/Slider.spec.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/main/test/specs/Slider.spec.js b/packages/main/test/specs/Slider.spec.js index 1b75d962c8b5..be13e2d6c460 100644 --- a/packages/main/test/specs/Slider.spec.js +++ b/packages/main/test/specs/Slider.spec.js @@ -3,6 +3,12 @@ const assert = require("chai").assert; describe("Slider general interaction", () => { browser.url("http://localhost:8080/test-resources/pages/Slider_Test_Page.html"); + before(() => { + browser.$("#slider").setProperty("_items",["1","2","3","4","5","6","7"]); + browser.$("#slider").setProperty("value","1"); + browser.$("#slider").setProperty("_expanded",true); + }); + it("tests slider's label rendering", () => { const textValue = browser.$("#slider").shadow$$(".ui5-slider-label")[0].getText(); @@ -19,6 +25,7 @@ describe("Slider general interaction", () => { it("Arrow up button is working", () => { const slider = browser.$("#slider"); + const button = slider.shadow$$(".ui5-slider-arrow")[0]; button.click(); From e57d15dfc9b85ff529088e7173f8ac4266945fed Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Thu, 5 Mar 2020 14:33:09 +0200 Subject: [PATCH 33/57] Added tests for timepicker and value state change --- packages/main/src/TimePicker.js | 3 +- packages/main/test/specs/TimePicker.spec.js | 40 +++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index a491052b277e..d21c912ba957 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -245,7 +245,7 @@ class TimePicker extends UI5Element { nextValue = this.normalizeValue(nextValue); } - this.value = nextValue; + this.setValue(nextValue); this.fireEvent("change", { value: nextValue, valid: isValid }); this.fireEvent("value-changed", { value: nextValue, valid: isValid }); } @@ -490,6 +490,7 @@ class TimePicker extends UI5Element { setValue(value) { if (this.isValid(value)) { this.value = this.normalizeValue(value); + this.valueState = ValueState.None; } else { this.valueState = ValueState.Error; } diff --git a/packages/main/test/specs/TimePicker.spec.js b/packages/main/test/specs/TimePicker.spec.js index c0718b6b6eaa..a9ca97287f73 100644 --- a/packages/main/test/specs/TimePicker.spec.js +++ b/packages/main/test/specs/TimePicker.spec.js @@ -3,4 +3,44 @@ const assert = require("chai").assert; describe("TimePicker general interaction", () => { browser.url("http://localhost:8080/test-resources/pages/TimePicker.html"); + it("Is default value today", () => { + const textValue = browser.$("#timepicker").shadow$$("#__ui5Timepicker1-inner")[0].getValue(); + const today = new Date(); + + assert.strictEqual(Number(textValue.substring(0,2)), today.getHours(), "Hours are equal"); + assert.strictEqual(Number(textValue.substring(3,5)), today.getMinutes(), "Minutes are equal"); + }); + + it("Check sliders value", () => { + browser.$("#timepicker").setProperty("value","11:12:13"); + const hoursSliderValue = browser.$("#timepicker").shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-hours-slider").getValue(); + const minutesSliderValue = browser.$("#timepicker").shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-minutes-slider").getValue(); + const secondsSliderValue = browser.$("#timepicker").shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-seconds-slider").getValue(); + + assert.strictEqual(hoursSliderValue, "11", "Hours are equal"); + assert.strictEqual(minutesSliderValue, "12", "Minutes are equal"); + assert.strictEqual(secondsSliderValue, "13", "Minutes are equal"); + }); + + it("Sliders submit value", () => { + browser.$("#timepicker").shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-hours-slider").setProperty("value","14"); + browser.$("#timepicker").shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-minutes-slider").setProperty("value","15"); + browser.$("#timepicker").shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-seconds-slider").setProperty("value","16"); + + browser.$("#timepicker").shadow$$(".ui5-timepicker-popover")[0].setProperty("opened",true); + browser.$("#timepicker").shadow$$(".ui5-timepicker-popover")[0].$("#submit").click(); + + const textValue = browser.$("#timepicker").shadow$$("#__ui5Timepicker1-inner")[0].getValue(); + + assert.strictEqual(textValue.substring(0,2), "14", "Hours are equal"); + assert.strictEqual(textValue.substring(3,5), "15", "Minutes are equal"); + }); + + it("Wrong value submit", () => { + browser.$("#timepicker").click(); + browser.$("#timepicker").keys("123123123"); + browser.$("#timepicker").keys("Enter"); + + assert.strictEqual(browser.$("#timepicker").shadow$("ui5-input").getProperty("valueState"), "Error", "The value state is on error"); + }); }); \ No newline at end of file From a6843a5a87508130f4248f16d7ed2aba49e4025b Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Fri, 6 Mar 2020 17:05:05 +0200 Subject: [PATCH 34/57] Comments fixed and playground sample added --- packages/main/src/Slider.hbs | 6 +- packages/main/src/Slider.js | 13 +-- packages/main/src/TimePicker.hbs | 3 +- packages/main/src/TimePicker.js | 99 +++++++++++++++---- packages/main/src/themes/Slider.css | 32 +++--- packages/main/src/themes/TimePicker.css | 23 ++++- .../src/themes/base/Slider-parameters.css | 1 + .../main/src/themes/base/sizes-parameters.css | 2 + .../themes/sap_belize/Slider-parameters.css | 1 - .../sap_belize_hcb/Slider-parameters.css | 1 - .../themes/sap_fiori_3/Slider-parameters.css | 1 - .../main/test/samples/TimePicker.sample.html | 39 ++++++++ 12 files changed, 164 insertions(+), 57 deletions(-) create mode 100644 packages/main/test/samples/TimePicker.sample.html diff --git a/packages/main/src/Slider.hbs b/packages/main/src/Slider.hbs index 9b3a5ea02a2d..37424d6b2857 100644 --- a/packages/main/src/Slider.hbs +++ b/packages/main/src/Slider.hbs @@ -15,12 +15,12 @@
{{label}}
- +
-
+
{{#if _expanded}}
    {{#each items}} @@ -34,5 +34,5 @@ {{/if}}
- +
\ No newline at end of file diff --git a/packages/main/src/Slider.js b/packages/main/src/Slider.js index 7f21057e3d55..affe04df08ef 100644 --- a/packages/main/src/Slider.js +++ b/packages/main/src/Slider.js @@ -1,6 +1,7 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import SliderTemplate from "./generated/templates/SliderTemplate.lit.js"; +import Button from "./Button.js"; import { isDown, isUp, @@ -142,11 +143,11 @@ class Slider extends UI5Element { this._itemCellHeight = this.shadowRoot.querySelectorAll(".ui5-slider-item").length && Number(getComputedStyle(this.shadowRoot.querySelector(".ui5-slider-item")).getPropertyValue("--_ui5_slider_item_height").replace("rem", "")); } - onAfterRendering() { - this.shadowRoot.querySelector(".ui5-slider-wrapper").addEventListener("wheel", e => { - this._handleWheel(e); - }); + static async onDefine() { + await Button.define(); + } + onAfterRendering() { if (this._expanded) { const elements = this.shadowRoot.querySelectorAll(".ui5-slider-item"); for (let i = 0; i < elements.length; i++) { @@ -161,11 +162,11 @@ class Slider extends UI5Element { } get items() { - return this._items; + return this._items || []; } _handleWheel(e) { - if (!e){ + if (!e) { return; } diff --git a/packages/main/src/TimePicker.hbs b/packages/main/src/TimePicker.hbs index a4e53b57068f..a23d153652f4 100644 --- a/packages/main/src/TimePicker.hbs +++ b/packages/main/src/TimePicker.hbs @@ -1,4 +1,4 @@ -
+
11:42:35 + * hh:mm:ss a -> 2:23:15 PM + * mm:ss -> 12:04 (only minutes and seconds) + * * @type {string} * @defaultvalue "" * @public @@ -71,23 +76,7 @@ const metadata = { }, /** - * Defines a short hint, intended to aid the user with data entry when the - * ui5-datepicker has no value. - * - * Note: When no placeholder is set, the format pattern is displayed as a placeholder. - * Passing an empty string as the value of this property will make the ui5-time-picker appear empty - without placeholder or format pattern. - * - * @type {string} - * @defaultvalue undefined - * @public - */ - placeholder: { - type: String, - defaultValue: undefined, - }, - - /** - * Determines whether the ui5-datepicker is displayed as disabled. + * Determines whether the ui5-timepicker is displayed as disabled. * * @type {boolean} * @defaultvalue false @@ -98,7 +87,7 @@ const metadata = { }, /** - * Determines whether the ui5-datepicker is displayed as readonly. + * Determines whether the ui5-timepicker is displayed as readonly. * * @type {boolean} * @defaultvalue false @@ -137,7 +126,20 @@ const metadata = { // }, events: /** @lends sap.ui.webcomponents.main.TimePicker.prototype */ { - // + /** + * Fired when the input operation has finished by pressing Enter or on focusout. + * + * @event + * @public + */ + change: {}, + /** + * Fired when the value of the ui5-timepicker is changed at each key stroke. + * + * @event + * @public + */ + input: {}, }, }; @@ -145,11 +147,33 @@ const metadata = { * @class * *

Overview

- * + * The ui5-timepicker component provides an input field with assigned sliders which opens on user action. + * The ui5-timepicker allows users to select a localized time using touch, + * mouse, or keyboard input. It consists of two parts: the time input field and the + * sliders. * *

Usage

- * + * The user can enter a time by: + *
    + *
  • Using the sliders that opens in a popup
  • + *
  • Typing it in directly in the input field
  • + *
+ *

+ * When the user makes an entry and chooses the enter key, the sliders shows the corresponding time. + * When the user directly triggers the sliders display, the actual time is displayed. * For the ui5-timepicker + * + *

Formatting

+ * + * If a time is entered by typing it into + * the input field, it must fit to the used time format. + *

+ * Supported format options are pattern-based on Unicode LDML Date Format notation. + * For more information, see UTS #35: Unicode Locale Data Markup Language. + *

+ * For example, if the format-pattern is "HH:mm:ss", + * a valid value string is "11:42:35" and the same is displayed in the input. + * *

ES6 Module Import

* * import @ui5/webcomponents/dist/TimePicker.js"; @@ -289,6 +313,10 @@ class TimePicker extends UI5Element { } } + /** + * Closes the picker + * @public + */ closePicker() { this._getPopover().close(); @@ -297,6 +325,13 @@ class TimePicker extends UI5Element { } } + /** + * Opens the picker. + * @param {object} options A JSON object with additional configuration.
+ * { focusInput: true } By default, the focus goes in the picker after opening it. + * Specify this option to focus the input field. + * @public + */ openPicker() { this._getPopover().open(this); this._isPickerOpen = true; @@ -310,6 +345,11 @@ class TimePicker extends UI5Element { } } + /** + * Checks if a value is valid against the current date format of the DatePicker + * @param {string} value A value to be tested against the current date format + * @public + */ isOpen() { return !!this._isPickerOpen; } @@ -383,9 +423,15 @@ class TimePicker extends UI5Element { this.setValue(this.getFormat().format(selectedDate)); + this.fireEvent("change", { value: this.value, valid: true }); + this.closePicker(); } + /** + * Opens the picker. + * @public + */ isValid(value = "") { return !!(value && this.getFormat().parse(value)); } @@ -541,6 +587,17 @@ class TimePicker extends UI5Element { } } + /** + * Currently selected date represented as JavaScript Date instance + * + * @readonly + * @type { Date } + * @public + */ + get dateValue() { + return this.getFormat().parse(this.value); + } + get shouldBuildHoursSlider() { return this._getSlidersContained()[0]; } diff --git a/packages/main/src/themes/Slider.css b/packages/main/src/themes/Slider.css index c407418e9456..bca89cd97193 100644 --- a/packages/main/src/themes/Slider.css +++ b/packages/main/src/themes/Slider.css @@ -6,27 +6,24 @@ box-sizing: border-box; font-family: var(--sapFontFamily); justify-content: space-between; - flex-direction: column; - display: inline-flex; + flex-direction: column; + display: inline-flex; } .ui5-slider .ui5-slider-label { box-sizing: border-box; - height: 2rem; - line-height: 2rem; - width: var(--_ui5_slider_item_width); - font-size: var(--_ui5_slider_label_text_size); - color: var(--_ui5_slider_label_text_color); - text-align: center; - vertical-align: middle; + height: 2rem; + line-height: 2rem; + width: var(--_ui5_slider_item_width); + font-size: var(--_ui5_slider_label_text_size); + color: var(--_ui5_slider_label_text_color); + text-align: center; + vertical-align: middle; } .ui5-slider .ui5-slider-arrow { visibility: hidden; box-sizing: border-box; height: 1.5rem; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; user-select: none; outline: none } @@ -43,9 +40,6 @@ overflow: hidden; height: 100%; box-sizing: border-box; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; user-select: none; list-style: none; margin-top: 0rem; @@ -100,7 +94,7 @@ } .ui5-slider .ui5-slider-inner .ui5-slider-wrapper { - height: 27rem; + height: var(--_ui5_slider_height); position: relative; overflow: hidden; outline: none; @@ -111,8 +105,8 @@ cursor: default; margin: 0; justify-content: space-between; - flex-direction: column; - display: inline-flex; + flex-direction: column; + display: inline-flex; } .ui5-slider[expanded] .ui5-slider-label { @@ -121,7 +115,7 @@ .ui5-slider .ui5-slider-inner { max-height: 100%; - height: 27rem; + height: var(--_ui5_slider_height); } .ui5-slider[expanded] .ui5-slider-inner .ui5-slider-item { diff --git a/packages/main/src/themes/TimePicker.css b/packages/main/src/themes/TimePicker.css index d9d8625d8d05..57e145e2b1e0 100644 --- a/packages/main/src/themes/TimePicker.css +++ b/packages/main/src/themes/TimePicker.css @@ -1,20 +1,35 @@ -.ui5-timepicker{ +:host(:not([hidden])) { display: inline-block; } -.ui5-timepicker-sliders-container{ +.ui5-timepicker-sliders-container { display: flex; justify-content: center; align-items: stretch; } -.ui5-timepicker-footer{ +.ui5-timepicker-footer { height: fit-content; display: flex; justify-content: flex-end; width: 100%; } -.ui5-timepicker-footer *{ +.ui5-timepicker-footer * { margin: 1%; +} + +.ui5-timepicker-input-icon-button:hover { + cursor: pointer; + background: var(--sapButton_Hover_Background); +} + +.ui5-timepicker-input-icon-button:active { + background-color: var(--sapButton_Active_Background); + color: var(--sapButton_Active_TextColor); +} + +.ui5-timepicker-input-icon-button[pressed] { + background-color: var(--sapButton_Active_Background); + color: var(--sapButton_Active_TextColor); } \ No newline at end of file diff --git a/packages/main/src/themes/base/Slider-parameters.css b/packages/main/src/themes/base/Slider-parameters.css index 7e01ce2878bd..a7f4ad2af50b 100644 --- a/packages/main/src/themes/base/Slider-parameters.css +++ b/packages/main/src/themes/base/Slider-parameters.css @@ -3,4 +3,5 @@ --_ui5_slider_label_text_size: .75rem; --_ui5_slider_selection_frame_margin_top: calc(var(--_ui5_slider_item_height) * 4); --_ui5_slider_label_text_color: var(--sapContent_LabelColor); + --_ui5_slider_height: 27rem; } \ No newline at end of file diff --git a/packages/main/src/themes/base/sizes-parameters.css b/packages/main/src/themes/base/sizes-parameters.css index 60e5b02527b4..0c2b12c7ae33 100644 --- a/packages/main/src/themes/base/sizes-parameters.css +++ b/packages/main/src/themes/base/sizes-parameters.css @@ -137,6 +137,8 @@ --_ui5_slider_item_width: 4rem; --_ui5_slider_item_height: 2rem; + --_ui5_slider_height: 22rem; + --_ui5_slider_selection_frame_margin_top: calc(var(--_ui5_slider_item_height) * 4); --_ui5_switch_height: var(--_ui5_switch_compact_height); --_ui5_switch_width: var(--_ui5_switch_compact_width); diff --git a/packages/main/src/themes/sap_belize/Slider-parameters.css b/packages/main/src/themes/sap_belize/Slider-parameters.css index be6cf53db2c4..a15c47115f54 100644 --- a/packages/main/src/themes/sap_belize/Slider-parameters.css +++ b/packages/main/src/themes/sap_belize/Slider-parameters.css @@ -1,5 +1,4 @@ @import "../base/Slider-parameters.css"; -@import "../../../../theme-base/src/themes/sap_belize/base-parameters.less"; :root{ --_ui5_slider_item_background_color: var(--sapTimePickerItemColor); diff --git a/packages/main/src/themes/sap_belize_hcb/Slider-parameters.css b/packages/main/src/themes/sap_belize_hcb/Slider-parameters.css index 006bc4235a3a..a0f57fbe2712 100644 --- a/packages/main/src/themes/sap_belize_hcb/Slider-parameters.css +++ b/packages/main/src/themes/sap_belize_hcb/Slider-parameters.css @@ -1,5 +1,4 @@ @import "../base/Slider-parameters.css"; -@import "../../../../theme-base/src/themes/sap_belize/base-parameters.less"; :root{ --_ui5_slider_item_background_color: var(--sapList_Background); diff --git a/packages/main/src/themes/sap_fiori_3/Slider-parameters.css b/packages/main/src/themes/sap_fiori_3/Slider-parameters.css index 909c777f48e3..498d42d69051 100644 --- a/packages/main/src/themes/sap_fiori_3/Slider-parameters.css +++ b/packages/main/src/themes/sap_fiori_3/Slider-parameters.css @@ -1,5 +1,4 @@ @import "../base/Slider-parameters.css"; -@import "../../../../theme-base/src/themes/sap_fiori_3/base-parameters.less"; :root{ --_ui5_slider_item_background_color: var(--sapTimePickerItemColor); diff --git a/packages/main/test/samples/TimePicker.sample.html b/packages/main/test/samples/TimePicker.sample.html new file mode 100644 index 000000000000..0566dc217311 --- /dev/null +++ b/packages/main/test/samples/TimePicker.sample.html @@ -0,0 +1,39 @@ +
+

TimePicker

+
+ +
@ui5/webcomponents
+ +
<ui5-timepicker>
+ +
+

Basic TimePicker

+
+ +
+
{% highlight html %}
+	
+{% endhighlight %}
+
+ +
+

TimePicker in twelve hours format

+
+ +
+
{% highlight html %}
+		
+	{% endhighlight %}
+
+ +
+

TimePicker with only minutes and seconds

+
+ +
+
{% highlight html %}
+		
+	{% endhighlight %}
+
+ + From 35a865582573a6d266bc8bc77a00efa5a7648153 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Mon, 9 Mar 2020 09:29:28 +0200 Subject: [PATCH 35/57] Fixed periods cldr and default time format --- packages/main/src/TimePicker.js | 14 +++++++++----- packages/main/src/i18n/messagebundle.properties | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index e5257a200e88..1a43bbec4a5e 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -4,6 +4,7 @@ import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18 import { getLocale } from "@ui5/webcomponents-base/dist/LocaleProvider.js"; import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js"; import DateFormat from "@ui5/webcomponents-utils/dist/sap/ui/core/format/DateFormat.js"; +import LocaleData from "@ui5/webcomponents-utils/dist/sap/ui/core/LocaleData.js"; import { fetchCldr } from "@ui5/webcomponents-base/dist/asset-registries/LocaleData.js"; import PopoverHorizontalAlign from "./types/PopoverHorizontalAlign.js"; import ResponsivePopover from "./ResponsivePopover.js"; @@ -58,7 +59,6 @@ const metadata = { */ formatPattern: { type: String, - defaultValue: "HH:mm:ss", }, /** @@ -241,6 +241,10 @@ class TimePicker extends UI5Element { }; this._slidersDomRefs = []; + + if (!this.formatPattern) { + this.formatPattern = LocaleData.getInstance(getLocale()).getTimePattern(this.getFormat().oFormatOptions.style); + } } onBeforeRendering() { @@ -306,9 +310,9 @@ class TimePicker extends UI5Element { secondsSlider.value = currentDate.getSeconds(); } if (this._hoursParameters.isTwelveHoursFormat && periodsSlider && this._hoursParameters.minHour === 1) { - periodsSlider.value = currentDate.getHours() > this._hoursParameters.maxHour ? "PM" : "AM"; + periodsSlider.value = currentDate.getHours() > this._hoursParameters.maxHour ? this.periodsArray[1] : this.periodsArray[0]; } else if (this._hoursParameters.isTwelveHoursFormat && periodsSlider) { - periodsSlider.value = (currentDate.getHours() > this._hoursParameters.maxHour || currentDate.getHours() === this._hoursParameters.minHour) ? "PM" : "AM"; + periodsSlider.value = (currentDate.getHours() > this._hoursParameters.maxHour || currentDate.getHours() === this._hoursParameters.minHour) ? this.periodsArray[1] : this.periodsArray[0]; } } } @@ -411,9 +415,9 @@ class TimePicker extends UI5Element { hours = hoursSlider ? hoursSlider.getAttribute("value") : this._hoursParameters.minHour.toString(), minutes = minutesSlider ? minutesSlider.getAttribute("value") : "0", seconds = secondsSlider ? secondsSlider.getAttribute("value") : "0", - period = periodsSlider ? periodsSlider.getAttribute("value") : "AM"; + period = periodsSlider ? periodsSlider.getAttribute("value") : this.periodsArray[0]; - if (period === "PM") { + if (period === this.periodsArray[1]) { selectedDate.setHours(hours * 1 + 12); } else { selectedDate.setHours(hours); diff --git a/packages/main/src/i18n/messagebundle.properties b/packages/main/src/i18n/messagebundle.properties index aa684ee8558b..e7d4328c277c 100644 --- a/packages/main/src/i18n/messagebundle.properties +++ b/packages/main/src/i18n/messagebundle.properties @@ -274,7 +274,7 @@ TIMEPICKER_MINUTES_LABEL=Minutes TIMEPICKER_SECONDS_LABEL=Seconds #XFLD: Timepicker slider header -TIMEPICKER_PERIODS_LABEL=Period +TIMEPICKER_PERIODS_LABEL=AM/PM #XACT: ARIA announcement for token deletable TOKEN_ARIA_DELETABLE=Deletable From 7c9af874044a4cfba5ecd3cb840966d941c5b0f6 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Mon, 9 Mar 2020 09:44:33 +0200 Subject: [PATCH 36/57] parameters changed in css base for slider --- packages/theme-base/src/themes/sap_fiori_3/base-parameters.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/theme-base/src/themes/sap_fiori_3/base-parameters.less b/packages/theme-base/src/themes/sap_fiori_3/base-parameters.less index a24aae51694d..a5b10a9597a4 100644 --- a/packages/theme-base/src/themes/sap_fiori_3/base-parameters.less +++ b/packages/theme-base/src/themes/sap_fiori_3/base-parameters.less @@ -262,6 +262,6 @@ @sapTimePicker_ItemBorderColor: @sapList_Background; -@sapTimePicker_ItemColor: darken(@sapList_Background, 3); +@sapTimePicker_ItemColor: @sapList_Background_Darken3; @sapTimePicker_ItemHoverColor: darken(@sapList_Background, 6); @sapTimePicker_SelectedItemHoverColor: darken(@sapSelectedColor, 10); \ No newline at end of file From 4429a6ceff39ba766d365ad0aa13092bce90b442 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Mon, 9 Mar 2020 13:03:21 +0200 Subject: [PATCH 37/57] change name from slider to wheelslider --- packages/main/bundle.esm.js | 3 +- packages/main/src/Slider.hbs | 38 ------------ packages/main/src/TimePicker.hbs | 16 ++--- packages/main/src/TimePicker.js | 18 +++--- packages/main/src/WheelSlider.hbs | 38 ++++++++++++ .../main/src/{Slider.js => WheelSlider.js} | 48 +++++++-------- .../themes/{Slider.css => WheelSlider.css} | 48 +++++++-------- .../src/themes/base/Slider-parameters.css | 7 --- .../themes/base/WheelSlider-parameters.css | 7 +++ .../main/src/themes/base/sizes-parameters.css | 8 +-- .../themes/sap_belize/Slider-parameters.css | 17 ------ .../sap_belize/WheelSlider-parameters.css | 17 ++++++ .../themes/sap_belize/parameters-bundle.css | 2 +- .../sap_belize_hcb/Slider-parameters.css | 17 ------ .../sap_belize_hcb/WheelSlider-parameters.css | 17 ++++++ .../sap_belize_hcb/parameters-bundle.css | 2 +- .../themes/sap_fiori_3/Slider-parameters.css | 17 ------ .../sap_fiori_3/WheelSlider-parameters.css | 17 ++++++ .../themes/sap_fiori_3/parameters-bundle.css | 2 +- .../sap_fiori_3_dark/Slider-parameters.css | 17 ------ .../WheelSlider-parameters.css | 17 ++++++ .../sap_fiori_3_dark/parameters-bundle.css | 2 +- ...t_Page.html => WheelSlider_Test_Page.html} | 2 +- packages/main/test/specs/Slider.spec.js | 60 ------------------- packages/main/test/specs/TimePicker.spec.js | 12 ++-- packages/main/test/specs/WheelSlider.spec.js | 60 +++++++++++++++++++ 26 files changed, 255 insertions(+), 254 deletions(-) delete mode 100644 packages/main/src/Slider.hbs create mode 100644 packages/main/src/WheelSlider.hbs rename packages/main/src/{Slider.js => WheelSlider.js} (75%) rename packages/main/src/themes/{Slider.css => WheelSlider.css} (66%) delete mode 100644 packages/main/src/themes/base/Slider-parameters.css create mode 100644 packages/main/src/themes/base/WheelSlider-parameters.css delete mode 100644 packages/main/src/themes/sap_belize/Slider-parameters.css create mode 100644 packages/main/src/themes/sap_belize/WheelSlider-parameters.css delete mode 100644 packages/main/src/themes/sap_belize_hcb/Slider-parameters.css create mode 100644 packages/main/src/themes/sap_belize_hcb/WheelSlider-parameters.css delete mode 100644 packages/main/src/themes/sap_fiori_3/Slider-parameters.css create mode 100644 packages/main/src/themes/sap_fiori_3/WheelSlider-parameters.css delete mode 100644 packages/main/src/themes/sap_fiori_3_dark/Slider-parameters.css create mode 100644 packages/main/src/themes/sap_fiori_3_dark/WheelSlider-parameters.css rename packages/main/test/pages/{Slider_Test_Page.html => WheelSlider_Test_Page.html} (89%) delete mode 100644 packages/main/test/specs/Slider.spec.js create mode 100644 packages/main/test/specs/WheelSlider.spec.js diff --git a/packages/main/bundle.esm.js b/packages/main/bundle.esm.js index ed537f41301b..9e36ee8b6159 100644 --- a/packages/main/bundle.esm.js +++ b/packages/main/bundle.esm.js @@ -45,7 +45,6 @@ import ResponsivePopover from "./dist/ResponsivePopover.js"; import SegmentedButton from "./dist/SegmentedButton.js"; import Select from "./dist/Select.js"; import Option from "./dist/Option.js"; -import Slider from "./dist/Slider.js" import Switch from "./dist/Switch.js"; import MessageStrip from "./dist/MessageStrip.js"; import MultiComboBox from "./dist/MultiComboBox.js"; @@ -63,6 +62,8 @@ import TimePicker from "./dist/TimePicker.js"; import Title from "./dist/Title.js"; import Toast from "./dist/Toast.js"; import ToggleButton from "./dist/ToggleButton.js"; +import WheelSlider from "./dist/WheelSlider.js" + import List from "./dist/List.js"; diff --git a/packages/main/src/Slider.hbs b/packages/main/src/Slider.hbs deleted file mode 100644 index 37424d6b2857..000000000000 --- a/packages/main/src/Slider.hbs +++ /dev/null @@ -1,38 +0,0 @@ -
-
-
{{label}}
-
- -
-
-
-
-
- {{#if _expanded}} -
    - {{#each items}} -
  • {{this}}
  • - {{/each}} -
- {{else}} -
    -
  • {{value}}
  • -
- {{/if}} -
-
- -
\ No newline at end of file diff --git a/packages/main/src/TimePicker.hbs b/packages/main/src/TimePicker.hbs index a23d153652f4..ba2cffc29047 100644 --- a/packages/main/src/TimePicker.hbs +++ b/packages/main/src/TimePicker.hbs @@ -33,37 +33,37 @@ >
{{#if shouldBuildHoursSlider}} - + > {{/if}} {{#if shouldBuildMinutesSlider}} - + > {{/if}} {{#if shouldBuildSecondsSlider}} - + > {{/if}} {{#if shouldBuildPeriodsSlider}} - + > {{/if}}
diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index 5f7403342520..54978daa5ea9 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -1,7 +1,7 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; -import getLocale from "@ui5/webcomponents-base/dist/locale/getLocale.js"; +import { getLocale } from "@ui5/webcomponents-base/dist/LocaleProvider.js"; import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js"; import DateFormat from "@ui5/webcomponents-utils/dist/sap/ui/core/format/DateFormat.js"; import LocaleData from "@ui5/webcomponents-utils/dist/sap/ui/core/LocaleData.js"; diff --git a/packages/main/src/WheelSlider.hbs b/packages/main/src/WheelSlider.hbs index 375032501afd..9704be289933 100644 --- a/packages/main/src/WheelSlider.hbs +++ b/packages/main/src/WheelSlider.hbs @@ -6,7 +6,7 @@ ?expanded= "{{_expanded}}" @click = {{_onclick}} @keydown={{_onkeydown}} - class = "ui5-wheelslider" + class = "ui5-wheelslider-root" data-sap-focus-ref @focusin="{{_onfocusin}}" @focusout="{{_onfocusout}}" diff --git a/packages/main/src/WheelSlider.js b/packages/main/src/WheelSlider.js index 7570c519bcf7..927a42bff90b 100644 --- a/packages/main/src/WheelSlider.js +++ b/packages/main/src/WheelSlider.js @@ -10,7 +10,7 @@ import { } from "../../base/src/events/PseudoEvents.js"; // Styles -import WheelSliderCss from "./generated/themes/WheelSliderCss.css.js"; +import WheelSliderCss from "./generated/themes/WheelSlider.css.js"; /** * @private diff --git a/packages/main/src/themes/WheelSlider.css b/packages/main/src/themes/WheelSlider.css index 96abdf6d9d35..f92b9e25657a 100644 --- a/packages/main/src/themes/WheelSlider.css +++ b/packages/main/src/themes/WheelSlider.css @@ -1,4 +1,4 @@ -.ui5-wheelslider { +.ui5-wheelslider-root { overflow: hidden; height: 100%; vertical-align: middle; @@ -9,18 +9,18 @@ flex-direction: column; display: inline-flex; } -.ui5-wheelslider .ui5-wheelslider-label { +.ui5-wheelslider-root .ui5-wheelslider-label { box-sizing: border-box; height: 2rem; line-height: 2rem; - width: var(--_ui5_slider_item_width); - font-size: var(--_ui5_slider_label_text_size); - color: var(--_ui5_slider_label_text_color); + width: var(--_ui5_wheelslider_item_width); + font-size: var(--_ui5_wheelslider_label_text_size); + color: var(--_ui5_wheelslider_label_text_color); text-align: center; vertical-align: middle; } -.ui5-wheelslider .ui5-wheelslider-arrow { +.ui5-wheelslider-root .ui5-wheelslider-arrow { visibility: hidden; box-sizing: border-box; height: 1.5rem; @@ -28,7 +28,7 @@ outline: none } -.ui5-wheelslider[expanded] .ui5-wheelslider-arrow { +.ui5-wheelslider-root[expanded] .ui5-wheelslider-arrow { visibility: visible; box-sizing: border-box; width: 100%; @@ -36,7 +36,7 @@ cursor: pointer; } -.ui5-wheelslider .ui5-wheelslider-inner { +.ui5-wheelslider-root .ui5-wheelslider-inner { overflow: hidden; height: 100%; box-sizing: border-box; @@ -45,62 +45,62 @@ margin-top: 0rem; } -.ui5-wheelslider[expanded] .ui5-wheelslider-inner { +.ui5-wheelslider-root[expanded] .ui5-wheelslider-inner { margin-top: 0; } -.ui5-wheelslider .ui5-wheelslider-inner .ui5-wheelslider-item { - height: var(--_ui5_slider_item_height); - line-height: var(--_ui5_slider_item_height); - width: var(--_ui5_slider_item_width); +.ui5-wheelslider-root .ui5-wheelslider-inner .ui5-wheelslider-item { + height: var(--_ui5_wheelslider_item_height); + line-height: var(--_ui5_wheelslider_item_height); + width: var(--_ui5_wheelslider_item_width); box-sizing: border-box; - background: var(--_ui5_slider_selected_item_background_color); - border: 0.625px solid var(--_ui5_slider_item_border_color); - font-size: var(--_ui5_slider_item_text_size); - color: var(--_ui5_slider_collapsed_item_text_color); + background: var(--_ui5_wheelslider_selected_item_background_color); + border: 0.625px solid var(--_ui5_wheelslider_item_border_color); + font-size: var(--_ui5_wheelslider_item_text_size); + color: var(--_ui5_wheelslider_collapsed_item_text_color); text-align: center; - border-radius: var(--_ui_slider_item_border_radius); + border-radius: var(--_ui_wheelslider_item_border_radius); cursor: pointer; } -.ui5-wheelslider .ui5-wheelslider-inner .ui5-wheelslider-item:hover { - background: var(--_ui5_slider_selected_item_hover_background_color); +.ui5-wheelslider-root .ui5-wheelslider-inner .ui5-wheelslider-item:hover { + background: var(--_ui5_wheelslider_selected_item_hover_background_color); } -.ui5-wheelslider .ui5-wheelslider-inner .ui5-wheelslider-item:focus { +.ui5-wheelslider-root .ui5-wheelslider-inner .ui5-wheelslider-item:focus { outline: 1px dotted black; outline-offset: -3px; } -.ui5-wheelslider .ui5-wheelslider-inner .ui5-wheelslider-selection-frame { - width: var(--_ui5_slider_item_width); - height: var(--_ui5_slider_item_height); +.ui5-wheelslider-root .ui5-wheelslider-inner .ui5-wheelslider-selection-frame { + width: var(--_ui5_wheelslider_item_width); + height: var(--_ui5_wheelslider_item_height); position: absolute; box-sizing: border-box; visibility: hidden; z-index: 1; } -.ui5-wheelslider .ui5-wheelslider-inner .ui5-wheelslider-wrapper > ul { +.ui5-wheelslider-root .ui5-wheelslider-inner .ui5-wheelslider-wrapper > ul { transition: all 400ms; margin: 0; padding: 0; position: absolute; - top: var(--_ui5_slider_selection_frame_margin_top); + top: var(--_ui5_wheelslider_selection_frame_margin_top); cursor: pointer; list-style-type: none; } -.ui5-wheelslider[expanded] .ui5-wheelslider-inner .ui5-wheelslider-wrapper > ul { +.ui5-wheelslider-root[expanded] .ui5-wheelslider-inner .ui5-wheelslider-wrapper > ul { list-style-type: none; top: 0; } -.ui5-wheelslider .ui5-wheelslider-inner .ui5-wheelslider-wrapper { - height: var(--_ui5_slider_height); +.ui5-wheelslider-root .ui5-wheelslider-inner .ui5-wheelslider-wrapper { + height: var(--_ui5_wheelslider_height); position: relative; overflow: hidden; outline: none; } -.ui5-wheelslider[expanded] { +.ui5-wheelslider-root[expanded] { height: 100%; cursor: default; margin: 0; @@ -109,54 +109,54 @@ display: inline-flex; } -.ui5-wheelslider[expanded] .ui5-wheelslider-label { +.ui5-wheelslider-root[expanded] .ui5-wheelslider-label { display: block; } -.ui5-wheelslider .ui5-wheelslider-inner { +.ui5-wheelslider-root .ui5-wheelslider-inner { max-height: 100%; - height: var(--_ui5_slider_height); + height: var(--_ui5_wheelslider_height); } -.ui5-wheelslider[expanded] .ui5-wheelslider-inner .ui5-wheelslider-item { - background: var(--_ui5_slider_item_background_color); - color: var(--_ui5_slider_item_text_color); - border: 1px solid var(--_ui5_slider_item_border_color); - border-radius: var(--_ui_slider_item_border_radius); +.ui5-wheelslider-root[expanded] .ui5-wheelslider-inner .ui5-wheelslider-item { + background: var(--_ui5_wheelslider_item_background_color); + color: var(--_ui5_wheelslider_item_text_color); + border: 1px solid var(--_ui5_wheelslider_item_border_color); + border-radius: var(--_ui_wheelslider_item_border_radius); offset-position: auto; cursor: pointer; } -.ui5-wheelslider[expanded] .ui5-wheelslider-inner .ui5-wheelslider-item:hover { - background: var(--_ui_slider_item_hover_color); +.ui5-wheelslider-root[expanded] .ui5-wheelslider-inner .ui5-wheelslider-item:hover { + background: var(--_ui_wheelslider_item_hover_color); } -.ui5-wheelslider[expanded] .ui5-wheelslider-inner .ui5-wheelslider-item:active { - background: var(--_ui5_slider_active_item_background_color); - color: var(--_ui5_slider_active_item_text_color); +.ui5-wheelslider-root[expanded] .ui5-wheelslider-inner .ui5-wheelslider-item:active { + background: var(--_ui5_wheelslider_active_item_background_color); + color: var(--_ui5_wheelslider_active_item_text_color); } -.ui5-wheelslider[expanded] .ui5-wheelslider-inner .ui5-wheelslider-item:focus { +.ui5-wheelslider-root[expanded] .ui5-wheelslider-inner .ui5-wheelslider-item:focus { outline: 1px dotted black; outline-offset: -3px; } -.ui5-wheelslider[expanded] .ui5-wheelslider-inner .ui5-wheelslider-selection-frame { +.ui5-wheelslider-root[expanded] .ui5-wheelslider-inner .ui5-wheelslider-selection-frame { visibility: visible; - -webkit-box-shadow: inset 0px 0px 0px 2px var(--_ui5_slider_selection_frame_color); - -moz-box-shadow: inset 0px 0px 0px 2px var(--_ui5_slider_selection_frame_color); - box-shadow: inset 0px 0px 0px 2px var(--_ui5_slider_selection_frame_color); - border-radius: var(--_ui_slider_item_border_radius); - margin-top: var(--_ui5_slider_selection_frame_margin_top); + -webkit-box-shadow: inset 0px 0px 0px 2px var(--_ui5_wheelslider_selection_frame_color); + -moz-box-shadow: inset 0px 0px 0px 2px var(--_ui5_wheelslider_selection_frame_color); + box-shadow: inset 0px 0px 0px 2px var(--_ui5_wheelslider_selection_frame_color); + border-radius: var(--_ui_wheelslider_item_border_radius); + margin-top: var(--_ui5_wheelslider_selection_frame_margin_top); } -.ui5-wheelslider[expanded] .ui5-wheelslider-inner .ui5-wheelslider-selection-frame:hover + ul > li.ui5-wheelslider-item.ui5-wheelslider-itemSelected { - background: var(--_ui5_slider_selected_item_background_color); +.ui5-wheelslider-root[expanded] .ui5-wheelslider-inner .ui5-wheelslider-selection-frame:hover + ul > li.ui5-wheelslider-item.ui5-wheelslider-itemSelected { + background: var(--_ui5_wheelslider_selected_item_background_color); } -.ui5-wheelslider[expanded] .ui5-wheelslider-inner .ui5-wheelslider-selection-frame:active + ul > li.ui5-wheelslider-item.ui5-wheelslider-itemSelected { - background: var(--_ui5_slider_selected_item_background_color); +.ui5-wheelslider-root[expanded] .ui5-wheelslider-inner .ui5-wheelslider-selection-frame:active + ul > li.ui5-wheelslider-item.ui5-wheelslider-itemSelected { + background: var(--_ui5_wheelslider_selected_item_background_color); color: lightgray; } -.ui5-wheelslider:focus { +.ui5-wheelslider-root:focus { outline: none; } \ No newline at end of file From 08907b05738d5cd4f6ef64a2c5a5ad6717090ecb Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Mon, 9 Mar 2020 16:02:18 +0200 Subject: [PATCH 39/57] Added new template popoverfor timepicker --- packages/main/src/TimePicker.hbs | 54 +------------------ packages/main/src/TimePicker.js | 46 ++++++++-------- packages/main/src/TimePickerPopover.hbs | 52 ++++++++++++++++++ packages/main/src/themes/TimePicker.css | 17 ------ .../main/src/themes/TimePickerPopover.css | 16 ++++++ 5 files changed, 92 insertions(+), 93 deletions(-) create mode 100644 packages/main/src/TimePickerPopover.hbs create mode 100644 packages/main/src/themes/TimePickerPopover.css diff --git a/packages/main/src/TimePicker.hbs b/packages/main/src/TimePicker.hbs index 31ef27cb2b72..3e0e01b8005d 100644 --- a/packages/main/src/TimePicker.hbs +++ b/packages/main/src/TimePicker.hbs @@ -8,6 +8,7 @@ @ui5-change="{{_handleInputChange}}" @ui5-input="{{_handleInputLiveChange}}" > + {{#unless readonly}} + {{/unless}} - -
- {{#if shouldBuildHoursSlider}} - - {{/if}} - {{#if shouldBuildMinutesSlider}} - - {{/if}} - {{#if shouldBuildSecondsSlider}} - - {{/if}} - {{#if shouldBuildPeriodsSlider}} - - {{/if}} -
- -
\ No newline at end of file diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index 54978daa5ea9..f4acfc3adc68 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -10,6 +10,7 @@ import PopoverHorizontalAlign from "./types/PopoverHorizontalAlign.js"; import ResponsivePopover from "./ResponsivePopover.js"; import PopoverPlacementType from "./types/PopoverPlacementType.js"; import TimePickerTemplate from "./generated/templates/TimePickerTemplate.lit.js"; +import TimePickerPopoverTemplate from "./generated/templates/TimePickerPopoverTemplate.lit.js" import { TIMEPICKER_HOURS_LABEL, TIMEPICKER_MINUTES_LABEL, @@ -25,6 +26,7 @@ import { // Styles import TimePickerCss from "./generated/themes/TimePicker.css.js"; +import TimePickerPopoverCss from "./generated/themes/TimePickerPopover.css.js"; import ResponsivePopoverCommonCss from "./generated/themes/ResponsivePopoverCommon.css.js"; /** @@ -198,6 +200,10 @@ class TimePicker extends UI5Element { return TimePickerCss; } + static get staticAreaTemplate() { + return TimePickerPopoverTemplate; + } + static get template() { return TimePickerTemplate; } @@ -211,7 +217,7 @@ class TimePicker extends UI5Element { } static get staticAreaStyles() { - return [ResponsivePopoverCommonCss]; + return [TimePickerPopoverCss, ResponsivePopoverCommonCss]; } @@ -254,17 +260,6 @@ class TimePicker extends UI5Element { this._initHoursFormatParameters(); } - onAfterRendering() { - const slidersEnablementArray = this._getSlidersContained(this.formatPattern); - this._slidersDomRefs = this._getPopover().default.length ? [...this._getPopover().default[0].children].filter(x => x.isUI5Element) : this._getPopover().default; - - for (let i = 0; i < this._slidersDomRefs.length; i++) { - this._slidersDomRefs[i].disabled = !slidersEnablementArray[i]; - } - - this.setSlidersValue(); - } - _handleInputChange() { let nextValue = this._getInput().getInputValue(); const isValid = this.isValid(nextValue); @@ -288,10 +283,10 @@ class TimePicker extends UI5Element { setSlidersValue() { const currentDate = this._getInput() ? this.getFormat().parse(this._getInput().getAttribute("value")) : null, - secondsSlider = this.shadowRoot.querySelector(".ui5-timepicker-seconds-wheelslider"), - minutesSlider = this.shadowRoot.querySelector(".ui5-timepicker-minutes-wheelslider"), - hoursSlider = this.shadowRoot.querySelector(".ui5-timepicker-hours-wheelslider"), - periodsSlider = this.shadowRoot.querySelector(".ui5-timepicker-period-wheelslider"); + secondsSlider = this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-seconds-wheelslider"), + minutesSlider = this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-minutes-wheelslider"), + hoursSlider = this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-hours-wheelslider"), + periodsSlider = this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-period-wheelslider"); if (currentDate) { if (hoursSlider) { @@ -339,6 +334,9 @@ class TimePicker extends UI5Element { openPicker() { this._getPopover().open(this); this._isPickerOpen = true; + this._slidersDomRefs = this._getPopover().default.length ? [...this._getPopover().default[0].children].filter(x => x.isUI5Element) : this._getPopover().default; + + this.setSlidersValue(); } togglePicker() { @@ -350,7 +348,7 @@ class TimePicker extends UI5Element { } /** - * Checks if a value is valid against the current date format of the DatePicker + * Checks if a value is valid against the current date format of the TimePicker * @param {string} value A value to be tested against the current date format * @public */ @@ -363,7 +361,7 @@ class TimePicker extends UI5Element { } _getPopover() { - return this.shadowRoot.querySelector("ui5-responsive-popover"); + return this.getStaticAreaItemDomRef().querySelector("ui5-responsive-popover"); } generateTimeItemsArray(x) { @@ -408,10 +406,10 @@ class TimePicker extends UI5Element { submitPickers() { const selectedDate = new Date(), - secondsSlider = this.shadowRoot.querySelector(".ui5-timepicker-seconds-wheelslider"), - minutesSlider = this.shadowRoot.querySelector(".ui5-timepicker-minutes-wheelslider"), - hoursSlider = this.shadowRoot.querySelector(".ui5-timepicker-hours-wheelslider"), - periodsSlider = this.shadowRoot.querySelector(".ui5-timepicker-period-wheelslider"), + secondsSlider = this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-seconds-wheelslider"), + minutesSlider = this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-minutes-wheelslider"), + hoursSlider = this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-hours-wheelslider"), + periodsSlider = this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-period-wheelslider"), hours = hoursSlider ? hoursSlider.getAttribute("value") : this._hoursParameters.minHour.toString(), minutes = minutesSlider ? minutesSlider.getAttribute("value") : "0", seconds = secondsSlider ? secondsSlider.getAttribute("value") : "0", @@ -517,9 +515,9 @@ class TimePicker extends UI5Element { } } if (isTabNext(e)) { - this.shadowRoot.querySelector(".ui5-timepicker-footer").firstElementChild.focus(); + this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-footer").firstElementChild.focus(); } else if (isTabPrevious(e)) { - this.shadowRoot.querySelector(`#${this._id}-inner`).focus(); + this.getStaticAreaItemDomRef().querySelector(`#${this._id}-inner`).focus(); } } diff --git a/packages/main/src/TimePickerPopover.hbs b/packages/main/src/TimePickerPopover.hbs new file mode 100644 index 000000000000..a5a58d9bbd35 --- /dev/null +++ b/packages/main/src/TimePickerPopover.hbs @@ -0,0 +1,52 @@ + +
+ {{#if shouldBuildHoursSlider}} + + {{/if}} + {{#if shouldBuildMinutesSlider}} + + {{/if}} + {{#if shouldBuildSecondsSlider}} + + {{/if}} + {{#if shouldBuildPeriodsSlider}} + + {{/if}} +
+ +
\ No newline at end of file diff --git a/packages/main/src/themes/TimePicker.css b/packages/main/src/themes/TimePicker.css index 57e145e2b1e0..ca5b6d52ed40 100644 --- a/packages/main/src/themes/TimePicker.css +++ b/packages/main/src/themes/TimePicker.css @@ -2,23 +2,6 @@ display: inline-block; } -.ui5-timepicker-sliders-container { - display: flex; - justify-content: center; - align-items: stretch; -} - -.ui5-timepicker-footer { - height: fit-content; - display: flex; - justify-content: flex-end; - width: 100%; -} - -.ui5-timepicker-footer * { - margin: 1%; -} - .ui5-timepicker-input-icon-button:hover { cursor: pointer; background: var(--sapButton_Hover_Background); diff --git a/packages/main/src/themes/TimePickerPopover.css b/packages/main/src/themes/TimePickerPopover.css new file mode 100644 index 000000000000..624aa0152ef3 --- /dev/null +++ b/packages/main/src/themes/TimePickerPopover.css @@ -0,0 +1,16 @@ +.ui5-timepicker-sliders-container { + display: flex; + justify-content: center; + align-items: stretch; +} + +.ui5-timepicker-footer { + height: fit-content; + display: flex; + justify-content: flex-end; + width: 100%; +} + +.ui5-timepicker-footer * { + margin: 1%; +} From efcb720f3a38804abf580a164859dcb2eeb1c7a9 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Tue, 10 Mar 2020 13:10:05 +0200 Subject: [PATCH 40/57] Test fixed --- packages/main/src/TimePicker.js | 2 ++ packages/main/test/specs/TimePicker.spec.js | 25 +++++++++++---------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index f4acfc3adc68..5a0eb9d06d8f 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -278,6 +278,7 @@ class TimePicker extends UI5Element { isValid = this.isValid(nextValue); this.value = nextValue; + this.setSlidersValue(); this.fireEvent("input", { value: nextValue, valid: isValid }); } @@ -538,6 +539,7 @@ class TimePicker extends UI5Element { setValue(value) { if (this.isValid(value)) { this.value = this.normalizeValue(value); + this.setSlidersValue(); this.valueState = ValueState.None; } else { this.valueState = ValueState.Error; diff --git a/packages/main/test/specs/TimePicker.spec.js b/packages/main/test/specs/TimePicker.spec.js index 8f049321b8bb..c3de0c3751d2 100644 --- a/packages/main/test/specs/TimePicker.spec.js +++ b/packages/main/test/specs/TimePicker.spec.js @@ -4,7 +4,7 @@ describe("TimePicker general interaction", () => { browser.url("http://localhost:8080/test-resources/pages/TimePicker.html"); it("Is default value today", () => { - const textValue = browser.$("#timepicker").shadow$$("#__ui5Timepicker1-inner")[0].getValue(); + const textValue = browser.$("#timepicker").shadow$$("#ui5wc_1-inner")[0].getValue(); const today = new Date(); assert.strictEqual(Number(textValue.substring(0,2)), today.getHours(), "Hours are equal"); @@ -12,25 +12,26 @@ describe("TimePicker general interaction", () => { }); it("Check sliders value", () => { - browser.$("#timepicker").setProperty("value","11:12:13"); - const hoursSliderValue = browser.$("#timepicker").shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-hours-wheelslider").getValue(); - const minutesSliderValue = browser.$("#timepicker").shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-minutes-wheelslider").getValue(); - const secondsSliderValue = browser.$("#timepicker").shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-seconds-wheelslider").getValue(); - + browser.$("#timepicker").setProperty("value", "11:12:13"); + browser.$("#timepicker").shadow$("ui5-input").$(".ui5-timepicker-input-icon-button").click(); + const hoursSliderValue = browser.$$(".ui5wc_1")[0].shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-hours-wheelslider").getValue(); + const minutesSliderValue = browser.$$(".ui5wc_1")[0].shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-minutes-wheelslider").getValue(); + const secondsSliderValue = browser.$$(".ui5wc_1")[0].shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-seconds-wheelslider").getValue(); assert.strictEqual(hoursSliderValue, "11", "Hours are equal"); assert.strictEqual(minutesSliderValue, "12", "Minutes are equal"); assert.strictEqual(secondsSliderValue, "13", "Minutes are equal"); }); it("Sliders submit value", () => { - browser.$("#timepicker").shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-hours-wheelslider").setProperty("value","14"); - browser.$("#timepicker").shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-minutes-wheelslider").setProperty("value","15"); - browser.$("#timepicker").shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-seconds-wheelslider").setProperty("value","16"); + browser.$$(".ui5wc_1")[0].shadow$$(".ui5-timepicker-popover")[0].setProperty("opened",true); + browser.$$(".ui5wc_1")[0].shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-hours-wheelslider").setProperty("value","14"); + browser.$$(".ui5wc_1")[0].shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-minutes-wheelslider").setProperty("value","15"); + browser.$$(".ui5wc_1")[0].shadow$$(".ui5-timepicker-popover")[0].$(".ui5-timepicker-seconds-wheelslider").setProperty("value","16"); - browser.$("#timepicker").shadow$$(".ui5-timepicker-popover")[0].setProperty("opened",true); - browser.$("#timepicker").shadow$$(".ui5-timepicker-popover")[0].$("#submit").click(); + // browser.$("#timepicker").shadow$$(".ui5-timepicker-popover")[0].setProperty("opened",true); + browser.$$(".ui5wc_1")[0].shadow$$(".ui5-timepicker-popover")[0].$("#submit").click(); - const textValue = browser.$("#timepicker").shadow$$("#__ui5Timepicker1-inner")[0].getValue(); + const textValue = browser.$("#timepicker").shadow$$("#ui5wc_1-inner")[0].getValue(); assert.strictEqual(textValue.substring(0,2), "14", "Hours are equal"); assert.strictEqual(textValue.substring(3,5), "15", "Minutes are equal"); From 39c1bcaf695786261c638b627f932c08d22db0e1 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Tue, 10 Mar 2020 13:11:00 +0200 Subject: [PATCH 41/57] lint fix --- packages/main/src/TimePicker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index 5a0eb9d06d8f..cb4e50e19b04 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -10,7 +10,7 @@ import PopoverHorizontalAlign from "./types/PopoverHorizontalAlign.js"; import ResponsivePopover from "./ResponsivePopover.js"; import PopoverPlacementType from "./types/PopoverPlacementType.js"; import TimePickerTemplate from "./generated/templates/TimePickerTemplate.lit.js"; -import TimePickerPopoverTemplate from "./generated/templates/TimePickerPopoverTemplate.lit.js" +import TimePickerPopoverTemplate from "./generated/templates/TimePickerPopoverTemplate.lit.js"; import { TIMEPICKER_HOURS_LABEL, TIMEPICKER_MINUTES_LABEL, From 0ad9588f64e4781f0e3562921444ce504104dd84 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Wed, 11 Mar 2020 08:09:07 +0200 Subject: [PATCH 42/57] merged master --- packages/main/src/TimePicker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index cb4e50e19b04..e2ef3830260b 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -1,7 +1,7 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; -import { getLocale } from "@ui5/webcomponents-base/dist/LocaleProvider.js"; +import getLocale from "@ui5/webcomponents-base/dist/locale/getLocale.js"; import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js"; import DateFormat from "@ui5/webcomponents-utils/dist/sap/ui/core/format/DateFormat.js"; import LocaleData from "@ui5/webcomponents-utils/dist/sap/ui/core/LocaleData.js"; From 68d16a5da38638ef1190f53a586520df484ef917 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Wed, 11 Mar 2020 08:33:23 +0200 Subject: [PATCH 43/57] removed unstable test --- packages/main/test/specs/TimePicker.spec.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/packages/main/test/specs/TimePicker.spec.js b/packages/main/test/specs/TimePicker.spec.js index c3de0c3751d2..70e49270e692 100644 --- a/packages/main/test/specs/TimePicker.spec.js +++ b/packages/main/test/specs/TimePicker.spec.js @@ -2,14 +2,6 @@ const assert = require("chai").assert; describe("TimePicker general interaction", () => { browser.url("http://localhost:8080/test-resources/pages/TimePicker.html"); - - it("Is default value today", () => { - const textValue = browser.$("#timepicker").shadow$$("#ui5wc_1-inner")[0].getValue(); - const today = new Date(); - - assert.strictEqual(Number(textValue.substring(0,2)), today.getHours(), "Hours are equal"); - assert.strictEqual(Number(textValue.substring(3,5)), today.getMinutes(), "Minutes are equal"); - }); it("Check sliders value", () => { browser.$("#timepicker").setProperty("value", "11:12:13"); From dd15ef675ecfd0bd3f14376cb9ef3c4c8fce9ce3 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Wed, 11 Mar 2020 12:35:40 +0200 Subject: [PATCH 44/57] Aligned with the new changes --- packages/main/src/TimePicker.js | 2 +- packages/main/src/WheelSlider.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index e2ef3830260b..bb3478d1dbc7 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -22,7 +22,7 @@ import { isRight, isTabNext, isTabPrevious, -} from "../../base/src/events/PseudoEvents.js"; +} from "../../base/src/Keys.js"; // Styles import TimePickerCss from "./generated/themes/TimePicker.css.js"; diff --git a/packages/main/src/WheelSlider.js b/packages/main/src/WheelSlider.js index 927a42bff90b..fa1ef14a6ce2 100644 --- a/packages/main/src/WheelSlider.js +++ b/packages/main/src/WheelSlider.js @@ -7,7 +7,7 @@ import { isUp, isTabNext, isTabPrevious, -} from "../../base/src/events/PseudoEvents.js"; +} from "../../base/src/Keys.js"; // Styles import WheelSliderCss from "./generated/themes/WheelSlider.css.js"; From b1fd733312af340be7f0cdd782ff181685e7cb1c Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Thu, 12 Mar 2020 11:43:48 +0200 Subject: [PATCH 45/57] Comments fixes --- packages/main/src/TimePicker.hbs | 2 +- packages/main/src/TimePicker.js | 142 +++++++++++++----- packages/main/src/TimePickerPopover.hbs | 7 +- packages/main/src/WheelSlider.js | 13 +- .../main/src/i18n/messagebundle.properties | 6 + .../main/src/themes/TimePickerPopover.css | 1 + packages/main/src/themes/WheelSlider.css | 6 +- .../themes/base/WheelSlider-parameters.css | 1 + .../main/src/themes/base/sizes-parameters.css | 1 + .../sap_belize_hcw/WheelSlider-parameters.css | 17 +++ .../sap_belize_hcw/parameters-bundle.css | 1 + packages/main/test/pages/TimePicker.html | 5 + .../main/test/samples/TimePicker.sample.html | 3 + 13 files changed, 156 insertions(+), 49 deletions(-) create mode 100644 packages/main/src/themes/sap_belize_hcw/WheelSlider-parameters.css diff --git a/packages/main/src/TimePicker.hbs b/packages/main/src/TimePicker.hbs index 3e0e01b8005d..f49bfa281b8c 100644 --- a/packages/main/src/TimePicker.hbs +++ b/packages/main/src/TimePicker.hbs @@ -1,4 +1,4 @@ -
+
this._hoursParameters.maxHour) { - hoursSlider.value = currentDate.getHours() - 12; - } else if (this._hoursParameters.isTwelveHoursFormat && currentDate.getHours() < this._hoursParameters.minHour) { - hoursSlider.value = currentDate.getHours() + 12; - } else { - hoursSlider.value = currentDate.getHours(); - } - } - if (minutesSlider) { - minutesSlider.value = currentDate.getMinutes(); - } - if (secondsSlider) { - secondsSlider.value = currentDate.getSeconds(); - } - if (this._hoursParameters.isTwelveHoursFormat && periodsSlider && this._hoursParameters.minHour === 1) { - periodsSlider.value = currentDate.getHours() > this._hoursParameters.maxHour ? this.periodsArray[1] : this.periodsArray[0]; - } else if (this._hoursParameters.isTwelveHoursFormat && periodsSlider) { - periodsSlider.value = (currentDate.getHours() > this._hoursParameters.maxHour || currentDate.getHours() === this._hoursParameters.minHour) ? this.periodsArray[1] : this.periodsArray[0]; + secondsSlider = this.secondsSlider, + minutesSlider = this.minutesSlider, + hoursSlider = this.hoursSlider, + periodsSlider = this.periodsSlider; + + if (!currentDate) { + return; + } + if (hoursSlider) { + if (this._hoursParameters.isTwelveHoursFormat && currentDate.getHours() > this._hoursParameters.maxHour) { + hoursSlider.value = currentDate.getHours() - 12; + } else if (this._hoursParameters.isTwelveHoursFormat && currentDate.getHours() < this._hoursParameters.minHour) { + hoursSlider.value = currentDate.getHours() + 12; + } else { + hoursSlider.value = currentDate.getHours(); } } + if (minutesSlider) { + minutesSlider.value = currentDate.getMinutes(); + } + if (secondsSlider) { + secondsSlider.value = currentDate.getSeconds(); + } + if (this._hoursParameters.isTwelveHoursFormat && periodsSlider && this._hoursParameters.minHour === 1) { + periodsSlider.value = currentDate.getHours() > this._hoursParameters.maxHour ? this.periodsArray[1] : this.periodsArray[0]; + } else if (this._hoursParameters.isTwelveHoursFormat && periodsSlider) { + periodsSlider.value = (currentDate.getHours() > this._hoursParameters.maxHour || currentDate.getHours() === this._hoursParameters.minHour) ? this.periodsArray[1] : this.periodsArray[0]; + } } /** @@ -327,7 +336,6 @@ class TimePicker extends UI5Element { /** * Opens the picker. - * @param {object} options A JSON object with additional configuration.
* { focusInput: true } By default, the focus goes in the picker after opening it. * Specify this option to focus the input field. * @public @@ -335,9 +343,13 @@ class TimePicker extends UI5Element { openPicker() { this._getPopover().open(this); this._isPickerOpen = true; - this._slidersDomRefs = this._getPopover().default.length ? [...this._getPopover().default[0].children].filter(x => x.isUI5Element) : this._getPopover().default; + this._slidersDomRefs = this.slidersDomRefs; this.setSlidersValue(); + + if (this._slidersDomRefs[0]) { + this._slidersDomRefs[0].focus(); + } } togglePicker() { @@ -401,16 +413,36 @@ class TimePicker extends UI5Element { return this.getFormat().aDayPeriods.map(x => x.toUpperCase()); } + get slidersDomRefs() { + return this._getPopover().default.length ? [...this._getPopover().default[0].children].filter(x => x.isUI5Element) : this._getPopover().default; + } + _getInput() { return this.shadowRoot.querySelector("ui5-input"); } + get secondsSlider() { + return this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-seconds-wheelslider"); + } + + get minutesSlider() { + return this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-minutes-wheelslider"); + } + + get hoursSlider() { + return this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-hours-wheelslider"); + } + + get periodsSlider() { + return this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-period-wheelslider"); + } + submitPickers() { const selectedDate = new Date(), - secondsSlider = this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-seconds-wheelslider"), - minutesSlider = this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-minutes-wheelslider"), - hoursSlider = this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-hours-wheelslider"), - periodsSlider = this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-period-wheelslider"), + secondsSlider = this.secondsSlider, + minutesSlider = this.minutesSlider, + hoursSlider = this.hoursSlider, + periodsSlider = this.periodsSlider, hours = hoursSlider ? hoursSlider.getAttribute("value") : this._hoursParameters.minHour.toString(), minutes = minutesSlider ? minutesSlider.getAttribute("value") : "0", seconds = secondsSlider ? secondsSlider.getAttribute("value") : "0", @@ -515,10 +547,40 @@ class TimePicker extends UI5Element { this._slidersDomRefs[0].focus(); } } - if (isTabNext(e)) { + + if (isTabNext(e) && e.target === this._slidersDomRefs[this._slidersDomRefs.length - 1]) { + e.preventDefault(); this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-footer").firstElementChild.focus(); - } else if (isTabPrevious(e)) { - this.getStaticAreaItemDomRef().querySelector(`#${this._id}-inner`).focus(); + } else if (isTabPrevious(e) && e.target === this._slidersDomRefs[0]) { + e.preventDefault(); + this.getStaticAreaItemDomRef().querySelector(`.ui5-timepicker-footer`).lastElementChild.focus(); + } + } + + _onfooterkeydown(e) { + if (isTabNext(e) && e.target === e.target.parentElement.lastElementChild) { + e.preventDefault(); + this._slidersDomRefs[0].focus(); + } + + if (isTabPrevious(e) && e.target === e.target.parentElement.firstElementChild) { + e.preventDefault(); + this._slidersDomRefs[this._slidersDomRefs.length - 1].focus(); + } + } + + _ontimepickerkeydown(e) { + this._handleTimepickerKeysDown(e); + } + + _ontimepickerpopoverkeydown(e) { + this._handleTimepickerKeysDown(e); + } + + _handleTimepickerKeysDown(e) { + if (isShow(e)) { + e.preventDefault(); + this.togglePicker(); } } @@ -633,6 +695,14 @@ class TimePicker extends UI5Element { get periodSliderTitle() { return this.i18nBundle.getText(TIMEPICKER_PERIODS_LABEL); } + + get submitButtonLabel() { + return this.i18nBundle.getText(TIMEPICKER_SUBMIT_BUTTON); + } + + get cancelButtonLabel() { + return this.i18nBundle.getText(TIMEPICKER_CANCEL_BUTTON); + } } TimePicker.define(); diff --git a/packages/main/src/TimePickerPopover.hbs b/packages/main/src/TimePickerPopover.hbs index a5a58d9bbd35..621f3d953c12 100644 --- a/packages/main/src/TimePickerPopover.hbs +++ b/packages/main/src/TimePickerPopover.hbs @@ -9,6 +9,7 @@ @ui5-afterOpen="{{_respPopover.afterOpen}}" header-text="Pick Time" class="ui5-timepicker-popover" + @keydown="{{_ontimepickerpopoverkeydown}}" >
{{#if shouldBuildHoursSlider}} @@ -45,8 +46,8 @@ > {{/if}}
-