@h-ai/ui 0.1.0-alpha.33 → 0.1.0-alpha.35
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/README.md +24 -5
- package/auto-import.js +2 -2
- package/dist/components/compounds/Combobox.svelte +12 -4
- package/dist/components/compounds/Combobox.svelte.d.ts +4 -1
- package/dist/components/compounds/DatePicker.svelte +19 -4
- package/dist/components/compounds/DatePicker.svelte.d.ts +4 -1
- package/dist/components/compounds/TagInput.svelte +36 -31
- package/dist/components/control-size.d.ts +18 -0
- package/dist/components/control-size.js +18 -0
- package/dist/components/primitives/Input.svelte +4 -25
- package/dist/components/primitives/Select.svelte +4 -10
- package/dist/components/scenes/ai/AiDocumentEditor.svelte +203 -22
- package/dist/components/scenes/ai/document-download.js +19 -2
- package/dist/components/scenes/ai/document-parse.d.ts +25 -2
- package/dist/components/scenes/ai/document-parse.js +137 -11
- package/dist/components/scenes/ai/index.d.ts +1 -1
- package/dist/components/scenes/ai/mermaid-host-sync.d.ts +34 -0
- package/dist/components/scenes/ai/mermaid-host-sync.js +35 -0
- package/dist/components/scenes/ai/mermaid-render.d.ts +5 -0
- package/dist/components/scenes/ai/mermaid-render.js +7 -0
- package/dist/components/scenes/charts/Chart.svelte +152 -0
- package/dist/components/scenes/charts/Chart.svelte.d.ts +5 -0
- package/dist/components/scenes/charts/chart-theme.d.ts +23 -0
- package/dist/components/scenes/charts/chart-theme.js +44 -0
- package/dist/components/scenes/charts/chart-types.d.ts +77 -0
- package/dist/components/scenes/charts/chart-types.js +7 -0
- package/dist/components/scenes/charts/index.d.ts +8 -0
- package/dist/components/scenes/charts/index.js +7 -0
- package/dist/components/scenes/charts/renderers/AreaChart.svelte +18 -0
- package/dist/components/scenes/charts/renderers/AreaChart.svelte.d.ts +5 -0
- package/dist/components/scenes/charts/renderers/BarChart.svelte +18 -0
- package/dist/components/scenes/charts/renderers/BarChart.svelte.d.ts +5 -0
- package/dist/components/scenes/charts/renderers/LineChart.svelte +571 -0
- package/dist/components/scenes/charts/renderers/LineChart.svelte.d.ts +19 -0
- package/dist/components/scenes/charts/renderers/PieChart.svelte +18 -0
- package/dist/components/scenes/charts/renderers/PieChart.svelte.d.ts +5 -0
- package/dist/components/scenes/charts/renderers/ScatterChart.svelte +18 -0
- package/dist/components/scenes/charts/renderers/ScatterChart.svelte.d.ts +5 -0
- package/dist/components/scenes/iam/PasswordInput.svelte +4 -15
- package/dist/components/scenes/index.d.ts +1 -0
- package/dist/components/scenes/index.js +2 -0
- package/dist/messages/en-US.json +2 -0
- package/dist/messages/zh-CN.json +2 -0
- package/dist/types.d.ts +1 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -187,11 +187,11 @@ components/
|
|
|
187
187
|
|
|
188
188
|
#### Bits UI headless 交互
|
|
189
189
|
|
|
190
|
-
| 组件 | 描述 | 主要属性
|
|
191
|
-
| ------------ | --------------------------- |
|
|
192
|
-
| `Combobox` | 可搜索下拉选择(单选/多选) | `options`, `value`, `multiple`, `placeholder` |
|
|
193
|
-
| `Calendar` | 独立日历 | `value: DateValue`, `minValue`, `maxValue`
|
|
194
|
-
| `DatePicker` | 日期输入+弹出 | `value: DateValue`, `minValue`, `maxValue`, `error` |
|
|
190
|
+
| 组件 | 描述 | 主要属性 |
|
|
191
|
+
| ------------ | --------------------------- | ----------------------------------------------------------- |
|
|
192
|
+
| `Combobox` | 可搜索下拉选择(单选/多选) | `options`, `value`, `multiple`, `placeholder`, `size` |
|
|
193
|
+
| `Calendar` | 独立日历 | `value: DateValue`, `minValue`, `maxValue` |
|
|
194
|
+
| `DatePicker` | 日期输入+弹出 | `value: DateValue`, `minValue`, `maxValue`, `error`, `size` |
|
|
195
195
|
|
|
196
196
|
> 日期值使用 `@internationalized/date` 的 `DateValue` / `CalendarDate` 类型。
|
|
197
197
|
|
|
@@ -309,6 +309,25 @@ components/
|
|
|
309
309
|
/>
|
|
310
310
|
```
|
|
311
311
|
|
|
312
|
+
#### Charts 图表
|
|
313
|
+
|
|
314
|
+
`Chart type='line'` 默认透传 LayerChart 原生折线图;需要监控看板常见的“分段线 + 圆点 + 最近点 hover + 竖向参考线”时,使用 `lineVariant='segmented-point'`:
|
|
315
|
+
|
|
316
|
+
```svelte
|
|
317
|
+
<Chart
|
|
318
|
+
type='line'
|
|
319
|
+
data={trendData}
|
|
320
|
+
x='label'
|
|
321
|
+
y={['rateLimit', 'circuitBreak']}
|
|
322
|
+
series={trendSeries}
|
|
323
|
+
lineVariant='segmented-point'
|
|
324
|
+
tooltipMode='nearest'
|
|
325
|
+
showCrosshair
|
|
326
|
+
legend
|
|
327
|
+
grid
|
|
328
|
+
/>
|
|
329
|
+
```
|
|
330
|
+
|
|
312
331
|
#### CRUD 场景(5 个)
|
|
313
332
|
|
|
314
333
|
| 组件 | 描述 | 主要属性 / 能力 |
|
package/auto-import.js
CHANGED
|
@@ -232,9 +232,9 @@ function autoImportHaiUi() {
|
|
|
232
232
|
return { code: content }
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
-
//
|
|
235
|
+
// 自动导入只服务应用源码;第三方依赖和 @h-ai/ui 自身必须保持原样,避免改写依赖内部的同名组件。
|
|
236
236
|
const normalizedPath = filename.replace(WINDOWS_PATH_SEPARATOR_REGEX, '/')
|
|
237
|
-
if (normalizedPath.includes('/packages/ui/') || normalizedPath.includes('/@h-ai/ui/')) {
|
|
237
|
+
if (normalizedPath.includes('/node_modules/') || normalizedPath.includes('/packages/ui/') || normalizedPath.includes('/@h-ai/ui/')) {
|
|
238
238
|
return { code: content }
|
|
239
239
|
}
|
|
240
240
|
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
@prop {string | string[]} value - 选中值(双向绑定,单选为 string,多选为 string[])
|
|
9
9
|
@prop {boolean} multiple - 是否多选模式
|
|
10
10
|
@prop {string} placeholder - 输入框占位符
|
|
11
|
+
@prop {Size} size - 输入框尺寸
|
|
11
12
|
@prop {boolean} disabled - 是否禁用
|
|
12
13
|
@prop {string} error - 错误消息
|
|
13
14
|
@prop {string} label - 表单标签
|
|
@@ -33,10 +34,11 @@
|
|
|
33
34
|
/>
|
|
34
35
|
-->
|
|
35
36
|
<script lang='ts'>
|
|
36
|
-
import type { DataAttributes } from '../../types.js'
|
|
37
|
+
import type { DataAttributes, Size } from '../../types.js'
|
|
37
38
|
import { Combobox } from 'bits-ui'
|
|
38
39
|
import { uiM } from '../../messages.js'
|
|
39
40
|
import { cn, getDataAttributes } from '../../utils.js'
|
|
41
|
+
import { getFormControlSizeClasses } from '../control-size.js'
|
|
40
42
|
import BareButton from '../primitives/BareButton.svelte'
|
|
41
43
|
|
|
42
44
|
/** 选项定义 */
|
|
@@ -60,6 +62,8 @@
|
|
|
60
62
|
multiple?: boolean
|
|
61
63
|
/** 输入框占位符 */
|
|
62
64
|
placeholder?: string
|
|
65
|
+
/** 尺寸 */
|
|
66
|
+
size?: Size
|
|
63
67
|
/** 是否禁用 */
|
|
64
68
|
disabled?: boolean
|
|
65
69
|
/** 错误消息 */
|
|
@@ -77,6 +81,7 @@
|
|
|
77
81
|
value = $bindable(),
|
|
78
82
|
multiple = false,
|
|
79
83
|
placeholder = '',
|
|
84
|
+
size = 'md',
|
|
80
85
|
disabled = false,
|
|
81
86
|
error,
|
|
82
87
|
label: fieldLabel,
|
|
@@ -86,6 +91,7 @@
|
|
|
86
91
|
}: Props & DataAttributes = $props()
|
|
87
92
|
|
|
88
93
|
const dataAttributes = $derived(getDataAttributes(restProps))
|
|
94
|
+
const sizeClasses = $derived(getFormControlSizeClasses(size))
|
|
89
95
|
// 为未提供 value 时设置初始默认值(仅在初始化时执行一次)
|
|
90
96
|
// 统一以空字符串初始化,避免在初始化阶段捕获 multiple 的初始值。
|
|
91
97
|
// 多选模式会通过 multiVal 派生为 [] 传给 Combobox.Root。
|
|
@@ -214,7 +220,8 @@
|
|
|
214
220
|
<div class='relative'>
|
|
215
221
|
<div
|
|
216
222
|
class={cn(
|
|
217
|
-
'
|
|
223
|
+
'rounded-lg border bg-base-100 flex flex-wrap gap-1.5 items-center py-1 pl-2.5 pr-9 transition-[border-color,box-shadow] duration-150',
|
|
224
|
+
sizeClasses.minHeight,
|
|
218
225
|
disabled ? 'opacity-50 cursor-not-allowed bg-base-200' : 'cursor-text',
|
|
219
226
|
controlStateClass,
|
|
220
227
|
)}
|
|
@@ -237,7 +244,7 @@
|
|
|
237
244
|
|
|
238
245
|
<Combobox.Input
|
|
239
246
|
bind:ref={inputRef}
|
|
240
|
-
class='flex-1 min-w-20 bg-transparent py-0.5
|
|
247
|
+
class={cn('flex-1 min-w-20 bg-transparent py-0.5 outline-none placeholder:text-base-content/40', sizeClasses.spacing)}
|
|
241
248
|
placeholder={selectedOptions.length === 0 ? placeholder : ''}
|
|
242
249
|
{disabled}
|
|
243
250
|
oninput={handleInput}
|
|
@@ -307,7 +314,8 @@
|
|
|
307
314
|
<Combobox.Input
|
|
308
315
|
bind:ref={inputRef}
|
|
309
316
|
class={cn(
|
|
310
|
-
'
|
|
317
|
+
'w-full rounded-lg border bg-base-100 pr-9 outline-none transition-[border-color,box-shadow] duration-150 placeholder:text-base-content/40',
|
|
318
|
+
sizeClasses.control,
|
|
311
319
|
controlStateClass,
|
|
312
320
|
disabled && 'opacity-50 cursor-not-allowed',
|
|
313
321
|
)}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DataAttributes } from '../../types.js';
|
|
1
|
+
import type { DataAttributes, Size } from '../../types.js';
|
|
2
2
|
import { Combobox } from 'bits-ui';
|
|
3
3
|
/** 选项定义 */
|
|
4
4
|
interface Option {
|
|
@@ -20,6 +20,8 @@ interface Props {
|
|
|
20
20
|
multiple?: boolean;
|
|
21
21
|
/** 输入框占位符 */
|
|
22
22
|
placeholder?: string;
|
|
23
|
+
/** 尺寸 */
|
|
24
|
+
size?: Size;
|
|
23
25
|
/** 是否禁用 */
|
|
24
26
|
disabled?: boolean;
|
|
25
27
|
/** 错误消息 */
|
|
@@ -42,6 +44,7 @@ type $$ComponentProps = Props & DataAttributes;
|
|
|
42
44
|
* @prop {string | string[]} value - 选中值(双向绑定,单选为 string,多选为 string[])
|
|
43
45
|
* @prop {boolean} multiple - 是否多选模式
|
|
44
46
|
* @prop {string} placeholder - 输入框占位符
|
|
47
|
+
* @prop {Size} size - 输入框尺寸
|
|
45
48
|
* @prop {boolean} disabled - 是否禁用
|
|
46
49
|
* @prop {string} error - 错误消息
|
|
47
50
|
* @prop {string} label - 表单标签
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
@prop {DateValue} minValue - 最小可选日期
|
|
8
8
|
@prop {DateValue} maxValue - 最大可选日期
|
|
9
9
|
@prop {string} placeholder - 输入框占位文本
|
|
10
|
+
@prop {Size} size - 输入框尺寸
|
|
10
11
|
@prop {boolean} disabled - 是否禁用
|
|
11
12
|
@prop {string} error - 错误消息
|
|
12
13
|
@prop {function} onchange - 日期变更回调
|
|
@@ -22,9 +23,10 @@
|
|
|
22
23
|
-->
|
|
23
24
|
<script lang='ts'>
|
|
24
25
|
import type { DateValue } from '@internationalized/date'
|
|
25
|
-
import type { DataAttributes } from '../../types.js'
|
|
26
|
+
import type { DataAttributes, Size } from '../../types.js'
|
|
26
27
|
import { DatePicker as BitsDatePicker } from 'bits-ui'
|
|
27
|
-
import { getDataAttributes } from '../../utils.js'
|
|
28
|
+
import { cn, getDataAttributes } from '../../utils.js'
|
|
29
|
+
import { getFormControlSizeClasses } from '../control-size.js'
|
|
28
30
|
|
|
29
31
|
interface Props {
|
|
30
32
|
/** 选中日期(双向绑定) */
|
|
@@ -39,6 +41,8 @@
|
|
|
39
41
|
isDateUnavailable?: (date: DateValue) => boolean
|
|
40
42
|
/** 是否禁用 */
|
|
41
43
|
disabled?: boolean
|
|
44
|
+
/** 尺寸 */
|
|
45
|
+
size?: Size
|
|
42
46
|
/** 错误消息 */
|
|
43
47
|
error?: string
|
|
44
48
|
/** 自定义类名 */
|
|
@@ -54,6 +58,7 @@
|
|
|
54
58
|
weekStartsOn = 1,
|
|
55
59
|
isDateUnavailable,
|
|
56
60
|
disabled = false,
|
|
61
|
+
size = 'md',
|
|
57
62
|
error,
|
|
58
63
|
class: className = '',
|
|
59
64
|
onchange,
|
|
@@ -61,6 +66,7 @@
|
|
|
61
66
|
}: Props & DataAttributes = $props()
|
|
62
67
|
|
|
63
68
|
const dataAttributes = $derived(getDataAttributes(restProps))
|
|
69
|
+
const sizeClasses = $derived(getFormControlSizeClasses(size))
|
|
64
70
|
</script>
|
|
65
71
|
|
|
66
72
|
<div {...dataAttributes} class='fieldset w-full {className}'>
|
|
@@ -73,12 +79,21 @@
|
|
|
73
79
|
{disabled}
|
|
74
80
|
onValueChange={v => onchange?.(v)}
|
|
75
81
|
>
|
|
76
|
-
<BitsDatePicker.Input
|
|
82
|
+
<BitsDatePicker.Input
|
|
83
|
+
class={cn(
|
|
84
|
+
'flex w-full items-center gap-0.5 rounded-lg border bg-base-100 pr-2 transition-[border-color,box-shadow] duration-150',
|
|
85
|
+
sizeClasses.control,
|
|
86
|
+
error
|
|
87
|
+
? 'border-error/60 focus-within:ring-2 focus-within:ring-error/15'
|
|
88
|
+
: 'border-base-content/15 hover:border-base-content/25 focus-within:border-primary/50 focus-within:ring-2 focus-within:ring-primary/10',
|
|
89
|
+
disabled && 'cursor-not-allowed opacity-50',
|
|
90
|
+
)}
|
|
91
|
+
>
|
|
77
92
|
{#snippet children({ segments })}
|
|
78
93
|
{#each segments as { part, value: segValue }, index (`${part}-${index}`)}
|
|
79
94
|
<BitsDatePicker.Segment
|
|
80
95
|
{part}
|
|
81
|
-
class='rounded px-0.5 py-0.5
|
|
96
|
+
class='rounded px-0.5 py-0.5 tabular-nums focus:bg-primary focus:text-primary-content focus:outline-none data-[type=literal]:px-0 data-[type=literal]:text-base-content/50'
|
|
82
97
|
>
|
|
83
98
|
{segValue}
|
|
84
99
|
</BitsDatePicker.Segment>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DateValue } from '@internationalized/date';
|
|
2
|
-
import type { DataAttributes } from '../../types.js';
|
|
2
|
+
import type { DataAttributes, Size } from '../../types.js';
|
|
3
3
|
interface Props {
|
|
4
4
|
/** 选中日期(双向绑定) */
|
|
5
5
|
value?: DateValue;
|
|
@@ -13,6 +13,8 @@ interface Props {
|
|
|
13
13
|
isDateUnavailable?: (date: DateValue) => boolean;
|
|
14
14
|
/** 是否禁用 */
|
|
15
15
|
disabled?: boolean;
|
|
16
|
+
/** 尺寸 */
|
|
17
|
+
size?: Size;
|
|
16
18
|
/** 错误消息 */
|
|
17
19
|
error?: string;
|
|
18
20
|
/** 自定义类名 */
|
|
@@ -30,6 +32,7 @@ type $$ComponentProps = Props & DataAttributes;
|
|
|
30
32
|
* @prop {DateValue} minValue - 最小可选日期
|
|
31
33
|
* @prop {DateValue} maxValue - 最大可选日期
|
|
32
34
|
* @prop {string} placeholder - 输入框占位文本
|
|
35
|
+
* @prop {Size} size - 输入框尺寸
|
|
33
36
|
* @prop {boolean} disabled - 是否禁用
|
|
34
37
|
* @prop {string} error - 错误消息
|
|
35
38
|
* @prop {function} onchange - 日期变更回调
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
<script lang='ts'>
|
|
11
11
|
import type { DataAttributes, TagInputProps } from '../../types.js'
|
|
12
12
|
import { uiM } from '../../messages.js'
|
|
13
|
-
import { cn, getDataAttributes
|
|
13
|
+
import { cn, getDataAttributes } from '../../utils.js'
|
|
14
|
+
import { getFormControlSizeClasses } from '../control-size.js'
|
|
14
15
|
import BareInput from '../primitives/BareInput.svelte'
|
|
15
16
|
import Tag from '../primitives/Tag.svelte'
|
|
16
17
|
|
|
@@ -27,6 +28,7 @@
|
|
|
27
28
|
}: TagInputProps & DataAttributes = $props()
|
|
28
29
|
|
|
29
30
|
const dataAttributes = $derived(getDataAttributes(restProps))
|
|
31
|
+
const sizeClasses = $derived(getFormControlSizeClasses(size))
|
|
30
32
|
let inputValue = $state('')
|
|
31
33
|
let inputElement = $state<HTMLInputElement | undefined>(undefined)
|
|
32
34
|
|
|
@@ -34,9 +36,10 @@
|
|
|
34
36
|
|
|
35
37
|
const containerClass = $derived(
|
|
36
38
|
cn(
|
|
37
|
-
'
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
'flex h-auto w-full flex-wrap items-center gap-1 rounded-lg border border-base-content/15 bg-base-100 py-1 transition-[border-color,box-shadow] duration-150 focus-within:border-primary/50 focus-within:ring-2 focus-within:ring-primary/10',
|
|
40
|
+
sizeClasses.minHeight,
|
|
41
|
+
sizeClasses.spacing,
|
|
42
|
+
disabled && 'cursor-not-allowed opacity-50',
|
|
40
43
|
className,
|
|
41
44
|
),
|
|
42
45
|
)
|
|
@@ -79,32 +82,34 @@
|
|
|
79
82
|
}
|
|
80
83
|
</script>
|
|
81
84
|
|
|
82
|
-
<div {...dataAttributes}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
85
|
+
<div {...dataAttributes} class='fieldset w-full'>
|
|
86
|
+
<div
|
|
87
|
+
class={containerClass}
|
|
88
|
+
onclick={() => inputElement?.focus()}
|
|
89
|
+
onkeydown={e => e.key === 'Enter' && inputElement?.focus()}
|
|
90
|
+
role='textbox'
|
|
91
|
+
tabindex='-1'
|
|
92
|
+
>
|
|
93
|
+
{#each tags as tag, index (index)}
|
|
94
|
+
<Tag
|
|
95
|
+
text={tag}
|
|
96
|
+
size='sm'
|
|
97
|
+
closable={!disabled}
|
|
98
|
+
onclose={() => removeTag(index)}
|
|
99
|
+
/>
|
|
100
|
+
{/each}
|
|
97
101
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
102
|
+
{#if canAddMore && !disabled}
|
|
103
|
+
<BareInput
|
|
104
|
+
type='text'
|
|
105
|
+
class='flex-1 min-w-[100px] bg-transparent border-none outline-none'
|
|
106
|
+
bind:value={inputValue}
|
|
107
|
+
bind:inputRef={inputElement}
|
|
108
|
+
placeholder={displayPlaceholder}
|
|
109
|
+
{disabled}
|
|
110
|
+
onkeydown={handleKeydown}
|
|
111
|
+
onblur={handleBlur}
|
|
112
|
+
/>
|
|
113
|
+
{/if}
|
|
114
|
+
</div>
|
|
110
115
|
</div>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Size } from '../types.js';
|
|
2
|
+
interface FormControlSizeClasses {
|
|
3
|
+
/** 固定高度,适用于单行控件 */
|
|
4
|
+
height: string;
|
|
5
|
+
/** 最小高度,适用于内容可换行的控件 */
|
|
6
|
+
minHeight: string;
|
|
7
|
+
/** 水平内边距与字号 */
|
|
8
|
+
spacing: string;
|
|
9
|
+
/** 固定高度、水平内边距与字号的完整组合 */
|
|
10
|
+
control: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 获取输入类控件的统一尺寸类名。
|
|
14
|
+
*
|
|
15
|
+
* 仅供组件内部复用,确保 Input、Select 与复合输入控件使用同一盒模型。
|
|
16
|
+
*/
|
|
17
|
+
export declare function getFormControlSizeClasses(size: Size): FormControlSizeClasses;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const FORM_CONTROL_SIZE_CLASSES = {
|
|
2
|
+
'xs': { height: 'h-8', minHeight: 'min-h-8', spacing: 'px-2.5 text-xs', control: 'h-8 px-2.5 text-xs' },
|
|
3
|
+
'sm': { height: 'h-9', minHeight: 'min-h-9', spacing: 'px-3 text-sm', control: 'h-9 px-3 text-sm' },
|
|
4
|
+
'md': { height: 'h-10', minHeight: 'min-h-10', spacing: 'px-3 text-sm', control: 'h-10 px-3 text-sm' },
|
|
5
|
+
'lg': { height: 'h-12', minHeight: 'min-h-12', spacing: 'px-4 text-base', control: 'h-12 px-4 text-base' },
|
|
6
|
+
'xl': { height: 'h-14', minHeight: 'min-h-14', spacing: 'px-4 text-lg', control: 'h-14 px-4 text-lg' },
|
|
7
|
+
'2xl': { height: 'h-14', minHeight: 'min-h-14', spacing: 'px-4 text-lg', control: 'h-14 px-4 text-lg' },
|
|
8
|
+
'3xl': { height: 'h-14', minHeight: 'min-h-14', spacing: 'px-4 text-lg', control: 'h-14 px-4 text-lg' },
|
|
9
|
+
'4xl': { height: 'h-14', minHeight: 'min-h-14', spacing: 'px-4 text-lg', control: 'h-14 px-4 text-lg' },
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* 获取输入类控件的统一尺寸类名。
|
|
13
|
+
*
|
|
14
|
+
* 仅供组件内部复用,确保 Input、Select 与复合输入控件使用同一盒模型。
|
|
15
|
+
*/
|
|
16
|
+
export function getFormControlSizeClasses(size) {
|
|
17
|
+
return FORM_CONTROL_SIZE_CLASSES[size];
|
|
18
|
+
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
<script lang='ts'>
|
|
6
6
|
import type { DataAttributes, InputProps } from '../../types.js'
|
|
7
7
|
import { cn, getDataAttributes } from '../../utils.js'
|
|
8
|
+
import { getFormControlSizeClasses } from '../control-size.js'
|
|
8
9
|
|
|
9
10
|
let {
|
|
10
11
|
value = $bindable(''),
|
|
@@ -39,29 +40,7 @@
|
|
|
39
40
|
}: InputProps & DataAttributes = $props()
|
|
40
41
|
|
|
41
42
|
const dataAttributes = $derived(getDataAttributes(restProps))
|
|
42
|
-
const
|
|
43
|
-
size === 'xs'
|
|
44
|
-
? 'h-8'
|
|
45
|
-
: size === 'sm'
|
|
46
|
-
? 'h-9'
|
|
47
|
-
: size === 'lg'
|
|
48
|
-
? 'h-12'
|
|
49
|
-
: size === 'xl'
|
|
50
|
-
? 'h-14'
|
|
51
|
-
: 'h-10',
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
const inputSpacingClass = $derived(
|
|
55
|
-
size === 'xs'
|
|
56
|
-
? 'px-2.5 text-xs'
|
|
57
|
-
: size === 'sm'
|
|
58
|
-
? 'px-3 text-sm'
|
|
59
|
-
: size === 'lg'
|
|
60
|
-
? 'px-4 text-base'
|
|
61
|
-
: size === 'xl'
|
|
62
|
-
? 'px-4 text-lg'
|
|
63
|
-
: 'px-3 text-sm',
|
|
64
|
-
)
|
|
43
|
+
const sizeClasses = $derived(getFormControlSizeClasses(size))
|
|
65
44
|
|
|
66
45
|
const inputTypeClass = $derived(
|
|
67
46
|
type === 'number'
|
|
@@ -72,7 +51,7 @@
|
|
|
72
51
|
const containerClass = $derived(
|
|
73
52
|
cn(
|
|
74
53
|
'flex items-center w-full rounded-lg border bg-base-100',
|
|
75
|
-
|
|
54
|
+
sizeClasses.height,
|
|
76
55
|
error
|
|
77
56
|
? 'border-error/60 focus-within:ring-2 focus-within:ring-error/15'
|
|
78
57
|
: 'border-base-content/15 focus-within:border-primary/50 focus-within:ring-2 focus-within:ring-primary/10',
|
|
@@ -136,7 +115,7 @@
|
|
|
136
115
|
autocomplete={autocomplete as HTMLInputElement['autocomplete']}
|
|
137
116
|
class={cn(
|
|
138
117
|
'flex-1 h-full bg-transparent border-none outline-none placeholder:text-base-content/35',
|
|
139
|
-
|
|
118
|
+
sizeClasses.spacing,
|
|
140
119
|
inputTypeClass,
|
|
141
120
|
)}
|
|
142
121
|
bind:value
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
<script lang='ts' generics="T = string">
|
|
12
12
|
import type { DataAttributes, SelectProps } from '../../types.js'
|
|
13
13
|
import { cn, getDataAttributes, portal } from '../../utils.js'
|
|
14
|
+
import { getFormControlSizeClasses } from '../control-size.js'
|
|
14
15
|
|
|
15
16
|
let {
|
|
16
17
|
value = $bindable<T>(),
|
|
@@ -39,14 +40,7 @@
|
|
|
39
40
|
// 下拉层定位样式(portal 到 body,用 fixed 逃逸 overflow/stacking)
|
|
40
41
|
let dropdownStyle = $state('')
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
const sizeClasses: Record<string, string> = {
|
|
44
|
-
xs: 'h-8 text-xs px-2.5',
|
|
45
|
-
sm: 'h-9 text-sm px-3',
|
|
46
|
-
md: 'h-10 text-sm px-3',
|
|
47
|
-
lg: 'h-12 text-base px-4',
|
|
48
|
-
xl: 'h-14 text-lg px-4',
|
|
49
|
-
}
|
|
43
|
+
const sizeClasses = $derived(getFormControlSizeClasses(size))
|
|
50
44
|
|
|
51
45
|
// 选项文字尺寸
|
|
52
46
|
const optionTextClass = $derived(
|
|
@@ -81,7 +75,7 @@
|
|
|
81
75
|
const wrapperClass = $derived(
|
|
82
76
|
cn(
|
|
83
77
|
'relative flex w-full min-w-0 items-center rounded-lg border bg-base-100 cursor-pointer',
|
|
84
|
-
sizeClasses
|
|
78
|
+
sizeClasses.control,
|
|
85
79
|
error
|
|
86
80
|
? 'border-error/60 focus-within:ring-2 focus-within:ring-error/15'
|
|
87
81
|
: isDropdownOpen
|
|
@@ -270,7 +264,7 @@
|
|
|
270
264
|
{/if}
|
|
271
265
|
|
|
272
266
|
<!-- 右侧图标区域 -->
|
|
273
|
-
<div class='flex items-center
|
|
267
|
+
<div class='flex items-center shrink-0'>
|
|
274
268
|
{#if showClear}
|
|
275
269
|
<button
|
|
276
270
|
type='button'
|