@lunar-js/lunar 0.0.1
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/CHANGELOG.md +12 -0
- package/LICENSE +21 -0
- package/README.md +41 -0
- package/dist/components/composite/Card/Card.d.ts +64 -0
- package/dist/components/composite/Card/Card.d.ts.map +1 -0
- package/dist/components/composite/Card/Card.js +86 -0
- package/dist/components/composite/Card/Card.js.map +1 -0
- package/dist/components/composite/Card/card.css.js +62 -0
- package/dist/components/composite/Card/card.css.js.map +1 -0
- package/dist/components/composite/Dialog/Dialog.d.ts +45 -0
- package/dist/components/composite/Dialog/Dialog.d.ts.map +1 -0
- package/dist/components/composite/Dialog/Dialog.js +117 -0
- package/dist/components/composite/Dialog/Dialog.js.map +1 -0
- package/dist/components/composite/Dialog/DialogProvider.d.ts +11 -0
- package/dist/components/composite/Dialog/DialogProvider.d.ts.map +1 -0
- package/dist/components/composite/Dialog/DialogProvider.js +19 -0
- package/dist/components/composite/Dialog/DialogProvider.js.map +1 -0
- package/dist/components/composite/Dialog/dialog.css.js +104 -0
- package/dist/components/composite/Dialog/dialog.css.js.map +1 -0
- package/dist/components/primitives/Button/Button.d.ts +27 -0
- package/dist/components/primitives/Button/Button.d.ts.map +1 -0
- package/dist/components/primitives/Button/Button.js +25 -0
- package/dist/components/primitives/Button/Button.js.map +1 -0
- package/dist/components/primitives/Button/button.css.d.ts +16 -0
- package/dist/components/primitives/Button/button.css.d.ts.map +1 -0
- package/dist/components/primitives/Button/button.css.js +202 -0
- package/dist/components/primitives/Button/button.css.js.map +1 -0
- package/dist/components/primitives/Button/button.types.d.ts +8 -0
- package/dist/components/primitives/Button/button.types.d.ts.map +1 -0
- package/dist/components/primitives/Input/Input.d.ts +12 -0
- package/dist/components/primitives/Input/Input.d.ts.map +1 -0
- package/dist/components/primitives/Input/Input.js +21 -0
- package/dist/components/primitives/Input/Input.js.map +1 -0
- package/dist/components/primitives/Input/input.css.js +54 -0
- package/dist/components/primitives/Input/input.css.js.map +1 -0
- package/dist/components/primitives/Label/Label.d.ts +13 -0
- package/dist/components/primitives/Label/Label.d.ts.map +1 -0
- package/dist/components/primitives/Label/Label.js +22 -0
- package/dist/components/primitives/Label/Label.js.map +1 -0
- package/dist/components/primitives/Label/label.css.js +35 -0
- package/dist/components/primitives/Label/label.css.js.map +1 -0
- package/dist/components/primitives/Typography/Text.d.ts +40 -0
- package/dist/components/primitives/Typography/Text.d.ts.map +1 -0
- package/dist/components/primitives/Typography/Text.js +28 -0
- package/dist/components/primitives/Typography/Text.js.map +1 -0
- package/dist/components/primitives/Typography/text.css.d.ts +31 -0
- package/dist/components/primitives/Typography/text.css.d.ts.map +1 -0
- package/dist/components/primitives/Typography/text.css.js +1019 -0
- package/dist/components/primitives/Typography/text.css.js.map +1 -0
- package/dist/components/primitives/Typography/text.types.d.ts +10 -0
- package/dist/components/primitives/Typography/text.types.d.ts.map +1 -0
- package/dist/constants/theming.d.ts +10 -0
- package/dist/constants/theming.d.ts.map +1 -0
- package/dist/constants/theming.js +11 -0
- package/dist/constants/theming.js.map +1 -0
- package/dist/hooks/dialog.d.ts +7 -0
- package/dist/hooks/dialog.d.ts.map +1 -0
- package/dist/hooks/dialog.js +14 -0
- package/dist/hooks/dialog.js.map +1 -0
- package/dist/hooks/refs.js +23 -0
- package/dist/hooks/refs.js.map +1 -0
- package/dist/hooks/theme.d.ts +7 -0
- package/dist/hooks/theme.d.ts.map +1 -0
- package/dist/hooks/theme.js +14 -0
- package/dist/hooks/theme.js.map +1 -0
- package/dist/hooks/utils.js +6 -0
- package/dist/hooks/utils.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +20 -0
- package/dist/styles.css.d.ts +4 -0
- package/dist/styles.css.js +5 -0
- package/dist/themes/ThemeProvider/ThemeProvider.d.ts +19 -0
- package/dist/themes/ThemeProvider/ThemeProvider.d.ts.map +1 -0
- package/dist/themes/ThemeProvider/ThemeProvider.js +25 -0
- package/dist/themes/ThemeProvider/ThemeProvider.js.map +1 -0
- package/dist/themes/regal.css.d.ts +5 -0
- package/dist/themes/regal.css.d.ts.map +1 -0
- package/dist/themes/regal.css.js +720 -0
- package/dist/themes/regal.css.js.map +1 -0
- package/dist/themes/styles/color-scheme.css.d.ts +6 -0
- package/dist/themes/styles/color-scheme.css.d.ts.map +1 -0
- package/dist/themes/styles/color-scheme.css.js +9 -0
- package/dist/themes/styles/color-scheme.css.js.map +1 -0
- package/dist/themes/styles/utilities.d.ts +125 -0
- package/dist/themes/styles/utilities.d.ts.map +1 -0
- package/dist/themes/styles/utilities.js +129 -0
- package/dist/themes/styles/utilities.js.map +1 -0
- package/dist/themes/tokens/primitives/borders.d.ts +22 -0
- package/dist/themes/tokens/primitives/borders.d.ts.map +1 -0
- package/dist/themes/tokens/primitives/borders.js +23 -0
- package/dist/themes/tokens/primitives/borders.js.map +1 -0
- package/dist/themes/tokens/primitives/colors.d.ts +100 -0
- package/dist/themes/tokens/primitives/colors.d.ts.map +1 -0
- package/dist/themes/tokens/primitives/colors.js +101 -0
- package/dist/themes/tokens/primitives/colors.js.map +1 -0
- package/dist/themes/tokens/primitives/shadows.d.ts +14 -0
- package/dist/themes/tokens/primitives/shadows.d.ts.map +1 -0
- package/dist/themes/tokens/primitives/shadows.js +15 -0
- package/dist/themes/tokens/primitives/shadows.js.map +1 -0
- package/dist/themes/tokens/primitives/spacing.d.ts +41 -0
- package/dist/themes/tokens/primitives/spacing.d.ts.map +1 -0
- package/dist/themes/tokens/primitives/spacing.js +42 -0
- package/dist/themes/tokens/primitives/spacing.js.map +1 -0
- package/dist/themes/tokens/primitives/typography.d.ts +105 -0
- package/dist/themes/tokens/primitives/typography.d.ts.map +1 -0
- package/dist/themes/tokens/primitives/typography.js +106 -0
- package/dist/themes/tokens/primitives/typography.js.map +1 -0
- package/dist/themes/tokens/semantic/borders.js +23 -0
- package/dist/themes/tokens/semantic/borders.js.map +1 -0
- package/dist/themes/tokens/semantic/colors.js +145 -0
- package/dist/themes/tokens/semantic/colors.js.map +1 -0
- package/dist/themes/tokens/semantic/shadows.js +15 -0
- package/dist/themes/tokens/semantic/shadows.js.map +1 -0
- package/dist/themes/tokens/semantic/spacing.js +70 -0
- package/dist/themes/tokens/semantic/spacing.js.map +1 -0
- package/dist/themes/tokens/semantic/typography.js +34 -0
- package/dist/themes/tokens/semantic/typography.js.map +1 -0
- package/dist/themes/tokens/tokens.css.d.ts +714 -0
- package/dist/themes/tokens/tokens.css.d.ts.map +1 -0
- package/dist/themes/tokens/tokens.css.js +36 -0
- package/dist/themes/tokens/tokens.css.js.map +1 -0
- package/dist/types/theming.d.ts +7 -0
- package/dist/types/theming.d.ts.map +1 -0
- package/package.json +80 -0
- package/src/components/composite/Card/Card.tsx +62 -0
- package/src/components/composite/Card/card.css.ts +79 -0
- package/src/components/composite/Dialog/Dialog.tsx +150 -0
- package/src/components/composite/Dialog/DialogProvider.tsx +21 -0
- package/src/components/composite/Dialog/dialog.css.ts +137 -0
- package/src/components/primitives/Button/Button.tsx +35 -0
- package/src/components/primitives/Button/button.css.ts +236 -0
- package/src/components/primitives/Button/button.types.ts +23 -0
- package/src/components/primitives/Input/Input.tsx +13 -0
- package/src/components/primitives/Input/input.css.ts +64 -0
- package/src/components/primitives/Label/Label.tsx +15 -0
- package/src/components/primitives/Label/label.css.ts +39 -0
- package/src/components/primitives/Typography/Text.tsx +55 -0
- package/src/components/primitives/Typography/text.css.ts +1091 -0
- package/src/components/primitives/Typography/text.types.ts +55 -0
- package/src/constants/theming.ts +16 -0
- package/src/hooks/dialog.ts +15 -0
- package/src/hooks/refs.ts +34 -0
- package/src/hooks/theme.ts +15 -0
- package/src/hooks/utils.ts +3 -0
- package/src/index.css.ts +26 -0
- package/src/index.ts +111 -0
- package/src/themes/ThemeProvider/ThemeProvider.tsx +39 -0
- package/src/themes/regal.css.ts +741 -0
- package/src/themes/styles/color-scheme.css.ts +11 -0
- package/src/themes/styles/utilities.ts +140 -0
- package/src/themes/tokens/primitives/borders.ts +21 -0
- package/src/themes/tokens/primitives/colors.ts +114 -0
- package/src/themes/tokens/primitives/shadows.ts +12 -0
- package/src/themes/tokens/primitives/spacing.ts +39 -0
- package/src/themes/tokens/primitives/typography.ts +125 -0
- package/src/themes/tokens/semantic/borders.ts +21 -0
- package/src/themes/tokens/semantic/colors.ts +166 -0
- package/src/themes/tokens/semantic/shadows.ts +12 -0
- package/src/themes/tokens/semantic/spacing.ts +75 -0
- package/src/themes/tokens/semantic/typography.ts +35 -0
- package/src/themes/tokens/tokens.css.ts +42 -0
- package/src/types/theming.ts +14 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# @lunar-js/lunar
|
|
2
|
+
|
|
3
|
+
## 0.0.1 (2025-11-29)
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Button, Input, Label, Typography, Card, Dialog components -
|
|
8
|
+
[`7e55503`](https://github.com/lunar-js/lunar/commit/7e55503ee0ed95325ed6fd967abd2ca99c9851c9) Thanks astronaut
|
|
9
|
+
[@prests](https://github.com/prests)!
|
|
10
|
+
- Initial design system and ThemeProvider -
|
|
11
|
+
[`7e55503`](https://github.com/lunar-js/lunar/commit/7e55503ee0ed95325ed6fd967abd2ca99c9851c9) Thanks astronaut
|
|
12
|
+
[@prests](https://github.com/prests)!
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Shayne Preston
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Lunar
|
|
2
|
+
|
|
3
|
+
A modern React component library inspired by Radix UI and ShadCN, built with TypeScript and Vanilla Extract for
|
|
4
|
+
CSS-in-JS styling.
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
Lunar provides a comprehensive set of accessible, customizable React components with a powerful theming system. It
|
|
9
|
+
combines the accessibility features of Radix UI with a clean design aesthetic and flexible styling approach.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
> **Note:** This package is ESM-only and requires a Node.js environment that supports ES modules.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Using pnpm (recommended)
|
|
17
|
+
pnpm add @lunar-js/lunar
|
|
18
|
+
|
|
19
|
+
# Using npm
|
|
20
|
+
npm install @lunar-js/lunar
|
|
21
|
+
|
|
22
|
+
# Using yarn
|
|
23
|
+
yarn add @lunar-js/lunar
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
Wrap your application with the `ThemeProvider` and provide a theme:
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import { ThemeProvider } from '@lunar-js/lunar';
|
|
32
|
+
import { regalTheme } from '@lunar-js/lunar/styles.css';
|
|
33
|
+
|
|
34
|
+
function App() {
|
|
35
|
+
return (
|
|
36
|
+
<ThemeProvider themeClassName={regalTheme}>
|
|
37
|
+
<YourAppContent />
|
|
38
|
+
</ThemeProvider>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
3
|
+
|
|
4
|
+
//#region src/components/composite/Card/Card.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Main card container component that provides a styled container with elevation and borders.
|
|
8
|
+
* Serves as the foundation for card-based layouts and content organization.
|
|
9
|
+
*/
|
|
10
|
+
declare const Card: ({
|
|
11
|
+
className,
|
|
12
|
+
...props
|
|
13
|
+
}: React.ComponentProps<"div">) => react_jsx_runtime0.JSX.Element;
|
|
14
|
+
/**
|
|
15
|
+
* Header section of the card, typically containing the card title and description.
|
|
16
|
+
* Provides consistent spacing and layout for the card's top section.
|
|
17
|
+
*/
|
|
18
|
+
declare const CardHeader: ({
|
|
19
|
+
className,
|
|
20
|
+
...props
|
|
21
|
+
}: React.ComponentProps<"div">) => react_jsx_runtime0.JSX.Element;
|
|
22
|
+
/**
|
|
23
|
+
* Title component for the card header with appropriate typography styling.
|
|
24
|
+
* Provides semantic structure and consistent text hierarchy.
|
|
25
|
+
*/
|
|
26
|
+
declare const CardTitle: ({
|
|
27
|
+
className,
|
|
28
|
+
...props
|
|
29
|
+
}: React.ComponentProps<"div">) => react_jsx_runtime0.JSX.Element;
|
|
30
|
+
/**
|
|
31
|
+
* Description component for the card header with muted text styling.
|
|
32
|
+
* Used to provide additional context or subtitle information.
|
|
33
|
+
*/
|
|
34
|
+
declare const CardDescription: ({
|
|
35
|
+
className,
|
|
36
|
+
...props
|
|
37
|
+
}: React.ComponentProps<"div">) => react_jsx_runtime0.JSX.Element;
|
|
38
|
+
/**
|
|
39
|
+
* Action area component for the card, typically containing buttons or interactive elements.
|
|
40
|
+
* Provides proper spacing and alignment for card actions.
|
|
41
|
+
*/
|
|
42
|
+
declare const CardAction: ({
|
|
43
|
+
className,
|
|
44
|
+
...props
|
|
45
|
+
}: React.ComponentProps<"div">) => react_jsx_runtime0.JSX.Element;
|
|
46
|
+
/**
|
|
47
|
+
* Main content area of the card with appropriate padding and spacing.
|
|
48
|
+
* Houses the primary content between the header and footer sections.
|
|
49
|
+
*/
|
|
50
|
+
declare const CardContent: ({
|
|
51
|
+
className,
|
|
52
|
+
...props
|
|
53
|
+
}: React.ComponentProps<"div">) => react_jsx_runtime0.JSX.Element;
|
|
54
|
+
/**
|
|
55
|
+
* Footer section of the card, typically used for actions, metadata, or additional information.
|
|
56
|
+
* Provides consistent spacing and styling for the card's bottom section.
|
|
57
|
+
*/
|
|
58
|
+
declare const CardFooter: ({
|
|
59
|
+
className,
|
|
60
|
+
...props
|
|
61
|
+
}: React.ComponentProps<"div">) => react_jsx_runtime0.JSX.Element;
|
|
62
|
+
//#endregion
|
|
63
|
+
export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };
|
|
64
|
+
//# sourceMappingURL=Card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Card.d.ts","names":[],"sources":["../../../../src/components/composite/Card/Card.tsx"],"sourcesContent":[],"mappings":";;;;;;;;AAAoC;cAS9B,IAEL,EAAA,CAAA;EAAA,SAAA;EAAA,GAAA;AAAA,CAAA,EAFsC,KAAA,CAAM,cAE5C,CAAA,KAAA,CAAA,EAAA,GAFiE,kBAAA,CAAA,GAAA,CAAA,OAEjE;;;;;AAAA,cAMK,UAEL,EAAA,CAAA;EAAA,SAAA;EAAA,GAAA;AAAA,CAAA,EAF4C,KAAA,CAAM,cAElD,CAAA,KAAA,CAAA,EAAA,GAFuE,kBAAA,CAAA,GAAA,CAAA,OAEvE;;;;;cAMK,SANL,EAAA,CAAA;EAAA,SAAA;EAAA,GAAA;AAAA,CAAA,EAM2C,KAAA,CAAM,cANjD,CAAA,KAAA,CAAA,EAAA,GAMsE,kBAAA,CAAA,GAAA,CAAA,OANtE;AAAA;;;;cAcK,eARiE,EAAA,CAAA;EAAA,SAAA;EAAA,GAAA;AAAA,CAAA,EAQrB,KAAA,CAAM,cARe,CAAA,KAAA,CAAA,EAAA,GAQM,kBAAA,CAAA,GAAA,CAAA,OARN;;AAEtE;;;cAcK,UARkD,EAAA,CAAA;EAAA,SAAA;EAAA,GAAA;AAAA,CAAA,EAQX,KAAA,CAAM,cARK,CAAA,KAAA,CAAA,EAAA,GAQgB,kBAAA,CAAA,GAAA,CAAA,OARhB;;;AAEvD;;cAcK,WARc,EAAA,CAAA;EAAA,SAAA;EAAA,GAAA;AAAA,CAAA,EAQ0B,KAAA,CAAM,cARhC,CAAA,KAAA,CAAA,EAAA,GAQqD,kBAAA,CAAA,GAAA,CAAA,OARrD;;;;AAEnB;cAcK,UANL,EAAA,CAAA;EAAA,SAAA;EAAA,GAAA;AAAA,CAAA,EAM4C,KAAA,CAAM,cANlD,CAAA,KAAA,CAAA,EAAA,GAMuE,kBAAA,CAAA,GAAA,CAAA,OANvE"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { card, cardAction, cardContent, cardDescription, cardFooter, cardHeader, cardTitle } from "./card.css.js";
|
|
2
|
+
import clsx from "clsx";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
|
|
5
|
+
//#region src/components/composite/Card/Card.tsx
|
|
6
|
+
/**
|
|
7
|
+
* Main card container component that provides a styled container with elevation and borders.
|
|
8
|
+
* Serves as the foundation for card-based layouts and content organization.
|
|
9
|
+
*/
|
|
10
|
+
const Card = ({ className, ...props }) => {
|
|
11
|
+
return /* @__PURE__ */ jsx("div", {
|
|
12
|
+
"data-slot": "card",
|
|
13
|
+
className: clsx(card, className),
|
|
14
|
+
...props
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Header section of the card, typically containing the card title and description.
|
|
19
|
+
* Provides consistent spacing and layout for the card's top section.
|
|
20
|
+
*/
|
|
21
|
+
const CardHeader = ({ className, ...props }) => {
|
|
22
|
+
return /* @__PURE__ */ jsx("div", {
|
|
23
|
+
"data-slot": "card-header",
|
|
24
|
+
className: clsx(cardHeader, className),
|
|
25
|
+
...props
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Title component for the card header with appropriate typography styling.
|
|
30
|
+
* Provides semantic structure and consistent text hierarchy.
|
|
31
|
+
*/
|
|
32
|
+
const CardTitle = ({ className, ...props }) => {
|
|
33
|
+
return /* @__PURE__ */ jsx("div", {
|
|
34
|
+
"data-slot": "card-title",
|
|
35
|
+
className: clsx(cardTitle, className),
|
|
36
|
+
...props
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Description component for the card header with muted text styling.
|
|
41
|
+
* Used to provide additional context or subtitle information.
|
|
42
|
+
*/
|
|
43
|
+
const CardDescription = ({ className, ...props }) => {
|
|
44
|
+
return /* @__PURE__ */ jsx("div", {
|
|
45
|
+
"data-slot": "card-description",
|
|
46
|
+
className: clsx(cardDescription, className),
|
|
47
|
+
...props
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Action area component for the card, typically containing buttons or interactive elements.
|
|
52
|
+
* Provides proper spacing and alignment for card actions.
|
|
53
|
+
*/
|
|
54
|
+
const CardAction = ({ className, ...props }) => {
|
|
55
|
+
return /* @__PURE__ */ jsx("div", {
|
|
56
|
+
"data-slot": "card-action",
|
|
57
|
+
className: clsx(cardAction, className),
|
|
58
|
+
...props
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Main content area of the card with appropriate padding and spacing.
|
|
63
|
+
* Houses the primary content between the header and footer sections.
|
|
64
|
+
*/
|
|
65
|
+
const CardContent = ({ className, ...props }) => {
|
|
66
|
+
return /* @__PURE__ */ jsx("div", {
|
|
67
|
+
"data-slot": "card-content",
|
|
68
|
+
className: clsx(cardContent, className),
|
|
69
|
+
...props
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Footer section of the card, typically used for actions, metadata, or additional information.
|
|
74
|
+
* Provides consistent spacing and styling for the card's bottom section.
|
|
75
|
+
*/
|
|
76
|
+
const CardFooter = ({ className, ...props }) => {
|
|
77
|
+
return /* @__PURE__ */ jsx("div", {
|
|
78
|
+
"data-slot": "card-footer",
|
|
79
|
+
className: clsx(cardFooter, className),
|
|
80
|
+
...props
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
//#endregion
|
|
85
|
+
export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };
|
|
86
|
+
//# sourceMappingURL=Card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Card.js","names":[],"sources":["../../../../src/components/composite/Card/Card.tsx"],"sourcesContent":["import type * as React from 'react';\nimport clsx from 'clsx';\n\nimport { card, cardHeader, cardTitle, cardDescription, cardAction, cardContent, cardFooter } from './card.css.js';\n\n/**\n * Main card container component that provides a styled container with elevation and borders.\n * Serves as the foundation for card-based layouts and content organization.\n */\nconst Card = ({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"card\" className={clsx(card, className)} {...props} />;\n};\n\n/**\n * Header section of the card, typically containing the card title and description.\n * Provides consistent spacing and layout for the card's top section.\n */\nconst CardHeader = ({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"card-header\" className={clsx(cardHeader, className)} {...props} />;\n};\n\n/**\n * Title component for the card header with appropriate typography styling.\n * Provides semantic structure and consistent text hierarchy.\n */\nconst CardTitle = ({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"card-title\" className={clsx(cardTitle, className)} {...props} />;\n};\n\n/**\n * Description component for the card header with muted text styling.\n * Used to provide additional context or subtitle information.\n */\nconst CardDescription = ({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"card-description\" className={clsx(cardDescription, className)} {...props} />;\n};\n\n/**\n * Action area component for the card, typically containing buttons or interactive elements.\n * Provides proper spacing and alignment for card actions.\n */\nconst CardAction = ({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"card-action\" className={clsx(cardAction, className)} {...props} />;\n};\n\n/**\n * Main content area of the card with appropriate padding and spacing.\n * Houses the primary content between the header and footer sections.\n */\nconst CardContent = ({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"card-content\" className={clsx(cardContent, className)} {...props} />;\n};\n\n/**\n * Footer section of the card, typically used for actions, metadata, or additional information.\n * Provides consistent spacing and styling for the card's bottom section.\n */\nconst CardFooter = ({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"card-footer\" className={clsx(cardFooter, className)} {...props} />;\n};\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent };\n"],"mappings":";;;;;;;;;AASA,MAAM,QAAQ,EAAE,WAAW,GAAG,YAAyC;AACrE,QAAO,oBAAC;EAAI,aAAU;EAAO,WAAW,KAAK,MAAM,UAAU;EAAE,GAAI;GAAS;;;;;;AAO9E,MAAM,cAAc,EAAE,WAAW,GAAG,YAAyC;AAC3E,QAAO,oBAAC;EAAI,aAAU;EAAc,WAAW,KAAK,YAAY,UAAU;EAAE,GAAI;GAAS;;;;;;AAO3F,MAAM,aAAa,EAAE,WAAW,GAAG,YAAyC;AAC1E,QAAO,oBAAC;EAAI,aAAU;EAAa,WAAW,KAAK,WAAW,UAAU;EAAE,GAAI;GAAS;;;;;;AAOzF,MAAM,mBAAmB,EAAE,WAAW,GAAG,YAAyC;AAChF,QAAO,oBAAC;EAAI,aAAU;EAAmB,WAAW,KAAK,iBAAiB,UAAU;EAAE,GAAI;GAAS;;;;;;AAOrG,MAAM,cAAc,EAAE,WAAW,GAAG,YAAyC;AAC3E,QAAO,oBAAC;EAAI,aAAU;EAAc,WAAW,KAAK,YAAY,UAAU;EAAE,GAAI;GAAS;;;;;;AAO3F,MAAM,eAAe,EAAE,WAAW,GAAG,YAAyC;AAC5E,QAAO,oBAAC;EAAI,aAAU;EAAe,WAAW,KAAK,aAAa,UAAU;EAAE,GAAI;GAAS;;;;;;AAO7F,MAAM,cAAc,EAAE,WAAW,GAAG,YAAyC;AAC3E,QAAO,oBAAC;EAAI,aAAU;EAAc,WAAW,KAAK,YAAY,UAAU;EAAE,GAAI;GAAS"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { themeContract } from "../../../themes/tokens/tokens.css.js";
|
|
2
|
+
import { style } from "@vanilla-extract/css";
|
|
3
|
+
|
|
4
|
+
//#region src/components/composite/Card/card.css.ts
|
|
5
|
+
const card = style({
|
|
6
|
+
backgroundColor: themeContract.colors.surface.bg.secondary,
|
|
7
|
+
color: themeContract.colors.text.primary,
|
|
8
|
+
display: "flex",
|
|
9
|
+
flexDirection: "column",
|
|
10
|
+
gap: themeContract.spacing[6],
|
|
11
|
+
borderRadius: themeContract.borderRadius["2xl"],
|
|
12
|
+
border: `${themeContract.borderWidth[1]} solid ${themeContract.colors.border.default}`,
|
|
13
|
+
paddingTop: themeContract.spacing[6],
|
|
14
|
+
paddingBottom: themeContract.spacing[6],
|
|
15
|
+
boxShadow: themeContract.boxShadow.lg
|
|
16
|
+
});
|
|
17
|
+
const cardHeader = style({
|
|
18
|
+
containerType: "inline-size",
|
|
19
|
+
containerName: "card-header",
|
|
20
|
+
display: "grid",
|
|
21
|
+
gridAutoRows: "min-content",
|
|
22
|
+
gridTemplateRows: "auto auto",
|
|
23
|
+
alignItems: "flex-start",
|
|
24
|
+
gap: themeContract.spacing[2],
|
|
25
|
+
paddingLeft: themeContract.spacing[6],
|
|
26
|
+
paddingRight: themeContract.spacing[6],
|
|
27
|
+
selectors: {
|
|
28
|
+
"&:has([data-slot=\"card-action\"])": { gridTemplateColumns: "1fr auto" },
|
|
29
|
+
"&.border-b": { paddingBottom: themeContract.spacing[6] }
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
const cardTitle = style({
|
|
33
|
+
lineHeight: "1",
|
|
34
|
+
fontWeight: themeContract.typography.body.md.bold.fontWeight
|
|
35
|
+
});
|
|
36
|
+
const cardDescription = style({
|
|
37
|
+
color: themeContract.colors.text.secondary,
|
|
38
|
+
fontSize: themeContract.typography.body.sm.medium.fontSize,
|
|
39
|
+
lineHeight: themeContract.typography.body.sm.medium.lineHeight
|
|
40
|
+
});
|
|
41
|
+
const cardAction = style({
|
|
42
|
+
gridColumn: "2",
|
|
43
|
+
gridRowStart: "1",
|
|
44
|
+
gridRowEnd: "span 2",
|
|
45
|
+
alignSelf: "flex-start",
|
|
46
|
+
justifySelf: "end"
|
|
47
|
+
});
|
|
48
|
+
const cardContent = style({
|
|
49
|
+
paddingLeft: themeContract.spacing[6],
|
|
50
|
+
paddingRight: themeContract.spacing[6]
|
|
51
|
+
});
|
|
52
|
+
const cardFooter = style({
|
|
53
|
+
display: "flex",
|
|
54
|
+
alignItems: "center",
|
|
55
|
+
paddingLeft: themeContract.spacing[6],
|
|
56
|
+
paddingRight: themeContract.spacing[6],
|
|
57
|
+
selectors: { "&.border-t": { paddingTop: themeContract.spacing[6] } }
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
export { card, cardAction, cardContent, cardDescription, cardFooter, cardHeader, cardTitle };
|
|
62
|
+
//# sourceMappingURL=card.css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.css.js","names":[],"sources":["../../../../src/components/composite/Card/card.css.ts"],"sourcesContent":["import { style } from '@vanilla-extract/css';\n\nimport { themeContract } from '../../../themes/tokens/tokens.css.js';\n\nconst card = style({\n backgroundColor: themeContract.colors.surface.bg.secondary,\n color: themeContract.colors.text.primary,\n display: 'flex',\n flexDirection: 'column',\n gap: themeContract.spacing[6],\n borderRadius: themeContract.borderRadius['2xl'],\n border: `${themeContract.borderWidth[1]} solid ${themeContract.colors.border.default}`,\n paddingTop: themeContract.spacing[6],\n paddingBottom: themeContract.spacing[6],\n boxShadow: themeContract.boxShadow.lg,\n});\n\nconst cardHeader = style({\n containerType: 'inline-size',\n containerName: 'card-header',\n display: 'grid',\n gridAutoRows: 'min-content',\n gridTemplateRows: 'auto auto',\n alignItems: 'flex-start',\n gap: themeContract.spacing[2],\n paddingLeft: themeContract.spacing[6],\n paddingRight: themeContract.spacing[6],\n\n // Conditional grid columns when card action is present\n selectors: {\n '&:has([data-slot=\"card-action\"])': {\n gridTemplateColumns: '1fr auto',\n },\n // Conditional padding when border-b class is present\n '&.border-b': {\n paddingBottom: themeContract.spacing[6],\n },\n },\n});\n\nconst cardTitle = style({\n lineHeight: '1',\n fontWeight: themeContract.typography.body.md.bold.fontWeight,\n});\n\nconst cardDescription = style({\n color: themeContract.colors.text.secondary,\n fontSize: themeContract.typography.body.sm.medium.fontSize,\n lineHeight: themeContract.typography.body.sm.medium.lineHeight,\n});\n\nconst cardAction = style({\n gridColumn: '2',\n gridRowStart: '1',\n gridRowEnd: 'span 2',\n alignSelf: 'flex-start',\n justifySelf: 'end',\n});\n\nconst cardContent = style({\n paddingLeft: themeContract.spacing[6],\n paddingRight: themeContract.spacing[6],\n});\n\nconst cardFooter = style({\n display: 'flex',\n alignItems: 'center',\n paddingLeft: themeContract.spacing[6],\n paddingRight: themeContract.spacing[6],\n\n // Conditional padding when border-t class is present\n selectors: {\n '&.border-t': {\n paddingTop: themeContract.spacing[6],\n },\n },\n});\n\nexport { card, cardTitle, cardAction, cardFooter, cardHeader, cardContent, cardDescription };\n"],"mappings":";;;;AAIA,MAAM,OAAO,MAAM;CACjB,iBAAiB,cAAc,OAAO,QAAQ,GAAG;CACjD,OAAO,cAAc,OAAO,KAAK;CACjC,SAAS;CACT,eAAe;CACf,KAAK,cAAc,QAAQ;CAC3B,cAAc,cAAc,aAAa;CACzC,QAAQ,GAAG,cAAc,YAAY,GAAG,SAAS,cAAc,OAAO,OAAO;CAC7E,YAAY,cAAc,QAAQ;CAClC,eAAe,cAAc,QAAQ;CACrC,WAAW,cAAc,UAAU;CACpC,CAAC;AAEF,MAAM,aAAa,MAAM;CACvB,eAAe;CACf,eAAe;CACf,SAAS;CACT,cAAc;CACd,kBAAkB;CAClB,YAAY;CACZ,KAAK,cAAc,QAAQ;CAC3B,aAAa,cAAc,QAAQ;CACnC,cAAc,cAAc,QAAQ;CAGpC,WAAW;EACT,sCAAoC,EAClC,qBAAqB,YACtB;EAED,cAAc,EACZ,eAAe,cAAc,QAAQ,IACtC;EACF;CACF,CAAC;AAEF,MAAM,YAAY,MAAM;CACtB,YAAY;CACZ,YAAY,cAAc,WAAW,KAAK,GAAG,KAAK;CACnD,CAAC;AAEF,MAAM,kBAAkB,MAAM;CAC5B,OAAO,cAAc,OAAO,KAAK;CACjC,UAAU,cAAc,WAAW,KAAK,GAAG,OAAO;CAClD,YAAY,cAAc,WAAW,KAAK,GAAG,OAAO;CACrD,CAAC;AAEF,MAAM,aAAa,MAAM;CACvB,YAAY;CACZ,cAAc;CACd,YAAY;CACZ,WAAW;CACX,aAAa;CACd,CAAC;AAEF,MAAM,cAAc,MAAM;CACxB,aAAa,cAAc,QAAQ;CACnC,cAAc,cAAc,QAAQ;CACrC,CAAC;AAEF,MAAM,aAAa,MAAM;CACvB,SAAS;CACT,YAAY;CACZ,aAAa,cAAc,QAAQ;CACnC,cAAc,cAAc,QAAQ;CAGpC,WAAW,EACT,cAAc,EACZ,YAAY,cAAc,QAAQ,IACnC,EACF;CACF,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ButtonProps } from "../../primitives/Button/Button.js";
|
|
2
|
+
import { ComponentProps, FC, ReactNode } from "react";
|
|
3
|
+
import "dialog-closedby-polyfill";
|
|
4
|
+
|
|
5
|
+
//#region src/components/composite/Dialog/Dialog.d.ts
|
|
6
|
+
interface DialogProps extends ComponentProps<'dialog'> {
|
|
7
|
+
/**
|
|
8
|
+
* Optional function that renders the trigger element for the dialog.
|
|
9
|
+
* This allows custom trigger components while maintaining dialog functionality.
|
|
10
|
+
*/
|
|
11
|
+
renderTrigger?: () => ReactNode;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Main Dialog component that renders a modal dialog element.
|
|
15
|
+
* Handles dialog state management and provides context for child components.
|
|
16
|
+
*/
|
|
17
|
+
declare const Dialog: FC<DialogProps>;
|
|
18
|
+
/**
|
|
19
|
+
* Button component that triggers the dialog to open.
|
|
20
|
+
* Automatically handles aria attributes and dialog state management.
|
|
21
|
+
*/
|
|
22
|
+
declare const DialogTrigger: FC<ButtonProps>;
|
|
23
|
+
/**
|
|
24
|
+
* Button component that closes the dialog when clicked.
|
|
25
|
+
* Handles dialog close functionality while preserving custom onClick handlers.
|
|
26
|
+
*/
|
|
27
|
+
declare const DialogClose: FC<ButtonProps>;
|
|
28
|
+
/**
|
|
29
|
+
* Container component for the main content area of the dialog.
|
|
30
|
+
* Provides semantic structure and consistent styling for dialog content.
|
|
31
|
+
*/
|
|
32
|
+
declare const DialogContent: FC<ComponentProps<'div'>>;
|
|
33
|
+
/**
|
|
34
|
+
* Header component for the dialog, typically containing the dialog title.
|
|
35
|
+
* Provides consistent spacing and styling for the dialog header area.
|
|
36
|
+
*/
|
|
37
|
+
declare const DialogHeader: FC<ComponentProps<'div'>>;
|
|
38
|
+
/**
|
|
39
|
+
* Footer component for the dialog, typically containing action buttons.
|
|
40
|
+
* Provides consistent spacing and styling for the dialog footer area.
|
|
41
|
+
*/
|
|
42
|
+
declare const DialogFooter: FC<ComponentProps<'div'>>;
|
|
43
|
+
//#endregion
|
|
44
|
+
export { Dialog, DialogClose, DialogContent, DialogFooter, DialogHeader, DialogTrigger };
|
|
45
|
+
//# sourceMappingURL=Dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dialog.d.ts","names":[],"sources":["../../../../src/components/composite/Dialog/Dialog.tsx"],"sourcesContent":[],"mappings":";;;;;UAoBU,WAAA,SAAoB;;AAH+C;;;eAG/C,CAAA,EAAA,GAAA,GAKN,SALM;;AAAc;;;;cAYtC,MAAU,EAAF,EAAE,CAAC,WAAD,CAAA;AAAA;;;;cAiCV,aAAiB,EAAF,EAAE,CAAC,WAAD,CAAA;AAAA;;;;cA6CjB,WAAe,EAAF,EAAE,CAAC,WAAD,CAAA;AAAA;;;;cAmBf,aAAiB,EAAF,EAAE,CAAC,cAAD,CAAA,KAAA,CAAA,CAAA;AAAA;;;;cAQjB,YAAgB,EAAF,EAAE,CAAC,cAAD,CAAA,KAAA,CAAA,CAAA;AAAA;;;;cAQhB,YAAgB,EAAF,EAAE,CAAC,cAAD,CAAA,KAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import Button_default from "../../primitives/Button/Button.js";
|
|
2
|
+
import DialogProvider_default from "./DialogProvider.js";
|
|
3
|
+
import { useDialog } from "../../../hooks/dialog.js";
|
|
4
|
+
import { useMergedRef } from "../../../hooks/refs.js";
|
|
5
|
+
import { dialog, dialogContent, dialogFooter, dialogHeader } from "./dialog.css.js";
|
|
6
|
+
import { useEffect, useEffectEvent, useRef, useState } from "react";
|
|
7
|
+
import clsx from "clsx";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import "dialog-closedby-polyfill";
|
|
10
|
+
|
|
11
|
+
//#region src/components/composite/Dialog/Dialog.tsx
|
|
12
|
+
/**
|
|
13
|
+
* Main Dialog component that renders a modal dialog element.
|
|
14
|
+
* Handles dialog state management and provides context for child components.
|
|
15
|
+
*/
|
|
16
|
+
const Dialog = ({ className, open = false, closedby = "any", renderTrigger, ref: forwardedRef, ...props }) => {
|
|
17
|
+
const internalDialogRef = useRef(null);
|
|
18
|
+
const mergedRef = useMergedRef(internalDialogRef, forwardedRef);
|
|
19
|
+
return /* @__PURE__ */ jsxs(DialogProvider_default, {
|
|
20
|
+
isOpen: open,
|
|
21
|
+
dialogRef: internalDialogRef,
|
|
22
|
+
children: [renderTrigger?.(), /* @__PURE__ */ jsx("dialog", {
|
|
23
|
+
ref: mergedRef,
|
|
24
|
+
open,
|
|
25
|
+
closedby,
|
|
26
|
+
"data-slot": "dialog",
|
|
27
|
+
className: clsx(dialog, className),
|
|
28
|
+
"aria-modal": "true",
|
|
29
|
+
...props
|
|
30
|
+
})]
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Button component that triggers the dialog to open.
|
|
35
|
+
* Automatically handles aria attributes and dialog state management.
|
|
36
|
+
*/
|
|
37
|
+
const DialogTrigger = ({ onClick, ...props }) => {
|
|
38
|
+
const { dialogRef, isOpen } = useDialog();
|
|
39
|
+
const [isAriaExpanded, setIsAriaExpanded] = useState(isOpen);
|
|
40
|
+
const handleClick = (event) => {
|
|
41
|
+
onClick?.(event);
|
|
42
|
+
if (event.defaultPrevented || event.isPropagationStopped()) return;
|
|
43
|
+
setIsAriaExpanded(true);
|
|
44
|
+
dialogRef.current?.showModal();
|
|
45
|
+
};
|
|
46
|
+
const handleClose = useEffectEvent(() => {
|
|
47
|
+
setIsAriaExpanded(false);
|
|
48
|
+
});
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
const dialog$1 = dialogRef.current;
|
|
51
|
+
if (!dialog$1) return;
|
|
52
|
+
dialog$1.addEventListener("close", handleClose);
|
|
53
|
+
return () => {
|
|
54
|
+
dialog$1.removeEventListener("close", handleClose);
|
|
55
|
+
};
|
|
56
|
+
}, [dialogRef]);
|
|
57
|
+
return /* @__PURE__ */ jsx(Button_default, {
|
|
58
|
+
"aria-expanded": isAriaExpanded,
|
|
59
|
+
"aria-haspopup": "dialog",
|
|
60
|
+
"data-slot": "dialog-trigger",
|
|
61
|
+
onClick: handleClick,
|
|
62
|
+
...props
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Button component that closes the dialog when clicked.
|
|
67
|
+
* Handles dialog close functionality while preserving custom onClick handlers.
|
|
68
|
+
*/
|
|
69
|
+
const DialogClose = ({ onClick, ...props }) => {
|
|
70
|
+
const { dialogRef } = useDialog();
|
|
71
|
+
const handleClick = (event) => {
|
|
72
|
+
onClick?.(event);
|
|
73
|
+
if (event.defaultPrevented || event.isPropagationStopped()) return;
|
|
74
|
+
dialogRef.current?.close();
|
|
75
|
+
};
|
|
76
|
+
return /* @__PURE__ */ jsx(Button_default, {
|
|
77
|
+
onClick: handleClick,
|
|
78
|
+
...props
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Container component for the main content area of the dialog.
|
|
83
|
+
* Provides semantic structure and consistent styling for dialog content.
|
|
84
|
+
*/
|
|
85
|
+
const DialogContent = ({ className, ...props }) => {
|
|
86
|
+
return /* @__PURE__ */ jsx("div", {
|
|
87
|
+
"data-slot": "dialog-content",
|
|
88
|
+
className: clsx(dialogContent, className),
|
|
89
|
+
...props
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Header component for the dialog, typically containing the dialog title.
|
|
94
|
+
* Provides consistent spacing and styling for the dialog header area.
|
|
95
|
+
*/
|
|
96
|
+
const DialogHeader = ({ className, ...props }) => {
|
|
97
|
+
return /* @__PURE__ */ jsx("div", {
|
|
98
|
+
"data-slot": "dialog-header",
|
|
99
|
+
className: clsx(dialogHeader, className),
|
|
100
|
+
...props
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Footer component for the dialog, typically containing action buttons.
|
|
105
|
+
* Provides consistent spacing and styling for the dialog footer area.
|
|
106
|
+
*/
|
|
107
|
+
const DialogFooter = ({ className, ...props }) => {
|
|
108
|
+
return /* @__PURE__ */ jsx("div", {
|
|
109
|
+
"data-slot": "dialog-footer",
|
|
110
|
+
className: clsx(dialogFooter, className),
|
|
111
|
+
...props
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
//#endregion
|
|
116
|
+
export { Dialog, DialogClose, DialogContent, DialogFooter, DialogHeader, DialogTrigger };
|
|
117
|
+
//# sourceMappingURL=Dialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dialog.js","names":["Dialog: FC<DialogProps>","DialogProvider","DialogTrigger: FC<ButtonProps>","dialog","Button","DialogClose: FC<ButtonProps>","DialogContent: FC<ComponentProps<'div'>>","DialogHeader: FC<ComponentProps<'div'>>","DialogFooter: FC<ComponentProps<'div'>>"],"sources":["../../../../src/components/composite/Dialog/Dialog.tsx"],"sourcesContent":["import {\n type ComponentProps,\n type FC,\n type MouseEvent,\n type ReactNode,\n useEffect,\n useEffectEvent,\n useRef,\n useState,\n} from 'react';\nimport clsx from 'clsx';\n// TODO: Remove once there's full browser support for Dialog's closedby attribute.\nimport 'dialog-closedby-polyfill';\n\nimport DialogProvider from './DialogProvider.js';\nimport { useDialog } from '../../../hooks/dialog.js';\nimport { useMergedRef } from '../../../hooks/refs.js';\nimport Button, { type ButtonProps } from '../../primitives/Button/Button.js';\nimport { dialog, dialogContent, dialogFooter, dialogHeader } from './dialog.css.js';\n\ninterface DialogProps extends ComponentProps<'dialog'> {\n /**\n * Optional function that renders the trigger element for the dialog.\n * This allows custom trigger components while maintaining dialog functionality.\n */\n renderTrigger?: () => ReactNode;\n}\n\n/**\n * Main Dialog component that renders a modal dialog element.\n * Handles dialog state management and provides context for child components.\n */\nconst Dialog: FC<DialogProps> = ({\n className,\n open = false,\n closedby = 'any',\n renderTrigger,\n ref: forwardedRef,\n ...props\n}) => {\n const internalDialogRef = useRef<HTMLDialogElement>(null);\n const mergedRef = useMergedRef(internalDialogRef, forwardedRef);\n\n return (\n <DialogProvider isOpen={open} dialogRef={internalDialogRef}>\n {renderTrigger?.()}\n\n <dialog\n ref={mergedRef}\n open={open}\n // eslint-disable-next-line react/no-unknown-property\n closedby={closedby}\n data-slot=\"dialog\"\n className={clsx(dialog, className)}\n aria-modal=\"true\"\n {...props}\n />\n </DialogProvider>\n );\n};\n\n/**\n * Button component that triggers the dialog to open.\n * Automatically handles aria attributes and dialog state management.\n */\nconst DialogTrigger: FC<ButtonProps> = ({ onClick, ...props }) => {\n const { dialogRef, isOpen } = useDialog();\n\n const [isAriaExpanded, setIsAriaExpanded] = useState(isOpen);\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (event.defaultPrevented || event.isPropagationStopped()) {\n return;\n }\n\n setIsAriaExpanded(true);\n dialogRef.current?.showModal();\n };\n\n const handleClose = useEffectEvent(() => {\n setIsAriaExpanded(false);\n });\n\n useEffect(() => {\n const dialog = dialogRef.current;\n if (!dialog) return;\n\n dialog.addEventListener('close', handleClose);\n\n return () => {\n dialog.removeEventListener('close', handleClose);\n };\n }, [dialogRef]);\n\n return (\n <Button\n aria-expanded={isAriaExpanded}\n aria-haspopup=\"dialog\"\n data-slot=\"dialog-trigger\"\n onClick={handleClick}\n {...props}\n />\n );\n};\n\n/**\n * Button component that closes the dialog when clicked.\n * Handles dialog close functionality while preserving custom onClick handlers.\n */\nconst DialogClose: FC<ButtonProps> = ({ onClick, ...props }) => {\n const { dialogRef } = useDialog();\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (event.defaultPrevented || event.isPropagationStopped()) {\n return;\n }\n\n dialogRef.current?.close();\n };\n\n return <Button onClick={handleClick} {...props} />;\n};\n\n/**\n * Container component for the main content area of the dialog.\n * Provides semantic structure and consistent styling for dialog content.\n */\nconst DialogContent: FC<ComponentProps<'div'>> = ({ className, ...props }) => {\n return <div data-slot=\"dialog-content\" className={clsx(dialogContent, className)} {...props} />;\n};\n\n/**\n * Header component for the dialog, typically containing the dialog title.\n * Provides consistent spacing and styling for the dialog header area.\n */\nconst DialogHeader: FC<ComponentProps<'div'>> = ({ className, ...props }) => {\n return <div data-slot=\"dialog-header\" className={clsx(dialogHeader, className)} {...props} />;\n};\n\n/**\n * Footer component for the dialog, typically containing action buttons.\n * Provides consistent spacing and styling for the dialog footer area.\n */\nconst DialogFooter: FC<ComponentProps<'div'>> = ({ className, ...props }) => {\n return <div data-slot=\"dialog-footer\" className={clsx(dialogFooter, className)} {...props} />;\n};\n\nexport { Dialog, DialogTrigger, DialogClose, DialogContent, DialogHeader, DialogFooter };\n"],"mappings":";;;;;;;;;;;;;;;AAgCA,MAAMA,UAA2B,EAC/B,WACA,OAAO,OACP,WAAW,OACX,eACA,KAAK,cACL,GAAG,YACC;CACJ,MAAM,oBAAoB,OAA0B,KAAK;CACzD,MAAM,YAAY,aAAa,mBAAmB,aAAa;AAE/D,QACE,qBAACC;EAAe,QAAQ;EAAM,WAAW;aACtC,iBAAiB,EAElB,oBAAC;GACC,KAAK;GACC;GAEI;GACV,aAAU;GACV,WAAW,KAAK,QAAQ,UAAU;GAClC,cAAW;GACX,GAAI;IACJ;GACa;;;;;;AAQrB,MAAMC,iBAAkC,EAAE,SAAS,GAAG,YAAY;CAChE,MAAM,EAAE,WAAW,WAAW,WAAW;CAEzC,MAAM,CAAC,gBAAgB,qBAAqB,SAAS,OAAO;CAE5D,MAAM,eAAe,UAAyC;AAC5D,YAAU,MAAM;AAChB,MAAI,MAAM,oBAAoB,MAAM,sBAAsB,CACxD;AAGF,oBAAkB,KAAK;AACvB,YAAU,SAAS,WAAW;;CAGhC,MAAM,cAAc,qBAAqB;AACvC,oBAAkB,MAAM;GACxB;AAEF,iBAAgB;EACd,MAAMC,WAAS,UAAU;AACzB,MAAI,CAACA,SAAQ;AAEb,WAAO,iBAAiB,SAAS,YAAY;AAE7C,eAAa;AACX,YAAO,oBAAoB,SAAS,YAAY;;IAEjD,CAAC,UAAU,CAAC;AAEf,QACE,oBAACC;EACC,iBAAe;EACf,iBAAc;EACd,aAAU;EACV,SAAS;EACT,GAAI;GACJ;;;;;;AAQN,MAAMC,eAAgC,EAAE,SAAS,GAAG,YAAY;CAC9D,MAAM,EAAE,cAAc,WAAW;CAEjC,MAAM,eAAe,UAAyC;AAC5D,YAAU,MAAM;AAChB,MAAI,MAAM,oBAAoB,MAAM,sBAAsB,CACxD;AAGF,YAAU,SAAS,OAAO;;AAG5B,QAAO,oBAACD;EAAO,SAAS;EAAa,GAAI;GAAS;;;;;;AAOpD,MAAME,iBAA4C,EAAE,WAAW,GAAG,YAAY;AAC5E,QAAO,oBAAC;EAAI,aAAU;EAAiB,WAAW,KAAK,eAAe,UAAU;EAAE,GAAI;GAAS;;;;;;AAOjG,MAAMC,gBAA2C,EAAE,WAAW,GAAG,YAAY;AAC3E,QAAO,oBAAC;EAAI,aAAU;EAAgB,WAAW,KAAK,cAAc,UAAU;EAAE,GAAI;GAAS;;;;;;AAO/F,MAAMC,gBAA2C,EAAE,WAAW,GAAG,YAAY;AAC3E,QAAO,oBAAC;EAAI,aAAU;EAAgB,WAAW,KAAK,cAAc,UAAU;EAAE,GAAI;GAAS"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RefObject } from "react";
|
|
2
|
+
import "react/jsx-runtime";
|
|
3
|
+
|
|
4
|
+
//#region src/components/composite/Dialog/DialogProvider.d.ts
|
|
5
|
+
interface DialogContextProps {
|
|
6
|
+
isOpen: boolean;
|
|
7
|
+
dialogRef: RefObject<HTMLDialogElement | null>;
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { type DialogContextProps };
|
|
11
|
+
//# sourceMappingURL=DialogProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DialogProvider.d.ts","names":[],"sources":["../../../../src/components/composite/Dialog/DialogProvider.tsx"],"sourcesContent":[],"mappings":";;;;UAEU,kBAAA;;aAEG,UAAU;AAJuD"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
|
|
4
|
+
//#region src/components/composite/Dialog/DialogProvider.tsx
|
|
5
|
+
const DialogContext = createContext(null);
|
|
6
|
+
const DialogProvider = ({ children, isOpen, dialogRef }) => {
|
|
7
|
+
return /* @__PURE__ */ jsx(DialogContext.Provider, {
|
|
8
|
+
value: {
|
|
9
|
+
isOpen,
|
|
10
|
+
dialogRef
|
|
11
|
+
},
|
|
12
|
+
children
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
var DialogProvider_default = DialogProvider;
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { DialogContext, DialogProvider_default as default };
|
|
19
|
+
//# sourceMappingURL=DialogProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DialogProvider.js","names":[],"sources":["../../../../src/components/composite/Dialog/DialogProvider.tsx"],"sourcesContent":["import { createContext, type PropsWithChildren, type RefObject } from 'react';\n\ninterface DialogContextProps {\n isOpen: boolean;\n dialogRef: RefObject<HTMLDialogElement | null>;\n}\n\nconst DialogContext = createContext<DialogContextProps | null>(null);\n\ninterface DialogProviderProps extends PropsWithChildren {\n isOpen: boolean;\n dialogRef: RefObject<HTMLDialogElement | null>;\n}\n\nconst DialogProvider = ({ children, isOpen, dialogRef }: DialogProviderProps) => {\n return <DialogContext.Provider value={{ isOpen, dialogRef }}>{children}</DialogContext.Provider>;\n};\n\nexport type { DialogContextProps };\nexport default DialogProvider;\nexport { DialogContext };\n"],"mappings":";;;;AAOA,MAAM,gBAAgB,cAAyC,KAAK;AAOpE,MAAM,kBAAkB,EAAE,UAAU,QAAQ,gBAAqC;AAC/E,QAAO,oBAAC,cAAc;EAAS,OAAO;GAAE;GAAQ;GAAW;EAAG;GAAkC;;AAIlG,6BAAe"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { BREAKPOINT__MD, BREAKPOINT__SM } from "../../../constants/theming.js";
|
|
2
|
+
import { themeContract } from "../../../themes/tokens/tokens.css.js";
|
|
3
|
+
import { withBreakpoint, withSafeTransition } from "../../../themes/styles/utilities.js";
|
|
4
|
+
import { keyframes, style } from "@vanilla-extract/css";
|
|
5
|
+
|
|
6
|
+
//#region src/components/composite/Dialog/dialog.css.ts
|
|
7
|
+
const fadeIn = keyframes({
|
|
8
|
+
from: {
|
|
9
|
+
opacity: "0",
|
|
10
|
+
transform: "scale(0.95) translateY(-10px)"
|
|
11
|
+
},
|
|
12
|
+
to: {
|
|
13
|
+
opacity: "1",
|
|
14
|
+
transform: "scale(1) translateY(0)"
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
const fadeOut = keyframes({
|
|
18
|
+
from: {
|
|
19
|
+
display: "block",
|
|
20
|
+
opacity: "1",
|
|
21
|
+
transform: "scale(1) translateY(0)"
|
|
22
|
+
},
|
|
23
|
+
to: {
|
|
24
|
+
display: "none",
|
|
25
|
+
opacity: "0",
|
|
26
|
+
transform: "scale(0.95) translateY(-10px)"
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
const fadeInBackdrop = keyframes({
|
|
30
|
+
from: { opacity: "0" },
|
|
31
|
+
to: { opacity: "1" }
|
|
32
|
+
});
|
|
33
|
+
const fadeOutBackdrop = keyframes({
|
|
34
|
+
from: { opacity: "1" },
|
|
35
|
+
to: { opacity: "0" }
|
|
36
|
+
});
|
|
37
|
+
const dialog = style([
|
|
38
|
+
{
|
|
39
|
+
boxSizing: "border-box",
|
|
40
|
+
padding: themeContract.spacing[4],
|
|
41
|
+
border: "none",
|
|
42
|
+
backgroundColor: themeContract.colors.surface.bg.primary,
|
|
43
|
+
color: themeContract.colors.text.primary,
|
|
44
|
+
borderRadius: themeContract.borderRadius.lg,
|
|
45
|
+
boxShadow: themeContract.boxShadow.xl,
|
|
46
|
+
width: "100vw",
|
|
47
|
+
height: "100vh",
|
|
48
|
+
maxWidth: "100vw",
|
|
49
|
+
maxHeight: "100vh",
|
|
50
|
+
"::backdrop": { filter: "brightness(0%)" }
|
|
51
|
+
},
|
|
52
|
+
withSafeTransition({
|
|
53
|
+
transition: "display 150ms allow-discrete, overlay 150ms allow-discrete",
|
|
54
|
+
animation: `${fadeOut} 150ms cubic-bezier(0.4, 0, 0.2, 1)`,
|
|
55
|
+
selectors: {
|
|
56
|
+
"&[open]": { animation: `${fadeIn} 250ms cubic-bezier(0.34, 1.56, 0.64, 1)` },
|
|
57
|
+
"&[open]::backdrop": { animation: `${fadeInBackdrop} 250ms` }
|
|
58
|
+
},
|
|
59
|
+
"::backdrop": {
|
|
60
|
+
transition: "display 150ms allow-discrete, overlay 150ms allow-discrete",
|
|
61
|
+
animation: `${fadeOutBackdrop} 150ms`
|
|
62
|
+
}
|
|
63
|
+
}),
|
|
64
|
+
withBreakpoint(BREAKPOINT__MD, {
|
|
65
|
+
width: "fit-content",
|
|
66
|
+
height: "fit-content",
|
|
67
|
+
maxWidth: "32rem",
|
|
68
|
+
maxHeight: "unset"
|
|
69
|
+
})
|
|
70
|
+
]);
|
|
71
|
+
const dialogContent = style([{
|
|
72
|
+
display: "flex",
|
|
73
|
+
flexDirection: "column",
|
|
74
|
+
gap: themeContract.spacing[4],
|
|
75
|
+
minHeight: "100%",
|
|
76
|
+
padding: 0,
|
|
77
|
+
overflowY: "auto",
|
|
78
|
+
WebkitOverflowScrolling: "touch"
|
|
79
|
+
}, withBreakpoint(BREAKPOINT__SM, {
|
|
80
|
+
minHeight: "auto",
|
|
81
|
+
maxHeight: "calc(100vh - 64px)",
|
|
82
|
+
padding: themeContract.spacing[6]
|
|
83
|
+
})]);
|
|
84
|
+
const dialogHeader = style([{
|
|
85
|
+
display: "flex",
|
|
86
|
+
flexDirection: "column",
|
|
87
|
+
gap: themeContract.spacing[2],
|
|
88
|
+
paddingBottom: themeContract.spacing[2],
|
|
89
|
+
borderBottom: `${themeContract.borderWidth[1]} solid ${themeContract.colors.border.subtle}`
|
|
90
|
+
}, withBreakpoint(BREAKPOINT__SM, { paddingBottom: themeContract.spacing[4] })]);
|
|
91
|
+
const dialogFooter = style([{
|
|
92
|
+
display: "flex",
|
|
93
|
+
flexDirection: "column-reverse",
|
|
94
|
+
gap: themeContract.spacing[2],
|
|
95
|
+
paddingTop: themeContract.spacing[4],
|
|
96
|
+
marginTop: "auto"
|
|
97
|
+
}, withBreakpoint(BREAKPOINT__SM, {
|
|
98
|
+
flexDirection: "row",
|
|
99
|
+
justifyContent: "flex-end"
|
|
100
|
+
})]);
|
|
101
|
+
|
|
102
|
+
//#endregion
|
|
103
|
+
export { dialog, dialogContent, dialogFooter, dialogHeader };
|
|
104
|
+
//# sourceMappingURL=dialog.css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialog.css.js","names":[],"sources":["../../../../src/components/composite/Dialog/dialog.css.ts"],"sourcesContent":["import { style, keyframes } from '@vanilla-extract/css';\n\nimport { themeContract } from '../../../themes/tokens/tokens.css.js';\nimport { withBreakpoint, withSafeTransition } from '../../../themes/styles/utilities.js';\nimport { BREAKPOINT__SM, BREAKPOINT__MD } from '../../../constants/theming.js';\n\nconst fadeIn = keyframes({\n from: {\n opacity: '0',\n transform: 'scale(0.95) translateY(-10px)',\n },\n to: {\n opacity: '1',\n transform: 'scale(1) translateY(0)',\n },\n});\n\nconst fadeOut = keyframes({\n from: {\n display: 'block',\n opacity: '1',\n transform: 'scale(1) translateY(0)',\n },\n to: {\n display: 'none',\n opacity: '0',\n transform: 'scale(0.95) translateY(-10px)',\n },\n});\n\nconst fadeInBackdrop = keyframes({\n from: {\n opacity: '0',\n },\n to: {\n opacity: '1',\n },\n});\n\nconst fadeOutBackdrop = keyframes({\n from: {\n opacity: '1',\n },\n to: {\n opacity: '0',\n },\n});\n\nconst dialog = style([\n {\n boxSizing: 'border-box',\n padding: themeContract.spacing[4],\n border: 'none',\n backgroundColor: themeContract.colors.surface.bg.primary,\n color: themeContract.colors.text.primary,\n borderRadius: themeContract.borderRadius.lg,\n boxShadow: themeContract.boxShadow.xl,\n width: '100vw',\n height: '100vh',\n maxWidth: '100vw',\n maxHeight: '100vh',\n\n '::backdrop': {\n filter: 'brightness(0%)',\n },\n },\n withSafeTransition({\n transition: 'display 150ms allow-discrete, overlay 150ms allow-discrete',\n animation: `${fadeOut} 150ms cubic-bezier(0.4, 0, 0.2, 1)`,\n\n selectors: {\n '&[open]': {\n animation: `${fadeIn} 250ms cubic-bezier(0.34, 1.56, 0.64, 1)`,\n },\n '&[open]::backdrop': {\n animation: `${fadeInBackdrop} 250ms`,\n },\n },\n\n '::backdrop': {\n transition: 'display 150ms allow-discrete, overlay 150ms allow-discrete',\n animation: `${fadeOutBackdrop} 150ms`,\n },\n }),\n withBreakpoint(BREAKPOINT__MD, {\n width: 'fit-content',\n height: 'fit-content',\n maxWidth: '32rem',\n maxHeight: 'unset',\n }),\n]);\n\nconst dialogContent = style([\n {\n display: 'flex',\n flexDirection: 'column',\n gap: themeContract.spacing[4],\n minHeight: '100%',\n padding: 0,\n overflowY: 'auto',\n WebkitOverflowScrolling: 'touch',\n },\n withBreakpoint(BREAKPOINT__SM, {\n minHeight: 'auto',\n maxHeight: 'calc(100vh - 64px)',\n padding: themeContract.spacing[6],\n }),\n]);\n\nconst dialogHeader = style([\n {\n display: 'flex',\n flexDirection: 'column',\n gap: themeContract.spacing[2],\n paddingBottom: themeContract.spacing[2],\n borderBottom: `${themeContract.borderWidth[1]} solid ${themeContract.colors.border.subtle}`,\n },\n withBreakpoint(BREAKPOINT__SM, {\n paddingBottom: themeContract.spacing[4],\n }),\n]);\n\nconst dialogFooter = style([\n {\n display: 'flex',\n flexDirection: 'column-reverse',\n gap: themeContract.spacing[2],\n paddingTop: themeContract.spacing[4],\n marginTop: 'auto',\n },\n withBreakpoint(BREAKPOINT__SM, {\n flexDirection: 'row',\n justifyContent: 'flex-end',\n }),\n]);\n\nexport { dialog, dialogContent, dialogHeader, dialogFooter };\n"],"mappings":";;;;;;AAMA,MAAM,SAAS,UAAU;CACvB,MAAM;EACJ,SAAS;EACT,WAAW;EACZ;CACD,IAAI;EACF,SAAS;EACT,WAAW;EACZ;CACF,CAAC;AAEF,MAAM,UAAU,UAAU;CACxB,MAAM;EACJ,SAAS;EACT,SAAS;EACT,WAAW;EACZ;CACD,IAAI;EACF,SAAS;EACT,SAAS;EACT,WAAW;EACZ;CACF,CAAC;AAEF,MAAM,iBAAiB,UAAU;CAC/B,MAAM,EACJ,SAAS,KACV;CACD,IAAI,EACF,SAAS,KACV;CACF,CAAC;AAEF,MAAM,kBAAkB,UAAU;CAChC,MAAM,EACJ,SAAS,KACV;CACD,IAAI,EACF,SAAS,KACV;CACF,CAAC;AAEF,MAAM,SAAS,MAAM;CACnB;EACE,WAAW;EACX,SAAS,cAAc,QAAQ;EAC/B,QAAQ;EACR,iBAAiB,cAAc,OAAO,QAAQ,GAAG;EACjD,OAAO,cAAc,OAAO,KAAK;EACjC,cAAc,cAAc,aAAa;EACzC,WAAW,cAAc,UAAU;EACnC,OAAO;EACP,QAAQ;EACR,UAAU;EACV,WAAW;EAEX,cAAc,EACZ,QAAQ,kBACT;EACF;CACD,mBAAmB;EACjB,YAAY;EACZ,WAAW,GAAG,QAAQ;EAEtB,WAAW;GACT,WAAW,EACT,WAAW,GAAG,OAAO,2CACtB;GACD,qBAAqB,EACnB,WAAW,GAAG,eAAe,SAC9B;GACF;EAED,cAAc;GACZ,YAAY;GACZ,WAAW,GAAG,gBAAgB;GAC/B;EACF,CAAC;CACF,eAAe,gBAAgB;EAC7B,OAAO;EACP,QAAQ;EACR,UAAU;EACV,WAAW;EACZ,CAAC;CACH,CAAC;AAEF,MAAM,gBAAgB,MAAM,CAC1B;CACE,SAAS;CACT,eAAe;CACf,KAAK,cAAc,QAAQ;CAC3B,WAAW;CACX,SAAS;CACT,WAAW;CACX,yBAAyB;CAC1B,EACD,eAAe,gBAAgB;CAC7B,WAAW;CACX,WAAW;CACX,SAAS,cAAc,QAAQ;CAChC,CAAC,CACH,CAAC;AAEF,MAAM,eAAe,MAAM,CACzB;CACE,SAAS;CACT,eAAe;CACf,KAAK,cAAc,QAAQ;CAC3B,eAAe,cAAc,QAAQ;CACrC,cAAc,GAAG,cAAc,YAAY,GAAG,SAAS,cAAc,OAAO,OAAO;CACpF,EACD,eAAe,gBAAgB,EAC7B,eAAe,cAAc,QAAQ,IACtC,CAAC,CACH,CAAC;AAEF,MAAM,eAAe,MAAM,CACzB;CACE,SAAS;CACT,eAAe;CACf,KAAK,cAAc,QAAQ;CAC3B,YAAY,cAAc,QAAQ;CAClC,WAAW;CACZ,EACD,eAAe,gBAAgB;CAC7B,eAAe;CACf,gBAAgB;CACjB,CAAC,CACH,CAAC"}
|