From 5d0e4334a280100d996f70c99a7076c2bcfe8f8c Mon Sep 17 00:00:00 2001 From: Kafuko Marvin Date: Thu, 21 Mar 2024 09:41:46 +0300 Subject: [PATCH 01/31] Override constrainToScroll prop default value to false --- lib/KDropdownMenu.vue | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/KDropdownMenu.vue b/lib/KDropdownMenu.vue index 355288e53..e296b4bc9 100644 --- a/lib/KDropdownMenu.vue +++ b/lib/KDropdownMenu.vue @@ -5,6 +5,7 @@ :z-index="99" :containFocus="true" :dropdownPosition="position" + :constrainToScrollParent="constrainToScrollParent" @close="handleClose" @open="handleOpen" > @@ -34,6 +35,11 @@ UiMenu, }, props: { + // Override default prop value + constrainToScrollParent: { + type: Boolean, + default: false + }, /** * An array of options objects, with one object per dropdown item */ From f1b8ee0129c455cd863b104a2d227ea7b140b625 Mon Sep 17 00:00:00 2001 From: Kafuko Marvin Date: Fri, 22 Mar 2024 08:13:19 +0300 Subject: [PATCH 02/31] Updated default constrainToScrollParent prop value --- CHANGELOG.md | 11 +++++++++++ lib/KDropdownMenu.vue | 6 ++++-- yarn.lock | 6 +++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b1d560b2..4a2f87c6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,17 @@ Changelog is rather internal in nature. See release notes for the public overvie ## Version 3.x.x (`release-v3` branch) +- [#586] + - **Description:** Adds a new prop `constrainToScrollParent ` to `KDropdownMenu` to allow overriding of its popover flipping behavior. + - **Products impact:** Bugfix + - **Addresses:** [#432](https://github.com/learningequality/kolibri-design-system/issues/432) + - **Components:** KDropdownMenu + - **Breaking:** no + - **Impacts a11y:** no + - **Guidance:** Use the `constrainToScrollParent` prop to override the default popover flipping behavior of the `KDropdownMenu` component prop where necessary. + +[#586]: https://github.com/learningequality/kolibri-design-system/pull/586 + - [#557] - **Description:** Updates development documentation in regards to linking products development servers to local KDS - **Products impact:** - diff --git a/lib/KDropdownMenu.vue b/lib/KDropdownMenu.vue index e296b4bc9..824d992c1 100644 --- a/lib/KDropdownMenu.vue +++ b/lib/KDropdownMenu.vue @@ -35,10 +35,12 @@ UiMenu, }, props: { - // Override default prop value + /** + * The dropdown menu popover flips its position to avoid overflows within the parent. Setting it to false disables the flipping behavior. + */ constrainToScrollParent: { type: Boolean, - default: false + default: true, }, /** * An array of options objects, with one object per dropdown item diff --git a/yarn.lock b/yarn.lock index efaf30e1f..27cf49300 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3645,9 +3645,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001016, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001254, caniuse-lite@^1.0.30001286: - version "1.0.30001346" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001346.tgz" - integrity sha512-q6ibZUO2t88QCIPayP/euuDREq+aMAxFE5S70PkrLh0iTDj/zEhgvJRKC2+CvXY6EWc6oQwUR48lL5vCW6jiXQ== + version "1.0.30001599" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz" + integrity sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA== capture-exit@^2.0.0: version "2.0.0" From 837d6e29e093606707c320679cac966f284d336f Mon Sep 17 00:00:00 2001 From: Kafuko Marvin Date: Fri, 22 Mar 2024 09:17:25 +0300 Subject: [PATCH 03/31] Reverted yarn.lock changes --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 27cf49300..efaf30e1f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3645,9 +3645,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001016, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001254, caniuse-lite@^1.0.30001286: - version "1.0.30001599" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz" - integrity sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA== + version "1.0.30001346" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001346.tgz" + integrity sha512-q6ibZUO2t88QCIPayP/euuDREq+aMAxFE5S70PkrLh0iTDj/zEhgvJRKC2+CvXY6EWc6oQwUR48lL5vCW6jiXQ== capture-exit@^2.0.0: version "2.0.0" From 44409f6057472494c10f3c5f8fa3e7fb47a086df Mon Sep 17 00:00:00 2001 From: Kafuko Marvin Date: Fri, 22 Mar 2024 09:36:53 +0300 Subject: [PATCH 04/31] Modified changelog.md --- CHANGELOG.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a2f87c6b..47e38a565 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,40 @@ Changelog is rather internal in nature. See release notes for the public overvie [#586]: https://github.com/learningequality/kolibri-design-system/pull/586 +- [#552] + - **Description:** New `KListWithOverflow` component. + - **Products impact:** new API. + - **Addresses:** https://github.com/learningequality/kolibri-design-system/issues/556, https://github.com/learningequality/studio/issues/3423, https://github.com/learningequality/kolibri/issues/11923. + - **Components:** KListWithOverflow. + - **Breaking:** no. + - **Impacts a11y:** no. + - **Guidance:** -. + +[#552]: https://github.com/learningequality/kolibri-design-system/pull/552 + +- [#552] + - **Description:** New `useKResponsiveElement` private composable, `KResponsiveElementMixin` translated to this composable. + - **Products impact:** -. + - **Addresses:** -. + - **Components:** -. + - **Breaking:** no. + - **Impacts a11y:** no. + - **Guidance:** -. + +[#552]: https://github.com/learningequality/kolibri-design-system/pull/552 + +- [#538] + - **Description:** Complete KImg implementation + - **Products impact:** new API + - **Addresses:** https://github.com/learningequality/kolibri-design-system/issues/368 + - **Components:** KImg + - **Breaking:** no + - **Impacts a11y:** yes + - **Guidance:** One of the benefits of using KImg is that it throws a11y related warnings + +[#538]: https://github.com/learningequality/kolibri-design-system/pull/538 + + - [#557] - **Description:** Updates development documentation in regards to linking products development servers to local KDS - **Products impact:** - From ec8cf3bdba0491f5b31b353a8903b030e74ce575 Mon Sep 17 00:00:00 2001 From: Kafuko Marvin Date: Fri, 22 Mar 2024 10:41:27 +0300 Subject: [PATCH 05/31] Revert "Modified changelog.md" This reverts commit 44409f6057472494c10f3c5f8fa3e7fb47a086df. --- CHANGELOG.md | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47e38a565..4a2f87c6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,40 +15,6 @@ Changelog is rather internal in nature. See release notes for the public overvie [#586]: https://github.com/learningequality/kolibri-design-system/pull/586 -- [#552] - - **Description:** New `KListWithOverflow` component. - - **Products impact:** new API. - - **Addresses:** https://github.com/learningequality/kolibri-design-system/issues/556, https://github.com/learningequality/studio/issues/3423, https://github.com/learningequality/kolibri/issues/11923. - - **Components:** KListWithOverflow. - - **Breaking:** no. - - **Impacts a11y:** no. - - **Guidance:** -. - -[#552]: https://github.com/learningequality/kolibri-design-system/pull/552 - -- [#552] - - **Description:** New `useKResponsiveElement` private composable, `KResponsiveElementMixin` translated to this composable. - - **Products impact:** -. - - **Addresses:** -. - - **Components:** -. - - **Breaking:** no. - - **Impacts a11y:** no. - - **Guidance:** -. - -[#552]: https://github.com/learningequality/kolibri-design-system/pull/552 - -- [#538] - - **Description:** Complete KImg implementation - - **Products impact:** new API - - **Addresses:** https://github.com/learningequality/kolibri-design-system/issues/368 - - **Components:** KImg - - **Breaking:** no - - **Impacts a11y:** yes - - **Guidance:** One of the benefits of using KImg is that it throws a11y related warnings - -[#538]: https://github.com/learningequality/kolibri-design-system/pull/538 - - - [#557] - **Description:** Updates development documentation in regards to linking products development servers to local KDS - **Products impact:** - From 996d695536719f4ed5334844b28afdc48399234b Mon Sep 17 00:00:00 2001 From: Kafuko Marvin Date: Fri, 22 Mar 2024 10:50:32 +0300 Subject: [PATCH 06/31] Updated CHANGELOG.md --- CHANGELOG.md | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a2f87c6b..451c501fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,39 @@ Changelog is rather internal in nature. See release notes for the public overvie [#586]: https://github.com/learningequality/kolibri-design-system/pull/586 +- [#552] + - **Description:** New `KListWithOverflow` component. + - **Products impact:** new API. + - **Addresses:** https://github.com/learningequality/kolibri-design-system/issues/556, https://github.com/learningequality/studio/issues/3423, https://github.com/learningequality/kolibri/issues/11923. + - **Components:** KListWithOverflow. + - **Breaking:** no. + - **Impacts a11y:** no. + - **Guidance:** -. + +[#552]: https://github.com/learningequality/kolibri-design-system/pull/552 + +- [#552] + - **Description:** New `useKResponsiveElement` private composable, `KResponsiveElementMixin` translated to this composable. + - **Products impact:** -. + - **Addresses:** -. + - **Components:** -. + - **Breaking:** no. + - **Impacts a11y:** no. + - **Guidance:** -. + +[#552]: https://github.com/learningequality/kolibri-design-system/pull/552 + +- [#538] + - **Description:** Complete KImg implementation + - **Products impact:** new API + - **Addresses:** https://github.com/learningequality/kolibri-design-system/issues/368 + - **Components:** KImg + - **Breaking:** no + - **Impacts a11y:** yes + - **Guidance:** One of the benefits of using KImg is that it throws a11y related warnings + +[#538]: https://github.com/learningequality/kolibri-design-system/pull/538 + - [#557] - **Description:** Updates development documentation in regards to linking products development servers to local KDS - **Products impact:** - @@ -1155,4 +1188,4 @@ This was the first release of the Design System, with documentation written in a ## Version 0.1.0 -The design system was originally based on a set of internal Kolibri components and their use as documented in the Kolibri Style Guide, which was first introduced into the Kolibri code base [in version 0.6](https://github.com/learningequality/kolibri/tree/release-v0.6.x/kolibri/plugins/style_guide). This remained until [version 0.13](https://github.com/learningequality/kolibri/tree/release-v0.13.x/kolibri/plugins/style_guide) after which the content was migrated to the [current site](https://design-system.learningequality.org/ 'Kolibri Design System Documentation'). +The design system was originally based on a set of internal Kolibri components and their use as documented in the Kolibri Style Guide, which was first introduced into the Kolibri code base [in version 0.6](https://github.com/learningequality/kolibri/tree/release-v0.6.x/kolibri/plugins/style_guide). This remained until [version 0.13](https://github.com/learningequality/kolibri/tree/release-v0.13.x/kolibri/plugins/style_guide) after which the content was migrated to the [current site](https://design-system.learningequality.org/ 'Kolibri Design System Documentation'). \ No newline at end of file From b577fa8588f6e77d48a39174cf38b222b473b60a Mon Sep 17 00:00:00 2001 From: MisRob Date: Wed, 26 Jul 2023 16:13:34 +0200 Subject: [PATCH 07/31] Move dimension styles to the container rather than applying them to in preparation for implementing the image scaling logic. --- lib/KImg/index.vue | 60 ++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 37 deletions(-) diff --git a/lib/KImg/index.vue b/lib/KImg/index.vue index e2dc212ce..2acb38b44 100644 --- a/lib/KImg/index.vue +++ b/lib/KImg/index.vue @@ -1,10 +1,10 @@ + + +

'fitXY' scale type

- + +
+ +
+
+ +
+ +
+
+

Aspect ratio

- + + diff --git a/lib/KImg/index.vue b/lib/KImg/index.vue index 2acb38b44..d541e86f8 100644 --- a/lib/KImg/index.vue +++ b/lib/KImg/index.vue @@ -1,20 +1,58 @@ - + diff --git a/lib/KImg/__tests__/KImg.spec.js b/lib/KImg/__tests__/KImg.spec.js index 3efb4dcd7..f318e493a 100644 --- a/lib/KImg/__tests__/KImg.spec.js +++ b/lib/KImg/__tests__/KImg.spec.js @@ -1,45 +1,69 @@ -import { mount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import KImg from '../'; -describe('KImg component', () => { - let wrapper; - let img; +function makeWrapper({ propsData = {} } = {}) { + return shallowMount(KImg, { propsData }); +} - const DEFAULT_PROPS = { - src: 'https://learningequality.org/static/img/le-logo.svg', - altText: "Learning Equality's logo", - }; - - function makeWrapper(newProps = {}) { - wrapper = mount(KImg, { - propsData: { ...DEFAULT_PROPS, ...newProps }, +describe('KImg', () => { + it(`renders without any errors when a valid 'src' and 'altText' are provided`, () => { + const wrapper = makeWrapper({ + propsData: { src: '/le-logo.svg', altText: 'LE logo' }, }); - img = wrapper.find('img'); - } - it('Renders without any errors when a valid src and altText are provided', () => { - makeWrapper(); expect(wrapper.exists()).toBe(true); + + const img = wrapper.find('img'); expect(img.exists()).toBe(true); + expect(img.attributes('src')).toBe('/le-logo.svg'); + expect(img.attributes('alt')).toBe('LE logo'); + }); - expect(img.attributes('src')).toBe(DEFAULT_PROPS.src); - expect(img.attributes('alt')).toBe(DEFAULT_PROPS.altText); + it(`throws an error when no 'altText' is provided`, () => { + expect(() => + makeWrapper({ + propsData: { src: '/le-logo.svg', altText: undefined }, + }) + ).toThrow(); }); - it('Throws an error when no altText is provided', () => { - expect(() => makeWrapper({ altText: undefined })).toThrow(); + describe(`when no 'altText' is provided and it is a decorative image`, () => { + it(`does not throw an error`, () => { + expect(() => + makeWrapper({ + propsData: { src: '/le-logo.svg', altText: undefined, isDecorative: true }, + }) + ).not.toThrow(); + }); + + it(`sets 'alt' attribute to an empty string`, () => { + const wrapper = makeWrapper({ + propsData: { src: '/le-logo.svg', altText: undefined, isDecorative: true }, + }); + expect(wrapper.exists()).toBe(true); + expect(wrapper.find('img').attributes('alt')).toBe(''); + }); }); - it('Does not throw an error when no altText is provided and it is a decorative image', () => { - expect(() => makeWrapper({ altText: undefined, isDecorative: true })).not.toThrow(); + it(`throws an error when 'aspectRatio' has an invalid format`, () => { + expect(() => + makeWrapper({ + propsData: { src: '/le-logo.svg', altText: 'LE logo', aspectRatio: '16/9' }, + }) + ).toThrow(); + }); - expect(wrapper.exists()).toBe(true); - expect(img.attributes('alt')).toBe(''); + it(`doesn't throw an error when 'aspectRatio' has a valid format`, () => { + expect(() => + makeWrapper({ + propsData: { src: '/le-logo.svg', altText: 'LE logo', aspectRatio: '16:9' }, + }) + ).not.toThrow(); }); - it('Emits an `error` event when there is an error in loading the image', () => { - makeWrapper({ - src: 'invalid-src.jpg', + it(`emits an 'error' event when there is an error in loading the image`, () => { + const wrapper = makeWrapper({ + propsData: { src: '/le-logo.svg', altText: 'LE logo' }, }); // Manually trigger the onError method to simulate the image load failure diff --git a/lib/KImg/index.vue b/lib/KImg/index.vue index cf5c501d4..20b07acf9 100644 --- a/lib/KImg/index.vue +++ b/lib/KImg/index.vue @@ -12,7 +12,7 @@ v-if="$slots.placeholder" :style="{ position: 'absolute', top: '0', right: '0', left: '0', bottom: '0', zIndex: '0' }" > - + @@ -103,7 +103,7 @@ */ altText: { type: String, - default: '', + default: null, }, /** * Sets the image as decorative. @@ -117,42 +117,42 @@ */ height: { type: [Number, String], - default: undefined, + default: null, }, /** * Sets the width of the image container */ width: { type: [Number, String], - default: undefined, + default: null, }, /** * Sets the maximum height of the image container */ maxHeight: { type: [Number, String], - default: undefined, + default: null, }, /** * Sets the minimum height of the image container */ minHeight: { type: [Number, String], - default: undefined, + default: null, }, /** * Sets the maximum width of the image container */ maxWidth: { type: [Number, String], - default: undefined, + default: null, }, /** * Sets the minimum width of the image container */ minWidth: { type: [Number, String], - default: undefined, + default: null, }, /** * Sets the ratio of the width(w) to the height(h) @@ -160,13 +160,12 @@ */ aspectRatio: { type: String, - default: undefined, + default: null, validator: isValidAspectRatio, }, /** * Specifies how an image should be scaled within the container. - * Can be one of `'centerInside'` (default), `'contain'`, or `'fitXY'`. - * See the documentation examples. + * Can be one of `'centerInside'`, `'contain'`, or `'fitXY'`. */ scaleType: { type: String, @@ -176,12 +175,12 @@ /** * A color to be displayed instead or behind an image. * It creates a background area which respects the dimensions - * set on the container. + * set on the image container. * * It can serve as (1) a color of the area surrounding an image when - * it's letterboxed, (2) creates a placeholder area displayed + * it's letterboxed, (2) a placeholder area displayed * over the whole container when an image source is not provided, - * (3) creates a progressive loading experience as the colored background + * (3) a progressive loading experience as the colored background * is displayed while an image is loading. * * Its default value is `$themePalette.grey.v_200`. @@ -192,8 +191,7 @@ default: null, }, /** - * The border radius of an image or its placeholder area - * as a standard CSS 'border-radius' value. + * The border radius of the image container or the placeholder area */ borderRadius: { type: String, @@ -201,8 +199,7 @@ default: null, }, /** - * Accepts a Vue dynamic styles object to override the default styles to modify the appearance of the component. - * It's attributes always take precedence over any specified styling (internal component's styles, styles calculated from props etc.) + * A dynamic style object that overrides the default styles */ appearanceOverrides: { type: Object, @@ -246,6 +243,11 @@ }, }; }, + /** + * Returns all styles related to the logic + * that controls how the image scales within + * the image container + */ scaleStyles() { const scaleKind = isValidScaleType(this.scaleType) ? this.scaleType : ScaleTypes.CONTAIN; const scaleStyles = { @@ -287,6 +289,10 @@ }; return scaleStyles[scaleKind]; }, + /** + * Returns all styles related to the logic + * that controls the image ratio + */ ratioStyles() { if (!this.aspectRatio) { return { @@ -295,6 +301,7 @@ img: {}, }; } + // https://www.sitepoint.com/maintain-image-aspect-ratios-responsive-web-design/ const paddingTopInPercent = (this.ratio.y / this.ratio.x) * 100; return { rootContainer: {}, From 86a55a3c3634908778905e5f55467404fec3e169 Mon Sep 17 00:00:00 2001 From: Alex Velez Date: Tue, 20 Feb 2024 09:12:43 -0500 Subject: [PATCH 13/31] Trying with hidden overflow flex wrapper --- docs/pages/kemptyplaceholder.vue | 80 ++++++++++++++++++++ lib/KListWithOverflow.vue | 124 +++++++++++++++++++++++++++++++ lib/KThemePlugin.js | 2 + 3 files changed, 206 insertions(+) create mode 100644 lib/KListWithOverflow.vue diff --git a/docs/pages/kemptyplaceholder.vue b/docs/pages/kemptyplaceholder.vue index ee0eb06da..a328adf99 100644 --- a/docs/pages/kemptyplaceholder.vue +++ b/docs/pages/kemptyplaceholder.vue @@ -64,6 +64,34 @@ + + + + @@ -72,6 +100,58 @@ + + \ No newline at end of file diff --git a/lib/KThemePlugin.js b/lib/KThemePlugin.js index 7c7315ba1..9e189f875 100644 --- a/lib/KThemePlugin.js +++ b/lib/KThemePlugin.js @@ -8,6 +8,7 @@ import KCircularLoader from './loaders/KCircularLoader'; import KDateRange from './KDateRange'; import KDropdownMenu from './KDropdownMenu'; import KEmptyPlaceholder from './KEmptyPlaceholder'; +import KListWithOverflow from './KListWithOverflow'; import KExternalLink from './buttons-and-links/KExternalLink'; import KFixedGrid from './grids/KFixedGrid'; import KFixedGridItem from './grids/KFixedGridItem'; @@ -100,6 +101,7 @@ export default function KThemePlugin(Vue) { Vue.component('KDateRange', KDateRange); Vue.component('KDropdownMenu', KDropdownMenu); Vue.component('KEmptyPlaceholder', KEmptyPlaceholder); + Vue.component('KListWithOverflow', KListWithOverflow); Vue.component('KExternalLink', KExternalLink); Vue.component('KFixedGrid', KFixedGrid); Vue.component('KFixedGridItem', KFixedGridItem); From 3f55c9ed3e28b229b2abb7de6cf8a62ab324bd4b Mon Sep 17 00:00:00 2001 From: Alex Velez Date: Tue, 20 Feb 2024 10:21:52 -0500 Subject: [PATCH 14/31] Overflow items with visibility hidden items --- docs/pages/kemptyplaceholder.vue | 52 +++++++-------- lib/KListWithOverflow.vue | 111 ++++++++++++++++++++----------- 2 files changed, 99 insertions(+), 64 deletions(-) diff --git a/docs/pages/kemptyplaceholder.vue b/docs/pages/kemptyplaceholder.vue index a328adf99..17bc53312 100644 --- a/docs/pages/kemptyplaceholder.vue +++ b/docs/pages/kemptyplaceholder.vue @@ -64,35 +64,35 @@ - + + + + diff --git a/lib/KListWithOverflow.vue b/lib/KListWithOverflow.vue index 38c150f45..3af5f9480 100644 --- a/lib/KListWithOverflow.vue +++ b/lib/KListWithOverflow.vue @@ -1,6 +1,9 @@ - +
+ +
@@ -39,22 +47,11 @@ return { mounted: false, overflowItems: [], - isMoreButtonVisible: false, + // default to true just to measure its width at first render + isMoreButtonVisible: true, + moreButtonWidth: 0, }; }, - computed: { - listHeight() { - const defaultHeight = 50; - // height of the first child, assuming all children have the same height - const { list } = this.$refs; - if (!list) { - return defaultHeight; - } - const firstChild = list.children[0]; - console.log('firstChild', firstChild); - return firstChild.clientHeight || defaultHeight; - }, - }, watch: { isMoreButtonVisible(prev, next) { if (!prev && next) { @@ -72,7 +69,7 @@ }, mounted() { this.mounted = true; - this.$refs.list.style.height = `${this.listHeight}px`; + this.setMoreButtonWidth(); this.$nextTick(() => { this.setOverflowItems(); }); @@ -87,26 +84,50 @@ }, methods: { setOverflowItems() { - if (!this.mounted) { + const { list, listWrapper } = this.$refs; + if ( + !this.mounted || + !listWrapper || + !list + ) { this.overflowItems = []; return; } - const list = this.$refs.list; - if (!list) { - return; - } - const containerTop = list.offsetTop; - const containerBottom = containerTop + list.clientHeight; - this.overflowItems = this.items.filter((_, idx) => { - const itemRef = list.children[idx]; - const itemRefTop = itemRef.offsetTop; - return itemRefTop >= containerBottom; - }); + let availableWidth = listWrapper.clientWidth; + availableWidth -= this.moreButtonWidth; + let maxWidth = 0; + + const overflowItems = []; + for (let i = 0; i < list.children.length; i++) { + const item = list.children[i]; + const itemWidth = item.clientWidth; + if (itemWidth > availableWidth || overflowItems.length > 0) { + overflowItems.push(this.items[i]); + item.style.visibility = 'hidden'; + } else { + item.style.visibility = 'visible'; + maxWidth += itemWidth; + availableWidth -= itemWidth; + } + } - this.isMoreButtonVisible = this.overflowItems.length > 0; - console.log('overflowItems', this.overflowItems); + + this.overflowItems = overflowItems; + this.isMoreButtonVisible = overflowItems.length > 0; + list.style.maxWidth = `${maxWidth}px`; }, + setMoreButtonWidth() { + const { moreButtonWrapper } = this.$refs; + if (!moreButtonWrapper) { + return; + } + this.moreButtonWidth = moreButtonWrapper.clientWidth; + + this.isMoreButtonVisible = false; + moreButtonWrapper.style.visibility = 'visible'; + console.log('moreButtonWidth', this.moreButtonWidth); + } }, } @@ -114,11 +135,25 @@ \ No newline at end of file From 98018f4d965cec62b046da85cdf4ba028cfee4a3 Mon Sep 17 00:00:00 2001 From: Alex Velez Date: Tue, 20 Feb 2024 10:48:49 -0500 Subject: [PATCH 15/31] Ensuring all visible items if moreButton were not rendered --- docs/pages/kemptyplaceholder.vue | 2 +- lib/KListWithOverflow.vue | 25 +++++++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/docs/pages/kemptyplaceholder.vue b/docs/pages/kemptyplaceholder.vue index 17bc53312..7ffef2558 100644 --- a/docs/pages/kemptyplaceholder.vue +++ b/docs/pages/kemptyplaceholder.vue @@ -70,7 +70,7 @@ > diff --git a/lib/KListWithOverflow.vue b/lib/KListWithOverflow.vue index 3af5f9480..b10f5ecac 100644 --- a/lib/KListWithOverflow.vue +++ b/lib/KListWithOverflow.vue @@ -98,12 +98,12 @@ availableWidth -= this.moreButtonWidth; let maxWidth = 0; - const overflowItems = []; + const overflowItemsIdx = []; for (let i = 0; i < list.children.length; i++) { const item = list.children[i]; const itemWidth = item.clientWidth; - if (itemWidth > availableWidth || overflowItems.length > 0) { - overflowItems.push(this.items[i]); + if (itemWidth > availableWidth || overflowItemsIdx.length > 0) { + overflowItemsIdx.push(i); item.style.visibility = 'hidden'; } else { item.style.visibility = 'visible'; @@ -112,9 +112,22 @@ } } - - this.overflowItems = overflowItems; - this.isMoreButtonVisible = overflowItems.length > 0; + // check that if the moreButton were not visible, the overflowed items would fit + const overflowedWidth = overflowItemsIdx.reduce( + (acc, idx) => acc + list.children[idx].clientWidth, + 0 + ); + if (overflowedWidth <= this.moreButtonWidth + availableWidth) { + while (overflowItemsIdx.length > 0) { + const idx = overflowItemsIdx.pop(); + const item = list.children[idx]; + item.style.visibility = 'visible'; + maxWidth += item.clientWidth; + } + } + + this.overflowItems = overflowItemsIdx.map(idx => this.items[idx]); + this.isMoreButtonVisible = overflowItemsIdx.length > 0; list.style.maxWidth = `${maxWidth}px`; }, setMoreButtonWidth() { From bcf6fa2ff4a26f960c10be2a72a0163d0f8f3f8f Mon Sep 17 00:00:00 2001 From: Alex Velez Date: Tue, 20 Feb 2024 11:07:50 -0500 Subject: [PATCH 16/31] Polishing example --- docs/pages/kemptyplaceholder.vue | 137 +++++++++++++++---------------- lib/KListWithOverflow.vue | 33 +++----- 2 files changed, 80 insertions(+), 90 deletions(-) diff --git a/docs/pages/kemptyplaceholder.vue b/docs/pages/kemptyplaceholder.vue index 7ffef2558..b2738744c 100644 --- a/docs/pages/kemptyplaceholder.vue +++ b/docs/pages/kemptyplaceholder.vue @@ -66,33 +66,29 @@ - - - + :items="items" + > + + +
@@ -106,52 +102,55 @@ name: 'DocsKEmptyPlaceholder', computed: { items() { - return [ { - username: 'user_1', - exercises: 11, - averageScore: '85%', - }, { - username: 'user_2', - exercises: 0, - averageScore: null, - }, { - username: 'user_2', - exercises: 0, - averageScore: null, - }, { - username: 'user_2', - exercises: 0, - averageScore: null, - }, { - username: 'user_2', - exercises: 0, - averageScore: null, - }, { - username: 'user_2', - exercises: 0, - averageScore: null, - }, { - username: 'user_2', - exercises: 0, - averageScore: null, - }, { - username: 'user_2', - exercises: 0, - averageScore: null, - }, { - username: 'user_2', - exercises: 0, - averageScore: null, - }, { - username: 'user_3', - exercises: 5, - averageScore: '100%', - }]; - } + return [ + { + label: 'Item 1', + icon: 'edit', + }, + { + label: 'Item 2', + icon: 'edit', + }, + { + label: 'Item 3', + icon: 'edit', + }, + { + label: 'Item 4', + icon: 'edit', + }, + { + label: 'Item 5', + icon: 'edit', + }, + { + label: 'Item 6', + icon: 'edit', + }, + { + label: 'Item 7', + icon: 'edit', + }, + { + label: 'Item 8', + icon: 'edit', + }, + { + label: 'Item 9', + icon: 'edit', + }, + { + label: 'Item 10', + icon: 'edit', + }, + ]; + }, }, }; + + \ No newline at end of file + From ce80b6aaa00f33d400a0a6aede230a4bc886ed07 Mon Sep 17 00:00:00 2001 From: Alex Velez Date: Wed, 21 Feb 2024 08:00:48 -0500 Subject: [PATCH 17/31] Add docs page --- docs/pages/kemptyplaceholder.vue | 79 ---------------------- docs/pages/klistwithoverflow.vue | 108 +++++++++++++++++++++++++++++++ docs/tableOfContents.js | 5 ++ 3 files changed, 113 insertions(+), 79 deletions(-) create mode 100644 docs/pages/klistwithoverflow.vue diff --git a/docs/pages/kemptyplaceholder.vue b/docs/pages/kemptyplaceholder.vue index b2738744c..ee0eb06da 100644 --- a/docs/pages/kemptyplaceholder.vue +++ b/docs/pages/kemptyplaceholder.vue @@ -65,30 +65,6 @@ - - - - @@ -96,61 +72,6 @@ - - - diff --git a/docs/tableOfContents.js b/docs/tableOfContents.js index 55d4d5670..43c4abb4e 100644 --- a/docs/tableOfContents.js +++ b/docs/tableOfContents.js @@ -397,6 +397,11 @@ export default [ title: 'KTextTruncator', isCode: true, }), + new Page({ + path: '/klistwithoverflow', + title: 'KListWithOverflow', + isCode: true, + }), ], }), ]; From 4b20918f0f32abf6439287bd478dba1300cf9599 Mon Sep 17 00:00:00 2001 From: Alex Velez Date: Wed, 21 Feb 2024 09:30:01 -0500 Subject: [PATCH 18/31] Add divider support --- docs/pages/klistwithoverflow.vue | 50 +++++++++++++++++++++++++++++++- lib/KListWithOverflow.vue | 38 ++++++++++++++++++++++-- 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/docs/pages/klistwithoverflow.vue b/docs/pages/klistwithoverflow.vue index a52fdc7d2..846fdeea0 100644 --- a/docs/pages/klistwithoverflow.vue +++ b/docs/pages/klistwithoverflow.vue @@ -65,6 +65,41 @@ +

+ You can also use dividers within the list by passing a { type: "divider" } object, and set a #divider slot. + Note that the visible list will not end with a divider. And a divider object will not be passed as a first overflowed item. +

+ + + + + + + @@ -76,10 +111,19 @@ export default { name: 'DocsKListWithOverflow', + computed: { + dividerStyle() { + return { + height: '100%', + backgroundColor: this.$themeTokens.fineLine, + width: '1px', + }; + }, + }, methods: { getItems(number, dividerMod) { return Array.from({ length: number }, (_, i) => - dividerMod && i % dividerMod === 0 + dividerMod && i && i % dividerMod === 0 ? { type: 'divider' } : { label: `Item ${i + 1}`, icon: 'edit' } ); @@ -105,4 +149,8 @@ padding-right: 16px; } + .divider-wrapper { + padding: 8px 12px; + } + diff --git a/lib/KListWithOverflow.vue b/lib/KListWithOverflow.vue index f89eb91dd..92d2ca4d8 100644 --- a/lib/KListWithOverflow.vue +++ b/lib/KListWithOverflow.vue @@ -8,11 +8,17 @@ ref="list" class="list" > -