@redseed/redseed-ui-vue3 2.3.0 → 2.4.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.
Files changed (29) hide show
  1. package/package.json +1 -1
  2. package/src/components/Button/ButtonDanger.vue +3 -21
  3. package/src/components/Button/ButtonDangerFull.vue +1 -9
  4. package/src/components/Button/ButtonDangerFullRounded.vue +1 -10
  5. package/src/components/Button/ButtonDangerRounded.vue +1 -9
  6. package/src/components/Button/ButtonPrimary.vue +3 -18
  7. package/src/components/Button/ButtonPrimaryFull.vue +1 -9
  8. package/src/components/Button/ButtonPrimaryFullRounded.vue +1 -10
  9. package/src/components/Button/ButtonPrimaryRounded.vue +1 -9
  10. package/src/components/Button/ButtonSecondary.vue +3 -19
  11. package/src/components/Button/ButtonSecondaryFull.vue +1 -9
  12. package/src/components/Button/ButtonSecondaryFullRounded.vue +1 -10
  13. package/src/components/Button/ButtonSecondaryRounded.vue +1 -9
  14. package/src/components/Button/ButtonSlot.vue +8 -5
  15. package/src/components/Button/ButtonTertiary.vue +3 -21
  16. package/src/components/Button/ButtonTertiaryFull.vue +1 -9
  17. package/src/components/Button/ButtonTertiaryFullRounded.vue +1 -10
  18. package/src/components/Button/ButtonTertiaryRounded.vue +1 -9
  19. package/src/components/ButtonGroup/ButtonGroupItem.vue +5 -5
  20. package/src/components/FormField/FormFieldCheckbox.vue +28 -32
  21. package/src/components/FormField/FormFieldEmail.vue +4 -28
  22. package/src/components/FormField/FormFieldHidden.vue +6 -4
  23. package/src/components/FormField/FormFieldPassword.vue +4 -48
  24. package/src/components/FormField/FormFieldPasswordToggle.vue +12 -24
  25. package/src/components/FormField/FormFieldSearch.vue +7 -20
  26. package/src/components/FormField/FormFieldSelect.vue +30 -34
  27. package/src/components/FormField/FormFieldSlot.vue +50 -23
  28. package/src/components/FormField/FormFieldText.vue +43 -24
  29. package/src/components/FormField/FormFieldTextSuffix.vue +6 -17
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redseed/redseed-ui-vue3",
3
- "version": "2.3.0",
3
+ "version": "2.4.0",
4
4
  "description": "RedSeed UI Vue 3 components",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -1,34 +1,16 @@
1
1
  <script setup>
2
- import { computed } from 'vue'
3
2
  import ButtonSlot from './ButtonSlot.vue'
4
-
5
- defineOptions({
6
- inheritAttrs: false,
7
- })
8
-
9
- const buttonClass = computed(() => [
10
- 'rsui-button-danger',
11
- ])
12
3
  </script>
13
4
  <template>
14
- <ButtonSlot
15
- :class="buttonClass"
16
- v-bind="$attrs"
17
- >
5
+ <ButtonSlot class="rsui-button-danger">
18
6
  <slot></slot>
19
7
  </ButtonSlot>
20
8
  </template>
21
9
  <style lang="scss" scoped>
22
10
  .rsui-button-danger {
23
11
  // default colors
24
- @apply bg-danger-content text-danger ring-danger/30 border-danger/40;
25
- // default hover state
26
- @apply hover:border-danger;
27
- // default focus state
28
- @apply focus-visible:border-danger/30;
12
+ @apply bg-danger-content text-danger border-danger;
29
13
  // default active state
30
- @apply active:border-danger active:bg-danger/10;
31
- // default disabled state
32
- @apply disabled:text-danger/20 disabled:border-danger/20 disabled:bg-danger-content;
14
+ @apply active:border-danger active:bg-danger-content;
33
15
  }
34
16
  </style>
@@ -1,16 +1,8 @@
1
1
  <script setup>
2
- import { computed } from 'vue'
3
2
  import ButtonDanger from './ButtonDanger.vue'
4
-
5
- defineOptions({
6
- inheritAttrs: false,
7
- })
8
3
  </script>
9
4
  <template>
10
- <ButtonDanger
11
- full
12
- v-bind="$attrs"
13
- >
5
+ <ButtonDanger full>
14
6
  <slot></slot>
15
7
  </ButtonDanger>
16
8
  </template>
@@ -1,17 +1,8 @@
1
1
  <script setup>
2
- import { computed } from 'vue'
3
2
  import ButtonDanger from './ButtonDanger.vue'
4
-
5
- defineOptions({
6
- inheritAttrs: false,
7
- })
8
3
  </script>
9
4
  <template>
10
- <ButtonDanger
11
- full
12
- rounded
13
- v-bind="$attrs"
14
- >
5
+ <ButtonDanger full rounded>
15
6
  <slot></slot>
16
7
  </ButtonDanger>
17
8
  </template>
@@ -1,16 +1,8 @@
1
1
  <script setup>
2
- import { computed } from 'vue'
3
2
  import ButtonDanger from './ButtonDanger.vue'
4
-
5
- defineOptions({
6
- inheritAttrs: false,
7
- })
8
3
  </script>
9
4
  <template>
10
- <ButtonDanger
11
- rounded
12
- v-bind="$attrs"
13
- >
5
+ <ButtonDanger rounded>
14
6
  <slot></slot>
15
7
  </ButtonDanger>
16
8
  </template>
@@ -1,32 +1,17 @@
1
1
  <script setup>
2
2
  import { computed } from 'vue'
3
3
  import ButtonSlot from './ButtonSlot.vue'
4
-
5
- defineOptions({
6
- inheritAttrs: false,
7
- })
8
-
9
- const buttonClass = computed(() => [
10
- 'rsui-button-primary',
11
- ])
12
4
  </script>
13
5
  <template>
14
- <ButtonSlot
15
- :class="buttonClass"
16
- v-bind="$attrs"
17
- >
6
+ <ButtonSlot class="rsui-button-primary">
18
7
  <slot></slot>
19
8
  </ButtonSlot>
20
9
  </template>
21
10
  <style lang="scss" scoped>
22
11
  .rsui-button-primary {
23
12
  // default colors
24
- @apply bg-primary text-primary-content ring-primary/30 border-primary;
25
- // default focus state
26
- @apply focus-visible:border-primary/30;
13
+ @apply bg-primary text-primary-content border-primary;
27
14
  // default active state
28
- @apply active:border-primary active:bg-primary/80;
29
- // default disabled state
30
- @apply disabled:text-primary-content disabled:border-transparent disabled:bg-primary/30;
15
+ @apply active:border-primary active:bg-primary;
31
16
  }
32
17
  </style>
@@ -1,16 +1,8 @@
1
1
  <script setup>
2
- import { computed } from 'vue'
3
2
  import ButtonPrimary from './ButtonPrimary.vue'
4
-
5
- defineOptions({
6
- inheritAttrs: false,
7
- })
8
3
  </script>
9
4
  <template>
10
- <ButtonPrimary
11
- full
12
- v-bind="$attrs"
13
- >
5
+ <ButtonPrimary full>
14
6
  <slot></slot>
15
7
  </ButtonPrimary>
16
8
  </template>
@@ -1,17 +1,8 @@
1
1
  <script setup>
2
- import { computed } from 'vue'
3
2
  import ButtonPrimary from './ButtonPrimary.vue'
4
-
5
- defineOptions({
6
- inheritAttrs: false,
7
- })
8
3
  </script>
9
4
  <template>
10
- <ButtonPrimary
11
- full
12
- rounded
13
- v-bind="$attrs"
14
- >
5
+ <ButtonPrimary full rounded>
15
6
  <slot></slot>
16
7
  </ButtonPrimary>
17
8
  </template>
@@ -1,16 +1,8 @@
1
1
  <script setup>
2
- import { computed } from 'vue'
3
2
  import ButtonPrimary from './ButtonPrimary.vue'
4
-
5
- defineOptions({
6
- inheritAttrs: false,
7
- })
8
3
  </script>
9
4
  <template>
10
- <ButtonPrimary
11
- rounded
12
- v-bind="$attrs"
13
- >
5
+ <ButtonPrimary rounded>
14
6
  <slot></slot>
15
7
  </ButtonPrimary>
16
8
  </template>
@@ -1,32 +1,16 @@
1
1
  <script setup>
2
- import { computed } from 'vue'
3
2
  import ButtonSlot from './ButtonSlot.vue'
4
-
5
- defineOptions({
6
- inheritAttrs: false,
7
- })
8
-
9
- const buttonClass = computed(() => [
10
- 'rsui-button-secondary',
11
- ])
12
3
  </script>
13
4
  <template>
14
- <ButtonSlot
15
- :class="buttonClass"
16
- v-bind="$attrs"
17
- >
5
+ <ButtonSlot class="rsui-button-secondary">
18
6
  <slot></slot>
19
7
  </ButtonSlot>
20
8
  </template>
21
9
  <style lang="scss" scoped>
22
10
  .rsui-button-secondary {
23
11
  // default colors
24
- @apply bg-secondary text-secondary-content ring-secondary/30 border-secondary;
25
- // default focus state
26
- @apply focus-visible:border-secondary/30;
12
+ @apply bg-secondary text-secondary-content border-secondary;
27
13
  // default active state
28
- @apply active:border-secondary active:bg-secondary/80;
29
- // default disabled state
30
- @apply disabled:text-secondary-content disabled:border-transparent disabled:bg-secondary/30;
14
+ @apply active:border-secondary active:bg-secondary;
31
15
  }
32
16
  </style>
@@ -1,16 +1,8 @@
1
1
  <script setup>
2
- import { computed } from 'vue'
3
2
  import ButtonSecondary from './ButtonSecondary.vue'
4
-
5
- defineOptions({
6
- inheritAttrs: false,
7
- })
8
3
  </script>
9
4
  <template>
10
- <ButtonSecondary
11
- full
12
- v-bind="$attrs"
13
- >
5
+ <ButtonSecondary full>
14
6
  <slot></slot>
15
7
  </ButtonSecondary>
16
8
  </template>
@@ -1,17 +1,8 @@
1
1
  <script setup>
2
- import { computed } from 'vue'
3
2
  import ButtonSecondary from './ButtonSecondary.vue'
4
-
5
- defineOptions({
6
- inheritAttrs: false,
7
- })
8
3
  </script>
9
4
  <template>
10
- <ButtonSecondary
11
- full
12
- rounded
13
- v-bind="$attrs"
14
- >
5
+ <ButtonSecondary full rounded>
15
6
  <slot></slot>
16
7
  </ButtonSecondary>
17
8
  </template>
@@ -1,16 +1,8 @@
1
1
  <script setup>
2
- import { computed } from 'vue'
3
2
  import ButtonSecondary from './ButtonSecondary.vue'
4
-
5
- defineOptions({
6
- inheritAttrs: false,
7
- })
8
3
  </script>
9
4
  <template>
10
- <ButtonSecondary
11
- rounded
12
- v-bind="$attrs"
13
- >
5
+ <ButtonSecondary rounded>
14
6
  <slot></slot>
15
7
  </ButtonSecondary>
16
8
  </template>
@@ -85,14 +85,17 @@ const buttonSlotClass = computed(() => [
85
85
  // default shape
86
86
  @apply font-semibold gap-2 rounded-md border transition;
87
87
  // default colors
88
- @apply bg-black text-white ring-black/20 border-black;
88
+ @apply bg-white text-rsui-default ring-highlight border-rsui-default;
89
+ // default hover state
90
+ @apply hover:brightness-110;
89
91
  // default focus state
90
- @apply focus-visible:ring-4;
92
+ @apply focus-visible:ring-4 focus-visible:ring-highlight focus-visible:border-highlight;
91
93
  // default active state
92
- @apply active:ring-0 active:bg-black/80;
94
+ @apply active:ring-0 active:bg-white active:filter-none;
93
95
  // default disabled state
94
- @apply disabled:bg-black/20 disabled:border-transparent;
95
- @apply disabled:active:ring-0 disabled:focus-visible:ring-0;
96
+ @apply disabled:bg-rsui-grey-200 disabled:border-transparent disabled:text-white disabled:filter-none;
97
+ @apply disabled:active:bg-rsui-grey-200 disabled:active:ring-0 disabled:active:border-transparent;
98
+ @apply disabled:focus-visible:ring-0;
96
99
  // modifier full width
97
100
  &--full {
98
101
  @apply w-full;
@@ -1,34 +1,16 @@
1
1
  <script setup>
2
- import { computed } from 'vue'
3
2
  import ButtonSlot from './ButtonSlot.vue'
4
-
5
- defineOptions({
6
- inheritAttrs: false,
7
- })
8
-
9
- const buttonClass = computed(() => [
10
- 'rsui-button-tertiary',
11
- ])
12
3
  </script>
13
4
  <template>
14
- <ButtonSlot
15
- :class="buttonClass"
16
- v-bind="$attrs"
17
- >
5
+ <ButtonSlot class="rsui-button-tertiary">
18
6
  <slot></slot>
19
7
  </ButtonSlot>
20
8
  </template>
21
9
  <style lang="scss" scoped>
22
10
  .rsui-button-tertiary {
23
11
  // default colors
24
- @apply bg-tertiary text-tertiary-content ring-tertiary-content/30 border-tertiary-content/40;
25
- // default hover state
26
- @apply hover:border-tertiary-content;
27
- // default focus state
28
- @apply focus-visible:border-tertiary-content/30;
12
+ @apply bg-tertiary text-tertiary-content border-tertiary-content;
29
13
  // default active state
30
- @apply active:border-tertiary-content active:bg-tertiary-content/10;
31
- // default disabled state
32
- @apply disabled:text-tertiary-content/20 disabled:border-tertiary-content/20 disabled:bg-tertiary;
14
+ @apply active:border-tertiary-content active:bg-tertiary;
33
15
  }
34
16
  </style>
@@ -1,16 +1,8 @@
1
1
  <script setup>
2
- import { computed } from 'vue'
3
2
  import ButtonTertiary from './ButtonTertiary.vue'
4
-
5
- defineOptions({
6
- inheritAttrs: false,
7
- })
8
3
  </script>
9
4
  <template>
10
- <ButtonTertiary
11
- full
12
- v-bind="$attrs"
13
- >
5
+ <ButtonTertiary full>
14
6
  <slot></slot>
15
7
  </ButtonTertiary>
16
8
  </template>
@@ -1,17 +1,8 @@
1
1
  <script setup>
2
- import { computed } from 'vue'
3
2
  import ButtonTertiary from './ButtonTertiary.vue'
4
-
5
- defineOptions({
6
- inheritAttrs: false,
7
- })
8
3
  </script>
9
4
  <template>
10
- <ButtonTertiary
11
- full
12
- rounded
13
- v-bind="$attrs"
14
- >
5
+ <ButtonTertiary full rounded>
15
6
  <slot></slot>
16
7
  </ButtonTertiary>
17
8
  </template>
@@ -1,16 +1,8 @@
1
1
  <script setup>
2
- import { computed } from 'vue'
3
2
  import ButtonTertiary from './ButtonTertiary.vue'
4
-
5
- defineOptions({
6
- inheritAttrs: false,
7
- })
8
3
  </script>
9
4
  <template>
10
- <ButtonTertiary
11
- rounded
12
- v-bind="$attrs"
13
- >
5
+ <ButtonTertiary rounded>
14
6
  <slot></slot>
15
7
  </ButtonTertiary>
16
8
  </template>
@@ -38,15 +38,15 @@ const buttonClass = computed(() => [
38
38
  // default shape
39
39
  @apply first:rounded-l-md last:rounded-r-md first:border-l border-r border-y ring-0;
40
40
  // default colors
41
- @apply bg-white text-segment-content border-segment-content/30;
41
+ @apply bg-segment text-segment-content border-rsui-grey-300;
42
42
  // default hover state
43
- @apply hover:bg-segment-content/10;
43
+ @apply hover:bg-rsui-grey-200;
44
44
  // default active/pressed state
45
- @apply active:ring-0 active:bg-white;
45
+ @apply active:ring-0 active:bg-segment;
46
46
  // default disabled state
47
- @apply disabled:text-segment-content/20 disabled:bg-white;
47
+ @apply disabled:text-rsui-grey-200 disabled:bg-white;
48
48
  &--selected {
49
- @apply bg-segment-content/10 active:bg-segment-content/10 cursor-default;
49
+ @apply bg-rsui-grey-200 active:bg-rsui-grey-200 cursor-default;
50
50
  }
51
51
  &__label {
52
52
  @apply gap-x-2 px-1 inline-flex items-center;
@@ -1,46 +1,37 @@
1
1
  <script setup>
2
- import { ref, computed } from 'vue'
2
+ import { ref } from 'vue'
3
3
  import FormFieldSlot from './FormFieldSlot.vue'
4
4
  import { CheckIcon } from '@heroicons/vue/24/outline'
5
5
 
6
- const emit = defineEmits(['update:checked'])
7
-
8
- const props = defineProps({
9
- checked: {
10
- type: [Array, Boolean],
11
- default: false,
12
- },
13
- value: {
14
- type: String,
15
- default: null,
16
- },
6
+ defineOptions({
7
+ inheritAttrs: false,
17
8
  })
18
9
 
19
- const iconChecked = ref(false)
10
+ const model = defineModel()
20
11
 
21
- const proxyChecked = computed({
22
- get() {
23
- iconChecked.value = props.checked
24
- return props.checked
25
- },
12
+ const checked = ref(model.value || false)
26
13
 
27
- set(val) {
28
- iconChecked.value = val
29
- emit('update:checked', val)
30
- },
31
- })
14
+ const emit = defineEmits(['input'])
15
+
16
+ function check(event) {
17
+ checked.value = !checked.value
18
+ emit('input', event)
19
+ }
32
20
  </script>
33
21
  <template>
34
22
  <FormFieldSlot class="rsui-form-field-checkbox">
35
23
  <template #label>
36
24
  <div class="rsui-form-field-checkbox__checkbox">
37
25
  <div class="rsui-form-field-checkbox__check">
38
- <CheckIcon v-if="iconChecked" class="rsui-form-field-checkbox__icon"></CheckIcon>
26
+ <CheckIcon v-if="checked"></CheckIcon>
39
27
  <input
40
- v-model="proxyChecked"
41
- v-bind="$attrs"
28
+ v-model="model"
29
+ :id="$attrs.id"
30
+ :name="$attrs.name"
31
+ :disabled="$attrs.disabled"
32
+ :required="$attrs.required"
33
+ @input="check"
42
34
  type="checkbox"
43
- :value="value"
44
35
  >
45
36
  </div>
46
37
  <div v-if="$slots.label"
@@ -64,13 +55,18 @@ const proxyChecked = computed({
64
55
  @apply ml-2;
65
56
  }
66
57
  &__check {
67
- @apply w-6 h-6 shrink-0 relative bg-white rounded-md;
58
+ @apply size-6 shrink-0 relative bg-white rounded-md;
59
+ @apply has-[:disabled]:text-rsui-light;
68
60
 
69
61
  input[type="checkbox"] {
70
- @apply appearance-none absolute inset-0 rounded-md transition shadow-sm;
71
- @apply w-full h-full border border-gray-300 text-transparent bg-none;
72
- @apply focus:border-gray-300 focus:ring focus:ring-offset-0 focus:ring-gray-300 focus:ring-opacity-50;
73
- @apply invalid:border-red-500 invalid:ring invalid:ring-red-500 invalid:ring-opacity-20;
62
+ @apply appearance-none absolute inset-0 z-0 rounded-md transition focus:outline-none;
63
+ @apply w-full h-full text-rsui-default border border-rsui-grey-200 text-transparent bg-none;
64
+ @apply focus:ring focus:ring-rsui-light focus:border-rsui-light;
65
+ @apply invalid:border-danger invalid:ring-0;
66
+ @apply disabled:text-rsui-light disabled:bg-rsui-grey-200;
67
+ }
68
+ svg {
69
+ @apply size-full relative z-1;
74
70
  }
75
71
  }
76
72
  }
@@ -1,44 +1,20 @@
1
1
  <script setup>
2
- import { ref } from 'vue'
3
- import FormFieldSlot from './FormFieldSlot.vue'
4
-
5
- // Apply all attributes to the input element, not the wrapper div
6
- defineOptions({
7
- inheritAttrs: false,
8
- })
9
-
10
- const props = defineProps({
11
- modelValue: [
12
- String,
13
- Number
14
- ], //vue3 specific v-model pattern
15
- })
16
-
17
- defineEmits(['update:modelValue']) //vue3 specific v-model pattern
18
-
19
- const input = ref(null)
2
+ import FormFieldText from './FormFieldText.vue'
20
3
  </script>
21
4
  <template>
22
- <FormFieldSlot
23
- class="rsui-form-field-email"
24
- :id="$attrs.id"
5
+ <FormFieldText class="rsui-form-field-email"
6
+ type="email"
25
7
  >
26
8
  <template #label v-if="$slots.label">
27
9
  <slot name="label"></slot>
28
10
  </template>
29
- <input ref="input"
30
- v-bind="$attrs"
31
- type="email"
32
- :value="modelValue"
33
- @input="$emit('update:modelValue', $event.target.value)"
34
- >
35
11
  <template #help v-if="$slots.help">
36
12
  <slot name="help"></slot>
37
13
  </template>
38
14
  <template #error v-if="$slots.error">
39
15
  <slot name="error"></slot>
40
16
  </template>
41
- </FormFieldSlot>
17
+ </FormFieldText>
42
18
  </template>
43
19
  <style lang="scss" scoped>
44
20
  </style>
@@ -1,19 +1,21 @@
1
1
  <script setup>
2
- import { ref } from 'vue'
3
2
  import FormFieldSlot from './FormFieldSlot.vue'
4
3
 
5
- // Apply all attributes to the input element, not the wrapper div
6
4
  defineOptions({
7
5
  inheritAttrs: false,
8
6
  })
9
7
 
10
- const input = ref(null)
8
+ const model = defineModel()
11
9
  </script>
12
10
  <template>
13
11
  <FormFieldSlot
14
12
  class="rsui-form-field-hidden"
15
13
  >
16
- <input ref="input"
14
+ <input
15
+ v-model="model"
16
+ :id="$attrs.id"
17
+ :name="$attrs.name"
18
+ :required="$attrs.required"
17
19
  type="hidden"
18
20
  >
19
21
  <template #error v-if="$slots.error">
@@ -1,46 +1,14 @@
1
1
  <script setup>
2
- import { ref } from 'vue'
3
- import FormFieldSlot from './FormFieldSlot.vue'
4
-
5
- // Apply all attributes to the input element, not the wrapper div
6
- defineOptions({
7
- inheritAttrs: false,
8
- })
9
-
10
- const props = defineProps({
11
- modelValue: [
12
- String,
13
- Number
14
- ], //vue3 specific v-model pattern
15
- })
16
-
17
- defineEmits(['update:modelValue']) //vue3 specific v-model pattern
18
-
19
- const input = ref(null)
2
+ import FormFieldText from './FormFieldText.vue'
20
3
  </script>
21
4
  <template>
22
- <FormFieldSlot
23
- class="rsui-form-field-password"
24
- :id="$attrs.id"
5
+ <FormFieldText class="rsui-form-field-password"
6
+ type="password"
25
7
  >
26
8
  <template #label v-if="$slots.label">
27
9
  <slot name="label"></slot>
28
10
  </template>
29
11
 
30
- <div :class="{
31
- 'rsui-form-field-password__group': true,
32
- 'rsui-form-field-password__group--toggle': $slots.toggle,
33
- }">
34
- <input ref="input"
35
- type="password"
36
- v-bind="$attrs"
37
- :value="modelValue"
38
- @input="$emit('update:modelValue', $event.target.value)"
39
- >
40
-
41
- <slot name="toggle"></slot>
42
- </div>
43
-
44
12
  <template #help v-if="$slots.help">
45
13
  <slot name="help"></slot>
46
14
  </template>
@@ -48,19 +16,7 @@ const input = ref(null)
48
16
  <template #error v-if="$slots.error">
49
17
  <slot name="error"></slot>
50
18
  </template>
51
- </FormFieldSlot>
19
+ </FormFieldText>
52
20
  </template>
53
21
  <style lang="scss" scoped>
54
- .rsui-form-field-password {
55
- @apply relative;
56
-
57
- &__group {
58
- @apply relative;
59
- &--toggle {
60
- input {
61
- @apply pr-12;
62
- }
63
- }
64
- }
65
- }
66
22
  </style>
@@ -1,13 +1,8 @@
1
1
  <script setup>
2
2
  import { ref } from 'vue'
3
- import FormFieldPassword from './FormFieldPassword.vue'
3
+ import FormFieldText from './FormFieldText.vue'
4
4
  import { EyeIcon, EyeSlashIcon } from '@heroicons/vue/24/outline'
5
5
 
6
- // Apply all attributes to the input element, not the wrapper div
7
- defineOptions({
8
- inheritAttrs: false,
9
- })
10
-
11
6
  const show = ref(false)
12
7
 
13
8
  function togglePassword() {
@@ -15,24 +10,19 @@ function togglePassword() {
15
10
  }
16
11
  </script>
17
12
  <template>
18
- <FormFieldPassword
19
- v-bind="$attrs"
13
+ <FormFieldText class="rsui-form-field-password"
20
14
  :type="show ? 'text' : 'password'"
21
15
  >
22
16
  <template #label v-if="$slots.label">
23
17
  <slot name="label"></slot>
24
18
  </template>
25
19
 
26
- <template #toggle>
27
- <div class="rsui-form-field-password__toggle"
28
- @click="togglePassword"
20
+ <template #suffix>
21
+ <div class="rsui-form-field-password__icon"
22
+ @click.prevent="togglePassword"
29
23
  >
30
- <EyeIcon v-if="!show"
31
- class="rsui-form-field-password__toggle-icon"
32
- ></EyeIcon>
33
- <EyeSlashIcon v-if="show"
34
- class="rsui-form-field-password__toggle-icon"
35
- ></EyeSlashIcon>
24
+ <EyeIcon v-if="!show"></EyeIcon>
25
+ <EyeSlashIcon v-if="show"></EyeSlashIcon>
36
26
  </div>
37
27
  </template>
38
28
 
@@ -43,17 +33,15 @@ function togglePassword() {
43
33
  <template #error v-if="$slots.error">
44
34
  <slot name="error"></slot>
45
35
  </template>
46
- </FormFieldPassword>
36
+ </FormFieldText>
47
37
  </template>
48
38
  <style lang="scss" scoped>
49
39
  .rsui-form-field-password {
50
- &__toggle {
51
- @apply absolute top-px bottom-px right-px rounded-tr rounded-br;
52
- @apply flex items-center justify-center px-3 select-none cursor-pointer;
40
+ &__icon {
41
+ @apply size-5 text-rsui-default;
53
42
  }
54
-
55
- &__toggle-icon {
56
- @apply w-5 h-5;
43
+ :deep(.rsui-form-field-text__suffix) {
44
+ @apply pl-0;
57
45
  }
58
46
  }
59
47
  </style>
@@ -1,26 +1,15 @@
1
1
  <script setup>
2
- import { ref } from 'vue'
3
2
  import FormFieldText from './FormFieldText.vue'
4
3
  import { MagnifyingGlassIcon } from '@heroicons/vue/24/outline'
5
-
6
- // Apply all attributes to the input element, not the wrapper div
7
- defineOptions({
8
- inheritAttrs: false,
9
- })
10
4
  </script>
11
5
  <template>
12
- <FormFieldText
13
- v-bind="$attrs"
14
- class="rsui-form-field-search"
15
- >
6
+ <FormFieldText class="rsui-form-field-search">
16
7
  <template #label v-if="$slots.label">
17
8
  <slot name="label"></slot>
18
9
  </template>
19
10
 
20
- <template #prefix class="search">
21
- <div class="rsui-form-field-search__prefix">
22
- <MagnifyingGlassIcon class="rsui-form-field-search__icon"></MagnifyingGlassIcon>
23
- </div>
11
+ <template #prefix>
12
+ <MagnifyingGlassIcon class="rsui-form-field-search__icon"></MagnifyingGlassIcon>
24
13
  </template>
25
14
 
26
15
  <template #help v-if="$slots.help">
@@ -34,13 +23,11 @@ defineOptions({
34
23
  </template>
35
24
  <style lang="scss" scoped>
36
25
  .rsui-form-field-search {
37
- &__prefix {
38
- @apply absolute top-px bottom-px left-px rounded-tl rounded-bl;
39
- @apply flex items-center justify-center select-none;
40
- @apply w-10 pointer-events-none;
41
- }
42
26
  &__icon {
43
- @apply size-5 text-rsui-medium;
27
+ @apply size-5 text-rsui-light;
28
+ }
29
+ :deep(.rsui-form-field-text__prefix) {
30
+ @apply pr-0;
44
31
  }
45
32
  }
46
33
  </style>
@@ -4,31 +4,28 @@ import { onClickOutside } from '@vueuse/core'
4
4
  import FormFieldSlot from './FormFieldSlot.vue'
5
5
  import { ChevronDownIcon, CheckIcon } from '@heroicons/vue/24/outline'
6
6
 
7
- // Apply all attributes to the input element, not the wrapper div
8
7
  defineOptions({
9
8
  inheritAttrs: false,
10
9
  })
11
10
 
11
+ const model = defineModel({ default: '' })
12
+
12
13
  const props = defineProps({
13
- modelValue: [
14
- String,
15
- Number
16
- ], //vue3 specific v-model pattern
17
14
  options: {
18
15
  type: Array,
19
16
  default: () => []
20
17
  },
21
18
  })
22
19
 
23
- const emit = defineEmits(['update:modelValue', 'change']) //vue3 specific v-model pattern
20
+ const emit = defineEmits(['change'])
24
21
 
25
- const formFieldSelect = ref(null)
22
+ const formFieldSelectElement = ref(null)
26
23
 
27
- onClickOutside(formFieldSelect, () => close())
24
+ onClickOutside(formFieldSelectElement, () => close())
28
25
 
29
26
  const isOpen = ref(false)
30
27
 
31
- function toggle() {
28
+ function toggleOptions() {
32
29
  isOpen.value = !isOpen.value
33
30
  }
34
31
 
@@ -36,39 +33,31 @@ function close() {
36
33
  isOpen.value = false
37
34
  }
38
35
 
39
-
40
- function onClick() {
41
- toggle()
42
- }
43
-
44
- function onChange(event) {
45
- emit('change', event)
46
- emit('update:modelValue', event.target.value)
47
- close()
48
- }
49
-
50
36
  function choose(option) {
37
+ model.value = option.value
51
38
  emit('change', option.value)
52
- emit('update:modelValue', option.value)
53
39
  close()
54
40
  }
55
41
  </script>
56
42
  <template>
57
43
  <FormFieldSlot
58
- ref="formFieldSelect"
44
+ ref="formFieldSelectElement"
59
45
  class="rsui-form-field-select"
60
46
  :id="$attrs.id"
47
+ :compact="$attrs.compact"
61
48
  >
62
49
  <template #label v-if="$slots.label">
63
50
  <slot name="label"></slot>
64
51
  </template>
65
- <div :class="{
66
- 'rsui-form-field-select__group': true,
67
- }">
52
+ <div class="rsui-form-field-select__group">
68
53
  <select
69
- v-bind="$attrs"
70
- @click="onClick"
71
- @change="onChange"
54
+ v-model="model"
55
+ :id="$attrs.id"
56
+ :name="$attrs.name"
57
+ :disabled="$attrs.disabled"
58
+ :required="$attrs.required"
59
+ @click.prevent="toggleOptions"
60
+ @change.prevent
72
61
  >
73
62
  <option value="">
74
63
  <slot name="default-option">
@@ -102,9 +91,11 @@ function choose(option) {
102
91
  <div class="rsui-form-field-select__option rsui-form-field-select__option--disabled"
103
92
  value=""
104
93
  >
105
- <slot name="default-option">
106
- Select an option
107
- </slot>
94
+ <div class="rsui-form-field-select__option-label">
95
+ <slot name="default-option">
96
+ Select an option
97
+ </slot>
98
+ </div>
108
99
  </div>
109
100
  <div v-for="option in options"
110
101
  :key="option.value"
@@ -164,10 +155,15 @@ function choose(option) {
164
155
 
165
156
  &__group {
166
157
  @apply relative;
167
- }
168
158
 
169
- select {
170
- @apply pr-14 truncate bg-none;
159
+ select {
160
+ @apply pl-5 pr-14 truncate;
161
+ @apply appearance-none rounded-full cursor-pointer;
162
+ @apply focus:ring focus:ring-rsui-light focus:border-rsui-light;
163
+ option {
164
+ @apply hidden;
165
+ }
166
+ }
171
167
  }
172
168
 
173
169
  &__options {
@@ -1,7 +1,13 @@
1
1
  <script setup>
2
2
  import { computed, useAttrs } from 'vue'
3
3
 
4
- // Apply all attributes to the input element, not the wrapper div
4
+ const props = defineProps({
5
+ compact: {
6
+ type: Boolean,
7
+ required: false,
8
+ },
9
+ })
10
+
5
11
  defineOptions({
6
12
  inheritAttrs: false,
7
13
  })
@@ -9,8 +15,11 @@ defineOptions({
9
15
  const attrs = useAttrs()
10
16
 
11
17
  const formFieldSlotClass = computed(() => [
18
+ attrs.class,
12
19
  'rsui-form-field-slot',
13
- attrs.class
20
+ {
21
+ 'rsui-form-field-slot--compact': props.compact,
22
+ },
14
23
  ])
15
24
  </script>
16
25
  <template>
@@ -24,29 +33,43 @@ const formFieldSlotClass = computed(() => [
24
33
  <slot name="label"></slot>
25
34
  </label>
26
35
  </div>
27
- <slot></slot>
28
- <div v-if="$slots.help"
29
- class="rsui-form-field-slot__help"
30
- >
31
- <slot name="help"></slot>
32
- </div>
33
- <div v-if="$slots.error"
34
- class="rsui-form-field-slot__error"
35
- >
36
- <slot name="error"></slot>
36
+ <div class="rsui-form-field-slot__field">
37
+ <slot></slot>
38
+ <div v-if="$slots.help"
39
+ class="rsui-form-field-slot__help"
40
+ >
41
+ <slot name="help"></slot>
42
+ </div>
43
+ <div v-if="$slots.error"
44
+ class="rsui-form-field-slot__error"
45
+ >
46
+ <slot name="error"></slot>
47
+ </div>
37
48
  </div>
38
49
  </div>
39
50
  </template>
40
51
  <style lang="scss" scoped>
41
52
  .rsui-form-field-slot {
42
- @apply flex flex-col space-y-1 border-0 bg-transparent p-0;
53
+ @apply flex flex-col gap-y-1 border-0 bg-transparent p-0;
54
+ &--compact {
55
+ @apply flex-row justify-between gap-x-2;
56
+ .rsui-form-field-slot {
57
+ &__label {
58
+ @apply pt-3 truncate;
59
+ }
60
+ }
61
+ }
43
62
 
44
63
  &__label {
45
64
  label {
46
- @apply block font-medium text-base text-gray-700;
65
+ @apply font-medium text-base text-gray-700;
47
66
  }
48
67
  }
49
68
 
69
+ &__field {
70
+ @apply shrink-0 flex flex-col gap-y-1;
71
+ }
72
+
50
73
  &__help {
51
74
  @apply text-xs text-gray-500;
52
75
  }
@@ -58,17 +81,21 @@ const formFieldSlotClass = computed(() => [
58
81
  </style>
59
82
  <style lang="scss">
60
83
  .rsui-form-field-slot {
61
- input:not([type='checkbox']):not([type='radio']), select {
62
- @apply block w-full border rounded-md shadow-sm text-base transition py-2 px-3;
63
- @apply bg-white placeholder-gray-300 border-gray-300;
64
- @apply focus:ring focus:ring-gray-300 focus:ring-opacity-50 focus:outline-none ring-0 focus:bg-white focus:border-gray-400;
65
- @apply invalid:border-red-500 invalid:ring invalid:ring-red-500 invalid:ring-opacity-20;
84
+ input[type='text'],
85
+ input[type='email'],
86
+ input[type='password']
87
+ {
88
+ @apply flex-1;
89
+ @apply text-base text-rsui-default transition py-3 px-4 outline-none focus:outline-none;
90
+ @apply bg-white placeholder-rsui-light;
91
+ @apply disabled:text-rsui-light disabled:bg-rsui-grey-200 disabled:ring-0;
66
92
  }
67
93
  select {
68
- @apply appearance-none rounded-full px-5 cursor-pointer;
69
- option {
70
- @apply hidden;
71
- }
94
+ @apply block w-full border ring-0 bg-none;
95
+ @apply text-base text-rsui-default transition py-3 px-4 rounded-md outline-none focus:outline-none;
96
+ @apply bg-white placeholder-rsui-light border-rsui-grey-200;
97
+ @apply invalid:border-danger invalid:ring-0;
98
+ @apply disabled:text-rsui-light disabled:bg-rsui-grey-200 disabled:ring-0;
72
99
  }
73
100
  }
74
101
  </style>
@@ -2,45 +2,50 @@
2
2
  import { ref } from 'vue'
3
3
  import FormFieldSlot from './FormFieldSlot.vue'
4
4
 
5
- // Apply all attributes to the input element, not the wrapper div
6
5
  defineOptions({
7
6
  inheritAttrs: false,
8
7
  })
9
8
 
10
- const props = defineProps({
11
- modelValue: [
12
- String,
13
- Number
14
- ], //vue3 specific v-model pattern
15
- })
9
+ defineEmits(['input'])
16
10
 
17
- defineEmits(['update:modelValue']) //vue3 specific v-model pattern
11
+ const model = defineModel()
18
12
 
19
- const input = ref(null)
13
+ const inputElement = ref(null)
20
14
  </script>
21
15
  <template>
22
16
  <FormFieldSlot
23
- class="rsui-form-field-text"
24
17
  :id="$attrs.id"
18
+ :class="$attrs.class || 'rsui-form-field-text'"
19
+ :compact="$attrs.compact"
25
20
  >
26
21
  <template #label v-if="$slots.label">
27
22
  <slot name="label"></slot>
28
23
  </template>
29
- <div :class="{
30
- 'rsui-form-field-text__group': true,
31
- 'rsui-form-field-text__group--prefix': $slots.prefix,
32
- 'rsui-form-field-text__group--suffix': $slots.suffix,
33
- }">
34
- <slot name="prefix"></slot>
35
-
36
- <input ref="input"
37
- v-bind="$attrs"
38
- type="text"
39
- :value="modelValue"
40
- @input="$emit('update:modelValue', $event.target.value)"
24
+ <div class="rsui-form-field-text__group">
25
+ <div v-if="$slots.prefix"
26
+ class="rsui-form-field-text__prefix"
27
+ @click.prevent="$refs.inputElement.focus()"
28
+ >
29
+ <slot name="prefix"></slot>
30
+ </div>
31
+
32
+ <input ref="inputElement"
33
+ v-model="model"
34
+ :id="$attrs.id"
35
+ :name="$attrs.name"
36
+ :type="$attrs.type || 'text'"
37
+ :placeholder="$attrs.placeholder"
38
+ :disabled="$attrs.disabled"
39
+ :required="$attrs.required"
40
+ @input="$emit('input', $event)"
41
41
  >
42
42
 
43
- <slot name="suffix"></slot>
43
+ <div v-if="$slots.suffix"
44
+ class="rsui-form-field-text__suffix"
45
+ @click.prevent="$refs.inputElement.focus()"
46
+ >
47
+ <slot name="suffix"></slot>
48
+ </div>
44
49
  </div>
45
50
 
46
51
  <template #help v-if="$slots.help">
@@ -57,7 +62,21 @@ const input = ref(null)
57
62
  @apply relative;
58
63
 
59
64
  &__group {
60
- @apply relative;
65
+ @apply relative flex flex-nowrap overflow-hidden;
66
+ @apply text-base transition;
67
+ @apply w-full border rounded-md ring-0;
68
+ @apply bg-white placeholder-rsui-light border-rsui-grey-200;
69
+ @apply has-[:focus]:ring has-[:focus]:ring-rsui-light has-[:focus]:border-rsui-light;
70
+ @apply has-[:invalid]:border-danger has-[:invalid]:ring-0;
71
+ @apply has-[:disabled]:text-rsui-light has-[:disabled]:bg-rsui-grey-200 has-[:disbaled]:ring-0;
72
+ }
73
+ &__prefix {
74
+ @apply flex items-center justify-center px-4 select-none;
75
+ @apply bg-transparent;
76
+ }
77
+ &__suffix {
78
+ @apply flex items-center justify-center px-4 select-none;
79
+ @apply bg-transparent;
61
80
  }
62
81
  }
63
82
  </style>
@@ -1,24 +1,14 @@
1
1
  <script setup>
2
- import { ref } from 'vue'
3
2
  import FormFieldText from './FormFieldText.vue'
4
-
5
- // Apply all attributes to the input element, not the wrapper div
6
- defineOptions({
7
- inheritAttrs: false,
8
- })
9
3
  </script>
10
4
  <template>
11
- <FormFieldText
12
- v-bind="$attrs"
13
- >
5
+ <FormFieldText class="rsui-form-field-suffix">
14
6
  <template #label v-if="$slots.label">
15
7
  <slot name="label"></slot>
16
8
  </template>
17
9
 
18
10
  <template #suffix>
19
- <div class="rsui-form-field-text__suffix">
20
- <slot name="suffix"></slot>
21
- </div>
11
+ <slot name="suffix"></slot>
22
12
  </template>
23
13
 
24
14
  <template #help v-if="$slots.help">
@@ -31,11 +21,10 @@ defineOptions({
31
21
  </FormFieldText>
32
22
  </template>
33
23
  <style lang="scss" scoped>
34
- .rsui-form-field-text {
35
- &__suffix {
36
- @apply absolute top-px bottom-px right-px rounded-tr rounded-br;
37
- @apply flex items-center justify-center px-3 select-none;
38
- @apply bg-gray-100 border-l border-gray-300;
24
+ .rsui-form-field-suffix {
25
+ :deep(.rsui-form-field-text__suffix) {
26
+ @apply border-l rounded-r-md;
27
+ @apply bg-rsui-grey-200 border-rsui-light;
39
28
  }
40
29
  }
41
30
  </style>