@adaptive-sm/astro-ui 0.2.1 → 0.3.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 +7 -7
- package/lib/badge/Badge.astro +27 -0
- package/lib/badge/classesBadge.ts +67 -0
- package/lib/button/Button.astro +17 -27
- package/lib/button/buttonCva.ts +2 -2
- package/lib/button/buttonIconCva.ts +2 -2
- package/lib/button/classesButtonClickAnimation.ts +1 -1
- package/lib/button/classesButtonClickAnimationPush.ts +1 -1
- package/lib/button/classesButtonClickAnimationSquish.ts +1 -1
- package/lib/card/CardWrapper.astro +6 -5
- package/lib/card/classesBorderWrapper.ts +1 -0
- package/lib/card/classesCardWrapper.ts +21 -9
- package/lib/card/classesShadow.ts +5 -0
- package/lib/details/Details.astro +13 -8
- package/lib/dev/TailwindIndicator.astro +2 -2
- package/lib/form/Fieldset.astro +8 -5
- package/lib/generate_demo_list/DemoList.astro +3 -3
- package/lib/generate_demo_list/generateDemoList.ts +2 -2
- package/lib/generate_image_list/generateImageList.ts +3 -3
- package/lib/grid/FeatureGridSection.astro +28 -35
- package/lib/grid/classesGridCols.ts +27 -2
- package/lib/header/PageHeader.astro +25 -0
- package/lib/header/SectionHeader.astro +37 -0
- package/lib/icon/Icon.astro +26 -0
- package/lib/icons/iconGithub.ts +4 -0
- package/lib/icons/iconGoogle.ts +4 -0
- package/lib/icons/iconLinkedin.ts +2 -0
- package/lib/icons/iconNpm.ts +2 -0
- package/lib/icons/iconTelegram.ts +2 -0
- package/lib/icons/iconTrello.ts +2 -0
- package/lib/icons/iconXcom.ts +1 -0
- package/lib/img/Img.astro +8 -5
- package/lib/img/TypedImg.astro +9 -10
- package/lib/img/TypedImgB2.astro +23 -0
- package/lib/layouts/MarkdownPageWrapper.astro +19 -0
- package/lib/layouts/MinimalLayout.astro +23 -16
- package/lib/layouts/parts/ThemeToggle.astro +9 -9
- package/lib/link/LinkButton.astro +18 -19
- package/lib/link/LinkText.astro +10 -7
- package/lib/link/classesTextLink.ts +1 -1
- package/lib/list/BlackBulletPoint.astro +1 -1
- package/lib/list/BlackBulletPoints.astro +7 -7
- package/lib/list/CheckPoint.astro +3 -3
- package/lib/list/CheckPoints.astro +3 -3
- package/lib/list/NumberedList.astro +1 -1
- package/lib/list/Ps.astro +8 -5
- package/lib/list/TextOrLink.astro +3 -9
- package/lib/md/MarkdownDiv.astro +18 -0
- package/lib/modal/Modal.astro +4 -4
- package/lib/modal/ModalButton.astro +24 -11
- package/lib/page/PageCentered.astro +5 -3
- package/lib/page/PageCenteredCard.astro +7 -5
- package/lib/page/classesPageCentered.ts +1 -1
- package/lib/popover/Popover1.astro +4 -4
- package/lib/select/Select.astro +14 -10
- package/lib/table/Table.astro +2 -2
- package/lib/table/TableD.astro +2 -2
- package/lib/table/TableM.astro +2 -2
- package/lib/table/TableMEntry.astro +2 -2
- package/lib/table/tableVisibilityClasses.ts +3 -3
- package/lib/utils/HasId.ts +3 -0
- package/lib/utils/HasSubtitle.ts +4 -0
- package/lib/utils/HasTitle.ts +4 -0
- package/lib/utils/MayHaveButtonVariant.ts +5 -0
- package/lib/utils/MayHaveClass.ts +3 -0
- package/lib/utils/MayHaveIcon.ts +4 -0
- package/lib/utils/MayHaveId.ts +3 -0
- package/lib/utils/MayHaveInnerClass.ts +3 -0
- package/lib/utils/MayHaveSubtitle.ts +4 -0
- package/lib/utils/MayHaveTitle.ts +4 -0
- package/package.json +13 -12
- package/lib/icon/Icon1.astro +0 -21
- package/lib/layouts/MarkdownWrapper.astro +0 -17
- package/lib/utils/bun/BunCmd.ts +0 -7
- package/lib/utils/bun/cryAndTryAgainLater.ts +0 -6
- package/lib/utils/bun/logBunCmd.ts +0 -1
- package/lib/utils/bun/runCmdAsync.ts +0 -44
- package/lib/utils/bun/runCmdLocally.ts +0 -13
- package/lib/utils/obj/objectKeys.ts +0 -21
- package/lib/utils/ran/generateId12.ts +0 -7
- package/lib/utils/ran/generateId3.ts +0 -7
- package/lib/utils/ran/generateId4.ts +0 -7
- package/lib/utils/ran/generateId5.ts +0 -7
- package/lib/utils/ran/generateId6.ts +0 -7
- package/lib/utils/ran/generateId7.ts +0 -7
- package/lib/utils/ran/generateReadableId.ts +0 -35
- package/lib/utils/ran/urlAlphabet32.ts +0 -8
- /package/lib/{layouts/parts → md}/markdown.css +0 -0
- /package/lib/utils/{ui/classArr.ts → classArr.ts} +0 -0
- /package/lib/utils/{ui/classMerge.ts → classMerge.ts} +0 -0
- /package/lib/utils/{ui/isDevEnv.ts → isDevEnv.ts} +0 -0
- /package/lib/utils/{ui/tailwindBreakpoint.ts → tailwindBreakpoint.ts} +0 -0
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ bun add @adaptive-sm/astro-ui
|
|
|
18
18
|
|
|
19
19
|
## Tailwind CSS Configuration
|
|
20
20
|
|
|
21
|
-
To ensure Tailwind scans the library's source files for classes (since components are published as source without a build step), add the following `@source` directive to your project's `src/layouts/
|
|
21
|
+
To ensure Tailwind scans the library's source files for classes (since components are published as source without a build step), add the following `@source` directive to your project's `src/layouts/tailwind.css` (or equivalent global stylesheet):
|
|
22
22
|
|
|
23
23
|
```css
|
|
24
24
|
@source '/node_modules/@adaptive-sm/astro-ui/lib/**/*.{astro,html,md,mdx,ts,tsx}';
|
|
@@ -38,7 +38,7 @@ In your `tsconfig.json`, set up the `~` alias to point to the library:
|
|
|
38
38
|
"baseUrl": ".",
|
|
39
39
|
"paths": {
|
|
40
40
|
"@/*": ["src/*"],
|
|
41
|
-
"
|
|
41
|
+
"~ui/*": ["node_modules/@adaptive-sm/astro-ui/lib/*"]
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
}
|
|
@@ -81,7 +81,7 @@ Import and use components directly in your Astro files. For example:
|
|
|
81
81
|
|
|
82
82
|
```astro
|
|
83
83
|
---
|
|
84
|
-
import { Button } from "
|
|
84
|
+
import { Button } from "~ui/button/Button.astro"
|
|
85
85
|
---
|
|
86
86
|
|
|
87
87
|
<Button variant="primary">Click me</Button>
|
|
@@ -91,7 +91,7 @@ import { Button } from "~/button/Button.astro"
|
|
|
91
91
|
|
|
92
92
|
```astro
|
|
93
93
|
---
|
|
94
|
-
import { CardWrapper } from "
|
|
94
|
+
import { CardWrapper } from "~ui/card/CardWrapper.astro"
|
|
95
95
|
---
|
|
96
96
|
|
|
97
97
|
<CardWrapper> Card content here. </CardWrapper>
|
|
@@ -101,7 +101,7 @@ import { CardWrapper } from "~/card/CardWrapper.astro"
|
|
|
101
101
|
|
|
102
102
|
```astro
|
|
103
103
|
---
|
|
104
|
-
import { Img } from "
|
|
104
|
+
import { Img } from "~ui/img/Img.astro"
|
|
105
105
|
---
|
|
106
106
|
|
|
107
107
|
<Img src="/path/to/image.jpg" alt="Description" />
|
|
@@ -130,7 +130,7 @@ Refer to individual component documentation in the source code for props and var
|
|
|
130
130
|
|
|
131
131
|
### Icons
|
|
132
132
|
|
|
133
|
-
- [
|
|
133
|
+
- [Icon.astro](lib/icon/Icon.astro) (replaces SVG icons)
|
|
134
134
|
|
|
135
135
|
usage:
|
|
136
136
|
|
|
@@ -153,7 +153,7 @@ usage:
|
|
|
153
153
|
### Layouts
|
|
154
154
|
|
|
155
155
|
- [MinimalLayout.astro](lib/layouts/MinimalLayout.astro)
|
|
156
|
-
- [
|
|
156
|
+
- [MarkdownPageWrapper.astro](lib/layouts/MarkdownPageWrapper.astro)
|
|
157
157
|
|
|
158
158
|
### Navigation bar
|
|
159
159
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types"
|
|
3
|
+
import { type BadgeVariant, badgeCva, badgeIconCva, badgeVariant } from "~ui/badge/classesBadge"
|
|
4
|
+
import Icon from "~ui/icon/Icon.astro"
|
|
5
|
+
import type { MayHaveClass } from "~ui/utils/MayHaveClass"
|
|
6
|
+
|
|
7
|
+
interface Props extends MayHaveClass {
|
|
8
|
+
id?: string
|
|
9
|
+
variant?: BadgeVariant
|
|
10
|
+
|
|
11
|
+
icon?: string
|
|
12
|
+
iconRight?: string
|
|
13
|
+
iconClass?: string
|
|
14
|
+
|
|
15
|
+
class?: string
|
|
16
|
+
restProps?: HTMLAttributes<"svg">
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const p = Astro.props
|
|
20
|
+
const v = p.variant ?? badgeVariant.outline
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
<span id={p.id} class={badgeCva(v, p.class)} {...p.restProps}>
|
|
24
|
+
{p.icon && <Icon path={p.icon} class={badgeIconCva(v, p.iconClass)} />}
|
|
25
|
+
<slot />
|
|
26
|
+
{p.iconRight && <Icon path={p.iconRight} class={badgeIconCva(v, p.iconClass)} />}
|
|
27
|
+
</span>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { classArr } from "~ui/utils/classArr"
|
|
2
|
+
import { classMerge } from "~ui/utils/classMerge"
|
|
3
|
+
|
|
4
|
+
export type BadgeVariant = keyof typeof badgeVariant
|
|
5
|
+
|
|
6
|
+
export const badgeVariant = {
|
|
7
|
+
base: "base",
|
|
8
|
+
contrast: "contrast",
|
|
9
|
+
outline: "outline",
|
|
10
|
+
} as const
|
|
11
|
+
|
|
12
|
+
export const classesBadgeBase = classArr(
|
|
13
|
+
"inline-flex items-center", // layout
|
|
14
|
+
"text-sm", // text
|
|
15
|
+
"px-2.5 py-0.5 rounded-full", // padding
|
|
16
|
+
"flex gap-2", // layout children
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
export const classesBadgeContrast = classArr(
|
|
20
|
+
classesBadgeBase,
|
|
21
|
+
"text-white dark:text-slate-900 dark:hover:text-slate-900", // text
|
|
22
|
+
"bg-slate-900 dark:bg-slate-50", // bg
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
export const classesBadgeOutline = classArr(
|
|
26
|
+
classesBadgeBase,
|
|
27
|
+
"border border-gray-400 dark:border-gray-500", // border
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
export const classesBadgeVariant = {
|
|
31
|
+
base: classesBadgeBase,
|
|
32
|
+
contrast: classesBadgeContrast,
|
|
33
|
+
outline: classesBadgeOutline,
|
|
34
|
+
} as const satisfies Record<BadgeVariant, string>
|
|
35
|
+
|
|
36
|
+
export function badgeCva(v: BadgeVariant, classes?: string): string {
|
|
37
|
+
return classMerge(classesBadgeVariant[v ?? badgeVariant.base], classes)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const classesTextFillBlack = "text-black fill-black"
|
|
41
|
+
const classesTextFillWhite = "text-white fill-white"
|
|
42
|
+
|
|
43
|
+
const classesBlackWhite = classArr(
|
|
44
|
+
classesTextFillBlack,
|
|
45
|
+
"dark:text-white", // dark text
|
|
46
|
+
"dark:fill-white", // dark fill
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
const classesWhiteWhite = classArr(
|
|
50
|
+
classesTextFillWhite,
|
|
51
|
+
"dark:text-white", // dark text
|
|
52
|
+
"dark:fill-white", // dark fill
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
const baseClasses = classArr(
|
|
56
|
+
"size-6", // size
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
const badgeIconClasses = {
|
|
60
|
+
base: classesBlackWhite,
|
|
61
|
+
outline: classesBlackWhite,
|
|
62
|
+
contrast: classArr(classesTextFillWhite, "dark:text-black dark:fill-black"),
|
|
63
|
+
} as const satisfies Record<BadgeVariant, string>
|
|
64
|
+
|
|
65
|
+
export function badgeIconCva(variant: BadgeVariant, classes?: string) {
|
|
66
|
+
return classMerge(baseClasses, badgeIconClasses[variant], classes)
|
|
67
|
+
}
|
package/lib/button/Button.astro
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import
|
|
2
|
+
import type { HTMLAttributes } from "astro/types"
|
|
3
|
+
import { buttonCva2, type ButtonSize, type ButtonVariant } from "~ui/button/buttonCva"
|
|
4
|
+
import { buttonIconCva } from "~ui/button/buttonIconCva"
|
|
5
|
+
import { classesButtonClickAnimation } from "~ui/button/classesButtonClickAnimation"
|
|
6
|
+
import Icon from "~ui/icon/Icon.astro"
|
|
7
|
+
import { classMerge } from "~ui/utils/classMerge"
|
|
7
8
|
|
|
8
9
|
interface Props {
|
|
9
10
|
id?: string
|
|
@@ -18,41 +19,30 @@ interface Props {
|
|
|
18
19
|
iconRight?: string
|
|
19
20
|
iconClass?: string
|
|
20
21
|
class?: string
|
|
21
|
-
|
|
22
|
+
restProps?: HTMLAttributes<"button">
|
|
22
23
|
}
|
|
23
|
-
const
|
|
24
|
+
const p = Astro.props
|
|
24
25
|
|
|
25
|
-
const classes = buttonCva2(
|
|
26
|
+
const classes = buttonCva2(p.variant, p.size, classesButtonClickAnimation, p.class)
|
|
26
27
|
const hasChildren = Astro.slots.has("default")
|
|
27
|
-
const hasContent = hasChildren ||
|
|
28
|
+
const hasContent = hasChildren || p.text
|
|
28
29
|
---
|
|
29
30
|
|
|
30
|
-
<button id={
|
|
31
|
+
<button id={p.id} title={p.title} class={classes} {...p.restProps}>
|
|
32
|
+
{p.icon && <Icon path={p.icon} class={classMerge(hasContent && "mr-2", buttonIconCva(p.variant, p.iconClass))} />}
|
|
31
33
|
{
|
|
32
|
-
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
class={classMerge(hasContent && "mr-2", buttonIconCva(props.variant, props.iconClass))}
|
|
36
|
-
/>
|
|
37
|
-
)
|
|
38
|
-
}
|
|
39
|
-
{
|
|
40
|
-
props.text && (
|
|
41
|
-
<span id={props.contentId} class={props.contentClass}>
|
|
42
|
-
{props.text}
|
|
34
|
+
p.text && (
|
|
35
|
+
<span id={p.contentId} class={p.contentClass}>
|
|
36
|
+
{p.text}
|
|
43
37
|
</span>
|
|
44
38
|
)
|
|
45
39
|
}
|
|
46
40
|
{
|
|
47
41
|
hasContent && (
|
|
48
|
-
<span id={
|
|
42
|
+
<span id={p.contentId} class={p.contentClass}>
|
|
49
43
|
<slot />
|
|
50
44
|
</span>
|
|
51
45
|
)
|
|
52
46
|
}
|
|
53
|
-
{
|
|
54
|
-
props.iconRight && (
|
|
55
|
-
<Icon1 path={props.iconRight} class={buttonIconCva(props.variant, hasContent && "ml-2", props.iconClass)} />
|
|
56
|
-
)
|
|
57
|
-
}
|
|
47
|
+
{p.iconRight && <Icon path={p.iconRight} class={buttonIconCva(p.variant, hasContent && "ml-2", p.iconClass)} />}
|
|
58
48
|
</button>
|
package/lib/button/buttonCva.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { classArr } from "
|
|
2
|
-
import { classMerge } from "
|
|
1
|
+
import { classArr } from "~ui/utils/classArr"
|
|
2
|
+
import { classMerge } from "~ui/utils/classMerge"
|
|
3
3
|
import { classesButtonClickAnimation } from "./classesButtonClickAnimation"
|
|
4
4
|
import { classesButtonDisabled } from "./classesButtonDisabled"
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { classArr } from "
|
|
2
|
-
import { classMerge } from "
|
|
1
|
+
import { classArr } from "~ui/utils/classArr"
|
|
2
|
+
import { classMerge } from "~ui/utils/classMerge"
|
|
3
3
|
import { type ButtonVariant } from "./buttonCva"
|
|
4
4
|
|
|
5
5
|
const classesTextFillBlack = "text-black fill-black"
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
---
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { classMerge } from "
|
|
2
|
+
import type { HTMLAttributes } from "astro/types"
|
|
3
|
+
import { classesCardWrapperP4 } from "~ui/card/classesCardWrapper"
|
|
4
|
+
import { classMerge } from "~ui/utils/classMerge"
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
7
|
-
id?:string
|
|
7
|
+
id?: string
|
|
8
8
|
class?: string
|
|
9
|
+
restProps?: HTMLAttributes<"div">
|
|
9
10
|
}
|
|
10
11
|
const p = Astro.props
|
|
11
12
|
---
|
|
12
13
|
|
|
13
|
-
<div id={p.id} class={classMerge(classesCardWrapperP4, p.class)}>
|
|
14
|
+
<div id={p.id} class={classMerge(classesCardWrapperP4, p.class)} {...p.restProps}>
|
|
14
15
|
<slot />
|
|
15
16
|
</div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const classesBorderWrapper = "border border-gray-500 rounded-xl"
|
|
@@ -1,16 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { classesShadowMdLg } from "~ui/card/classesShadow"
|
|
2
|
+
import { classArr } from "~ui/utils/classArr"
|
|
3
|
+
|
|
4
|
+
export const classesCardWrapperBorderDark = "dark:border dark:border-gray-500"
|
|
5
|
+
export const classesCardWrapperBg = "bg-white dark:bg-zinc-800"
|
|
2
6
|
|
|
3
7
|
export const classesCardWrapper = classArr(
|
|
4
|
-
"rounded-lg
|
|
5
|
-
|
|
8
|
+
"rounded-lg",
|
|
9
|
+
classesShadowMdLg, // card shadows/padding
|
|
10
|
+
classesCardWrapperBg, // bg
|
|
11
|
+
classesCardWrapperBorderDark, // border
|
|
6
12
|
)
|
|
7
13
|
|
|
8
|
-
export const
|
|
9
|
-
export const
|
|
14
|
+
export const classesPadding4Lg8 = "p-4 lg:p-8"
|
|
15
|
+
export const classesPadding4sm8 = "p-4 sm:p-8"
|
|
16
|
+
export const classesPadding4sm8md12 = "p-4 sm:p-8 md:p-12"
|
|
17
|
+
|
|
18
|
+
export const classesCardWrapperP4 = classArr(classesCardWrapper, classesPadding4Lg8)
|
|
19
|
+
export const classesCardWrapperP8 = classArr(classesCardWrapper, classesPadding4sm8)
|
|
20
|
+
|
|
21
|
+
export const classesRoundedShadowXl = "rounded-xl shadow-xl"
|
|
10
22
|
|
|
11
23
|
export const classesCardWrapperPage = classArr(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
24
|
+
classesRoundedShadowXl, // rounded border + shadow
|
|
25
|
+
classesPadding4sm8md12, // padding
|
|
26
|
+
classesCardWrapperBg, // bg
|
|
27
|
+
classesCardWrapperBorderDark, // border
|
|
16
28
|
)
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
import
|
|
3
|
-
import { classArr } from "
|
|
4
|
-
import { classMerge } from "
|
|
2
|
+
import Icon from "~ui/icon/Icon.astro"
|
|
3
|
+
import { classArr } from "~ui/utils/classArr"
|
|
4
|
+
import { classMerge } from "~ui/utils/classMerge"
|
|
5
5
|
import { mdiChevronDown } from "@mdi/js"
|
|
6
|
+
import type { HTMLAttributes } from "astro/types"
|
|
6
7
|
|
|
7
8
|
interface Props {
|
|
8
9
|
icon?: string
|
|
@@ -10,6 +11,8 @@ interface Props {
|
|
|
10
11
|
subtitle?: string
|
|
11
12
|
class?: string
|
|
12
13
|
summaryClass?: string
|
|
14
|
+
restProps?: HTMLAttributes<"details">
|
|
15
|
+
summaryProps?: HTMLAttributes<"summary">
|
|
13
16
|
}
|
|
14
17
|
const p = Astro.props
|
|
15
18
|
const icon = p.icon
|
|
@@ -27,6 +30,7 @@ const hasSummary = Astro.slots.has("summary")
|
|
|
27
30
|
"overflow-hidden",
|
|
28
31
|
p.class,
|
|
29
32
|
)}
|
|
33
|
+
{...p.restProps}
|
|
30
34
|
>
|
|
31
35
|
<summary
|
|
32
36
|
class={classArr(
|
|
@@ -35,20 +39,21 @@ const hasSummary = Astro.slots.has("summary")
|
|
|
35
39
|
"cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors",
|
|
36
40
|
p.summaryClass,
|
|
37
41
|
)}
|
|
42
|
+
{...p.summaryProps}
|
|
38
43
|
>
|
|
39
44
|
{
|
|
40
45
|
!hasSummary && title && (
|
|
41
46
|
<>
|
|
42
|
-
{icon && <
|
|
43
|
-
<
|
|
47
|
+
{icon && <Icon path={icon} class="size-7 mt-1" />}
|
|
48
|
+
<span class="flex-1">
|
|
44
49
|
<h3 class={"text-xl font-semibold"}>{title}</h3>
|
|
45
|
-
{subtitle && <
|
|
46
|
-
</
|
|
50
|
+
{subtitle && <span class={"text-muted-foreground mt-1"}>{subtitle}</span>}
|
|
51
|
+
</span>
|
|
47
52
|
</>
|
|
48
53
|
)
|
|
49
54
|
}
|
|
50
55
|
<slot name="summary" />
|
|
51
|
-
<
|
|
56
|
+
<Icon
|
|
52
57
|
path={mdiChevronDown}
|
|
53
58
|
class={classArr("size-7", "text-gray-400 dark:text-gray-600", "transition-transform group-open:rotate-180")}
|
|
54
59
|
/>
|
package/lib/form/Fieldset.astro
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types"
|
|
2
3
|
import { classesFieldset } from "./classesFieldset"
|
|
3
|
-
import { classMerge } from "
|
|
4
|
+
import { classMerge } from "~ui/utils/classMerge"
|
|
4
5
|
|
|
5
6
|
interface Props {
|
|
6
7
|
title: string
|
|
@@ -8,13 +9,15 @@ interface Props {
|
|
|
8
9
|
subtitles?: string | string[]
|
|
9
10
|
subtitleClass?: string
|
|
10
11
|
class?: string
|
|
12
|
+
restProps?: HTMLAttributes<"fieldset">
|
|
13
|
+
legendProps?: HTMLAttributes<"legend">
|
|
11
14
|
}
|
|
12
|
-
const
|
|
15
|
+
const p = Astro.props
|
|
13
16
|
---
|
|
14
17
|
|
|
15
|
-
<fieldset class={classMerge(classesFieldset,
|
|
16
|
-
<legend class={classMerge("px-1",
|
|
17
|
-
{
|
|
18
|
+
<fieldset class={classMerge(classesFieldset, p.class)} {...p.restProps}>
|
|
19
|
+
<legend class={classMerge("px-1", p.titleClass)} {...p.legendProps}>
|
|
20
|
+
{p.title}
|
|
18
21
|
<!--{props.subtitles && <PopoverI title={props.title} points={props.subtitles} />}-->
|
|
19
22
|
</legend>
|
|
20
23
|
<slot />
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
|
-
import { classesTextLink } from "
|
|
3
|
-
import { classArr } from "
|
|
2
|
+
import { classesTextLink } from "~ui/link/classesTextLink"
|
|
3
|
+
import { classArr } from "~ui/utils/classArr"
|
|
4
4
|
import { type DemoListType } from "./DemoListType"
|
|
5
|
-
import { classMerge } from "
|
|
5
|
+
import { classMerge } from "~ui/utils/classMerge"
|
|
6
6
|
|
|
7
7
|
interface Props {
|
|
8
8
|
demos: DemoListType
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readdir, writeFile } from "node:fs/promises"
|
|
2
2
|
import { join } from "node:path"
|
|
3
|
-
import { runCmdAsync } from "
|
|
3
|
+
import { runCmdAsync } from "~utils/bun/runCmdAsync"
|
|
4
4
|
import type { DemoListType } from "./DemoListType"
|
|
5
5
|
|
|
6
6
|
export async function generateDemoList(demosPath: string, outputPath: string) {
|
|
@@ -20,7 +20,7 @@ export async function generateDemoList(demosPath: string, outputPath: string) {
|
|
|
20
20
|
}
|
|
21
21
|
sortDemoPageList(demoPageList)
|
|
22
22
|
|
|
23
|
-
const outputContent = `import type { DemoListType } from "
|
|
23
|
+
const outputContent = `import type { DemoListType } from "~ui/generate_demo_list/DemoListType"
|
|
24
24
|
|
|
25
25
|
export const demoList = ${JSON.stringify(demoPageList, null, 2)} satisfies DemoListType;
|
|
26
26
|
`
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import imageSize from "image-size"
|
|
2
2
|
import { promises as fs } from "node:fs"
|
|
3
3
|
import path from "node:path"
|
|
4
|
-
import type { ImageType } from "
|
|
5
|
-
import { runCmdAsync } from "
|
|
4
|
+
import type { ImageType } from "~ui/img/ImageType"
|
|
5
|
+
import { runCmdAsync } from "~utils/bun/runCmdAsync"
|
|
6
6
|
|
|
7
7
|
const IMAGE_EXTENSIONS = new Set([".jpg", ".jpeg", ".png", ".gif", ".webp", ".avif", ".tiff", ".svg"])
|
|
8
8
|
|
|
@@ -42,7 +42,7 @@ export async function generateImageList(
|
|
|
42
42
|
|
|
43
43
|
async function writeGeneratedImagesFile(imageMap: Record<string, ImageType>, outputPath: string): Promise<void> {
|
|
44
44
|
const outputContent = `
|
|
45
|
-
import type { ImageType } from "
|
|
45
|
+
import type { ImageType } from "~ui/img/ImageType"
|
|
46
46
|
// Auto-generated, manual changes will be lost
|
|
47
47
|
export const imageList = ${JSON.stringify(imageMap, null, 2)} as const satisfies Record<string, ImageType>;
|
|
48
48
|
`
|
|
@@ -1,39 +1,52 @@
|
|
|
1
1
|
---
|
|
2
|
-
import
|
|
3
|
-
import { classArr } from "
|
|
2
|
+
import Icon from "~ui/icon/Icon.astro"
|
|
3
|
+
import { classArr } from "~ui/utils/classArr"
|
|
4
4
|
import { mdiLink } from "@mdi/js"
|
|
5
5
|
import type { GridFeatureType } from "./GridFeatureType"
|
|
6
|
-
import { classMerge } from "
|
|
6
|
+
import { classMerge } from "~ui/utils/classMerge"
|
|
7
|
+
import type { HTMLAttributes } from "astro/types"
|
|
8
|
+
import type { CssProperties } from "node_modules/astro/dist/assets/fonts/definitions"
|
|
9
|
+
import { classesShadowMdLg } from "~ui/card/classesShadow"
|
|
7
10
|
|
|
8
11
|
interface Props {
|
|
9
12
|
id: string
|
|
10
13
|
title: string
|
|
14
|
+
titleClass?: string
|
|
11
15
|
subtitle1: string
|
|
16
|
+
subtitle1Class?: string
|
|
12
17
|
subtitle2?: string
|
|
18
|
+
subtitle2Class?: string
|
|
13
19
|
features: GridFeatureType[]
|
|
14
20
|
class?: string
|
|
21
|
+
headerClass?: string
|
|
15
22
|
gridClass?: string
|
|
16
23
|
cardClass?: string
|
|
24
|
+
restProps?: HTMLAttributes<"section">
|
|
25
|
+
style?: CssProperties
|
|
17
26
|
}
|
|
18
27
|
const p = Astro.props
|
|
19
28
|
---
|
|
20
29
|
|
|
21
|
-
<section id={p.id} class={classMerge("w-full", "py-25 px-4", p.class)}>
|
|
22
|
-
<div class={classArr("max-w-7xl mx-auto", "text-center mb-8")}>
|
|
30
|
+
<section id={p.id} class={classMerge("w-full", "py-25 px-4", p.class)} style={p.style} {...p.restProps}>
|
|
31
|
+
<div class={classArr("max-w-7xl mx-auto", "text-center mb-8", p.headerClass)}>
|
|
23
32
|
<h2 class={classArr("text-3xl sm:text-4xl font-bold", "mb-4", "group flex items-center justify-center")}>
|
|
24
33
|
<span>{p.title}</span>
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
class="opacity-0 group-hover:opacity-100
|
|
28
|
-
title="
|
|
34
|
+
<a
|
|
35
|
+
href={"#" + p.id}
|
|
36
|
+
class="opacity-0 group-hover:opacity-100 p-1 rounded hidden sm:flex"
|
|
37
|
+
title="Link to this section"
|
|
29
38
|
>
|
|
30
|
-
<
|
|
31
|
-
</
|
|
39
|
+
<Icon path={mdiLink} class="size-6 fill-gray-500 dark:fill-gray-500" />
|
|
40
|
+
</a>
|
|
32
41
|
</h2>
|
|
33
|
-
<p class="text-xl text-muted-foreground mx-auto">
|
|
42
|
+
<p class={classMerge("text-xl text-muted-foreground mx-auto", p.subtitle1Class)}>
|
|
34
43
|
{p.subtitle1}
|
|
35
44
|
</p>
|
|
36
|
-
{
|
|
45
|
+
{
|
|
46
|
+
p.subtitle2 && (
|
|
47
|
+
<p class={classMerge("text-xl text-muted-foreground mx-auto mt-1", p.subtitle2Class)}>{p.subtitle2}</p>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
37
50
|
</div>
|
|
38
51
|
|
|
39
52
|
<div class={classMerge("grid md:grid-cols-2 lg:grid-cols-3 gap-8", "max-w-7xl mx-auto", p.gridClass)}>
|
|
@@ -44,12 +57,12 @@ const p = Astro.props
|
|
|
44
57
|
"bg-white dark:bg-gray-800", // bg
|
|
45
58
|
"rounded-lg p-6", // padding
|
|
46
59
|
// "border", // border
|
|
47
|
-
|
|
60
|
+
classesShadowMdLg,
|
|
48
61
|
p.cardClass,
|
|
49
62
|
)}
|
|
50
63
|
>
|
|
51
64
|
<div class="flex items-center gap-3 mb-4">
|
|
52
|
-
<
|
|
65
|
+
<Icon path={feature.icon} class="size-8" />
|
|
53
66
|
<h3 class="text-xl font-semibold">{feature.title}</h3>
|
|
54
67
|
</div>
|
|
55
68
|
<p class="text-muted-foreground">{feature.description}</p>
|
|
@@ -58,23 +71,3 @@ const p = Astro.props
|
|
|
58
71
|
}
|
|
59
72
|
</div>
|
|
60
73
|
</section>
|
|
61
|
-
|
|
62
|
-
<script>
|
|
63
|
-
declare global {
|
|
64
|
-
interface Window {
|
|
65
|
-
copyLink?: (id: string) => void
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
window.copyLink = function (id: string) {
|
|
69
|
-
const url = window.location.href.split("#")[0] + "#" + id
|
|
70
|
-
navigator.clipboard
|
|
71
|
-
.writeText(url)
|
|
72
|
-
.then(() => {
|
|
73
|
-
// Optional: show a toast or feedback
|
|
74
|
-
console.log("Link copied:", url)
|
|
75
|
-
})
|
|
76
|
-
.catch((err) => {
|
|
77
|
-
console.error("Failed to copy link:", err)
|
|
78
|
-
})
|
|
79
|
-
}
|
|
80
|
-
</script>
|
|
@@ -1,14 +1,33 @@
|
|
|
1
|
-
import { classArr } from "
|
|
1
|
+
import { classArr } from "~ui/utils/classArr"
|
|
2
2
|
|
|
3
3
|
export const classesGridCols2ContentFr = "grid grid-cols-[max-content_1fr]"
|
|
4
4
|
export const classesGridCols3MaxMinFr = "grid grid-cols-[max-content_min-content_1fr]"
|
|
5
5
|
|
|
6
|
+
export const classesGridCols2sm = classArr("grid grid-cols-1", "sm:grid-cols-2")
|
|
7
|
+
|
|
8
|
+
export const classesGridCols2md = classArr("grid grid-cols-1", "md:grid-cols-2")
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 1280/2 = 640 px = 35.5 rem / col
|
|
12
|
+
*/
|
|
13
|
+
export const classesGridCols2lg = classArr("grid grid-cols-1", "lg:grid-cols-2")
|
|
14
|
+
|
|
6
15
|
/**
|
|
7
16
|
* ~600 px (37rem, ~60ch) / col
|
|
8
17
|
*/
|
|
9
18
|
export const classesGridCols2xl = classArr("grid grid-cols-1", "xl:grid-cols-2")
|
|
10
19
|
export const classesGridCols2xl3 = classArr(classesGridCols2xl, "2xl:grid-cols-4", "3xl:grid-cols-6")
|
|
11
20
|
|
|
21
|
+
/**
|
|
22
|
+
* 1024/3 = 341 px = 19rem / col
|
|
23
|
+
* xl: 1280/340 = 3.75
|
|
24
|
+
* lg: 1024/340 = 3
|
|
25
|
+
* md: 768/340 = 2.26
|
|
26
|
+
* sm: 640/340 = 1.8
|
|
27
|
+
* xs: 400/340 = 1.17
|
|
28
|
+
*/
|
|
29
|
+
export const classesGridCols3lg = classArr("grid grid-cols-1", "md:grid-cols-2", "lg:grid-cols-3")
|
|
30
|
+
|
|
12
31
|
/**
|
|
13
32
|
* ~400 px (25rem, ~40ch) / col
|
|
14
33
|
*/
|
|
@@ -36,7 +55,13 @@ export const classesGridCols4xl3 = classArr(classesGridCols4xl, "2xl:grid-cols-8
|
|
|
36
55
|
* sm: 640/256 = 2.5
|
|
37
56
|
* xs: 400/256 = 1.56
|
|
38
57
|
*/
|
|
39
|
-
export const classesGridCols5xl = classArr(
|
|
58
|
+
export const classesGridCols5xl = classArr(
|
|
59
|
+
"grid grid-cols-1",
|
|
60
|
+
"sm:grid-cols-2",
|
|
61
|
+
"md:grid-cols-3",
|
|
62
|
+
"lg:grid-cols-4",
|
|
63
|
+
"xl:grid-cols-5",
|
|
64
|
+
)
|
|
40
65
|
export const classesGridCols5xl3 = classArr(classesGridCols5xl, "2xl:grid-cols-10", "3xl:grid-cols-15")
|
|
41
66
|
|
|
42
67
|
/**
|