@nattui/react-components 0.0.11 → 0.0.13

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.
@@ -1,248 +0,0 @@
1
- /* ===================================================== */
2
- /* Base */
3
- /* ===================================================== */
4
- .button {
5
- align-items: safe center;
6
- border-color: transparent;
7
- border-style: solid;
8
- border-width: 1px;
9
- column-gap: 8px;
10
- cursor: pointer;
11
- display: flex;
12
- flex-shrink: 0;
13
- font-family: var(--font-sans, sans-serif);
14
- font-size: 14px;
15
- font-weight: 500;
16
- justify-content: safe center;
17
- line-height: 1.5;
18
- outline-color: var(--color-primary-9, #e93d82);
19
- outline-offset: 2px;
20
- outline-style: solid;
21
- outline-width: 0;
22
- overflow: hidden;
23
- position: relative;
24
- transition-duration: 150ms;
25
- transition-property:
26
- background-color, border-color, box-shadow, color, filter, opacity,
27
- translate;
28
- user-select: none;
29
- }
30
-
31
- .button:disabled {
32
- cursor: not-allowed;
33
- opacity: 0.5;
34
- }
35
-
36
- .button:focus-visible {
37
- outline-width: 2px;
38
- }
39
-
40
- .button:enabled[aria-pressed="true"],
41
- .button:enabled:active {
42
- translate: 0 1px;
43
- }
44
-
45
- /* Disable child shadow */
46
- .button:enabled[aria-pressed="true"] > *,
47
- .button:enabled:active > *,
48
- .button:enabled:hover > * {
49
- filter: none !important;
50
- }
51
-
52
- /* Hover */
53
- .button:enabled[aria-pressed="true"],
54
- .button:enabled:active,
55
- .button:enabled:hover {
56
- opacity: 0.85;
57
- }
58
-
59
- /* Button background */
60
- .button:enabled[aria-pressed="true"] > [data-element="button-background"],
61
- .button:enabled:active > [data-element="button-background"],
62
- .button:enabled:hover > [data-element="button-background"] {
63
- opacity: 0;
64
- }
65
-
66
- /* ===================================================== */
67
- /* Icon only */
68
- /* ===================================================== */
69
- .button__icon_only {
70
- padding: 0 !important;
71
- width: var(--size) !important;
72
- }
73
-
74
- /* ===================================================== */
75
- /* Rounded */
76
- /* ===================================================== */
77
- .button__rounded_base {
78
- border-radius: 8px;
79
- }
80
-
81
- .button__rounded_full {
82
- border-radius: 9999px;
83
- }
84
-
85
- /* ===================================================== */
86
- /* Size */
87
- /* ===================================================== */
88
- .button__size_32 {
89
- --size: 32px;
90
- height: var(--size);
91
- padding: 0 8px;
92
- }
93
-
94
- .button__size_36 {
95
- --size: 36px;
96
- height: var(--size);
97
- padding: 0 12px;
98
- }
99
-
100
- .button__size_40 {
101
- --size: 40px;
102
- height: var(--size);
103
- padding: 0 16px;
104
- }
105
-
106
- .button__size_44 {
107
- --size: 44px;
108
- height: var(--size);
109
- padding: 0 20px;
110
- }
111
-
112
- /* ===================================================== */
113
- /* Variant */
114
- /* ===================================================== */
115
- /* Accent */
116
- .button__variant_accent {
117
- background-image: linear-gradient(
118
- to bottom,
119
- var(--color-primary-9, #e93d82),
120
- var(--color-primary-10, #e03177)
121
- );
122
- border-color: var(--color-primary-9, #e93d82);
123
- box-shadow:
124
- inset 0 1px 0 0 rgba(255, 255, 255, 0.25),
125
- inset 0 -1px 0 0 rgba(0, 0, 0, 0.1);
126
- color: var(--color-gray-1, #fdfcfd);
127
- }
128
-
129
- .button__variant_accent:enabled[aria-pressed="true"],
130
- .button__variant_accent:enabled:active {
131
- box-shadow:
132
- inset 0 -1px 0 0 rgba(255, 255, 255, 0.25),
133
- inset 0 1px 0 0 var(--color-primary-11, #d31e66) !important;
134
- }
135
-
136
- /* Ghost */
137
- .button__variant_ghost {
138
- background-color: transparent;
139
- color: var(--color-gray-11, #6f6e77);
140
- }
141
-
142
- .button__variant_ghost:enabled[aria-pressed="true"],
143
- .button__variant_ghost:enabled:active {
144
- background-color: var(--color-gray-5, #e9e8ea) !important;
145
- color: var(--color-gray-12, #1a1523);
146
- }
147
-
148
- .button__variant_ghost:enabled:hover {
149
- background-color: color-mix(
150
- in oklab,
151
- var(--color-gray-5, #e9e8ea) 75%,
152
- transparent
153
- );
154
- color: var(--color-gray-12, #1a1523);
155
- }
156
-
157
- /* Primary */
158
- .button__variant_primary {
159
- background-image: linear-gradient(
160
- to bottom,
161
- color-mix(in oklab, var(--color-gray-12, #1a1523) 90%, transparent),
162
- var(--color-gray-12, #1a1523)
163
- );
164
- border-color: var(--color-gray-12, #1a1523);
165
- box-shadow:
166
- inset 0 1px 0 0 rgba(255, 255, 255, 0.25),
167
- inset 0 -1px 0 0 rgba(0, 0, 0, 0.1);
168
- color: var(--color-gray-1, #fdfcfd);
169
- }
170
-
171
- .button__variant_primary:enabled[aria-pressed="true"],
172
- .button__variant_primary:enabled:active {
173
- box-shadow:
174
- inset 0 -1px 0 0 rgba(255, 255, 255, 0.25),
175
- inset 0 1px 0 0 var(--color-gray-12, #1a1523) !important;
176
- }
177
-
178
- /* Secondary */
179
- .button__variant_secondary {
180
- background-image: linear-gradient(
181
- to bottom,
182
- var(--color-gray-1, #fdfcfd),
183
- var(--color-gray-3, #f4f2f4)
184
- );
185
- border-color: var(--color-gray-6, #e4e2e4);
186
- box-shadow:
187
- inset 0 1px 0 0 rgba(255, 255, 255, 0.25),
188
- inset 0 -1px 0 0 rgba(0, 0, 0, 0.1);
189
- color: var(--color-gray-11, #6f6e77);
190
- }
191
-
192
- .button__variant_secondary:enabled[aria-pressed="true"],
193
- .button__variant_secondary:enabled:active,
194
- .button__variant_secondary:enabled:hover {
195
- border-color: var(--color-gray-8, #c8c7cb);
196
- color: var(--color-gray-12, #1a1523);
197
- }
198
-
199
- .button__variant_secondary:enabled[aria-pressed="true"],
200
- .button__variant_secondary:enabled:active {
201
- box-shadow:
202
- inset 0 -1px 0 0 var(--color-gray-1, #fdfcfd),
203
- inset 0 1px 0 0 rgba(0, 0, 0, 0.1) !important;
204
- }
205
-
206
- /* Group */
207
- .button__variant_accent,
208
- .button__variant_primary,
209
- .button__variant_secondary {
210
- filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.05));
211
- }
212
-
213
- .button__variant_accent > * {
214
- filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.1));
215
- }
216
-
217
- .button__variant_primary > * {
218
- filter: drop-shadow(0 1px 0 rgb(255 255 255 / 0.1));
219
- }
220
-
221
- .button__variant_accent:enabled:active,
222
- .button__variant_accent:enabled:hover,
223
- .button__variant_accent:enabled[aria-pressed="true"],
224
- .button__variant_primary:enabled:active,
225
- .button__variant_primary:enabled:hover,
226
- .button__variant_primary:enabled[aria-pressed="true"],
227
- .button__variant_secondary:enabled:active,
228
- .button__variant_secondary:enabled:hover,
229
- .button__variant_secondary:enabled[aria-pressed="true"] {
230
- box-shadow: inset 0 0 0 0 transparent;
231
- filter: drop-shadow(0 1px 0 transparent);
232
- }
233
-
234
- .button__variant_ghost:enabled:hover,
235
- .button__variant_secondary:enabled:hover {
236
- color: var(--color-gray-12, #1a1523);
237
- }
238
-
239
- /* ===================================================== */
240
- /* Width */
241
- /* ===================================================== */
242
- .button__width_base {
243
- width: max-content;
244
- }
245
-
246
- .button__width_full {
247
- width: 100%;
248
- }
package/src/button.tsx DELETED
@@ -1,104 +0,0 @@
1
- import type { ComponentProps, JSX, ReactNode } from "react"
2
- import { ButtonBackground } from "@/button-background"
3
- import { ButtonSpinner } from "@/button-spinner"
4
- import styles from "@/button.module.css"
5
-
6
- export interface ButtonProps
7
- extends Omit<ComponentProps<"button">, "aria-pressed" | "disabled"> {
8
- iconEnd?: ReactNode
9
- iconOnly?: boolean
10
- iconStart?: ReactNode
11
- isActive?: boolean
12
- isDisabled?: boolean
13
- isFullWidth?: boolean
14
- isLoading?: boolean
15
- isRounded?: boolean
16
- size?: 32 | 36 | 40 | 44
17
- variant?: "accent" | "ghost" | "primary" | "secondary"
18
- }
19
-
20
- type ButtonPropsInternal = ButtonPropsWithIcon | ButtonPropsWithText
21
-
22
- interface ButtonPropsWithIcon extends ButtonProps {
23
- children?: ReactNode
24
- iconEnd?: never
25
- iconOnly: true
26
- iconStart?: never
27
- }
28
-
29
- interface ButtonPropsWithText extends ButtonProps {
30
- children?: string
31
- iconOnly?: false
32
- }
33
-
34
- export function Button(props: ButtonPropsInternal): JSX.Element {
35
- const {
36
- children = "",
37
- className: customClassName = "",
38
- iconEnd = "",
39
- iconOnly = false,
40
- iconStart = "",
41
- isActive = false,
42
- isDisabled = false,
43
- isFullWidth = false,
44
- isLoading = false,
45
- isRounded = false,
46
- size = 36,
47
- type = "button",
48
- variant = "primary",
49
- ...rest
50
- } = props
51
-
52
- const combinedClassName = `
53
- ${BUTTON_CLASS_NAME.BASE}
54
- ${BUTTON_CLASS_NAME.SIZE[size]}
55
- ${BUTTON_CLASS_NAME.VARIANT[variant.toUpperCase() as keyof typeof BUTTON_CLASS_NAME.VARIANT]}
56
- ${isFullWidth ? BUTTON_CLASS_NAME.WIDTH.FULL : BUTTON_CLASS_NAME.WIDTH.BASE}
57
- ${iconOnly ? BUTTON_CLASS_NAME.ICON_ONLY : ""}
58
- ${isRounded ? BUTTON_CLASS_NAME.ROUNDED.FULL : BUTTON_CLASS_NAME.ROUNDED.BASE}
59
- ${customClassName}
60
- `
61
- .replaceAll(/\s+/g, " ")
62
- .trim()
63
-
64
- return (
65
- <button
66
- aria-pressed={isActive}
67
- className={combinedClassName}
68
- disabled={isDisabled || isLoading}
69
- type={type}
70
- {...rest}
71
- >
72
- <ButtonBackground isRounded={isRounded} variant={variant} />
73
- {isLoading && <ButtonSpinner />}
74
- {!isLoading && iconStart}
75
- {iconOnly ? children : <span>{children}</span>}
76
- {!isLoading && iconEnd}
77
- </button>
78
- )
79
- }
80
-
81
- export const BUTTON_CLASS_NAME = {
82
- BASE: styles.button,
83
- ICON_ONLY: styles.button__icon_only,
84
- ROUNDED: {
85
- BASE: styles.button__rounded_base,
86
- FULL: styles.button__rounded_full,
87
- },
88
- SIZE: {
89
- 32: styles.button__size_32,
90
- 36: styles.button__size_36,
91
- 40: styles.button__size_40,
92
- 44: styles.button__size_44,
93
- },
94
- VARIANT: {
95
- ACCENT: styles.button__variant_accent,
96
- GHOST: styles.button__variant_ghost,
97
- PRIMARY: styles.button__variant_primary,
98
- SECONDARY: styles.button__variant_secondary,
99
- },
100
- WIDTH: {
101
- BASE: styles.button__width_base,
102
- FULL: styles.button__width_full,
103
- },
104
- } as const
package/src/index.ts DELETED
@@ -1,3 +0,0 @@
1
- export * from "@/button"
2
- export * from "@/input"
3
- export * from "@/label"
@@ -1,57 +0,0 @@
1
- /* ===================================================== */
2
- /* Base */
3
- /* ===================================================== */
4
- .input {
5
- appearance: none;
6
- background-color: var(--color-gray-1, #fcfcfc);
7
- border-color: var(--color-gray-5, #e0e0e0);
8
- border-radius: 8px;
9
- border-style: solid;
10
- border-width: 1px;
11
- box-shadow: 0 1px rgba(0, 0, 0, 0.05);
12
- color: var(--color-gray-12, #202020);
13
- cursor: text;
14
- font-family: var(--font-sans, sans-serif);
15
- font-size: 14px;
16
- font-weight: 400;
17
- height: 40px;
18
- line-height: 1.5;
19
- outline-color: var(--color-primary-9, #e93d82);
20
- outline-offset: 2px;
21
- outline-style: solid;
22
- outline-width: 0;
23
- padding: 0 12px;
24
- text-decoration: none;
25
- transition-duration: 150ms;
26
- transition-property: background-color, border-color, box-shadow, opacity;
27
- width: 100%;
28
- }
29
-
30
- .input::placeholder {
31
- color: var(--color-gray-9, #8d8d8d);
32
- user-select: none;
33
- }
34
-
35
- .input:disabled {
36
- cursor: not-allowed;
37
- opacity: 0.5;
38
- }
39
-
40
- .input:enabled:active,
41
- .input:enabled:focus,
42
- .input:enabled:hover,
43
- .input:enabled[aria-pressed="true"] {
44
- border-color: var(--color-gray-8, #bbbbbb);
45
- box-shadow: 0 1px transparent;
46
- }
47
-
48
- .input:focus-visible {
49
- outline-width: 2px;
50
- }
51
-
52
- /* ===================================================== */
53
- /* Password */
54
- /* ===================================================== */
55
- .input__password {
56
- font-family: var(--font-mono, monospace);
57
- }
package/src/input.tsx DELETED
@@ -1,49 +0,0 @@
1
- import type { ComponentProps, JSX } from "react"
2
- import styles from "@/input.module.css"
3
-
4
- export interface InputProps
5
- extends Omit<
6
- ComponentProps<"input">,
7
- "aria-pressed" | "disabled" | "readOnly"
8
- > {
9
- isActive?: boolean
10
- isDisabled?: boolean
11
- isReadOnly?: boolean
12
- }
13
-
14
- export function Input(props: InputProps): JSX.Element {
15
- const {
16
- className: customClassName = "",
17
- isActive = false,
18
- isDisabled = false,
19
- isReadOnly = false,
20
- type = "text",
21
- ...rest
22
- } = props
23
-
24
- const isPassword = type === "password"
25
-
26
- const combinedClassName = `
27
- ${INPUT_CLASS_NAME.BASE}
28
- ${isPassword ? INPUT_CLASS_NAME.PASSWORD : ""}
29
- ${customClassName}
30
- `
31
- .replaceAll(/\s+/g, " ")
32
- .trim()
33
-
34
- return (
35
- <input
36
- aria-pressed={isActive}
37
- className={combinedClassName}
38
- disabled={isDisabled}
39
- readOnly={isReadOnly}
40
- type={type}
41
- {...rest}
42
- />
43
- )
44
- }
45
-
46
- export const INPUT_CLASS_NAME = {
47
- BASE: styles.input,
48
- PASSWORD: styles.input__password,
49
- } as const
@@ -1,8 +0,0 @@
1
- /* ===================================================== */
2
- /* Base */
3
- /* ===================================================== */
4
- .label {
5
- color: var(--color-gray-11, #646464);
6
- font-size: 13px;
7
- width: fit-content;
8
- }
package/src/label.tsx DELETED
@@ -1,21 +0,0 @@
1
- import type { ComponentProps, JSX } from "react"
2
- import styles from "@/label.module.css"
3
-
4
- export interface LabelProps extends ComponentProps<"label"> {}
5
-
6
- export function Label(props: LabelProps): JSX.Element {
7
- const { className: customClassName = "", ...rest } = props
8
-
9
- const combinedClassName = `
10
- ${LABEL_CLASS_NAME.BASE}
11
- ${customClassName}
12
- `
13
- .replaceAll(/\s+/g, " ")
14
- .trim()
15
-
16
- return <label className={combinedClassName} {...rest} />
17
- }
18
-
19
- export const LABEL_CLASS_NAME = {
20
- BASE: styles.label,
21
- } as const
package/tsconfig.json DELETED
@@ -1,13 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "baseUrl": ".",
4
- "esModuleInterop": true,
5
- "jsx": "react-jsx",
6
- "lib": ["dom", "esnext"],
7
- "module": "esnext",
8
- "moduleResolution": "bundler",
9
- "paths": {
10
- "@/*": ["src/*"]
11
- }
12
- }
13
- }
package/tsup.config.ts DELETED
@@ -1,13 +0,0 @@
1
- import { defineConfig } from "tsup"
2
-
3
- export default defineConfig({
4
- clean: true,
5
- dts: true,
6
- entry: ["src/index.ts"],
7
- external: ["react", "react-dom"],
8
- format: ["cjs", "esm"],
9
- loader: { ".css": "copy" },
10
- sourcemap: true,
11
- splitting: true,
12
- treeshake: true,
13
- })
@@ -1,15 +1,15 @@
1
1
  /* Base */
2
2
  .button_background {
3
+ position: absolute;
4
+ top: 0;
5
+ right: 0;
3
6
  bottom: 50%;
4
- filter: none !important;
5
7
  left: 0;
8
+ z-index: -1;
6
9
  opacity: 0.2;
7
- position: absolute;
8
- right: 0;
9
- top: 0;
10
+ filter: none !important;
10
11
  transition-duration: inherit;
11
12
  transition-property: opacity;
12
- z-index: -1;
13
13
  }
14
14
 
15
15
  /* Rounded */
@@ -1,9 +1,9 @@
1
1
  .button_spinner {
2
- animation: spinner 1000ms steps(12, end) infinite;
3
- height: var(--size);
4
2
  position: relative;
5
- scale: -1 1;
6
3
  width: var(--size);
4
+ height: var(--size);
5
+ scale: -1 1;
6
+ animation: spinner 1000ms steps(12, end) infinite;
7
7
  }
8
8
 
9
9
  @keyframes spinner {
@@ -13,25 +13,25 @@
13
13
  }
14
14
 
15
15
  .button_spinner > div {
16
- height: calc(var(--size) / 12);
17
- pointer-events: none;
18
16
  position: absolute;
19
- right: 0;
20
17
  top: 50%;
18
+ right: 0;
19
+ width: calc(var(--size) / 2);
20
+ height: calc(var(--size) / 12);
21
+ pointer-events: none;
21
22
  transform-origin: center left;
22
- transition: all 150ms;
23
23
  translate: 0 -50%;
24
- width: calc(var(--size) / 2);
24
+ transition: all 150ms;
25
25
  }
26
26
 
27
27
  .button_spinner > div::after {
28
- background-color: currentColor;
29
- border-radius: 9999px;
30
- content: "";
31
- height: 100%;
32
28
  position: absolute;
33
29
  right: 0;
34
30
  width: 50%;
31
+ height: 100%;
32
+ content: "";
33
+ background-color: currentColor;
34
+ border-radius: 9999px;
35
35
  }
36
36
 
37
37
  .button_spinner > div:nth-child(1) {