Skip to content

Commit

Permalink
Merge pull request #727 from BabyElias/gsoc-table-develop
Browse files Browse the repository at this point in the history
Initial Implementation Of KTable Component
  • Loading branch information
MisRob authored Sep 10, 2024
2 parents 0245abf + 7acfa97 commit 754f629
Show file tree
Hide file tree
Showing 12 changed files with 1,167 additions and 0 deletions.
4 changes: 4 additions & 0 deletions custom-icons/sortColumn.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
153 changes: 153 additions & 0 deletions docs/pages/ktable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<template>

<DocsPageTemplate apiDocs>
<DocsPageSection title="Overview" anchor="#overview">
<p>
The <code>KTable</code> component is an accessible and customizable table component designed to handle a variety of data presentation needs. The component is suitable for both simple and complex data tables. It offers:
<ul>
<li>Offers built-in sorting by default</li>
<li>Integrates with already sorted data</li>
<li>Keyboard navigation</li>
<li>Dynamic column resizing</li>
<li>Sticky headers</li>
</ul>
</p>
</DocsPageSection>
<DocsPageSection title="Usage" anchor="#usage">
<!--Non-Sortable Table-->
<h3>Table without sorting functionality</h3>
<p>
This is an example to show how <code>KTable</code> can be used without any sorting functionality, as a simple table. Use of slots is optional.
</p>
<!-- eslint-disable -->
<DocsShowCode language="html">
<KTable
:headers="headers"
:rows="rows"
caption="Non Sortable Table"
>

<template #header="{ header, colIndex }">
<span>{ header.label } (Backend)</span>
</template>
<template #cell="{ content, rowIndex, colIndex }">
<span v-if="colIndex === 2">{ content } (City)</span>
<span v-else>{ content }</span>
</template>
</KTable>

</DocsShowCode>

<DocsShowCode language="javascript">
data() {
return {
headers: [
{ label: 'Name', dataType: 'string' },
{ label: 'Age', dataType: 'number' },
{ label: 'City', dataType: 'string' },
],
rows: [
['John Doe', 28, 'New York'],
['Jane Smith', 34, 'Los Angeles'],
['Samuel Green', 22, 'Chicago'],
['Alice Johnson', 30, 'Houston'],
['Michael Brown', 45, 'Phoenix'],
['Emily Davis', 27, 'Philadelphia'],
]
};
},
</DocsShowCode>

<DocsShow block>
<KTable
:headers="headers"
:rows="rows"
caption="Non-sortable table"
>
<template #header="{ header, colIndex }">
<span>{{ header.label }} (Backend)</span>
</template>
<template #cell="{ content, rowIndex, colIndex }">
<span v-if="colIndex === 2">{{ content }} (City)</span>
<span v-else>{{ content }}</span>
</template>
</KTable>
</DocsShow>

<!-- Frontend Sorting Example-->
<h3>Table with Default Sorting</h3>
<p>
The <code>KTable</code> can be used with default sorting functionality, allowing you to sort data on the client side without the need for server requests. There are 4 permissible data types - <code>string</code>,<code>number</code>,<code>date</code> and <code>undefined</code>. Columns declared with <code>undefined</code> data type are not sortable. This example demonstrates a table with default sorting enabled.
</p>

<DocsShowCode language="html">
<KTable
:headers="headers"
:rows="rows"
caption="Table with built-in sorting"
sortable
/>

</DocsShowCode>

<DocsShowCode language="javascript">
data() {
return {
headers: [
{ label: 'Name', dataType: 'string' },
{ label: 'Age', dataType: 'number' },
{ label: 'City', dataType: 'string' },
],
rows: [
['John Doe', 28, 'New York'],
['Jane Smith', 34, 'Los Angeles'],
['Samuel Green', 22, 'Chicago'],
['Alice Johnson', 30, 'Houston'],
['Michael Brown', 45, 'Phoenix'],
['Emily Davis', 27, 'Philadelphia'],
]
};
},
</DocsShowCode>
<DocsShow block>
<KTable
:headers="headers"
:rows="rows"
caption="Local Sorting Table"
sortable
/>
<!-- eslint-enable -->
</DocsShow>

</DocsPageSection>


</DocsPageTemplate>

</template>


<script>
export default {
name: 'DocsKTable',
data() {
return {
headers: [
{ label: 'Name', dataType: 'string' },
{ label: 'Age', dataType: 'number' },
{ label: 'City', dataType: 'string' },
],
rows: [
['John Doe', 28, 'New York'],
['Jane Smith', 34, 'Los Angeles'],
['Samuel Green', 22, 'Chicago'],
['Alice Johnson', 30, 'Houston'],
['Michael Brown', 45, 'Phoenix'],
['Emily Davis', 27, 'Philadelphia'],
],
};
},
};
</script>
1 change: 1 addition & 0 deletions docs/rstIconReplacements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@
.. |skillsResource| replace:: :raw-html:`<span class="design-system-icon"><svg role="presentation" focusable="false" width="24" height="24" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5 28.75V35h6.25l18.433-18.45-6.25-6.25L5 28.75zm32.683 1.85L30.6 37.684l-8.667-8.667 2.95-2.95 1.667 1.667 4.117-4.134 2.366 2.367-2.433 2.367L32.367 30l2.366-2.333 2.95 2.933zM11.017 18.05l-8.7-8.65L9.4 2.317l2.933 2.95L8.217 9.4 10 11.167l4.1-4.133L16.467 9.4 14.1 11.75l1.667 1.667-4.75 4.633zm23.5-6.383c.65-.65.65-1.667 0-2.35l-3.9-3.833c-.617-.65-1.7-.65-2.35 0L25.2 8.534l6.25 6.25 3.067-3.117z"/></svg></span>`
.. |slideshow| replace:: :raw-html:`<span class="design-system-icon"><svg viewBox="0 0 24 24" role="presentation" focusable="false" xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M22 16V4c0-1.1-.9-2-2-2H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2zm-11-4l2.03 2.71L16 11l4 5H8l3-4zM2 6v14c0 1.1.9 2 2 2h14v-2H4V6H2z"/></svg></span>`
.. |socialSciencesResource| replace:: :raw-html:`<span class="design-system-icon"><svg viewBox="0 0 24 24" role="presentation" focusable="false" xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M12 12.75c1.63 0 3.07.39 4.24.9 1.08.48 1.76 1.56 1.76 2.73V18H6v-1.61c0-1.18.68-2.26 1.76-2.73 1.17-.52 2.61-.91 4.24-.91zM4 13c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm1.13 1.1c-.37-.06-.74-.1-1.13-.1-.99 0-1.93.21-2.78.58A2.01 2.01 0 000 16.43V18h4.5v-1.61c0-.83.23-1.61.63-2.29zM20 13c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm4 3.43c0-.81-.48-1.53-1.22-1.85A6.95 6.95 0 0020 14c-.39 0-.76.04-1.13.1.4.68.63 1.46.63 2.29V18H24v-1.57zM12 6c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3z"/></svg></span>`
.. |sortColumn| replace:: :raw-html:`<span class="design-system-icon"><svg viewBox="0 0 24 24" role="presentation" focusable="false" width="24" height="25" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12.178 4.154l5.177 5.523H7l5.177-5.523zM12.177 20.654L7 15.13h10.354l-5.177 5.524z" fill="#000"/></svg></span>`
.. |sort| replace:: :raw-html:`<span class="design-system-icon"><svg viewBox="0 0 24 24" role="presentation" focusable="false" xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M18 21l-4-4h3V7h-3l4-4 4 4h-3v10h3M2 19v-2h10v2M2 13v-2h7v2M2 7V5h4v2H2z"/></svg></span>`
.. |starBorder| replace:: :raw-html:`<span class="design-system-icon"><svg viewBox="0 0 24 24" role="presentation" focusable="false" xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M22 9.24l-7.19-.62L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21 12 17.27 18.18 21l-1.63-7.03L22 9.24zM12 15.4l-3.76 2.27 1-4.28-3.32-2.88 4.38-.38L12 6.1l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.4z"/></svg></span>`
.. |star| replace:: :raw-html:`<span class="design-system-icon"><svg viewBox="0 0 24 24" role="presentation" focusable="false" xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></svg></span>`
Expand Down
5 changes: 5 additions & 0 deletions docs/tableOfContents.js
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,11 @@ export default [
isCode: true,
keywords: ['button'],
}),
new Page({
path: '/ktable',
title: 'KTable',
isCode: true,
}),
new Page({
path: '/kgrid',
title: 'KGrid',
Expand Down
3 changes: 3 additions & 0 deletions lib/KIcon/iconDefinitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ const KolibriIcons = {
icon: require('./precompiled-icons/le/preview-unavailable.vue').default,
},
sort: { icon: require('./precompiled-icons/le/sort.vue').default },
sortColumn: {
icon: require('./precompiled-icons/le/sortColumn.vue').default,
},

// Features and links
learn: { icon: require('./precompiled-icons/material-icons/school/baseline.vue').default },
Expand Down
12 changes: 12 additions & 0 deletions lib/KIcon/precompiled-icons/le/sortColumn.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<template>

<svg viewBox="0 0 24 24" role="presentation" focusable="false" width="24" height="25" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12.178 4.154l5.177 5.523H7l5.177-5.523zM12.177 20.654L7 15.13h10.354l-5.177 5.524z" fill="#000"/></svg>

</template>


<script>
export default {"name":"icon-804c4e229f501f72a23ba2f5a5cc42d5"}
</script>
85 changes: 85 additions & 0 deletions lib/KTable/KTableGridItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<template>

<td
:class="$computedClass(coreOutlineFocus)"
:style="{ textAlign: textAlign, minWidth: minWidth, width: width }"
tabindex="0"
data-focus="true"
role="gridcell"
@keydown="onKeydown"
>
<slot :content="content">
{{ content }}
</slot>
</td>

</template>


<script>
export default {
name: 'KTableGridItem',
props: {
content: {
type: [String, Number, Boolean, Object, Array],
required: true,
},
rowIndex: {
type: Number,
required: true,
},
colIndex: {
type: Number,
required: true,
},
minWidth: {
type: String,
default: 'auto',
},
width: {
type: String,
default: 'auto',
},
textAlign: {
type: String,
required: true,
},
},
computed: {
coreOutlineFocus() {
return {
':focus': {
...this.$coreOutline,
outlineOffset: '-2px',
},
};
},
},
methods: {
onKeydown(event) {
// Ensures that clickable elements within a table cell, such as buttons and links, can be clicked with ENTER key.
const focusedElement = event.target;
if (
event.key === 'Enter' &&
(focusedElement.tagName === 'BUTTON' || focusedElement.tagName === 'A')
) {
focusedElement.click();
} else {
this.$emit('keydown', event, this.rowIndex, this.colIndex);
}
},
},
};
</script>


<style scoped>
td {
word-wrap: break-word;
white-space: normal;
}
</style>
Loading

0 comments on commit 754f629

Please sign in to comment.