@lolmath/ui 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.
Files changed (100) hide show
  1. package/.turbo/turbo-build.log +30 -0
  2. package/dist/chunk-UXIASGQL.js +31 -0
  3. package/dist/chunk-UXIASGQL.js.map +1 -0
  4. package/dist/font/beaufort/beaufort.css +79 -0
  5. package/dist/font/beaufort/files/beaufort-300-italic.woff +0 -0
  6. package/dist/font/beaufort/files/beaufort-300-italic.woff2 +0 -0
  7. package/dist/font/beaufort/files/beaufort-300-normal.woff +0 -0
  8. package/dist/font/beaufort/files/beaufort-300-normal.woff2 +0 -0
  9. package/dist/font/beaufort/files/beaufort-400-italic.woff +0 -0
  10. package/dist/font/beaufort/files/beaufort-400-italic.woff2 +0 -0
  11. package/dist/font/beaufort/files/beaufort-400-normal.woff +0 -0
  12. package/dist/font/beaufort/files/beaufort-400-normal.woff2 +0 -0
  13. package/dist/font/beaufort/files/beaufort-500-italic.woff +0 -0
  14. package/dist/font/beaufort/files/beaufort-500-italic.woff2 +0 -0
  15. package/dist/font/beaufort/files/beaufort-500-normal.woff +0 -0
  16. package/dist/font/beaufort/files/beaufort-500-normal.woff2 +0 -0
  17. package/dist/font/beaufort/files/beaufort-700-italic.woff +0 -0
  18. package/dist/font/beaufort/files/beaufort-700-italic.woff2 +0 -0
  19. package/dist/font/beaufort/files/beaufort-700-normal.woff +0 -0
  20. package/dist/font/beaufort/files/beaufort-700-normal.woff2 +0 -0
  21. package/dist/font/beaufort/files/beaufort-900-italic.woff +0 -0
  22. package/dist/font/beaufort/files/beaufort-900-italic.woff2 +0 -0
  23. package/dist/font/beaufort/files/beaufort-900-normal.woff +0 -0
  24. package/dist/font/beaufort/files/beaufort-900-normal.woff2 +0 -0
  25. package/dist/font/spiegel/files/spiegel-400-italic.woff +0 -0
  26. package/dist/font/spiegel/files/spiegel-400-italic.woff2 +0 -0
  27. package/dist/font/spiegel/files/spiegel-400-normal.woff +0 -0
  28. package/dist/font/spiegel/files/spiegel-400-normal.woff2 +0 -0
  29. package/dist/font/spiegel/files/spiegel-600-normal.woff +0 -0
  30. package/dist/font/spiegel/files/spiegel-600-normal.woff2 +0 -0
  31. package/dist/font/spiegel/files/spiegel-700-italic.woff +0 -0
  32. package/dist/font/spiegel/files/spiegel-700-italic.woff2 +0 -0
  33. package/dist/font/spiegel/files/spiegel-700-normal.woff +0 -0
  34. package/dist/font/spiegel/files/spiegel-700-normal.woff2 +0 -0
  35. package/dist/font/spiegel/spiegel.css +44 -0
  36. package/dist/index.cjs +493 -0
  37. package/dist/index.cjs.map +1 -0
  38. package/dist/index.d.cts +57 -0
  39. package/dist/index.d.ts +57 -0
  40. package/dist/index.js +481 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/plugin.cjs +167 -0
  43. package/dist/plugin.cjs.map +1 -0
  44. package/dist/plugin.d.cts +8 -0
  45. package/dist/plugin.d.ts +8 -0
  46. package/dist/plugin.js +134 -0
  47. package/dist/plugin.js.map +1 -0
  48. package/package.json +60 -0
  49. package/public/font/beaufort/beaufort.css +79 -0
  50. package/public/font/beaufort/files/beaufort-300-italic.woff +0 -0
  51. package/public/font/beaufort/files/beaufort-300-italic.woff2 +0 -0
  52. package/public/font/beaufort/files/beaufort-300-normal.woff +0 -0
  53. package/public/font/beaufort/files/beaufort-300-normal.woff2 +0 -0
  54. package/public/font/beaufort/files/beaufort-400-italic.woff +0 -0
  55. package/public/font/beaufort/files/beaufort-400-italic.woff2 +0 -0
  56. package/public/font/beaufort/files/beaufort-400-normal.woff +0 -0
  57. package/public/font/beaufort/files/beaufort-400-normal.woff2 +0 -0
  58. package/public/font/beaufort/files/beaufort-500-italic.woff +0 -0
  59. package/public/font/beaufort/files/beaufort-500-italic.woff2 +0 -0
  60. package/public/font/beaufort/files/beaufort-500-normal.woff +0 -0
  61. package/public/font/beaufort/files/beaufort-500-normal.woff2 +0 -0
  62. package/public/font/beaufort/files/beaufort-700-italic.woff +0 -0
  63. package/public/font/beaufort/files/beaufort-700-italic.woff2 +0 -0
  64. package/public/font/beaufort/files/beaufort-700-normal.woff +0 -0
  65. package/public/font/beaufort/files/beaufort-700-normal.woff2 +0 -0
  66. package/public/font/beaufort/files/beaufort-900-italic.woff +0 -0
  67. package/public/font/beaufort/files/beaufort-900-italic.woff2 +0 -0
  68. package/public/font/beaufort/files/beaufort-900-normal.woff +0 -0
  69. package/public/font/beaufort/files/beaufort-900-normal.woff2 +0 -0
  70. package/public/font/spiegel/files/spiegel-400-italic.woff +0 -0
  71. package/public/font/spiegel/files/spiegel-400-italic.woff2 +0 -0
  72. package/public/font/spiegel/files/spiegel-400-normal.woff +0 -0
  73. package/public/font/spiegel/files/spiegel-400-normal.woff2 +0 -0
  74. package/public/font/spiegel/files/spiegel-600-normal.woff +0 -0
  75. package/public/font/spiegel/files/spiegel-600-normal.woff2 +0 -0
  76. package/public/font/spiegel/files/spiegel-700-italic.woff +0 -0
  77. package/public/font/spiegel/files/spiegel-700-italic.woff2 +0 -0
  78. package/public/font/spiegel/files/spiegel-700-normal.woff +0 -0
  79. package/public/font/spiegel/files/spiegel-700-normal.woff2 +0 -0
  80. package/public/font/spiegel/spiegel.css +44 -0
  81. package/src/components/accordion.tsx +109 -0
  82. package/src/components/button.tsx +81 -0
  83. package/src/components/checkbox.tsx +37 -0
  84. package/src/components/progress-bar.tsx +47 -0
  85. package/src/components/search-field.tsx +65 -0
  86. package/src/components/select.tsx +113 -0
  87. package/src/components/slider.tsx +108 -0
  88. package/src/components/switch.tsx +66 -0
  89. package/src/index.ts +7 -0
  90. package/src/plugin.ts +56 -0
  91. package/src/utilities/border.tsx +7 -0
  92. package/src/utilities/constants.tsx +11 -0
  93. package/src/utilities/outline.tsx +2 -0
  94. package/temp/button/button.css +503 -0
  95. package/temp/button/keyframes.css +63 -0
  96. package/temp/select/dropdown.css +166 -0
  97. package/temp/select/select.css +193 -0
  98. package/temp/slider/slider.css +116 -0
  99. package/tsconfig.json +21 -0
  100. package/tsup.config.ts +13 -0
@@ -0,0 +1,79 @@
1
+ @font-face {
2
+ font-family: beaufort;
3
+ src: url("./files/beaufort-300-italic.woff2") format("woff2"),
4
+ url("./files/beaufort-300-italic.woff") format("woff");
5
+ font-weight: 300;
6
+ font-style: italic;
7
+ }
8
+
9
+ @font-face {
10
+ font-family: beaufort;
11
+ src: url("./files/beaufort-400-italic.woff2") format("woff2"),
12
+ url("./files/beaufort-400-italic.woff") format("woff");
13
+ font-weight: 400;
14
+ font-style: italic;
15
+ }
16
+
17
+ @font-face {
18
+ font-family: beaufort;
19
+ src: url("./files/beaufort-500-italic.woff2") format("woff2"),
20
+ url("./files/beaufort-500-italic.woff") format("woff");
21
+ font-weight: 500;
22
+ font-style: italic;
23
+ }
24
+
25
+ @font-face {
26
+ font-family: beaufort;
27
+ src: url("./files/beaufort-700-italic.woff2") format("woff2"),
28
+ url("./files/beaufort-700-italic.woff") format("woff");
29
+ font-weight: 700;
30
+ font-style: italic;
31
+ }
32
+
33
+ @font-face {
34
+ font-family: beaufort;
35
+ src: url("./files/beaufort-900-italic.woff2") format("woff2"),
36
+ url("./files/beaufort-900-italic.woff") format("woff");
37
+ font-weight: 900;
38
+ font-style: italic;
39
+ }
40
+
41
+ @font-face {
42
+ font-family: beaufort;
43
+ src: url("./files/beaufort-300-normal.woff2") format("woff2"),
44
+ url("./files/beaufort-300-normal.woff") format("woff");
45
+ font-weight: 300;
46
+ font-style: normal;
47
+ }
48
+
49
+ @font-face {
50
+ font-family: beaufort;
51
+ src: url("./files/beaufort-400-normal.woff2") format("woff2"),
52
+ url("./files/beaufort-400-normal.woff") format("woff");
53
+ font-weight: 400;
54
+ font-style: normal;
55
+ }
56
+
57
+ @font-face {
58
+ font-family: beaufort;
59
+ src: url("./files/beaufort-500-normal.woff2") format("woff2"),
60
+ url("./files/beaufort-500-normal.woff") format("woff");
61
+ font-weight: 500;
62
+ font-style: normal;
63
+ }
64
+
65
+ @font-face {
66
+ font-family: beaufort;
67
+ src: url("./files/beaufort-700-normal.woff2") format("woff2"),
68
+ url("./files/beaufort-700-normal.woff") format("woff");
69
+ font-weight: 700;
70
+ font-style: normal;
71
+ }
72
+
73
+ @font-face {
74
+ font-family: beaufort;
75
+ src: url("./files/beaufort-900-normal.woff2") format("woff2"),
76
+ url("./files/beaufort-900-normal.woff") format("woff");
77
+ font-weight: 900;
78
+ font-style: normal;
79
+ }
@@ -0,0 +1,44 @@
1
+ @font-face {
2
+ font-family: spiegel;
3
+ src:
4
+ url("./files/spiegel-400-italic.woff2") format("woff2"),
5
+ url("./files/spiegel-400-italic.woff") format("woff");
6
+ font-weight: 400;
7
+ font-style: italic;
8
+ }
9
+
10
+ @font-face {
11
+ font-family: spiegel;
12
+ src:
13
+ url("./files/spiegel-700-italic.woff2") format("woff2"),
14
+ url("./files/spiegel-700-italic.woff") format("woff");
15
+ font-weight: 700;
16
+ font-style: italic;
17
+ }
18
+
19
+ @font-face {
20
+ font-family: spiegel;
21
+ src:
22
+ url("./files/spiegel-400-normal.woff2") format("woff2"),
23
+ url("./files/spiegel-400-normal.woff") format("woff");
24
+ font-weight: 400;
25
+ font-style: normal;
26
+ }
27
+
28
+ @font-face {
29
+ font-family: spiegel;
30
+ src:
31
+ url("./files/spiegel-600-normal.woff2") format("woff2"),
32
+ url("./files/spiegel-600-normal.woff") format("woff");
33
+ font-weight: 600;
34
+ font-style: normal;
35
+ }
36
+
37
+ @font-face {
38
+ font-family: spiegel;
39
+ src:
40
+ url("./files/spiegel-700-normal.woff2") format("woff2"),
41
+ url("./files/spiegel-700-normal.woff") format("woff");
42
+ font-weight: 700;
43
+ font-style: normal;
44
+ }
@@ -0,0 +1,109 @@
1
+ "use client";
2
+
3
+ import { createContext, useState, useContext } from "react";
4
+ import { twMerge } from "tailwind-merge";
5
+
6
+ interface AccordionProps {
7
+ children: React.ReactNode;
8
+ className?: string;
9
+ }
10
+
11
+ export function Accordion({ children, className }: AccordionProps) {
12
+ const [activeItem, setActiveItem] = useState<string>("");
13
+ return (
14
+ <AccordionContext.Provider
15
+ value={{
16
+ activeItem,
17
+ setActiveItem,
18
+ }}
19
+ >
20
+ <div
21
+ className={twMerge(
22
+ "bg-lol-blue-950 border-lol-gold-500 overflow-hidden rounded border",
23
+ className,
24
+ )}
25
+ >
26
+ {children}
27
+ </div>
28
+ </AccordionContext.Provider>
29
+ );
30
+ }
31
+
32
+ interface AccordionTriggerProps {
33
+ children: React.ReactNode;
34
+ className?: string;
35
+ }
36
+ export function AccordionTrigger({
37
+ children,
38
+ className,
39
+ }: AccordionTriggerProps) {
40
+ const { setActiveItem, activeItem } = useContext(AccordionContext);
41
+ const { item } = useContext(AccordionItemContext);
42
+
43
+ return (
44
+ <button
45
+ className={twMerge(
46
+ "text-lol-gray-300 font-beaufort hover:bg-lol-blue-800 active:bg-lol-blue-700 active:text-lol-gold-200 hover:text-lol-gray-100 flex w-full items-center px-5 py-2 text-left font-bold uppercase",
47
+ className,
48
+ )}
49
+ onClick={() => {
50
+ setActiveItem((currentItem) => (currentItem === item ? "" : item));
51
+ }}
52
+ >
53
+ <span
54
+ className={twMerge(
55
+ "mr-2 inline-block transform text-sm transition-transform",
56
+ item === activeItem && "rotate-90",
57
+ )}
58
+ >
59
+
60
+ </span>
61
+ {children}
62
+ </button>
63
+ );
64
+ }
65
+
66
+ interface AccordionItemProps {
67
+ children: React.ReactNode;
68
+ value: string;
69
+ }
70
+ export function AccordionItem({ children, value }: AccordionItemProps) {
71
+ return (
72
+ <AccordionItemContext.Provider
73
+ value={{
74
+ item: value,
75
+ }}
76
+ >
77
+ <div className="border-lol-gold-500 border-b last-of-type:border-none">
78
+ {children}
79
+ </div>
80
+ </AccordionItemContext.Provider>
81
+ );
82
+ }
83
+
84
+ interface AccordionContentProps {
85
+ children: React.ReactNode;
86
+ }
87
+ export function AccordionContent({ children }: AccordionContentProps) {
88
+ const { activeItem } = useContext(AccordionContext);
89
+ const { item } = useContext(AccordionItemContext);
90
+
91
+ if (activeItem !== item) {
92
+ return null;
93
+ }
94
+
95
+ return (
96
+ <div className="bg-lol-blue-900 border-lol-gold-500 font-spiegel text-lol-blue-100 border-t px-5 py-2">
97
+ {children}
98
+ </div>
99
+ );
100
+ }
101
+
102
+ const AccordionContext = createContext<{
103
+ activeItem: string;
104
+ setActiveItem: React.Dispatch<React.SetStateAction<string>>;
105
+ }>(undefined as any);
106
+
107
+ const AccordionItemContext = createContext<{
108
+ item: string;
109
+ }>(undefined as any);
@@ -0,0 +1,81 @@
1
+ "use client";
2
+
3
+ import { Ref, forwardRef } from "react";
4
+ import {
5
+ Button as AriaButton,
6
+ ButtonProps as AriaButtonProps,
7
+ } from "react-aria-components";
8
+ import { twMerge } from "tailwind-merge";
9
+ import {
10
+ borderClassName,
11
+ borderDisabledClassName,
12
+ borderHoverClassName,
13
+ borderPressedClassName,
14
+ } from "../utilities/border";
15
+
16
+ interface ButtonProps extends AriaButtonProps {
17
+ priority?: "primary" | "secondary";
18
+ }
19
+
20
+ function _Button(
21
+ { children, className, priority, ...props }: ButtonProps,
22
+ ref: Ref<HTMLButtonElement>,
23
+ ) {
24
+ return (
25
+ <AriaButton
26
+ ref={ref}
27
+ className={(values) => {
28
+ const overrideClassname =
29
+ typeof className === "undefined"
30
+ ? ""
31
+ : typeof className === "string"
32
+ ? className
33
+ : className(values);
34
+
35
+ // #5a401f 0%, #47341B #332717 100% primary background gradient.
36
+
37
+ return twMerge(
38
+ "font-[beaufort] font-black uppercase transition-colors duration-200 outline-none bg-gradient-to-t",
39
+ borderClassName,
40
+ values.isHovered && borderHoverClassName,
41
+ values.isPressed && borderPressedClassName,
42
+ values.isDisabled && borderDisabledClassName,
43
+ values.isFocused && "",
44
+ values.isFocusVisible && "outline outline-yellow-50 outline-offset-2",
45
+ overrideClassname,
46
+ );
47
+ }}
48
+ {...props}
49
+ >
50
+ {(values) => {
51
+ return (
52
+ <span
53
+ className={twMerge(
54
+ "block m-0.5 px-4 py-2 bg-[#1e2328] transition-colors duration-200",
55
+ priority === "primary" && "bg-gradient-to-b",
56
+ "text-[#cdbe91] tracking-wide",
57
+ values.isHovered && "text-[#f0e6d2]",
58
+ values.isPressed && "text-[#5c5b57]",
59
+ values.isDisabled && "text-[#5c5b57]",
60
+ values.isFocused && "",
61
+ values.isFocusVisible && "",
62
+
63
+ priority === "primary" &&
64
+ "from-[#5a401f] via-[#47341B] to-[#332717]",
65
+ priority === "primary" &&
66
+ values.isHovered &&
67
+ "from-[#604522] via-[#846745] to-[#725634]",
68
+ priority === "primary" &&
69
+ values.isPressed &&
70
+ "from-[#261b0d] via-[#261b0d] to-[#261b0d] text-[#67604c]",
71
+ )}
72
+ >
73
+ {typeof children === "function" ? children(values) : children}
74
+ </span>
75
+ );
76
+ }}
77
+ </AriaButton>
78
+ );
79
+ }
80
+
81
+ export const Button = forwardRef(_Button);
@@ -0,0 +1,37 @@
1
+ "use client";
2
+
3
+ import { Checkbox as AriaCheckbox, CheckboxProps } from "react-aria-components";
4
+ import { twMerge } from "tailwind-merge";
5
+
6
+ export function ToggleButton({ children, className, ...props }: CheckboxProps) {
7
+ return (
8
+ <AriaCheckbox
9
+ className={(values) => {
10
+ const overrideClassname =
11
+ typeof className === "undefined"
12
+ ? ""
13
+ : typeof className === "string"
14
+ ? className
15
+ : className(values);
16
+
17
+ return twMerge(
18
+ "",
19
+ "",
20
+ values.isSelected && "",
21
+ values.isIndeterminate && "",
22
+ values.isReadOnly && "",
23
+ values.isRequired && "",
24
+ values.isHovered && "",
25
+ values.isPressed && "",
26
+ values.isDisabled && "",
27
+ values.isFocused && "",
28
+ values.isFocusVisible && "",
29
+ overrideClassname,
30
+ );
31
+ }}
32
+ {...props}
33
+ >
34
+ {children}
35
+ </AriaCheckbox>
36
+ );
37
+ }
@@ -0,0 +1,47 @@
1
+ "use client";
2
+
3
+ import {
4
+ ProgressBar as AriaProgressBar,
5
+ Label,
6
+ ProgressBarProps as AriaProgressBarProps,
7
+ } from "react-aria-components";
8
+ import { twMerge } from "tailwind-merge";
9
+ import { borderClassName } from "../utilities/border";
10
+
11
+ interface ProgressBarProps extends Omit<AriaProgressBarProps, "children"> {
12
+ label?: string;
13
+ }
14
+
15
+ export function ProgressBar({
16
+ className,
17
+ label,
18
+ ...props
19
+ }: ProgressBarProps): JSX.Element {
20
+ return (
21
+ <AriaProgressBar className={"flex w-56 flex-col gap-1 text-sm"} {...props}>
22
+ {({ percentage, valueText }) => (
23
+ <>
24
+ <div className="flex font-[beaufort] font-bold uppercase text-[#f0e6d2]">
25
+ <Label className="flex-1 ">{label ?? "Loading"}</Label>
26
+ <span>{valueText}</span>
27
+ </div>
28
+ <div
29
+ className={twMerge(
30
+ borderClassName,
31
+ "-ml-0.5 -mr-1 h-3 rounded-full p-px",
32
+ )}
33
+ >
34
+ <div className={twMerge("h-full w-full rounded-full bg-[#1e2328]")}>
35
+ <div
36
+ className={twMerge(
37
+ "h-full rounded-full bg-gradient-to-r from-[#005A82] via-[#067F9B] to-[#73CCD5]",
38
+ )}
39
+ style={{ width: `${percentage}%` }}
40
+ />
41
+ </div>
42
+ </div>
43
+ </>
44
+ )}
45
+ </AriaProgressBar>
46
+ );
47
+ }
@@ -0,0 +1,65 @@
1
+ import type { SearchFieldProps as AriaSearchFieldProps } from "react-aria-components";
2
+ import {
3
+ SearchField as AriaSearchField,
4
+ Input as AriaInput,
5
+ Button as AriaButton,
6
+ } from "react-aria-components";
7
+ import { twMerge } from "tailwind-merge";
8
+ import { borderClassName } from "../utilities/border";
9
+
10
+ export function SearchField({
11
+ className,
12
+ placeholder,
13
+ ...props
14
+ }: AriaSearchFieldProps & {
15
+ placeholder?: string;
16
+ }) {
17
+ return (
18
+ <AriaSearchField
19
+ className={() =>
20
+ twMerge(
21
+ "flex flex-col outline-none [webkit-search-cancel-button]:hidden",
22
+ borderClassName,
23
+ "focus-within:from-[#c89c3c] focus-within:via-[#dcc188] focus-within:to-[#f0e6d8]",
24
+ props.isDisabled && "from-[#3c3c41] via-[#3c3c41] to-[#3c3c41]",
25
+ )
26
+ }
27
+ {...props}
28
+ >
29
+ {({ state }) => (
30
+ <div
31
+ className={twMerge(
32
+ "m-px bg-[#000000] flex flex-row focus-within:from-[#071019] focus-within:to-[#20272c] focus-within:bg-gradient-to-b",
33
+ props.isDisabled && "text-[#5c5b57] bg-[#1e2328]",
34
+ )}
35
+ >
36
+ <AriaInput
37
+ className="bg-transparent grow py-2 pl-6 text-[#f0e6d2] text-xs outline-none font-[spiegel] tracking-wide"
38
+ type="text"
39
+ style={{
40
+ backgroundImage:
41
+ "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAERElEQVR42uycz0tVQRTH54lamBakLUStQKhEW6V/gC2qhRgRqJURVJj9oBL7oWVBWFj0O/pd2EbJ3ARt2uW6tFUWZkhkiYQVSBZk6esc7rkgkXfm3rkzb957c+CL8Obcc+d+5vcPjESjUWZtdkuxCCwgC8gCsoAsIAvIArKArFlAASzVj/P46KuE+OgFuSvVAJKsqWWgclApaBkoDzSP0n+ARkCDoD5QD6gXNB1XNSiA5YP2graACjz85oAWgrBoN9JvH0GdoBugT4nWB2XThw2BmjhwZrMCenaIYmUnCqAq0ABoDyg9hHjpFAtjVsczIGyut0CPQDkK8ooxu+gdqfEGKAP0GFSvIc/19K6MeAGEpfkQVKGx5lfQO1PjAdB1UGUM+s9KerfRgLDT3OXDfxh0FrSWRqm5oCxQEWgdpb33EQ/fvUkloIifTft/ZtLZNLLkCILBIbsbNCVQaNUEa7FA7G+gFaAxFTNpmRp0WhDOE1AJ9RlTAv7T5FtMf3mGE8xW05oYluwOAb+roA2g7wHeMUEz8MsCvtsFa5s2QLtBaRwfnA81SK6nsP03UiwvS6M8GQEIn6kV6HN20gfKWpRiDXP8alWsDIIELKNFqJc1UxMJyzDWUYGFcZkJgFZz0j/QkiBs66bYXlZuAqBVnPQuRfs40wLgS00AtJyT3qNw3tYjmTctgHI56f0KAfVL5k0LoCxO+heFgMYk8xaz7Y6EtSCAeLPiHIX5XSSZNy2ARjnpxQoBlUjmTQugt5LzJBkrl8ybFkAvOenVivo2dxvEy/pMAMSbiyxlzslG2FZFsbXOwYIAesH4B3nnQJkh5jOTYnoZ5qnXBEA45e/g+ODezD1QJIQ8RigWb7+nQ8USJ2hfgSedkxyfGuZsdqVIwjlPsbxskvLETAGE1fm+gN8B5pxhZQVsVlgrGgV825mi83uZ0j0J+irgV0lrqBrB96WQ72vQZgH/cVCLSTNp1xDOPkFf7D9wAx6PdNpAa5hz/SWNlEe/Ydo78hXdY54P2qoKkMyxj2u3mb+zMVWGTfGSiKOuYx/X9jPnaCfWdhF0yMTVPI4geLr51ABIOOIdMXG74ydoPeiOAZBwQtlkGiC038y5moK1ScWm2S8fvm1hjWwqFpW4sV5EnfdkSE0YYy0BPfDxXCtNRYwDxKgG4UlnIVX5kQAxRujZQor1mTkHiO0+YpwixXSYFy0IPNTDvSI8NsJrwPkzFrQTNBMepO2UZ2z2a8C4/LhLsEQNL1qcCDLM67rrhx/6nCRrWKJ1FLNO8JkWKqTjpjQx1RalAeGmj2eOgc4kCyAXEi51RK/h4d2kN8kEyIWEM/lrAnC2MefmflIBciEdBF0JG06iAHIhNfxnsSoFJ5EAzVzRXwgLjs5hXqcdBv1hziZdp2ywRASE1hxWoIj95ybJ1QdZQBaQBWQBWUAWkDULyAKygPTYXwEGAArW2QJagQgvAAAAAElFTkSuQmCC')",
42
+ backgroundRepeat: "no-repeat",
43
+ backgroundPosition: "5px center",
44
+ backgroundSize: "16px",
45
+ }}
46
+ placeholder={placeholder}
47
+ />
48
+ {state.value.length > 0 && (
49
+ <AriaButton
50
+ className={(buttonValues) =>
51
+ twMerge(
52
+ "font-black text-[#cdbe91] text-xs px-4",
53
+ buttonValues.isHovered && "text-[#f0e6d2]",
54
+ buttonValues.isPressed && "text-[#463714]",
55
+ )
56
+ }
57
+ >
58
+
59
+ </AriaButton>
60
+ )}
61
+ </div>
62
+ )}
63
+ </AriaSearchField>
64
+ );
65
+ }
@@ -0,0 +1,113 @@
1
+ "use client";
2
+
3
+ import { ReactNode } from "react";
4
+ import type {
5
+ ItemProps as AriaItemProps,
6
+ SelectProps as AriaSelectProps,
7
+ } from "react-aria-components";
8
+ import {
9
+ Text as AriaText,
10
+ Select as AriaSelect,
11
+ Button as AriaButton,
12
+ Popover as AriaPopover,
13
+ ListBox as AriaListBox,
14
+ SelectValue as AriaSelectValue,
15
+ Item as AriaItem,
16
+ } from "react-aria-components";
17
+ import { twMerge } from "tailwind-merge";
18
+ import {
19
+ borderClassName,
20
+ borderDisabledClassName,
21
+ borderHoverClassName,
22
+ borderPressedClassName,
23
+ } from "../utilities/border";
24
+ import { outlineClassName } from "../utilities/outline";
25
+
26
+ interface SelectProps<T extends object>
27
+ extends Omit<AriaSelectProps<T>, "children"> {
28
+ label?: string;
29
+ description?: string;
30
+ errorMessage?: string;
31
+ children?: ReactNode | ((item: T) => ReactNode);
32
+ }
33
+
34
+ export function Select<T extends object>({
35
+ description,
36
+ errorMessage,
37
+ children,
38
+ ...props
39
+ }: SelectProps<T>) {
40
+ return (
41
+ <AriaSelect {...props} className="font-[spiegel]">
42
+ {(values) => (
43
+ <>
44
+ <AriaButton
45
+ className={(buttonValues) =>
46
+ twMerge(
47
+ "inline-block outline-none",
48
+ borderClassName,
49
+ buttonValues.isHovered && borderHoverClassName,
50
+ (buttonValues.isPressed || values.isOpen) &&
51
+ borderPressedClassName,
52
+ buttonValues.isDisabled && borderDisabledClassName,
53
+ buttonValues.isFocused && "",
54
+ buttonValues.isFocusVisible && outlineClassName,
55
+ )
56
+ }
57
+ >
58
+ <span
59
+ className={twMerge(
60
+ "block m-px bg-[#1e2328] px-2 py-1 text-[#a09b8c] text-xs font-normal tracking-wide pr-6 bg-no-repeat",
61
+ )}
62
+ style={{
63
+ backgroundPosition: "right 0.5rem center",
64
+ backgroundImage: values.isOpen
65
+ ? "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAASCAYAAACAa1QyAAAA90lEQVR42mL8//8/A6mAiYEMwILVJG4RNiAlDcQgZzz79/XNL2R5RnTnATWwAyn5BEfBaqDUv4UH3rcD+Q+QNaJoAmrgAFJyiY6CdWL8LNEgsRcf/ixA14juJ6kkJ8FGkIbn7//MB2pYKCHAkhDvIFgJksPlJ0ZGRgbmp+9+z1py6EMvSACoASyO009A53FCTfwNCgCoS2A2wAOEcWDiCcl5v6DOY8bmPBYsodf28/f/90sPf+iDBgQo5BiAwd4ICnZcKeKfjDBrepy9IAsoJEFBDgp6fKGHLXIXAm1pQ45cfMmoBpqM2vAmIzSNUkQnWJrFE0CAAQCQxYvehN8YFAAAAABJRU5ErkJggg==')"
66
+ : "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAASCAYAAACAa1QyAAAAiUlEQVR42mL8//8/A6mAiYEMQJYmFnSBk6vzYcwmIP4LxI0gjnnoRNyaoKAViKuQ+I14bQKCTiAuA+I6IGYG4gZ0jSw4nFwB1QwDjIRsKkbjNwxckFNNUw8QlyLx66EYb0D8A+IuIGaDyjcQE0+gOPoDxC1I8dNASBMDNDX8hWKMIGcc3FkDIMAA1n8bpHnZDOAAAAAASUVORK5CYII=')",
67
+ }}
68
+ >
69
+ <AriaSelectValue />
70
+ </span>
71
+ </AriaButton>
72
+ {description && <AriaText slot="description">{description}</AriaText>}
73
+ {errorMessage && (
74
+ <AriaText slot="errorMessage">{errorMessage}</AriaText>
75
+ )}
76
+ <AriaPopover offset={4}>
77
+ <AriaListBox
78
+ className={(listbox) =>
79
+ twMerge(
80
+ "bg-[#010a13] border border-[#463714] outline-none",
81
+ listbox.isFocused && "",
82
+ )
83
+ }
84
+ >
85
+ {children as any}
86
+ </AriaListBox>
87
+ </AriaPopover>
88
+ </>
89
+ )}
90
+ </AriaSelect>
91
+ );
92
+ }
93
+
94
+ export function Item({ className, ...props }: AriaItemProps) {
95
+ return (
96
+ <AriaItem
97
+ {...props}
98
+ className={(values) => {
99
+ const finalClassName =
100
+ typeof className === "function" ? className(values) : className;
101
+
102
+ return twMerge(
103
+ "px-2 py-0.5 border-b border-[#1f2123] text-[#cdbe91] text-sm font-[spiegel] font-bold outline-none",
104
+ values.isHovered && "bg-[#1e2328] text-[#f0e6d2]",
105
+ values.isPressed && "bg-[#1e232880] text-[#463714]",
106
+ values.isFocusVisible && outlineClassName,
107
+ values.isFocused && "",
108
+ finalClassName,
109
+ );
110
+ }}
111
+ />
112
+ );
113
+ }