@modlin/ui 0.0.241 → 0.0.242
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 +1 -1
- package/src/checkbox.tsx +0 -1
- package/src/select.tsx +140 -141
- package/src/toast.tsx +1 -1
- package/tsconfig.json +12 -9
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/package",
|
|
3
3
|
"name": "@modlin/ui",
|
|
4
4
|
"description": "A lightweight UI library built on the Suffix design system for consistent, fast, and elegant interfaces.",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.242",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"exports": {
|
package/src/checkbox.tsx
CHANGED
package/src/select.tsx
CHANGED
|
@@ -1,172 +1,171 @@
|
|
|
1
1
|
"use client"
|
|
2
|
-
import { IconChevronDown } from "@tabler/icons-react"
|
|
2
|
+
import { IconChevronDown, IconSelector } from "@tabler/icons-react"
|
|
3
3
|
import Button from "./button"
|
|
4
4
|
import Text from "./text"
|
|
5
5
|
import { cn } from "./utils"
|
|
6
6
|
import React, { type ReactElement, type ReactNode, useState } from "react"
|
|
7
7
|
|
|
8
8
|
export interface SelectTriggerProps {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
placeholder?: string
|
|
10
|
+
id?: string
|
|
11
|
+
children?: string
|
|
12
12
|
}
|
|
13
13
|
export function SelectTrigger(props: SelectTriggerProps) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
return (
|
|
15
|
+
<button type="button" className={cn("flex items-center", "bg-(--background)")}>
|
|
16
|
+
{props.placeholder}
|
|
17
|
+
</button>
|
|
18
|
+
)
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export function Dropdown() {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
return (
|
|
23
|
+
<div className="grid">
|
|
24
|
+
<SelectTrigger placeholder="Select a gender" />
|
|
25
|
+
<Button variant="outline" size="xl" className="text-(--description)">
|
|
26
|
+
<Text className="flex grow-1">Country</Text>
|
|
27
|
+
<IconChevronDown />
|
|
28
|
+
</Button>
|
|
29
|
+
</div>
|
|
30
|
+
)
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export interface SelectItemProps {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
value: string
|
|
35
|
+
children: ReactNode
|
|
36
|
+
className?: string
|
|
37
|
+
onPress?: () => void
|
|
38
38
|
}
|
|
39
39
|
export function SelectItem(props: Readonly<SelectItemProps>): ReactElement<SelectItemProps> {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
40
|
+
return (
|
|
41
|
+
<button
|
|
42
|
+
type="button"
|
|
43
|
+
role="option"
|
|
44
|
+
value={props.value}
|
|
45
|
+
onClick={props.onPress}
|
|
46
|
+
className={cn(
|
|
47
|
+
"flex items-center min-h-12 px-4 gap-4",
|
|
48
|
+
"select-none hover:bg-secondary",
|
|
49
|
+
// "[&>svg]:size-4 [&>svg]:scale-125",
|
|
50
|
+
props.className,
|
|
51
|
+
)}
|
|
52
|
+
>
|
|
53
|
+
{props.children}
|
|
54
|
+
</button>
|
|
55
|
+
)
|
|
56
56
|
}
|
|
57
57
|
export interface SelectContentProps {
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
defaultValue: string
|
|
59
|
+
children?: ReactNode
|
|
60
60
|
}
|
|
61
61
|
export function SelectContent(props: SelectContentProps) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
const [value, setValue] = useState<string>(props.defaultValue)
|
|
63
|
+
const [expanded, setExpanded] = useState(false)
|
|
64
|
+
const enhanced = React.Children.map(props.children, child => {
|
|
65
|
+
// We don't use Radix
|
|
66
|
+
const children = child as ReactElement<SelectItemProps>
|
|
67
|
+
if (!React.isValidElement(children)) return children
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
69
|
+
// Add/override props here
|
|
70
|
+
return React.cloneElement(children, {
|
|
71
|
+
onPress() {
|
|
72
|
+
setValue(children.props.value)
|
|
73
|
+
setExpanded(false)
|
|
74
|
+
},
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
)
|
|
78
|
+
return (
|
|
79
|
+
<div className="relative flex">
|
|
80
|
+
<button
|
|
81
|
+
type="button"
|
|
82
|
+
role="combobox"
|
|
83
|
+
aria-expanded={expanded}
|
|
84
|
+
aria-autocomplete="none"
|
|
85
|
+
aria-haspopup="listbox"
|
|
86
|
+
value={value}
|
|
87
|
+
id="country"
|
|
88
|
+
onClick={() => setExpanded(!expanded)}
|
|
89
|
+
// onBlur={() => setExpanded(false)}
|
|
90
|
+
className={cn("absolute flex items-center justify-center gap-1 px-4 h-12")}
|
|
91
|
+
>
|
|
92
|
+
<p className="font-medium w-6 h-6">{value}</p>
|
|
93
|
+
<IconSelector size={16} className="text-muted-foreground" />
|
|
94
|
+
</button>
|
|
95
|
+
<ul
|
|
96
|
+
className={cn(
|
|
97
|
+
"absolute top-[100%] flex flex-col mt-2 w-full max-h-72 overflow-auto",
|
|
98
|
+
"rounded-2xl",
|
|
99
|
+
"bg-background shadow-[0_0_16px_0_var(--shadow)]",
|
|
100
|
+
"animate-popup origin-top-left",
|
|
101
|
+
)}
|
|
102
|
+
>
|
|
103
|
+
{enhanced}
|
|
104
|
+
</ul>
|
|
105
|
+
</div>
|
|
106
|
+
)
|
|
108
107
|
}
|
|
109
108
|
|
|
110
109
|
export interface SelectProps {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
110
|
+
defaultValue?: string
|
|
111
|
+
placeholder: string
|
|
112
|
+
value?: string
|
|
113
|
+
name?: string
|
|
114
|
+
id?: string
|
|
115
|
+
children: ReactElement<SelectItemProps>[]
|
|
117
116
|
}
|
|
118
117
|
export function Select(props: SelectProps) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
const [expanded, setExpanded] = useState(false)
|
|
119
|
+
const [value, setValue] = useState(props.defaultValue)
|
|
120
|
+
const [selected, setSelected] = useState<ReactNode>(props.placeholder)
|
|
122
121
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
122
|
+
const children: ReactElement[] = []
|
|
123
|
+
for (let i = 0; i < props.children.length; i++) {
|
|
124
|
+
const child = props.children[i]
|
|
125
|
+
if (React.isValidElement<SelectItemProps>(child)) {
|
|
126
|
+
children.push(
|
|
127
|
+
React.cloneElement(child as ReactElement<SelectItemProps>, {
|
|
128
|
+
onPress() {
|
|
129
|
+
setValue(child.props.value)
|
|
130
|
+
setSelected(child.props.children)
|
|
131
|
+
setExpanded(false)
|
|
132
|
+
},
|
|
133
|
+
}),
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
138
137
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
138
|
+
return (
|
|
139
|
+
<div className="relative flex flex-col w-full max-w-56">
|
|
140
|
+
<button
|
|
141
|
+
type="button"
|
|
142
|
+
role="combobox"
|
|
143
|
+
aria-expanded={expanded}
|
|
144
|
+
aria-autocomplete="none"
|
|
145
|
+
aria-haspopup="listbox"
|
|
146
|
+
value={value}
|
|
147
|
+
name={props.name}
|
|
148
|
+
id={props.id}
|
|
149
|
+
onClick={() => setExpanded(!expanded)}
|
|
150
|
+
// onBlur={() => setExpanded(false)}
|
|
151
|
+
className={cn("flex items-center gap-x-4", "[&>svg]:size-4 [&>svg]:scale-125", "focus:underline")}
|
|
152
|
+
>
|
|
153
|
+
{selected}
|
|
154
|
+
<IconChevronDown size={16} />
|
|
155
|
+
</button>
|
|
156
|
+
{expanded ? (
|
|
157
|
+
<ul
|
|
158
|
+
id={props.id}
|
|
159
|
+
className={cn(
|
|
160
|
+
"absolute flex flex-col w-full top-[100%] overflow-hidden",
|
|
161
|
+
"rounded-2xl",
|
|
162
|
+
"bg-(--background) shadow-[0_0_16px_0_var(--shadow)]",
|
|
163
|
+
"animate-appear-tc",
|
|
164
|
+
)}
|
|
165
|
+
>
|
|
166
|
+
{children}
|
|
167
|
+
</ul>
|
|
168
|
+
) : null}
|
|
169
|
+
</div>
|
|
170
|
+
)
|
|
172
171
|
}
|
package/src/toast.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export interface ToastOptions {
|
|
2
2
|
description?: string
|
|
3
3
|
}
|
|
4
|
-
export function toast(title: string,
|
|
4
|
+
export function toast(title: string, _options?: ToastOptions) {
|
|
5
5
|
const toast = document.createElement("div")
|
|
6
6
|
toast.className =
|
|
7
7
|
"transition transition-all transition-duration-250 ease-out absolute top-[-64px] p-4 rounded-2xl text-bold bg-white dark:bg-black inset-ring inset-ring-black/25"
|
package/tsconfig.json
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"allowJs": true,
|
|
4
|
+
"allowImportingTsExtensions": true,
|
|
4
5
|
"declaration": true,
|
|
5
6
|
"declarationMap": true,
|
|
6
7
|
"esModuleInterop": true,
|
|
7
8
|
"incremental": false,
|
|
8
9
|
"isolatedModules": true,
|
|
9
|
-
"
|
|
10
|
-
"
|
|
10
|
+
"jsx": "react-jsx",
|
|
11
|
+
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
|
12
|
+
"module": "Preserve",
|
|
11
13
|
"moduleDetection": "force",
|
|
12
|
-
"moduleResolution": "
|
|
14
|
+
"moduleResolution": "bundler",
|
|
15
|
+
"noEmit": true,
|
|
13
16
|
"noUncheckedIndexedAccess": true,
|
|
17
|
+
"outdir": "dist",
|
|
14
18
|
"resolveJsonModule": true,
|
|
19
|
+
"rootDir": "src",
|
|
15
20
|
"skipLibCheck": true,
|
|
16
21
|
"strict": true,
|
|
17
|
-
"target": "
|
|
18
|
-
"
|
|
19
|
-
"outdir": "dist",
|
|
20
|
-
"rootDir": "src"
|
|
22
|
+
"target": "ESNext",
|
|
23
|
+
"verbatimModuleSyntax": true
|
|
21
24
|
},
|
|
22
25
|
"include": ["src"],
|
|
23
26
|
"exclude": ["node_modules", "dist"]
|