bonkers-ui 1.0.24 → 1.0.26

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.
@@ -0,0 +1,32 @@
1
+ import { create } from '@storybook/theming/create';
2
+
3
+ export default create({
4
+ base: 'light',
5
+ colorPrimary: '#56c55d',
6
+ colorSecondary: 'rgba(86, 197, 93, 0.9)',
7
+
8
+ // UI
9
+ appBg: 'white',
10
+ appContentBg: 'white',
11
+ appBorderColor: 'silver',
12
+ appBorderRadius: 4,
13
+
14
+ // Text colors
15
+ textColor: 'black',
16
+ textInverseColor: 'rgba(255,255,255,0.9)',
17
+
18
+ // Toolbar default and active colors
19
+ barTextColor: 'silver',
20
+ barSelectedColor: '#56c55d',
21
+ barBg: 'white',
22
+
23
+ // Form colors
24
+ inputBg: 'white',
25
+ inputBorder: 'silver',
26
+ inputTextColor: 'black',
27
+ inputBorderRadius: 4,
28
+
29
+ brandTitle: 'Bonkers-UI Design System',
30
+ brandUrl: 'https://github.com/bonkers-ie/bonkers-ui',
31
+ brandImage: 'https://web-assets.bonkers.ie/packs/static/logo/bonkers_logo-279f0cff5a9b71e3059a.svg',
32
+ });
@@ -0,0 +1,7 @@
1
+
2
+ import { addons } from '@storybook/addons';
3
+ import BonkersTheme from './BonkersTheme';
4
+
5
+ addons.setConfig({
6
+ theme: BonkersTheme,
7
+ });
@@ -6,10 +6,10 @@ import { library } from '@fortawesome/fontawesome-svg-core';
6
6
  import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
7
7
 
8
8
  /* import specific icons */
9
- import { faFaceSmile } from '@fortawesome/free-regular-svg-icons';
9
+ import { faFaceSmile, faCircleCheck } from '@fortawesome/free-regular-svg-icons';
10
10
 
11
11
  /* add icons to the library */
12
- library.add(faFaceSmile);
12
+ library.add(faFaceSmile, faCircleCheck);
13
13
 
14
14
  import '../src/main.css';
15
15
 
@@ -19,6 +19,24 @@ export const parameters = {
19
19
  darkMode: false,
20
20
  stylePreview: true,
21
21
  actions: {argTypesRegex: "^on[A-Z].*"},
22
+ backgrounds: {
23
+ default: "Bonkers",
24
+ values: [
25
+ {
26
+ name: "Bonkers",
27
+ value: "url(https://web-assets.bonkers.ie/maverick/img/about.0ed347c.png)",
28
+ },
29
+ {
30
+ name: "Light",
31
+ value: "#ffffff"
32
+ },
33
+ {
34
+ name: "Dark",
35
+ value: "#202124"
36
+ }
37
+ ],
38
+ },
39
+ layout: "padded",
22
40
  controls: {
23
41
  matchers: {
24
42
  color: /(background|color)$/i,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bonkers-ui",
3
- "version": "1.0.24",
3
+ "version": "1.0.26",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "storybook": "start-storybook -p 6006",
@@ -19,6 +19,8 @@
19
19
  "@fortawesome/free-regular-svg-icons": "^6.2.0",
20
20
  "@fortawesome/free-solid-svg-icons": "^6.2.0",
21
21
  "@fortawesome/vue-fontawesome": "^3.0.1",
22
+ "@vueuse/components": "^9.4.0",
23
+ "@vueuse/core": "^9.4.0",
22
24
  "husky": "4.3.8",
23
25
  "vue": "^3.2.41"
24
26
  },
@@ -0,0 +1 @@
1
+ export { default } from "./ui-backdrop.vue";
@@ -0,0 +1,42 @@
1
+ <template>
2
+ <transition-group
3
+ name="fade"
4
+ enter-active-class="transition-opacity duration-300"
5
+ leave-active-class="transition-opacity duration-300 opacity-0"
6
+ enter-from-class="opacity-0"
7
+ leave-to-class="opacity-0"
8
+ >
9
+ <div
10
+ v-if="visible"
11
+ class="
12
+ backdrop-color
13
+ fixed
14
+ backdrop-blur-sm
15
+ transition-all
16
+ inset-0
17
+ z-0
18
+ "
19
+ />
20
+
21
+ <slot />
22
+ </transition-group>
23
+ </template>
24
+
25
+ <script lang="ts" setup>
26
+
27
+ withDefaults(
28
+ defineProps<{
29
+ visible?: boolean;
30
+ }>(),
31
+ {
32
+ visible: true,
33
+ }
34
+ );
35
+
36
+ </script>
37
+
38
+ <style lang="css" scoped>
39
+ .backdrop-color {
40
+ background-color: rgb(0 0 0 / 50%);
41
+ }
42
+ </style>
@@ -54,7 +54,7 @@ const Template: Story<TComponentProps> = (args) => ({
54
54
  return { args, ESize };
55
55
  },
56
56
  // And then the `args` are bound to your component with `v-bind="args"`
57
- template: `
57
+ template: /*html*/`
58
58
  <ui-button :kind="args.kind"
59
59
  :size="args.size"
60
60
  :fullWidth="args.fullWidth"
@@ -82,7 +82,7 @@ const TemplateAll: Story<TComponentProps> = () => ({
82
82
  return { EButtonSizes, EButtonTypes };
83
83
  },
84
84
 
85
- template: `
85
+ template: /*html*/`
86
86
  <div :style="{
87
87
  display: 'flex',
88
88
  flexWrap: 'wrap'
@@ -1,2 +1,2 @@
1
1
  export { default } from "./ui-icon-wrapper.vue";
2
- export { EIconWrapperTypes } from "./_typings";
2
+ export { EIconWrapperTypes, EIconWrapperSizes } from "./_typings";
@@ -20,13 +20,15 @@
20
20
  <slot name="prefix-icon" />
21
21
 
22
22
  <input
23
- v-model="inputModel"
23
+ :value="modelValue"
24
+ :pattern="pattern"
24
25
  class="bg-transparent border-0 outline-none w-full placeholder:text-secondary-alt placeholder:italic"
25
26
  :type="type || 'text'"
26
27
  :placeholder="placeholder"
27
- :pattern="pattern"
28
28
  :maxlength="maxlength"
29
29
  :minlength="minlength"
30
+ @input="$emit('update:modelValue', ($event.target as HTMLTextAreaElement)?.value)"
31
+ @focus="focusHandler"
30
32
  >
31
33
 
32
34
  <slot name="postfix-icon" />
@@ -42,11 +44,10 @@
42
44
  </template>
43
45
 
44
46
  <script lang="ts" setup>
45
- import { computed } from "vue";
46
47
  import { EInputKinds, EInputType } from "./_typings";
47
48
  import UiTypography, { ETypographySizes, ETextWeight } from "../ui-typography";
48
49
 
49
- const props = defineProps<{
50
+ withDefaults(defineProps<{
50
51
  placeholder?: string;
51
52
  modelValue: string;
52
53
  disabled?: boolean;
@@ -57,17 +58,11 @@
57
58
  pattern?: string;
58
59
  maxlength?: string;
59
60
  minlength?: string;
60
- }>();
61
-
62
- const emit = defineEmits(["update:modelValue"]);
63
-
64
- const inputModel = computed({
65
- get() {
66
- return props.modelValue;
67
- },
68
- set(value) {
69
- emit("update:modelValue", value);
70
- }
61
+ focusHandler?: (e:FocusEvent) => void;
62
+ }>(), {
63
+ modelValue: ""
71
64
  });
72
65
 
66
+ defineEmits(["update:modelValue"]);
67
+
73
68
  </script>
@@ -42,18 +42,19 @@ const Template: Story<TComponentProps> = (args) => ({
42
42
  },
43
43
  template:/*html*/`
44
44
  <ul>
45
- <ui-list-item :icon="['far', 'face-smile']" title="title only" :kind="args.kind" :size="args.size">
45
+ <ui-list-item v-bind="args" :icon="['far', 'face-smile']" title="title only">
46
46
  {{args.slot}}
47
47
  </ui-list-item>
48
48
 
49
- <ui-list-item :icon="['far', 'face-smile']" :kind="args.kind" :size="args.size">
49
+ <ui-list-item v-bind="args" :icon="['far', 'face-smile']">
50
50
  text only
51
51
  </ui-list-item>
52
52
 
53
- <ui-list-item v-for= "item in 5" :key="item" :icon="['far', 'face-smile']" :title="args.title" :kind="args.kind" :size="args.size">
53
+ <ui-list-item v-bind="args" v-for= "item in 5" :key="item" :icon="['far', 'face-smile']">
54
54
  {{ args.title }}
55
55
  </ui-list-item>
56
- <ui-list-item class="compact-list-item" :icon="['far', 'face-smile']" :size="args.size" :title="args.title">
56
+
57
+ <ui-list-item v-bind="args" class="compact-list-item" :icon="['far', 'face-smile']" />
57
58
  </ul>
58
59
  `,
59
60
  });
@@ -11,14 +11,14 @@
11
11
  v-if="kind===EListItemTypes.PROGRESS"
12
12
  class="ui-list-item__line bg-primary-300 h-full absolute w-xxs left-xs -translate-x-2/4 top-sm group-last:hidden"
13
13
  />
14
-
14
+
15
15
  <ui-icon
16
16
  v-if="icon"
17
- :kind="pickKind"
18
17
  class="bg-white text-primary"
19
18
  :icon-name="icon"
20
19
  :size="ESize.SM"
21
20
  />
21
+
22
22
  <div>
23
23
  <ui-typography
24
24
  v-if="title"
@@ -32,30 +32,21 @@
32
32
  </template>
33
33
 
34
34
  <script lang="ts" setup>
35
- import { computed } from "vue";
36
35
  import UiIcon, { type TIconName } from "../ui-icon";
37
36
  import UiTypography, { ETextWeight } from "../ui-typography";
38
37
  import { ESize } from "../../_types/sizing";
39
- import { EListItemTypes } from "./_types";
40
- import { EListItemSizes } from "./_types";
38
+ import { EListItemTypes, EListItemSizes } from "./_types";
41
39
 
42
- const props = withDefaults(defineProps<{
43
- icon: TIconName
40
+ withDefaults(defineProps<{
41
+ icon?: TIconName
44
42
  title?: string
45
43
  kind?: EListItemTypes
46
- size: EListItemSizes
44
+ size?: EListItemSizes
47
45
  }>(), {
48
46
  kind: EListItemTypes.DEFAULT,
49
47
  size: EListItemSizes.COMPACT,
50
- title: ""
51
- });
52
-
53
- const pickKind = computed(()=>{
54
- switch(props.kind){
55
- case EListItemTypes.DEFAULT: return EListItemTypes.DEFAULT;
56
- case EListItemTypes.PROGRESS: return EListItemTypes.PROGRESS;
57
- default: return EListItemTypes.DEFAULT;
58
- }
48
+ title: "",
49
+ icon: undefined
59
50
  });
60
51
 
61
52
  </script>
@@ -0,0 +1,6 @@
1
+ export enum EModalSizes {
2
+ SM = "sm",
3
+ MD = "md",
4
+ LG = "lg",
5
+ RESPONSIVE = "responsive",
6
+ }
@@ -0,0 +1,2 @@
1
+ export { default } from "./ui-modal.vue";
2
+ export { EModalSizes } from "./_typings";
@@ -0,0 +1,103 @@
1
+ import { ref } from "vue";
2
+ import type { Story } from "@storybook/vue3";
3
+ import UiModal from "./ui-modal.vue";
4
+ import UiButton from "../ui-button";
5
+ import UiBackdrop from "../ui-backdrop";
6
+ import UiIcon from "../ui-icon";
7
+ import UiTypography from "../ui-typography";
8
+ import { ESize } from "../../_types/sizing";
9
+ import { EModalSizes } from "./_typings";
10
+
11
+ export default {
12
+ title: "Components/ui-modal",
13
+ component: UiModal,
14
+ argTypes: {
15
+ title: {
16
+ control: { type: "text" },
17
+ description: "The modal title text",
18
+ },
19
+ modalSize: {
20
+ control: { type: "select" },
21
+ options: Object.values(EModalSizes),
22
+ description: "The modal kinds",
23
+ },
24
+ modalVisible: {
25
+ control: { type: "boolean" },
26
+ description: "Control Modal Visibility",
27
+ },
28
+
29
+ },
30
+ args: {
31
+ title: "Password Updated",
32
+ body: "You can now use your new security info to sign in to your account",
33
+ modalSize: ESize.SM,
34
+ }
35
+ };
36
+
37
+ type TComponentProps = InstanceType<typeof UiModal>["$props"];
38
+
39
+ const Template: Story<TComponentProps> = (args) => ({
40
+ components: { UiModal, UiBackdrop, UiButton, UiIcon, UiTypography },
41
+ setup() {
42
+ const isVisible = ref(false);
43
+
44
+ const showModal = () => {
45
+ isVisible.value = true;
46
+ };
47
+
48
+ const closeModal = () => {
49
+ isVisible.value = false;
50
+ };
51
+
52
+ return { args, showModal, closeModal, isVisible, ESize };
53
+ },
54
+ template:/*html*/`
55
+ <transition
56
+ name="ui-modal"
57
+ mode="out-in"
58
+ appear
59
+ enter-active-class="transition delay-100"
60
+ enter-from-class="opacity-0 translate-y-1/4"
61
+ enter-to-class="opacity-100 translate-y-0"
62
+ leave-active-class="transition"
63
+ leave-to-class="opacity-0 translate-y-1/4"
64
+ leave-from-class="opacity-100 translate-y-0"
65
+ >
66
+ <ui-modal
67
+ v-if="isVisible"
68
+ :title="args.title"
69
+ :modalSize="args.modalSize"
70
+ :closeModal="closeModal"
71
+ >
72
+ <template #icon>
73
+ <ui-icon class="text-primary" :icon-name="['far', 'circle-check']" :size=ESize.XL />
74
+ </template>
75
+ <template #title>
76
+ <ui-typography class="text-2xl font-bold">{{ args.title }}</ui-typography>
77
+ </template>
78
+
79
+ <template #default >
80
+ {{args.body}}
81
+ </template>
82
+ <template #footer>
83
+ <ui-button
84
+ fullWidth
85
+ @click="closeModal"
86
+ >
87
+ Ok
88
+ </ui-button>
89
+ </template>
90
+ </ui-modal>
91
+ </transition>
92
+
93
+ <ui-backdrop v-if="isVisible" />
94
+
95
+ <div class="absolute" style="top: calc(50vh - 2rem); left: calc(50vw - 4rem)">
96
+ <ui-button @click="showModal">
97
+ Toggle Modal
98
+ </ui-button>
99
+ </div>
100
+ `
101
+ });
102
+
103
+ export const Default = Template.bind({});
@@ -0,0 +1,71 @@
1
+ <template>
2
+ <div
3
+ v-on-click-outside="closeModal"
4
+ class="
5
+ ui-modal
6
+ absolute
7
+ m-auto
8
+ flex flex-col
9
+ items-center
10
+ z-10
11
+ opacity-0
12
+ inset-0
13
+ rounded-2xl
14
+ shadow-md
15
+ p-md
16
+ bg-white
17
+ overflow-y-scroll
18
+ "
19
+ :class="[
20
+ modalSize === EModalSizes.SM &&'h-fit max-h-[24rem] max-w-[24rem]',
21
+ modalSize === EModalSizes.MD &&'h-fit max-h-[32rem] max-w-[32rem]',
22
+ modalSize === EModalSizes.LG &&'h-fit max-h-[40rem] max-w-[40rem]',
23
+ modalSize === EModalSizes.RESPONSIVE && 'h-5/6 w-11/12',
24
+ ]"
25
+ >
26
+ <div
27
+ class="mt-md mb-sm"
28
+ >
29
+ <slot name="icon" />
30
+ </div>
31
+ <ui-typography
32
+ v-if="title"
33
+ class="my-md"
34
+ :weight="ETextWeight.BOLD"
35
+ :align="ETextAlign.CENTER"
36
+ :size="ETypographySizes.LG"
37
+ >
38
+ {{ title }}
39
+ </ui-typography>
40
+ <ui-typography
41
+ :weight="ETextWeight.REGULAR"
42
+ :align="ETextAlign.CENTER"
43
+ line-height
44
+ class="text-secondary mb-md"
45
+ >
46
+ <slot />
47
+ </ui-typography>
48
+
49
+ <div class="w-full mt-auto">
50
+ <slot name="footer" />
51
+ </div>
52
+ </div>
53
+ </template>
54
+ <script lang="ts" setup>
55
+ import { vOnClickOutside } from "@vueuse/components";
56
+ import { ETypographySizes } from "../ui-typography/";
57
+ import UiTypography, { ETextWeight, ETextAlign } from "../ui-typography";
58
+ import { EModalSizes } from "./_typings";
59
+
60
+ withDefaults(
61
+ defineProps<{
62
+ title: string;
63
+ modalSize?: EModalSizes;
64
+ closeModal: () => void;
65
+ }>(),
66
+ {
67
+ modalSize: EModalSizes.SM,
68
+ }
69
+ );
70
+
71
+ </script>
@@ -8,7 +8,7 @@
8
8
  type="radio"
9
9
  :name="name"
10
10
  :value="value"
11
- class="peer group fixed w-0"
11
+ class="peer group appearance-none absolute"
12
12
  :class="disabled && 'pointer-events-none opacity-50'"
13
13
  >
14
14
  <div
@@ -19,6 +19,7 @@
19
19
  py-sm px-sm
20
20
  border
21
21
  border-secondary-alt-500
22
+ bg-white
22
23
  hover:border-secondary-alt-700
23
24
  cursor-pointer
24
25
  rounded-xl
@@ -63,7 +64,6 @@
63
64
  modelValue: string;
64
65
  name: string;
65
66
  value: string | number;
66
- id: string;
67
67
  iconName: TIconName;
68
68
  disabled?: boolean;
69
69
  }>();