@histoire/controls 0.11.0 → 0.11.1
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/HstWrapper.vue.d.ts +16 -3
- package/dist/components/button/HstButton.story.vue.d.ts +2 -0
- package/dist/components/button/HstButton.vue.d.ts +15 -0
- package/dist/components/button/HstButtonGroup.story.vue.d.ts +2 -0
- package/dist/components/button/HstButtonGroup.vue.d.ts +24 -0
- package/dist/components/checkbox/HstCheckboxList.story.vue.d.ts +2 -0
- package/dist/components/checkbox/HstCheckboxList.vue.d.ts +24 -0
- package/dist/components/checkbox/HstSimpleCheckbox.story.vue.d.ts +2 -0
- package/dist/components/checkbox/HstSimpleCheckbox.vue.d.ts +21 -0
- package/dist/index.d.ts +134 -0
- package/dist/index.es.js +543 -396
- package/dist/style-standalone.css +102 -23
- package/package.json +2 -2
- package/src/components/HstWrapper.vue +12 -4
- package/src/components/button/HstButton.story.vue +30 -0
- package/src/components/button/HstButton.vue +26 -0
- package/src/components/button/HstButtonGroup.story.vue +51 -0
- package/src/components/button/HstButtonGroup.vue +64 -0
- package/src/components/checkbox/HstCheckbox.story.vue +5 -1
- package/src/components/checkbox/HstCheckbox.vue +4 -50
- package/src/components/checkbox/HstCheckboxList.story.vue +49 -0
- package/src/components/checkbox/HstCheckboxList.vue +79 -0
- package/src/components/checkbox/HstSimpleCheckbox.story.vue +28 -0
- package/src/components/checkbox/HstSimpleCheckbox.vue +82 -0
- package/src/components/checkbox/__snapshots__/HstCheckbox.test.ts.snap +6 -6
- package/src/components/design-tokens/HstColorShades.story.vue +2 -1
- package/src/components/design-tokens/HstTokenGrid.story.vue +2 -1
- package/src/components/design-tokens/HstTokenList.story.vue +2 -1
- package/src/components/number/HstNumber.story.vue +1 -0
- package/src/components/number/HstNumber.vue +1 -2
- package/src/components/radio/HstRadio.story.vue +5 -1
- package/src/components/select/HstSelect.story.vue +1 -0
- package/src/components/slider/HstSlider.story.vue +2 -0
- package/src/components/text/HstText.story.vue +1 -0
- package/src/components/textarea/HstTextarea.story.vue +4 -1
- package/src/index.ts +9 -0
|
@@ -324,6 +324,11 @@
|
|
|
324
324
|
margin:0px
|
|
325
325
|
}
|
|
326
326
|
|
|
327
|
+
.-htw-my-1{
|
|
328
|
+
margin-top:-0.25rem;
|
|
329
|
+
margin-bottom:-0.25rem
|
|
330
|
+
}
|
|
331
|
+
|
|
327
332
|
.htw-my-0{
|
|
328
333
|
margin-top:0px;
|
|
329
334
|
margin-bottom:0px
|
|
@@ -339,19 +344,14 @@
|
|
|
339
344
|
margin-right:1rem
|
|
340
345
|
}
|
|
341
346
|
|
|
342
|
-
|
|
343
|
-
margin-
|
|
344
|
-
margin-bottom:-0.25rem
|
|
347
|
+
.htw-mr-2{
|
|
348
|
+
margin-right:0.5rem
|
|
345
349
|
}
|
|
346
350
|
|
|
347
351
|
.htw-mb-2{
|
|
348
352
|
margin-bottom:0.5rem
|
|
349
353
|
}
|
|
350
354
|
|
|
351
|
-
.htw-mr-2{
|
|
352
|
-
margin-right:0.5rem
|
|
353
|
-
}
|
|
354
|
-
|
|
355
355
|
.htw-ml-auto{
|
|
356
356
|
margin-left:auto
|
|
357
357
|
}
|
|
@@ -380,6 +380,10 @@
|
|
|
380
380
|
height:1rem
|
|
381
381
|
}
|
|
382
382
|
|
|
383
|
+
.htw-h-\[22px\]{
|
|
384
|
+
height:22px
|
|
385
|
+
}
|
|
386
|
+
|
|
383
387
|
.htw-h-\[16px\]{
|
|
384
388
|
height:16px
|
|
385
389
|
}
|
|
@@ -444,14 +448,14 @@
|
|
|
444
448
|
width:0.75rem
|
|
445
449
|
}
|
|
446
450
|
|
|
447
|
-
.htw-flex-none{
|
|
448
|
-
flex:none
|
|
449
|
-
}
|
|
450
|
-
|
|
451
451
|
.htw-flex-1{
|
|
452
452
|
flex:1 1 0%
|
|
453
453
|
}
|
|
454
454
|
|
|
455
|
+
.htw-flex-none{
|
|
456
|
+
flex:none
|
|
457
|
+
}
|
|
458
|
+
|
|
455
459
|
.htw-shrink-0{
|
|
456
460
|
flex-shrink:0
|
|
457
461
|
}
|
|
@@ -474,14 +478,14 @@
|
|
|
474
478
|
cursor:pointer
|
|
475
479
|
}
|
|
476
480
|
|
|
477
|
-
.htw-cursor-ew-resize{
|
|
478
|
-
cursor:ew-resize
|
|
479
|
-
}
|
|
480
|
-
|
|
481
481
|
.htw-cursor-text{
|
|
482
482
|
cursor:text
|
|
483
483
|
}
|
|
484
484
|
|
|
485
|
+
.htw-cursor-ew-resize{
|
|
486
|
+
cursor:ew-resize
|
|
487
|
+
}
|
|
488
|
+
|
|
485
489
|
.htw-select-none{
|
|
486
490
|
-webkit-user-select:none;
|
|
487
491
|
-moz-user-select:none;
|
|
@@ -510,6 +514,10 @@
|
|
|
510
514
|
flex-wrap:wrap
|
|
511
515
|
}
|
|
512
516
|
|
|
517
|
+
.htw-flex-nowrap{
|
|
518
|
+
flex-wrap:nowrap
|
|
519
|
+
}
|
|
520
|
+
|
|
513
521
|
.htw-items-end{
|
|
514
522
|
align-items:flex-end
|
|
515
523
|
}
|
|
@@ -526,6 +534,10 @@
|
|
|
526
534
|
gap:0.25rem
|
|
527
535
|
}
|
|
528
536
|
|
|
537
|
+
.htw-gap-px{
|
|
538
|
+
gap:1px
|
|
539
|
+
}
|
|
540
|
+
|
|
529
541
|
.htw-gap-4{
|
|
530
542
|
gap:1rem
|
|
531
543
|
}
|
|
@@ -552,6 +564,10 @@
|
|
|
552
564
|
border-radius:0.25rem
|
|
553
565
|
}
|
|
554
566
|
|
|
567
|
+
.\!htw-rounded-\[3px\]{
|
|
568
|
+
border-radius:3px !important
|
|
569
|
+
}
|
|
570
|
+
|
|
555
571
|
.htw-rounded{
|
|
556
572
|
border-radius:0.375rem
|
|
557
573
|
}
|
|
@@ -580,20 +596,34 @@
|
|
|
580
596
|
border-style:solid
|
|
581
597
|
}
|
|
582
598
|
|
|
599
|
+
.htw-border-black\/25{
|
|
600
|
+
border-color:rgb(0 0 0 / 0.25)
|
|
601
|
+
}
|
|
602
|
+
|
|
583
603
|
.htw-border-primary-500{
|
|
584
604
|
--tw-border-opacity:1;
|
|
585
605
|
border-color:rgb(16 185 129 / var(--tw-border-opacity))
|
|
586
606
|
}
|
|
587
607
|
|
|
588
|
-
.htw-border-black\/25{
|
|
589
|
-
border-color:rgb(0 0 0 / 0.25)
|
|
590
|
-
}
|
|
591
|
-
|
|
592
608
|
.htw-border-gray-850{
|
|
593
609
|
--tw-border-opacity:1;
|
|
594
610
|
border-color:rgb(31 31 33 / var(--tw-border-opacity))
|
|
595
611
|
}
|
|
596
612
|
|
|
613
|
+
.htw-bg-gray-200{
|
|
614
|
+
--tw-bg-opacity:1;
|
|
615
|
+
background-color:rgb(228 228 231 / var(--tw-bg-opacity))
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
.htw-bg-primary-500{
|
|
619
|
+
--tw-bg-opacity:1;
|
|
620
|
+
background-color:rgb(16 185 129 / var(--tw-bg-opacity))
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
.htw-bg-transparent{
|
|
624
|
+
background-color:transparent
|
|
625
|
+
}
|
|
626
|
+
|
|
597
627
|
.htw-bg-white{
|
|
598
628
|
--tw-bg-opacity:1;
|
|
599
629
|
background-color:rgb(255 255 255 / var(--tw-bg-opacity))
|
|
@@ -607,10 +637,6 @@
|
|
|
607
637
|
background-color:rgb(113 113 122 / 0.5)
|
|
608
638
|
}
|
|
609
639
|
|
|
610
|
-
.htw-bg-transparent{
|
|
611
|
-
background-color:transparent
|
|
612
|
-
}
|
|
613
|
-
|
|
614
640
|
.htw-bg-gray-50{
|
|
615
641
|
--tw-bg-opacity:1;
|
|
616
642
|
background-color:rgb(250 250 250 / var(--tw-bg-opacity))
|
|
@@ -656,10 +682,19 @@
|
|
|
656
682
|
padding:0.5rem
|
|
657
683
|
}
|
|
658
684
|
|
|
685
|
+
.htw-p-px{
|
|
686
|
+
padding:1px
|
|
687
|
+
}
|
|
688
|
+
|
|
659
689
|
.htw-p-4{
|
|
660
690
|
padding:1rem
|
|
661
691
|
}
|
|
662
692
|
|
|
693
|
+
.htw-px-1{
|
|
694
|
+
padding-left:0.25rem;
|
|
695
|
+
padding-right:0.25rem
|
|
696
|
+
}
|
|
697
|
+
|
|
663
698
|
.htw-py-1{
|
|
664
699
|
padding-top:0.25rem;
|
|
665
700
|
padding-bottom:0.25rem
|
|
@@ -688,6 +723,11 @@
|
|
|
688
723
|
line-height:1.5
|
|
689
724
|
}
|
|
690
725
|
|
|
726
|
+
.htw-text-gray-900{
|
|
727
|
+
--tw-text-opacity:1;
|
|
728
|
+
color:rgb(24 24 27 / var(--tw-text-opacity))
|
|
729
|
+
}
|
|
730
|
+
|
|
691
731
|
.htw-text-white{
|
|
692
732
|
--tw-text-opacity:1;
|
|
693
733
|
color:rgb(255 255 255 / var(--tw-text-opacity))
|
|
@@ -776,6 +816,20 @@ body {
|
|
|
776
816
|
background-color:rgb(209 250 229 / var(--tw-bg-opacity))
|
|
777
817
|
}
|
|
778
818
|
|
|
819
|
+
.hover\:htw-bg-primary-200:hover{
|
|
820
|
+
--tw-bg-opacity:1;
|
|
821
|
+
background-color:rgb(167 243 208 / var(--tw-bg-opacity))
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
.hover\:htw-bg-primary-600:hover{
|
|
825
|
+
--tw-bg-opacity:1;
|
|
826
|
+
background-color:rgb(5 150 105 / var(--tw-bg-opacity))
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
.hover\:htw-bg-gray-500\/20:hover{
|
|
830
|
+
background-color:rgb(113 113 122 / 0.2)
|
|
831
|
+
}
|
|
832
|
+
|
|
779
833
|
.hover\:htw-text-primary-500:hover{
|
|
780
834
|
--tw-text-opacity:1;
|
|
781
835
|
color:rgb(16 185 129 / var(--tw-text-opacity))
|
|
@@ -803,6 +857,11 @@ body {
|
|
|
803
857
|
border-color:rgb(255 255 255 / 0.25)
|
|
804
858
|
}
|
|
805
859
|
|
|
860
|
+
.htw-dark .dark\:htw-bg-gray-750{
|
|
861
|
+
--tw-bg-opacity:1;
|
|
862
|
+
background-color:rgb(50 50 56 / var(--tw-bg-opacity))
|
|
863
|
+
}
|
|
864
|
+
|
|
806
865
|
.htw-dark .dark\:htw-bg-black{
|
|
807
866
|
--tw-bg-opacity:1;
|
|
808
867
|
background-color:rgb(0 0 0 / var(--tw-bg-opacity))
|
|
@@ -823,6 +882,16 @@ body {
|
|
|
823
882
|
background-color:rgb(82 82 91 / var(--tw-bg-opacity))
|
|
824
883
|
}
|
|
825
884
|
|
|
885
|
+
.htw-dark .dark\:htw-text-gray-100{
|
|
886
|
+
--tw-text-opacity:1;
|
|
887
|
+
color:rgb(244 244 245 / var(--tw-text-opacity))
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
.htw-dark .dark\:htw-text-black{
|
|
891
|
+
--tw-text-opacity:1;
|
|
892
|
+
color:rgb(0 0 0 / var(--tw-text-opacity))
|
|
893
|
+
}
|
|
894
|
+
|
|
826
895
|
.htw-dark .dark\:hover\:htw-border-primary-500:hover{
|
|
827
896
|
--tw-border-opacity:1;
|
|
828
897
|
border-color:rgb(16 185 129 / var(--tw-border-opacity))
|
|
@@ -833,6 +902,11 @@ body {
|
|
|
833
902
|
background-color:rgb(6 95 70 / var(--tw-bg-opacity))
|
|
834
903
|
}
|
|
835
904
|
|
|
905
|
+
.htw-dark .dark\:hover\:htw-bg-primary-900:hover{
|
|
906
|
+
--tw-bg-opacity:1;
|
|
907
|
+
background-color:rgb(6 78 59 / var(--tw-bg-opacity))
|
|
908
|
+
}
|
|
909
|
+
|
|
836
910
|
.htw-dark .dark\:hover\:htw-bg-primary-700:hover{
|
|
837
911
|
--tw-bg-opacity:1;
|
|
838
912
|
background-color:rgb(4 120 87 / var(--tw-bg-opacity))
|
|
@@ -842,3 +916,8 @@ body {
|
|
|
842
916
|
--tw-border-opacity:1;
|
|
843
917
|
border-color:rgb(16 185 129 / var(--tw-border-opacity))
|
|
844
918
|
}
|
|
919
|
+
|
|
920
|
+
.htw-group:hover .htw-dark .group-hover\:dark\:htw-border-primary-500{
|
|
921
|
+
--tw-border-opacity:1;
|
|
922
|
+
border-color:rgb(16 185 129 / var(--tw-border-opacity))
|
|
923
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@histoire/controls",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "Prebuilt controls components",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"*.vue"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@histoire/vendors": "^0.11.
|
|
34
|
+
"@histoire/vendors": "^0.11.1"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@peeky/server": "^0.14.0",
|
|
@@ -5,15 +5,23 @@ export default {
|
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
7
|
<script lang="ts" setup>
|
|
8
|
+
import { withDefaults, computed } from 'vue'
|
|
8
9
|
import { VTooltip as vTooltip } from 'floating-vue'
|
|
9
10
|
|
|
10
|
-
defineProps<{
|
|
11
|
+
const props = withDefaults(defineProps<{
|
|
11
12
|
title?: string
|
|
12
|
-
|
|
13
|
+
tag?: string
|
|
14
|
+
}>(), {
|
|
15
|
+
tag: 'label',
|
|
16
|
+
})
|
|
17
|
+
|
|
13
18
|
</script>
|
|
14
19
|
|
|
15
20
|
<template>
|
|
16
|
-
<
|
|
21
|
+
<component
|
|
22
|
+
:is="tag"
|
|
23
|
+
class="htw-p-2 hover:htw-bg-primary-100 dark:hover:htw-bg-primary-800 htw-flex htw-gap-2 htw-flex-wrap"
|
|
24
|
+
>
|
|
17
25
|
<span
|
|
18
26
|
v-tooltip="{
|
|
19
27
|
content: title,
|
|
@@ -30,5 +38,5 @@ defineProps<{
|
|
|
30
38
|
</span>
|
|
31
39
|
<slot name="actions" />
|
|
32
40
|
</span>
|
|
33
|
-
</
|
|
41
|
+
</component>
|
|
34
42
|
</template>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import HstButton from './HstButton.vue'
|
|
3
|
+
|
|
4
|
+
const variants: Array<{name: string, bind?: unknown}> = [
|
|
5
|
+
{ name: 'Default' },
|
|
6
|
+
{ name: 'Primary', bind: { color: 'primary' } },
|
|
7
|
+
{ name: 'Flat', bind: { color: 'flat' } },
|
|
8
|
+
]
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<Story
|
|
13
|
+
title="HstButton"
|
|
14
|
+
group="controls"
|
|
15
|
+
:layout="{ type: 'grid', width: '200px', iframe: false }"
|
|
16
|
+
>
|
|
17
|
+
<Variant
|
|
18
|
+
v-for="(variant, key) of variants"
|
|
19
|
+
:key="key"
|
|
20
|
+
:title="variant.name"
|
|
21
|
+
>
|
|
22
|
+
<HstButton
|
|
23
|
+
v-bind="variant.bind"
|
|
24
|
+
class="htw-p-2"
|
|
25
|
+
>
|
|
26
|
+
Click me!
|
|
27
|
+
</HstButton>
|
|
28
|
+
</Variant>
|
|
29
|
+
</Story>
|
|
30
|
+
</template>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export default {
|
|
3
|
+
name: 'HstButton',
|
|
4
|
+
}
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<script setup lang="ts">
|
|
8
|
+
const colors = {
|
|
9
|
+
default: 'htw-bg-gray-200 dark:htw-bg-gray-750 htw-text-gray-900 dark:htw-text-gray-100 hover:htw-bg-primary-200 dark:hover:htw-bg-primary-900',
|
|
10
|
+
primary: 'htw-bg-primary-500 hover:htw-bg-primary-600 htw-text-white dark:htw-text-black',
|
|
11
|
+
flat: 'htw-bg-transparent hover:htw-bg-gray-500/20 htw-text-gray-900 dark:htw-text-gray-100',
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
defineProps<{
|
|
15
|
+
color?: keyof typeof colors
|
|
16
|
+
}>()
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<template>
|
|
20
|
+
<button
|
|
21
|
+
class="htw-cursor-pointer htw-rounded-sm"
|
|
22
|
+
:class="colors[color ?? 'default']"
|
|
23
|
+
>
|
|
24
|
+
<slot />
|
|
25
|
+
</button>
|
|
26
|
+
</template>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import HstButtonGroup from './HstButtonGroup.vue'
|
|
3
|
+
|
|
4
|
+
const options = {
|
|
5
|
+
slow: 'Slow',
|
|
6
|
+
fast: 'Fast',
|
|
7
|
+
max: 'Max',
|
|
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
|
+
speed: flatOptions[0],
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<template>
|
|
25
|
+
<Story
|
|
26
|
+
title="HstButtonGroup"
|
|
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
|
+
<HstButtonGroup
|
|
36
|
+
v-model="state.speed"
|
|
37
|
+
title="Label"
|
|
38
|
+
:options="objectOptions"
|
|
39
|
+
/>
|
|
40
|
+
</template>
|
|
41
|
+
|
|
42
|
+
<template #controls="{ state }">
|
|
43
|
+
<HstButtonGroup
|
|
44
|
+
v-model="state.speed"
|
|
45
|
+
title="Label"
|
|
46
|
+
:options="objectOptions"
|
|
47
|
+
/>
|
|
48
|
+
</template>
|
|
49
|
+
</Variant>
|
|
50
|
+
</Story>
|
|
51
|
+
</template>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export default {
|
|
3
|
+
name: 'HstButtonGroup',
|
|
4
|
+
}
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<script setup lang="ts">
|
|
8
|
+
import { computed, ComputedRef } from 'vue'
|
|
9
|
+
import HstWrapper from '../HstWrapper.vue'
|
|
10
|
+
import { HstControlOption } from '../../types'
|
|
11
|
+
import HstButton from './HstButton.vue'
|
|
12
|
+
|
|
13
|
+
const props = defineProps<{
|
|
14
|
+
title?: string
|
|
15
|
+
modelValue: string
|
|
16
|
+
options: HstControlOption[]
|
|
17
|
+
}>()
|
|
18
|
+
|
|
19
|
+
const formattedOptions: ComputedRef<Record<string, string>> = computed(() => {
|
|
20
|
+
if (Array.isArray(props.options)) {
|
|
21
|
+
return Object.fromEntries(props.options.map((value: string | HstControlOption) => {
|
|
22
|
+
if (typeof value === 'string') {
|
|
23
|
+
return [value, value]
|
|
24
|
+
} else {
|
|
25
|
+
return [value.value, value.label]
|
|
26
|
+
}
|
|
27
|
+
}))
|
|
28
|
+
}
|
|
29
|
+
return props.options
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const emit = defineEmits<{
|
|
33
|
+
(e: 'update:modelValue', value: string): void
|
|
34
|
+
}>()
|
|
35
|
+
|
|
36
|
+
function selectOption (value: string) {
|
|
37
|
+
emit('update:modelValue', value)
|
|
38
|
+
}
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<template>
|
|
42
|
+
<HstWrapper
|
|
43
|
+
tag="div"
|
|
44
|
+
role="group"
|
|
45
|
+
:title="title"
|
|
46
|
+
class="htw-flex-nowrap htw-items-center"
|
|
47
|
+
>
|
|
48
|
+
<div class="htw-flex htw-gap-px htw-border htw-border-solid htw-border-black/25 dark:htw-border-white/25 htw-rounded-sm htw-p-px">
|
|
49
|
+
<HstButton
|
|
50
|
+
v-for="( label, value ) in formattedOptions"
|
|
51
|
+
:key="value"
|
|
52
|
+
class="htw-px-1 htw-h-[22px] htw-flex-1 !htw-rounded-[3px]"
|
|
53
|
+
:color="value === modelValue ? 'primary' : 'flat'"
|
|
54
|
+
:rounded="false"
|
|
55
|
+
@click="selectOption(value)"
|
|
56
|
+
>
|
|
57
|
+
{{ label }}
|
|
58
|
+
</HstButton>
|
|
59
|
+
</div>
|
|
60
|
+
<template #actions>
|
|
61
|
+
<slot name="actions" />
|
|
62
|
+
</template>
|
|
63
|
+
</HstWrapper>
|
|
64
|
+
</template>
|
|
@@ -5,36 +5,21 @@ export default {
|
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
7
|
<script lang="ts" setup>
|
|
8
|
-
import { computed, ref, watch } from 'vue'
|
|
9
8
|
import HstWrapper from '../HstWrapper.vue'
|
|
9
|
+
import HstSimpleCheckbox from './HstSimpleCheckbox.vue'
|
|
10
10
|
|
|
11
11
|
const props = defineProps<{
|
|
12
12
|
modelValue: boolean
|
|
13
13
|
title?: string
|
|
14
14
|
}>()
|
|
15
15
|
|
|
16
|
-
const
|
|
16
|
+
const emits = defineEmits({
|
|
17
17
|
'update:modelValue': (newValue: boolean) => true,
|
|
18
18
|
})
|
|
19
19
|
|
|
20
20
|
function toggle () {
|
|
21
|
-
|
|
22
|
-
animationEnabled.value = true
|
|
21
|
+
emits('update:modelValue', !props.modelValue)
|
|
23
22
|
}
|
|
24
|
-
|
|
25
|
-
// SVG check
|
|
26
|
-
|
|
27
|
-
const path = ref<SVGPathElement>()
|
|
28
|
-
const dasharray = ref(0)
|
|
29
|
-
const progress = computed(() => props.modelValue ? 1 : 0)
|
|
30
|
-
const dashoffset = computed(() => (1 - progress.value) * dasharray.value)
|
|
31
|
-
|
|
32
|
-
// animationEnabled prevents the animation from triggering on mounted
|
|
33
|
-
const animationEnabled = ref(false)
|
|
34
|
-
|
|
35
|
-
watch(path, () => {
|
|
36
|
-
dasharray.value = path.value.getTotalLength?.() ?? 21.21
|
|
37
|
-
})
|
|
38
23
|
</script>
|
|
39
24
|
|
|
40
25
|
<template>
|
|
@@ -47,38 +32,7 @@ watch(path, () => {
|
|
|
47
32
|
@keydown.enter.prevent="toggle()"
|
|
48
33
|
@keydown.space.prevent="toggle()"
|
|
49
34
|
>
|
|
50
|
-
<
|
|
51
|
-
<div
|
|
52
|
-
class="htw-border htw-border-solid 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"
|
|
53
|
-
:class="[
|
|
54
|
-
modelValue
|
|
55
|
-
? 'htw-border-primary-500 htw-border-8'
|
|
56
|
-
: 'htw-border-black/25 dark:htw-border-white/25 htw-delay-150',
|
|
57
|
-
]"
|
|
58
|
-
/>
|
|
59
|
-
<svg
|
|
60
|
-
width="16"
|
|
61
|
-
height="16"
|
|
62
|
-
viewBox="0 0 24 24"
|
|
63
|
-
class="htw-relative htw-z-10"
|
|
64
|
-
>
|
|
65
|
-
<path
|
|
66
|
-
ref="path"
|
|
67
|
-
d="m 4 12 l 5 5 l 10 -10"
|
|
68
|
-
fill="none"
|
|
69
|
-
class="htw-stroke-white htw-stroke-2 htw-duration-200 htw-ease-in-out"
|
|
70
|
-
:class="[
|
|
71
|
-
animationEnabled ? 'htw-transition-all' : 'htw-transition-none',
|
|
72
|
-
{
|
|
73
|
-
'htw-delay-150': modelValue,
|
|
74
|
-
},
|
|
75
|
-
]"
|
|
76
|
-
:stroke-dasharray="dasharray"
|
|
77
|
-
:stroke-dashoffset="dashoffset"
|
|
78
|
-
/>
|
|
79
|
-
</svg>
|
|
80
|
-
</div>
|
|
81
|
-
|
|
35
|
+
<HstSimpleCheckbox :model-value="modelValue" />
|
|
82
36
|
<template #actions>
|
|
83
37
|
<slot name="actions" />
|
|
84
38
|
</template>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import HstCheckboxList from './HstCheckboxList.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 objectOptions = Object.keys(options).map(key => ({
|
|
11
|
+
label: options[key],
|
|
12
|
+
value: key,
|
|
13
|
+
}))
|
|
14
|
+
|
|
15
|
+
function initState () {
|
|
16
|
+
return {
|
|
17
|
+
characters: [],
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<template>
|
|
23
|
+
<Story
|
|
24
|
+
title="HstCheckboxList"
|
|
25
|
+
group="controls"
|
|
26
|
+
:layout="{ type: 'single', iframe: false }"
|
|
27
|
+
>
|
|
28
|
+
<Variant
|
|
29
|
+
title="playground"
|
|
30
|
+
:init-state="initState"
|
|
31
|
+
>
|
|
32
|
+
<template #default="{ state }">
|
|
33
|
+
<HstCheckboxList
|
|
34
|
+
v-model="state.characters"
|
|
35
|
+
title="Label"
|
|
36
|
+
:options="objectOptions"
|
|
37
|
+
/>
|
|
38
|
+
</template>
|
|
39
|
+
|
|
40
|
+
<template #controls="{ state }">
|
|
41
|
+
<HstCheckboxList
|
|
42
|
+
v-model="state.characters"
|
|
43
|
+
title="Label"
|
|
44
|
+
:options="objectOptions"
|
|
45
|
+
/>
|
|
46
|
+
</template>
|
|
47
|
+
</Variant>
|
|
48
|
+
</Story>
|
|
49
|
+
</template>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export default {
|
|
3
|
+
name: 'HstCheckboxList',
|
|
4
|
+
}
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<script lang="ts" setup>
|
|
8
|
+
import { computed, ComputedRef } from 'vue'
|
|
9
|
+
import HstWrapper from '../HstWrapper.vue'
|
|
10
|
+
import { HstControlOption } from '../../types'
|
|
11
|
+
import HstSimpleCheckbox from './HstSimpleCheckbox.vue'
|
|
12
|
+
|
|
13
|
+
const props = defineProps<{
|
|
14
|
+
title?: string
|
|
15
|
+
modelValue: Array<string>
|
|
16
|
+
options: HstControlOption[]
|
|
17
|
+
}>()
|
|
18
|
+
|
|
19
|
+
const formattedOptions: ComputedRef<Record<string, string>> = computed(() => {
|
|
20
|
+
if (Array.isArray(props.options)) {
|
|
21
|
+
return Object.fromEntries(props.options.map((value: string | HstControlOption) => {
|
|
22
|
+
if (typeof value === 'string') {
|
|
23
|
+
return [value, value]
|
|
24
|
+
} else {
|
|
25
|
+
return [value.value, value.label]
|
|
26
|
+
}
|
|
27
|
+
}))
|
|
28
|
+
}
|
|
29
|
+
return props.options
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const emits = defineEmits<{
|
|
33
|
+
(e: 'update:modelValue', value: Array<string>): void
|
|
34
|
+
}>()
|
|
35
|
+
|
|
36
|
+
function toggleOption (value: string) {
|
|
37
|
+
if (props.modelValue.includes(value)) {
|
|
38
|
+
emits('update:modelValue', props.modelValue.filter(element => element !== value))
|
|
39
|
+
} else {
|
|
40
|
+
emits('update:modelValue', [...props.modelValue, value])
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<template>
|
|
46
|
+
<HstWrapper
|
|
47
|
+
role="group"
|
|
48
|
+
:title="title"
|
|
49
|
+
class="htw-cursor-text"
|
|
50
|
+
:class="$attrs.class"
|
|
51
|
+
:style="$attrs.style"
|
|
52
|
+
>
|
|
53
|
+
<div class="-htw-my-1">
|
|
54
|
+
<template
|
|
55
|
+
v-for="( label, value ) in formattedOptions"
|
|
56
|
+
:key="value"
|
|
57
|
+
>
|
|
58
|
+
<label
|
|
59
|
+
tabindex="0"
|
|
60
|
+
:for="`${value}-radio`"
|
|
61
|
+
class="htw-cursor-pointer htw-flex htw-items-center htw-relative htw-py-1 htw-group"
|
|
62
|
+
@keydown.enter.prevent="toggleOption(value)"
|
|
63
|
+
@keydown.space.prevent="toggleOption(value)"
|
|
64
|
+
@click="toggleOption(value)"
|
|
65
|
+
>
|
|
66
|
+
<HstSimpleCheckbox
|
|
67
|
+
:model-value="modelValue.includes(value)"
|
|
68
|
+
class="htw-mr-2"
|
|
69
|
+
/>
|
|
70
|
+
{{ label }}
|
|
71
|
+
</label>
|
|
72
|
+
</template>
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
<template #actions>
|
|
76
|
+
<slot name="actions" />
|
|
77
|
+
</template>
|
|
78
|
+
</HstWrapper>
|
|
79
|
+
</template>
|