tembro 1.0.1 → 1.0.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.
Files changed (48) hide show
  1. package/dist/components/calendar/calendar.cjs +1 -1
  2. package/dist/components/calendar/calendar.js +3 -3
  3. package/dist/components/calendar/date-picker.cjs +1 -1
  4. package/dist/components/calendar/date-picker.js +2 -2
  5. package/dist/components/calendar/date-range-picker.cjs +1 -1
  6. package/dist/components/calendar/date-range-picker.js +2 -4
  7. package/dist/components/data-table/data-table-toolbar.cjs +1 -1
  8. package/dist/components/data-table/data-table-toolbar.js +2 -2
  9. package/dist/components/data-table/data-table.cjs +1 -1
  10. package/dist/components/data-table/data-table.js +3 -3
  11. package/dist/components/display/carousel.cjs +1 -1
  12. package/dist/components/display/carousel.d.ts +3 -1
  13. package/dist/components/display/carousel.js +38 -27
  14. package/dist/components/inputs/async-select.cjs +1 -1
  15. package/dist/components/inputs/async-select.js +21 -21
  16. package/dist/components/inputs/combobox.cjs +1 -1
  17. package/dist/components/inputs/combobox.d.ts +5 -1
  18. package/dist/components/inputs/combobox.js +69 -59
  19. package/dist/components/inputs/simple-select.cjs +1 -1
  20. package/dist/components/inputs/simple-select.d.ts +1 -1
  21. package/dist/components/inputs/simple-select.js +5 -5
  22. package/dist/components/ui/button.cjs +1 -0
  23. package/dist/components/ui/button.d.ts +1 -0
  24. package/dist/components/ui/button.js +2 -0
  25. package/dist/components/ui/input.cjs +1 -0
  26. package/dist/components/ui/input.d.ts +1 -0
  27. package/dist/components/ui/input.js +3 -0
  28. package/dist/components/ui/select/index.cjs +1 -1
  29. package/dist/components/ui/select/index.d.ts +1 -1
  30. package/dist/components/ui/select/index.js +3 -3
  31. package/dist/showcase/tembro-registry.json.cjs +1 -1
  32. package/dist/showcase/tembro-registry.json.js +1 -1
  33. package/package.json +2 -1
  34. package/packages/cli/dist/index.cjs +2 -2
  35. package/packages/cli/vendor/src/components/calendar/calendar.tsx +3 -3
  36. package/packages/cli/vendor/src/components/calendar/date-picker.tsx +2 -2
  37. package/packages/cli/vendor/src/components/calendar/date-range-picker.tsx +4 -5
  38. package/packages/cli/vendor/src/components/data-table/data-table-toolbar.tsx +2 -2
  39. package/packages/cli/vendor/src/components/data-table/data-table.tsx +3 -3
  40. package/packages/cli/vendor/src/components/display/carousel.tsx +30 -12
  41. package/packages/cli/vendor/src/components/inputs/async-select.tsx +22 -22
  42. package/packages/cli/vendor/src/components/inputs/combobox.tsx +71 -41
  43. package/packages/cli/vendor/src/components/inputs/simple-select.tsx +6 -6
  44. package/packages/cli/vendor/src/components/ui/button.tsx +2 -0
  45. package/packages/cli/vendor/src/components/ui/input.tsx +2 -0
  46. package/packages/cli/vendor/src/components/ui/select/index.tsx +4 -4
  47. package/packages/cli/vendor/src/showcase/tembro-registry.json +1 -1
  48. package/registry.json +1 -1
@@ -314,7 +314,7 @@ function AsyncStateMessage({
314
314
  <div
315
315
  data-slot="async-select-state"
316
316
  className={cn(
317
- "rounded-[min(var(--radius-xl),16px)] border px-3 py-3 text-sm text-muted-foreground",
317
+ "rounded-[var(--radius-md)] border border-[color:var(--aui-card-border,var(--border))] bg-[color:color-mix(in_oklch,var(--muted),transparent_55%)] px-3 py-3 text-sm leading-5 text-muted-foreground",
318
318
  className
319
319
  )}
320
320
  >
@@ -356,18 +356,18 @@ function AsyncOptionButton<
356
356
  data-selected={selected || undefined}
357
357
  data-disabled={option.disabled || undefined}
358
358
  className={cn(
359
- "flex w-full items-start gap-2 rounded-[min(var(--radius-xl),16px)] border border-transparent px-3 py-2.5 text-left text-sm outline-none transition-[background-color,border-color,color,box-shadow] disabled:pointer-events-none disabled:opacity-50",
359
+ "flex w-full items-start gap-2.5 rounded-[var(--radius-md)] border border-transparent px-3 py-2.5 text-left text-sm outline-none transition-[background-color,border-color,color,box-shadow] hover:border-[color:color-mix(in_oklch,var(--primary),transparent_76%)] hover:bg-[color:color-mix(in_oklch,var(--primary),transparent_93%)] focus-visible:border-[color:var(--aui-focus-ring,var(--ring))] focus-visible:shadow-[0_0_0_3px_var(--aui-focus-ring-soft,transparent)] data-[selected=true]:border-[color:color-mix(in_oklch,var(--primary),transparent_68%)] data-[selected=true]:bg-[color:color-mix(in_oklch,var(--primary),transparent_89%)] data-[selected=true]:text-foreground disabled:pointer-events-none disabled:opacity-50",
360
360
  optionClassName
361
361
  )}
362
362
  onClick={() => onSelect(option)}
363
363
  >
364
- <span className="flex size-4 shrink-0 items-center justify-center">
365
- {selected && <CheckIcon className="size-4" />}
364
+ <span className={cn("mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full border border-border/70", selected && "border-primary bg-primary text-primary-foreground")}>
365
+ {selected && <CheckIcon className="size-3" />}
366
366
  </span>
367
367
  <span className="min-w-0 flex-1">
368
368
  {renderOption?.(option, { selected }) ?? (
369
369
  <span className="flex min-w-0 flex-col">
370
- <span className="truncate">{option.label}</span>
370
+ <span className="truncate font-medium">{option.label}</span>
371
371
  {option.description && (
372
372
  <span className="truncate text-xs text-muted-foreground">{option.description}</span>
373
373
  )}
@@ -397,7 +397,7 @@ function AsyncCreateButton({
397
397
  type="button"
398
398
  disabled={isCreating}
399
399
  data-slot="async-select-create"
400
- className="flex w-full items-center gap-2 rounded-[min(var(--radius-xl),16px)] border border-dashed px-3 py-2.5 text-left text-sm outline-none transition-[background-color,border-color,color,box-shadow] disabled:pointer-events-none disabled:opacity-50"
400
+ className="flex w-full items-center gap-2 rounded-[var(--radius-md)] border border-dashed border-[color:color-mix(in_oklch,var(--primary),transparent_55%)] bg-[color:color-mix(in_oklch,var(--primary),transparent_94%)] px-3 py-2.5 text-left text-sm font-medium text-foreground outline-none transition-[background-color,border-color,color,box-shadow] hover:bg-[color:color-mix(in_oklch,var(--primary),transparent_90%)] disabled:pointer-events-none disabled:opacity-50"
401
401
  onClick={onCreate}
402
402
  >
403
403
  <span className="flex size-4 shrink-0 items-center justify-center">
@@ -625,17 +625,17 @@ function AsyncSelect<
625
625
  aria-invalid={invalid || undefined}
626
626
  data-slot="async-select-trigger"
627
627
  className={cn(
628
- "min-h-11 w-full justify-between",
628
+ "min-h-11 w-full justify-between rounded-[var(--aui-control-radius,var(--radius-md))] px-3.5 text-left",
629
629
  triggerClassName
630
630
  )}
631
631
  onKeyDown={handleTriggerKeyDown}
632
632
  />
633
633
  }
634
634
  >
635
- <span className="min-w-0 flex-1 text-left">
635
+ <span className="min-w-0 flex-1 text-left">
636
636
  {currentOption ? (
637
- <span className="flex min-w-0 flex-col">
638
- <span className="truncate">
637
+ <span className="flex min-w-0 flex-col gap-0.5">
638
+ <span className="truncate font-semibold">
639
639
  {renderValue?.(currentOption) ?? currentOption.label}
640
640
  </span>
641
641
  {currentOption.disabled && currentOption.disabledReason && (
@@ -643,7 +643,7 @@ function AsyncSelect<
643
643
  )}
644
644
  </span>
645
645
  ) : (
646
- <span className="truncate">{labels?.placeholder ?? "Select"}</span>
646
+ <span className="truncate text-muted-foreground">{labels?.placeholder ?? "Select"}</span>
647
647
  )}
648
648
  </span>
649
649
  <span className="ml-2 flex shrink-0 items-center gap-1">
@@ -671,7 +671,7 @@ function AsyncSelect<
671
671
  align="start"
672
672
  data-slot="async-select-content"
673
673
  className={cn(
674
- "w-(--anchor-width) gap-3 rounded-[var(--radius-2xl)] p-3.5",
674
+ "w-(--anchor-width) min-w-72 gap-3 rounded-[var(--aui-card-radius,var(--radius-lg))] border-[color:var(--aui-card-border,var(--border))] bg-popover p-3 shadow-[var(--aui-control-panel-shadow,0_18px_40px_rgba(15,23,42,0.14))]",
675
675
  contentClassName
676
676
  )}
677
677
  >
@@ -686,7 +686,7 @@ function AsyncSelect<
686
686
  />
687
687
  </div>
688
688
 
689
- <div className="max-h-64 space-y-1 overflow-y-auto pr-1">
689
+ <div className="max-h-72 space-y-1 overflow-y-auto pr-1">
690
690
  {searchTooShort && flatOptions.length === 0 && (
691
691
  renderMinSearch?.(state) ?? (
692
692
  <AsyncStateMessage>
@@ -1043,7 +1043,7 @@ function AsyncMultiSelect<
1043
1043
  aria-invalid={invalid || undefined}
1044
1044
  data-slot="async-select-trigger"
1045
1045
  className={cn(
1046
- "min-h-11 w-full justify-between",
1046
+ "min-h-11 w-full justify-between rounded-[var(--aui-control-radius,var(--radius-md))] px-3.5 text-left",
1047
1047
  triggerClassName
1048
1048
  )}
1049
1049
  onKeyDown={handleTriggerKeyDown}
@@ -1057,7 +1057,7 @@ function AsyncMultiSelect<
1057
1057
  key={option.value}
1058
1058
  data-slot="async-select-tag"
1059
1059
  className={cn(
1060
- "inline-flex max-w-full items-center gap-1 rounded-full border px-2 py-1 text-xs text-foreground",
1060
+ "inline-flex max-w-full items-center gap-1.5 rounded-[var(--radius-sm)] border border-[color:color-mix(in_oklch,var(--primary),transparent_70%)] bg-[color:color-mix(in_oklch,var(--primary),transparent_92%)] px-2 py-1 text-xs font-medium text-foreground",
1061
1061
  tagClassName
1062
1062
  )}
1063
1063
  >
@@ -1076,7 +1076,7 @@ function AsyncMultiSelect<
1076
1076
  role="button"
1077
1077
  tabIndex={0}
1078
1078
  data-slot="async-select-tag-remove"
1079
- className="rounded-full text-muted-foreground transition-colors hover:text-foreground"
1079
+ className="rounded-full p-0.5 text-muted-foreground transition-colors hover:bg-background hover:text-foreground"
1080
1080
  aria-label={`Remove ${getOptionLabelText(option)}`}
1081
1081
  onClick={(event) => {
1082
1082
  stopInteractivePropagation(event)
@@ -1101,7 +1101,7 @@ function AsyncMultiSelect<
1101
1101
  role="button"
1102
1102
  tabIndex={0}
1103
1103
  data-slot="async-select-clear"
1104
- className="rounded-full border p-1 text-muted-foreground transition-colors hover:text-foreground"
1104
+ className="rounded-full border border-border/65 p-1 text-muted-foreground transition-colors hover:border-border hover:bg-muted/55 hover:text-foreground"
1105
1105
  aria-label={labels?.clearAll ?? labels?.clear ?? "Clear all"}
1106
1106
  onClick={handleClear}
1107
1107
  onKeyDown={(event) => {
@@ -1121,7 +1121,7 @@ function AsyncMultiSelect<
1121
1121
  align="start"
1122
1122
  data-slot="async-select-content"
1123
1123
  className={cn(
1124
- "w-(--anchor-width) gap-3 rounded-[var(--radius-2xl)] p-3.5",
1124
+ "w-(--anchor-width) min-w-72 gap-3 rounded-[var(--aui-card-radius,var(--radius-lg))] border-[color:var(--aui-card-border,var(--border))] bg-popover p-3 shadow-[var(--aui-control-panel-shadow,0_18px_40px_rgba(15,23,42,0.14))]",
1125
1125
  contentClassName
1126
1126
  )}
1127
1127
  >
@@ -1136,7 +1136,7 @@ function AsyncMultiSelect<
1136
1136
  />
1137
1137
  </div>
1138
1138
 
1139
- <div data-slot="async-select-meta" className="flex flex-wrap items-center justify-between gap-2 rounded-[min(var(--radius-xl),16px)] border px-3 py-2 text-xs text-muted-foreground">
1139
+ <div data-slot="async-select-meta" className="flex flex-wrap items-center justify-between gap-2 rounded-[var(--radius-md)] border border-[color:var(--aui-card-border,var(--border))] bg-[color:color-mix(in_oklch,var(--muted),transparent_62%)] px-3 py-2 text-xs text-muted-foreground">
1140
1140
  {hasValue && labels?.selectedCount && <span>{labels.selectedCount(values.length)}</span>}
1141
1141
  {isMaxReached &&
1142
1142
  (renderMaxSelected?.(state) ?? (
@@ -1147,7 +1147,7 @@ function AsyncMultiSelect<
1147
1147
  <button
1148
1148
  type="button"
1149
1149
  data-slot="async-select-meta-action"
1150
- className="rounded-full border border-border/75 px-2.5 py-1 font-medium text-foreground transition-colors hover:bg-background"
1150
+ className="rounded-[var(--radius-sm)] border border-border/75 px-2.5 py-1 font-medium text-foreground transition-colors hover:bg-background"
1151
1151
  onClick={handleSelectAllVisible}
1152
1152
  >
1153
1153
  {labels?.selectAll ?? "Select all"}
@@ -1157,7 +1157,7 @@ function AsyncMultiSelect<
1157
1157
  <button
1158
1158
  type="button"
1159
1159
  data-slot="async-select-meta-action"
1160
- className="rounded-full border border-border/75 px-2.5 py-1 font-medium text-foreground transition-colors hover:bg-background"
1160
+ className="rounded-[var(--radius-sm)] border border-border/75 px-2.5 py-1 font-medium text-foreground transition-colors hover:bg-background"
1161
1161
  onClick={() => onValueChange?.([], [])}
1162
1162
  >
1163
1163
  {labels?.clearAll ?? labels?.clear ?? "Clear all"}
@@ -1166,7 +1166,7 @@ function AsyncMultiSelect<
1166
1166
  </div>
1167
1167
  </div>
1168
1168
 
1169
- <div className="max-h-64 space-y-1 overflow-y-auto pr-1">
1169
+ <div className="max-h-72 space-y-1 overflow-y-auto pr-1">
1170
1170
  {searchTooShort && flatOptions.length === 0 && (
1171
1171
  renderMinSearch?.(state) ?? (
1172
1172
  <AsyncStateMessage>
@@ -1,9 +1,10 @@
1
1
  import * as React from "react"
2
2
  import { CheckIcon, ChevronDownIcon, SearchIcon } from "lucide-react"
3
3
 
4
- import { Button } from "@/components/ui/button"
5
- import { Input } from "@/components/ui/input"
6
- import { cn } from "@/lib/utils"
4
+ import { Button } from "@/components/ui/button"
5
+ import { Input } from "@/components/ui/input"
6
+ import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
7
+ import { cn } from "@/lib/utils"
7
8
 
8
9
  export type ComboboxOption<TValue extends string = string> = {
9
10
  value: TValue
@@ -22,8 +23,12 @@ export type ComboboxProps<TValue extends string = string> = React.ComponentProps
22
23
  searchPlaceholder?: string
23
24
  emptyLabel?: React.ReactNode
24
25
  disabled?: boolean
25
- invalid?: boolean
26
- }
26
+ invalid?: boolean
27
+ triggerClassName?: string
28
+ contentClassName?: string
29
+ optionClassName?: string
30
+ searchClassName?: string
31
+ }
27
32
 
28
33
  function Combobox<TValue extends string = string>({
29
34
  value,
@@ -32,11 +37,15 @@ function Combobox<TValue extends string = string>({
32
37
  placeholder = "Select option",
33
38
  searchPlaceholder = "Search...",
34
39
  emptyLabel = "No option found",
35
- disabled = false,
36
- invalid,
37
- className,
38
- ...props
39
- }: ComboboxProps<TValue>) {
40
+ disabled = false,
41
+ invalid,
42
+ triggerClassName,
43
+ contentClassName,
44
+ optionClassName,
45
+ searchClassName,
46
+ className,
47
+ ...props
48
+ }: ComboboxProps<TValue>) {
40
49
  const [open, setOpen] = React.useState(false)
41
50
  const [search, setSearch] = React.useState("")
42
51
  const selectedOption = options.find((option) => option.value === value)
@@ -47,45 +56,66 @@ function Combobox<TValue extends string = string>({
47
56
  return String(option.searchValue ?? option.label).toLowerCase().includes(normalizedSearch)
48
57
  })
49
58
 
50
- return (
51
- <div data-slot="combobox" className={cn("relative grid gap-2", className)} {...props}>
52
- <Button type="button" variant="outline" disabled={disabled} aria-invalid={invalid || undefined} className="w-full justify-between" onClick={() => setOpen((value) => !value)}>
53
- <span className={cn("truncate", !selectedOption && "text-muted-foreground")}>{selectedOption?.label ?? placeholder}</span>
54
- <ChevronDownIcon className="size-4 opacity-60" />
55
- </Button>
56
- {open && (
57
- <div className="absolute top-full z-30 mt-2 w-full rounded-md border bg-popover p-2 text-popover-foreground shadow-md">
58
- <div className="relative mb-2">
59
- <SearchIcon className="pointer-events-none absolute left-2 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
60
- <Input value={search} onChange={(event) => setSearch(event.target.value)} placeholder={searchPlaceholder} className="h-9 pl-8" />
61
- </div>
62
- <div className="max-h-64 overflow-y-auto">
63
- {filteredOptions.length ? filteredOptions.map((option) => {
59
+ return (
60
+ <div data-slot="combobox" className={cn("grid w-full gap-2", className)} {...props}>
61
+ <Popover open={open} onOpenChange={setOpen}>
62
+ <PopoverTrigger
63
+ render={
64
+ <Button
65
+ type="button"
66
+ variant="outline"
67
+ disabled={disabled}
68
+ aria-expanded={open}
69
+ aria-invalid={invalid || undefined}
70
+ className={cn("min-h-11 w-full justify-between rounded-[var(--aui-control-radius,var(--radius-md))] px-3.5 text-left", triggerClassName)}
71
+ />
72
+ }
73
+ >
74
+ <span className={cn("min-w-0 flex-1 truncate font-medium", !selectedOption && "font-normal text-muted-foreground")}>
75
+ {selectedOption?.label ?? placeholder}
76
+ </span>
77
+ <ChevronDownIcon className="size-4 opacity-60" />
78
+ </PopoverTrigger>
79
+ <PopoverContent
80
+ align="start"
81
+ data-slot="combobox-content"
82
+ className={cn("w-(--anchor-width) min-w-72 rounded-[var(--aui-card-radius,var(--radius-lg))] border-[color:var(--aui-card-border,var(--border))] bg-popover p-3 shadow-[var(--aui-control-panel-shadow,0_18px_40px_rgba(15,23,42,0.14))]", contentClassName)}
83
+ >
84
+ <div className="relative mb-2">
85
+ <SearchIcon className="pointer-events-none absolute left-2 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
86
+ <Input value={search} onChange={(event) => setSearch(event.target.value)} placeholder={searchPlaceholder} className={cn("h-9 pl-8", searchClassName)} />
87
+ </div>
88
+ <div className="max-h-64 overflow-y-auto">
89
+ {filteredOptions.length ? filteredOptions.map((option) => {
64
90
  const active = option.value === value
65
91
  return (
66
92
  <button
67
- key={option.value}
68
- type="button"
69
- disabled={option.disabled}
70
- className={cn("flex w-full items-start gap-2 rounded-md px-2 py-2 text-left text-sm hover:bg-muted disabled:pointer-events-none disabled:opacity-50", active && "bg-muted")}
71
- onClick={() => {
72
- onValueChange?.(option.value, option)
73
- setOpen(false)
74
- }}
75
- >
76
- <span className="mt-0.5 flex size-4 shrink-0 items-center justify-center">{active && <CheckIcon className="size-4" />}</span>
93
+ key={option.value}
94
+ type="button"
95
+ disabled={option.disabled}
96
+ data-selected={active || undefined}
97
+ className={cn(
98
+ "flex w-full items-start gap-2.5 rounded-[var(--radius-md)] border border-transparent px-3 py-2.5 text-left text-sm transition-colors hover:border-[color:color-mix(in_oklch,var(--primary),transparent_76%)] hover:bg-[color:color-mix(in_oklch,var(--primary),transparent_93%)] disabled:pointer-events-none disabled:opacity-50 data-[selected=true]:border-[color:color-mix(in_oklch,var(--primary),transparent_68%)] data-[selected=true]:bg-[color:color-mix(in_oklch,var(--primary),transparent_89%)]",
99
+ optionClassName
100
+ )}
101
+ onClick={() => {
102
+ onValueChange?.(option.value, option)
103
+ setOpen(false)
104
+ }}
105
+ >
106
+ <span className={cn("mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full border border-border/70", active && "border-primary bg-primary text-primary-foreground")}>{active && <CheckIcon className="size-3" />}</span>
77
107
  <span className="min-w-0">
78
108
  <span className="block truncate font-medium">{option.label}</span>
79
109
  {option.description && <span className="block text-xs text-muted-foreground">{option.description}</span>}
80
110
  </span>
81
111
  </button>
82
112
  )
83
- }) : <div className="px-2 py-6 text-center text-sm text-muted-foreground">{emptyLabel}</div>}
84
- </div>
85
- </div>
86
- )}
87
- </div>
88
- )
89
- }
113
+ }) : <div className="rounded-[var(--radius-md)] border border-[color:var(--aui-card-border,var(--border))] bg-[color:color-mix(in_oklch,var(--muted),transparent_55%)] px-3 py-6 text-center text-sm text-muted-foreground">{emptyLabel}</div>}
114
+ </div>
115
+ </PopoverContent>
116
+ </Popover>
117
+ </div>
118
+ )
119
+ }
90
120
 
91
121
  export { Combobox }
@@ -29,7 +29,7 @@ export type SimpleSelectProps = Omit<
29
29
  searchPlaceholder?: string
30
30
  emptyLabel?: React.ReactNode
31
31
  clearLabel?: string
32
- size?: "sm" | "default"
32
+ size?: "sm" | "default" | "lg"
33
33
  clearable?: boolean
34
34
  searchable?: boolean
35
35
  loading?: boolean
@@ -94,7 +94,7 @@ function SimpleSelect({
94
94
  <button
95
95
  type="button"
96
96
  aria-label={clearLabel}
97
- className="ml-1 rounded-sm p-0.5 text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
97
+ className="ml-1 rounded-[var(--radius-sm)] border border-border/65 p-1 text-muted-foreground transition-colors hover:border-border hover:bg-muted/55 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
98
98
  onClick={(event) => {
99
99
  event.preventDefault()
100
100
  stopInteractivePropagation(event)
@@ -114,7 +114,7 @@ function SimpleSelect({
114
114
  )}
115
115
  >
116
116
  {searchable ? (
117
- <div data-slot="select-search" className="sticky top-0 z-10 mb-1 flex items-center gap-2 rounded-[min(var(--radius-lg),14px)] border px-2.5 py-2 text-sm">
117
+ <div data-slot="select-search" className="sticky top-0 z-10 mb-1 flex items-center gap-2 rounded-[var(--radius-md)] border border-[color:var(--aui-card-border,var(--border))] bg-popover px-2.5 py-2 text-sm">
118
118
  <SearchIcon className="size-4 text-muted-foreground" />
119
119
  <input
120
120
  value={search}
@@ -126,12 +126,12 @@ function SimpleSelect({
126
126
  ) : null}
127
127
 
128
128
  {loading ? (
129
- <div data-slot="select-state" className="flex items-center gap-2 rounded-[min(var(--radius-lg),14px)] px-3 py-2.5 text-sm text-muted-foreground">
129
+ <div data-slot="select-state" className="flex items-center gap-2 rounded-[var(--radius-md)] border border-[color:var(--aui-card-border,var(--border))] bg-[color:color-mix(in_oklch,var(--muted),transparent_55%)] px-3 py-2.5 text-sm text-muted-foreground">
130
130
  <LoaderCircleIcon className="size-4 animate-spin" />
131
131
  {loadingLabel}
132
132
  </div>
133
133
  ) : filteredOptions.length === 0 ? (
134
- <div data-slot="select-state" className="rounded-[min(var(--radius-lg),14px)] px-3 py-2.5 text-sm text-muted-foreground">{emptyLabel}</div>
134
+ <div data-slot="select-state" className="rounded-[var(--radius-md)] border border-[color:var(--aui-card-border,var(--border))] bg-[color:color-mix(in_oklch,var(--muted),transparent_55%)] px-3 py-2.5 text-sm text-muted-foreground">{emptyLabel}</div>
135
135
  ) : (
136
136
  filteredOptions.map((option) => {
137
137
  const selected = option.value === value
@@ -140,7 +140,7 @@ function SimpleSelect({
140
140
  key={option.value}
141
141
  value={option.value}
142
142
  disabled={option.disabled}
143
- className={cn("rounded-[min(var(--radius-lg),14px)]", itemClassName)}
143
+ className={cn("rounded-[var(--radius-md)]", itemClassName)}
144
144
  >
145
145
  {renderOption ? (
146
146
  renderOption(option, { selected })
@@ -0,0 +1,2 @@
1
+ export * from "./button/index"
2
+
@@ -0,0 +1,2 @@
1
+ export * from "./input/index"
2
+
@@ -9,7 +9,7 @@ import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react"
9
9
  export type SelectRootProps = React.ComponentPropsWithoutRef<typeof SelectPrimitive.Root>
10
10
  export type SelectGroupProps = SelectPrimitive.Group.Props
11
11
  export type SelectValueProps = SelectPrimitive.Value.Props
12
- export type SelectTriggerProps = SelectPrimitive.Trigger.Props & { size?: "sm" | "default" }
12
+ export type SelectTriggerProps = SelectPrimitive.Trigger.Props & { size?: "sm" | "default" | "lg" }
13
13
  export type SelectContentProps = SelectPrimitive.Popup.Props &
14
14
  Pick<
15
15
  SelectPrimitive.Positioner.Props,
@@ -54,7 +54,7 @@ function SelectTrigger({
54
54
  data-slot="select-trigger"
55
55
  data-size={size}
56
56
  className={cn(
57
- "flex w-fit min-w-36 items-center justify-between gap-2 rounded-[var(--aui-control-radius,var(--radius-lg))] border border-[color:var(--aui-control-border-strong,var(--input))] bg-[color:var(--aui-control-surface,var(--background))] py-2 pr-3 pl-3 text-sm whitespace-nowrap text-foreground shadow-[var(--aui-control-shadow,0_1px_2px_rgba(15,23,42,0.04))] transition-[background-color,border-color,box-shadow,color] outline-none select-none hover:border-[color:var(--aui-control-hover-border,var(--ring))] hover:bg-[color:var(--aui-control-surface-hover,var(--background))] hover:shadow-[var(--aui-control-shadow-hover,0_2px_6px_rgba(15,23,42,0.06))] focus-visible:border-[color:var(--ring)] focus-visible:ring-0 focus-visible:shadow-[var(--aui-control-shadow,0_1px_2px_rgba(15,23,42,0.04)),0_0_0_1px_var(--aui-focus-ring,var(--ring)),0_0_0_5px_var(--aui-focus-ring-soft,transparent)] disabled:cursor-not-allowed disabled:border-[color:color-mix(in_oklch,var(--border),transparent_18%)] disabled:bg-[color:var(--aui-control-surface-disabled,var(--muted))] disabled:opacity-100 aria-invalid:border-destructive aria-invalid:shadow-[var(--aui-control-shadow,0_1px_2px_rgba(15,23,42,0.04)),0_0_0_1px_var(--aui-danger-ring,var(--destructive)),0_0_0_5px_var(--aui-danger-ring-soft,transparent)] data-placeholder:text-muted-foreground/74 data-[size=default]:h-10 data-[size=sm]:h-9 data-[size=sm]:rounded-[var(--radius-sm)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
57
+ "flex w-full min-w-0 items-center justify-between gap-2 rounded-[var(--aui-control-radius,var(--radius-md))] border border-[color:var(--aui-control-border-strong,var(--input))] bg-[color:var(--aui-control-surface,var(--background))] pr-3 pl-3 text-sm whitespace-nowrap text-foreground shadow-[var(--aui-control-shadow,0_1px_2px_rgba(15,23,42,0.04))] transition-[background-color,border-color,box-shadow,color] outline-none select-none hover:border-[color:var(--aui-control-hover-border,var(--ring))] hover:bg-[color:var(--aui-control-surface-hover,var(--background))] hover:shadow-[var(--aui-control-shadow-hover,0_2px_6px_rgba(15,23,42,0.06))] focus-visible:border-[color:var(--ring)] focus-visible:ring-0 focus-visible:shadow-[var(--aui-control-shadow,0_1px_2px_rgba(15,23,42,0.04)),0_0_0_1px_var(--aui-focus-ring,var(--ring)),0_0_0_4px_var(--aui-focus-ring-soft,transparent)] disabled:cursor-not-allowed disabled:border-[color:color-mix(in_oklch,var(--border),transparent_18%)] disabled:bg-[color:var(--aui-control-surface-disabled,var(--muted))] disabled:opacity-100 aria-invalid:border-destructive aria-invalid:shadow-[var(--aui-control-shadow,0_1px_2px_rgba(15,23,42,0.04)),0_0_0_1px_var(--aui-danger-ring,var(--destructive)),0_0_0_4px_var(--aui-danger-ring-soft,transparent)] data-placeholder:text-muted-foreground/74 data-[size=default]:h-10 data-[size=lg]:h-11 data-[size=sm]:h-9 data-[size=sm]:rounded-[var(--radius-sm)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:min-w-0 *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
58
58
  className
59
59
  )}
60
60
  {...props}
@@ -92,7 +92,7 @@ function SelectContent({
92
92
  <SelectPrimitive.Popup
93
93
  data-slot="select-content"
94
94
  data-align-trigger={alignItemWithTrigger}
95
- className={cn("relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-44 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-[var(--aui-card-radius,var(--radius-xl))] border border-[color:var(--aui-card-border,var(--border))] bg-popover p-1.5 text-popover-foreground shadow-[var(--aui-control-panel-shadow,0_18px_40px_rgba(15,23,42,0.14))] backdrop-blur duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className)}
95
+ className={cn("relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-52 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-[var(--aui-card-radius,var(--radius-lg))] border border-[color:var(--aui-card-border,var(--border))] bg-popover p-1.5 text-popover-foreground shadow-[var(--aui-control-panel-shadow,0_18px_40px_rgba(15,23,42,0.14))] backdrop-blur duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className)}
96
96
  {...props}
97
97
  >
98
98
  <SelectScrollUpButton />
@@ -126,7 +126,7 @@ function SelectItem({
126
126
  <SelectPrimitive.Item
127
127
  data-slot="select-item"
128
128
  className={cn(
129
- "relative flex w-full cursor-default items-center gap-1.5 rounded-[var(--radius-md)] border border-transparent py-2.5 pr-9 pl-3 text-sm text-[color:var(--aui-page-muted-strong,var(--foreground))] outline-hidden select-none transition-[background-color,border-color,color,box-shadow,transform] data-[highlighted]:border-[color:var(--aui-control-hover-border,var(--ring))] data-[highlighted]:bg-[color:var(--aui-control-surface-hover,var(--muted))] data-[highlighted]:text-foreground data-[selected]:font-semibold data-[selected]:text-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
129
+ "relative flex w-full cursor-default items-center gap-2 rounded-[var(--radius-md)] border border-transparent py-2.5 pr-9 pl-3 text-sm text-[color:var(--aui-page-muted-strong,var(--foreground))] outline-hidden select-none transition-[background-color,border-color,color,box-shadow,transform] data-[highlighted]:border-[color:color-mix(in_oklch,var(--primary),transparent_72%)] data-[highlighted]:bg-[color:color-mix(in_oklch,var(--primary),transparent_92%)] data-[highlighted]:text-foreground data-[selected]:border-[color:color-mix(in_oklch,var(--primary),transparent_70%)] data-[selected]:bg-[color:color-mix(in_oklch,var(--primary),transparent_90%)] data-[selected]:font-semibold data-[selected]:text-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:min-w-0 *:[span]:last:items-center *:[span]:last:gap-2",
130
130
  className
131
131
  )}
132
132
  {...props}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://tembro.dev/registry.schema.json",
3
3
  "name": "tembro",
4
- "version": "1.0.1",
4
+ "version": "1.0.3",
5
5
  "description": "Reusable React + TypeScript UI kit registry",
6
6
  "groups": {
7
7
  "ui": [
package/registry.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://tembro.dev/registry.schema.json",
3
3
  "name": "tembro",
4
- "version": "1.0.1",
4
+ "version": "1.0.3",
5
5
  "description": "Reusable React + TypeScript UI kit registry",
6
6
  "groups": {
7
7
  "ui": [