@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.
Files changed (54) hide show
  1. package/README.md +148 -0
  2. package/package.json +35 -0
  3. package/src/components/Accordion.astro +24 -0
  4. package/src/components/AccordionItem.astro +172 -0
  5. package/src/components/Background.astro +75 -0
  6. package/src/components/Badge.astro +140 -0
  7. package/src/components/Bento.astro +37 -0
  8. package/src/components/BentoItem.astro +26 -0
  9. package/src/components/Box.astro +189 -0
  10. package/src/components/Breadcrumb.astro +62 -0
  11. package/src/components/Button.astro +273 -0
  12. package/src/components/Card.astro +228 -0
  13. package/src/components/Container.astro +76 -0
  14. package/src/components/Divider.astro +85 -0
  15. package/src/components/Drawer.astro +139 -0
  16. package/src/components/Flex.astro +150 -0
  17. package/src/components/Flow.astro +119 -0
  18. package/src/components/Grid.astro +335 -0
  19. package/src/components/GridItem.astro +225 -0
  20. package/src/components/Group.astro +106 -0
  21. package/src/components/Image.astro +191 -0
  22. package/src/components/Link.astro +118 -0
  23. package/src/components/List.astro +57 -0
  24. package/src/components/ListItem.astro +31 -0
  25. package/src/components/Mark.astro +161 -0
  26. package/src/components/Marquee.astro +193 -0
  27. package/src/components/Masonry.astro +75 -0
  28. package/src/components/MasonryItem.astro +28 -0
  29. package/src/components/Menu.astro +71 -0
  30. package/src/components/MenuItem.astro +93 -0
  31. package/src/components/NavBar.astro +211 -0
  32. package/src/components/Section.astro +108 -0
  33. package/src/components/Space.astro +400 -0
  34. package/src/components/Stack.astro +237 -0
  35. package/src/components/Text.astro +270 -0
  36. package/src/components/Theme.astro +37 -0
  37. package/src/components/ThemeToggle.astro +141 -0
  38. package/src/components/Title.astro +141 -0
  39. package/src/index.d.ts +80 -0
  40. package/src/index.ts +77 -0
  41. package/src/lib/border.ts +92 -0
  42. package/src/lib/pattern.ts +37 -0
  43. package/src/lib/spacing.ts +48 -0
  44. package/src/styles/border.css +180 -0
  45. package/src/styles/colors.css +99 -0
  46. package/src/styles/global.css +57 -0
  47. package/src/styles/radius.css +22 -0
  48. package/src/styles/shadow.css +11 -0
  49. package/src/styles/spacing/display.css +198 -0
  50. package/src/styles/spacing/gap.css +19 -0
  51. package/src/styles/spacing/margin.css +157 -0
  52. package/src/styles/spacing/padding.css +154 -0
  53. package/src/styles/spacing/spacing.css +2 -0
  54. package/src/types.ts +10 -0
@@ -0,0 +1,106 @@
1
+ ---
2
+ import "../styles/spacing/gap.css";
3
+ import type { Base, Gap } from "../types";
4
+
5
+ type ScreenSize = "sm" | "md" | "lg" | "xl";
6
+
7
+ export interface GroupProps extends Base {
8
+ gap?: Gap;
9
+ grow?: boolean;
10
+ justify?:
11
+ | "start"
12
+ | "center"
13
+ | "end"
14
+ | "space-between"
15
+ | "space-around"
16
+ | "space-evenly";
17
+ not?: ScreenSize | ScreenSize[];
18
+ wrap?: boolean;
19
+ }
20
+
21
+ const {
22
+ class: className,
23
+ justify = "start",
24
+ gap = "md",
25
+ grow = false,
26
+ wrap = false,
27
+ not,
28
+ } = Astro.props as GroupProps;
29
+ const notScreens = typeof not === "string" ? [not] : not;
30
+ ---
31
+
32
+ <div
33
+ class:list={[
34
+ "naut-group",
35
+ grow && "grow",
36
+ wrap && "wrap",
37
+ gap && `gap-${gap}`,
38
+ justify && `justify-${justify}`,
39
+ notScreens?.map((s) => `not-${s}`).join(" "),
40
+ className]}
41
+ >
42
+ <slot />
43
+ </div>
44
+
45
+ <style>
46
+ .naut-group {
47
+ display: inline-flex;
48
+ align-items: center;
49
+
50
+ &.not-sm {
51
+ @media only screen and (max-width: 817px) {
52
+ flex-direction: column;
53
+ }
54
+ }
55
+
56
+ &.not-md {
57
+ @media only screen and (min-width: 818px) and (min-width: 1041px) {
58
+ flex-direction: column;
59
+ }
60
+ }
61
+
62
+ &.not-lg {
63
+ @media only screen and (min-width: 1042px) and (min-width: 1249px) {
64
+ flex-direction: column;
65
+ }
66
+ }
67
+
68
+ &.not-xl {
69
+ @media only screen and (min-width: 1250px) {
70
+ flex-direction: column;
71
+ }
72
+ }
73
+
74
+ &.justify-start {
75
+ justify-content: flex-start;
76
+ }
77
+
78
+ &.justify-center {
79
+ justify-content: center;
80
+ }
81
+
82
+ &.justify-end {
83
+ justify-content: flex-end;
84
+ }
85
+
86
+ &.justify-space-between {
87
+ justify-content: space-between;
88
+ }
89
+
90
+ &.justify-space-around {
91
+ justify-content: space-around;
92
+ }
93
+
94
+ &.justify-space-evenly {
95
+ justify-content: space-evenly;
96
+ }
97
+
98
+ &.grow {
99
+ flex-grow: 1;
100
+ }
101
+
102
+ &.wrap {
103
+ flex-wrap: wrap;
104
+ }
105
+ }
106
+ </style>
@@ -0,0 +1,191 @@
1
+ ---
2
+ import type { Base, Radius } from "../types";
3
+
4
+ export interface ImageProps extends Base {
5
+ alt: string;
6
+ cover?: boolean;
7
+ fluid?: boolean;
8
+ maxHeight?: string;
9
+ maxWidth?: string;
10
+ radius?: Radius;
11
+ ratio?: "1:1" | "16:9" | "4:3" | "3:2" | "2:1" | "9:16 | 3:4" | "2:3" | "1:2";
12
+ responsive?: boolean;
13
+ shadow?: "sm" | "md" | "lg" | "xl";
14
+ src: string;
15
+ [key: string]: unknown;
16
+ }
17
+
18
+ const {
19
+ src,
20
+ alt,
21
+ class: className,
22
+ ratio,
23
+ radius,
24
+ shadow,
25
+ cover = false,
26
+ fluid = false,
27
+ responsive = false,
28
+ maxWidth,
29
+ maxHeight,
30
+ ...rest
31
+ } = Astro.props as ImageProps;
32
+ const ratioName = ratio ? ratio.replace(":", "x") : undefined;
33
+ const imageMaxWidth = maxWidth && !cover ? maxWidth : undefined;
34
+ const imageMaxHeight = maxHeight && !cover ? maxHeight : undefined;
35
+ const imageHeight = maxHeight && !cover ? maxHeight : undefined;
36
+ ---
37
+
38
+ <div
39
+ class:list={[
40
+ "naut-image",
41
+ ratioName && `ratio ratio-${ratioName}`,
42
+ radius && `radius-${radius}`,
43
+ shadow && `shadow-${shadow}`,
44
+ cover && "fit-cover",
45
+ maxHeight && !cover && "fit-height",
46
+ fluid && "fluid",
47
+ responsive && "responsive",
48
+ className
49
+ ]}
50
+ >
51
+ <img src={src} alt={alt} {...rest}>
52
+ </div>
53
+ <style define:vars={{ imageHeight, imageMaxHeight, imageMaxWidth }}>
54
+ .naut-image {
55
+ --radius-scale: 1.575;
56
+ position: relative;
57
+ display: inline-block;
58
+ max-width: var(--imageMaxWidth);
59
+ height: var(--imageHeight);
60
+ max-height: var(--imageMaxHeight);
61
+ overflow: hidden;
62
+ background-color: var(--naut-color-base-100);
63
+
64
+ img {
65
+ display: block;
66
+ width: auto;
67
+ height: auto;
68
+ }
69
+
70
+ &.fit-cover {
71
+ width: 100%;
72
+ height: 100%;
73
+ object-fit: cover;
74
+ img {
75
+ width: 100%;
76
+ height: 100%;
77
+ object-fit: cover;
78
+ }
79
+ }
80
+
81
+ &.fluid:not(.fit-cover) {
82
+ width: 100%;
83
+ img {
84
+ width: 100%;
85
+ }
86
+ }
87
+
88
+ &.responsive:not(.fluid) {
89
+ @media only screen and (max-width: 1041px) {
90
+ width: 100%;
91
+ max-width: 100%;
92
+ height: auto;
93
+ img {
94
+ width: 100%;
95
+ height: auto;
96
+ }
97
+ }
98
+ }
99
+
100
+ &.fit-height:not(.ratio):not(.fit-cover):not(.fluid) {
101
+ width: fit-content;
102
+ max-width: 100%;
103
+ img {
104
+ display: block;
105
+ width: auto;
106
+ max-width: none;
107
+ height: 100%;
108
+ }
109
+ }
110
+
111
+ &.ratio {
112
+ img {
113
+ width: 100%;
114
+ height: 100%;
115
+ object-fit: cover;
116
+ }
117
+ }
118
+
119
+ &.ratio-1x1 {
120
+ aspect-ratio: 1 / 1;
121
+ }
122
+
123
+ &.ratio-16x9 {
124
+ aspect-ratio: 16 / 9;
125
+ }
126
+
127
+ &.ratio-4x3 {
128
+ aspect-ratio: 4 / 3;
129
+ }
130
+
131
+ &.ratio-3x2 {
132
+ aspect-ratio: 3 / 2;
133
+ }
134
+
135
+ &.ratio-2x1 {
136
+ aspect-ratio: 2 / 1;
137
+ }
138
+
139
+ &.ratio-9x16 {
140
+ aspect-ratio: 9 / 16;
141
+ }
142
+
143
+ &.ratio-3x4 {
144
+ aspect-ratio: 3 / 4;
145
+ }
146
+
147
+ &.ratio-2x3 {
148
+ aspect-ratio: 2 / 3;
149
+ }
150
+
151
+ &.ratio-1x2 {
152
+ aspect-ratio: 1 / 2;
153
+ }
154
+
155
+ &.radius-none {
156
+ border-radius: 0;
157
+ }
158
+
159
+ &.radius-sm {
160
+ border-radius: calc(var(--naut-border-radius-sm) * var(--radius-scale));
161
+ }
162
+
163
+ &.radius-md {
164
+ border-radius: calc(var(--naut-border-radius-md) * var(--radius-scale));
165
+ }
166
+
167
+ &.radius-lg {
168
+ border-radius: calc(var(--naut-border-radius-lg) * var(--radius-scale));
169
+ }
170
+
171
+ &.radius-full {
172
+ border-radius: 9999px;
173
+ }
174
+
175
+ &.shadow-sm:not(.cover) {
176
+ box-shadow: var(--naut-shadow-sm);
177
+ }
178
+
179
+ &.shadow-md:not(.cover) {
180
+ box-shadow: var(--naut-shadow-md);
181
+ }
182
+
183
+ &.shadow-lg:not(.cover) {
184
+ box-shadow: var(--naut-shadow-lg);
185
+ }
186
+
187
+ &.shadow-xl:not(.cover) {
188
+ box-shadow: var(--naut-shadow-xl);
189
+ }
190
+ }
191
+ </style>
@@ -0,0 +1,118 @@
1
+ ---
2
+ import type { Base } from "../types";
3
+
4
+ export interface LinkProps extends Base {
5
+ dimmed?: boolean;
6
+ external?: boolean;
7
+ hover?: "underline" | "dimmed" | "surface";
8
+ to: string;
9
+ underline?: boolean;
10
+ wrap?: boolean;
11
+ }
12
+
13
+ const {
14
+ to,
15
+ title,
16
+ dimmed,
17
+ class: className,
18
+ hover = "underline",
19
+ external = false,
20
+ underline = false,
21
+ wrap = false,
22
+ ...rest
23
+ } = Astro.props as LinkProps;
24
+ ---
25
+
26
+ <a
27
+ class:list={[
28
+ "naut-link",
29
+ `hover--${hover}`,
30
+ wrap && "wrap",
31
+ dimmed && "dimmed",
32
+ external && "external",
33
+ underline && "underline",
34
+ className
35
+ ]}
36
+ href={to}
37
+ {...rest}
38
+ >
39
+ <div class="link--wrapper"><slot /></div>
40
+ {external && (
41
+ <svg
42
+ class="lucide lucide-external-link-icon external-link-icon"
43
+ fill="none"
44
+ height="16"
45
+ stroke="currentColor"
46
+ stroke-linecap="round"
47
+ stroke-linejoin="round"
48
+ stroke-width="2"
49
+ viewBox="0 0 24 24"
50
+ width="16"
51
+ xmlns="http://www.w3.org/2000/svg"
52
+ >
53
+ <title>External Link</title>
54
+ <path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/></svg>
55
+ )}
56
+ </a>
57
+ <style>
58
+ .naut-link {
59
+ display: inline-flex;
60
+ flex-wrap: nowrap;
61
+ gap: 0.5rem;
62
+ align-items: center;
63
+ padding: 0.2rem 0.8rem;
64
+ color: var(--naut-color-link);
65
+ text-decoration: none;
66
+
67
+ .link--wrapper {
68
+ display: inline-flex;
69
+ flex-wrap: nowrap;
70
+ gap: 0.5rem;
71
+ align-items: center;
72
+ text-wrap: nowrap;
73
+ }
74
+
75
+ &.wrap {
76
+ flex-wrap: wrap;
77
+
78
+ .link--wrapper {
79
+ flex-wrap: wrap;
80
+ text-wrap: wrap;
81
+ }
82
+ }
83
+
84
+ &.underline {
85
+ text-decoration: underline;
86
+ }
87
+
88
+ &.dimmed {
89
+ opacity: 0.5;
90
+ }
91
+
92
+ &.external {
93
+ gap: 0.3rem;
94
+
95
+ .external-link-icon {
96
+ opacity: 0.5;
97
+ }
98
+ }
99
+
100
+ &:hover {
101
+ &.dimmed {
102
+ opacity: 1;
103
+ }
104
+
105
+ &.hover--underline {
106
+ text-decoration: underline;
107
+ }
108
+
109
+ &.hover--dimmed {
110
+ opacity: 0.5;
111
+ }
112
+
113
+ &.hover--surface {
114
+ background-color: var(--naut-color-base-100);
115
+ }
116
+ }
117
+ }
118
+ </style>
@@ -0,0 +1,57 @@
1
+ ---
2
+ import "../styles/spacing/gap.css";
3
+ import type { Base, Gap } from "../types";
4
+
5
+ export interface ListProps extends Base {
6
+ gap?: Gap;
7
+ horizontal?: boolean;
8
+ marker?: "none" | string;
9
+ noMarker?: boolean;
10
+ ordered?: boolean;
11
+ }
12
+
13
+ const {
14
+ class: className,
15
+ gap = "sm",
16
+ ordered = false,
17
+ horizontal = false,
18
+ marker,
19
+ ...rest
20
+ } = Astro.props as ListProps;
21
+ const markerValue = marker && marker !== "none" ? `"${marker} "` : undefined;
22
+ const classList = [
23
+ "naut-list",
24
+ horizontal && "horizontal",
25
+ marker === "none" && "no-marker",
26
+ gap && `gap-${gap}`,
27
+ className,
28
+ ];
29
+ const spacing = `var(--naut-spacing-${gap})`;
30
+ ---
31
+
32
+ {!ordered && <ul class:list={classList} {...rest}>
33
+ <slot />
34
+ </ul>}
35
+
36
+ {ordered && <ol class:list={classList} {...rest}>
37
+ <slot />
38
+ </ol>}
39
+
40
+ <style define:vars={{ marker: markerValue }}>
41
+ .naut-list {
42
+ display: grid;
43
+ padding-left: var(--naut-spacing-md);
44
+
45
+ &.no-marker {
46
+ padding-left: 0;
47
+ list-style: none;
48
+ }
49
+
50
+ &.horizontal {
51
+ display: flex;
52
+ flex-direction: row;
53
+ gap: calc(var(--naut-spacing) * 1.5);
54
+ padding: 0;
55
+ }
56
+ }
57
+ </style>
@@ -0,0 +1,31 @@
1
+ ---
2
+ import type { Base } from "../types";
3
+
4
+ export interface ListItemProps extends Base {
5
+ marker?: "none" | string;
6
+ }
7
+
8
+ const { class: className, marker, ...rest }: ListItemProps = Astro.props;
9
+
10
+ const markerVar = marker && marker !== "none" ? `"${marker} "` : undefined;
11
+ const itemMarker = markerVar || "var(--marker)"; // marker var from parent
12
+ ---
13
+
14
+ <li
15
+ class:list={[ "naut-list-item", marker === "none" && "no-marker", className]}
16
+ {...rest}
17
+ >
18
+ <slot />
19
+ </li>
20
+
21
+ <style define:vars={{ itemMarker }}>
22
+ li.naut-list-item {
23
+ &:not(.no-marker)::marker {
24
+ content: var(--itemMarker);
25
+ }
26
+
27
+ &.no-marker {
28
+ list-style-type: none;
29
+ }
30
+ }
31
+ </style>
@@ -0,0 +1,161 @@
1
+ ---
2
+ import type { Base } from "../types";
3
+
4
+ export interface MarkProps extends Base {
5
+ gradient?: { colors: string[]; deg?: number };
6
+ rotate?: "sm" | "md" | "lg";
7
+ variant?:
8
+ | "default"
9
+ | "underline"
10
+ | "halflight"
11
+ | "parallelogram"
12
+ | "sketch-circle";
13
+ }
14
+
15
+ const {
16
+ class: className,
17
+ variant,
18
+ rotate,
19
+ gradient,
20
+ ...rest
21
+ } = Astro.props as MarkProps;
22
+ const gradientBg = gradient
23
+ ? `linear-gradient(${gradient.deg || 45}deg, ${gradient.colors.join(", ")})`
24
+ : undefined;
25
+ ---
26
+
27
+ <mark
28
+ class:list={[
29
+ "naut-mark",
30
+ variant && `variant--${variant}`,
31
+ rotate && `rotate--${rotate}`,
32
+ gradient && "gradient",
33
+ className]}
34
+ {...rest}
35
+ >
36
+ <slot />
37
+ </mark>
38
+
39
+ <style define:vars={{ gradientBg }}>
40
+ .naut-mark {
41
+ display: inline-block;
42
+ padding-right: 1rem;
43
+ padding-left: 1rem;
44
+ color: var(--naut-color-content);
45
+ -moz-text-fill-color: var(--naut-color-content);
46
+ -webkit-text-fill-color: var(--naut-color-content);
47
+ background-color: var(--naut-color-highlight);
48
+
49
+ &::selection {
50
+ color: var(--naut-color-content);
51
+ }
52
+
53
+ &.rotate--sm {
54
+ transform: rotate(-1.25deg);
55
+ }
56
+
57
+ &.rotate--md {
58
+ transform: rotate(-1.5deg);
59
+ }
60
+
61
+ &.rotate--lg {
62
+ transform: rotate(-1.95deg);
63
+ }
64
+
65
+ &.variant--underline {
66
+ color: inherit;
67
+ background:
68
+ linear-gradient(120deg, var(--naut-color-highlight) 0 100%) no-repeat
69
+ 18px calc(100% + 4px) / calc(100% - 32px) 0.2em transparent;
70
+ }
71
+
72
+ &.variant--halflight {
73
+ padding: 0 0.3rem;
74
+ color: inherit;
75
+ background:
76
+ linear-gradient(120deg, var(--naut-color-highlight) 0% 100%) no-repeat 0
77
+ 88% / 100% 0.4em transparent;
78
+ }
79
+
80
+ &.variant--parallelogram {
81
+ padding-inline: 1.4rem;
82
+ margin-inline: calc(1.4rem * -1);
83
+ background-color: transparent;
84
+ background-image:
85
+ linear-gradient(
86
+ to bottom right,
87
+ transparent 50%,
88
+ var(--naut-color-highlight) 50%
89
+ ),
90
+ linear-gradient(
91
+ var(--naut-color-highlight),
92
+ var(--naut-color-highlight)
93
+ ),
94
+ linear-gradient(
95
+ to top left,
96
+ transparent 50%,
97
+ var(--naut-color-highlight) 50%
98
+ );
99
+ background-repeat: no-repeat;
100
+ background-position:
101
+ left center,
102
+ center,
103
+ right center;
104
+ background-size:
105
+ 0.25em 1.5em,
106
+ calc(100% - 0.25em * 2 + 1.5px) 1.5em,
107
+ 0.25em 1.5em;
108
+ }
109
+
110
+ &.variant--sketch-circle {
111
+ position: relative;
112
+ color: inherit;
113
+ background-color: transparent;
114
+
115
+ &::before {
116
+ position: absolute;
117
+ top: -0.1em;
118
+ left: -0.5em;
119
+ z-index: -1;
120
+ width: 100%;
121
+ height: 1em;
122
+ padding: 0.1em 0.25em;
123
+ content: "";
124
+ border: 6px solid var(--naut-color-highlight);
125
+ border-right-color: transparent;
126
+ border-radius: 50%;
127
+ transform: rotate(2deg);
128
+ }
129
+
130
+ &::after {
131
+ position: absolute;
132
+ top: 0.1em;
133
+ left: -0.5em;
134
+ z-index: -1;
135
+ width: 100%;
136
+ height: 1em;
137
+ padding: 0.1em 0.25em;
138
+ content: "";
139
+ border: 6px solid var(--naut-color-highlight);
140
+ border-top-color: transparent;
141
+ border-left-color: transparent;
142
+ border-radius: 50%;
143
+ transform: rotate(-2deg);
144
+ }
145
+ }
146
+
147
+ &.gradient {
148
+ color: transparent;
149
+ background-color: transparent;
150
+ background-image: var(--gradientBg);
151
+ -webkit-background-clip: text;
152
+ background-clip: text;
153
+
154
+ &::selection {
155
+ color: var(--naut-color-content);
156
+ background-color: var(--naut-color-selection);
157
+ background-image: none;
158
+ }
159
+ }
160
+ }
161
+ </style>