@proj-airi/ui 0.8.1-beta.9 → 0.8.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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@proj-airi/ui",
3
3
  "type": "module",
4
- "version": "0.8.1-beta.9",
4
+ "version": "0.8.3",
5
5
  "description": "A collection of UI components that used by Project AIRI",
6
6
  "author": {
7
7
  "name": "Moeru AI Project AIRI Team",
@@ -10,6 +10,7 @@ import {
10
10
  ComboboxItem,
11
11
  ComboboxItemIndicator,
12
12
  ComboboxLabel,
13
+ ComboboxPortal,
13
14
  ComboboxRoot,
14
15
  ComboboxSeparator,
15
16
  ComboboxTrigger,
@@ -62,69 +63,79 @@ function toDisplayValue(value: T): string {
62
63
  </ComboboxTrigger>
63
64
  </ComboboxAnchor>
64
65
 
65
- <ComboboxContent
66
- :avoid-collisions="true"
67
- :class="[
68
- 'absolute z-10 w-full mt-1 min-w-[160px] overflow-hidden rounded-xl shadow-sm border will-change-[opacity,transform] max-h-50dvh',
69
- 'data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade',
70
- 'bg-white dark:bg-neutral-900',
71
- 'border-neutral-200 dark:border-neutral-800 border-solid border-2 focus:border-neutral-300 dark:focus:border-neutral-600',
72
- ]"
73
- >
74
- <ComboboxViewport class="p-[2px]">
75
- <ComboboxEmpty
76
- :class="[
77
- 'font-medium py-2 px-2',
78
- 'text-xs text-neutral-700 dark:text-neutral-200',
79
- 'transition-colors duration-200 ease-in-out',
80
- ]"
81
- />
66
+ <ComboboxPortal>
67
+ <ComboboxContent
68
+ position="popper"
69
+ side="bottom"
70
+ align="start"
71
+ :side-offset="4"
72
+ :avoid-collisions="true"
73
+ :class="[
74
+ // NOTICE: DrawerContent is z-[1000], here we choose `1010`
75
+ // Read more at: https://github.com/moeru-ai/airi/blob/0fddd043f2b213f441f3998c52dca1d24acb8405/packages/stage-ui/src/components/scenarios/dialogs/audio-input/hearing-config-dialog.vue#L62C8-L62C21
76
+ 'z-[1010]',
77
+ 'w-full min-w-[160px] overflow-hidden rounded-xl shadow-sm border will-change-[opacity,transform]',
78
+ 'data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade',
79
+ 'bg-white dark:bg-neutral-900',
80
+ 'border-neutral-200 dark:border-neutral-800 border-solid border-2 focus:border-neutral-300 dark:focus:border-neutral-600',
81
+ ]"
82
+ :style="{ width: 'var(--reka-combobox-trigger-width)' }"
83
+ >
84
+ <ComboboxViewport :class="['p-[2px]', 'max-h-50dvh', 'overflow-y-auto']">
85
+ <ComboboxEmpty
86
+ :class="[
87
+ 'font-medium py-2 px-2',
88
+ 'text-xs text-neutral-700 dark:text-neutral-200',
89
+ 'transition-colors duration-200 ease-in-out',
90
+ ]"
91
+ />
82
92
 
83
- <template
84
- v-for="(group, index) in options"
85
- :key="group.groupLabel"
86
- >
87
- <ComboboxGroup :class="['overflow-x-hidden']">
88
- <ComboboxSeparator
89
- v-if="index !== 0"
90
- :class="['m-[5px]', 'h-[1px]', 'bg-neutral-400']"
91
- />
93
+ <template
94
+ v-for="(group, index) in options"
95
+ :key="group.groupLabel"
96
+ >
97
+ <ComboboxGroup :class="['overflow-x-hidden']">
98
+ <ComboboxSeparator
99
+ v-if="index !== 0"
100
+ :class="['m-[5px]', 'h-[1px]', 'bg-neutral-400']"
101
+ />
92
102
 
93
- <ComboboxLabel
94
- :class="[
95
- 'px-[25px] text-xs leading-[25px]',
96
- 'text-neutral-500 dark:text-neutral-400',
97
- 'transition-colors duration-200 ease-in-out',
98
- ]"
99
- >
100
- {{ group.groupLabel }}
101
- </ComboboxLabel>
103
+ <ComboboxLabel
104
+ :class="[
105
+ 'px-[25px] text-xs leading-[25px]',
106
+ 'text-neutral-500 dark:text-neutral-400',
107
+ 'transition-colors duration-200 ease-in-out',
108
+ ]"
109
+ >
110
+ {{ group.groupLabel }}
111
+ </ComboboxLabel>
102
112
 
103
- <ComboboxItem
104
- v-for="option in group.children"
105
- :key="option.label"
106
- :text-value="option.label"
107
- :value="option.value"
108
- :class="[
109
- 'leading-none rounded-lg flex items-center h-8 pr-[0.5rem] pl-[1.5rem] relative select-none data-[disabled]:pointer-events-none data-[highlighted]:outline-none',
110
- 'data-[highlighted]:bg-neutral-100 dark:data-[highlighted]:bg-neutral-800',
111
- 'text-sm text-neutral-700 dark:text-neutral-200 data-[disabled]:text-neutral-400 dark:data-[disabled]:text-neutral-600 data-[highlighted]:text-grass1',
112
- 'transition-colors duration-200 ease-in-out',
113
- 'cursor-pointer',
114
- ]"
115
- >
116
- <ComboboxItemIndicator
117
- :class="['absolute', 'left-0', 'w-[25px]', 'inline-flex', 'items-center', 'justify-center', 'opacity-30']"
113
+ <ComboboxItem
114
+ v-for="option in group.children"
115
+ :key="option.label"
116
+ :text-value="option.label"
117
+ :value="option.value"
118
+ :class="[
119
+ 'leading-normal rounded-lg flex items-center h-8 pr-[0.5rem] pl-[1.5rem] relative select-none data-[disabled]:pointer-events-none data-[highlighted]:outline-none',
120
+ 'data-[highlighted]:bg-neutral-100 dark:data-[highlighted]:bg-neutral-800',
121
+ 'text-sm text-neutral-700 dark:text-neutral-200 data-[disabled]:text-neutral-400 dark:data-[disabled]:text-neutral-600 data-[highlighted]:text-grass1',
122
+ 'transition-colors duration-200 ease-in-out',
123
+ 'cursor-pointer',
124
+ ]"
118
125
  >
119
- <div i-solar:alt-arrow-right-outline />
120
- </ComboboxItemIndicator>
121
- <span :class="['line-clamp-1', 'overflow-hidden', 'text-ellipsis', 'whitespace-nowrap']">
122
- {{ option.label }}
123
- </span>
124
- </ComboboxItem>
125
- </ComboboxGroup>
126
- </template>
127
- </ComboboxViewport>
128
- </ComboboxContent>
126
+ <ComboboxItemIndicator
127
+ :class="['absolute', 'left-0', 'w-[25px]', 'inline-flex', 'items-center', 'justify-center', 'opacity-30']"
128
+ >
129
+ <div i-solar:alt-arrow-right-outline />
130
+ </ComboboxItemIndicator>
131
+ <span :class="['line-clamp-1', 'overflow-hidden', 'text-ellipsis', 'whitespace-nowrap']">
132
+ {{ option.label }}
133
+ </span>
134
+ </ComboboxItem>
135
+ </ComboboxGroup>
136
+ </template>
137
+ </ComboboxViewport>
138
+ </ComboboxContent>
139
+ </ComboboxPortal>
129
140
  </ComboboxRoot>
130
141
  </template>
@@ -1,4 +1,8 @@
1
- <script setup lang="ts">
1
+ <script
2
+ setup
3
+ lang="ts"
4
+ generic="InputType extends 'number' | string, T = InputType extends 'number' ? (number | undefined) : ((string | undefined))"
5
+ >
2
6
  import { Input } from '../input'
3
7
 
4
8
  const props = withDefaults(defineProps<{
@@ -6,14 +10,14 @@ const props = withDefaults(defineProps<{
6
10
  description?: string
7
11
  placeholder?: string
8
12
  required?: boolean
9
- type?: string
13
+ type?: InputType
10
14
  inputClass?: string
11
15
  singleLine?: boolean
12
16
  }>(), {
13
17
  singleLine: true,
14
18
  })
15
19
 
16
- const modelValue = defineModel<string>({ required: false })
20
+ const modelValue = defineModel<T>({ required: false })
17
21
  </script>
18
22
 
19
23
  <template>
@@ -33,15 +37,22 @@ const modelValue = defineModel<string>({ required: false })
33
37
  </div>
34
38
  </div>
35
39
  <Input
36
- v-if="singleLine"
40
+ v-if="singleLine && props.type === 'number'"
41
+ v-model.number="modelValue"
42
+ :type="props.type"
43
+ :placeholder="props.placeholder"
44
+ :class="props.inputClass"
45
+ />
46
+ <Input
47
+ v-else-if="singleLine"
37
48
  v-model="modelValue"
38
49
  :type="props.type"
39
50
  :placeholder="props.placeholder"
40
51
  :class="props.inputClass"
41
52
  />
42
53
  <textarea
43
- v-else
44
- v-model="modelValue"
54
+ v-else-if="props.type !== 'number'"
55
+ v-model="modelValue as string | undefined"
45
56
  :type="props.type"
46
57
  :placeholder="props.placeholder"
47
58
  :class="[
@@ -1,4 +1,8 @@
1
- <script setup lang="ts">
1
+ <script
2
+ setup
3
+ lang="ts"
4
+ generic="InputType extends 'number' | string, T = InputType extends 'number' ? (number | undefined) : ((string | undefined))"
5
+ >
2
6
  // Define button variants for better type safety and maintainability
3
7
  type InputVariant = 'primary' | 'secondary' | 'primary-dimmed'
4
8
 
@@ -8,7 +12,7 @@ type InputTheme = 'default'
8
12
  type InputSize = 'sm' | 'md' | 'lg'
9
13
 
10
14
  const props = withDefaults(defineProps<{
11
- type?: string
15
+ type?: InputType
12
16
  variant?: InputVariant // Button style variant
13
17
  size?: InputSize // Button size variant
14
18
  theme?: InputTheme // Button theme
@@ -18,7 +22,7 @@ const props = withDefaults(defineProps<{
18
22
  theme: 'default',
19
23
  })
20
24
 
21
- const modelValue = defineModel<string>({ required: false })
25
+ const modelValue = defineModel<T>({ required: false })
22
26
 
23
27
  const variantClasses: Record<InputVariant, Record<InputTheme, {
24
28
  default: string[]
@@ -59,13 +63,26 @@ const variantClasses: Record<InputVariant, Record<InputTheme, {
59
63
  </script>
60
64
 
61
65
  <template>
62
- <input
63
- v-model="modelValue"
64
- :type="props.type || 'text'"
65
- :class="[
66
- 'transition-all duration-200 ease-in-out',
67
- 'cursor-disabled:not-allowed',
68
- ...variantClasses[props.variant][props.theme].default,
69
- ]"
70
- >
66
+ <template v-if="props.type === 'number'">
67
+ <input
68
+ v-model.number="modelValue"
69
+ :type="props.type || 'text'"
70
+ :class="[
71
+ 'transition-all duration-200 ease-in-out',
72
+ 'cursor-disabled:not-allowed',
73
+ ...variantClasses[props.variant][props.theme].default,
74
+ ]"
75
+ >
76
+ </template>
77
+ <template v-else>
78
+ <input
79
+ v-model="modelValue"
80
+ :type="props.type || 'text'"
81
+ :class="[
82
+ 'transition-all duration-200 ease-in-out',
83
+ 'cursor-disabled:not-allowed',
84
+ ...variantClasses[props.variant][props.theme].default,
85
+ ]"
86
+ >
87
+ </template>
71
88
  </template>