@ponti-studios/ui 1.0.0 → 1.0.1

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@ponti-studios/ui",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "private": false,
5
5
  "description": "Shared UI component library for Ponti Studios",
6
6
  "license": "MIT",
@@ -5,7 +5,6 @@ import {
5
5
  DropdownMenu,
6
6
  DropdownMenuContent,
7
7
  DropdownMenuGroup,
8
- DropdownMenuItem,
9
8
  DropdownMenuLabel,
10
9
  DropdownMenuSeparator,
11
10
  DropdownMenuTrigger,
@@ -57,10 +56,9 @@ export function SortControls({
57
56
  .filter((_, i) => i !== index)
58
57
  .map((option) => option.field);
59
58
  return (
60
- <DropdownMenuItem
59
+ <div
61
60
  key={sort.field}
62
- onSelect={(e) => e.preventDefault()}
63
- className={`p-0 focus:bg-transparent ${index === focusedSortIndex ? "bg-muted" : ""}`}
61
+ className={`rounded-sm ${index === focusedSortIndex ? "bg-muted" : ""}`}
64
62
  >
65
63
  <SortRow
66
64
  sortOption={sort}
@@ -70,27 +68,26 @@ export function SortControls({
70
68
  updateSortOption={updateSortOption}
71
69
  removeSortOption={removeSortOption}
72
70
  />
73
- </DropdownMenuItem>
71
+ </div>
74
72
  );
75
73
  })}
76
74
  </DropdownMenuGroup>
77
75
  {availableFieldsToAdd.length > 0 && (
78
76
  <>
79
77
  <DropdownMenuSeparator />
80
- <DropdownMenuItem
81
- onSelect={(e) => {
82
- e.preventDefault();
78
+ <button
79
+ type="button"
80
+ onClick={() => {
83
81
  const firstAvailable = availableFieldsToAdd[0];
84
82
  if (firstAvailable) {
85
83
  addSortOption({ field: firstAvailable, direction: "desc" });
86
84
  }
87
85
  }}
88
- disabled={availableFieldsToAdd.length === 0}
89
- className="mt-1"
86
+ className="hover:bg-muted focus-visible:ring-ring mt-1 flex w-full cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none focus-visible:ring-2 focus-visible:ring-offset-2"
90
87
  >
91
88
  <PlusCircle className="mr-2 size-4" />
92
89
  Add Sort Criterion
93
- </DropdownMenuItem>
90
+ </button>
94
91
  </>
95
92
  )}
96
93
  </DropdownMenuContent>
@@ -1,7 +1,13 @@
1
+ import { ArrowDownWideNarrow, ArrowUpWideNarrow, X } from "lucide-react";
2
+
1
3
  import type { SortField, SortOption } from "../../hooks/sort.types";
2
- import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../forms/select";
4
+ import {
5
+ DropdownMenu,
6
+ DropdownMenuContent,
7
+ DropdownMenuItem,
8
+ DropdownMenuTrigger,
9
+ } from "../overlays/dropdown-menu";
3
10
  import { Button } from "../primitives/button";
4
- import { X } from "lucide-react";
5
11
 
6
12
  export interface SortRowProps {
7
13
  sortOption: SortOption;
@@ -12,6 +18,10 @@ export interface SortRowProps {
12
18
  removeSortOption: (index: number) => void;
13
19
  }
14
20
 
21
+ function fieldLabel(field: SortField) {
22
+ return field.charAt(0).toUpperCase() + field.slice(1);
23
+ }
24
+
15
25
  export function SortRow({
16
26
  sortOption,
17
27
  index,
@@ -25,47 +35,51 @@ export function SortRow({
25
35
  );
26
36
 
27
37
  return (
28
- <div key={sortOption.field} className="flex items-center gap-2">
29
- <Select
30
- value={sortOption.field}
31
- onValueChange={(value) => updateSortOption(index, { ...sortOption, field: value })}
32
- >
33
- <SelectTrigger className="h-8 w-[130px] text-xs">
34
- <SelectValue placeholder="Select field" />
35
- </SelectTrigger>
36
- <SelectContent>
38
+ <div className="flex w-full items-center gap-1">
39
+ <DropdownMenu>
40
+ <DropdownMenuTrigger asChild>
41
+ <button
42
+ type="button"
43
+ className="hover:bg-muted focus-visible:ring-ring flex-1 rounded-md px-2 py-1.5 text-left text-sm outline-none focus-visible:ring-2 focus-visible:ring-offset-2"
44
+ >
45
+ {fieldLabel(sortOption.field)}
46
+ </button>
47
+ </DropdownMenuTrigger>
48
+ <DropdownMenuContent>
37
49
  {availableFieldsForCurrentSelect.map((field) => (
38
- <SelectItem key={field} value={field} className="text-xs">
39
- {field.charAt(0).toUpperCase() + field.slice(1)}
40
- </SelectItem>
50
+ <DropdownMenuItem
51
+ key={field}
52
+ onClick={() => updateSortOption(index, { ...sortOption, field })}
53
+ >
54
+ {fieldLabel(field)}
55
+ </DropdownMenuItem>
41
56
  ))}
42
- </SelectContent>
43
- </Select>
44
- <Select
45
- value={sortOption.direction}
46
- onValueChange={(value) => {
47
- if (value === "asc" || value === "desc") {
48
- updateSortOption(index, { ...sortOption, direction: value });
49
- }
50
- }}
57
+ </DropdownMenuContent>
58
+ </DropdownMenu>
59
+ <Button
60
+ variant="ghost"
61
+ size="sm"
62
+ className="size-8 p-0"
63
+ aria-label={sortOption.direction === "asc" ? "Sorted ascending" : "Sorted descending"}
64
+ onClick={() =>
65
+ updateSortOption(index, {
66
+ ...sortOption,
67
+ direction: sortOption.direction === "asc" ? "desc" : "asc",
68
+ })
69
+ }
51
70
  >
52
- <SelectTrigger className="h-8 w-[110px] text-xs">
53
- <SelectValue placeholder="Direction" />
54
- </SelectTrigger>
55
- <SelectContent>
56
- <SelectItem value="asc" className="text-xs">
57
- Ascending
58
- </SelectItem>
59
- <SelectItem value="desc" className="text-xs">
60
- Descending
61
- </SelectItem>
62
- </SelectContent>
63
- </Select>
71
+ {sortOption.direction === "asc" ? (
72
+ <ArrowUpWideNarrow className="size-4" />
73
+ ) : (
74
+ <ArrowDownWideNarrow className="size-4" />
75
+ )}
76
+ </Button>
64
77
  <Button
65
78
  variant="ghost"
66
79
  size="sm"
67
80
  onClick={() => removeSortOption(index)}
68
81
  className="size-8 p-0"
82
+ aria-label="Remove sort criterion"
69
83
  >
70
84
  <X className="text-muted-foreground size-4" />
71
85
  </Button>
@@ -15,7 +15,7 @@ export function PaginationControls({
15
15
  onPageChange,
16
16
  }: PaginationControlsProps) {
17
17
  return (
18
- <div className="border-border bg-background text-foreground inline-flex items-center overflow-hidden rounded-full border text-sm">
18
+ <div className="border-border bg-background text-foreground inline-flex w-fit shrink-0 items-center self-start overflow-hidden rounded-full border text-sm">
19
19
  <Button
20
20
  type="button"
21
21
  variant="outline"
@@ -43,14 +43,16 @@
43
43
  animation-name: zoom-out;
44
44
  }
45
45
 
46
- /* shadcn New York semantic contract. Values are generated from the DTCG
47
- * source; this file only names the roles consumed by web components. */
46
+ /*
47
+ Values are generated from the DTCG source;
48
+ this file only names the roles consumed by web components.
49
+ */
48
50
  @theme inline {
49
51
  --color-background: var(--background);
50
52
  --color-foreground: var(--text-primary);
51
53
  --color-card: var(--card);
52
54
  --color-card-foreground: var(--text-primary);
53
- --color-popover: var(--popover);
55
+ --color-popover: var(--background);
54
56
  --color-popover-foreground: var(--text-primary);
55
57
  --color-primary: var(--primary);
56
58
  --color-primary-foreground: var(--primary-foreground);