@adaptive-sm/astro-ui 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 (86) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +183 -0
  3. package/lib/button/Button.astro +58 -0
  4. package/lib/button/buttonCva.ts +196 -0
  5. package/lib/button/buttonIconCva.ts +52 -0
  6. package/lib/button/classesButtonClickAnimation.ts +8 -0
  7. package/lib/button/classesButtonClickAnimationPush.ts +6 -0
  8. package/lib/button/classesButtonClickAnimationSquish.ts +6 -0
  9. package/lib/button/classesButtonDisabled.ts +1 -0
  10. package/lib/card/CardWrapper.astro +15 -0
  11. package/lib/card/classesCardWrapper.ts +16 -0
  12. package/lib/details/Details.astro +57 -0
  13. package/lib/dev/TailwindIndicator.astro +28 -0
  14. package/lib/form/Fieldset.astro +21 -0
  15. package/lib/form/classesFieldset.ts +1 -0
  16. package/lib/generate_ai_rules/generate_agent_rules.bash +9 -0
  17. package/lib/generate_ai_rules/generate_agent_rules_1_lib.bash +33 -0
  18. package/lib/generate_ai_rules/generate_agent_rules_2_copy.bash +14 -0
  19. package/lib/generate_ai_rules/generate_agent_rules_3_combine.bash +31 -0
  20. package/lib/generate_demo_list/DemoList.astro +31 -0
  21. package/lib/generate_demo_list/DemoListType.ts +1 -0
  22. package/lib/generate_demo_list/generateDemoList.ts +55 -0
  23. package/lib/generate_image_list/generateImageList.ts +101 -0
  24. package/lib/grid/classesGridCols.ts +86 -0
  25. package/lib/icon/Icon1.astro +21 -0
  26. package/lib/img/ImageType.ts +6 -0
  27. package/lib/img/Img.astro +27 -0
  28. package/lib/img/TypedImg.astro +26 -0
  29. package/lib/img/classInvertDiagram.ts +1 -0
  30. package/lib/img/classesImgZoomInOnHover.ts +1 -0
  31. package/lib/layouts/MarkdownWrapper.astro +17 -0
  32. package/lib/layouts/MinimalLayout.astro +67 -0
  33. package/lib/layouts/parts/ThemeToggle.astro +137 -0
  34. package/lib/layouts/parts/astroElementId.ts +7 -0
  35. package/lib/layouts/parts/markdown.css +93 -0
  36. package/lib/link/LinkButton.astro +48 -0
  37. package/lib/link/LinkText.astro +23 -0
  38. package/lib/link/classesTextLink.ts +13 -0
  39. package/lib/list/BlackBulletPoint.astro +16 -0
  40. package/lib/list/BlackBulletPoints.astro +23 -0
  41. package/lib/list/CheckPoint.astro +20 -0
  42. package/lib/list/CheckPoints.astro +23 -0
  43. package/lib/list/NumberedList.astro +14 -0
  44. package/lib/list/Ps.astro +12 -0
  45. package/lib/list/TextOrLink.astro +19 -0
  46. package/lib/modal/Modal.astro +54 -0
  47. package/lib/modal/Modal.module.css +19 -0
  48. package/lib/modal/ModalButton.astro +41 -0
  49. package/lib/modal/modal.ts +137 -0
  50. package/lib/page/PageCentered.astro +14 -0
  51. package/lib/page/PageCenteredCard.astro +17 -0
  52. package/lib/page/classesBg.ts +27 -0
  53. package/lib/page/classesPageCentered.ts +6 -0
  54. package/lib/popover/Popover1.astro +45 -0
  55. package/lib/popover/setupPopoverListeners.ts +22 -0
  56. package/lib/select/Select.astro +45 -0
  57. package/lib/table/DesktopTableClassses.ts +6 -0
  58. package/lib/table/MobileTableClassses.ts +7 -0
  59. package/lib/table/Table.astro +41 -0
  60. package/lib/table/TableColumnDef.ts +10 -0
  61. package/lib/table/TableD.astro +55 -0
  62. package/lib/table/TableM.astro +22 -0
  63. package/lib/table/TableMEntry.astro +27 -0
  64. package/lib/table/sharedTableRowClasses.ts +1 -0
  65. package/lib/table/tableVisibilityClasses.ts +28 -0
  66. package/lib/text/classesTextGray.ts +1 -0
  67. package/lib/text/classesTextHeader.ts +1 -0
  68. package/lib/utils/bun/BunCmd.ts +7 -0
  69. package/lib/utils/bun/cryAndTryAgainLater.ts +6 -0
  70. package/lib/utils/bun/logBunCmd.ts +1 -0
  71. package/lib/utils/bun/runCmdAsync.ts +44 -0
  72. package/lib/utils/bun/runCmdLocally.ts +13 -0
  73. package/lib/utils/obj/objectKeys.ts +21 -0
  74. package/lib/utils/ran/generateId12.ts +7 -0
  75. package/lib/utils/ran/generateId3.ts +7 -0
  76. package/lib/utils/ran/generateId4.ts +7 -0
  77. package/lib/utils/ran/generateId5.ts +7 -0
  78. package/lib/utils/ran/generateId6.ts +7 -0
  79. package/lib/utils/ran/generateId7.ts +7 -0
  80. package/lib/utils/ran/generateReadableId.ts +35 -0
  81. package/lib/utils/ran/urlAlphabet32.ts +8 -0
  82. package/lib/utils/ui/classArr.ts +3 -0
  83. package/lib/utils/ui/classMerge.ts +10 -0
  84. package/lib/utils/ui/isDevEnv.ts +7 -0
  85. package/lib/utils/ui/tailwindBreakpoint.ts +83 -0
  86. package/package.json +56 -0
@@ -0,0 +1,137 @@
1
+ ---
2
+ import { mdiMoonWaxingCrescent, mdiWhiteBalanceSunny } from "@mdi/js"
3
+ import { buttonVariant, type ButtonVariant } from "~/button/buttonCva"
4
+ import Button from "~/button/Button.astro"
5
+ import Icon1 from "~/icon/Icon1.astro"
6
+ import { classArr } from "~/utils/ui/classArr"
7
+ import { astroElementId } from "~/layouts/parts/astroElementId"
8
+
9
+ /*
10
+ * have to use "is:inline" script to run/apply theme before page render -> white flash on page reload otherwise
11
+ * https://docs.astro.build/en/tutorial/6-islands/2/
12
+ * https://axellarsson.com/blog/astrojs-prevent-dark-mode-flicker/
13
+ * https://docs.astro.build/en/tutorials/add-view-transitions/#update-scripts
14
+ * https://github.com/Toxocious/toxocious.github.io/blob/main/src/components/theme_toggle/theme_toggle.astro
15
+ */
16
+ interface Props {
17
+ class?: string
18
+ iconClass?: string
19
+ iconLightClass?: string
20
+ iconDarkClass?: string
21
+ variant?: ButtonVariant
22
+ title?: string
23
+ textLight?: string
24
+ textDark?: string
25
+ textClass?: string
26
+ textLightClass?: string
27
+ textDarkClass?: string
28
+ }
29
+ const p = Astro.props
30
+ const title = p.title ?? "Toggle theme"
31
+ const textLight = p.textLight ?? "Light"
32
+ const textDark = p.textLight ?? "Dark"
33
+ ---
34
+
35
+ <Button
36
+ variant={p.variant ?? buttonVariant.ghost}
37
+ id={astroElementId.themeToggle}
38
+ transition:name={astroElementId.themeToggle}
39
+ title={title}
40
+ class={classArr(p.class)}
41
+ contentClass={classArr("flex flex-row gap-1")}
42
+ >
43
+ <Icon1 path={mdiWhiteBalanceSunny} class={classArr("size-6 dark:hidden mr-2", p.iconClass, p.iconLightClass)} />
44
+ <Icon1 path={mdiMoonWaxingCrescent} class={classArr("hidden size-6 dark:block mr-2", p.iconClass, p.iconDarkClass)} />
45
+ <p id="theme-toggle-text-light" class={classArr("dark:hidden", p.textClass, p.textLightClass)}>{textLight}</p>
46
+ <p id="theme-toggle-text-dark" class={classArr("hidden dark:block", p.textClass, p.textDarkClass)}>{textDark}</p>
47
+ </Button>
48
+
49
+ <script is:inline>
50
+ const log = false
51
+
52
+ if (log) console.log("theme-toggle script start")
53
+ function loadTheme() {
54
+ const stored = typeof localStorage !== "undefined" && localStorage.getItem("theme")
55
+ if (log) console.log("loadTheme", stored)
56
+ if (stored) {
57
+ return stored
58
+ }
59
+ if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
60
+ return "dark"
61
+ }
62
+ return "light"
63
+ }
64
+
65
+ function applyThemeToWindow(theme) {
66
+ if (log) console.log("applyThemeToWindow", theme)
67
+ if (theme === "light") {
68
+ document.documentElement.classList.remove("dark")
69
+ // document.body.classList.remove("dark")
70
+ } else {
71
+ document.documentElement.classList.add("dark")
72
+ // document.body.classList.add("dark")
73
+ }
74
+ }
75
+
76
+ let theme = loadTheme()
77
+
78
+ if (log) console.log("theme", theme)
79
+
80
+ //
81
+ // apply theme on page load
82
+ //
83
+ applyThemeToWindow(theme)
84
+
85
+ // window.localStorage.setItem('theme', theme)
86
+
87
+ const handleToggleClick = () => {
88
+ const element = document.documentElement
89
+ element.classList.toggle("dark")
90
+ const isDark = element.classList.contains("dark")
91
+ localStorage.setItem("theme", isDark ? "dark" : "light")
92
+ if (log) console.log("handleToggleClick", isDark ? "dark" : "light")
93
+ }
94
+
95
+ //
96
+ // apply theme on button click
97
+ //
98
+ const themeButton = document.getElementById("themeToggle")
99
+ if (themeButton) {
100
+ themeButton.addEventListener("click", handleToggleClick)
101
+ } else {
102
+ if (log) console.log("themeButton not found")
103
+ }
104
+
105
+ //
106
+ // apply theme with keyboard shortcut
107
+ //
108
+ document.addEventListener("keydown", (event) => {
109
+ if (event.altKey && event.key === "s") {
110
+ event.preventDefault()
111
+ handleToggleClick()
112
+ } else if (event.altKey && event.key === "a") {
113
+ window.location.href = "/demos"
114
+ }
115
+ })
116
+
117
+ //
118
+ // apply theme after view transition
119
+ //
120
+ document.addEventListener("astro:after-swap", function () {
121
+ const stored = localStorage.getItem("theme")
122
+ if (log) console.log("astro swap", stored)
123
+ if (stored === "dark") document.documentElement.classList.toggle("dark", true)
124
+ })
125
+
126
+ //
127
+ // apply theme across multiple tabs
128
+ //
129
+ const onStorage = (e) => {
130
+ if (log) console.log("onStorage event", e.key)
131
+ if (e.key !== "theme") return
132
+ const theme = e.newValue
133
+ if (theme) applyThemeToWindow(theme)
134
+ }
135
+ window.addEventListener("storage", onStorage)
136
+ if (log) console.log("theme-toggle script end")
137
+ </script>
@@ -0,0 +1,7 @@
1
+ export const astroElementId = {
2
+ navbar: "navbar",
3
+ logo: "logo",
4
+ themeToggle: "themeToggle",
5
+ footer: "footer",
6
+ tailwindIndicator: "tailwindIndicator",
7
+ } as const
@@ -0,0 +1,93 @@
1
+ /*
2
+ rem -> px
3
+ - 0.67rem -> 10.72px
4
+ - 0.5rem -> 8px
5
+ - 0.875rem -> 14px
6
+ - 1.25rem -> 20px
7
+ - 1.5rem -> 24px
8
+ - 2rem -> 32px
9
+ */
10
+
11
+ .markdown-body {
12
+ line-height: 1.5;
13
+ word-wrap: break-word;
14
+ font-size: 1.125rem;
15
+ }
16
+
17
+ .markdown-body h1,
18
+ .markdown-body h2,
19
+ .markdown-body h3,
20
+ .markdown-body h4,
21
+ .markdown-body h5,
22
+ .markdown-body h6 {
23
+ margin-top: 1.5rem;
24
+ margin-bottom: 1rem;
25
+ font-weight: var(--base-text-weight-semibold, 600);
26
+ line-height: 1.25;
27
+ }
28
+
29
+ .markdown-body h1 {
30
+ margin-top: 0.67rem;
31
+ margin-bottom: 0.67rem;
32
+ font-weight: var(--base-text-weight-semibold, 600);
33
+ font-size: 2rem;
34
+ border-bottom: 0.0625rem solid var(--color-border-muted);
35
+ }
36
+
37
+ .markdown-body h2 {
38
+ font-weight: var(--base-text-weight-semibold, 600);
39
+ font-size: 1.5rem;
40
+ border-bottom: 0.0625rem solid var(--color-border-muted);
41
+ }
42
+
43
+ .markdown-body h3 {
44
+ font-weight: var(--base-text-weight-semibold, 600);
45
+ font-size: 1.25rem;
46
+ }
47
+
48
+ .markdown-body h4 {
49
+ font-weight: var(--base-text-weight-semibold, 600);
50
+ font-size: 1rem;
51
+ }
52
+
53
+ .markdown-body h5 {
54
+ font-weight: var(--base-text-weight-semibold, 600);
55
+ font-size: 0.875rem;
56
+ }
57
+
58
+ .markdown-body h6 {
59
+ font-weight: var(--base-text-weight-semibold, 600);
60
+ font-size: 0.85rem;
61
+ color: var(--color-fg-muted);
62
+ }
63
+
64
+ .markdown-body p {
65
+ margin-top: 0.5rem;
66
+ margin-bottom: 0.5rem;
67
+ }
68
+
69
+ .markdown-body ul,
70
+ .markdown-body ol {
71
+ margin-top: 0;
72
+ margin-bottom: 0;
73
+ padding-left: 2rem;
74
+ }
75
+
76
+ /*
77
+ Add bullet points for list items
78
+ */
79
+ .markdown-body ul {
80
+ list-style-type: disc;
81
+ }
82
+
83
+ .markdown-body ol {
84
+ list-style-type: decimal;
85
+ }
86
+
87
+ .markdown-body li {
88
+ display: list-item;
89
+ }
90
+
91
+ .markdown-body a {
92
+ color: hsl(var(--link));
93
+ }
@@ -0,0 +1,48 @@
1
+ ---
2
+ import { buttonCva2, buttonVariant, type ButtonSize, type ButtonVariant } from "~/button/buttonCva"
3
+ import { buttonIconCva } from "~/button/buttonIconCva"
4
+ import { classesButtonClickAnimation } from "~/button/classesButtonClickAnimation"
5
+ import Icon1 from "~/icon/Icon1.astro"
6
+
7
+ interface Props {
8
+ title?: string
9
+ href: string
10
+ variant?: ButtonVariant
11
+ size?: ButtonSize
12
+ icon?: string
13
+ iconRight?: string
14
+ iconClass?: string
15
+ newTab?: boolean
16
+ class?: string
17
+ id?: string
18
+ clickAnimation?: boolean
19
+ }
20
+ const props = Astro.props
21
+ const hasChildren = Astro.slots.has("default")
22
+ const classes = buttonCva2(
23
+ props.variant ?? buttonVariant.link,
24
+ props.size,
25
+ props.clickAnimation ?? classesButtonClickAnimation,
26
+ props.class,
27
+ )
28
+ ---
29
+
30
+ <a href={props.href} class={classes} target={props.newTab ? "_blank" : undefined} id={props.id} title={props.title}>
31
+ {
32
+ props.icon && (
33
+ <Icon1
34
+ path={props.icon}
35
+ class={buttonIconCva(props.variant ?? "link", (props.title || hasChildren) && "mr-2", props.iconClass)}
36
+ />
37
+ )
38
+ }
39
+ <slot />
40
+ {
41
+ props.iconRight && (
42
+ <Icon1
43
+ path={props.iconRight}
44
+ class={buttonIconCva(props.variant ?? "link", (props.title || hasChildren) && "ml-2", props.iconClass)}
45
+ />
46
+ )
47
+ }
48
+ </a>
@@ -0,0 +1,23 @@
1
+ ---
2
+ import { classMerge } from "~/utils/ui/classMerge"
3
+
4
+ interface Props {
5
+ title?: string
6
+ href: string
7
+ newTab?: boolean
8
+ class?: string
9
+ }
10
+ const props = Astro.props
11
+ const title = props.title
12
+ const href = props.href
13
+ const newTab = props.newTab
14
+ ---
15
+
16
+ <a
17
+ href={href}
18
+ class={classMerge("text-blue-500 no-underline hover:underline", props.class)}
19
+ target={newTab ? "_blank" : undefined}
20
+ title={title}
21
+ >
22
+ <slot/>
23
+ </a>
@@ -0,0 +1,13 @@
1
+ import { classArr } from "../utils/ui/classArr"
2
+
3
+ export const classesTextLink = classArr(
4
+ "text-blue-600 hover:text-black", // light
5
+ "dark:text-orange-600 dark:hover:text-orange-400", // dark
6
+ "transition-colors", // animation
7
+ )
8
+
9
+ export const classesTextLinkGroupHover = classArr(
10
+ "group-hover:text-blue-600", // light
11
+ "dark:group-hover:text-orange-400", // dark
12
+ "transition-colors", // animation
13
+ )
@@ -0,0 +1,16 @@
1
+ ---
2
+ import { classMerge } from "~/utils/ui/classMerge"
3
+
4
+ interface Props {
5
+ class?: string
6
+ }
7
+ const props = Astro.props
8
+ ---
9
+
10
+ <span
11
+ class={classMerge("text-xs text-blue-500 select-none mr-1 mt-1.5", props.class)}
12
+ aria-hidden={true}
13
+ style={{ fontSize: "0.5rem" }}
14
+ >
15
+ ●</span
16
+ >
@@ -0,0 +1,23 @@
1
+ ---
2
+ import { mdiCircle } from "@mdi/js"
3
+ import { classMerge } from "~/utils/ui/classMerge"
4
+ import TextOrLink from "./TextOrLink.astro"
5
+ import Icon1 from "~/icon/Icon1.astro"
6
+
7
+ interface Props {
8
+ points: string[] | Readonly<string[]>
9
+ class?: string
10
+ classText?: string
11
+ classBullet?: string
12
+ }
13
+ const props = Astro.props
14
+ ---
15
+
16
+ {
17
+ props.points.map((p) => (
18
+ <div class={classMerge("flex flex-row flex-nowrap", props.class)}>
19
+ <Icon1 path={mdiCircle} class={classMerge("w-1.5 h-1.5 mt-3 mx-1.5 shrink-0", props.classBullet)} />
20
+ <TextOrLink text={p} class={props.classText} />
21
+ </div>
22
+ ))
23
+ }
@@ -0,0 +1,20 @@
1
+ ---
2
+ import { mdiCheck } from "@mdi/js"
3
+ import { classMerge } from "~/utils/ui/classMerge"
4
+ import TextOrLink from "./TextOrLink.astro"
5
+ import Icon1 from "~/icon/Icon1.astro"
6
+
7
+ interface Props {
8
+ point: string
9
+ class?: string
10
+ classText?: string
11
+ classBullet?: string
12
+ }
13
+ const p = Astro.props
14
+ ---
15
+
16
+ <div class={classMerge("flex flex-row flex-nowrap", p.class)}>
17
+ <Icon1 path={mdiCheck} class={classMerge("fill-green-600 dark:fill-green-600 mr-1 flex-none", p.classBullet)} />
18
+ <TextOrLink text={p.point} class={p.classText} />
19
+ <slot />
20
+ </div>
@@ -0,0 +1,23 @@
1
+ ---
2
+ import { mdiCheck } from "@mdi/js"
3
+ import { classMerge } from "~/utils/ui/classMerge"
4
+ import Icon1 from "~/icon/Icon1.astro"
5
+ import TextOrLink from "./TextOrLink.astro"
6
+
7
+ interface Props {
8
+ points: string[] | Readonly<string[]>
9
+ class?: string
10
+ classText?: string
11
+ classBullet?: string
12
+ }
13
+ const props = Astro.props
14
+ ---
15
+
16
+ {
17
+ props.points.map((p) => (
18
+ <div class={classMerge("flex flex-row flex-nowrap", props.class)}>
19
+ <Icon1 path={mdiCheck} class={classMerge("fill-green-600 dark:fill-green-600 mr-1 flex-none", props.classBullet)} />
20
+ <TextOrLink text={p} class={props.classText} />
21
+ </div>
22
+ ))
23
+ }
@@ -0,0 +1,14 @@
1
+ ---
2
+ import { classMerge } from "~/utils/ui/classMerge"
3
+
4
+ interface Props {
5
+ points: string[] | Readonly<string[]>
6
+ classText?: string
7
+ class?: string
8
+ }
9
+ const props = Astro.props
10
+ ---
11
+
12
+ <ol class={classMerge("list-decimal", props.class)} style={{ paddingInlineStart: "18px" }}>
13
+ {props.points.map((l) => <li class={props.classText}>{l}</li>)}
14
+ </ol>
@@ -0,0 +1,12 @@
1
+ ---
2
+ interface Props {
3
+ lines: string[] | Readonly<string[]>
4
+ class?: string
5
+ }
6
+ const props = Astro.props
7
+ const lines = props.lines
8
+ ---
9
+
10
+ <>
11
+ {lines.map((line) => <p class={props.class}>{line}</p>)}
12
+ </>
@@ -0,0 +1,19 @@
1
+ ---
2
+ import LinkText from "~/link/LinkText.astro"
3
+ import { classMerge } from "~/utils/ui/classMerge"
4
+
5
+ interface Props {
6
+ text: string
7
+ class?: string
8
+ }
9
+ const props = Astro.props
10
+ const text = props.text
11
+ ---
12
+
13
+ {
14
+ text.startsWith("http") ? (
15
+ <LinkText href={text}>{text}</LinkText>
16
+ ) : (
17
+ <p class={classMerge("leading-relaxed", props.class)}>{text}</p>
18
+ )
19
+ }
@@ -0,0 +1,54 @@
1
+ ---
2
+ import "./Modal.module.css"
3
+ import { classesTextHeader } from "~/text/classesTextHeader"
4
+ import { classMerge } from "~/utils/ui/classMerge"
5
+ import { buttonVariant } from "~/button/buttonCva"
6
+ import Button from "~/button/Button.astro"
7
+
8
+ /**
9
+ * https://github.com/markteekman/accessible-astro-components/blob/main/Modal.astro
10
+ */
11
+ interface Props {
12
+ triggerId: string
13
+ title: string
14
+ titleClass?: string
15
+ closeText?: string
16
+ class?: string
17
+ classContentArea?: string
18
+ }
19
+
20
+ const props = Astro.props
21
+ const triggerId = props.triggerId
22
+ const title = props.title
23
+ const titleClass = props.titleClass
24
+ const closeText = props.closeText ?? "Close"
25
+ const classContentArea = props.classContentArea
26
+ const closeId = `${triggerId}-close`
27
+ ---
28
+
29
+ <dialog
30
+ class={classMerge(
31
+ "modal",
32
+ "fixed m-auto",
33
+ "max-w-5xl",
34
+ "bg-white dark:bg-gray-900 text-black dark:text-white", // bg
35
+ "border-1 border-black p-4 rounded-xl", // border
36
+ props.class,
37
+ )}
38
+ aria-labelledby={triggerId}
39
+ >
40
+ <div class={classMerge("w-full rounded-xl", classContentArea)}>
41
+ <div class="modal-content flex flex-col items-start gap-2 p-4">
42
+ <h2 tabindex="-1" class={classMerge(classesTextHeader, titleClass)}>
43
+ {title}
44
+ </h2>
45
+ <slot>Modal description</slot>
46
+ <Button id={closeId} variant={buttonVariant.outline} class="modal-close w-full">{closeText}</Button>
47
+ </div>
48
+ </div>
49
+ </dialog>
50
+
51
+ <script>
52
+ import { modal } from "./modal"
53
+ modal()
54
+ </script>
@@ -0,0 +1,19 @@
1
+ dialog::backdrop {
2
+ background-color: rgba(0, 0, 0, 0.5);
3
+ filter: blur(6px);
4
+ }
5
+
6
+ /* Animation */
7
+ dialog[open],
8
+ dialog[open]::backdrop {
9
+ animation: fadein 0.2s ease-in-out;
10
+ }
11
+
12
+ @keyframes fadein {
13
+ from {
14
+ opacity: 0;
15
+ }
16
+ to {
17
+ opacity: 1;
18
+ }
19
+ }
@@ -0,0 +1,41 @@
1
+ ---
2
+ import { generateId5 } from "~/utils/ran/generateId5"
3
+ import type { ButtonSize, ButtonVariant } from "~/button/buttonCva"
4
+ import Modal from "./Modal.astro"
5
+ import { classesTextGray } from "~/text/classesTextGray"
6
+ import { classArr } from "~/utils/ui/classArr"
7
+ import Button from "~/button/Button.astro"
8
+
9
+ interface Props {
10
+ button: {
11
+ title?: string
12
+ text?: string
13
+ variant: ButtonVariant
14
+ size?: ButtonSize
15
+ icon?: string
16
+ iconRight?: string
17
+ iconClass?: string
18
+ class?: string
19
+ }
20
+ id?: string
21
+ title?: string
22
+ class?: string
23
+ classContentArea?: string
24
+ }
25
+ const props = Astro.props
26
+ const id = props.id ?? `modal-id-${generateId5()}`
27
+ const button = props.button
28
+ const title = props.title ?? "Dialog Title"
29
+ const classContentArea = props.classContentArea
30
+ ---
31
+
32
+ <Button id={id} {...button} />
33
+ <Modal
34
+ triggerId={id}
35
+ title={title}
36
+ titleClass={classArr(classesTextGray, "text-xl", "mb-2")}
37
+ class={props.class}
38
+ classContentArea={classContentArea}
39
+ >
40
+ <slot />
41
+ </Modal>