@histoire/controls 0.2.5 → 0.3.2
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/dist/components/design-tokens/HstTokenGrid.vue.d.ts +5 -5
- package/dist/components/design-tokens/HstTokenList.vue.d.ts +4 -4
- package/dist/components/select/HstSelect.story.vue.d.ts +2 -0
- package/dist/components/select/HstSelect.vue.d.ts +43 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.es.js +298 -81
- package/dist/style-standalone.css +667 -0
- package/dist/style.css +1 -656
- package/package.json +8 -9
- package/src/components/design-tokens/HstColorShades.vue +10 -6
- package/src/components/design-tokens/HstTokenGrid.vue +23 -14
- package/src/components/design-tokens/HstTokenList.vue +15 -11
- package/src/components/select/HstSelect.story.vue +110 -0
- package/src/components/select/HstSelect.vue +67 -0
- package/src/index.ts +9 -0
|
@@ -5,14 +5,12 @@ export default {
|
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
7
|
<script lang="ts" setup>
|
|
8
|
-
import { computed } from 'vue'
|
|
8
|
+
import { computed, ref } from 'vue'
|
|
9
9
|
import { VTooltip as vTooltip } from 'floating-vue'
|
|
10
10
|
import HstCopyIcon from '../HstCopyIcon.vue'
|
|
11
11
|
|
|
12
12
|
const props = defineProps<{
|
|
13
13
|
shades: Record<string, string>
|
|
14
|
-
// @TODO report eslint bug
|
|
15
|
-
// eslint-disable-next-line func-call-spacing
|
|
16
14
|
getName?: (key: string, color: string) => string
|
|
17
15
|
search?: string
|
|
18
16
|
}>()
|
|
@@ -38,6 +36,8 @@ const displayedShades = computed(() => {
|
|
|
38
36
|
}
|
|
39
37
|
return list
|
|
40
38
|
})
|
|
39
|
+
|
|
40
|
+
const hover = ref<string>(null)
|
|
41
41
|
</script>
|
|
42
42
|
|
|
43
43
|
<template>
|
|
@@ -48,7 +48,9 @@ const displayedShades = computed(() => {
|
|
|
48
48
|
<div
|
|
49
49
|
v-for="shade of displayedShades"
|
|
50
50
|
:key="shade.key"
|
|
51
|
-
class="htw-flex htw-flex-col htw-gap-2
|
|
51
|
+
class="htw-flex htw-flex-col htw-gap-2"
|
|
52
|
+
@mouseenter="hover = shade.key"
|
|
53
|
+
@mouseleave="hover = null"
|
|
52
54
|
>
|
|
53
55
|
<slot
|
|
54
56
|
:color="shade.color"
|
|
@@ -67,8 +69,9 @@ const displayedShades = computed(() => {
|
|
|
67
69
|
class="htw-my-0 htw-truncate htw-shrink"
|
|
68
70
|
>{{ shade.name }}</pre>
|
|
69
71
|
<HstCopyIcon
|
|
72
|
+
v-if="hover === shade.key"
|
|
70
73
|
:content="shade.name"
|
|
71
|
-
class="htw-
|
|
74
|
+
class="htw-flex-none"
|
|
72
75
|
/>
|
|
73
76
|
</div>
|
|
74
77
|
<div class="htw-flex htw-gap-1">
|
|
@@ -77,8 +80,9 @@ const displayedShades = computed(() => {
|
|
|
77
80
|
class="htw-my-0 htw-opacity-50 htw-truncate htw-shrink"
|
|
78
81
|
>{{ shade.color }}</pre>
|
|
79
82
|
<HstCopyIcon
|
|
83
|
+
v-if="hover === shade.key"
|
|
80
84
|
:content="shade.color"
|
|
81
|
-
class="htw-
|
|
85
|
+
class="htw-flex-none"
|
|
82
86
|
/>
|
|
83
87
|
</div>
|
|
84
88
|
</div>
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
export default {
|
|
3
|
-
name: '
|
|
3
|
+
name: 'HstTokenGrid',
|
|
4
4
|
}
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
7
|
<script lang="ts" setup>
|
|
8
|
-
import { computed, withDefaults } from 'vue'
|
|
8
|
+
import { computed, ref, withDefaults } from 'vue'
|
|
9
9
|
import { VTooltip as vTooltip } from 'floating-vue'
|
|
10
10
|
import HstCopyIcon from '../HstCopyIcon.vue'
|
|
11
11
|
|
|
12
12
|
const props = withDefaults(defineProps<{
|
|
13
|
-
tokens: Record<string, string | number
|
|
13
|
+
tokens: Record<string, string | number | any[] | Record<string, any>>
|
|
14
14
|
colSize?: number
|
|
15
|
-
|
|
16
|
-
// eslint-disable-next-line func-call-spacing
|
|
17
|
-
getName?: (key: string, value: string | number) => string
|
|
15
|
+
getName?: (key: string, value: string | number | any[] | Record<string, any>) => string
|
|
18
16
|
}>(), {
|
|
19
17
|
colSize: 180,
|
|
20
18
|
getName: null,
|
|
@@ -28,20 +26,29 @@ const processedTokens = computed(() => {
|
|
|
28
26
|
return {
|
|
29
27
|
key,
|
|
30
28
|
name,
|
|
31
|
-
value: typeof value === '
|
|
29
|
+
value: typeof value === 'number' ? value.toString() : value,
|
|
32
30
|
}
|
|
33
31
|
})
|
|
34
32
|
})
|
|
35
33
|
|
|
36
34
|
const colSizePx = computed(() => `${props.colSize}px`)
|
|
35
|
+
|
|
36
|
+
const hover = ref<string>(null)
|
|
37
37
|
</script>
|
|
38
38
|
|
|
39
39
|
<template>
|
|
40
|
-
<div
|
|
40
|
+
<div
|
|
41
|
+
class="htw-bind-col-size htw-grid htw-gap-4 htw-m-4"
|
|
42
|
+
:style="{
|
|
43
|
+
'--histoire-col-size': colSizePx,
|
|
44
|
+
}"
|
|
45
|
+
>
|
|
41
46
|
<div
|
|
42
47
|
v-for="token of processedTokens"
|
|
43
48
|
:key="token.key"
|
|
44
|
-
class="htw-flex htw-flex-col htw-gap-2
|
|
49
|
+
class="htw-flex htw-flex-col htw-gap-2"
|
|
50
|
+
@mouseenter="hover = token.key"
|
|
51
|
+
@mouseleave="hover = null"
|
|
45
52
|
>
|
|
46
53
|
<slot
|
|
47
54
|
:token="token"
|
|
@@ -53,8 +60,9 @@ const colSizePx = computed(() => `${props.colSize}px`)
|
|
|
53
60
|
class="htw-my-0 htw-truncate htw-shrink"
|
|
54
61
|
>{{ token.name }}</pre>
|
|
55
62
|
<HstCopyIcon
|
|
63
|
+
v-if="hover === token.key"
|
|
56
64
|
:content="token.name"
|
|
57
|
-
class="htw-
|
|
65
|
+
class="htw-flex-none"
|
|
58
66
|
/>
|
|
59
67
|
</div>
|
|
60
68
|
<div class="htw-flex htw-gap-1">
|
|
@@ -63,8 +71,9 @@ const colSizePx = computed(() => `${props.colSize}px`)
|
|
|
63
71
|
class="htw-my-0 htw-opacity-50 htw-truncate htw-shrink"
|
|
64
72
|
>{{ token.value }}</pre>
|
|
65
73
|
<HstCopyIcon
|
|
66
|
-
|
|
67
|
-
|
|
74
|
+
v-if="hover === token.key"
|
|
75
|
+
:content="typeof token.value === 'string' ? token.value : JSON.stringify(token.value)"
|
|
76
|
+
class="htw-flex-none"
|
|
68
77
|
/>
|
|
69
78
|
</div>
|
|
70
79
|
</div>
|
|
@@ -72,8 +81,8 @@ const colSizePx = computed(() => `${props.colSize}px`)
|
|
|
72
81
|
</div>
|
|
73
82
|
</template>
|
|
74
83
|
|
|
75
|
-
<style
|
|
84
|
+
<style>
|
|
76
85
|
.htw-bind-col-size {
|
|
77
|
-
grid-template-columns: repeat(auto-fill, minmax(
|
|
86
|
+
grid-template-columns: repeat(auto-fill, minmax(var(--histoire-col-size), 1fr));
|
|
78
87
|
}
|
|
79
88
|
</style>
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
export default {
|
|
3
|
-
name: '
|
|
3
|
+
name: 'HstTokenList',
|
|
4
4
|
}
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
7
|
<script lang="ts" setup>
|
|
8
|
-
import { computed } from 'vue'
|
|
8
|
+
import { computed, ref } from 'vue'
|
|
9
9
|
import HstCopyIcon from '../HstCopyIcon.vue'
|
|
10
10
|
|
|
11
11
|
const props = defineProps<{
|
|
12
|
-
tokens: Record<string, string | number
|
|
13
|
-
|
|
14
|
-
// eslint-disable-next-line func-call-spacing
|
|
15
|
-
getName?: (key: string, value: string | number) => string
|
|
12
|
+
tokens: Record<string, string | number | any[] | Record<string, any>>
|
|
13
|
+
getName?: (key: string, value: string | number | any[] | Record<string, any>) => string
|
|
16
14
|
}>()
|
|
17
15
|
|
|
18
16
|
const processedTokens = computed(() => {
|
|
@@ -23,17 +21,21 @@ const processedTokens = computed(() => {
|
|
|
23
21
|
return {
|
|
24
22
|
key,
|
|
25
23
|
name,
|
|
26
|
-
value: typeof value === '
|
|
24
|
+
value: typeof value === 'number' ? value.toString() : value,
|
|
27
25
|
}
|
|
28
26
|
})
|
|
29
27
|
})
|
|
28
|
+
|
|
29
|
+
const hover = ref<string>(null)
|
|
30
30
|
</script>
|
|
31
31
|
|
|
32
32
|
<template>
|
|
33
33
|
<div
|
|
34
34
|
v-for="token of processedTokens"
|
|
35
35
|
:key="token.key"
|
|
36
|
-
class="htw-flex htw-flex-col htw-gap-2 htw-
|
|
36
|
+
class="htw-flex htw-flex-col htw-gap-2 htw-my-8"
|
|
37
|
+
@mouseenter="hover = token.key"
|
|
38
|
+
@mouseleave="hover = null"
|
|
37
39
|
>
|
|
38
40
|
<slot
|
|
39
41
|
:token="token"
|
|
@@ -42,15 +44,17 @@ const processedTokens = computed(() => {
|
|
|
42
44
|
<div class="htw-flex htw-gap-1">
|
|
43
45
|
<pre class="htw-my-0 htw-truncate htw-shrink">{{ token.name }}</pre>
|
|
44
46
|
<HstCopyIcon
|
|
47
|
+
v-if="hover === token.key"
|
|
45
48
|
:content="token.name"
|
|
46
|
-
class="htw-
|
|
49
|
+
class="htw-flex-none"
|
|
47
50
|
/>
|
|
48
51
|
</div>
|
|
49
52
|
<div class="htw-flex htw-gap-1">
|
|
50
53
|
<pre class="htw-my-0 htw-opacity-50 htw-truncate htw-shrink">{{ token.value }}</pre>
|
|
51
54
|
<HstCopyIcon
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
v-if="hover === token.key"
|
|
56
|
+
:content="typeof token.value === 'string' ? token.value : JSON.stringify(token.value)"
|
|
57
|
+
class="htw-flex-none"
|
|
54
58
|
/>
|
|
55
59
|
</div>
|
|
56
60
|
</div>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import HstSelect from './HstSelect.vue'
|
|
3
|
+
|
|
4
|
+
const options = [
|
|
5
|
+
{ label: 'Crash Bandicoot', value: 'crash-bandicoot' },
|
|
6
|
+
{ label: 'The Last of Us', value: 'the-last-of-us' },
|
|
7
|
+
{ label: 'Ghost of Tsushima', value: 'ghost-of-tsushima' },
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
const flatOptions = options.map(option => option.label)
|
|
11
|
+
|
|
12
|
+
function initState () {
|
|
13
|
+
return {
|
|
14
|
+
label: 'My really long label',
|
|
15
|
+
select: 'crash-bandicoot',
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<Story
|
|
22
|
+
title="HstSelect"
|
|
23
|
+
:layout="{
|
|
24
|
+
type: 'grid',
|
|
25
|
+
width: '100%',
|
|
26
|
+
}"
|
|
27
|
+
>
|
|
28
|
+
<Variant
|
|
29
|
+
title="default"
|
|
30
|
+
:init-state="initState"
|
|
31
|
+
>
|
|
32
|
+
<template #default="{ state }">
|
|
33
|
+
<HstSelect
|
|
34
|
+
v-model="state.select"
|
|
35
|
+
:title="state.label"
|
|
36
|
+
:options="options"
|
|
37
|
+
/>
|
|
38
|
+
</template>
|
|
39
|
+
|
|
40
|
+
<template #controls="{ state }">
|
|
41
|
+
<HstSelect
|
|
42
|
+
v-model="state.select"
|
|
43
|
+
title="Select"
|
|
44
|
+
:options="options"
|
|
45
|
+
/>
|
|
46
|
+
</template>
|
|
47
|
+
</Variant>
|
|
48
|
+
|
|
49
|
+
<Variant
|
|
50
|
+
title="no-label"
|
|
51
|
+
:init-state="initState"
|
|
52
|
+
>
|
|
53
|
+
<template #default="{ state }">
|
|
54
|
+
<HstSelect
|
|
55
|
+
v-model="state.select"
|
|
56
|
+
:options="options"
|
|
57
|
+
/>
|
|
58
|
+
</template>
|
|
59
|
+
<template #controls="{ state }">
|
|
60
|
+
<HstSelect
|
|
61
|
+
v-model="state.select"
|
|
62
|
+
title="Select"
|
|
63
|
+
:options="options"
|
|
64
|
+
/>
|
|
65
|
+
</template>
|
|
66
|
+
</Variant>
|
|
67
|
+
|
|
68
|
+
<Variant
|
|
69
|
+
title="options-as-array-of-objects"
|
|
70
|
+
:init-state="initState"
|
|
71
|
+
>
|
|
72
|
+
<template #default="{ state }">
|
|
73
|
+
<pre class="htw-text-xs htw-bg-gray-50 dark:htw-bg-gray-600 htw-rounded htw-p-4">{{ options }}</pre>
|
|
74
|
+
<HstSelect
|
|
75
|
+
v-model="state.select"
|
|
76
|
+
title="Games"
|
|
77
|
+
:options="options"
|
|
78
|
+
/>
|
|
79
|
+
</template>
|
|
80
|
+
<template #controls="{ state }">
|
|
81
|
+
<HstSelect
|
|
82
|
+
v-model="state.select"
|
|
83
|
+
title="Games"
|
|
84
|
+
:options="options"
|
|
85
|
+
/>
|
|
86
|
+
</template>
|
|
87
|
+
</Variant>
|
|
88
|
+
|
|
89
|
+
<Variant
|
|
90
|
+
title="options-as-array-of-strings"
|
|
91
|
+
:init-state="initState"
|
|
92
|
+
>
|
|
93
|
+
<template #default="{ state }">
|
|
94
|
+
<pre class="htw-text-xs htw-bg-gray-50 dark:htw-bg-gray-600 htw-rounded htw-p-4">{{ flatOptions }}</pre>
|
|
95
|
+
<HstSelect
|
|
96
|
+
v-model="state.select"
|
|
97
|
+
title="Select"
|
|
98
|
+
:options="flatOptions"
|
|
99
|
+
/>
|
|
100
|
+
</template>
|
|
101
|
+
<template #controls="{ state }">
|
|
102
|
+
<HstSelect
|
|
103
|
+
v-model="state.select"
|
|
104
|
+
title="Select"
|
|
105
|
+
:options="flatOptions"
|
|
106
|
+
/>
|
|
107
|
+
</template>
|
|
108
|
+
</Variant>
|
|
109
|
+
</Story>
|
|
110
|
+
</template>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export default {
|
|
3
|
+
name: 'HstSelect',
|
|
4
|
+
}
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<script lang="ts" setup>
|
|
8
|
+
import { ref, computed, ComputedRef, PropType } from 'vue'
|
|
9
|
+
import HstWrapper from '../HstWrapper.vue'
|
|
10
|
+
|
|
11
|
+
export interface HstSelectOptions {
|
|
12
|
+
label: string
|
|
13
|
+
value: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const props = defineProps({
|
|
17
|
+
title: {
|
|
18
|
+
type: String,
|
|
19
|
+
default: '',
|
|
20
|
+
},
|
|
21
|
+
modelValue: {
|
|
22
|
+
type: String,
|
|
23
|
+
default: null,
|
|
24
|
+
},
|
|
25
|
+
options: {
|
|
26
|
+
type: Array as PropType<HstSelectOptions[] | string[]>,
|
|
27
|
+
required: true,
|
|
28
|
+
default: () => [],
|
|
29
|
+
},
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const formattedOtions: ComputedRef<HstSelectOptions[]> =
|
|
33
|
+
computed(() => props.options.map(option => typeof option === 'string' ? { label: option, value: option } as HstSelectOptions : option as HstSelectOptions))
|
|
34
|
+
|
|
35
|
+
const emit = defineEmits({
|
|
36
|
+
'update:modelValue': (newValue: string) => true,
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const select = ref<HTMLInputElement>()
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<template>
|
|
43
|
+
<HstWrapper
|
|
44
|
+
:title="title"
|
|
45
|
+
class="htw-cursor-text htw-items-center"
|
|
46
|
+
:class="$attrs.class"
|
|
47
|
+
:style="$attrs.style"
|
|
48
|
+
@click="select.focus()"
|
|
49
|
+
>
|
|
50
|
+
<select
|
|
51
|
+
ref="select"
|
|
52
|
+
class="htw-text-inherit htw-bg-transparent htw-w-full htw-outline-none htw-px-2 htw-py-1 -htw-my-1 htw-border htw-border-solid htw-border-black/25 dark:htw-border-white/25 focus:htw-border-primary-500 dark:focus:htw-border-primary-500 htw-rounded-sm"
|
|
53
|
+
:value="modelValue"
|
|
54
|
+
@input="emit('update:modelValue', ($event.target as HTMLInputElement).value)"
|
|
55
|
+
>
|
|
56
|
+
<option
|
|
57
|
+
v-for="{ label, value } in formattedOtions"
|
|
58
|
+
v-bind="{ ...$attrs, class: null, style: null }"
|
|
59
|
+
:key="label"
|
|
60
|
+
class="dark:htw-bg-gray-600"
|
|
61
|
+
:value="value"
|
|
62
|
+
>
|
|
63
|
+
{{ label }}
|
|
64
|
+
</option>
|
|
65
|
+
</select>
|
|
66
|
+
</HstWrapper>
|
|
67
|
+
</template>
|
package/src/index.ts
CHANGED
|
@@ -3,7 +3,10 @@ import HstCheckboxVue from './components/checkbox/HstCheckbox.vue'
|
|
|
3
3
|
import HstTextVue from './components/text/HstText.vue'
|
|
4
4
|
import HstNumberVue from './components/number/HstNumber.vue'
|
|
5
5
|
import HstTextareaVue from './components/textarea/HstTextarea.vue'
|
|
6
|
+
import HstSelectVue from './components/select/HstSelect.vue'
|
|
6
7
|
import HstColorShadesVue from './components/design-tokens/HstColorShades.vue'
|
|
8
|
+
import HstTokenListVue from './components/design-tokens/HstTokenList.vue'
|
|
9
|
+
import HstTokenGridVue from './components/design-tokens/HstTokenGrid.vue'
|
|
7
10
|
import HstCopyIconVue from './components/HstCopyIcon.vue'
|
|
8
11
|
|
|
9
12
|
export const HstCheckbox = HstCheckboxVue
|
|
@@ -11,11 +14,17 @@ export const HstText = HstTextVue
|
|
|
11
14
|
export const HstNumber = HstNumberVue
|
|
12
15
|
export const HstTextarea = HstTextareaVue
|
|
13
16
|
export const HstColorShades = HstColorShadesVue
|
|
17
|
+
export const HstTokenList = HstTokenListVue
|
|
18
|
+
export const HstTokenGrid = HstTokenGridVue
|
|
14
19
|
export const HstCopyIcon = HstCopyIconVue
|
|
15
20
|
|
|
16
21
|
export function registerVueComponents (app: App) {
|
|
17
22
|
app.component('HstCheckbox', HstCheckboxVue)
|
|
18
23
|
app.component('HstText', HstTextVue)
|
|
19
24
|
app.component('HstNumber', HstNumberVue)
|
|
25
|
+
app.component('HstSelect', HstSelectVue)
|
|
20
26
|
app.component('HstTextarea', HstTextareaVue)
|
|
27
|
+
app.component('HstColorShades', HstColorShadesVue)
|
|
28
|
+
app.component('HstTokenList', HstTokenListVue)
|
|
29
|
+
app.component('HstTokenGrid', HstTokenGridVue)
|
|
21
30
|
}
|