@histoire/controls 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +5 -0
- package/dist/components/checkbox/HstCheckbox.story.vue.d.ts +2 -0
- package/dist/components/checkbox/HstCheckbox.test.d.ts +1 -0
- package/dist/components/checkbox/HstCheckbox.vue.d.ts +18 -0
- package/dist/components/input/HstInput.story.vue.d.ts +2 -0
- package/dist/components/input/HstInput.vue.d.ts +18 -0
- package/dist/histoire-setup.d.ts +3 -0
- package/dist/histoire.svg +51 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.es.js +144 -0
- package/dist/peeky-preview.d.ts +1 -0
- package/dist/style.css +678 -0
- package/histoire-dist/__sandbox.html +15 -0
- package/histoire-dist/assets/BaseEmpty.a84c14c8.js +1 -0
- package/histoire-dist/assets/HomeView.f524bd4b.js +1 -0
- package/histoire-dist/assets/HstCheckbox.story.9f622545.js +1 -0
- package/histoire-dist/assets/HstInput.story.945401ce.js +1 -0
- package/histoire-dist/assets/SearchModal.76c035f2.js +1 -0
- package/histoire-dist/assets/StoryView.e4c41518.js +15 -0
- package/histoire-dist/assets/global-components.84d0ab22.js +1 -0
- package/histoire-dist/assets/histoire-text-dark.a529813a.svg +89 -0
- package/histoire-dist/assets/histoire-text.1d4474b5.svg +89 -0
- package/histoire-dist/assets/histoire.8af7bd1f.svg +51 -0
- package/histoire-dist/assets/index.58f51dd0.js +1 -0
- package/histoire-dist/assets/preview-settings.a634d101.js +1 -0
- package/histoire-dist/assets/sandbox.2c60450a.js +1 -0
- package/histoire-dist/assets/style.7657d2ac.css +1 -0
- package/histoire-dist/assets/vendor.70a554f6.js +9 -0
- package/histoire-dist/index.html +15 -0
- package/package.json +63 -0
- package/postcss.config.cjs +8 -0
- package/public/histoire.svg +51 -0
- package/src/components/checkbox/HstCheckbox.story.vue +34 -0
- package/src/components/checkbox/HstCheckbox.test.ts +32 -0
- package/src/components/checkbox/HstCheckbox.vue +82 -0
- package/src/components/checkbox/__snapshots__/HstCheckbox.test.ts.snap +59 -0
- package/src/components/input/HstInput.story.vue +54 -0
- package/src/components/input/HstInput.vue +47 -0
- package/src/histoire-setup.ts +5 -0
- package/src/index.ts +11 -0
- package/src/peeky-preview.ts +1 -0
- package/src/style/main.css +7 -0
- package/tailwind.config.cjs +11 -0
- package/tsconfig.json +40 -0
- package/vite.config.ts +48 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils'
|
|
2
|
+
import HstCheckbox from './HstCheckbox.vue'
|
|
3
|
+
|
|
4
|
+
describe('HstCheckbox', () => {
|
|
5
|
+
test('toggle to checked', async () => {
|
|
6
|
+
const wrapper = mount(HstCheckbox, {
|
|
7
|
+
props: {
|
|
8
|
+
modelValue: false,
|
|
9
|
+
},
|
|
10
|
+
slots: {
|
|
11
|
+
default: 'Label',
|
|
12
|
+
},
|
|
13
|
+
})
|
|
14
|
+
await wrapper.trigger('click')
|
|
15
|
+
expect(wrapper.emitted('update:modelValue')[0]).toEqual([true])
|
|
16
|
+
expect(wrapper.html()).toMatchSnapshot()
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
test('toggle to unchecked', async () => {
|
|
20
|
+
const wrapper = mount(HstCheckbox, {
|
|
21
|
+
props: {
|
|
22
|
+
modelValue: true,
|
|
23
|
+
},
|
|
24
|
+
slots: {
|
|
25
|
+
default: 'Label',
|
|
26
|
+
},
|
|
27
|
+
})
|
|
28
|
+
await wrapper.trigger('click')
|
|
29
|
+
expect(wrapper.emitted('update:modelValue')[0]).toEqual([false])
|
|
30
|
+
expect(wrapper.html()).toMatchSnapshot()
|
|
31
|
+
})
|
|
32
|
+
})
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export default {
|
|
3
|
+
name: 'HstCheckbox',
|
|
4
|
+
}
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<script lang="ts" setup>
|
|
8
|
+
import { computed, ref, watch } from 'vue'
|
|
9
|
+
|
|
10
|
+
const props = defineProps({
|
|
11
|
+
modelValue: {
|
|
12
|
+
type: Boolean,
|
|
13
|
+
default: false,
|
|
14
|
+
},
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const emit = defineEmits({
|
|
18
|
+
'update:modelValue': (newValue: boolean) => true,
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
function toggle () {
|
|
22
|
+
emit('update:modelValue', !props.modelValue)
|
|
23
|
+
animationEnabled.value = true
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// SVG check
|
|
27
|
+
|
|
28
|
+
const path = ref<SVGPathElement>()
|
|
29
|
+
const dasharray = ref(0)
|
|
30
|
+
const progress = computed(() => props.modelValue ? 1 : 0)
|
|
31
|
+
const dashoffset = computed(() => (1 - progress.value) * dasharray.value)
|
|
32
|
+
const animationEnabled = ref(false)
|
|
33
|
+
|
|
34
|
+
watch(path, value => {
|
|
35
|
+
dasharray.value = path.value.getTotalLength?.() ?? 21.21
|
|
36
|
+
})
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<template>
|
|
40
|
+
<div
|
|
41
|
+
role="checkbox"
|
|
42
|
+
tabindex="0"
|
|
43
|
+
class="htw-flex htw-items-center htw-gap-2 htw-select-none htw-px-4 htw-py-3 htw-cursor-pointer hover:htw-bg-primary-100 dark:hover:htw-bg-primary-700"
|
|
44
|
+
@click="toggle()"
|
|
45
|
+
@keydown.enter.prevent="toggle()"
|
|
46
|
+
@keydown.space.prevent="toggle()"
|
|
47
|
+
>
|
|
48
|
+
<div class="htw-text-white htw-w-[16px] htw-h-[16px] htw-relative">
|
|
49
|
+
<div
|
|
50
|
+
class="htw-border group-active:htw-bg-gray-500/20 htw-rounded-sm htw-box-border htw-absolute htw-inset-0 htw-transition-border htw-duration-150 htw-ease-out"
|
|
51
|
+
:class="[
|
|
52
|
+
modelValue
|
|
53
|
+
? 'htw-border-primary-500 htw-border-8'
|
|
54
|
+
: 'htw-border-gray-300 dark:htw-border-gray-500 htw-delay-150',
|
|
55
|
+
]"
|
|
56
|
+
/>
|
|
57
|
+
<svg
|
|
58
|
+
width="16"
|
|
59
|
+
height="16"
|
|
60
|
+
viewBox="0 0 24 24"
|
|
61
|
+
class="htw-relative htw-z-10"
|
|
62
|
+
>
|
|
63
|
+
<path
|
|
64
|
+
ref="path"
|
|
65
|
+
d="m 4 12 l 5 5 l 10 -10"
|
|
66
|
+
fill="none"
|
|
67
|
+
class="htw-stroke-white htw-stroke-2 htw-duration-200 htw-ease-in-out"
|
|
68
|
+
:class="[
|
|
69
|
+
animationEnabled ? 'htw-transition-all' : 'htw-transition-none',
|
|
70
|
+
{
|
|
71
|
+
'htw-delay-150': modelValue,
|
|
72
|
+
},
|
|
73
|
+
]"
|
|
74
|
+
:stroke-dasharray="dasharray"
|
|
75
|
+
:stroke-dashoffset="dashoffset"
|
|
76
|
+
/>
|
|
77
|
+
</svg>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
<slot />
|
|
81
|
+
</div>
|
|
82
|
+
</template>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Peeky snapshots v1.0
|
|
2
|
+
|
|
3
|
+
exports[`HstCheckbox toggle to checked 1`] = `
|
|
4
|
+
<div
|
|
5
|
+
role="checkbox"
|
|
6
|
+
tabindex="0"
|
|
7
|
+
class="htw-flex htw-items-center htw-gap-2 htw-select-none htw-px-4 htw-py-3 htw-cursor-pointer hover:htw-bg-primary-100 dark:hover:htw-bg-primary-700"
|
|
8
|
+
>
|
|
9
|
+
<div class="htw-text-white htw-w-[16px] htw-h-[16px] htw-relative">
|
|
10
|
+
<div class="htw-border group-active:htw-bg-gray-500/20 htw-rounded-sm htw-box-border htw-absolute htw-inset-0 htw-transition-border htw-duration-150 htw-ease-out htw-border-gray-300 dark:htw-border-gray-500 htw-delay-150">
|
|
11
|
+
</div>
|
|
12
|
+
<svg
|
|
13
|
+
width="16"
|
|
14
|
+
height="16"
|
|
15
|
+
viewbox="0 0 24 24"
|
|
16
|
+
class="htw-relative htw-z-10"
|
|
17
|
+
>
|
|
18
|
+
<path
|
|
19
|
+
d="m 4 12 l 5 5 l 10 -10"
|
|
20
|
+
fill="none"
|
|
21
|
+
class="htw-stroke-white htw-stroke-2 htw-duration-200 htw-ease-in-out htw-transition-all"
|
|
22
|
+
stroke-dasharray="21.21"
|
|
23
|
+
stroke-dashoffset="21.21"
|
|
24
|
+
>
|
|
25
|
+
</path>
|
|
26
|
+
</svg>
|
|
27
|
+
</div>
|
|
28
|
+
Label
|
|
29
|
+
</div>
|
|
30
|
+
`;
|
|
31
|
+
|
|
32
|
+
exports[`HstCheckbox toggle to unchecked 1`] = `
|
|
33
|
+
<div
|
|
34
|
+
role="checkbox"
|
|
35
|
+
tabindex="0"
|
|
36
|
+
class="htw-flex htw-items-center htw-gap-2 htw-select-none htw-px-4 htw-py-3 htw-cursor-pointer hover:htw-bg-primary-100 dark:hover:htw-bg-primary-700"
|
|
37
|
+
>
|
|
38
|
+
<div class="htw-text-white htw-w-[16px] htw-h-[16px] htw-relative">
|
|
39
|
+
<div class="htw-border group-active:htw-bg-gray-500/20 htw-rounded-sm htw-box-border htw-absolute htw-inset-0 htw-transition-border htw-duration-150 htw-ease-out htw-border-primary-500 htw-border-8">
|
|
40
|
+
</div>
|
|
41
|
+
<svg
|
|
42
|
+
width="16"
|
|
43
|
+
height="16"
|
|
44
|
+
viewbox="0 0 24 24"
|
|
45
|
+
class="htw-relative htw-z-10"
|
|
46
|
+
>
|
|
47
|
+
<path
|
|
48
|
+
d="m 4 12 l 5 5 l 10 -10"
|
|
49
|
+
fill="none"
|
|
50
|
+
class="htw-stroke-white htw-stroke-2 htw-duration-200 htw-ease-in-out htw-transition-all htw-delay-150"
|
|
51
|
+
stroke-dasharray="21.21"
|
|
52
|
+
stroke-dashoffset="0"
|
|
53
|
+
>
|
|
54
|
+
</path>
|
|
55
|
+
</svg>
|
|
56
|
+
</div>
|
|
57
|
+
Label
|
|
58
|
+
</div>
|
|
59
|
+
`;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import HstInput from './HstInput.vue'
|
|
3
|
+
|
|
4
|
+
function initState () {
|
|
5
|
+
return {
|
|
6
|
+
text: '',
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<Story title="HstInput">
|
|
13
|
+
<Variant
|
|
14
|
+
title="playground"
|
|
15
|
+
:init-state="initState"
|
|
16
|
+
>
|
|
17
|
+
<template #default="{ state }">
|
|
18
|
+
<HstInput
|
|
19
|
+
v-model="state.text"
|
|
20
|
+
>
|
|
21
|
+
Label
|
|
22
|
+
</HstInput>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<template #controls="{ state }">
|
|
26
|
+
<HstInput
|
|
27
|
+
v-model="state.text"
|
|
28
|
+
>
|
|
29
|
+
Label
|
|
30
|
+
</HstInput>
|
|
31
|
+
</template>
|
|
32
|
+
</Variant>
|
|
33
|
+
|
|
34
|
+
<Variant
|
|
35
|
+
title="no-label"
|
|
36
|
+
:init-state="initState"
|
|
37
|
+
>
|
|
38
|
+
<template #default="{ state }">
|
|
39
|
+
<HstInput
|
|
40
|
+
v-model="state.text"
|
|
41
|
+
placeholder="Enter some text..."
|
|
42
|
+
/>
|
|
43
|
+
</template>
|
|
44
|
+
|
|
45
|
+
<template #controls="{ state }">
|
|
46
|
+
<HstInput
|
|
47
|
+
v-model="state.text"
|
|
48
|
+
>
|
|
49
|
+
Label
|
|
50
|
+
</HstInput>
|
|
51
|
+
</template>
|
|
52
|
+
</Variant>
|
|
53
|
+
</Story>
|
|
54
|
+
</template>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export default {
|
|
3
|
+
name: 'HstInput',
|
|
4
|
+
|
|
5
|
+
inheritAttrs: false,
|
|
6
|
+
}
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<script lang="ts" setup>
|
|
10
|
+
import { ref } from 'vue'
|
|
11
|
+
|
|
12
|
+
const props = defineProps({
|
|
13
|
+
modelValue: {
|
|
14
|
+
type: [String, Number],
|
|
15
|
+
default: '',
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const emit = defineEmits({
|
|
20
|
+
'update:modelValue': (newValue: string | number) => true,
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const input = ref<HTMLInputElement>()
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<template>
|
|
27
|
+
<div
|
|
28
|
+
class="htw-p-2 hover:htw-bg-primary-100 dark:hover:htw-bg-primary-700 htw-cursor-text"
|
|
29
|
+
:class="$attrs.class"
|
|
30
|
+
:style="$attrs.style"
|
|
31
|
+
@click="input.focus()"
|
|
32
|
+
>
|
|
33
|
+
<label
|
|
34
|
+
v-if="$slots.default"
|
|
35
|
+
class="htw-text-sm htw-px-2 htw-cursor-text"
|
|
36
|
+
>
|
|
37
|
+
<slot />
|
|
38
|
+
</label>
|
|
39
|
+
<input
|
|
40
|
+
ref="input"
|
|
41
|
+
v-bind="{ ...$attrs, style: null, class: null }"
|
|
42
|
+
:value="modelValue"
|
|
43
|
+
class="htw-text-inherit htw-bg-transparent htw-w-full htw-outline-none htw-px-2 htw-py-0 htw-border htw-border-gray-300 dark:htw-border-gray-500 focus:htw-border-primary-500 dark:focus:htw-border-primary-500 htw-rounded-sm"
|
|
44
|
+
@input="emit('update:modelValue', ($event.target as HTMLInputElement).value)"
|
|
45
|
+
>
|
|
46
|
+
</div>
|
|
47
|
+
</template>
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { App } from 'vue'
|
|
2
|
+
import HstCheckboxVue from './components/checkbox/HstCheckbox.vue'
|
|
3
|
+
import HstInputVue from './components/input/HstInput.vue'
|
|
4
|
+
|
|
5
|
+
export const HstCheckbox = HstCheckboxVue
|
|
6
|
+
export const HstInput = HstInputVue
|
|
7
|
+
|
|
8
|
+
export function registerVueComponents (app: App) {
|
|
9
|
+
app.component('HstCheckbox', HstCheckboxVue)
|
|
10
|
+
app.component('HstInput', HstInputVue)
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import './style/main.css'
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"outDir": "dist",
|
|
7
|
+
"rootDir": "src",
|
|
8
|
+
"allowSyntheticDefaultImports": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"removeComments": false,
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"types": [
|
|
14
|
+
"node",
|
|
15
|
+
"@peeky/test"
|
|
16
|
+
],
|
|
17
|
+
"lib": [
|
|
18
|
+
"ESNext",
|
|
19
|
+
"DOM"
|
|
20
|
+
],
|
|
21
|
+
"sourceMap": false,
|
|
22
|
+
"preserveWatchOutput": true,
|
|
23
|
+
"preserveSymlinks": true,
|
|
24
|
+
// Strict
|
|
25
|
+
"noImplicitAny": false,
|
|
26
|
+
"noImplicitThis": true,
|
|
27
|
+
"alwaysStrict": true,
|
|
28
|
+
"strictBindCallApply": true,
|
|
29
|
+
"strictFunctionTypes": true,
|
|
30
|
+
},
|
|
31
|
+
"include": [
|
|
32
|
+
"src"
|
|
33
|
+
],
|
|
34
|
+
"exclude": [
|
|
35
|
+
"node_modules",
|
|
36
|
+
"generated/**/*",
|
|
37
|
+
"dist/**/*",
|
|
38
|
+
"src/**/*.spec.ts"
|
|
39
|
+
]
|
|
40
|
+
}
|
package/vite.config.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/// <reference types="@peeky/test"/>
|
|
2
|
+
/// <reference types="histoire"/>
|
|
3
|
+
|
|
4
|
+
import { defineConfig } from 'vite'
|
|
5
|
+
import vue from '@vitejs/plugin-vue'
|
|
6
|
+
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
plugins: [
|
|
9
|
+
vue(),
|
|
10
|
+
],
|
|
11
|
+
|
|
12
|
+
build: {
|
|
13
|
+
emptyOutDir: false,
|
|
14
|
+
|
|
15
|
+
lib: {
|
|
16
|
+
entry: 'src/index.ts',
|
|
17
|
+
formats: [
|
|
18
|
+
'es',
|
|
19
|
+
],
|
|
20
|
+
fileName: 'index',
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
rollupOptions: {
|
|
24
|
+
external: [
|
|
25
|
+
'vue',
|
|
26
|
+
],
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
histoire: {
|
|
31
|
+
setupFile: '/src/histoire-setup.ts',
|
|
32
|
+
vite: (config) => {
|
|
33
|
+
config.build.lib = false
|
|
34
|
+
config.build.rollupOptions.external = []
|
|
35
|
+
},
|
|
36
|
+
theme: {
|
|
37
|
+
title: 'Histoire controls',
|
|
38
|
+
favicon: '/histoire.svg',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
test: {
|
|
43
|
+
runtimeEnv: 'dom',
|
|
44
|
+
previewSetupFiles: [
|
|
45
|
+
'src/peeky-preview.ts',
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
})
|