Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add vue adapter #87

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
34 changes: 33 additions & 1 deletion docs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,39 @@
"to": "framework/react/examples/update-on-drag"
}
]
}
}
]
},
{
"framework": "vue",
"menuItems": [
{
"label": "Adapters",
"children": [
{
"label": "Vue Ranger",
"to": "framework/vue/vue-ranger"
}
]
},
{
"label": "API Reference",
"children": [
{
"label": "Basic",
"to": "framework/vue/api/basic"
}
]
},
{
"label": "Examples",
"children": [
{
"label": "Basic",
"to": "framework/vue/examples/basic"
}
]
}
]
}
]
Expand Down
68 changes: 68 additions & 0 deletions docs/framework/vue/api/basic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
name: Basic
route: /api/basic
menu: API
---

## Examples
Want to skip to the implementation? Check out these examples:

- [basic](../../examples/vue/basic)

The API below described how to use the **basic** features.

## Options

### values

```tsx
values: ReadonlyArray<number>
```
**Required** The current value (or values) for the range.

### min

```tsx
min: number
```
**Required** The minimum limit for the range.

### max

```tsx
max: number
```
**Required** The maximum limit for the range.

### stepSize

```ts
stepSize: number
```
**Required** The distance between selectable steps.

### onChange

```ts
onChange: (instance: Ranger<TTrackElement>) => void
```
A function that is called when the handle is released.

## API

### handles
```tsx
handles: ReadonlyArray<{value: number; isActive: boolean; onKeyDownHandler(event): function; onMouseDownHandler(event): function; onTouchStart(event): function}>
```
Handles to be rendered. Each `handle` has the following props:
- `value: number` - The current value for the handle.
- `isActive: boolean` - Denotes if the handle is currently being dragged.
- `onKeyDownHandler(event): func`
- `onMouseDownHandler(event): func`
- `onTouchStart(event): func`

### activeHandleIndex
```tsx
activeHandleIndex: null | number
```
The zero-based index of the handle that is currently being dragged, or `null` if no handle is being dragged.
9 changes: 9 additions & 0 deletions docs/framework/vue/vue-ranger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: Vue Ranger
---

You can install TanStack Ranger with any [NPM](https://npmjs.com) package manager.

```sh
npm install @tanstack/vue-ranger
```
2 changes: 1 addition & 1 deletion docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ Depending on your framework of choice, install one of the following packages:

- [React](./adapters/react-ranger)
- Solid (coming soon!)
- Vue (coming soon!)
- [Vue](./adapters/vue-ranger)
- Svelte (coming soon!)
- Angular (coming soon!)
24 changes: 24 additions & 0 deletions examples/vue/basic/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
6 changes: 6 additions & 0 deletions examples/vue/basic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Example

To run this example:

- `npm install` or `yarn`
- `npm run start` or `yarn start`
14 changes: 14 additions & 0 deletions examples/vue/basic/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script type="module" src="https://cdn.skypack.dev/twind/shim"></script>
<title>Vite + Vue</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
19 changes: 19 additions & 0 deletions examples/vue/basic/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "basic",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"start": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@tanstack/vue-ranger": "0.0.4",
"vue": "^3.4.19"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.4",
"vite": "^5.1.4"
}
}
90 changes: 90 additions & 0 deletions examples/vue/basic/src/App.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<script lang="ts" setup>
import { computed, ref } from 'vue'
import { Ranger, useRanger } from '@tanstack/vue-ranger'

const rangerRefEl = ref<HTMLDivElement | null>(null)

const values = ref([10, 15, 50,])

const ranger = useRanger<HTMLDivElement>(computed(() => ({
min: 0,
max: 100,
values: values.value,
stepSize: 5,

onChange: (instance: Ranger<HTMLDivElement>) => {
values.value = instance.sortedValues
},
getRangerElement: () => rangerRefEl.value,
})))
</script>

<template>
<div class="App" :style="{ padding: '10px' }">
<h1>Basic Range</h1>
<span>Active Index: {{ ranger.activeHandleIndex }}</span>
<br />
<br />
<div>
<div
ref="rangerRefEl"
:style="{
position: 'relative',
userSelect: 'none',
height: '4px',
background: '#ddd',
boxShadow: 'inset 0 1px 2px rgba(0,0,0,.6)',
borderRadius: '2px',
}"
>
<button
v-for="({
value,
onKeyDownHandler,
onMouseDownHandler,
onTouchStart,
isActive,
}, i) in ranger.handles()"
:key="i"
role="slider"
:aria-valuemin="ranger.options.min"
:aria-valuemax="ranger.options.max"
:aria-valuenow="value"
:style="{
position: 'absolute',
top: '50%',
left: `${ranger.getPercentageForValue(value)}%`,
zIndex: isActive ? '1' : '0',
transform: 'translate(-50%, -50%)',
width: '14px',
height: '14px',
outline: 'none',
borderRadius: '100%',
background: 'linear-gradient(to bottom, #eee 45%, #ddd 55%)',
border: 'solid 1px #888',
}"
@keydown="onKeyDownHandler"
@mousedown="onMouseDownHandler"
@touchstart="onTouchStart"
/>
</div>
</div>
<br />
<br />
<br />
<pre
:style="{
display: 'inline-block',
textAlign: 'left',
}"
>
<code>
{{ JSON.stringify({ values }) }}
</code>
</pre>
</div>
</template>

<style scoped>

</style>
4 changes: 4 additions & 0 deletions examples/vue/basic/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')
12 changes: 12 additions & 0 deletions examples/vue/basic/tsconfig.dev.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"composite": true,
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./build/types"
},
"files": ["src/main.tsx"],
"include": [
"src"
// "__tests__/**/*.test.*"
]
}
7 changes: 7 additions & 0 deletions examples/vue/basic/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"strict": true,
"esModuleInterop": true,
"jsx": "react"
}
}
7 changes: 7 additions & 0 deletions examples/vue/basic/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
})
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"pnpm": {
"overrides": {
"@tanstack/ranger": "workspace:*",
"@tanstack/vue-ranger": "workspace:*",
"@tanstack/react-ranger": "workspace:*"
}
},
Expand Down Expand Up @@ -69,7 +70,7 @@
"svelte": "^3.55.0",
"ts-node": "^10.7.0",
"typescript": "^4.9.4",
"vue": "^3.2.33"
"vue": "^3.3.4"
},
"dependencies": {
"@rollup/plugin-commonjs": "^23.0.4",
Expand Down
38 changes: 38 additions & 0 deletions packages/vue-ranger/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
![React Ranger Header](https://github.com/tanstack/ranger/raw/main/media/headerv1.png)

Headless UI for building ranger component in TS/JS and React

<a href="https://twitter.com/intent/tweet?button_hashtag=TanStack" target="\_parent">
<img alt="#TanStack" src="https://img.shields.io/twitter/url?color=%2308a0e9&label=%23TanStack&style=social&url=https%3A%2F%2Ftwitter.com%2Fintent%2Ftweet%3Fbutton_hashtag%3DTanStack" />
</a><a href="https://github.com/TanStack/ranger/actions/workflows/ci.yml">
<img src="https://github.com/tanstack/ranger/actions/workflows/ci.yml/badge.svg" />
</a><a href="https://npmjs.com/package/@tanstack/ranger-core" target="\_parent">
<img alt="" src="https://img.shields.io/npm/dm/@tanstack/ranger-core.svg" />
</a><a href="https://bundlephobia.com/result?p=@tanstack/ranger@latest" target="\_parent">
<img alt="" src="https://badgen.net/bundlephobia/minzip/@tanstack/ranger@latest" />
</a><a href="#badge">
<img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg">
</a><a href="https://github.com/tanstack/ranger/discussions">
<img alt="Join the discussion on Github" src="https://img.shields.io/badge/Github%20Discussions%20%26%20Support-Chat%20now!-blue" />
</a><a href="https://github.com/tanstack/ranger" target="\_parent">
<img alt="" src="https://img.shields.io/github/stars/tanstack/ranger.svg?style=social&label=Star" />
</a><a href="https://twitter.com/tannerlinsley" target="\_parent">
<img alt="" src="https://img.shields.io/twitter/follow/tannerlinsley.svg?style=social&label=Follow" />
</a>

<br />
<br />

Enjoy this library? Try the entire [TanStack](https://tanstack.com)! [React Query](https://github.com/TanStack/react-query), [TanStack Table](https://github.com/TanStack/table), [React Charts](https://github.com/TanStack/react-charts)

## Visit [tanstack.com/ranger](https://tanstack.com/ranger) for docs, guides, API and more!

## Quick Features

- Headless!
- Single or Multiple Handles
- Handle Devider Items
- Custom Steps or Step-Size
- Custom Ticks

<!-- Force -->
7 changes: 7 additions & 0 deletions packages/vue-ranger/__tests__/core/core.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { describe, test, it, expect } from 'vitest'

describe('Vue Ranger', () => {
it('has no tests', () => {
expect('yup').toEqual('yup')
})
})
2 changes: 2 additions & 0 deletions packages/vue-ranger/__tests__/jest.setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// import { act } from '@testing-library/react'
import '@testing-library/jest-dom'
Loading