@poveste/controls 0.2.0 → 0.3.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.
- package/dist/index.es.css +2 -1
- package/dist/index.es.js +13222 -16350
- package/dist/style-standalone.css +877 -964
- package/package.json +11 -11
- package/postcss.config.cjs +3 -4
- package/src/components/HstCopyIcon.vue +1 -1
- package/src/components/HstWrapper.vue +4 -4
- package/src/components/button/HstButton.story.vue +1 -1
- package/src/components/button/HstButton.vue +7 -7
- package/src/components/button/HstButtonGroup.vue +7 -7
- package/src/components/checkbox/HstCheckbox.vue +1 -1
- package/src/components/checkbox/HstCheckboxList.vue +8 -8
- package/src/components/checkbox/HstSimpleCheckbox.vue +9 -9
- package/src/components/checkbox/__snapshots__/HstCheckbox.spec.ts.snap +2 -2
- package/src/components/colorselect/HstColorSelect.vue +3 -3
- package/src/components/design-tokens/HstColorShades.story.vue +3 -3
- package/src/components/design-tokens/HstColorShades.vue +9 -9
- package/src/components/design-tokens/HstTokenGrid.story.vue +1 -1
- package/src/components/design-tokens/HstTokenGrid.vue +9 -9
- package/src/components/design-tokens/HstTokenList.story.vue +2 -2
- package/src/components/design-tokens/HstTokenList.vue +8 -8
- package/src/components/json/HstJson.vue +3 -3
- package/src/components/number/HstNumber.vue +4 -4
- package/src/components/radio/HstRadio.vue +16 -16
- package/src/components/select/CustomSelect.vue +25 -18
- package/src/components/select/HstSelect.story.vue +4 -4
- package/src/components/select/HstSelect.vue +1 -1
- package/src/components/slider/HstSlider.vue +15 -12
- package/src/components/text/HstText.vue +2 -2
- package/src/components/textarea/HstTextarea.vue +2 -2
- package/src/style/main.css +52 -4
- package/tsconfig.json +1 -1
- package/tailwind.config.cjs +0 -13
|
@@ -16,6 +16,10 @@ const props = defineProps<{
|
|
|
16
16
|
options: HstControlOption[]
|
|
17
17
|
}>()
|
|
18
18
|
|
|
19
|
+
const emit = defineEmits<{
|
|
20
|
+
(e: 'update:modelValue', value: string): void
|
|
21
|
+
}>()
|
|
22
|
+
|
|
19
23
|
const formattedOptions: ComputedRef<Record<string, string>> = computed(() => {
|
|
20
24
|
if (Array.isArray(props.options)) {
|
|
21
25
|
return Object.fromEntries(props.options.map((value: string | HstControlOption) => {
|
|
@@ -30,10 +34,6 @@ const formattedOptions: ComputedRef<Record<string, string>> = computed(() => {
|
|
|
30
34
|
return props.options
|
|
31
35
|
})
|
|
32
36
|
|
|
33
|
-
const emit = defineEmits<{
|
|
34
|
-
(e: 'update:modelValue', value: string): void
|
|
35
|
-
}>()
|
|
36
|
-
|
|
37
37
|
function selectOption(value: string) {
|
|
38
38
|
emit('update:modelValue', value)
|
|
39
39
|
animationEnabled.value = true
|
|
@@ -47,11 +47,11 @@ const animationEnabled = ref(false)
|
|
|
47
47
|
<HstWrapper
|
|
48
48
|
role="group"
|
|
49
49
|
:title="title"
|
|
50
|
-
class="poveste-radio
|
|
50
|
+
class="poveste-radio cursor-text"
|
|
51
51
|
:class="$attrs.class"
|
|
52
52
|
:style="$attrs.style"
|
|
53
53
|
>
|
|
54
|
-
<div class="-
|
|
54
|
+
<div class="-my-1">
|
|
55
55
|
<template
|
|
56
56
|
v-for="(label, value) in formattedOptions"
|
|
57
57
|
:key="value"
|
|
@@ -62,13 +62,13 @@ const animationEnabled = ref(false)
|
|
|
62
62
|
:name="`${value}-radio_${title}`"
|
|
63
63
|
:value="value"
|
|
64
64
|
:checked="value === modelValue"
|
|
65
|
-
class="!
|
|
65
|
+
class="hidden!"
|
|
66
66
|
@change="selectOption(value)"
|
|
67
67
|
>
|
|
68
68
|
<label
|
|
69
69
|
tabindex="0"
|
|
70
70
|
:for="`${value}-radio_${title}`"
|
|
71
|
-
class="
|
|
71
|
+
class="cursor-pointer flex items-center relative py-1 group"
|
|
72
72
|
@keydown.enter.prevent="selectOption(value)"
|
|
73
73
|
@keydown.space.prevent="selectOption(value)"
|
|
74
74
|
>
|
|
@@ -76,24 +76,24 @@ const animationEnabled = ref(false)
|
|
|
76
76
|
width="16"
|
|
77
77
|
height="16"
|
|
78
78
|
viewBox="-12 -12 24 24"
|
|
79
|
-
class="
|
|
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
80
|
:class="[
|
|
81
81
|
modelValue === value
|
|
82
|
-
? '
|
|
83
|
-
: '
|
|
82
|
+
? 'border-primary-500'
|
|
83
|
+
: 'border-black/25 dark:border-white/25',
|
|
84
84
|
]"
|
|
85
85
|
>
|
|
86
86
|
<circle
|
|
87
87
|
r="7"
|
|
88
|
-
class="
|
|
88
|
+
class="will-change-transform"
|
|
89
89
|
:class="[
|
|
90
|
-
animationEnabled ? '
|
|
90
|
+
animationEnabled ? 'transition-all' : 'transition-none',
|
|
91
91
|
{
|
|
92
|
-
'
|
|
92
|
+
'delay-150': modelValue === value,
|
|
93
93
|
},
|
|
94
94
|
modelValue === value
|
|
95
|
-
? '
|
|
96
|
-
: '
|
|
95
|
+
? 'fill-primary-500'
|
|
96
|
+
: 'fill-transparent scale-0',
|
|
97
97
|
]"
|
|
98
98
|
/>
|
|
99
99
|
</svg>
|
|
@@ -50,27 +50,27 @@ function selectValue(value: any, hide: () => void) {
|
|
|
50
50
|
auto-boundary-max-size
|
|
51
51
|
>
|
|
52
52
|
<div
|
|
53
|
-
class="
|
|
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
54
|
>
|
|
55
|
-
<div class="
|
|
55
|
+
<div class="flex-1 truncate">
|
|
56
56
|
<slot :label="selectedLabel">
|
|
57
57
|
{{ selectedLabel }}
|
|
58
58
|
</slot>
|
|
59
59
|
</div>
|
|
60
60
|
<Icon
|
|
61
61
|
icon="carbon:chevron-sort"
|
|
62
|
-
class="
|
|
62
|
+
class="w-4 h-4 flex-none ml-auto"
|
|
63
63
|
/>
|
|
64
64
|
</div>
|
|
65
65
|
<template #popper="{ hide }">
|
|
66
|
-
<div class="
|
|
66
|
+
<div class="flex flex-col bg-gray-50 dark:bg-gray-700">
|
|
67
67
|
<div
|
|
68
68
|
v-for="[value, label] of formattedOptions"
|
|
69
69
|
v-bind="{ ...$attrs, class: null, style: null }"
|
|
70
70
|
:key="label"
|
|
71
|
-
class="
|
|
71
|
+
class="px-2 py-1 cursor-pointer hover:bg-primary-100 dark:hover:bg-primary-700"
|
|
72
72
|
:class="{
|
|
73
|
-
'
|
|
73
|
+
'bg-primary-200 dark:bg-primary-800': props.modelValue === value,
|
|
74
74
|
}"
|
|
75
75
|
@click="selectValue(value, hide)"
|
|
76
76
|
>
|
|
@@ -82,6 +82,9 @@ function selectValue(value: any, hide: () => void) {
|
|
|
82
82
|
</template>
|
|
83
83
|
|
|
84
84
|
<style lang="postcss">
|
|
85
|
+
/* v4: @apply in a component <style> needs the theme referenced explicitly. */
|
|
86
|
+
@reference "../../style/main.css";
|
|
87
|
+
|
|
85
88
|
/* @TODO custom themes */
|
|
86
89
|
|
|
87
90
|
.v-popper {
|
|
@@ -89,18 +92,22 @@ function selectValue(value: any, hide: () => void) {
|
|
|
89
92
|
}
|
|
90
93
|
|
|
91
94
|
.v-popper--theme-dropdown {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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;
|
|
104
111
|
}
|
|
105
112
|
|
|
106
113
|
&.v-popper__popper--show-from .v-popper__wrapper {
|
|
@@ -79,7 +79,7 @@ function initState() {
|
|
|
79
79
|
:init-state="initState"
|
|
80
80
|
>
|
|
81
81
|
<template #default="{ state }">
|
|
82
|
-
<pre class="
|
|
82
|
+
<pre class="text-xs bg-gray-50 dark:bg-gray-600 rounded p-4">{{ options }}</pre>
|
|
83
83
|
<HstSelect
|
|
84
84
|
v-model="state.select"
|
|
85
85
|
title="Games"
|
|
@@ -100,7 +100,7 @@ function initState() {
|
|
|
100
100
|
:init-state="initState"
|
|
101
101
|
>
|
|
102
102
|
<template #default="{ state }">
|
|
103
|
-
<pre class="
|
|
103
|
+
<pre class="text-xs bg-gray-50 dark:bg-gray-600 rounded p-4">{{ objectOptions }}</pre>
|
|
104
104
|
<HstSelect
|
|
105
105
|
v-model="state.select"
|
|
106
106
|
title="Games"
|
|
@@ -121,7 +121,7 @@ function initState() {
|
|
|
121
121
|
:init-state="initState"
|
|
122
122
|
>
|
|
123
123
|
<template #default="{ state }">
|
|
124
|
-
<pre class="
|
|
124
|
+
<pre class="text-xs bg-gray-50 dark:bg-gray-600 rounded p-4">{{ flatOptions }}</pre>
|
|
125
125
|
<HstSelect
|
|
126
126
|
v-model="state.select"
|
|
127
127
|
title="Select"
|
|
@@ -142,7 +142,7 @@ function initState() {
|
|
|
142
142
|
:init-state="initState"
|
|
143
143
|
>
|
|
144
144
|
<template #default="{ state }">
|
|
145
|
-
<pre class="
|
|
145
|
+
<pre class="text-xs bg-gray-50 dark:bg-gray-600 rounded p-4">{{ numberOptions }}</pre>
|
|
146
146
|
<HstSelect
|
|
147
147
|
v-model="state.count"
|
|
148
148
|
title="Select"
|
|
@@ -50,19 +50,19 @@ const tooltipStyle = computed<CSSProperties>(() => {
|
|
|
50
50
|
|
|
51
51
|
<template>
|
|
52
52
|
<HstWrapper
|
|
53
|
-
class="poveste-slider
|
|
53
|
+
class="poveste-slider items-center"
|
|
54
54
|
:title="title"
|
|
55
55
|
:class="$attrs.class"
|
|
56
56
|
:style="$attrs.style"
|
|
57
57
|
>
|
|
58
|
-
<div class="
|
|
59
|
-
<div class="
|
|
60
|
-
<div class="
|
|
58
|
+
<div class="relative w-full flex items-center">
|
|
59
|
+
<div class="absolute inset-0 flex items-center">
|
|
60
|
+
<div class="border border-black/25 dark:border-white/25 h-1 w-full rounded-full" />
|
|
61
61
|
</div>
|
|
62
62
|
<input
|
|
63
63
|
ref="input"
|
|
64
64
|
v-model.number="numberModel"
|
|
65
|
-
class="
|
|
65
|
+
class="range-input appearance-none border-0 bg-transparent cursor-pointer relative w-full m-0 text-gray-700"
|
|
66
66
|
type="range"
|
|
67
67
|
v-bind="{ ...$attrs, class: null, style: null, min, max }"
|
|
68
68
|
@mouseover="showTooltip = true"
|
|
@@ -71,7 +71,7 @@ const tooltipStyle = computed<CSSProperties>(() => {
|
|
|
71
71
|
<div
|
|
72
72
|
v-if="showTooltip"
|
|
73
73
|
v-tooltip="{ content: modelValue.toString(), shown: true, distance: 16, delay: 0 }"
|
|
74
|
-
class="
|
|
74
|
+
class="absolute"
|
|
75
75
|
:style="tooltipStyle"
|
|
76
76
|
/>
|
|
77
77
|
</div>
|
|
@@ -79,25 +79,28 @@ const tooltipStyle = computed<CSSProperties>(() => {
|
|
|
79
79
|
</template>
|
|
80
80
|
|
|
81
81
|
<style lang="pcss">
|
|
82
|
-
.
|
|
82
|
+
/* v4: @apply in a component <style> needs the theme referenced explicitly. */
|
|
83
|
+
@reference "../../style/main.css";
|
|
84
|
+
|
|
85
|
+
.range-input {
|
|
83
86
|
&::-webkit-slider-thumb {
|
|
84
|
-
@apply
|
|
87
|
+
@apply appearance-none h-3 w-3 bg-white dark:bg-gray-700 border border-solid border-black/25 dark:border-white/25 rounded-full;
|
|
85
88
|
}
|
|
86
89
|
|
|
87
90
|
&:hover::-webkit-slider-thumb {
|
|
88
|
-
@apply
|
|
91
|
+
@apply bg-primary-500! border-primary-500!;
|
|
89
92
|
}
|
|
90
93
|
}
|
|
91
94
|
|
|
92
95
|
/* Separate rules for -moz-range-thumb to prevent a bug with Safari that causes it to ignore custom style */
|
|
93
96
|
|
|
94
|
-
.
|
|
97
|
+
.range-input {
|
|
95
98
|
&::-moz-range-thumb {
|
|
96
|
-
@apply
|
|
99
|
+
@apply appearance-none h-3 w-3 bg-white dark:bg-gray-700 border border-solid border-black/25 dark:border-white/25 rounded-full;
|
|
97
100
|
}
|
|
98
101
|
|
|
99
102
|
&:hover::-moz-range-thumb {
|
|
100
|
-
@apply
|
|
103
|
+
@apply bg-primary-500! border-primary-500!;
|
|
101
104
|
}
|
|
102
105
|
}
|
|
103
106
|
</style>
|
|
@@ -23,7 +23,7 @@ const input = ref<HTMLInputElement>()
|
|
|
23
23
|
<template>
|
|
24
24
|
<HstWrapper
|
|
25
25
|
:title="title"
|
|
26
|
-
class="poveste-text
|
|
26
|
+
class="poveste-text cursor-text items-center"
|
|
27
27
|
:class="$attrs.class"
|
|
28
28
|
:style="$attrs.style"
|
|
29
29
|
@click="input.focus()"
|
|
@@ -33,7 +33,7 @@ const input = ref<HTMLInputElement>()
|
|
|
33
33
|
v-bind="{ ...$attrs, class: null, style: null }"
|
|
34
34
|
type="text"
|
|
35
35
|
:value="modelValue"
|
|
36
|
-
class="
|
|
36
|
+
class="text-inherit bg-transparent w-full outline-none px-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"
|
|
37
37
|
@input="emit('update:modelValue', ($event.target as HTMLInputElement).value)"
|
|
38
38
|
>
|
|
39
39
|
|
|
@@ -24,7 +24,7 @@ const input = ref<HTMLInputElement>()
|
|
|
24
24
|
<template>
|
|
25
25
|
<HstWrapper
|
|
26
26
|
:title="title"
|
|
27
|
-
class="poveste-textarea
|
|
27
|
+
class="poveste-textarea cursor-text"
|
|
28
28
|
:class="$attrs.class"
|
|
29
29
|
:style="$attrs.style"
|
|
30
30
|
@click="input.focus()"
|
|
@@ -33,7 +33,7 @@ const input = ref<HTMLInputElement>()
|
|
|
33
33
|
ref="input"
|
|
34
34
|
v-bind="{ ...$attrs, class: null, style: null }"
|
|
35
35
|
:value="modelValue"
|
|
36
|
-
class="
|
|
36
|
+
class="text-inherit bg-transparent w-full outline-none px-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 box-border resize-y min-h-[26px]"
|
|
37
37
|
@input="emit('update:modelValue', ($event.target as HTMLInputElement).value)"
|
|
38
38
|
/>
|
|
39
39
|
|
package/src/style/main.css
CHANGED
|
@@ -1,13 +1,61 @@
|
|
|
1
1
|
@import 'floating-vue/dist/style.css';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/*
|
|
4
|
+
* Tailwind v4. Preflight is intentionally omitted (was `corePlugins.preflight:
|
|
5
|
+
* false` in v3) by importing the theme + utilities layers individually. The
|
|
6
|
+
* `ptw-` utility prefix is gone — chrome/story isolation is handled by @scope (#27).
|
|
7
|
+
*/
|
|
8
|
+
@layer theme, base, components, utilities;
|
|
9
|
+
@import 'tailwindcss/theme.css' layer(theme);
|
|
10
|
+
@import 'tailwindcss/utilities.css' layer(utilities);
|
|
6
11
|
|
|
12
|
+
/* Chrome dark mode. Deliberately a distinct class from the story-side
|
|
13
|
+
`theme.darkClass` default (`dark`) so chrome and story themes stay independent —
|
|
14
|
+
in v3 the `ptw-` prefix applied to the dark class and kept them separate. */
|
|
15
|
+
@custom-variant dark (&:where(.ptw-dark, .ptw-dark *));
|
|
16
|
+
|
|
17
|
+
@theme {
|
|
18
|
+
/* primary = emerald (ported from the root v3 config) */
|
|
19
|
+
--color-primary-50: var(--color-emerald-50);
|
|
20
|
+
--color-primary-100: var(--color-emerald-100);
|
|
21
|
+
--color-primary-200: var(--color-emerald-200);
|
|
22
|
+
--color-primary-300: var(--color-emerald-300);
|
|
23
|
+
--color-primary-400: var(--color-emerald-400);
|
|
24
|
+
--color-primary-500: var(--color-emerald-500);
|
|
25
|
+
--color-primary-600: var(--color-emerald-600);
|
|
26
|
+
--color-primary-700: var(--color-emerald-700);
|
|
27
|
+
--color-primary-800: var(--color-emerald-800);
|
|
28
|
+
--color-primary-900: var(--color-emerald-900);
|
|
29
|
+
--color-primary-950: var(--color-emerald-950);
|
|
30
|
+
|
|
31
|
+
/* gray = zinc, plus the custom 750/850/950 shades from the root v3 config */
|
|
32
|
+
--color-gray-50: var(--color-zinc-50);
|
|
33
|
+
--color-gray-100: var(--color-zinc-100);
|
|
34
|
+
--color-gray-200: var(--color-zinc-200);
|
|
35
|
+
--color-gray-300: var(--color-zinc-300);
|
|
36
|
+
--color-gray-400: var(--color-zinc-400);
|
|
37
|
+
--color-gray-500: var(--color-zinc-500);
|
|
38
|
+
--color-gray-600: var(--color-zinc-600);
|
|
39
|
+
--color-gray-700: var(--color-zinc-700);
|
|
40
|
+
--color-gray-750: #323238;
|
|
41
|
+
--color-gray-800: var(--color-zinc-800);
|
|
42
|
+
--color-gray-850: #1f1f21;
|
|
43
|
+
--color-gray-900: var(--color-zinc-900);
|
|
44
|
+
--color-gray-950: #101012;
|
|
45
|
+
|
|
46
|
+
/* border radius (ported from the root v3 config) */
|
|
47
|
+
--radius-sm: 0.25rem;
|
|
48
|
+
--radius: 0.375rem;
|
|
49
|
+
--radius-md: 0.5rem;
|
|
50
|
+
--radius-lg: 0.75rem;
|
|
51
|
+
--radius-xl: 1rem;
|
|
52
|
+
--radius-2xl: 1.5rem;
|
|
53
|
+
--radius-3xl: 2rem;
|
|
54
|
+
}
|
|
7
55
|
|
|
8
56
|
body {
|
|
9
57
|
font-size: 1.125rem;
|
|
10
|
-
@apply dark:
|
|
58
|
+
@apply dark:text-gray-100;
|
|
11
59
|
}
|
|
12
60
|
|
|
13
61
|
@media (min-width: 640px) {
|
package/tsconfig.json
CHANGED
package/tailwind.config.cjs
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
const path = require('node:path')
|
|
2
|
-
const inheritedConfig = require('../../tailwind.config.cjs')
|
|
3
|
-
|
|
4
|
-
module.exports = {
|
|
5
|
-
...inheritedConfig,
|
|
6
|
-
prefix: 'ptw-',
|
|
7
|
-
content: [
|
|
8
|
-
path.resolve(__dirname, './src/**/*.{vue,js,ts,jsx,tsx,md}'),
|
|
9
|
-
],
|
|
10
|
-
corePlugins: {
|
|
11
|
-
preflight: false,
|
|
12
|
-
},
|
|
13
|
-
}
|