Skip to content

Commit

Permalink
feat(comp:slider): add slider component (#186)
Browse files Browse the repository at this point in the history
fix #186
  • Loading branch information
imguolao committed Dec 14, 2021
1 parent 4bc51bf commit 38c41e1
Show file tree
Hide file tree
Showing 41 changed files with 1,810 additions and 3 deletions.
17 changes: 17 additions & 0 deletions packages/cdk/utils/src/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,20 @@ export function isVisibleElement(element: HTMLElement | SVGElement | undefined):

return isStyleVisible(element) && isAttributeVisible(element)
}

export function getMouseClientXY(ev: MouseEvent | TouchEvent): { clientX: number; clientY: number } {
let clientX: number
let clientY: number
if (ev.type.startsWith('touch')) {
clientY = (ev as TouchEvent).touches[0].clientY
clientX = (ev as TouchEvent).touches[0].clientX
} else {
clientY = (ev as MouseEvent).clientY
clientX = (ev as MouseEvent).clientX
}

return {
clientX,
clientY,
}
}
53 changes: 53 additions & 0 deletions packages/components/components.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
@import './affix/style/index.less';
@import './alert/style/index.less';
@import './anchor/style/index.less';
@import './avatar/style/index.less';
@import './back-top/style/index.less';
@import './badge/style/index.less';
@import './button/style/index.less';
@import './card/style/index.less';
@import './checkbox/style/index.less';
@import './collapse/style/index.less';
@import './date-picker/style/index.less';
@import './divider/style/index.less';
@import './drawer/style/index.less';
@import './dropdown/style/index.less';
@import './empty/style/index.less';
@import './form/style/index.less';
@import './grid/style/index.less';
@import './header/style/index.less';
@import './icon/style/index.less';
@import './image/style/index.less';
@import './input/style/index.less';
@import './input-number/style/index.less';
@import './layout/style/index.less';
@import './list/style/index.less';
@import './menu/style/index.less';
@import './message/style/index.less';
@import './modal/style/index.less';
@import './notification/style/index.less';
@import './pagination/style/index.less';
@import './popconfirm/style/index.less';
@import './popover/style/index.less';
@import './progress/style/index.less';
@import './radio/style/index.less';
@import './rate/style/index.less';
@import './result/style/index.less';
@import './select/style/index.less';
@import './skeleton/style/index.less';
@import './space/style/index.less';
@import './spin/style/index.less';
@import './statistic/style/index.less';
@import './stepper/style/index.less';
@import './switch/style/index.less';
@import './table/style/index.less';
@import './tabs/style/index.less';
@import './tag/style/index.less';
@import './textarea/style/index.less';
@import './time-picker/style/index.less';
@import './timeline/style/index.less';
@import './tooltip/style/index.less';
@import './tree/style/index.less';
@import './typography/style/index.less';

@import './slider/style/index.less';
1 change: 1 addition & 0 deletions packages/components/default.less
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
@import './result/style/themes/default.less';
@import './select/style/themes/default.less';
@import './skeleton/style/themes/default.less';
@import './slider/style/themes/default.less';
@import './space/style/themes/default.less';
@import './spin/style/themes/default.less';
@import './statistic/style/themes/default.less';
Expand Down
2 changes: 2 additions & 0 deletions packages/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import { IxRate } from '@idux/components/rate'
import { IxResult } from '@idux/components/result'
import { IxSelect, IxSelectOption, IxSelectOptionGroup } from '@idux/components/select'
import { IxSkeleton } from '@idux/components/skeleton'
import { IxSlider } from '@idux/components/slider'
import { IxSpace } from '@idux/components/space'
import { IxSpin } from '@idux/components/spin'
import { IxStatistic } from '@idux/components/statistic'
Expand Down Expand Up @@ -122,6 +123,7 @@ const components = [
IxSelectOption,
IxSelectOptionGroup,
IxSkeleton,
IxSlider,
IxSpace,
IxSpin,
IxStatistic,
Expand Down
2 changes: 1 addition & 1 deletion packages/components/input-number/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ export type InputNumberComponent = DefineComponent<
Omit<HTMLAttributes, keyof InputNumberPublicProps> & InputNumberPublicProps,
InputNumberBindings
>
export type InputNumberInstance = InstanceType<DefineComponent<InputNumberProps>>
export type InputNumberInstance = InstanceType<DefineComponent<InputNumberProps, InputNumberBindings>>
4 changes: 2 additions & 2 deletions packages/components/input-number/src/useInputNumber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,6 @@ export function getPrecision(value: number | undefined | null): number {
return 0
}

const fraction = String(value).split('.')[1]
return fraction ? fraction.length : 0
const decimal = String(value).split('.')[1]
return decimal ? decimal.length : 0
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Slider render work 1`] = `
"<div class=\\"ix-slider\\">
<div class=\\"ix-slider-rail\\"></div>
<div class=\\"ix-slider-track\\" style=\\"left: 0%; width: 30%;\\"></div>
<div class=\\"ix-slider-step\\"></div>
<div role=\\"slider\\" tabindex=\\"0\\" aria-label=\\"Slider\\" aria-valuemin=\\"0\\" aria-valuemax=\\"100\\" aria-valuenow=\\"30\\" aria-readonly=\\"false\\" aria-orientation=\\"horizontal\\" style=\\"transform: translateX(-50%); left: 30%;\\" class=\\"ix-slider-thumb\\"></div>
<!---->
<div class=\\"ix-slider-mark\\">
<!---->
</div>
</div>"
`;
84 changes: 84 additions & 0 deletions packages/components/slider/__tests__/slider.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { mount } from '@vue/test-utils'
import { ref } from 'vue'

import { renderWork } from '@tests'

import Slider from '../src/Slider'
import { SliderProps } from '../src/types'

describe('Slider', () => {
// const SliderMount = (options?: MountingOptions<Partial<SliderProps>>) => mount(Slider, { ...options })

renderWork<SliderProps>(Slider, {
props: { value: 30 },
})

test('v-model work', async () => {
const valueRef = ref(1)
const wrapper = mount({
components: { Slider },
template: `<Slider v-model:value="valueRef" />`,
setup() {
return { valueRef }
},
})
const thumb = wrapper.find('.ix-slider-thumb')

expect(valueRef.value).toBe(1)
expect(getComputedStyle(thumb.element).left).toBe('1%')

await thumb.trigger('focus')
await thumb.trigger('keydown', { code: 'ArrowUp' })

expect(valueRef.value).toBe(2)
expect(getComputedStyle(thumb.element).left).toBe('2%')
})

test('range work', () => {
const valueRef = ref([20, 50])
const wrapper = mount({
components: { Slider },
template: `<Slider v-model:value="valueRef" range />`,
setup() {
return { valueRef }
},
})
const thumbs = wrapper.findAll('.ix-slider-thumb')

expect(valueRef.value).toEqual([20, 50])
expect(getComputedStyle(thumbs[0].element).left).toBe('20%')
expect(getComputedStyle(thumbs[1].element).left).toBe('50%')
})

test('vertical work', () => {
const valueRef = ref(30)
const wrapper = mount({
components: { Slider },
template: `<Slider v-model:value="valueRef" vertical style="height: 300px" />`,
setup() {
return { valueRef }
},
})
const thumb = wrapper.find('.ix-slider-thumb')

expect(valueRef.value).toBe(30)
expect(getComputedStyle(thumb.element).left).toBe('')
expect(getComputedStyle(thumb.element).bottom).toBe('30%')
})

test('reverse work', () => {
const valueRef = ref(30)
const wrapper = mount({
components: { Slider },
template: `<Slider v-model:value="valueRef" reverse />`,
setup() {
return { valueRef }
},
})
const thumb = wrapper.find('.ix-slider-thumb')

expect(valueRef.value).toBe(30)
expect(getComputedStyle(thumb.element).left).toBe('')
expect(getComputedStyle(thumb.element).right).toBe('30%')
})
})
14 changes: 14 additions & 0 deletions packages/components/slider/demo/Basic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title:
zh: 基本使用
en: Basic usage
order: 0
---

## zh

最简单的用法。

## en

The simplest usage.
13 changes: 13 additions & 0 deletions packages/components/slider/demo/Basic.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<template>
<IxSlider v-model:value="value0" :disabled="isDisabled"></IxSlider>
<IxSlider v-model:value="value1" :disabled="isDisabled" range></IxSlider>
Disabled: <IxSwitch v-model:checked="isDisabled"></IxSwitch>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const value0 = ref(30)
const value1 = ref([20, 50])
const isDisabled = ref(false)
</script>
14 changes: 14 additions & 0 deletions packages/components/slider/demo/Event.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title:
zh: 事件
en: Event
order: 0
---

## zh

在拖动滑块的过程中会触发 `onInput` 事件,并把改变后的值作为参数传入。

`Slider` 的值发生改变后,会触发 `onChange` 事件,并把改变后的值作为参数传入,一般情况下,`onChange` 都在 `mouseup` 阶段触发。

## en
19 changes: 19 additions & 0 deletions packages/components/slider/demo/Event.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<template>
<IxSlider v-model:value="value0" @change="onChange" @input="onInput"></IxSlider>
<IxSlider v-model:value="value1" range @change="onChange" @input="onInput"></IxSlider>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const value0 = ref(30)
const value1 = ref([20, 50])
function onInput(val: number | number[]) {
console.log('input', val)
}
function onChange(val: number | number[]) {
console.log('change', val)
}
</script>
14 changes: 14 additions & 0 deletions packages/components/slider/demo/InputNumber.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title:
zh: 显示输入框
en: show input number
order: 0
---

## zh

[数字输入框](components/input-number/zh) 组件保持同步。

## en

Synchronize with [InputNumber](components/input-number/en) component.
33 changes: 33 additions & 0 deletions packages/components/slider/demo/InputNumber.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<template>
<IxRow>
<IxCol span="16">
<IxSlider v-model:value="value0" :min="0" :max="20" @change="onChange" @input="onInput"></IxSlider>
</IxCol>
<IxCol span="6" offset="1">
<IxInputNumber v-model:value="value0" :min="0" :max="20"></IxInputNumber>
</IxCol>
</IxRow>
<IxRow>
<IxCol span="16">
<IxSlider v-model:value="value1" :min="0" :max="1" :step="0.01" @change="onChange" @input="onInput"></IxSlider>
</IxCol>
<IxCol span="6" offset="1">
<IxInputNumber v-model:value="value1" :min="0" :max="1" :step="0.01"></IxInputNumber>
</IxCol>
</IxRow>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const value0 = ref(3)
const value1 = ref(0.5)
function onInput(val: number | number[]) {
console.log('input', val)
}
function onChange(val: number | number[]) {
console.log('changed', val)
}
</script>
14 changes: 14 additions & 0 deletions packages/components/slider/demo/Keyboard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title:
zh: 键盘行为
en: Keyboard
order: 0
---

## zh

使用 `keyboard` 属性可以控制键盘行为,当滑块获得焦点后,使用方向键可以控制滑块进行移动。

## en

Control keyboard behavior by `keyboard`.
13 changes: 13 additions & 0 deletions packages/components/slider/demo/Keyboard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<template>
<IxSlider v-model:value="value0" :keyboard="keyboard"></IxSlider>
<IxSlider v-model:value="value1" :keyboard="keyboard" range></IxSlider>
Use Keyboard Behavior: <IxSwitch v-model:checked="keyboard"></IxSwitch>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const value0 = ref(30)
const value1 = ref([20, 50])
const keyboard = ref(true)
</script>
12 changes: 12 additions & 0 deletions packages/components/slider/demo/Marks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
title:
zh: 标签
en: Marks
order: 0
---

## zh

使用 `marks` 属性标注分段式滑块,使用 `value` 指定滑块位置。当 `step=null` 时,`Slider` 的可选值仅有 `marks` 标出来的部分。

## en
26 changes: 26 additions & 0 deletions packages/components/slider/demo/Marks.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<template>
<h4>marks & step</h4>
<IxSlider v-model:value="value0" :marks="marks"></IxSlider>

<h4>step=null</h4>
<IxSlider v-model:value="value1" :marks="marks" :step="null"></IxSlider>
</template>

<script setup lang="ts">
import { h, ref } from 'vue'
const marks = {
0: '0°C',
26: '26°C',
37: '37°C',
100: {
style: {
color: 'red',
},
label: h('strong', '100°C'),
},
}
const value0 = ref(30)
const value1 = ref(50)
</script>
Loading

0 comments on commit 38c41e1

Please sign in to comment.