bonkers-ui 1.0.2 → 1.0.5

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 (71) hide show
  1. package/.storybook/preview.js +1 -2
  2. package/README.md +1 -1
  3. package/package.json +5 -5
  4. package/src/{_colors.json → _styles/classTypes/_colors.json} +2 -2
  5. package/src/{_font-sizes.json → _styles/classTypes/_font-sizes.json} +1 -1
  6. package/src/{_shadow.json → _styles/classTypes/_shadow.json} +1 -1
  7. package/src/{_spacing.json → _styles/classTypes/_spacing.json} +1 -0
  8. package/src/_styles/{colors.css → variables/colors.css} +0 -0
  9. package/src/_styles/{font-sizes.css → variables/font-sizes.css} +1 -1
  10. package/src/_styles/variables/shadow.css +8 -0
  11. package/src/_styles/{spacing.css → variables/spacing.css} +1 -0
  12. package/src/components/ui-badge/_typings.ts +11 -0
  13. package/src/components/ui-badge/index.ts +2 -0
  14. package/src/components/ui-badge/ui-badge.stories.ts +45 -0
  15. package/src/components/ui-badge/ui-badge.vue +59 -0
  16. package/src/components/ui-ber-rank/index.ts +1 -0
  17. package/src/components/ui-ber-rank/ui-ber-rank.stories.ts +34 -0
  18. package/src/components/ui-ber-rank/ui-ber-rank.vue +142 -0
  19. package/src/components/ui-button/index.ts +1 -0
  20. package/src/components/ui-button/ui-button.stories.ts +26 -5
  21. package/src/components/ui-button/ui-button.vue +34 -6
  22. package/src/components/ui-card-cta/ui-card-cta.stories.ts +3 -8
  23. package/src/components/ui-card-cta/ui-card-cta.vue +6 -11
  24. package/src/components/ui-card-result/index.ts +1 -0
  25. package/src/components/ui-card-result/ui-card-result.stories.ts +107 -0
  26. package/src/components/ui-card-result/ui-card-result.vue +70 -0
  27. package/src/components/ui-card-simple/ui-card-simple.stories.ts +1 -1
  28. package/src/components/ui-card-simple/ui-card-simple.vue +1 -1
  29. package/src/components/ui-checkbox/ui-checkbox.stories.ts +1 -1
  30. package/src/components/ui-checkbox/ui-checkbox.vue +1 -1
  31. package/src/components/ui-icon/ui-icon.stories.ts +2 -2
  32. package/src/components/ui-icon/ui-icon.vue +1 -1
  33. package/src/components/ui-input/_typings.ts +0 -2
  34. package/src/components/ui-input/ui-input.stories.ts +9 -3
  35. package/src/components/ui-input/ui-input.vue +49 -20
  36. package/src/components/ui-input-range/index.ts +1 -0
  37. package/src/components/ui-input-range/ui-input-range.stories.ts +48 -0
  38. package/src/components/ui-input-range/ui-input-range.vue +62 -0
  39. package/src/components/ui-list-item/index.ts +1 -0
  40. package/src/components/ui-list-item/ui-list-item.stories.ts +40 -0
  41. package/src/components/ui-list-item/ui-list-item.vue +29 -0
  42. package/src/components/ui-radio/ui-radio.stories.ts +8 -3
  43. package/src/components/ui-radio/ui-radio.vue +36 -3
  44. package/src/components/ui-radio-list-fancy/ui-radio-item/ui-radio-item.vue +4 -4
  45. package/src/components/ui-radio-list-fancy/ui-radio-list-fancy.stories.ts +1 -1
  46. package/src/components/ui-ripple/ui-ripple.stories.ts +1 -1
  47. package/src/components/ui-ripple/ui-ripple.vue +2 -2
  48. package/src/components/ui-select/index.ts +1 -0
  49. package/src/components/ui-select/ui-select.stories.ts +45 -0
  50. package/src/components/ui-select/ui-select.vue +68 -0
  51. package/src/components/ui-tabs/index.ts +1 -0
  52. package/src/components/ui-tabs/ui-tabs.stories.ts +32 -0
  53. package/src/components/ui-tabs/ui-tabs.vue +58 -0
  54. package/src/components/ui-toggle/index.ts +1 -0
  55. package/src/components/ui-toggle/ui-toggle.stories.ts +40 -0
  56. package/src/components/ui-toggle/ui-toggle.vue +92 -0
  57. package/src/components/ui-typography/_typings.ts +5 -31
  58. package/src/components/ui-typography/index.ts +1 -1
  59. package/src/components/ui-typography/ui-typography.stories.ts +7 -2
  60. package/src/components/ui-typography/ui-typography.vue +4 -3
  61. package/src/components/ui-verification-input/ui-verification-input.stories.ts +1 -2
  62. package/src/components/ui-verification-input/ui-verification-input.vue +2 -2
  63. package/src/main.css +6 -5
  64. package/src/stories/colors/ui-colors.vue +1 -1
  65. package/src/stories/font-sizes/font-sizes.stories.ts +13 -0
  66. package/src/stories/font-sizes/ui-font-sizes.vue +28 -0
  67. package/src/stories/spacings/ui-spacings.vue +2 -2
  68. package/tailwind.config.js +4 -4
  69. package/tsconfig.json +4 -1
  70. package/vite.config.ts +5 -3
  71. package/src/_styles/shadow.css +0 -7
@@ -0,0 +1,107 @@
1
+ import UiCardResult from "./ui-card-result.vue";
2
+ import UiTypography, { ETypographySizes, ETextWeight, ETextAlign } from "../ui-typography";
3
+ import UiBadge from "../ui-badge";
4
+ import UiListItem from "../ui-list-item";
5
+ import UiButton, { EButtonTypes } from "../ui-button";
6
+ import UiIcon from "../ui-icon";
7
+ import { ESize } from "../../_types/sizing";
8
+ import type { Story } from "@storybook/vue3";
9
+
10
+ export default {
11
+ title: "Components/ui-card-result",
12
+ component: UiCardResult,
13
+ argTypes: {
14
+ className: {
15
+ control: { type: "text" },
16
+ description: "The Element classes",
17
+ },
18
+ exclusiveText: {
19
+ control: { type: "boolean" },
20
+ description: "Whether to show the exclusive text",
21
+ },
22
+ exclusiveTextBottom: {
23
+ control: { type: "boolean" },
24
+ description: "Whether to show the exclusive text",
25
+ },
26
+ },
27
+ args: {
28
+ slot: "default text",
29
+ exclusiveText: true,
30
+ exclusiveTextBottom: true,
31
+ },
32
+ };
33
+
34
+ type TComponentProps = InstanceType<typeof UiCardResult>["$props"];
35
+
36
+ const Template: Story<TComponentProps> = (args) => ({
37
+ components: { UiCardResult, UiTypography, UiBadge, UiListItem, UiButton, UiIcon },
38
+ setup() {
39
+ return { args, ETypographySizes, ETextWeight, ETextAlign, EButtonTypes, ESize };
40
+ },
41
+ template: `
42
+ <ui-card-result
43
+ v-bind="args"
44
+ header="Some header"
45
+ :exclusive-text="args.exclusiveText
46
+ ? 'Only available on bonkers.ie'
47
+ : undefined"
48
+ :exclusive-text-bottom="args.exclusiveTextBottom
49
+ ? 'The price changes made available on 04/04/2022 has been factored into your results'
50
+ : undefined"
51
+ >
52
+ <template #sidebar>
53
+ <ui-typography :size='ETypographySizes.XXS' line-height>
54
+ Special offer text
55
+ </ui-typography>
56
+ </template>
57
+
58
+ <template #default>
59
+ <div class="flex flex-wrap gap-xs mb-xs">
60
+ <ui-badge
61
+ v-for="item in ['10% annual overpayment allowance', 'Flexibility built in', 'Flexibility built in!', 'Flexibility built inas', 'lorem5 aslijdhsdoi ashjd oiahsjdoi ']"
62
+ :icon="['far', 'face-smile']"
63
+ :key="item"
64
+ >
65
+ {{ item }}
66
+ </ui-badge>
67
+ </div>
68
+
69
+ <ul>
70
+ <ui-list-item
71
+ v-for="item in 5"
72
+ class-name="mb-xs"
73
+ :key="item"
74
+ :icon="['far', 'face-smile']"
75
+ >
76
+ Feature item {{ item }}
77
+ </ui-list-item>
78
+ </ul>
79
+
80
+ <ui-typography
81
+ :weight="ETextWeight.BOLD"
82
+ :size="ETypographySizes.LG"
83
+ :align="ETextAlign.RIGHT"
84
+ class-name="mb-xs"
85
+ >
86
+ €1004.63 p/m
87
+ </ui-typography>
88
+
89
+ <div class="flex gap-sm">
90
+ <ui-button :kind="EButtonTypes.SECONDARY_OVERLAY">
91
+ <template #prefix>
92
+ <ui-icon
93
+ :icon-name="['far', 'face-smile']"
94
+ :size="ESize.SM"
95
+ />
96
+ </template>
97
+ </ui-button>
98
+
99
+ <ui-button full-width>Some text</ui-button>
100
+ </div>
101
+
102
+ </template>
103
+ </ui-card-result>
104
+ `,
105
+ });
106
+
107
+ export const Default = Template.bind({});
@@ -0,0 +1,70 @@
1
+ <template>
2
+ <div class="ui-card-result__wrapper">
3
+ <div
4
+ v-if="exclusiveText"
5
+ class="ui-card-result__exclusive bg-primary rounded-2xl px-sm pb-lg -mb-lg"
6
+ >
7
+ <ui-typography
8
+ class-name="py-xs"
9
+ line-height
10
+ :size="ETypographySizes.XXS"
11
+ :kind="EColors.WHITE"
12
+ :align="ETextAlign.CENTER"
13
+ :weight="ETextWeight.SEMI_BOLD"
14
+ >
15
+ {{ exclusiveText }}
16
+ </ui-typography>
17
+ </div>
18
+
19
+ <div class="ui-card-result flex border border-secondary-alt rounded-2xl overflow-hidden">
20
+ <div
21
+ v-if="slots.sidebar"
22
+ class="ui-card-result__sidebar bg-secondary-alt-200 p-sm w-xl border-r border-secondary-alt flex items-center justify-center text-center"
23
+ >
24
+ <slot name="sidebar" />
25
+ </div>
26
+
27
+ <main class="p-sm bg-white w-full">
28
+ <ui-typography
29
+ v-if="header"
30
+ class-name="mb-xs"
31
+ :size="ETypographySizes.SM"
32
+ :weight="ETextWeight.SEMI_BOLD"
33
+ >
34
+ {{ header }}
35
+ </ui-typography>
36
+ <slot />
37
+ </main>
38
+ </div>
39
+
40
+ <div
41
+ v-if="exclusiveTextBottom"
42
+ class="ui-card-result__exclusive_bottom bg-secondary rounded-2xl px-sm pt-lg -mt-lg"
43
+ >
44
+ <ui-typography
45
+ class-name="py-xs"
46
+ :size="ETypographySizes.XXS"
47
+ :kind="EColors.WHITE"
48
+ :align="ETextAlign.CENTER"
49
+ line-height
50
+ >
51
+ {{ exclusiveTextBottom }}
52
+ </ui-typography>
53
+ </div>
54
+ </div>
55
+ </template>
56
+
57
+ <script lang="ts" setup>
58
+ import UiTypography, { ETypographySizes, ETextWeight, ETextAlign } from "../ui-typography";
59
+ import { EColors } from "../../_types/colors";
60
+ import { useSlots } from "vue";
61
+
62
+ const slots = useSlots();
63
+
64
+ defineProps<{
65
+ header?: string;
66
+ exclusiveText?: string;
67
+ exclusiveTextBottom?: string;
68
+ }>();
69
+
70
+ </script>
@@ -1,5 +1,5 @@
1
1
  import UiCardSimple from "./ui-card-simple.vue";
2
- import { Story } from "@storybook/vue3";
2
+ import type { Story } from "@storybook/vue3";
3
3
 
4
4
  export default {
5
5
  title: "Components/ui-card-simple",
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div
3
- class="ui-card-simple rounded-3xl shadow-m py-md px-sm"
3
+ class="ui-card-simple rounded-3xl shadow-md py-md px-sm"
4
4
  :class="className"
5
5
  >
6
6
  <ui-typography
@@ -1,5 +1,5 @@
1
1
  import UiCheckbox from "./ui-checkbox.vue";
2
- import { Story } from "@storybook/vue3";
2
+ import type { Story } from "@storybook/vue3";
3
3
  import { ref } from "vue";
4
4
  import { EJustify } from "../../_types/align";
5
5
 
@@ -18,7 +18,7 @@
18
18
  class="appearance-none absolute"
19
19
  type="checkbox"
20
20
  :disabled="disabled"
21
- @input="$emit('update:modelValue', $event.target.checked)"
21
+ @input="$emit('update:modelValue', !!($event.target as HTMLInputElement)?.value)"
22
22
  >
23
23
  <span
24
24
  class="ui-checkbox_custom w-md h-md flex items-center justify-center border border-secondary-alt-500 rounded relative hover:border-secondary-alt-700"
@@ -1,5 +1,5 @@
1
1
  import UiIcon from "./ui-icon.vue";
2
- import { Story } from "@storybook/vue3";
2
+ import type { Story } from "@storybook/vue3";
3
3
  import { ESize } from "../../_types/sizing";
4
4
 
5
5
  export default {
@@ -39,7 +39,7 @@ const Template: Story<TComponentProps> = (args) => ({
39
39
  },
40
40
  // And then the `args` are bound to your component with `v-bind="args"`
41
41
  template: `
42
- <ui-icon v-bind="args" :icon-name="['fas', 'fa-user-secret']" />
42
+ <ui-icon v-bind="args" :icon-name="['far', 'fa-face-smile']" />
43
43
  `,
44
44
  });
45
45
 
@@ -18,7 +18,7 @@
18
18
 
19
19
  <script lang="ts" setup>
20
20
  import { ESize } from "../../_types/sizing";
21
- import { TIconName } from "./_typings";
21
+ import type { TIconName } from "./_typings";
22
22
 
23
23
  defineProps<{
24
24
  className?: string;
@@ -1,6 +1,4 @@
1
1
  export enum EInputTypes {
2
2
  PRIMARY = "primary",
3
- SECONDARY = "secondary",
4
3
  ERROR = "error",
5
- WARNING = "warning",
6
4
  }
@@ -1,4 +1,4 @@
1
- import { Story } from "@storybook/vue3";
1
+ import type { Story } from "@storybook/vue3";
2
2
  import UiInput from "./ui-input.vue";
3
3
  import Icon from "../../_samples/icon.vue";
4
4
  import { ref } from "vue";
@@ -26,10 +26,16 @@ export default {
26
26
  control: { type: "boolean" },
27
27
  description: "The full width size",
28
28
  },
29
+ disabled: {
30
+ control: { type: "boolean" },
31
+ description: "The Element disabled state",
32
+ },
29
33
  },
30
34
  args: {
31
35
  placeholder: "Placeholder",
32
- fullWidth: false
36
+ fullWidth: false,
37
+ kind: undefined,
38
+ disabled: false,
33
39
  }
34
40
  };
35
41
 
@@ -47,7 +53,7 @@ const Template: Story<MyComponentProps> = (args: MyComponentProps) => ({
47
53
  };
48
54
  },
49
55
  template: `
50
- <ui-input v-bind="args" v-model="valueModel" />
56
+ <ui-input v-bind="args" v-model="valueModel" heading="heading" sub-label="subLabel" />
51
57
  `
52
58
  });
53
59
 
@@ -1,30 +1,52 @@
1
1
  <template>
2
- <div
3
- class="ui-input grid rounded-md border border-secondary-alt-500 bg-white max-w-xs items-center p-xs gap-xs"
4
- :class="[
5
- kind === EInputTypes.PRIMARY && 'border-primary',
6
- fullWidth && 'max-w-full',
7
- className,
8
- ]"
9
- >
10
- <div class="icon-wrapper">
11
- <slot name="prefix-icon" />
12
- </div>
13
- <input
14
- class="bg-transparent border-0 outline-0"
15
- type="text"
16
- :placeholder="placeholder"
17
- :value="modelValue"
18
- @input="$emit('update:modelValue', $event.target.value)"
2
+ <div class="ui-input">
3
+ <ui-typography
4
+ v-if="heading"
5
+ :weight="ETextWeight.BOLD"
6
+ class-name="mb-sm"
7
+ >
8
+ {{ heading }}
9
+ </ui-typography>
10
+ <div
11
+ class="ui-input__wrapper grid rounded-lg border bg-white max-w-xs items-center p-sm gap-xs"
12
+ :class="[
13
+ !kind && 'border-secondary-alt-500 hover:border-secondary-alt-700',
14
+ kind === EInputTypes.PRIMARY && 'border-primary',
15
+ kind === EInputTypes.ERROR && 'border-error',
16
+
17
+ disabled && 'border-secondary-alt-300 bg-secondary-alt-200',
18
+
19
+ fullWidth && 'max-w-full',
20
+ className,
21
+ ]"
19
22
  >
20
- <div class="icon-wrapper">
21
- <slot name="postfix-icon" />
23
+ <div class="icon-wrapper">
24
+ <slot name="prefix-icon" />
25
+ </div>
26
+ <input
27
+ class="bg-transparent border-0 outline-0"
28
+ type="text"
29
+ :placeholder="placeholder"
30
+ :value="modelValue"
31
+ @input="$emit('update:modelValue', ($event.target as HTMLTextAreaElement)?.value)"
32
+ >
33
+ <div class="icon-wrapper">
34
+ <slot name="postfix-icon" />
35
+ </div>
22
36
  </div>
37
+ <ui-typography
38
+ v-if="subLabel"
39
+ :size="ETypographySizes.SM"
40
+ class-name="mt-sm"
41
+ >
42
+ {{ subLabel }}
43
+ </ui-typography>
23
44
  </div>
24
45
  </template>
25
46
 
26
47
  <script lang="ts" setup>
27
48
  import { EInputTypes } from "./_typings";
49
+ import UiTypography, { ETypographySizes, ETextWeight } from "../ui-typography";
28
50
 
29
51
  defineProps<{
30
52
  placeholder?: string;
@@ -33,13 +55,20 @@
33
55
  fullWidth?: boolean;
34
56
  kind?: EInputTypes;
35
57
  className?: string;
58
+ heading?: string;
59
+ subLabel?: string;
36
60
  }>();
37
61
 
38
62
  defineEmits(["update:modelValue"]);
39
63
  </script>
40
64
 
41
65
  <style scoped>
42
- .ui-input {
66
+ .ui-input__wrapper {
43
67
  grid-template-columns: auto 1fr auto;
44
68
  }
69
+
70
+ .ui-input__wrapper input::placeholder {
71
+ color: var(--color-secondary-alt-500);
72
+ font-style: italic;
73
+ }
45
74
  </style>
@@ -0,0 +1 @@
1
+ export { default } from "./ui-input-range.vue";
@@ -0,0 +1,48 @@
1
+ import { ref } from "vue";
2
+ import UiInputRange from "./ui-input-range.vue";
3
+ import type { Story } from "@storybook/vue3";
4
+
5
+ export default {
6
+ title: "Components/ui-input-range",
7
+ component: UiInputRange,
8
+ argTypes: {
9
+ className: {
10
+ control: { type: "text" },
11
+ description: "The Element classes",
12
+ },
13
+ min:{
14
+ control: { type: "number" },
15
+ description: "The Element min value",
16
+ },
17
+ max:{
18
+ control: { type: "number" },
19
+ description: "The Element max value",
20
+ },
21
+ step:{
22
+ control: { type: "number" },
23
+ description: "The Element max value",
24
+ }
25
+ },
26
+ args: {
27
+ min: 0,
28
+ max: 100,
29
+ step: 1,
30
+ },
31
+ };
32
+
33
+ type TComponentProps = InstanceType<typeof UiInputRange>["$props"];
34
+
35
+ const Template: Story<TComponentProps> = (args) => ({
36
+ components: { UiInputRange },
37
+ setup() {
38
+ const modelValue = ref(50);
39
+
40
+ return { args, modelValue };
41
+ },
42
+ template: `
43
+ <ui-input-range v-bind="args" v-model:modelValue="modelValue"/>
44
+ <div>{{ modelValue }}</div>
45
+ `,
46
+ });
47
+
48
+ export const Default = Template.bind({});
@@ -0,0 +1,62 @@
1
+ <template>
2
+ <div
3
+ class="ui-input-range relative h-lg"
4
+ :class="className"
5
+ >
6
+ <input
7
+ class="appearance-none cursor-pointer bg-transparent w-full h-full"
8
+ type="range"
9
+ :min="min"
10
+ :max="max"
11
+ :value="modelValue"
12
+ :step="step"
13
+ @input="$emit('update:modelValue', ($event.target as HTMLInputElement).value)"
14
+ >
15
+ <div class="ui-input-range__line h-xs w-full bg-secondary-alt rounded absolute left-0 -z-10" />
16
+ <div
17
+ class="ui-input-range__line h-xs bg-primary rounded absolute left-0 -z-10"
18
+ :style="{
19
+ width: getPercentage + '%',
20
+ }"
21
+ />
22
+ </div>
23
+ </template>
24
+
25
+ <script lang="ts" setup>
26
+ import { computed } from "vue";
27
+
28
+ const props = defineProps<{
29
+ modelValue: string | number;
30
+ min: string | number;
31
+ max: string | number;
32
+ step: string | number;
33
+ className?: string;
34
+ }>();
35
+
36
+ defineEmits<{
37
+ (e: "update:modelValue", state: string | number): void
38
+ }>();
39
+
40
+ const getPercentage = computed(() => {
41
+ return Math.round(((+props.modelValue - +props.min) / (+props.max - +props.min)) * 100);
42
+ });
43
+ </script>
44
+
45
+ <style scoped>
46
+ input[type="range"]::-webkit-slider-thumb {
47
+ appearance: none;
48
+ background-color: var(--color-primary);
49
+ height: 13px;
50
+ width: 13px;
51
+ border-radius: 50%;
52
+ border: var(--xs) solid var(--color-white);
53
+ box-shadow: 0 0 0 4px var(--color-primary);
54
+ box-sizing: content-box;
55
+ z-index: 1;
56
+ }
57
+
58
+ .ui-input-range__line {
59
+ top: 50%;
60
+ transform: translate3d(0, -50%, 0);
61
+ }
62
+ </style>
@@ -0,0 +1 @@
1
+ export { default } from "./ui-list-item.vue";
@@ -0,0 +1,40 @@
1
+ import UiIconList from "./ui-list-item.vue";
2
+ import type { Story } from "@storybook/vue3";
3
+
4
+ export default {
5
+ title: "Components/ui-list-item",
6
+ component: UiIconList,
7
+ argTypes: {
8
+ className: {
9
+ control: { type: "text" },
10
+ description: "The Element classes",
11
+ },
12
+ },
13
+ args: {
14
+ slot: "default text",
15
+ }
16
+ };
17
+
18
+ type TComponentProps = InstanceType<typeof UiIconList>["$props"];
19
+
20
+ const Template: Story<TComponentProps> = (args) => ({
21
+ components: { UiIconList },
22
+ setup() {
23
+ return { args };
24
+ },
25
+ template: `
26
+ <ul>
27
+ <ui-icon-list :icon="['far', 'face-smile']">
28
+ {{args.slot}}
29
+ </ui-icon-list>
30
+ <ui-icon-list :icon="['far', 'face-smile']">
31
+ {{args.slot}}
32
+ </ui-icon-list>
33
+ <ui-icon-list :icon="['far', 'face-smile']">
34
+ {{args.slot}}
35
+ </ui-icon-list>
36
+ </ul>
37
+ `
38
+ });
39
+
40
+ export const Default = Template.bind({});
@@ -0,0 +1,29 @@
1
+ <template>
2
+ <li class="ui-icon-list">
3
+ <ui-icon
4
+ v-if="icon"
5
+ class-name="mr-xs"
6
+ :size="ESize.SM"
7
+ :icon-name="icon"
8
+ />
9
+
10
+ <ui-typography
11
+ is="span"
12
+ :weight="ETextWeight.SEMI_BOLD"
13
+ :size="ETypographySizes.SM"
14
+ >
15
+ <slot />
16
+ </ui-typography>
17
+ </li>
18
+ </template>
19
+
20
+ <script lang="ts" setup>
21
+ import UiIcon, { type TIconName } from "../ui-icon";
22
+ import { ESize } from "../../_types/sizing";
23
+ import UiTypography, { ETypographySizes, ETextWeight } from "../ui-typography";
24
+
25
+ defineProps<{
26
+ icon?: TIconName;
27
+ }>();
28
+
29
+ </script>
@@ -1,5 +1,5 @@
1
1
  import UiRadio from "./ui-radio.vue";
2
- import { Story } from "@storybook/vue3";
2
+ import type { Story } from "@storybook/vue3";
3
3
  import { ref } from "vue";
4
4
  import { EJustify } from "../../_types/align";
5
5
 
@@ -21,11 +21,16 @@ export default {
21
21
  control: { type: "boolean" },
22
22
  description: "The Element order",
23
23
  },
24
+ disabled: {
25
+ control: { type: "boolean" },
26
+ description: "The Element disabled state",
27
+ },
24
28
  },
25
29
  args: {
26
30
  slot: "Some text",
27
31
  justify: EJustify.START,
28
32
  invertOrder: false,
33
+ disabled: false,
29
34
  },
30
35
  };
31
36
 
@@ -36,7 +41,7 @@ const Template: Story<TComponentProps> = (args) => ({
36
41
  components: { UiRadio },
37
42
  // The story's `args` need to be mapped into the template through the `setup()` method
38
43
  setup() {
39
- const modelValue = ref("value2");
44
+ const modelValue = ref("value4");
40
45
 
41
46
  return { args, modelValue };
42
47
  },
@@ -52,7 +57,7 @@ const Template: Story<TComponentProps> = (args) => ({
52
57
  <ui-radio v-bind="args" name="radio" value="value3" v-model="modelValue">
53
58
  {{args.slot}}
54
59
  </ui-radio>
55
- <ui-radio v-bind="args" name="radio" value="value4" v-model="modelValue">
60
+ <ui-radio v-bind="args" name="radio" disabled value="value4" v-model="modelValue">
56
61
  {{args.slot}}
57
62
  </ui-radio>
58
63
  </div>
@@ -9,6 +9,7 @@
9
9
  justify === EJustify.BETWEEN && 'justify-between',
10
10
  justify === EJustify.EVENLY && 'justify-evenly',
11
11
  justify === EJustify.CENTER && 'justify-center',
12
+ disabled && 'pointer-events-none',
12
13
  className
13
14
  ]"
14
15
  >
@@ -18,11 +19,12 @@
18
19
  type="radio"
19
20
  :name="name"
20
21
  :value="value"
22
+ :disabled="disabled"
21
23
  class="appearance-none absolute"
22
- @input="$emit('update:modelValue', $event.target.value)"
24
+ @input="$emit('update:modelValue', ($event.target as HTMLTextAreaElement)?.value)"
23
25
  >
24
26
  <span
25
- class="ui-radio_custom block w-md h-md border border-2 border-primary rounded-full relative"
27
+ class="ui-radio_custom block w-md h-md border border-secondary-alt rounded-full relative hover:border-secondary-alt-700 focus:border-secondary-alt-700"
26
28
  :class="invertOrder && 'order-last'"
27
29
  >
28
30
  <span class="ui-radio__dot absolute top-2/4 left-2/4 w-xs h-xs block bg-primary rounded-full" />
@@ -42,13 +44,14 @@
42
44
  value: string;
43
45
  justify?: EJustify;
44
46
  invertOrder?: boolean;
47
+ disabled?: boolean;
45
48
  }>();
46
49
 
47
50
  defineEmits(["update:modelValue"]);
48
51
 
49
52
  const localValue = ref(props.modelValue);
50
53
 
51
- watch(()=>props.modelValue, (newValue)=>{
54
+ watch(() => props.modelValue, (newValue) => {
52
55
  if(newValue !== localValue.value){
53
56
  localValue.value = newValue;
54
57
  }
@@ -65,7 +68,37 @@
65
68
  transition: transform 0.2s ease-in-out;
66
69
  }
67
70
 
71
+ input:disabled + .ui-radio_custom {
72
+ border: 1px solid var(--color-secondary-alt-400);
73
+ background-color: var(--color-secondary-alt-200);
74
+ }
75
+
76
+ input:focus + .ui-radio_custom {
77
+ box-shadow: var(--shadow-border-primary);
78
+ }
79
+
80
+ input:checked + .ui-radio_custom {
81
+ border: 2px solid var(--color-primary);
82
+ }
83
+
68
84
  input:checked + .ui-radio_custom .ui-radio__dot {
69
85
  transform: translate3d(-50%, -50%, 0) scale(1);
70
86
  }
87
+
88
+ input:checked + .ui-radio_custom:hover {
89
+ border: 2px solid var(--color-primary-600);
90
+ }
91
+
92
+ input:checked + .ui-radio_custom:hover .ui-radio__dot {
93
+ background-color: var(--color-primary-600);
94
+ }
95
+
96
+ input:checked:disabled + .ui-radio_custom {
97
+ border: 2px solid var(--color-primary-300);
98
+ background-color: var(--color-white);
99
+ }
100
+
101
+ input:checked:disabled + .ui-radio_custom .ui-radio__dot {
102
+ background-color: var(--color-primary-300);
103
+ }
71
104
  </style>