Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ Prerequisites:

- [Yarn](https://yarnpkg.com/) (latest)

Once you have the prerequisites and a local clone of the repository, open a shell to the root of the cloned repo and run `yarn` to install the packages. Once that's done, you can use `yarn build` to build the component. Other scripts are available in `package.json` for things like building in dev mode, running tests, or building documentation.
Once you have the prerequisites and a local clone of the repository, open a shell to the root of the cloned repo and run `yarn` to install the packages. Once that's done, you can use `yarn build` to build. Other scripts are available in `package.json` for things like running tests or building documentation.

### Implement changes

The three main things you'll update are the code, the tests, and the documentation. How you choose to make these updates is up to you. When your changes are pushed and ready for a PR the expectation is that all changes to these areas are done.

#### Make your code changes

There isn't a huge amount of code in a single component like vue-tree, however some code has been split out to simplify how much code you'll need to sift through to make your changes. For instance, most code related to implementing the ARIA recomendations for accessibile tree views is split into mixins used by the main component .vue files. If you find yourself writing a sizable amount of code for something that may benefit from such a split, bring it up in the conversation for the issue you're working on.
There isn't a huge amount of code in a small library like vue-tree, however some code has been split out to simplify how much code you'll need to sift through to make your changes. For instance, most code related to implementing the ARIA recomendations for accessibile tree views is split into composables used by the main component .vue files. (Note: Some of the composables are a bit kludgy due to porting from Vue 2 mixins.) If you find yourself writing a sizable amount of code for something that may benefit from such a split, bring it up in the conversation for the issue you're working on.

This project includes a `.editorconfig` which should help with basic formatting. In addition to these few rules, keep the [Vue Style Guide](https://vuejs.org/v2/style-guide/) in mind when making changes to the components.
This project includes an `.editorconfig` which should help with basic formatting. In addition to these few rules, keep the [Vue Style Guide](https://vuejs.org/style-guide/) in mind when making changes to the components.

#### Update the tests

Expand All @@ -60,7 +60,7 @@ describe('myComponent', () => {

When writing tests, it's often required to have node data to test with. There's a helper method available in `tests/data/node-generator.js` that can help with creating various nodes for testing. See existing tests and the comment in that file for examples of how to craft test node data.

In addition to unit tests, a very simple test site is available at `/tests/local/index.html`. You can run the `test-site` script in `package.json` to start the site. If your changes would make sense with a demonstration, go ahead and add to this site.
In addition to unit tests, the Storybook documentation pages can run locally and provide a way to both document and test changes. You can run `yarn storybook` to start the site. If your changes would make sense with a demonstration, go ahead and add to the demos on this site.

#### Update the documentation

Expand Down
31 changes: 26 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,45 @@ If you're using it in a .vue file:
<tree-view id="my-tree" :initial-model="dataModel"></tree-view>
</template>

// Options API
<script>
import { TreeView } from "@grapoza/vue-tree"

export default {
components: {
TreeView
TreeView
},
data() {
return {
dataModel: [
{id: "numberOrString", label: "Root Node", children: [
{id: 1, label: "Child Node"},
{id: "node2", label: "Second Child"}]
}]
{
id: "numberOrString",
label: "Root Node",
children: [
{id: 1, label: "Child Node"},
{id: "node2", label: "Second Child"}
]
}
]
}
}
}
</script>

// Composition API
<script setup>
import { TreeView } from "@grapoza/vue-tree"
const dataModel = ref([
{
id: "numberOrString",
label: "Root Node",
children: [
{id: 1, label: "Child Node"},
{id: "node2", label: "Second Child"}
]
}
])
</script>
```

Or, import it into your application:
Expand Down
18 changes: 17 additions & 1 deletion src/stories/Home.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ If you're using it in a .vue file:
<tree-view id="my-tree" :initial-model="dataModel"></tree-view>
</template>

// Options API
<script>
import { TreeView } from "@grapoza/vue-tree"

Expand All @@ -73,6 +74,21 @@ export default {
}
}
</script>

// Composition API
<script setup>
import { TreeView } from "@grapoza/vue-tree"
const dataModel = ref([
{
id: "numberOrString",
label: "Root Node",
children: [
{id: 1, label: "Child Node"},
{id: "node2", label: "Second Child"}
]
}
])
</script>
```

Or, import it into your application:
Expand Down Expand Up @@ -201,7 +217,7 @@ The properties below can be specified for each node. Note that `id`, `label`, an
|:---------------------|:----------------|:---------------------------------------------------------------------------|:-----------------------------------|:---------|
| id | Number/String | An ID that uniquely identifies this node within the tree | - | Yes |
| label | String | The text to show in the tree view | - | Yes |
| children | Array\<Object\> | The child nodes of this node | `[]` | |
| children | Array<Object\> | The child nodes of this node | `[]` | |
| treeNodeSpec | Object | The object containing data about the node's capabilities and initial state | See next table | |

The `treeNodeSpec` property contains any data about the node's capabilities and its initial state. This keeps the tree-specific data separate from the data of the model itself. This makes it more convenient to drop data into the tree view as-is, potentially with a `modelDefaults` specified on the tree view to define common values used in the `treeNodeSpec` of every node.
Expand Down
2 changes: 1 addition & 1 deletion src/stories/definitions/TreeView.AddRemove.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const docSourceCode = `
</template>
<script setup>
import { ref } from "vue";
import TreeView from "../../src/components/TreeView.vue";
import { TreeView } from "@grapoza/vue-tree";
import addRemoveTreeData from "../data/addRemoveTreeViewData";

const modelDefaults = ref({ addChildCallback: addChildCallback });
Expand Down
2 changes: 1 addition & 1 deletion src/stories/definitions/TreeView.Async.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const docSourceCode = `
</template>
<script setup>
import { ref } from "vue";
import TreeView from "../../src/components/TreeView.vue";
import { TreeView } from "@grapoza/vue-tree";

const modelDefaults = ref({ loadChildrenAsync: loadChildrenCallback });

Expand Down
8 changes: 5 additions & 3 deletions src/stories/definitions/TreeView.Basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ const Template = (args) => ({
setup() {
return { args };
},
template: `<tree-view v-bind="args" ref="treeViewRef"></tree-view>
template: `<span>
<tree-view v-bind="args" ref="treeViewRef"></tree-view>
<section class="checked-nodes">
<button type="button" style="margin-top: 1rem" @click="refreshCheckedTvList">What's been checked (checkboxes and radiobuttons)?</button>
<ul id="checkedList">
<li v-for="checkedNode in checkedTvNodes">{{ checkedNode.id }}</li>
</ul>
</section>`,
</section>
</span>`,
data() {
return {
checkedTvNodes: []
Expand All @@ -36,7 +38,7 @@ const docsSourceCode = `
</template>
<script setup>
import { ref } from "vue";
import TreeView from "../../src/components/TreeView.vue";
import { TreeView } from "@grapoza/vue-tree";
import treeViewData from "../data/basicTreeViewData";

const tvModel = ref(treeViewData);
Expand Down
8 changes: 5 additions & 3 deletions src/stories/definitions/TreeView.Checkboxes.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ const Template = (args) => ({
setup() {
return { args };
},
template: `<tree-view v-bind="args" ref="treeViewRef"></tree-view>
template: `<span>
<tree-view v-bind="args" ref="treeViewRef"></tree-view>
<section class="checked-nodes">
<button type="button" style="margin-top: 1rem" @click="refreshCheckedTvList">What's been checked?</button>
<ul id="checkedList">
<li v-for="checkedNode in checkedTvNodes">{{ checkedNode.id }}</li>
</ul>
</section>`,
</section>
</span>`,
data() {
return {
checkedTvNodes: []
Expand Down Expand Up @@ -41,7 +43,7 @@ const docSourceCode = `
</template>
<script setup>
import { ref } from "vue";
import TreeView from "../../src/components/TreeView.vue";
import { TreeView } from "@grapoza/vue-tree";
import treeViewData from "../data/checkboxesTreeViewData";

const modelDefaults = ref({
Expand Down
2 changes: 1 addition & 1 deletion src/stories/definitions/TreeView.Customization.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const docClassSourceCode = `
</template>
<script setup>
import { ref } from "vue";
import TreeView from "../../src/components/TreeView.vue";
import { TreeView } from "@grapoza/vue-tree";

const tvModel = ref([
{
Expand Down
9 changes: 5 additions & 4 deletions src/stories/definitions/TreeView.DragDrop.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import TreeView from '../../components/TreeView.vue';
import dragDropTreeData from "../data/dragDropTreeViewData";

const dragDropTemplateHtml =
`<h2>Tree 1</h2>
const dragDropTemplateHtml = `<span>
<h2>Tree 1</h2>
<tree-view :initial-model="args.initialModel.tree1Data" :model-defaults="args.modelDefaults"></tree-view>
<h2>Tree 2</h2>
<tree-view :initial-model="args.initialModel.tree2Data" :model-defaults="args.modelDefaults"></tree-view>
<h2>Text Drop Target</h2>
<textarea style="width: 90%" rows="10"></textarea>`;
<textarea style="width: 90%" rows="10"></textarea>
</span>`;

const Template = (args) => ({
components: { TreeView },
Expand Down Expand Up @@ -41,7 +42,7 @@ const docSourceCode = `
</template>
<script setup>
import { ref } from "vue";
import TreeView from "../../src/components/TreeView.vue";
import { TreeView } from "@grapoza/vue-tree";
import treeViewData from "../data/checkboxesTreeViewData";

const modelDefaults = ref({
Expand Down
8 changes: 5 additions & 3 deletions src/stories/definitions/TreeView.Radiobuttons.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ const Template = (args) => ({
setup() {
return { args };
},
template: `<tree-view v-bind="args" ref="treeViewRef"></tree-view>
template: `<span>
<tree-view v-bind="args" ref="treeViewRef"></tree-view>
<section class="checked-nodes">
<button type="button" style="margin-top: 1rem" @click="refreshCheckedTvList">What's been checked?</button>
<ul id="checkedList">
<li v-for="checkedNode in checkedTvNodes">{{ checkedNode.id }}</li>
</ul>
</section>`,
</section>
</span>`,
data() {
return {
checkedTvNodes: []
Expand Down Expand Up @@ -41,7 +43,7 @@ const docSourceCode = `
</template>
<script setup>
import { ref } from "vue";
import TreeView from "../../src/components/TreeView.vue";
import { TreeView } from "@grapoza/vue-tree";
import treeViewData from "../data/radiobuttonsTreeViewData";

const modelDefaults = ref({
Expand Down
9 changes: 5 additions & 4 deletions src/stories/definitions/TreeView.Selection.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import TreeView from '../../components/TreeView.vue';
import selectionTreeData from "../data/selectionTreeViewData";

const selectionTemplateHtml =
`<label for="modeSelect">Selection Mode</label>
const selectionTemplateHtml = `<span>
<label for="modeSelect">Selection Mode</label>
<select v-model="selectionMode" id="modeSelect" style="margin: 0 0 2rem 1rem;">
<option value="single">Single</option>
<option value="selectionFollowsFocus">Selection Follows Focus</option>
Expand All @@ -15,7 +15,8 @@ const selectionTemplateHtml =
<ul id="selectedList">
<li v-for="selectedNode in selectedNodes">{{ selectedNode.id }}</li>
</ul>
</section>`;
</section>
</span>`;

const Template = (args) => ({
components: { TreeView },
Expand Down Expand Up @@ -53,7 +54,7 @@ const docSourceCode = `
</template>
<script setup>
import { ref } from "vue";
import TreeView from "../../src/components/TreeView.vue";
import { TreeView } from "@grapoza/vue-tree";
import treeViewData from "../data/selectionTreeViewData";

const tvModel = ref(treeViewData);
Expand Down
2 changes: 1 addition & 1 deletion src/stories/definitions/TreeView.SettingDefaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const docSourceCode = `
</template>
<script setup>
import { ref } from "vue";
import TreeView from "../../src/components/TreeView.vue";
import { TreeView } from "@grapoza/vue-tree";

const modelDefaults = ref({
idProperty: 'identifier',
Expand Down
8 changes: 5 additions & 3 deletions src/stories/definitions/TreeView.Slots.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ const Template = (args) => ({
setup() {
return { args };
},
template: `<tree-view v-bind="args">
template: `<span>
<tree-view v-bind="args">
<template v-slot:loading-root>Root loading custom slot (Not used in this demo)</template>
<template v-slot:checkbox="{ model, customClasses, inputId, checkboxChangeHandler }">
<label :for="inputId" :title="model.treeNodeSpec.title">
Expand Down Expand Up @@ -37,7 +38,8 @@ const Template = (args) => ({
LOADING PLACHOLDER FOR CHILDREN OF {{ model[model.treeNodeSpec.labelProperty] }}. This is custom slot content.
</span>
</template>
</tree-view>`
</tree-view>
</span>`
});

export const Slots = Template.bind({});
Expand Down Expand Up @@ -82,7 +84,7 @@ const docsSourceCode = `
</template>
<script setup>
import { ref } from "vue";
import TreeView from "../../src/components/TreeView.vue";
import { TreeView } from "@grapoza/vue-tree";
import treeViewData from "../data/basicTreeViewData";

const tvModel = ref(treeViewData);
Expand Down
2 changes: 1 addition & 1 deletion src/stories/definitions/TreeView.Static.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const docsSourceCode = `
</template>
<script setup>
import { ref } from "vue";
import TreeView from "../../src/components/TreeView.vue";
import { TreeView } from "@grapoza/vue-tree";
import treeViewData from "../data/staticTreeViewData";

const modelDefaults = ref({
Expand Down