@nautui/core 0.1.0
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/README.md +148 -0
- package/package.json +35 -0
- package/src/components/Accordion.astro +24 -0
- package/src/components/AccordionItem.astro +172 -0
- package/src/components/Background.astro +75 -0
- package/src/components/Badge.astro +140 -0
- package/src/components/Bento.astro +37 -0
- package/src/components/BentoItem.astro +26 -0
- package/src/components/Box.astro +189 -0
- package/src/components/Breadcrumb.astro +62 -0
- package/src/components/Button.astro +273 -0
- package/src/components/Card.astro +228 -0
- package/src/components/Container.astro +76 -0
- package/src/components/Divider.astro +85 -0
- package/src/components/Drawer.astro +139 -0
- package/src/components/Flex.astro +150 -0
- package/src/components/Flow.astro +119 -0
- package/src/components/Grid.astro +335 -0
- package/src/components/GridItem.astro +225 -0
- package/src/components/Group.astro +106 -0
- package/src/components/Image.astro +191 -0
- package/src/components/Link.astro +118 -0
- package/src/components/List.astro +57 -0
- package/src/components/ListItem.astro +31 -0
- package/src/components/Mark.astro +161 -0
- package/src/components/Marquee.astro +193 -0
- package/src/components/Masonry.astro +75 -0
- package/src/components/MasonryItem.astro +28 -0
- package/src/components/Menu.astro +71 -0
- package/src/components/MenuItem.astro +93 -0
- package/src/components/NavBar.astro +211 -0
- package/src/components/Section.astro +108 -0
- package/src/components/Space.astro +400 -0
- package/src/components/Stack.astro +237 -0
- package/src/components/Text.astro +270 -0
- package/src/components/Theme.astro +37 -0
- package/src/components/ThemeToggle.astro +141 -0
- package/src/components/Title.astro +141 -0
- package/src/index.d.ts +80 -0
- package/src/index.ts +77 -0
- package/src/lib/border.ts +92 -0
- package/src/lib/pattern.ts +37 -0
- package/src/lib/spacing.ts +48 -0
- package/src/styles/border.css +180 -0
- package/src/styles/colors.css +99 -0
- package/src/styles/global.css +57 -0
- package/src/styles/radius.css +22 -0
- package/src/styles/shadow.css +11 -0
- package/src/styles/spacing/display.css +198 -0
- package/src/styles/spacing/gap.css +19 -0
- package/src/styles/spacing/margin.css +157 -0
- package/src/styles/spacing/padding.css +154 -0
- package/src/styles/spacing/spacing.css +2 -0
- package/src/types.ts +10 -0
package/README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Core Components for Naut UI
|
|
2
|
+
|
|
3
|
+
Low-level, reusable building blocks for marketing websites built with Astro.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @nautui/core
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @nautui/core
|
|
11
|
+
# or
|
|
12
|
+
bun add @nautui/core
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
### 1. Add Theme Provider
|
|
18
|
+
|
|
19
|
+
Wrap your layout with the theme provider to enable theming:
|
|
20
|
+
|
|
21
|
+
```astro
|
|
22
|
+
---
|
|
23
|
+
import { Theme } from "@nautui/core";
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
<html lang="en">
|
|
27
|
+
<body>
|
|
28
|
+
<Theme>
|
|
29
|
+
<slot />
|
|
30
|
+
</Theme>
|
|
31
|
+
</body>
|
|
32
|
+
</html>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 2. Use Components
|
|
36
|
+
|
|
37
|
+
```astro
|
|
38
|
+
---
|
|
39
|
+
import { Button, Container, Section, Title, Text } from "@nautui/core";
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
<Section variant="dimmed">
|
|
43
|
+
<Container>
|
|
44
|
+
<Title level={1}>Welcome</Title>
|
|
45
|
+
<Text>Get started with Astro NautUI</Text>
|
|
46
|
+
<Button variant="primary">Get Started</Button>
|
|
47
|
+
</Container>
|
|
48
|
+
</Section>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Components
|
|
52
|
+
|
|
53
|
+
### Theme
|
|
54
|
+
- [x] `Theme` — provider that injects tokens and wires up auto dark mode
|
|
55
|
+
- [x] `ThemeToggle` — button that switches between light and dark, persists choice
|
|
56
|
+
|
|
57
|
+
### Layouts
|
|
58
|
+
- [x] `Container` — center content with padding and max-width
|
|
59
|
+
- [x] `Box` — low-level layout component for spacing, borders, backgrounds
|
|
60
|
+
- [x] `Section` — full-width page section with variants (dimmed, highlight, inverted)
|
|
61
|
+
- [x] `Group` — flex container helper with gap and alignment shortcuts
|
|
62
|
+
- [x] `Grid` — responsive 1–6 column grid with configurable gap
|
|
63
|
+
|
|
64
|
+
### Elements
|
|
65
|
+
- [x] `Button` — link or button with 11 variants (primary, secondary, outline, ghost, destructive, rainbow, …)
|
|
66
|
+
- [x] `Card` — surface container with default, bordered, and flat variants
|
|
67
|
+
- [x] `Divider` — horizontal rule styled with theme tokens
|
|
68
|
+
- [x] `Badge` — small pill label for status, counts, or tags
|
|
69
|
+
- [x] `Image` — responsive image with optional caption
|
|
70
|
+
|
|
71
|
+
### Typography
|
|
72
|
+
- [x] `Title` — semantic h1–h6 with consistent sizing
|
|
73
|
+
- [x] `Text` — body text with size variants
|
|
74
|
+
- [x] `Mark` — `<mark>` styled with highlight color
|
|
75
|
+
- [x] `Link` — themed anchor with hover and focus states
|
|
76
|
+
- [x] `List` — styled ordered and unordered lists
|
|
77
|
+
- [ ] `Quote` — blockquote with themed border
|
|
78
|
+
|
|
79
|
+
### Navigation
|
|
80
|
+
- [x] `Navbar` — horizontal site navigation
|
|
81
|
+
- [x] `Drawer` — off-canvas sidebar for mobile
|
|
82
|
+
- [x] `Breadcrumbs` — hierarchical page links
|
|
83
|
+
|
|
84
|
+
## Dark Mode
|
|
85
|
+
|
|
86
|
+
Dark mode is enabled by default. Disable it with `dark={false}`:
|
|
87
|
+
|
|
88
|
+
```astro
|
|
89
|
+
<Theme dark={false}><slot /></Theme>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Use the toggle for manual switching:
|
|
93
|
+
|
|
94
|
+
```astro
|
|
95
|
+
<ThemeToggle />
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Theming
|
|
99
|
+
|
|
100
|
+
Provide two brand colors, and the palette is derived at runtime using CSS `color-mix()` and OKLCH.
|
|
101
|
+
|
|
102
|
+
### Required Tokens
|
|
103
|
+
|
|
104
|
+
```astro
|
|
105
|
+
<style>
|
|
106
|
+
:root {
|
|
107
|
+
--naut-color-primary: #ffb000; /* must meet ≥ 4.5:1 vs white */
|
|
108
|
+
--naut-color-secondary: #555522; /* must meet ≥ 4.5:1 vs white */
|
|
109
|
+
}
|
|
110
|
+
</style>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Optional Overrides
|
|
114
|
+
|
|
115
|
+
```astro
|
|
116
|
+
<style>
|
|
117
|
+
:root {
|
|
118
|
+
/* Brand colors */
|
|
119
|
+
--naut-color-primary: #ffb000;
|
|
120
|
+
--naut-color-secondary: #555522;
|
|
121
|
+
--naut-color-destructive: #ff2222;
|
|
122
|
+
|
|
123
|
+
/* Tint strengths */
|
|
124
|
+
--naut-tint: 3%;
|
|
125
|
+
--naut-tint-base: 3%;
|
|
126
|
+
--naut-tint-primary: 25%;
|
|
127
|
+
--naut-tint-secondary: 35%;
|
|
128
|
+
--naut-tint-destructive: 10%;
|
|
129
|
+
|
|
130
|
+
/* Typography */
|
|
131
|
+
--naut-font-family: "Inter", sans-serif;
|
|
132
|
+
}
|
|
133
|
+
</style>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
All other tokens (`--naut-color-base`, `--naut-color-text`, `--naut-color-surface`, etc.) are derived automatically.
|
|
137
|
+
|
|
138
|
+
### Browser Support
|
|
139
|
+
|
|
140
|
+
Baseline 2024: Chrome 119+, Safari 16.4+, Firefox 128+.
|
|
141
|
+
|
|
142
|
+
## Icons
|
|
143
|
+
|
|
144
|
+
Recommended: [Lucide Icons](https://lucide.dev/guide/astro/).
|
|
145
|
+
|
|
146
|
+
## License
|
|
147
|
+
|
|
148
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nautui/core",
|
|
3
|
+
"description": "Core components for NautUI",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"author": "Virak Hor",
|
|
6
|
+
"homepage": "https://github.com/viirak/nautui",
|
|
7
|
+
"repository": "https://github.com/viirak/nautui",
|
|
8
|
+
"bugs": "https://github.com/viirak/nautui/issues",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"keywords": [
|
|
11
|
+
"Astro",
|
|
12
|
+
"UI",
|
|
13
|
+
"Components",
|
|
14
|
+
"library",
|
|
15
|
+
"NautUI"
|
|
16
|
+
],
|
|
17
|
+
"main": "./src/index.ts",
|
|
18
|
+
"types": "./src/index.d.ts",
|
|
19
|
+
"files": [
|
|
20
|
+
"src"
|
|
21
|
+
],
|
|
22
|
+
"exports": {
|
|
23
|
+
".": "./src/index.ts"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"peerDependencies": {
|
|
29
|
+
"astro": "^4.0.0 || ^5.0.0"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"lint": "biome check src",
|
|
33
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { Base } from "../types";
|
|
3
|
+
|
|
4
|
+
export interface AccordionProps extends Base {}
|
|
5
|
+
|
|
6
|
+
const { class: className, ...rest } = Astro.props as AccordionProps;
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<div
|
|
10
|
+
class:list={[
|
|
11
|
+
"naut-accordion",
|
|
12
|
+
className
|
|
13
|
+
]}
|
|
14
|
+
{...rest}
|
|
15
|
+
>
|
|
16
|
+
<slot />
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<style>
|
|
20
|
+
.naut-accordion {
|
|
21
|
+
display: flex;
|
|
22
|
+
flex-direction: column;
|
|
23
|
+
}
|
|
24
|
+
</style>
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { Base } from "../types";
|
|
3
|
+
import Text from "./Text.astro";
|
|
4
|
+
|
|
5
|
+
export interface AccordionItemProps extends Base {
|
|
6
|
+
icon?: "chevron" | "plus";
|
|
7
|
+
size?: "md" | "lg" | "xl";
|
|
8
|
+
title: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
title,
|
|
13
|
+
size = "md",
|
|
14
|
+
icon = "plus",
|
|
15
|
+
class: className,
|
|
16
|
+
...rest
|
|
17
|
+
} = Astro.props as AccordionItemProps;
|
|
18
|
+
|
|
19
|
+
const uniqueId = Math.random().toString(36).slice(2, 9);
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
<div
|
|
23
|
+
class:list={[
|
|
24
|
+
"naut-accordion-item",
|
|
25
|
+
`size-${size}`,
|
|
26
|
+
className
|
|
27
|
+
]}
|
|
28
|
+
{...rest}
|
|
29
|
+
>
|
|
30
|
+
<input
|
|
31
|
+
type="radio"
|
|
32
|
+
id={uniqueId}
|
|
33
|
+
name="accordion-group"
|
|
34
|
+
class="accordion-radio"
|
|
35
|
+
hidden
|
|
36
|
+
>
|
|
37
|
+
<label class="accordion-header" for={uniqueId}>
|
|
38
|
+
<Text inline size={size}>{title}</Text>
|
|
39
|
+
<span class:list={["accordion-icon", icon]}></span>
|
|
40
|
+
</label>
|
|
41
|
+
<div class="accordion-content">
|
|
42
|
+
<div class="content-inner"><slot /></div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<style>
|
|
47
|
+
.naut-accordion-item {
|
|
48
|
+
display: block;
|
|
49
|
+
|
|
50
|
+
&::after {
|
|
51
|
+
display: block;
|
|
52
|
+
margin: 0 var(--naut-spacing-sm);
|
|
53
|
+
content: "";
|
|
54
|
+
border-bottom: 1px solid var(--naut-color-border);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
&:last-child::after {
|
|
58
|
+
display: none;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.accordion-header {
|
|
62
|
+
display: flex;
|
|
63
|
+
align-items: center;
|
|
64
|
+
justify-content: space-between;
|
|
65
|
+
padding: var(--naut-spacing-sm);
|
|
66
|
+
cursor: pointer;
|
|
67
|
+
user-select: none;
|
|
68
|
+
background-color: var(--accordion-item-bg);
|
|
69
|
+
|
|
70
|
+
.accordion-icon {
|
|
71
|
+
position: relative;
|
|
72
|
+
display: block;
|
|
73
|
+
margin: 8px;
|
|
74
|
+
opacity: 0.5;
|
|
75
|
+
transition:
|
|
76
|
+
transform 0.3s ease-in-out,
|
|
77
|
+
opacity 0.3s ease-in-out;
|
|
78
|
+
|
|
79
|
+
&.chevron {
|
|
80
|
+
width: 8px;
|
|
81
|
+
height: 8px;
|
|
82
|
+
border-right: var(--naut-border-width-md) solid
|
|
83
|
+
var(--naut-color-content);
|
|
84
|
+
border-bottom: var(--naut-border-width-md) solid
|
|
85
|
+
var(--naut-color-content);
|
|
86
|
+
transform: rotate(45deg); /* Points down */
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
&.plus {
|
|
90
|
+
width: 16px;
|
|
91
|
+
height: 16px;
|
|
92
|
+
|
|
93
|
+
/* Horizontal Base Line (-) */
|
|
94
|
+
&::before {
|
|
95
|
+
position: absolute;
|
|
96
|
+
top: 50%;
|
|
97
|
+
left: 0;
|
|
98
|
+
width: 100%;
|
|
99
|
+
height: var(--naut-border-width-md);
|
|
100
|
+
content: "";
|
|
101
|
+
background-color: var(--naut-color-content);
|
|
102
|
+
transform: translateY(-50%);
|
|
103
|
+
transition: transform 0.3s ease-in-out;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/* Vertical Crossing Line (|) */
|
|
107
|
+
&::after {
|
|
108
|
+
position: absolute;
|
|
109
|
+
top: 0;
|
|
110
|
+
left: 50%;
|
|
111
|
+
width: var(--naut-border-width-md);
|
|
112
|
+
height: 100%;
|
|
113
|
+
content: "";
|
|
114
|
+
background-color: var(--naut-color-content);
|
|
115
|
+
transform: translateX(-50%);
|
|
116
|
+
transition:
|
|
117
|
+
transform 0.3s ease-in-out,
|
|
118
|
+
opacity 0.3s ease-in-out;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.accordion-content {
|
|
125
|
+
max-height: 0;
|
|
126
|
+
overflow: hidden;
|
|
127
|
+
transition: max-height 0.3s ease-in-out;
|
|
128
|
+
|
|
129
|
+
.content-inner {
|
|
130
|
+
padding: var(--naut-spacing-sm);
|
|
131
|
+
padding-top: 0;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.accordion-radio:checked {
|
|
136
|
+
~ .accordion-header {
|
|
137
|
+
.accordion-icon.chevron {
|
|
138
|
+
opacity: 1;
|
|
139
|
+
transform: rotate(-135deg);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.accordion-icon.plus {
|
|
143
|
+
opacity: 1;
|
|
144
|
+
|
|
145
|
+
&::after {
|
|
146
|
+
opacity: 0;
|
|
147
|
+
transform: translateX(-50%) scaleY(0);
|
|
148
|
+
}
|
|
149
|
+
&::before {
|
|
150
|
+
transform: translateY(-50%) rotate(180deg); /* Smooth spin */
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
~ .accordion-content {
|
|
155
|
+
max-height: 400px;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
</style>
|
|
160
|
+
|
|
161
|
+
<script>
|
|
162
|
+
const headers = document.querySelectorAll(".accordion-header");
|
|
163
|
+
for (const header of headers) {
|
|
164
|
+
header.addEventListener("click", (event) => {
|
|
165
|
+
const radio = header.previousElementSibling as HTMLInputElement;
|
|
166
|
+
if (radio?.checked) {
|
|
167
|
+
event.preventDefault(); // Stop default browser lock
|
|
168
|
+
radio.checked = false; // Manually collapse the item
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
</script>
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { getGradientPattern, type PatternProps } from "../lib/pattern";
|
|
3
|
+
|
|
4
|
+
interface GradientProps {
|
|
5
|
+
colors: string[];
|
|
6
|
+
deg?: number;
|
|
7
|
+
type: "linear" | "radial";
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface BackgroundProps {
|
|
11
|
+
color?: string;
|
|
12
|
+
gradient?: GradientProps;
|
|
13
|
+
image?: string;
|
|
14
|
+
opacity?: number;
|
|
15
|
+
pattern?: PatternProps;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const { color, image, pattern, gradient, opacity } =
|
|
19
|
+
Astro.props as BackgroundProps;
|
|
20
|
+
const backgroundColor = color || "transparent";
|
|
21
|
+
const backgroundImage = image ? `url("${image}")` : undefined;
|
|
22
|
+
const backgroundSize = image ? "cover" : undefined;
|
|
23
|
+
const backgroundPosition = image ? "center" : undefined;
|
|
24
|
+
const backgroundRepeat = image ? "no-repeat" : undefined;
|
|
25
|
+
const backgroundOpacity = opacity || 1;
|
|
26
|
+
const backgroundPattern = getGradientPattern(pattern);
|
|
27
|
+
const backgroundGradient = gradient
|
|
28
|
+
? `linear-gradient(${gradient.deg || 45}deg, ${gradient.colors.join(", ")})`
|
|
29
|
+
: undefined;
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
<div class:list={["naut-background"]}>
|
|
33
|
+
{gradient && <div class:list={["naut-background-gradient", gradient.type]}></div>}
|
|
34
|
+
{pattern && <div class:list={["naut-background-pattern", pattern.type]}></div>}
|
|
35
|
+
<slot />
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<style
|
|
39
|
+
define:vars={{
|
|
40
|
+
backgroundColor,
|
|
41
|
+
backgroundImage,
|
|
42
|
+
backgroundSize,
|
|
43
|
+
backgroundPosition,
|
|
44
|
+
backgroundRepeat,
|
|
45
|
+
backgroundOpacity,
|
|
46
|
+
backgroundPattern,
|
|
47
|
+
backgroundGradient
|
|
48
|
+
}}
|
|
49
|
+
>
|
|
50
|
+
.naut-background {
|
|
51
|
+
position: absolute;
|
|
52
|
+
inset: 0;
|
|
53
|
+
z-index: 0;
|
|
54
|
+
background-color: var(--backgroundColor);
|
|
55
|
+
background-image: var(--backgroundImage);
|
|
56
|
+
background-repeat: var(--backgroundRepeat);
|
|
57
|
+
background-position: var(--backgroundPosition);
|
|
58
|
+
background-size: var(--backgroundSize);
|
|
59
|
+
opacity: var(--backgroundOpacity);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.naut-background-pattern {
|
|
63
|
+
position: absolute;
|
|
64
|
+
inset: 0;
|
|
65
|
+
z-index: 2;
|
|
66
|
+
background: var(--backgroundPattern);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.naut-background-gradient {
|
|
70
|
+
position: absolute;
|
|
71
|
+
inset: 0;
|
|
72
|
+
z-index: 1;
|
|
73
|
+
background: var(--backgroundGradient);
|
|
74
|
+
}
|
|
75
|
+
</style>
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { Base, Radius } from "../types";
|
|
3
|
+
|
|
4
|
+
export interface BadgeProps extends Base {
|
|
5
|
+
gradient?: { colors: string[]; textColor: string; deg?: number };
|
|
6
|
+
iconOnly?: boolean;
|
|
7
|
+
outlineColor?: string;
|
|
8
|
+
radius?: Radius | "full";
|
|
9
|
+
size?: "sm" | "md" | "lg";
|
|
10
|
+
solid?: { background: string; color: string };
|
|
11
|
+
variant?: "default" | "solid" | "outline" | "dot" | "flat";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
size = "md",
|
|
16
|
+
solid = { background: "darkorchid", color: "white" },
|
|
17
|
+
gradient,
|
|
18
|
+
radius = "sm",
|
|
19
|
+
variant = "default",
|
|
20
|
+
outlineColor,
|
|
21
|
+
iconOnly = false,
|
|
22
|
+
...rest
|
|
23
|
+
} = Astro.props as BadgeProps;
|
|
24
|
+
|
|
25
|
+
const gradientBg = gradient
|
|
26
|
+
? `linear-gradient(${gradient.deg || 45}deg, ${gradient.colors.join(", ")})`
|
|
27
|
+
: "none";
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
<div
|
|
31
|
+
class:list={[
|
|
32
|
+
"naut-badge",
|
|
33
|
+
`variant--${variant}`,
|
|
34
|
+
`radius--${radius}`,
|
|
35
|
+
`size--${size}`,
|
|
36
|
+
gradient && "color--gradient",
|
|
37
|
+
iconOnly && "icon-only"]}
|
|
38
|
+
{...rest}
|
|
39
|
+
>
|
|
40
|
+
<slot />
|
|
41
|
+
</div>
|
|
42
|
+
<style
|
|
43
|
+
define:vars={{
|
|
44
|
+
solidBackground: solid.background,
|
|
45
|
+
solidColor: solid.color,
|
|
46
|
+
gradientBg,
|
|
47
|
+
gradientColor: gradient?.textColor,
|
|
48
|
+
outlineColor: outlineColor ?? "var(--naut-color-content)",
|
|
49
|
+
outlineBg: outlineColor ? `rgb(from ${outlineColor} r g b / 0.15)` : "transparent",
|
|
50
|
+
}}
|
|
51
|
+
>
|
|
52
|
+
.naut-badge {
|
|
53
|
+
--outline-color: var(--outlineColor);
|
|
54
|
+
display: inline-flex;
|
|
55
|
+
gap: 0.5rem;
|
|
56
|
+
align-items: center;
|
|
57
|
+
justify-content: center;
|
|
58
|
+
text-transform: uppercase;
|
|
59
|
+
text-wrap: nowrap;
|
|
60
|
+
border: 1px solid var(--naut-color-border);
|
|
61
|
+
|
|
62
|
+
&.variant--solid {
|
|
63
|
+
color: var(--solidColor);
|
|
64
|
+
background-color: var(--solidBackground);
|
|
65
|
+
border-color: var(--solidBackground);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
&.color--gradient {
|
|
69
|
+
color: var(--gradientColor);
|
|
70
|
+
background: var(--gradientBg);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
&.variant--outline {
|
|
74
|
+
color: var(--outline-color);
|
|
75
|
+
background-color: var(--outlineBg);
|
|
76
|
+
border: 1px solid var(--outline-color);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
&.variant--flat {
|
|
80
|
+
background-color: var(--naut-color-base-200);
|
|
81
|
+
border: none;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
&.variant--dot {
|
|
85
|
+
&::before {
|
|
86
|
+
display: inline-block;
|
|
87
|
+
width: 0.5rem;
|
|
88
|
+
height: 0.5rem;
|
|
89
|
+
content: "";
|
|
90
|
+
background-color: var(--naut-color-content);
|
|
91
|
+
border-radius: 50%;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
&.radius--sm {
|
|
96
|
+
border-radius: var(--naut-border-radius-sm);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
&.radius--md {
|
|
100
|
+
border-radius: var(--naut-border-radius-md);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
&.radius--lg {
|
|
104
|
+
border-radius: var(--naut-border-radius-lg);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
&.radius--full {
|
|
108
|
+
padding: 0.25rem 0.95rem;
|
|
109
|
+
border-radius: 50rem;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
&.icon-only {
|
|
113
|
+
aspect-ratio: 1 / 1;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
&.size--sm {
|
|
117
|
+
padding: 0.03rem 0.65rem;
|
|
118
|
+
font-size: 0.75rem;
|
|
119
|
+
&.icon-only {
|
|
120
|
+
padding: 0.65rem;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
&.size--md {
|
|
125
|
+
padding: 0.2rem 0.85rem;
|
|
126
|
+
font-size: 0.875rem;
|
|
127
|
+
&.icon-only {
|
|
128
|
+
padding: 0.85rem;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
&.size--lg {
|
|
133
|
+
padding: 0.35rem 1.15rem;
|
|
134
|
+
font-size: 1.125rem;
|
|
135
|
+
&.icon-only {
|
|
136
|
+
padding: 1.15rem;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
</style>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Base } from "../types";
|
|
3
|
+
|
|
4
|
+
export interface BentoProps extends Base {
|
|
5
|
+
columns?: number;
|
|
6
|
+
gap?: string;
|
|
7
|
+
rows?: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const {
|
|
11
|
+
rows = 4,
|
|
12
|
+
columns = 4,
|
|
13
|
+
gap = "1rem",
|
|
14
|
+
class: className,
|
|
15
|
+
...rest
|
|
16
|
+
} = Astro.props as BentoProps;
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
<div class:list={["naut-bento", className]} {...rest}><slot /></div>
|
|
20
|
+
<style define:vars={{ bentoColumns: columns, bentoRows: rows, bentoGap: gap }}>
|
|
21
|
+
.naut-bento {
|
|
22
|
+
--naut-bento-cols: var(--bentoColumns);
|
|
23
|
+
--naut-bento-rows: var(--bentoRows);
|
|
24
|
+
display: grid;
|
|
25
|
+
grid-template-rows: repeat(var(--naut-bento-rows), 1fr);
|
|
26
|
+
grid-template-columns: repeat(var(--naut-bento-cols), 1fr);
|
|
27
|
+
gap: var(--bentoGap);
|
|
28
|
+
aspect-ratio: var(--naut-bento-cols) / var(--naut-bento-rows);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@media screen and (aspect-ratio < 1) {
|
|
32
|
+
.naut-bento {
|
|
33
|
+
--naut-bento-cols: var(--bentoRows);
|
|
34
|
+
--naut-bento-rows: var(--bentoColumns);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
</style>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Base } from "../types";
|
|
3
|
+
|
|
4
|
+
export interface BentoItemProps extends Base {
|
|
5
|
+
col?: number;
|
|
6
|
+
row?: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
row = 1,
|
|
11
|
+
col = 1,
|
|
12
|
+
class: className,
|
|
13
|
+
...rest
|
|
14
|
+
} = Astro.props as BentoItemProps;
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
<div class:list={["naut-bento-item", className]} {...rest}><slot /></div>
|
|
18
|
+
<style define:vars={{ bentoItemRows: row, bentoItemColumns: col }}>
|
|
19
|
+
.naut-bento-item {
|
|
20
|
+
position: relative;
|
|
21
|
+
grid-row: span var(--bentoItemRows);
|
|
22
|
+
grid-column: span var(--bentoItemColumns);
|
|
23
|
+
overflow: hidden;
|
|
24
|
+
background: var(--naut-color-base-100);
|
|
25
|
+
}
|
|
26
|
+
</style>
|