@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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -0
  3. package/dist/components/checkbox/HstCheckbox.story.vue.d.ts +2 -0
  4. package/dist/components/checkbox/HstCheckbox.test.d.ts +1 -0
  5. package/dist/components/checkbox/HstCheckbox.vue.d.ts +18 -0
  6. package/dist/components/input/HstInput.story.vue.d.ts +2 -0
  7. package/dist/components/input/HstInput.vue.d.ts +18 -0
  8. package/dist/histoire-setup.d.ts +3 -0
  9. package/dist/histoire.svg +51 -0
  10. package/dist/index.d.ts +36 -0
  11. package/dist/index.es.js +144 -0
  12. package/dist/peeky-preview.d.ts +1 -0
  13. package/dist/style.css +678 -0
  14. package/histoire-dist/__sandbox.html +15 -0
  15. package/histoire-dist/assets/BaseEmpty.a84c14c8.js +1 -0
  16. package/histoire-dist/assets/HomeView.f524bd4b.js +1 -0
  17. package/histoire-dist/assets/HstCheckbox.story.9f622545.js +1 -0
  18. package/histoire-dist/assets/HstInput.story.945401ce.js +1 -0
  19. package/histoire-dist/assets/SearchModal.76c035f2.js +1 -0
  20. package/histoire-dist/assets/StoryView.e4c41518.js +15 -0
  21. package/histoire-dist/assets/global-components.84d0ab22.js +1 -0
  22. package/histoire-dist/assets/histoire-text-dark.a529813a.svg +89 -0
  23. package/histoire-dist/assets/histoire-text.1d4474b5.svg +89 -0
  24. package/histoire-dist/assets/histoire.8af7bd1f.svg +51 -0
  25. package/histoire-dist/assets/index.58f51dd0.js +1 -0
  26. package/histoire-dist/assets/preview-settings.a634d101.js +1 -0
  27. package/histoire-dist/assets/sandbox.2c60450a.js +1 -0
  28. package/histoire-dist/assets/style.7657d2ac.css +1 -0
  29. package/histoire-dist/assets/vendor.70a554f6.js +9 -0
  30. package/histoire-dist/index.html +15 -0
  31. package/package.json +63 -0
  32. package/postcss.config.cjs +8 -0
  33. package/public/histoire.svg +51 -0
  34. package/src/components/checkbox/HstCheckbox.story.vue +34 -0
  35. package/src/components/checkbox/HstCheckbox.test.ts +32 -0
  36. package/src/components/checkbox/HstCheckbox.vue +82 -0
  37. package/src/components/checkbox/__snapshots__/HstCheckbox.test.ts.snap +59 -0
  38. package/src/components/input/HstInput.story.vue +54 -0
  39. package/src/components/input/HstInput.vue +47 -0
  40. package/src/histoire-setup.ts +5 -0
  41. package/src/index.ts +11 -0
  42. package/src/peeky-preview.ts +1 -0
  43. package/src/style/main.css +7 -0
  44. package/tailwind.config.cjs +11 -0
  45. package/tsconfig.json +40 -0
  46. 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>
@@ -0,0 +1,5 @@
1
+ import './style/main.css'
2
+
3
+ export default () => {
4
+ // Noop
5
+ }
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'
@@ -0,0 +1,7 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ body {
6
+ @apply dark:htw-text-gray-100;
7
+ }
@@ -0,0 +1,11 @@
1
+ const inheritedConfig = require('../../tailwind.config.cjs')
2
+
3
+ module.exports = {
4
+ ...inheritedConfig,
5
+ content: [
6
+ './src/**/*.{vue,js,ts,jsx,tsx,md}',
7
+ ],
8
+ // corePlugins: {
9
+ // preflight: false,
10
+ // },
11
+ }
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
+ })