@poveste/controls 0.6.0 → 0.7.0

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 (49) hide show
  1. package/package.json +16 -3
  2. package/postcss.config.cjs +0 -7
  3. package/src/components/HstCopyIcon.story.vue +0 -26
  4. package/src/components/HstCopyIcon.vue +0 -38
  5. package/src/components/HstWrapper.vue +0 -41
  6. package/src/components/button/HstButton.story.vue +0 -30
  7. package/src/components/button/HstButton.vue +0 -26
  8. package/src/components/button/HstButtonGroup.story.vue +0 -79
  9. package/src/components/button/HstButtonGroup.vue +0 -71
  10. package/src/components/checkbox/HstCheckbox.spec.ts +0 -28
  11. package/src/components/checkbox/HstCheckbox.story.vue +0 -47
  12. package/src/components/checkbox/HstCheckbox.vue +0 -56
  13. package/src/components/checkbox/HstCheckboxList.story.vue +0 -49
  14. package/src/components/checkbox/HstCheckboxList.vue +0 -82
  15. package/src/components/checkbox/HstSimpleCheckbox.story.vue +0 -28
  16. package/src/components/checkbox/HstSimpleCheckbox.vue +0 -82
  17. package/src/components/checkbox/__snapshots__/HstCheckbox.spec.ts.snap +0 -5
  18. package/src/components/colorselect/HstColorSelect.story.vue +0 -28
  19. package/src/components/colorselect/HstColorSelect.vue +0 -89
  20. package/src/components/design-tokens/HstColorShades.story.vue +0 -392
  21. package/src/components/design-tokens/HstColorShades.vue +0 -101
  22. package/src/components/design-tokens/HstTokenGrid.story.vue +0 -36
  23. package/src/components/design-tokens/HstTokenGrid.vue +0 -88
  24. package/src/components/design-tokens/HstTokenList.story.vue +0 -81
  25. package/src/components/design-tokens/HstTokenList.vue +0 -62
  26. package/src/components/json/HstJson.story.vue +0 -41
  27. package/src/components/json/HstJson.vue +0 -167
  28. package/src/components/json/serialize.spec.ts +0 -85
  29. package/src/components/json/serialize.ts +0 -54
  30. package/src/components/number/HstNumber.story.vue +0 -42
  31. package/src/components/number/HstNumber.vue +0 -95
  32. package/src/components/radio/HstRadio.story.vue +0 -51
  33. package/src/components/radio/HstRadio.vue +0 -109
  34. package/src/components/select/CustomSelect.vue +0 -126
  35. package/src/components/select/HstSelect.story.vue +0 -161
  36. package/src/components/select/HstSelect.vue +0 -40
  37. package/src/components/slider/HstSlider.story.vue +0 -37
  38. package/src/components/slider/HstSlider.vue +0 -106
  39. package/src/components/text/HstText.story.vue +0 -63
  40. package/src/components/text/HstText.vue +0 -44
  41. package/src/components/textarea/HstTextarea.story.vue +0 -35
  42. package/src/components/textarea/HstTextarea.vue +0 -44
  43. package/src/end.d.ts +0 -8
  44. package/src/index.ts +0 -54
  45. package/src/style/main.css +0 -65
  46. package/src/types.ts +0 -4
  47. package/src/utils.ts +0 -12
  48. package/tsconfig.json +0 -53
  49. package/vite.config.ts +0 -46
@@ -1,95 +0,0 @@
1
- <script lang="ts">
2
- export default {
3
- name: 'HstNumber',
4
- inheritAttrs: false,
5
- }
6
- </script>
7
-
8
- <script lang="ts" setup>
9
- import { computed, onUnmounted, ref } from 'vue'
10
- import HstWrapper from '../HstWrapper.vue'
11
-
12
- const props = defineProps<{
13
- title?: string
14
- modelValue?: number | null
15
- }>()
16
-
17
- const emit = defineEmits({
18
- 'update:modelValue': (newValue: number) => true,
19
- })
20
-
21
- const numberModel = computed({
22
- get: () => props.modelValue,
23
- set: (value) => {
24
- emit('update:modelValue', value)
25
- },
26
- })
27
-
28
- const input = ref<HTMLInputElement>()
29
-
30
- function focusAndSelect() {
31
- input.value.focus()
32
- input.value.select()
33
- }
34
-
35
- // Drag to modify
36
-
37
- const isDragging = ref(false)
38
- let startX: number
39
- let startValue: number
40
-
41
- function onMouseDown(event: MouseEvent) {
42
- isDragging.value = true
43
- startX = event.clientX
44
- startValue = numberModel.value
45
- window.addEventListener('mousemove', onMouseMove)
46
- window.addEventListener('mouseup', stopDragging)
47
- }
48
-
49
- function onMouseMove(event: MouseEvent) {
50
- let step = Number.parseFloat(input.value.step)
51
- if (Number.isNaN(step)) {
52
- step = 1
53
- }
54
- numberModel.value = startValue + Math.round((event.clientX - startX) / 10 / step) * step
55
- }
56
-
57
- function stopDragging() {
58
- isDragging.value = false
59
- window.removeEventListener('mousemove', onMouseMove)
60
- window.removeEventListener('mouseup', stopDragging)
61
- }
62
-
63
- onUnmounted(() => {
64
- stopDragging()
65
- })
66
- </script>
67
-
68
- <template>
69
- <HstWrapper
70
- class="poveste-number cursor-ew-resize items-center"
71
- :title="title"
72
- :class="[
73
- $attrs.class,
74
- { 'select-none': isDragging },
75
- ]"
76
- :style="$attrs.style"
77
- @click="focusAndSelect"
78
- @mousedown="onMouseDown"
79
- >
80
- <input
81
- ref="input"
82
- v-bind="{ ...$attrs, class: null, style: null }"
83
- v-model.number="numberModel"
84
- type="number"
85
- :class="{
86
- 'select-none': isDragging,
87
- }"
88
- class="text-inherit bg-transparent w-full outline-none pl-2 py-1 -my-1 border border-solid border-black/25 dark:border-white/25 focus:border-primary-500 dark:focus:border-primary-500 rounded-sm cursor-ew-resize box-border"
89
- >
90
-
91
- <template #actions>
92
- <slot name="actions" />
93
- </template>
94
- </HstWrapper>
95
- </template>
@@ -1,51 +0,0 @@
1
- <script lang="ts" setup>
2
- import HstRadio from './HstRadio.vue'
3
-
4
- const options = {
5
- 'crash-bandicoot': 'Crash Bandicoot',
6
- 'the-last-of-us': 'The Last of Us',
7
- 'ghost-of-tsushima': 'Ghost of Tsushima',
8
- }
9
-
10
- const flatOptions = Object.keys(options)
11
-
12
- const objectOptions = Object.keys(options).map(key => ({
13
- label: options[key],
14
- value: key,
15
- }))
16
-
17
- function initState() {
18
- return {
19
- character: flatOptions[0],
20
- }
21
- }
22
- </script>
23
-
24
- <template>
25
- <Story
26
- title="HstRadio"
27
- group="controls"
28
- :layout="{ type: 'single', iframe: false }"
29
- >
30
- <Variant
31
- title="playground"
32
- :init-state="initState"
33
- >
34
- <template #default="{ state }">
35
- <HstRadio
36
- v-model="state.character"
37
- title="Label"
38
- :options="objectOptions"
39
- />
40
- </template>
41
-
42
- <template #controls="{ state }">
43
- <HstRadio
44
- v-model="state.character"
45
- title="Label"
46
- :options="objectOptions"
47
- />
48
- </template>
49
- </Variant>
50
- </Story>
51
- </template>
@@ -1,109 +0,0 @@
1
- <script lang="ts">
2
- export default {
3
- name: 'HstRadio',
4
- }
5
- </script>
6
-
7
- <script lang="ts" setup>
8
- import type { ComputedRef } from 'vue'
9
- import type { HstControlOption } from '../../types'
10
- import { computed, ref } from 'vue'
11
- import HstWrapper from '../HstWrapper.vue'
12
-
13
- const props = defineProps<{
14
- title?: string
15
- modelValue?: string | null
16
- options: HstControlOption[]
17
- }>()
18
-
19
- const emit = defineEmits<{
20
- (e: 'update:modelValue', value: string): void
21
- }>()
22
-
23
- const formattedOptions: ComputedRef<Record<string, string>> = computed(() => {
24
- if (Array.isArray(props.options)) {
25
- return Object.fromEntries(props.options.map((value: string | HstControlOption) => {
26
- if (typeof value === 'string') {
27
- return [value, value]
28
- }
29
- else {
30
- return [value.value, value.label]
31
- }
32
- }))
33
- }
34
- return props.options
35
- })
36
-
37
- function selectOption(value: string) {
38
- emit('update:modelValue', value)
39
- animationEnabled.value = true
40
- }
41
-
42
- // animationEnabled prevents the animation from triggering on mounted
43
- const animationEnabled = ref(false)
44
- </script>
45
-
46
- <template>
47
- <HstWrapper
48
- role="group"
49
- :title="title"
50
- class="poveste-radio cursor-text"
51
- :class="$attrs.class"
52
- :style="$attrs.style"
53
- >
54
- <div class="-my-1">
55
- <template
56
- v-for="(label, value) in formattedOptions"
57
- :key="value"
58
- >
59
- <input
60
- :id="`${value}-radio_${title}`"
61
- type="radio"
62
- :name="`${value}-radio_${title}`"
63
- :value="value"
64
- :checked="value === modelValue"
65
- class="hidden!"
66
- @change="selectOption(value)"
67
- >
68
- <label
69
- tabindex="0"
70
- :for="`${value}-radio_${title}`"
71
- class="cursor-pointer flex items-center relative py-1 group"
72
- @keydown.enter.prevent="selectOption(value)"
73
- @keydown.space.prevent="selectOption(value)"
74
- >
75
- <svg
76
- width="16"
77
- height="16"
78
- viewBox="-12 -12 24 24"
79
- class="relative z-10 border border-solid text-inherit rounded-full box-border inset-0 transition-border duration-150 ease-out mr-2 group-hover:border-primary-500"
80
- :class="[
81
- modelValue === value
82
- ? 'border-primary-500'
83
- : 'border-black/25 dark:border-white/25',
84
- ]"
85
- >
86
- <circle
87
- r="7"
88
- class="will-change-transform"
89
- :class="[
90
- animationEnabled ? 'transition-all' : 'transition-none',
91
- {
92
- 'delay-150': modelValue === value,
93
- },
94
- modelValue === value
95
- ? 'fill-primary-500'
96
- : 'fill-transparent scale-0',
97
- ]"
98
- />
99
- </svg>
100
- {{ label }}
101
- </label>
102
- </template>
103
- </div>
104
-
105
- <template #actions>
106
- <slot name="actions" />
107
- </template>
108
- </HstWrapper>
109
- </template>
@@ -1,126 +0,0 @@
1
- <script lang="ts">
2
- export default {
3
- name: 'CustomSelect',
4
- }
5
- </script>
6
-
7
- <script lang="ts" setup>
8
- import type { ComputedRef } from 'vue'
9
- import type { HstControlOption } from '../../types'
10
- import { Icon } from '@iconify/vue'
11
- import { Dropdown as VDropdown } from 'floating-vue'
12
- import { computed } from 'vue'
13
-
14
- const props = defineProps<{
15
- modelValue: string
16
- options: Record<string, any> | string[] | number[] | HstControlOption[]
17
- }>()
18
-
19
- const emit = defineEmits<{
20
- (e: 'update:modelValue', value: string): void
21
- }>()
22
-
23
- const formattedOptions: ComputedRef<[any, string][]> = computed(() => {
24
- if (Array.isArray(props.options)) {
25
- return props.options.map((option) => {
26
- if (typeof option === 'string' || typeof option === 'number') {
27
- return [option, String(option)] as [any, string]
28
- }
29
- else {
30
- return [option.value, option.label] as [any, string]
31
- }
32
- })
33
- }
34
- else {
35
- return Object.entries(props.options)
36
- }
37
- })
38
-
39
- const selectedLabel = computed(() => formattedOptions.value.find(([value]) => value === props.modelValue)?.[1])
40
-
41
- function selectValue(value: any, hide: () => void) {
42
- emit('update:modelValue', value)
43
- hide()
44
- }
45
- </script>
46
-
47
- <template>
48
- <VDropdown
49
- auto-size
50
- auto-boundary-max-size
51
- >
52
- <div
53
- class="cursor-pointer w-full outline-none px-2 h-[27px] -my-1 border border-solid border-black/25 dark:border-white/25 hover:border-primary-500 dark:hover:border-primary-500 rounded-sm flex gap-2 items-center leading-normal"
54
- >
55
- <div class="flex-1 truncate">
56
- <slot :label="selectedLabel">
57
- {{ selectedLabel }}
58
- </slot>
59
- </div>
60
- <Icon
61
- icon="carbon:chevron-sort"
62
- class="w-4 h-4 flex-none ml-auto"
63
- />
64
- </div>
65
- <template #popper="{ hide }">
66
- <div class="flex flex-col bg-gray-50 dark:bg-gray-700">
67
- <div
68
- v-for="[value, label] of formattedOptions"
69
- v-bind="{ ...$attrs, class: null, style: null }"
70
- :key="label"
71
- class="px-2 py-1 cursor-pointer hover:bg-primary-100 dark:hover:bg-primary-700"
72
- :class="{
73
- 'bg-primary-200 dark:bg-primary-800': props.modelValue === value,
74
- }"
75
- @click="selectValue(value, hide)"
76
- >
77
- {{ label }}
78
- </div>
79
- </div>
80
- </template>
81
- </VDropdown>
82
- </template>
83
-
84
- <style lang="postcss">
85
- /* v4: @apply in a component <style> needs the theme referenced explicitly. */
86
- @reference "../../style/main.css";
87
-
88
- /* @TODO custom themes */
89
-
90
- .v-popper {
91
- line-height: 0;
92
- }
93
-
94
- .v-popper--theme-dropdown {
95
- /*
96
- * `dark:` rather than `.ptw-dark &` — the chrome CSS is wrapped in `@scope`
97
- * and `.ptw-dark` lives on `<html>`, above the scope root, so a descendant
98
- * rule keyed on it never matches and the select's options fall back to
99
- * floating-vue's stock light theme (black text on the dark UI). See #101.
100
- */
101
- .v-popper__inner {
102
- @apply dark:bg-gray-700 dark:border-gray-850 dark:text-gray-100;
103
- }
104
-
105
- .v-popper__arrow-inner {
106
- @apply dark:border-gray-700;
107
- }
108
-
109
- .v-popper__arrow-outer {
110
- @apply dark:border-gray-850;
111
- }
112
-
113
- &.v-popper__popper--show-from .v-popper__wrapper {
114
- transform: scale(.75);
115
- }
116
-
117
- &.v-popper__popper--show-to .v-popper__wrapper {
118
- transform: none;
119
- transition: transform .15s cubic-bezier(0, 1, .5, 1);
120
- }
121
- }
122
-
123
- .v-popper__popper:focus-visible {
124
- outline: none;
125
- }
126
- </style>
@@ -1,161 +0,0 @@
1
- <script lang="ts" setup>
2
- import HstSelect from './HstSelect.vue'
3
-
4
- const options = {
5
- 'crash-bandicoot': 'Crash Bandicoot',
6
- 'the-last-of-us': 'The Last of Us',
7
- 'ghost-of-tsushima': 'Ghost of Tsushima',
8
- }
9
-
10
- const flatOptions = Object.keys(options)
11
-
12
- const objectOptions = Object.keys(options).map(key => ({
13
- label: options[key],
14
- value: key,
15
- }))
16
-
17
- const numberOptions = [0, 1, 2, 3, 4, 5]
18
-
19
- function initState() {
20
- return {
21
- label: 'My really long label',
22
- select: 'crash-bandicoot',
23
- count: 0,
24
- }
25
- }
26
- </script>
27
-
28
- <template>
29
- <Story
30
- title="HstSelect"
31
- group="controls"
32
- :layout="{
33
- type: 'grid',
34
- width: '100%',
35
- }"
36
- >
37
- <Variant
38
- title="default"
39
- :init-state="initState"
40
- >
41
- <template #default="{ state }">
42
- <HstSelect
43
- v-model="state.select"
44
- :title="state.label"
45
- :options="options"
46
- />
47
- </template>
48
-
49
- <template #controls="{ state }">
50
- <HstSelect
51
- v-model="state.select"
52
- title="Select"
53
- :options="options"
54
- />
55
- </template>
56
- </Variant>
57
-
58
- <Variant
59
- title="no-label"
60
- :init-state="initState"
61
- >
62
- <template #default="{ state }">
63
- <HstSelect
64
- v-model="state.select"
65
- :options="options"
66
- />
67
- </template>
68
- <template #controls="{ state }">
69
- <HstSelect
70
- v-model="state.select"
71
- title="Select"
72
- :options="options"
73
- />
74
- </template>
75
- </Variant>
76
-
77
- <Variant
78
- title="options-as-object"
79
- :init-state="initState"
80
- >
81
- <template #default="{ state }">
82
- <pre class="text-xs bg-gray-50 dark:bg-gray-600 rounded p-4">{{ options }}</pre>
83
- <HstSelect
84
- v-model="state.select"
85
- title="Games"
86
- :options="options"
87
- />
88
- </template>
89
- <template #controls="{ state }">
90
- <HstSelect
91
- v-model="state.select"
92
- title="Games"
93
- :options="options"
94
- />
95
- </template>
96
- </Variant>
97
-
98
- <Variant
99
- title="options-as-array-of-objects"
100
- :init-state="initState"
101
- >
102
- <template #default="{ state }">
103
- <pre class="text-xs bg-gray-50 dark:bg-gray-600 rounded p-4">{{ objectOptions }}</pre>
104
- <HstSelect
105
- v-model="state.select"
106
- title="Games"
107
- :options="objectOptions"
108
- />
109
- </template>
110
- <template #controls="{ state }">
111
- <HstSelect
112
- v-model="state.select"
113
- title="Games"
114
- :options="objectOptions"
115
- />
116
- </template>
117
- </Variant>
118
-
119
- <Variant
120
- title="options-as-array-of-strings"
121
- :init-state="initState"
122
- >
123
- <template #default="{ state }">
124
- <pre class="text-xs bg-gray-50 dark:bg-gray-600 rounded p-4">{{ flatOptions }}</pre>
125
- <HstSelect
126
- v-model="state.select"
127
- title="Select"
128
- :options="flatOptions"
129
- />
130
- </template>
131
- <template #controls="{ state }">
132
- <HstSelect
133
- v-model="state.select"
134
- title="Select"
135
- :options="flatOptions"
136
- />
137
- </template>
138
- </Variant>
139
-
140
- <Variant
141
- title="options-as-array-of-numbers"
142
- :init-state="initState"
143
- >
144
- <template #default="{ state }">
145
- <pre class="text-xs bg-gray-50 dark:bg-gray-600 rounded p-4">{{ numberOptions }}</pre>
146
- <HstSelect
147
- v-model="state.count"
148
- title="Select"
149
- :options="numberOptions"
150
- />
151
- </template>
152
- <template #controls="{ state }">
153
- <HstSelect
154
- v-model="state.count"
155
- title="Select"
156
- :options="numberOptions"
157
- />
158
- </template>
159
- </Variant>
160
- </Story>
161
- </template>
@@ -1,40 +0,0 @@
1
- <script lang="ts">
2
- export default {
3
- name: 'HstSelect',
4
- }
5
- </script>
6
-
7
- <script lang="ts" setup>
8
- import type { HstControlOption } from '../../types'
9
- import HstWrapper from '../HstWrapper.vue'
10
- import CustomSelect from './CustomSelect.vue'
11
-
12
- defineProps<{
13
- title?: string
14
- modelValue?: any
15
- options: Record<string, any> | string[] | HstControlOption[]
16
- }>()
17
-
18
- const emit = defineEmits<{
19
- (e: 'update:modelValue', value: any): void
20
- }>()
21
- </script>
22
-
23
- <template>
24
- <HstWrapper
25
- :title="title"
26
- class="poveste-select cursor-text items-center"
27
- :class="$attrs.class"
28
- :style="$attrs.style"
29
- >
30
- <CustomSelect
31
- :options="options"
32
- :model-value="modelValue"
33
- @update:model-value="emit('update:modelValue', $event)"
34
- />
35
-
36
- <template #actions>
37
- <slot name="actions" />
38
- </template>
39
- </HstWrapper>
40
- </template>
@@ -1,37 +0,0 @@
1
- <script lang="ts" setup>
2
- import { reactive } from 'vue'
3
- import HstSlider from './HstSlider.vue'
4
-
5
- const state = reactive({
6
- value: 20,
7
- min: 0,
8
- max: 100,
9
- step: 5,
10
- })
11
- </script>
12
-
13
- <template>
14
- <Story
15
- title="HstSlider"
16
- group="controls"
17
- :layout="{ type: 'single', iframe: false }"
18
- >
19
- <HstSlider
20
- v-model="state.value"
21
- :step="state.step"
22
- :min="state.min"
23
- :max="state.max"
24
- title="Slide"
25
- />
26
- <pre>{{ state }}</pre>
27
- <template #controls>
28
- <HstSlider
29
- v-model="state.value"
30
- :step="state.step"
31
- :min="state.min"
32
- :max="state.max"
33
- title="Value"
34
- />
35
- </template>
36
- </Story>
37
- </template>