@modlin/ui 0.0.23 → 0.0.24
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 +11 -18
- package/{components → src}/alert.tsx +1 -1
- package/{components → src}/avatar.tsx +1 -1
- package/{components → src}/badge.tsx +1 -1
- package/{components → src}/button.tsx +3 -3
- package/{components → src}/card.tsx +3 -3
- package/{components → src}/checkbox.tsx +6 -9
- package/{components → src}/content.tsx +1 -1
- package/{components → src}/divider.tsx +1 -1
- package/{components → src}/footer.tsx +1 -1
- package/{components → src}/global.ts +5 -5
- package/{components → src}/header.tsx +1 -1
- package/{components → src}/heading.tsx +1 -1
- package/{components → src}/input.tsx +4 -2
- package/{components → src}/label.tsx +1 -1
- package/{components → src}/select.tsx +70 -25
- package/{components → src}/stack.tsx +1 -1
- package/src/switch.tsx +79 -0
- package/{components → src}/text.tsx +1 -1
- package/{components → src}/textarea.tsx +1 -1
- package/{components → src}/typography.tsx +1 -1
- package/tsconfig.json +8 -32
- package/biome.json +0 -36
- package/components/switch.tsx +0 -79
- package/globals.css +0 -72
- /package/{components → src}/radio.tsx +0 -0
- /package/{components → src}/toast.tsx +0 -0
- /package/{components → src}/tooltip.tsx +0 -0
- /package/{lib → src}/utils.ts +0 -0
package/package.json
CHANGED
|
@@ -1,24 +1,17 @@
|
|
|
1
1
|
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/package",
|
|
2
3
|
"name": "@modlin/ui",
|
|
3
4
|
"description": "A lightweight UI library built on the Suffix design system for consistent, fast, and elegant interfaces.",
|
|
4
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.24",
|
|
5
6
|
"main": "src/index.ts",
|
|
6
7
|
"type": "module",
|
|
7
8
|
"exports": {
|
|
8
|
-
"./*": "./
|
|
9
|
-
"./globals.css": "./globals.css"
|
|
10
|
-
},
|
|
11
|
-
"scripts": {
|
|
12
|
-
"dev": "next dev --turbopack",
|
|
13
|
-
"build": "next build --turbopack",
|
|
14
|
-
"start": "next start",
|
|
15
|
-
"lint": "biome check",
|
|
16
|
-
"format": "biome format --write"
|
|
9
|
+
"./*": "./src/*.tsx"
|
|
17
10
|
},
|
|
18
11
|
"dependencies": {
|
|
19
|
-
"@tabler/icons-react": "
|
|
20
|
-
"clsx": "
|
|
21
|
-
"tailwind-merge": "
|
|
12
|
+
"@tabler/icons-react": "latest",
|
|
13
|
+
"clsx": "latest",
|
|
14
|
+
"tailwind-merge": "latest"
|
|
22
15
|
},
|
|
23
16
|
"peerDependencies": {
|
|
24
17
|
"next": "latest",
|
|
@@ -26,10 +19,10 @@
|
|
|
26
19
|
"react-dom": "latest"
|
|
27
20
|
},
|
|
28
21
|
"devDependencies": {
|
|
29
|
-
"@types/bun": "
|
|
30
|
-
"typescript": "
|
|
31
|
-
"@
|
|
32
|
-
"@types/react
|
|
33
|
-
"@
|
|
22
|
+
"@types/bun": "latest",
|
|
23
|
+
"typescript": "latest",
|
|
24
|
+
"@repo/typescript-config": "0.0.0",
|
|
25
|
+
"@types/react": "latest",
|
|
26
|
+
"@types/react-dom": "latest"
|
|
34
27
|
}
|
|
35
28
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cn } from "
|
|
1
|
+
import { cn } from "./utils"
|
|
2
2
|
import { IconLoader2 } from "@tabler/icons-react"
|
|
3
3
|
import type { MouseEvent, FocusEvent, ReactNode, ReactHTMLElement } from "react"
|
|
4
4
|
import React from "react"
|
|
@@ -34,7 +34,7 @@ const sizeMap = {
|
|
|
34
34
|
}
|
|
35
35
|
const variant: Variants = {
|
|
36
36
|
primary:
|
|
37
|
-
"bg-primary disabled:bg-
|
|
37
|
+
"bg-primary disabled:bg-primary/60 hover:bg-primary/85 text-background",
|
|
38
38
|
secondary: "bg-secondary hover:bg-secondary/75",
|
|
39
39
|
destructive: "bg-(--red) hover:bg-(--red)/85 text-white",
|
|
40
40
|
outline: cn(
|
|
@@ -82,7 +82,7 @@ export default function Button(props: Readonly<ButtonProps>) {
|
|
|
82
82
|
const className = cn(
|
|
83
83
|
"flex items-center justify-center leading-none truncate",
|
|
84
84
|
"select-none hover:cursor-pointer disabled:hover:cursor-not-allowed",
|
|
85
|
-
"transition transition-
|
|
85
|
+
"transition transition-[background-color] transition-duration-250 ease",
|
|
86
86
|
variant[props.variant ?? "primary"],
|
|
87
87
|
sizeMap[props.size ?? "xl"],
|
|
88
88
|
props.className,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cn } from "
|
|
1
|
+
import { cn } from "./utils"
|
|
2
2
|
import type * as React from "react"
|
|
3
3
|
|
|
4
4
|
export interface CardHeaderProps {
|
|
@@ -72,8 +72,8 @@ export const Card: React.FC<CardProps> = props => {
|
|
|
72
72
|
className={cn(
|
|
73
73
|
"flex flex-col",
|
|
74
74
|
size[props.size ?? "md"],
|
|
75
|
-
"bg-
|
|
76
|
-
"sm:inset-ring inset-ring-
|
|
75
|
+
"bg-background",
|
|
76
|
+
"sm:inset-ring inset-ring-outline",
|
|
77
77
|
props.className,
|
|
78
78
|
)}
|
|
79
79
|
>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
import { useEffect, useState } from "react"
|
|
3
3
|
import Image from "next/image"
|
|
4
|
-
import { cn } from "
|
|
4
|
+
import { cn } from "./utils"
|
|
5
5
|
|
|
6
6
|
export interface CheckboxProps {
|
|
7
7
|
checked?: boolean
|
|
@@ -45,7 +45,7 @@ export default function Checkbox(props: Readonly<CheckboxProps>) {
|
|
|
45
45
|
onClick={() => setChecked(v => !v)}
|
|
46
46
|
disabled={props.disabled}
|
|
47
47
|
className={cn(
|
|
48
|
-
"w-4 h-4 rounded-sm hover:cursor-pointer",
|
|
48
|
+
"w-4 h-4 rounded-sm hover:cursor-pointer text-background",
|
|
49
49
|
"transition transition-all transition-duration-150 ease",
|
|
50
50
|
"data-[state=unchecked]:bg-white data-[state=unchecked]:dark:bg-black",
|
|
51
51
|
"data-[state=checked]:bg-black data-[state=checked]:dark:bg-white",
|
|
@@ -55,13 +55,10 @@ export default function Checkbox(props: Readonly<CheckboxProps>) {
|
|
|
55
55
|
"data-[state=unchecked]:disabled:inset-ring-black/25 data-[state=unchecked]:dark:disabled:inset-ring-white/25",
|
|
56
56
|
)}
|
|
57
57
|
>
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
height={16}
|
|
63
|
-
className="dark:invert select-none"
|
|
64
|
-
/>
|
|
58
|
+
<svg width={16} height={16} viewBox="0 0 16 16" fill="none">
|
|
59
|
+
<title>Check</title>
|
|
60
|
+
<path d="M12 5L9 8L6.5 10.5L4 8" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
61
|
+
</svg>
|
|
65
62
|
</button>
|
|
66
63
|
</>
|
|
67
64
|
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cn } from "
|
|
1
|
+
import { cn } from "./utils"
|
|
2
2
|
|
|
3
3
|
export type Variant =
|
|
4
4
|
| "primary"
|
|
@@ -14,12 +14,12 @@ export const input_variant: Variants = {
|
|
|
14
14
|
primary: cn(
|
|
15
15
|
"bg-background",
|
|
16
16
|
"placeholder:text-description disabled:text-disabled",
|
|
17
|
-
// "inset-ring inset-ring-
|
|
18
|
-
"border border-disabled disabled:border-outline focus:border-
|
|
19
|
-
"focus:ring-4 focus:ring-
|
|
17
|
+
// "inset-ring inset-ring-disabled disabled:inset-ring-outline focus:inset-ring-primary",
|
|
18
|
+
"border border-disabled disabled:border-outline focus:border-primary/75",
|
|
19
|
+
"focus:ring-4 focus:ring-primary/10",
|
|
20
20
|
"invalid:inset-ring-red",
|
|
21
21
|
"data-[invalid=true]:border data-[invalid=true]:border-red/50 data-[invalid=true]:focus:border-red",
|
|
22
|
-
"data-[invalid=true]:focus:ring-4 data-[invalid=true]:focus:ring-red/
|
|
22
|
+
"data-[invalid=true]:focus:ring-4 data-[invalid=true]:focus:ring-red/10",
|
|
23
23
|
),
|
|
24
24
|
secondary: cn(),
|
|
25
25
|
destructive: cn(
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
forwardRef,
|
|
7
7
|
} from "react"
|
|
8
8
|
import { input_variant, type Variant } from "./global"
|
|
9
|
-
import { cn } from "
|
|
9
|
+
import { cn } from "./utils"
|
|
10
10
|
|
|
11
11
|
export interface InputProps {
|
|
12
12
|
variant?: Variant
|
|
@@ -45,6 +45,7 @@ export interface InputProps {
|
|
|
45
45
|
// onChange?: (value: string) => void
|
|
46
46
|
className?: string
|
|
47
47
|
invalid?: boolean
|
|
48
|
+
describedby?: string
|
|
48
49
|
}
|
|
49
50
|
const Input = forwardRef<HTMLInputElement, Readonly<InputProps>>(
|
|
50
51
|
(props, ref) => {
|
|
@@ -73,10 +74,11 @@ const Input = forwardRef<HTMLInputElement, Readonly<InputProps>>(
|
|
|
73
74
|
id={props.id}
|
|
74
75
|
autoComplete={props.autoComplete}
|
|
75
76
|
data-invalid={props.invalid}
|
|
77
|
+
aria-describedby={props.describedby}
|
|
76
78
|
className={cn(
|
|
77
79
|
"flex items-center w-full h-12 px-4",
|
|
78
80
|
"peer rounded-2xl",
|
|
79
|
-
"transition-duration-150 transition-[box-
|
|
81
|
+
"transition transition-duration-150 transition-[border,box-shadow] ease-in",
|
|
80
82
|
input_variant[props.variant ?? "primary"],
|
|
81
83
|
props.className,
|
|
82
84
|
)}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { IconChevronDown } from "@tabler/icons-react"
|
|
3
3
|
import Button from "./button"
|
|
4
4
|
import Text from "./text"
|
|
5
|
-
import { cn } from "
|
|
5
|
+
import { cn } from "./utils"
|
|
6
6
|
import React, { type ReactElement, type ReactNode, useState } from "react"
|
|
7
7
|
|
|
8
8
|
export interface SelectTriggerProps {
|
|
@@ -12,10 +12,7 @@ export interface SelectTriggerProps {
|
|
|
12
12
|
}
|
|
13
13
|
export function SelectTrigger(props: SelectTriggerProps) {
|
|
14
14
|
return (
|
|
15
|
-
<button
|
|
16
|
-
type="button"
|
|
17
|
-
className={cn("flex items-center", "bg-(--background)")}
|
|
18
|
-
>
|
|
15
|
+
<button type="button" className={cn("flex items-center", "bg-(--background)")}>
|
|
19
16
|
{props.placeholder}
|
|
20
17
|
</button>
|
|
21
18
|
)
|
|
@@ -37,28 +34,78 @@ export interface SelectItemProps {
|
|
|
37
34
|
value: string
|
|
38
35
|
children: ReactNode
|
|
39
36
|
className?: string
|
|
40
|
-
|
|
37
|
+
onPress?: () => void
|
|
41
38
|
}
|
|
42
|
-
export function SelectItem(
|
|
43
|
-
props: Readonly<SelectItemProps>,
|
|
44
|
-
): ReactElement<SelectItemProps> {
|
|
39
|
+
export function SelectItem(props: Readonly<SelectItemProps>): ReactElement<SelectItemProps> {
|
|
45
40
|
return (
|
|
46
41
|
<button
|
|
47
42
|
type="button"
|
|
48
43
|
role="option"
|
|
49
44
|
value={props.value}
|
|
50
|
-
onClick={props.
|
|
45
|
+
onClick={props.onPress}
|
|
51
46
|
className={cn(
|
|
52
47
|
"flex items-center min-h-12 px-4 gap-4",
|
|
53
48
|
"select-none hover:bg-secondary",
|
|
54
49
|
// "[&>svg]:size-4 [&>svg]:scale-125",
|
|
55
|
-
|
|
50
|
+
props.className,
|
|
56
51
|
)}
|
|
57
52
|
>
|
|
58
53
|
{props.children}
|
|
59
54
|
</button>
|
|
60
55
|
)
|
|
61
56
|
}
|
|
57
|
+
export interface SelectContentProps {
|
|
58
|
+
defaultValue: string
|
|
59
|
+
children?: ReactNode
|
|
60
|
+
}
|
|
61
|
+
export function SelectContent(props: SelectContentProps) {
|
|
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
|
+
|
|
69
|
+
// Add/override props here
|
|
70
|
+
return React.cloneElement(children, {
|
|
71
|
+
onPress() {
|
|
72
|
+
setValue(children.props.value)
|
|
73
|
+
setExpanded(false)
|
|
74
|
+
},
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
|
|
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
|
+
{...register("country")}
|
|
91
|
+
className={cn("absolute flex items-center justify-center gap-1 px-4 h-12")}
|
|
92
|
+
>
|
|
93
|
+
<p className="font-medium w-6 h-6">{value}</p>
|
|
94
|
+
<IconSelector size={16} className="text-muted-foreground" />
|
|
95
|
+
</button>
|
|
96
|
+
<ul
|
|
97
|
+
className={cn(
|
|
98
|
+
"absolute top-[100%] flex flex-col mt-2 w-full max-h-72 overflow-auto",
|
|
99
|
+
"rounded-2xl",
|
|
100
|
+
"bg-background shadow-[0_0_16px_0_var(--shadow)]",
|
|
101
|
+
"animate-popup origin-top-left",
|
|
102
|
+
)}
|
|
103
|
+
>
|
|
104
|
+
{enhanced}
|
|
105
|
+
</ul>
|
|
106
|
+
</div>
|
|
107
|
+
)
|
|
108
|
+
}
|
|
62
109
|
|
|
63
110
|
export interface SelectProps {
|
|
64
111
|
defaultValue?: string
|
|
@@ -76,15 +123,17 @@ export function Select(props: SelectProps) {
|
|
|
76
123
|
const children: ReactElement[] = []
|
|
77
124
|
for (let i = 0; i < props.children.length; i++) {
|
|
78
125
|
const child = props.children[i]
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
126
|
+
if (React.isValidElement<SelectItemProps>(child)) {
|
|
127
|
+
children.push(
|
|
128
|
+
React.cloneElement(child, {
|
|
129
|
+
onClick() {
|
|
130
|
+
setValue(child.props.value)
|
|
131
|
+
setSelected(child.props.children)
|
|
132
|
+
setExpanded(false)
|
|
133
|
+
},
|
|
134
|
+
}),
|
|
135
|
+
)
|
|
136
|
+
}
|
|
88
137
|
}
|
|
89
138
|
|
|
90
139
|
return (
|
|
@@ -100,11 +149,7 @@ export function Select(props: SelectProps) {
|
|
|
100
149
|
id={props.id}
|
|
101
150
|
onClick={() => setExpanded(!expanded)}
|
|
102
151
|
// onBlur={() => setExpanded(false)}
|
|
103
|
-
className={cn(
|
|
104
|
-
"flex items-center gap-x-4",
|
|
105
|
-
"[&>svg]:size-4 [&>svg]:scale-125",
|
|
106
|
-
"focus:underline",
|
|
107
|
-
)}
|
|
152
|
+
className={cn("flex items-center gap-x-4", "[&>svg]:size-4 [&>svg]:scale-125", "focus:underline")}
|
|
108
153
|
>
|
|
109
154
|
{selected}
|
|
110
155
|
<IconChevronDown size={16} />
|
package/src/switch.tsx
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
import { cn } from "./utils"
|
|
3
|
+
import { useEffect, useState } from "react"
|
|
4
|
+
|
|
5
|
+
const sizes = {
|
|
6
|
+
sm: "w-9 h-5 p-0.5",
|
|
7
|
+
lg: "w-14 h-8 p-1",
|
|
8
|
+
}
|
|
9
|
+
const thumb_sizes = {
|
|
10
|
+
sm: "w-4 h-4",
|
|
11
|
+
lg: "w-6 h-6",
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface SwitchProps {
|
|
15
|
+
checked?: boolean
|
|
16
|
+
onChange?(checked: boolean): void
|
|
17
|
+
disabled?: boolean
|
|
18
|
+
// loading?: boolean
|
|
19
|
+
|
|
20
|
+
size?: "sm" | "lg"
|
|
21
|
+
|
|
22
|
+
label?: string
|
|
23
|
+
|
|
24
|
+
required?: boolean // web
|
|
25
|
+
name?: string // web
|
|
26
|
+
value?: string // web
|
|
27
|
+
id?: string // web
|
|
28
|
+
}
|
|
29
|
+
export default function Switch(props: Readonly<SwitchProps>) {
|
|
30
|
+
const [checked, setChecked] = useState(props.checked ?? false)
|
|
31
|
+
|
|
32
|
+
const onChange = props.onChange
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
if (onChange) onChange(checked)
|
|
35
|
+
}, [checked, onChange])
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<>
|
|
39
|
+
<input
|
|
40
|
+
type="checkbox"
|
|
41
|
+
checked={checked}
|
|
42
|
+
onChange={() => setChecked(v => !v)}
|
|
43
|
+
disabled={props.disabled}
|
|
44
|
+
aria-label={props.label}
|
|
45
|
+
required={props.required}
|
|
46
|
+
name={props.id}
|
|
47
|
+
value={props.value}
|
|
48
|
+
id={props.id}
|
|
49
|
+
className="peer hidden"
|
|
50
|
+
/>
|
|
51
|
+
<button
|
|
52
|
+
type="button"
|
|
53
|
+
role="switch"
|
|
54
|
+
data-state={checked ? "checked" : "unchecked"}
|
|
55
|
+
aria-checked={checked}
|
|
56
|
+
onClick={() => setChecked(v => !v)}
|
|
57
|
+
disabled={props.disabled}
|
|
58
|
+
className={cn(
|
|
59
|
+
sizes[props.size ?? "lg"],
|
|
60
|
+
"rounded-full hover:cursor-pointer",
|
|
61
|
+
"transition transition-all transition-duration-150 ease",
|
|
62
|
+
"data-[state=checked]:bg-primary",
|
|
63
|
+
"data-[state=unchecked]:bg-foreground/10",
|
|
64
|
+
)}
|
|
65
|
+
>
|
|
66
|
+
<div
|
|
67
|
+
data-state={checked ? "checked" : "unchecked"}
|
|
68
|
+
className={cn(
|
|
69
|
+
thumb_sizes[props.size ?? "lg"],
|
|
70
|
+
"rounded-full",
|
|
71
|
+
"transition transition-all transition-duration-150 ease",
|
|
72
|
+
"bg-background",
|
|
73
|
+
"data-[state=unchecked]:translate-x-0 data-[state=checked]:translate-x-[100%]",
|
|
74
|
+
)}
|
|
75
|
+
></div>
|
|
76
|
+
</button>
|
|
77
|
+
</>
|
|
78
|
+
)
|
|
79
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -1,34 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"strict": true,
|
|
12
|
-
"noEmit": true,
|
|
13
|
-
"esModuleInterop": true,
|
|
14
|
-
"module": "esnext",
|
|
15
|
-
"moduleResolution": "bundler",
|
|
16
|
-
"resolveJsonModule": true,
|
|
17
|
-
"isolatedModules": true,
|
|
18
|
-
"jsx": "preserve",
|
|
19
|
-
"incremental": true,
|
|
20
|
-
"paths": {
|
|
21
|
-
"@/*": [
|
|
22
|
-
"./*"
|
|
23
|
-
]
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
"include": [
|
|
27
|
-
"next-env.d.ts",
|
|
28
|
-
"**/*.ts",
|
|
29
|
-
"**/*.tsx"
|
|
30
|
-
],
|
|
31
|
-
"exclude": [
|
|
32
|
-
"node_modules"
|
|
33
|
-
]
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"extends": "@repo/typescript-config/react-library.json",
|
|
4
|
+
"compileroptions": {
|
|
5
|
+
"outdir": "dist",
|
|
6
|
+
"rootDir": "src"
|
|
7
|
+
},
|
|
8
|
+
"include": ["src"],
|
|
9
|
+
"exclude": ["node_modules", "dist"]
|
|
34
10
|
}
|
package/biome.json
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://biomejs.dev/schemas/2.1.2/schema.json",
|
|
3
|
-
"vcs": {
|
|
4
|
-
"enabled": false,
|
|
5
|
-
"clientKind": "git",
|
|
6
|
-
"useIgnoreFile": false
|
|
7
|
-
},
|
|
8
|
-
"files": {
|
|
9
|
-
"ignoreUnknown": false
|
|
10
|
-
},
|
|
11
|
-
"formatter": {
|
|
12
|
-
"enabled": true,
|
|
13
|
-
"indentStyle": "tab"
|
|
14
|
-
},
|
|
15
|
-
"linter": {
|
|
16
|
-
"enabled": true,
|
|
17
|
-
"rules": {
|
|
18
|
-
"recommended": true
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
"javascript": {
|
|
22
|
-
"formatter": {
|
|
23
|
-
"quoteStyle": "double",
|
|
24
|
-
"semicolons": "asNeeded",
|
|
25
|
-
"arrowParentheses": "asNeeded"
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
"assist": {
|
|
29
|
-
"enabled": true,
|
|
30
|
-
"actions": {
|
|
31
|
-
"source": {
|
|
32
|
-
"organizeImports": "off"
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
package/components/switch.tsx
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
import { cn } from "@/lib/utils"
|
|
3
|
-
import { useEffect, useState } from "react"
|
|
4
|
-
|
|
5
|
-
const sizes = {
|
|
6
|
-
sm: "w-9 h-5 p-0.5",
|
|
7
|
-
lg: "w-14 h-8 p-1",
|
|
8
|
-
}
|
|
9
|
-
const thumb_sizes = {
|
|
10
|
-
sm: "w-4 h-4",
|
|
11
|
-
lg: "w-6 h-6",
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface SwitchProps {
|
|
15
|
-
checked?: boolean
|
|
16
|
-
onChange?(checked: boolean): void
|
|
17
|
-
disabled?: boolean
|
|
18
|
-
// loading?: boolean
|
|
19
|
-
|
|
20
|
-
size?: "sm" | "lg"
|
|
21
|
-
|
|
22
|
-
label?: string
|
|
23
|
-
|
|
24
|
-
required?: boolean // web
|
|
25
|
-
name?: string // web
|
|
26
|
-
value?: string // web
|
|
27
|
-
id?: string // web
|
|
28
|
-
}
|
|
29
|
-
export default function Switch(props: Readonly<SwitchProps>) {
|
|
30
|
-
const [checked, setChecked] = useState(props.checked ?? false)
|
|
31
|
-
|
|
32
|
-
const onChange = props.onChange
|
|
33
|
-
useEffect(() => {
|
|
34
|
-
if (onChange) onChange(checked)
|
|
35
|
-
}, [checked, onChange])
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<>
|
|
39
|
-
<input
|
|
40
|
-
type="checkbox"
|
|
41
|
-
checked={checked}
|
|
42
|
-
onChange={() => setChecked(v => !v)}
|
|
43
|
-
disabled={props.disabled}
|
|
44
|
-
aria-label={props.label}
|
|
45
|
-
required={props.required}
|
|
46
|
-
name={props.id}
|
|
47
|
-
value={props.value}
|
|
48
|
-
id={props.id}
|
|
49
|
-
className="peer hidden"
|
|
50
|
-
/>
|
|
51
|
-
<button
|
|
52
|
-
type="button"
|
|
53
|
-
role="switch"
|
|
54
|
-
data-state={checked ? "checked" : "unchecked"}
|
|
55
|
-
aria-checked={checked}
|
|
56
|
-
onClick={() => setChecked(v => !v)}
|
|
57
|
-
disabled={props.disabled}
|
|
58
|
-
className={cn(
|
|
59
|
-
sizes[props.size ?? "lg"],
|
|
60
|
-
"rounded-full hover:cursor-pointer",
|
|
61
|
-
"transition transition-all transition-duration-150 ease",
|
|
62
|
-
"data-[state=checked]:bg-black dark:data-[state=checked]:bg-white",
|
|
63
|
-
"data-[state=unchecked]:bg-black/10 dark:data-[state=unchecked]:bg-white/10",
|
|
64
|
-
)}
|
|
65
|
-
>
|
|
66
|
-
<div
|
|
67
|
-
data-state={checked ? "checked" : "unchecked"}
|
|
68
|
-
className={cn(
|
|
69
|
-
thumb_sizes[props.size ?? "lg"],
|
|
70
|
-
"rounded-full",
|
|
71
|
-
"transition transition-all transition-duration-150 ease",
|
|
72
|
-
"bg-white dark:bg-black",
|
|
73
|
-
"data-[state=unchecked]:translate-x-0 data-[state=checked]:translate-x-[100%]",
|
|
74
|
-
)}
|
|
75
|
-
></div>
|
|
76
|
-
</button>
|
|
77
|
-
</>
|
|
78
|
-
)
|
|
79
|
-
}
|
package/globals.css
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
@import "tailwindcss";
|
|
2
|
-
|
|
3
|
-
:root {
|
|
4
|
-
--background: hsl(0 0% 100%);
|
|
5
|
-
/* 100% white */
|
|
6
|
-
--foreground: hsl(0 0% 0%);
|
|
7
|
-
/* 100% black */
|
|
8
|
-
--muted: hsl(0 0% 75%);
|
|
9
|
-
--muted-foreground: hsl(0 0% 50%);
|
|
10
|
-
--outline: oklch(90% 0 0);
|
|
11
|
-
/* 15% black */
|
|
12
|
-
--priority: rgb(64, 64, 64);
|
|
13
|
-
/* 75% black */
|
|
14
|
-
--description: #7f7f7f;
|
|
15
|
-
/* 50% black */
|
|
16
|
-
--disabled: #bfbfbf;
|
|
17
|
-
/* 25% black */
|
|
18
|
-
--light: rgb(236, 236, 242);
|
|
19
|
-
/* 5% black */
|
|
20
|
-
--shadow: rgba(0, 0, 0, 0.1);
|
|
21
|
-
--primary: hsl(0 0% 0%);
|
|
22
|
-
--secondary: hsl(0 0% 95%);
|
|
23
|
-
--red: #f11c42;
|
|
24
|
-
--green: #00bc7a;
|
|
25
|
-
--blue: #4c52f4;
|
|
26
|
-
--purple: #7962f0;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
@media (prefers-color-scheme: dark) {
|
|
30
|
-
:root {
|
|
31
|
-
--background: #000000;
|
|
32
|
-
/* 100% black */
|
|
33
|
-
--foreground: #ffffff;
|
|
34
|
-
/* 100% white */
|
|
35
|
-
--muted: oklch(25% 0 0);
|
|
36
|
-
--muted-foreground: oklch(70% 0 0);
|
|
37
|
-
|
|
38
|
-
--outline: oklch(30% 0 0);
|
|
39
|
-
/* 25% white */
|
|
40
|
-
--priority: rgb(191, 191, 191);
|
|
41
|
-
/* 75% white */
|
|
42
|
-
--description: rgba(255, 255, 255, 0.5);
|
|
43
|
-
--disabled: rgba(255, 255, 255, 0.25);
|
|
44
|
-
--light: rgb(25, 25, 25);
|
|
45
|
-
/* 5% black */
|
|
46
|
-
--shadow: rgba(255, 255, 255, 0.25);
|
|
47
|
-
--primary: #ffffff;
|
|
48
|
-
--secondary: #1a1a1a;
|
|
49
|
-
--red: #f11c42;
|
|
50
|
-
--green: #33c995;
|
|
51
|
-
--blue: #7075f6;
|
|
52
|
-
--purple: #8366f4;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
body {
|
|
57
|
-
background: var(--background);
|
|
58
|
-
color: var(--foreground);
|
|
59
|
-
font-size: 16px;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
button:focus {
|
|
63
|
-
outline: none;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
input:focus {
|
|
67
|
-
outline: none;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
textarea:focus {
|
|
71
|
-
outline: none;
|
|
72
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/{lib → src}/utils.ts
RENAMED
|
File without changes
|