@livestorm/ui-vue 1.1.2 → 1.1.3

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.
@@ -1,3 +1,94 @@
1
+ <script setup lang="ts">
2
+ import { useSlotsAsComponents } from '../../utils/slot'
3
+ import { computed, inject } from 'vue'
4
+
5
+ interface BaseFormInputInjectionType {
6
+ childConfig: { value: any } | undefined,
7
+ setInputModel: (value: any) => void,
8
+ }
9
+
10
+ const BaseFormInputInjection = inject<BaseFormInputInjectionType | undefined>('BaseFormInputInjection', undefined)
11
+
12
+ const props = withDefaults(defineProps<{
13
+ modelValue?: any,
14
+ value?: any,
15
+ label?: string,
16
+ labelClass?: string,
17
+ description?: string,
18
+ inputClass?: string,
19
+ forId: string,
20
+ tooltip?: string,
21
+ required?: boolean,
22
+ disabled?: boolean,
23
+ disableChange?: boolean,
24
+ isConsent?: boolean,
25
+ icon?: string,
26
+ orientation?: 'horizontal' | 'vertical',
27
+ }>(), {
28
+ value: false,
29
+ label: undefined,
30
+ labelClass: undefined,
31
+ description: undefined,
32
+ inputClass: undefined,
33
+ forId: undefined,
34
+ tooltip: undefined,
35
+ required: false,
36
+ disabled: false,
37
+ disableChange: false,
38
+ isConsent: false,
39
+ icon: 'i-ls-check',
40
+ orientation: 'horizontal',
41
+ })
42
+
43
+ const emit = defineEmits<{
44
+ (e: 'change', a: any): void,
45
+ (e: 'update:modelValue', a: any): void,
46
+ (e: 'tooltip-clicked'): void,
47
+ }>()
48
+
49
+ const slots = useSlotsAsComponents()
50
+ const iconSlot = computed(() => slots.icon ? slots.icon() : null)
51
+
52
+ const baseFormInputValue = computed(() => BaseFormInputInjection?.childConfig?.value)
53
+
54
+ function isValueChecked (modelValue: any) {
55
+ if (Array.isArray(modelValue)) {
56
+ return modelValue.includes(props.value)
57
+ }
58
+ return modelValue === props.value
59
+ }
60
+
61
+ const checked = computed(() => {
62
+ if (props.modelValue !== undefined) {
63
+ return isValueChecked(props.modelValue)
64
+ } else if (BaseFormInputInjection && !!baseFormInputValue.value) {
65
+ return isValueChecked(baseFormInputValue.value) && props.value
66
+ }
67
+ return props.value
68
+ })
69
+
70
+ function onChange (event: Event) {
71
+ const target = event.target as HTMLInputElement
72
+ let newValue: any = target.checked
73
+
74
+ if (props.modelValue !== undefined) {
75
+ newValue = [...props.modelValue]
76
+ if (target.checked) {
77
+ newValue.push(props.value)
78
+ } else {
79
+ newValue.splice(newValue.indexOf(props.value), 1)
80
+ }
81
+ }
82
+
83
+ emit('update:modelValue', newValue)
84
+ emit('change', newValue)
85
+
86
+ if (BaseFormInputInjection) {
87
+ BaseFormInputInjection.setInputModel(newValue)
88
+ }
89
+ }
90
+ </script>
91
+
1
92
  <template>
2
93
  <div
3
94
  class="base-checkbox"
@@ -5,6 +96,7 @@
5
96
  'base-checkbox-disabled': disabled,
6
97
  'pointer-events-none': disableChange,
7
98
  'base-checkbox-consent' : isConsent,
99
+ 'with-description': description,
8
100
  }"
9
101
  >
10
102
  <input
@@ -15,8 +107,25 @@
15
107
  type="checkbox"
16
108
  @change="onChange"
17
109
  >
18
- <label :for="forId">
110
+ <label
111
+ :for="forId"
112
+ :class="{
113
+ 'flex flex-col vertical-padding-large': orientation === 'vertical',
114
+ 'vertical-padding': description && orientation === 'horizontal',
115
+ }"
116
+ >
117
+ <div
118
+ v-if="iconSlot"
119
+ class="w-4 h-4 icon flex items-center justify-center"
120
+ :class="[orientation === 'vertical' ? 'mb-2' : 'mr-2']"
121
+ >
122
+ <RenderSlot
123
+ :vnodes="iconSlot"
124
+ />
125
+ </div>
126
+
19
127
  <span
128
+ v-if="orientation === 'horizontal'"
20
129
  class="input-custom !mt-[1px]"
21
130
  :class="inputClass"
22
131
  >
@@ -29,9 +138,15 @@
29
138
  <span
30
139
  v-if="label"
31
140
  class="label-custom"
141
+ :class="{
142
+ 'mb-2 !ml-0 text-center': orientation === 'vertical'
143
+ }"
32
144
  >
33
145
  <span
34
- :class="labelClass"
146
+ class="text-grey-700 label"
147
+ :class="[
148
+ labelClass,
149
+ ]"
35
150
  v-html="required ? `${label} *` : label"
36
151
  />
37
152
  <span
@@ -40,122 +155,26 @@
40
155
  data-testid="open-tooltip"
41
156
  @click.stop.prevent="$emit('tooltip-clicked')"
42
157
  />
158
+ <span
159
+ v-if="description"
160
+ class="text-14-medium text-grey-600 description block"
161
+ :class="{
162
+ 'text-center': orientation === 'vertical'
163
+ }"
164
+ v-html="description"
165
+ />
166
+ </span>
167
+
168
+ <span
169
+ v-if="orientation === 'vertical'"
170
+ class="input-custom"
171
+ >
172
+ <div
173
+ v-if="!disabled || checked"
174
+ :class="icon"
175
+ class="check-checkbox"
176
+ />
43
177
  </span>
44
178
  </label>
45
179
  </div>
46
180
  </template>
47
-
48
- <script>
49
- export default {
50
- inject: {
51
- BaseFormInputInjection: { default: null },
52
- },
53
-
54
- props: {
55
- // eslint-disable-next-line
56
- modelValue: {},
57
-
58
- // eslint-disable-next-line
59
- value: {
60
- default: false,
61
- },
62
-
63
- label: {
64
- type: String,
65
- default: null,
66
- },
67
-
68
- labelClass: {
69
- type: String,
70
- default: null,
71
- },
72
-
73
- inputClass: {
74
- type: String,
75
- default: null,
76
- },
77
-
78
- forId: {
79
- type: String,
80
- required: true,
81
- },
82
-
83
- tooltip: {
84
- type: String,
85
- default: null,
86
- },
87
-
88
- required: {
89
- type: Boolean,
90
- default: false,
91
- },
92
-
93
- disabled: {
94
- type: Boolean,
95
- default: false,
96
- },
97
-
98
- disableChange: {
99
- type: Boolean,
100
- default: false,
101
- },
102
-
103
- isConsent: {
104
- type: Boolean,
105
- default: false,
106
- },
107
-
108
- icon: {
109
- type: String,
110
- default: 'i-ls-check',
111
- },
112
- },
113
-
114
- emits: [
115
- 'change',
116
- 'update:modelValue',
117
- 'tooltip-clicked',
118
- ],
119
-
120
- computed: {
121
- baseFormInputValue () {
122
- return this.BaseFormInputInjection && this.BaseFormInputInjection.childConfig.value
123
- },
124
-
125
- checked () {
126
- if (this.modelValue !== undefined) {
127
- return Array.isArray(this.modelValue)
128
- ? this.modelValue.includes(this.value)
129
- : this.modelValue === this.value
130
- } else if (this.BaseFormInputInjection && !!this.baseFormInputValue) {
131
- return Array.isArray(this.baseFormInputValue)
132
- ? this.baseFormInputValue.includes(this.value)
133
- : this.baseFormInputValue === this.value && this.value
134
- }
135
- return this.value
136
- },
137
- },
138
-
139
- methods: {
140
- onChange (event) {
141
- let newValue = event.target.checked
142
-
143
- if (this.modelValue !== undefined) {
144
- newValue = [...this.modelValue]
145
- if (event.target.checked) {
146
- newValue.push(this.value)
147
- } else {
148
- newValue.splice(newValue.indexOf(this.value), 1)
149
- }
150
- }
151
-
152
- this.$emit('update:modelValue', newValue)
153
- this.$emit('change', newValue)
154
-
155
- if (this.BaseFormInputInjection) {
156
- this.BaseFormInputInjection.setInputModel(newValue)
157
- }
158
- },
159
- },
160
- }
161
- </script>
@@ -1,4 +1,5 @@
1
1
  import BaseModal from './BaseModal.vue'
2
+ import { icons } from '@/../../frontend/.storybook/icons'
2
3
  import { action } from '@storybook/addon-actions'
3
4
  import { withDesign } from 'storybook-addon-designs'
4
5
 
@@ -22,6 +23,12 @@ export default {
22
23
  },
23
24
  options: ['info', 'success', 'warning', 'alert'],
24
25
  },
26
+ customIcon: {
27
+ control: {
28
+ type: 'select',
29
+ },
30
+ options: icons,
31
+ },
25
32
  },
26
33
  decorators: [withDesign],
27
34
  parameters: {
@@ -127,6 +134,11 @@ Locked.args = {
127
134
  locked: true,
128
135
  }
129
136
 
137
+ export const CustomIcon = TitleContentActions.bind({})
138
+ CustomIcon.args = {
139
+ customIcon: 'i-ls-mail',
140
+ }
141
+
130
142
  export const ConfirmLoading = TitleContentActions.bind({})
131
143
  ConfirmLoading.args = {
132
144
  confirmLoading: true,
File without changes
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { computed, defineEmits, defineProps, inject, watch } from 'vue'
2
+ import { computed, inject, watch } from 'vue'
3
3
  import BaseButton from '../BaseButton/BaseButton.vue'
4
4
  import { useSlotsAsComponents } from '../../utils/slot'
5
5
  import { InjectClose, InjectOnClose, InjectPropsFromContent } from './BaseModal.vue'
@@ -13,6 +13,7 @@ interface ModalProps {
13
13
  confirmLoading?: boolean
14
14
  confirmColor?: string
15
15
  confirmHref?: string
16
+ customIcon?: string;
16
17
  type?: 'alert'|'warning'|'info'|'success'
17
18
  }
18
19
 
@@ -60,9 +61,9 @@ const emit = defineEmits([
60
61
  'close',
61
62
  ])
62
63
 
63
- // Types
64
+ const modalIcon = computed(() => {
65
+ if (props.customIcon) return props.customIcon
64
66
 
65
- const typeIcon = computed(() => {
66
67
  switch (props.type) {
67
68
  case 'alert':
68
69
  return 'i-ls-alert-circle text-red-600'
@@ -73,9 +74,10 @@ const typeIcon = computed(() => {
73
74
  case 'success':
74
75
  return 'i-ls-check-circle text-green-600'
75
76
  default:
76
- return 'i-ls-alert-circle text-livestorm-600'
77
+ return undefined
77
78
  }
78
79
  })
80
+
79
81
  </script>
80
82
 
81
83
  <template>
@@ -91,9 +93,9 @@ const typeIcon = computed(() => {
91
93
  class="flex items-center px-6 pt-6"
92
94
  >
93
95
  <div
94
- v-if="props.type"
96
+ v-if="modalIcon"
95
97
  class="w-6 h-6 mr-2 sm:mr-3 shrink-0"
96
- :class="typeIcon"
98
+ :class="modalIcon"
97
99
  />
98
100
  <span
99
101
  data-testid="modal-title"
@@ -0,0 +1,164 @@
1
+ import BaseRadio from './BaseRadio.vue'
2
+ import { action } from '@storybook/addon-actions'
3
+
4
+ export default {
5
+ title: 'common/vue/components/BaseRadio',
6
+ component: BaseRadio,
7
+ }
8
+
9
+ const actions = {
10
+ onChange: action('change'),
11
+ onClick: action('click'),
12
+ }
13
+
14
+ const Template = (args) => ({
15
+ components: { BaseRadio },
16
+ setup: () => ({ args, ...actions }),
17
+ template: '<BaseRadio v-bind="args" @tooltip-clicked="onClick" @change="onChange" />',
18
+ })
19
+
20
+ const TemplateWithBackground = (args) => ({
21
+ components: { BaseRadio },
22
+ setup: () => ({ args, ...actions }),
23
+ template: '<BaseRadio class="base-choice" v-bind="args" @tooltip-clicked="onClick" @change="onChange" />',
24
+ })
25
+
26
+ export const Selected = Template.bind({})
27
+ Selected.args = {
28
+ value: true,
29
+ modelValue: true,
30
+ forId: 'my-radio',
31
+ label: 'This Radio button is selected',
32
+ }
33
+
34
+ export const SelectedWithBackground = TemplateWithBackground.bind({})
35
+ SelectedWithBackground.args = Selected.args
36
+
37
+ export const NotSelected = Template.bind({})
38
+ NotSelected.args = {
39
+ value: false,
40
+ modelValue: true,
41
+ forId: 'my-radio',
42
+ label: 'This Radio button is not selected',
43
+ }
44
+
45
+ export const WithLabelClass = Template.bind({})
46
+ WithLabelClass.args = {
47
+ value: false,
48
+ modelValue: true,
49
+ forId: 'my-radio',
50
+ label: 'This radio button has a label class',
51
+ labelClass: '!text-16-medium',
52
+ }
53
+
54
+ export const WithDescription = Template.bind({})
55
+ WithDescription.args = {
56
+ value: false,
57
+ modelValue: true,
58
+ forId: 'my-radio',
59
+ label: 'This radio button has a description',
60
+ description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam diam leo, semper ut urna ut, tristique placerat dolor. Mauris hendrerit dolor tempus purus fringilla malesuada.',
61
+ }
62
+
63
+ export const Required = Template.bind({})
64
+ Required.args = {
65
+ value: true,
66
+ modelValue: true,
67
+ forId: 'my-radio',
68
+ label: 'This Radio button is required',
69
+ required: true,
70
+ }
71
+
72
+ export const Disabled = Template.bind({})
73
+ Disabled.args = {
74
+ value: true,
75
+ modelValue: true,
76
+ forId: 'my-radio',
77
+ label: 'This Radio button is disabled',
78
+ disabled: true,
79
+ }
80
+
81
+ export const WithTooltip = Template.bind({})
82
+ WithTooltip.args = {
83
+ value: true,
84
+ modelValue: true,
85
+ forId: 'my-radio',
86
+ label: 'This Radio button has a tooltip',
87
+ tooltip: 'Base radio tooltip',
88
+ }
89
+
90
+ const WithBorderTemplate = (args) => ({
91
+ components: { BaseRadio },
92
+ setup: () => ({ args, ...actions }),
93
+ template: '<BaseRadio class="base-choice" v-bind="args" @tooltip-clicked="onClick" @change="onChange" />',
94
+ })
95
+
96
+ export const WithBorder = WithBorderTemplate.bind({})
97
+ WithBorder.args = {
98
+ value: true,
99
+ modelValue: true,
100
+ forId: 'my-radio',
101
+ label: 'This Radio has a border',
102
+ }
103
+
104
+ export const WithBorderDisabled = WithBorderTemplate.bind({})
105
+ WithBorderDisabled.args = {
106
+ value: true,
107
+ modelValue: true,
108
+ disabled: true,
109
+ forId: 'my-radio',
110
+ label: 'This Radio has a border and is disabled',
111
+ }
112
+
113
+ export const SelectedWithBorder = WithBorderTemplate.bind({})
114
+ SelectedWithBorder.args = Selected.args
115
+
116
+ export const NotSelectedWithBorder = WithBorderTemplate.bind({})
117
+ NotSelectedWithBorder.args = NotSelected.args
118
+
119
+ export const WithDescriptionWithBorder = WithBorderTemplate.bind({})
120
+ WithDescriptionWithBorder.args = WithDescription.args
121
+
122
+ export const WithBorderVertical = WithBorderTemplate.bind({})
123
+ WithBorderVertical.args = {
124
+ ...WithBorder.args,
125
+ orientation: 'vertical',
126
+ }
127
+
128
+ export const WithBorderWithDescriptionVertical = WithBorderTemplate.bind({})
129
+ WithBorderWithDescriptionVertical.args = {
130
+ ...WithDescription.args,
131
+ orientation: 'vertical',
132
+ }
133
+
134
+ const WithBorderAndImageTemplate = (args) => ({
135
+ components: { BaseRadio },
136
+ setup: () => ({ args, ...actions }),
137
+ template: `<BaseRadio class="base-choice" v-bind="args" @tooltip-clicked="onClick" @change="onChange">
138
+ <template #icon>
139
+ <div class="i-ls-twitter-fill" />
140
+ </template>
141
+ </BaseRadio>`,
142
+ })
143
+
144
+ export const WithBorderWithDescriptionWithIconVertical = WithBorderAndImageTemplate.bind({})
145
+ WithBorderWithDescriptionWithIconVertical.args = {
146
+ ...WithDescription.args,
147
+ orientation: 'vertical',
148
+ }
149
+
150
+ const withBorderAndImageTemplate = (args) => ({
151
+ components: { BaseRadio },
152
+ setup: () => ({ args, ...actions }),
153
+ template: `<BaseRadio class="base-choice" v-bind="args" @tooltip-clicked="onClick" @change="onChange">
154
+ <template #icon>
155
+ <img src="/outlook.svg" />
156
+ </template>
157
+ </BaseRadio>`,
158
+ })
159
+
160
+ export const WithBorderWithDescriptionWithImageVertical = withBorderAndImageTemplate.bind({})
161
+ WithBorderWithDescriptionWithImageVertical.args = {
162
+ ...WithDescription.args,
163
+ orientation: 'vertical',
164
+ }
@@ -0,0 +1,153 @@
1
+ <script setup lang="ts">
2
+ import { useSlotsAsComponents } from '../../utils/slot'
3
+ import { computed, inject, ref } from 'vue'
4
+
5
+ interface BaseFormInputInjectionType {
6
+ childConfig: { value: any } | undefined,
7
+ setInputModel: (value: any) => void,
8
+ }
9
+
10
+ const BaseFormInputInjection = inject<BaseFormInputInjectionType | undefined>('BaseFormInputInjection', undefined)
11
+
12
+ const props = withDefaults(defineProps<{
13
+ modelValue?: any,
14
+ value: any,
15
+ label?: string,
16
+ labelContainerClass?: string,
17
+ labelClass?: string,
18
+ description?: string,
19
+ forId?: string,
20
+ required?: boolean,
21
+ disabled?: boolean,
22
+ tooltip?: string,
23
+ orientation?: 'horizontal' | 'vertical'
24
+ }>(), {
25
+ modelValue: null,
26
+ label: undefined,
27
+ labelContainerClass: undefined,
28
+ labelClass: undefined,
29
+ description: undefined,
30
+ forId: undefined,
31
+ required: false,
32
+ disabled: false,
33
+ tooltip: undefined,
34
+ orientation: 'horizontal',
35
+ })
36
+
37
+ const emit = defineEmits<{
38
+ (e: 'change', a: any): void,
39
+ (e: 'update:modelValue', a: any): void,
40
+ (e: 'tooltip-clicked'): void,
41
+ }>()
42
+
43
+ const slots = useSlotsAsComponents()
44
+ const iconSlot = computed(() => slots.icon ? slots.icon() : null)
45
+
46
+ const finalCurrentValue = computed(() => BaseFormInputInjection?.childConfig?.value)
47
+ const checked = computed(() => {
48
+ if (!BaseFormInputInjection) {
49
+ return props.modelValue === props.value
50
+ }
51
+ return finalCurrentValue.value === props.value
52
+ })
53
+
54
+ function onChange () {
55
+ if (!BaseFormInputInjection) {
56
+ emit('update:modelValue', props.value)
57
+ emit('change', props.value)
58
+ return false
59
+ }
60
+ BaseFormInputInjection.setInputModel(props.value)
61
+ }
62
+
63
+ const myUid = ref()
64
+
65
+ myUid.value = `BaseRadio:${uid++}`
66
+ </script>
67
+
68
+ <template>
69
+ <div
70
+ class="base-radio"
71
+ :class="{
72
+ 'base-radio-disabled': disabled,
73
+ 'with-description': description,
74
+ }"
75
+ >
76
+ <input
77
+ :id="forId || myUid"
78
+ :checked="checked"
79
+ :disabled="disabled"
80
+ :value="value"
81
+ type="radio"
82
+ @change="onChange"
83
+ >
84
+ <label
85
+ :for="forId || myUid"
86
+ :class="{
87
+ 'label-disabled': disabled,
88
+ 'flex flex-col vertical-padding-large': orientation === 'vertical',
89
+ 'vertical-padding': description && orientation === 'horizontal',
90
+ }"
91
+ >
92
+
93
+ <div
94
+ v-if="iconSlot"
95
+ class="w-4 h-4 icon flex items-center justify-center"
96
+ :class="[orientation === 'vertical' ? 'mb-2' : 'mr-2']"
97
+ >
98
+ <RenderSlot
99
+ :vnodes="iconSlot"
100
+ />
101
+ </div>
102
+
103
+ <span
104
+ v-if="orientation === 'horizontal'"
105
+ class="input-custom"
106
+ >
107
+ <span class="check-radio" />
108
+ </span>
109
+
110
+ <span
111
+ v-if="label"
112
+ class="label-custom"
113
+ :class="{
114
+ 'mb-2 !ml-0 text-center': orientation === 'vertical'
115
+ }"
116
+ >
117
+ <span
118
+ class="text-grey-700 label"
119
+ :class="[
120
+ labelClass,
121
+ ]"
122
+ v-html="required ? `${label} *` : label"
123
+ />
124
+ <span
125
+ v-if="tooltip"
126
+ v-tooltip="tooltip"
127
+ @click.stop.prevent="$emit('tooltip-clicked')"
128
+ />
129
+ <span
130
+ v-if="description"
131
+ class="description text-grey-600 block"
132
+ :class="{
133
+ 'text-center': orientation === 'vertical'
134
+ }"
135
+ v-html="description"
136
+ />
137
+ </span>
138
+
139
+ <span
140
+ v-if="orientation === 'vertical'"
141
+ class="input-custom"
142
+ >
143
+ <span class="check-radio" />
144
+ </span>
145
+
146
+ <slot name="incentive" />
147
+ </label>
148
+ </div>
149
+ </template>
150
+
151
+ <script lang="ts">
152
+ let uid = 0
153
+ </script>
@@ -342,6 +342,15 @@
342
342
  }
343
343
  }
344
344
 
345
+ &-alpha-black {
346
+ @apply text-white bg-alpha-black-800;
347
+ &:not(:disabled):not(.disabled) {
348
+ &:hover {
349
+ @apply bg-alpha-black-600;
350
+ }
351
+ }
352
+ }
353
+
345
354
  &-alpha-white-bg {
346
355
  @apply text-white bg-transparent;
347
356
  transition: background .5s ease-out;