Skip to content

Commit

Permalink
Merge pull request #448 from MisRob/k-show
Browse files Browse the repository at this point in the history
Add supporting code for Kolibri loaders
  • Loading branch information
MisRob authored Sep 25, 2023
2 parents 5bd95bb + cfd99de commit 3ab9801
Show file tree
Hide file tree
Showing 9 changed files with 504 additions and 46 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
Releases are recorded as git tags in the [Github releases](https://github.com/learningequality/kolibri-design-system/releases) page.

## Develop (to become version 1.5.x)

- [#448] - `KCircularLoader`: Renames `show` prop to `shouldShow`
- [#448] - `KCircularLoader`: Adds `disableDefaultTransition` prop
- [#448] - Adds `useKShow` composable
- [#448] - Adds `KTransition` component
- [#426] - Adds `'click'` event to `KTabsList`
- [#425] - Adds `pinned` and `notPinned` icons. Updates `cloud` icon to outline
- [#424] - Adds `laptop` `cloud `and `wifi` icons to KDS
Expand Down Expand Up @@ -38,6 +43,7 @@ Releases are recorded as git tags in the [Github releases](https://github.com/le
[#426]: https://github.com/learningequality/kolibri-design-system/pull/426
[#427]: https://github.com/learningequality/kolibri-design-system/pull/427
[#433]: https://github.com/learningequality/kolibri-design-system/pull/433
[#448]: https://github.com/learningequality/kolibri-design-system/pull/448

## Version 1.4.x

Expand Down
7 changes: 7 additions & 0 deletions docs/pages/kcircularloader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@
</ul>
</DocsPageSection>

<DocsPageSection title="Related" anchor="#related">
<ul>
<li>
<code>KCircularLoader</code>'s <code>minVisibleTime</code> isn't sufficient when switching between more components, for example as part of <code>v-if/v-else</code> blocks. In such situations, <DocsInternalLink text="useKShow" href="/usekshow" /> may come handy.
</li>
</ul>
</DocsPageSection>
</DocsPageTemplate>

</template>
79 changes: 79 additions & 0 deletions docs/pages/ktransition.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<template>

<DocsPageTemplate apiDocs>
<DocsPageSection title="Overview" anchor="#overview">
<p>Exposes predefined set of transitions built on top of Vue's <code>&lt;transition&gt;</code>.</p>
</DocsPageSection>

<DocsPageSection title="Usage" anchor="#usage">
<ul>
<li>Don't forget to define <code>key</code> on child elements of <code>KTransition</code> as described <DocsExternalLink text="in Vue documentation" href="https://v2.vuejs.org/v2/guide/transitions#Transitioning-Between-Elements" />.</li>
</ul>
</DocsPageSection>

<DocsPageSection title="Available transitions" anchor="#overview">
<section>
<h3><code>component-fade-out-in</code></h3>
<p>Suitable when switching between two elements/components.</p>

<DocsShowCode language="html">
<KTransition kind="component-fade-out-in">
<div v-if="isTruthy" key="key-1">
First component
</div>
<div v-else key="key-2">
Second component
</div>
</KTransition>
</DocsShowCode>

<p>Output:</p>
<DocsShow block language="html">
<KTransition kind="component-fade-out-in">
<div v-if="isTruthy" key="key-1">
First component
</div>
<div v-else key="key-2">
Second component
</div>
</KTransition>
</DocsShow>
</section>

</DocsPageSection>

<DocsPageSection title="Related" anchor="#related">
<ul>
<li>
<DocsExternalLink text="Vue's transitions documentation" href="https://v2.vuejs.org/v2/guide/transitions" />
</li>
</ul>
</DocsPageSection>
</DocsPageTemplate>

</template>


<script>
export default {
data() {
return {
isTruthy: true,
intervalId: null,
};
},
mounted() {
this.intervalId = setInterval(() => {
this.isTruthy = !this.isTruthy;
}, 2000);
},
beforeDestroy() {
clearInterval(this.intervalId);
},
};
</script>


<style lang="scss" scoped></style>
196 changes: 196 additions & 0 deletions docs/pages/usekshow.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
<template>

<DocsPageTemplate apiDocs>

<DocsPageSection title="Overview" anchor="#overview">
<p>A composable that offers the <code>show</code> reactive function. This function guarantees that something will be displayed at least for a specified duration after an initial trigger. This is typically used to prevent a jarring user experience when showing or hiding certain elements. For example, it can be used to ensure that a loader remains visible for a certain amount of time, even when the related data has already been loaded.</p>
</DocsPageSection>

<DocsPageSection title="Usage" anchor="#usage">
<code>show(key, shouldShow, minVisibleTime)</code>

<DocsShowCode language="html">
<div v-if="show('key-1', isLoading, minVisibleTime)">
Loading...
</div>
<div v-else>
Loaded!
</div>
</DocsShowCode>
<!-- eslint-disable -->
<!-- prevent prettier from changing indentation -->
<DocsShowCode language="javascript">
import useKShow from 'kolibri-design-system/lib/composables/useKShow';

export default {
setup() {
const { show } = useKShow();
return { show };
}
};
</DocsShowCode>
<!-- eslint-enable -->
</DocsPageSection>

<DocsPageSection title="Example" anchor="#example">
<p>This is a simulation of a typical use-case of showing a loader while fetching data. You can set your own fetch request length and minimum visible time, and then hit the fetch button to see the output.</p>

<DocsShowCode language="html">
<KTransition kind="component-fade-out-in">
<KCircularLoader
v-if="show('key-1', isFetching, minVisibleTime )"
/>
<div v-else>
Loaded!
</div>
</KTransition>
</DocsShowCode>

<div :style="{ marginTop: '24px', display: 'flex' }">
<div>
<span :style="{ marginLeft: '8px' }">Output:</span>
<DocsShow>
<div :style="{ width: '200px', height: '160px', display: 'flex', flexDirection: 'column', justifyContent: 'space-between', padding: '12px 2px 4px 2px' }">
<div>
<KTransition kind="component-fade-out-in">
<KCircularLoader
v-if="show('key-1', isFetching, minVisibleTime )"
key="loader"
disableDefaultTransition
/>
<div v-else key="message" :style="{ textAlign: 'center' }">
Loaded!
</div>
</KTransition>
</div>
<div>
<code>isFetching: {{ isFetching }}</code>
<code>minVisibleTime: {{ minVisibleTime }}</code>
</div>
</div>
</DocsShow>
</div>
<div :style="{ marginTop: '28px', marginLeft: '24px' }">
<span>
<label :style="{ display: 'block' }">Fetch request length (ms)</label>
<input
v-model="fetchingTimeInput"
type="number"
:style="{ display: 'block' }"
>
</span>
<span>
<label :style="{ display: 'block', marginTop: '12px' }">
Minimum visible time (ms)
</label>
<input
v-model="minVisibleTimeInput"
type="number"
:style="{ display: 'block' }"
>
</span>
<KButton :style="{ marginTop: '24px' }" @click="fetchData">
Fetch data
</KButton>
</div>
</div>
</DocsPageSection>

<DocsPageSection title="Related" anchor="#related">
<ul>
<li>
Some components offer a simpler interfance to achieve the same effect when there is no need to be switching between more components. For example, see <DocsInternalLink href="/kcircularloader#prop:minVisibleTime">
KCircularLoader's <code>minVisibleTime</code>
</DocsInternalLink>.
</li>
</ul>
</DocsPageSection>

<DocsPageSection title="Parameters" anchor="#parameters">
<PropsTable :api="params" />
</DocsPageSection>

<DocsPageSection title="Returns" anchor="#returns">
<p><span style="font-weight: bold">Type:</span> <code>boolean</code></p>
<p><span style="font-weight: bold">Description:</span> Returns <code>true</code> after <code>shouldShow</code> becomes truthy and keeps returning <code>true</code> for the duration of <code>minVisibleTime</code> (even when <code>shouldShow</code> changes back to falsy meanwhile). After <code>minVisibleTime</code> elapses and when <code>shouldShow</code> is falsy already, it returns <code>false</code>.</p>
</DocsPageSection>
</DocsPageTemplate>

</template>


<script>
import { ref } from '@vue/composition-api';
import useKShow from '../../lib/composables/useKShow';
import PropsTable from '../common/DocsPageTemplate/jsdocs/PropsTable';
export default {
components: {
PropsTable,
},
setup() {
const { show } = useKShow();
let timeoutId;
const isFetching = ref(false);
const minVisibleTime = ref(5000);
const minVisibleTimeInput = ref(5000);
const fetchingTime = ref(1000);
const fetchingTimeInput = ref(1000);
function fetchData() {
clearTimeout(timeoutId);
fetchingTime.value = fetchingTimeInput.value;
minVisibleTime.value = minVisibleTimeInput.value;
isFetching.value = true;
timeoutId = setTimeout(function() {
isFetching.value = false;
}, fetchingTime.value);
}
return {
show,
isFetching,
fetchingTime,
minVisibleTime,
fetchingTimeInput,
minVisibleTimeInput,
fetchData,
};
},
data() {
return {
params: [
{
name: 'key',
required: true,
type: { name: 'number|string' },
description:
'Each `show` function instance has to pass a key unique in the context of a whole page to this attribute',
},
{
name: 'shouldShow',
required: false,
default: false,
type: { name: 'boolean' },
description:
'Accurate, real-time information on whether something should be shown. For example, it should be set to `false` for a loader immediately after related data have finished loading.',
},
{
name: 'minVisibleTime',
required: false,
default: 0,
type: { name: 'number' },
description: 'For how long should `show` return `true` after an initial trigger',
},
],
};
},
};
</script>
28 changes: 28 additions & 0 deletions docs/tableOfContents.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ const textRelatedKeywords = ['text', 'area', 'field', 'box'];
const layoutRelatedKeywords = ['grid', 'layout', 'container', 'page'];
const responsiveComponentsRelatedKeywords = ['responsive', 'mixin', 'breakpoint'];
const tabsRelatedKeywords = ['tab', 'tabs', 'panel', 'tablist', 'tabpanel'];
const compositionRelatedKeywords = ['composable', 'composition'];

export default [
new Section({
Expand Down Expand Up @@ -170,6 +171,27 @@ export default [
}),
],
}),
new Section({
title: 'Composables',
autoSort: true,
pages: [
new Page({
path: '/usekshow',
title: 'useKShow',
isCode: true,
keywords: [
...compositionRelatedKeywords,
'if',
'show',
'time',
'minimum',
'visible',
'loader',
'loading',
],
}),
],
}),
new Section({
title: 'Code library components',
autoSort: true,
Expand Down Expand Up @@ -359,6 +381,12 @@ export default [
isCode: true,
keywords: tabsRelatedKeywords,
}),
new Page({
path: '/ktransition',
title: 'KTransition',
isCode: true,
keywords: ['transition'],
}),
],
}),
];
2 changes: 2 additions & 0 deletions lib/KThemePlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import KTabsList from './tabs/KTabsList';
import KTabsPanel from './tabs/KTabsPanel';
import KTextbox from './KTextbox';
import KTooltip from './KTooltip';
import KTransition from './KTransition';

import { themeTokens, themeBrand, themePalette, themeOutlineStyle } from './styles/theme';
import globalThemeState from './styles/globalThemeState';
Expand Down Expand Up @@ -119,4 +120,5 @@ export default function KThemePlugin(Vue) {
Vue.component('KTabsPanel', KTabsPanel);
Vue.component('KTextbox', KTextbox);
Vue.component('KTooltip', KTooltip);
Vue.component('KTransition', KTransition);
}
Loading

0 comments on commit 3ab9801

Please sign in to comment.