mado-ui 0.3.1 → 0.3.2
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/css/index.css +28 -8
- package/dist/components/button.d.ts +75 -10
- package/dist/components/details.d.ts +3 -5
- package/dist/components/drop-down.d.ts +3 -2
- package/dist/components/form/submit-button.d.ts +2 -3
- package/dist/components/index.d.ts +3 -3
- package/dist/components/link.d.ts +61 -4
- package/dist/components.esm.js +148 -18
- package/dist/components.esm.js.map +1 -1
- package/dist/components.js +149 -17
- package/dist/components.js.map +1 -1
- package/dist/index.esm.js +148 -18
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +149 -17
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/css/index.css
CHANGED
|
@@ -451,6 +451,9 @@
|
|
|
451
451
|
.min-w-0 {
|
|
452
452
|
min-width: calc(var(--spacing) * 0);
|
|
453
453
|
}
|
|
454
|
+
.min-w-64 {
|
|
455
|
+
min-width: calc(var(--spacing) * 64);
|
|
456
|
+
}
|
|
454
457
|
.min-w-fit {
|
|
455
458
|
min-width: fit-content;
|
|
456
459
|
}
|
|
@@ -1278,18 +1281,18 @@
|
|
|
1278
1281
|
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
1279
1282
|
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
1280
1283
|
}
|
|
1281
|
-
.transition-\[background-size\] {
|
|
1282
|
-
transition-property: background-size;
|
|
1284
|
+
.transition-\[background-size\,background-image\,color\] {
|
|
1285
|
+
transition-property: background-size,background-image,color;
|
|
1283
1286
|
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
1284
1287
|
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
1285
1288
|
}
|
|
1286
|
-
.transition-\[background-
|
|
1287
|
-
transition-property: background-size
|
|
1289
|
+
.transition-\[background-size\,color\] {
|
|
1290
|
+
transition-property: background-size,color;
|
|
1288
1291
|
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
1289
1292
|
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
1290
1293
|
}
|
|
1291
|
-
.transition-\[background-
|
|
1292
|
-
transition-property: background-size
|
|
1294
|
+
.transition-\[background-size\] {
|
|
1295
|
+
transition-property: background-size;
|
|
1293
1296
|
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
1294
1297
|
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
1295
1298
|
}
|
|
@@ -1313,8 +1316,8 @@
|
|
|
1313
1316
|
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
1314
1317
|
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
1315
1318
|
}
|
|
1316
|
-
.transition-\[
|
|
1317
|
-
transition-property: transform
|
|
1319
|
+
.transition-\[transform\,color\] {
|
|
1320
|
+
transition-property: transform,color;
|
|
1318
1321
|
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
1319
1322
|
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
1320
1323
|
}
|
|
@@ -1376,6 +1379,9 @@
|
|
|
1376
1379
|
.\[--theme-color\:var\(--color-cyan-500\)\] {
|
|
1377
1380
|
--theme-color: var(--color-cyan-500);
|
|
1378
1381
|
}
|
|
1382
|
+
.\[--theme-color\:var\(--color-primary-500\)\] {
|
|
1383
|
+
--theme-color: var(--color-primary-500);
|
|
1384
|
+
}
|
|
1379
1385
|
.\[--theme-color\:var\(--color-ui-blue\)\] {
|
|
1380
1386
|
--theme-color: var(--color-ui-blue);
|
|
1381
1387
|
}
|
|
@@ -1709,6 +1715,14 @@
|
|
|
1709
1715
|
color: var(--color-ui-red);
|
|
1710
1716
|
}
|
|
1711
1717
|
}
|
|
1718
|
+
.after\:transition-\[transform\,background-color\] {
|
|
1719
|
+
&::after {
|
|
1720
|
+
content: var(--tw-content);
|
|
1721
|
+
transition-property: transform,background-color;
|
|
1722
|
+
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
1723
|
+
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1712
1726
|
.after\:transition-\[transform_background-color\] {
|
|
1713
1727
|
&::after {
|
|
1714
1728
|
content: var(--tw-content);
|
|
@@ -1752,6 +1766,12 @@
|
|
|
1752
1766
|
--theme-color: var(--color-blue-500);
|
|
1753
1767
|
}
|
|
1754
1768
|
}
|
|
1769
|
+
.after\:\[--theme-color\:var\(--color-primary-500\)\] {
|
|
1770
|
+
&::after {
|
|
1771
|
+
content: var(--tw-content);
|
|
1772
|
+
--theme-color: var(--color-primary-500);
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1755
1775
|
.after\:\[--theme-color\:var\(--color-ui-blue\)\] {
|
|
1756
1776
|
&::after {
|
|
1757
1777
|
content: var(--tw-content);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Url, UrlObject } from 'node:url';
|
|
1
2
|
import { ElementType } from 'react';
|
|
2
3
|
import { AnyElementProps, OneOf } from '../types';
|
|
3
4
|
type ColorTheme = OneOf<[
|
|
@@ -20,24 +21,88 @@ type ColorTheme = OneOf<[
|
|
|
20
21
|
]>;
|
|
21
22
|
}
|
|
22
23
|
]>;
|
|
23
|
-
type LinkOrOther<TTag extends ElementType
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
type LinkOrOther<TTag extends ElementType = typeof HeadlessButton> = OneOf<[
|
|
25
|
+
AnyElementProps<TTag> & {
|
|
26
|
+
href?: never;
|
|
27
|
+
},
|
|
28
|
+
AnyElementProps<typeof Anchor> & {
|
|
29
|
+
href?: string | Url | UrlObject;
|
|
30
|
+
}
|
|
31
|
+
]>;
|
|
32
|
+
export type ButtonPadding = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
33
|
+
export type ButtonBorderRadius = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
34
|
+
export type ButtonProps<TTag extends ElementType = typeof HeadlessButton> = LinkOrOther<TTag> & ColorTheme & {
|
|
29
35
|
/** Customizes the theme color to a sensible gradient. */
|
|
30
36
|
gradient?: boolean;
|
|
31
37
|
/** The size of the element based on padding. */
|
|
32
|
-
padding?:
|
|
33
|
-
/** The size of the border
|
|
34
|
-
rounded?:
|
|
38
|
+
padding?: ButtonPadding;
|
|
39
|
+
/** The size of the border radius. */
|
|
40
|
+
rounded?: ButtonBorderRadius;
|
|
41
|
+
};
|
|
42
|
+
export type ExtendedButtonConfig = {
|
|
43
|
+
/** Modifies the default(s) for what element is rendered. The `as` prop on the component still overrides the default(s) set here. */
|
|
44
|
+
as?: ElementType | {
|
|
45
|
+
/** Modifies the base link element when `href` is present. */
|
|
46
|
+
link?: ElementType;
|
|
47
|
+
/** Modifies the base button element. */
|
|
48
|
+
default?: ElementType;
|
|
49
|
+
};
|
|
50
|
+
/** Adds default classes. */
|
|
51
|
+
className?: string;
|
|
52
|
+
defaultTheme?: ColorTheme['theme'] | string;
|
|
53
|
+
/** Sets the default for the `gradient` prop. */
|
|
54
|
+
gradient?: boolean;
|
|
55
|
+
/** Sets the default for the `padding` prop. */
|
|
56
|
+
padding?: ButtonPadding;
|
|
57
|
+
/** Sets the default for the `rounded` prop. */
|
|
58
|
+
rounded?: ButtonBorderRadius;
|
|
59
|
+
/** Add more theme options. */
|
|
60
|
+
theme?: {
|
|
61
|
+
[themeName: string]: {
|
|
62
|
+
/** Custom theme configuration */
|
|
63
|
+
customTheme: NonNullable<ColorTheme['customTheme']>;
|
|
64
|
+
/** Additional CSS classes to apply */
|
|
65
|
+
className?: string;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
export type ExtendedThemeNames<T extends ExtendedButtonConfig> = T['theme'] extends Record<string, unknown> ? keyof T['theme'] : never;
|
|
70
|
+
export type ExtendedButtonProps<TExtendedConfig extends ExtendedButtonConfig, TTag extends ElementType = typeof HeadlessButton> = Omit<ButtonProps<TTag>, 'theme' | 'customTheme'> & {
|
|
71
|
+
theme?: ButtonProps<TTag>['theme'] | ExtendedThemeNames<TExtendedConfig>;
|
|
72
|
+
customTheme?: ButtonProps<TTag>['customTheme'];
|
|
35
73
|
};
|
|
36
|
-
import {
|
|
74
|
+
import { Anchor } from './link';
|
|
37
75
|
import { Button as HeadlessButton } from '@headlessui/react';
|
|
38
76
|
/**
|
|
39
77
|
* # Button
|
|
40
78
|
* - A pre-styled button with utility props for easy customization depending on use case.
|
|
41
79
|
*/
|
|
42
80
|
export default function Button<TTag extends ElementType = typeof HeadlessButton>({ className, customTheme, gradient, padding, rounded, theme, ...props }: ButtonProps<TTag>): import("react/jsx-runtime").JSX.Element;
|
|
81
|
+
/**
|
|
82
|
+
* # createButton
|
|
83
|
+
* Creates an extended Button component with additional theme options.
|
|
84
|
+
*
|
|
85
|
+
* @param extendedThemes - Configuration object defining new themes
|
|
86
|
+
* @returns A new Button component with extended theme support
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```tsx
|
|
90
|
+
* const MyButton = createButton({
|
|
91
|
+
* as: {
|
|
92
|
+
* default: 'div',
|
|
93
|
+
* link: NextLink
|
|
94
|
+
* },
|
|
95
|
+
* className: 'min-w-64',
|
|
96
|
+
* padding: 'sm',
|
|
97
|
+
* rounded: 'full',
|
|
98
|
+
* theme: {
|
|
99
|
+
* primary: {
|
|
100
|
+
* customTheme: { themeColor: '[--theme-color:var(--color-primary-500)]' },
|
|
101
|
+
* className: 'text-white'
|
|
102
|
+
* }
|
|
103
|
+
* }
|
|
104
|
+
* })
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export declare function createButton<TExtendedConfig extends ExtendedButtonConfig>(config: TExtendedConfig): <TTag extends ElementType = typeof HeadlessButton>({ theme, className, customTheme, gradient, padding, rounded, as, ...props }: ExtendedButtonProps<TExtendedConfig, TTag>) => import("react/jsx-runtime").JSX.Element;
|
|
43
108
|
export {};
|
|
@@ -5,14 +5,12 @@ export type DetailsBodyProps<TTag extends ElementType = 'div'> = Omit<Disclosure
|
|
|
5
5
|
export type DetailsProps<TTag extends ElementType = 'div'> = Omit<DisclosureProps<TTag>, 'className' | 'role'> & {
|
|
6
6
|
className?: string;
|
|
7
7
|
};
|
|
8
|
-
export type DetailsSummaryProps<TTag extends ElementType = typeof Button
|
|
9
|
-
href?: never;
|
|
10
|
-
}, 'className' | 'href' | 'role'> & {
|
|
8
|
+
export type DetailsSummaryProps<TTag extends ElementType = typeof Button<typeof HeadlessButton>> = Omit<DisclosureButtonProps<TTag>, 'as' | 'className' | 'role'> & {
|
|
11
9
|
arrow?: boolean | ReactNode;
|
|
12
10
|
className?: string;
|
|
13
11
|
};
|
|
14
|
-
import { DisclosureProps, DisclosureButtonProps, DisclosurePanelProps } from '@headlessui/react';
|
|
12
|
+
import { Button as HeadlessButton, DisclosureProps, DisclosureButtonProps, DisclosurePanelProps } from '@headlessui/react';
|
|
15
13
|
import Button from './button';
|
|
16
|
-
export declare function DetailsSummary<TTag extends ElementType = typeof Button
|
|
14
|
+
export declare function DetailsSummary<TTag extends ElementType = typeof Button>({ arrow, children, className, ...props }: DetailsSummaryProps<TTag>): import("react/jsx-runtime").JSX.Element;
|
|
17
15
|
export declare function DetailsBody<TTag extends ElementType = 'div'>({ children, className, ...props }: DetailsBodyProps<TTag>): import("react/jsx-runtime").JSX.Element;
|
|
18
16
|
export default function Details<TTag extends ElementType = 'div'>({ as, className, ...props }: DetailsProps<TTag>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -7,10 +7,11 @@ export type DropDownButtonProps<TTag extends ElementType = 'button'> = Omit<Menu
|
|
|
7
7
|
export type DropDownItemProps = MenuItemProps;
|
|
8
8
|
export type DropDownItemsProps = Omit<MenuItemsProps, 'className' | 'transition'> & {
|
|
9
9
|
className?: string;
|
|
10
|
+
containerClassName?: string;
|
|
10
11
|
};
|
|
11
12
|
export type DropDownProps = MenuProps;
|
|
12
13
|
export type DropDownSectionProps = MenuSectionProps & {
|
|
13
|
-
label
|
|
14
|
+
label?: string;
|
|
14
15
|
labelProps?: Omit<MenuHeadingProps, 'children'> & {
|
|
15
16
|
/** @deprecated Use `label` instead. */
|
|
16
17
|
children?: never;
|
|
@@ -22,7 +23,7 @@ export type DropDownSeparatorProps = MenuSeparatorProps;
|
|
|
22
23
|
import { MenuButtonProps, MenuHeadingProps, MenuItemProps, MenuItemsProps, MenuProps, MenuSectionProps, MenuSeparatorProps } from '@headlessui/react';
|
|
23
24
|
export declare function DropDownButton<TTag extends ElementType = 'button'>({ arrow, as, children, className, ...props }: DropDownButtonProps<TTag>): import("react/jsx-runtime").JSX.Element;
|
|
24
25
|
export declare function DropDownItem({ as, ...props }: DropDownItemProps): import("react/jsx-runtime").JSX.Element;
|
|
25
|
-
export declare function DropDownItems({ anchor, children, className, style, ...props }: DropDownItemsProps): import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
export declare function DropDownItems({ anchor, children, className, containerClassName, style, ...props }: DropDownItemsProps): import("react/jsx-runtime").JSX.Element;
|
|
26
27
|
export declare function DropDownSection({ children, label, labelProps, separatorAbove, separatorBelow, ...props }: DropDownSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
27
28
|
export declare function DropDownSeparator({ className, ...props }: DropDownSeparatorProps): import("react/jsx-runtime").JSX.Element;
|
|
28
29
|
export default function DropDown(props: DropDownProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
export type SubmitButtonProps = Omit<ButtonProps
|
|
3
|
-
|
|
4
|
-
}, 'as' | 'customTheme' | 'href' | 'theme'> & {
|
|
2
|
+
export type SubmitButtonProps = Omit<ButtonProps, 'as' | 'customTheme' | 'href' | 'theme'> & {
|
|
3
|
+
/** This doesn't do much by default, because we use built-in colors for different form states. You'll have to modify a good bit to make this do anything. */
|
|
5
4
|
customTheme?: {
|
|
6
5
|
/** Example: `'[--theme-color:var(--color-blue-500)]'` */
|
|
7
6
|
themeColor: string;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import Button, { ButtonProps } from './button';
|
|
1
|
+
import Button, { ButtonProps, createButton, ExtendedButtonConfig, ExtendedButtonProps } from './button';
|
|
2
2
|
import Details, { DetailsBody, DetailsBodyProps, DetailsProps, DetailsSummary, DetailsSummaryProps } from './details';
|
|
3
3
|
import DropDown, { DropDownButton, DropDownButtonProps, DropDownItem, DropDownItemProps, DropDownItems, DropDownItemsProps, DropDownProps, DropDownSection, DropDownSectionProps, DropDownSeparator, DropDownSeparatorProps } from './drop-down';
|
|
4
4
|
import Form, { Fieldset, FieldsetProps, FormProps, FormSubmitArgs, Input, InputProps, SubmitButton, SubmitButtonProps, Textarea, TextareaProps } from './form';
|
|
5
5
|
import Ghost from './ghost';
|
|
6
6
|
import Heading, { HeadingProps } from './heading';
|
|
7
|
-
import Link, { Anchor, AnchorProps, LinkProps } from './link';
|
|
7
|
+
import Link, { Anchor, AnchorProps, createLink, ExtendedLinkConfig, ExtendedLinkProps, LinkProps } from './link';
|
|
8
8
|
import Modal, { ModalDialog, ModalProps, ModalTrigger } from './modal';
|
|
9
9
|
import Time from './time';
|
|
10
10
|
import Tooltip, { TooltipPanel, TooltipProps, TooltipTrigger } from './tooltip';
|
|
11
|
-
export { Anchor, AnchorProps, Button, ButtonProps, Details, DetailsBody, DetailsBodyProps, DetailsProps, DetailsSummary, DetailsSummaryProps, DropDown, DropDownButton, DropDownButtonProps, DropDownItem, DropDownItemProps, DropDownItems, DropDownItemsProps, DropDownProps, DropDownSection, DropDownSectionProps, DropDownSeparator, DropDownSeparatorProps, Fieldset, FieldsetProps, Form, FormProps, FormSubmitArgs, Ghost, Heading, HeadingProps, Input, InputProps, Link, LinkProps, Modal, ModalDialog, ModalProps, ModalTrigger, SubmitButton, SubmitButtonProps, Textarea, TextareaProps, Time, Tooltip, TooltipPanel, TooltipProps, TooltipTrigger, };
|
|
11
|
+
export { Anchor, AnchorProps, Button, ButtonProps, createButton, createLink, Details, DetailsBody, DetailsBodyProps, DetailsProps, DetailsSummary, DetailsSummaryProps, DropDown, DropDownButton, DropDownButtonProps, DropDownItem, DropDownItemProps, DropDownItems, DropDownItemsProps, DropDownProps, DropDownSection, DropDownSectionProps, DropDownSeparator, DropDownSeparatorProps, ExtendedButtonConfig, ExtendedButtonProps, ExtendedLinkConfig, ExtendedLinkProps, Fieldset, FieldsetProps, Form, FormProps, FormSubmitArgs, Ghost, Heading, HeadingProps, Input, InputProps, Link, LinkProps, Modal, ModalDialog, ModalProps, ModalTrigger, SubmitButton, SubmitButtonProps, Textarea, TextareaProps, Time, Tooltip, TooltipPanel, TooltipProps, TooltipTrigger, };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { AnyElementProps, OneOf } from '../types';
|
|
2
2
|
import { ElementType } from 'react';
|
|
3
|
-
export type AnchorProps<TTag extends ElementType
|
|
3
|
+
export type AnchorProps<TTag extends ElementType = 'a'> = AnyElementProps<TTag> & {
|
|
4
4
|
disabled?: boolean;
|
|
5
5
|
};
|
|
6
|
-
export declare function Anchor({ as, className, disabled, href, onClick, target, rel, ...props }: AnchorProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare function Anchor<TTag extends ElementType = 'a'>({ as, className, disabled, href, onClick, target, rel, ...props }: AnchorProps<TTag>): import("react/jsx-runtime").JSX.Element;
|
|
7
7
|
type ThemeColorOrClasses = OneOf<[
|
|
8
8
|
{
|
|
9
9
|
/**
|
|
@@ -28,7 +28,7 @@ type ColorTheme = OneOf<[
|
|
|
28
28
|
customTheme: ThemeColorOrClasses;
|
|
29
29
|
}
|
|
30
30
|
]>;
|
|
31
|
-
export type LinkProps<TTag extends ElementType
|
|
31
|
+
export type LinkProps<TTag extends ElementType = typeof Anchor> = AnyElementProps<TTag, OneOf<[
|
|
32
32
|
{
|
|
33
33
|
type?: 'center' | 'lift' | 'ltr' | 'multiline' | 'multiline-center' | 'multiline-lift' | 'multiline-ltr' | 'multiline-rtl' | 'multiline-static' | 'normal' | 'rtl' | 'static';
|
|
34
34
|
},
|
|
@@ -65,5 +65,62 @@ export type LinkProps<TTag extends ElementType<any, 'a'> = 'a'> = AnyElementProp
|
|
|
65
65
|
* @example
|
|
66
66
|
* <Link href='/about' type='fill-ltr' theme='red' title='About Us'>Learn more about our company</Link>
|
|
67
67
|
*/
|
|
68
|
-
export default function Link({ as, className, customTheme, theme, type, ...props }: LinkProps): import("react/jsx-runtime").JSX.Element;
|
|
68
|
+
export default function Link<TTag extends ElementType = typeof Anchor>({ as, className, customTheme, theme, type, ...props }: LinkProps<TTag>): import("react/jsx-runtime").JSX.Element;
|
|
69
|
+
export type ExtendedLinkConfig = {
|
|
70
|
+
/** Modifies the default element that is rendered. The `as` prop on the component still overrides the default set here. */
|
|
71
|
+
as?: ElementType;
|
|
72
|
+
/** Adds default classes. */
|
|
73
|
+
className?: string;
|
|
74
|
+
/** Sets the default theme. */
|
|
75
|
+
defaultTheme?: ColorTheme['theme'] | string;
|
|
76
|
+
/** Sets the default for the `type` prop. */
|
|
77
|
+
type?: LinkProps['type'];
|
|
78
|
+
/** Add more theme options. */
|
|
79
|
+
theme?: {
|
|
80
|
+
[themeName: string]: {
|
|
81
|
+
/** Custom theme configuration - supports both multiline and regular link theme formats */
|
|
82
|
+
customTheme: Omit<ThemeColorOrClasses, 'themeColor'> & {
|
|
83
|
+
themeColor?: {
|
|
84
|
+
/** Example: `'after:[--theme-color:var(--color-blue-500)]'` */
|
|
85
|
+
fill: string;
|
|
86
|
+
/** Example: `'[--theme-color:var(--color-blue-500)]'` */
|
|
87
|
+
multilineFill: string;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
/** Additional CSS classes to apply */
|
|
91
|
+
className?: string;
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
export type ExtendedThemeNames<T extends ExtendedLinkConfig> = T['theme'] extends Record<string, unknown> ? keyof T['theme'] : never;
|
|
96
|
+
export type ExtendedLinkProps<TExtendedConfig extends ExtendedLinkConfig, TTag extends ElementType = typeof Anchor> = Omit<LinkProps<TTag>, 'theme' | 'customTheme'> & {
|
|
97
|
+
theme?: LinkProps<TTag>['theme'] | ExtendedThemeNames<TExtendedConfig>;
|
|
98
|
+
customTheme?: LinkProps<TTag>['customTheme'];
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* # createLink
|
|
102
|
+
* Creates an extended Link component with additional theme options.
|
|
103
|
+
*
|
|
104
|
+
* @param config - Configuration object defining new themes and defaults
|
|
105
|
+
* @returns A new Link component with extended theme support
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```tsx
|
|
109
|
+
* const MyLink = createLink({
|
|
110
|
+
* as: NextLink,
|
|
111
|
+
* className: 'font-bold',
|
|
112
|
+
* type: 'fill',
|
|
113
|
+
* theme: {
|
|
114
|
+
* primary: {
|
|
115
|
+
* customTheme: {
|
|
116
|
+
* fill: 'after:[--theme-color:var(--color-primary-500)]',
|
|
117
|
+
* multilineFill: '[--theme-color:var(--color-primary-500)]'
|
|
118
|
+
* },
|
|
119
|
+
* className: 'text-white'
|
|
120
|
+
* }
|
|
121
|
+
* }
|
|
122
|
+
* })
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
export declare function createLink<TExtendedConfig extends ExtendedLinkConfig>(config: TExtendedConfig): <TTag extends ElementType = typeof Anchor>({ theme, className, customTheme, type, as, ...props }: ExtendedLinkProps<TExtendedConfig, TTag>) => import("react/jsx-runtime").JSX.Element;
|
|
69
126
|
export {};
|
package/dist/components.esm.js
CHANGED
|
@@ -346,7 +346,7 @@ const lineLiftClasses = twJoin([
|
|
|
346
346
|
scaleYClasses,
|
|
347
347
|
'after:origin-bottom after:translate-y-1 after:scale-x-75 active:after:translate-y-0 active:after:scale-x-100 pointer-fine:hover:after:translate-y-0 pointer-fine:hover:after:scale-x-100',
|
|
348
348
|
]);
|
|
349
|
-
const fillClasses = twJoin(baseClasses, 'whitespace-nowrap transition-[
|
|
349
|
+
const fillClasses = twJoin(baseClasses, 'whitespace-nowrap transition-[transform,color] after:top-1/2 after:h-[calc(100%+0.05rem)] after:w-[calc(100%+0.25rem)] after:-translate-y-1/2 after:rounded after:ease-exponential active:text-zinc-50 pointer-fine:hover:text-zinc-50');
|
|
350
350
|
// Define theme-specific fill color transition classes
|
|
351
351
|
const getFillColorTransitionClasses = (theme = 'blue', customTheme) => {
|
|
352
352
|
let fillColorTransitionClasses = twJoin(fillClasses, 'transition-transform after:bg-(--theme-color)');
|
|
@@ -399,7 +399,7 @@ const getFillColorTransitionClasses = (theme = 'blue', customTheme) => {
|
|
|
399
399
|
};
|
|
400
400
|
// Define theme-specific fill center classes
|
|
401
401
|
const getFillCenterClasses = (theme = 'blue', customTheme) => {
|
|
402
|
-
let fillCenterColorClasses = twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-(--theme-color)/0 after:transition-[
|
|
402
|
+
let fillCenterColorClasses = twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-(--theme-color)/0 after:transition-[transform,background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-(--theme-color) pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-(--theme-color)');
|
|
403
403
|
switch (theme) {
|
|
404
404
|
case 'blue':
|
|
405
405
|
fillCenterColorClasses = twJoin(fillCenterColorClasses, 'after:[--theme-color:var(--color-ui-blue)]');
|
|
@@ -458,7 +458,7 @@ const multilineLineCenterClasses = twJoin([multilineXClasses, 'bg-[position:50%_
|
|
|
458
458
|
const multilineLineLiftClasses = twJoin(multilineLineClasses, 'bg-[size:auto_0px] focus-visible:bg-[size:auto_2px] active:bg-[size:auto_2px] pointer-fine:hover:bg-[size:auto_2px]');
|
|
459
459
|
const multilineFillBaseClasses = twJoin(multilineBaseClasses, 'rounded px-0.5 py-0.75 focus-visible:text-zinc-50 active:text-zinc-50 pointer-fine:hover:text-zinc-50');
|
|
460
460
|
const getMultilineFillColorClasses = (theme = 'blue', customTheme) => {
|
|
461
|
-
let multilineFillColorClasses = twJoin(multilineFillBaseClasses, 'from-(--theme-color) to-(--theme-color) transition-[background-
|
|
461
|
+
let multilineFillColorClasses = twJoin(multilineFillBaseClasses, 'from-(--theme-color) to-(--theme-color) transition-[background-size,color]');
|
|
462
462
|
switch (theme) {
|
|
463
463
|
case 'blue':
|
|
464
464
|
multilineFillColorClasses = twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-blue)]');
|
|
@@ -507,7 +507,7 @@ const getMultilineFillColorClasses = (theme = 'blue', customTheme) => {
|
|
|
507
507
|
return multilineFillColorClasses;
|
|
508
508
|
};
|
|
509
509
|
const getMultilineFillClasses = (theme = 'blue', customTheme) => {
|
|
510
|
-
let multilineFillColorClasses = twJoin(multilineFillBaseClasses, 'from-(--theme-color)/0 to-(--theme-color)/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-
|
|
510
|
+
let multilineFillColorClasses = twJoin(multilineFillBaseClasses, 'from-(--theme-color)/0 to-(--theme-color)/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size,background-image,color] focus-visible:from-(--theme-color) focus-visible:to-(--theme-color) focus-visible:bg-[size:100%_100%] active:from-(--theme-color) active:to-(--theme-color) active:bg-[size:100%_100%] contrast-more:from-(--theme-color)/0 pointer-fine:hover:from-(--theme-color) pointer-fine:hover:to-(--theme-color) pointer-fine:hover:bg-[size:100%_100%]');
|
|
511
511
|
switch (theme) {
|
|
512
512
|
case 'blue':
|
|
513
513
|
multilineFillColorClasses = twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-blue)]');
|
|
@@ -647,6 +647,71 @@ function Link({ as, className, customTheme, theme = 'blue', type, ...props }) {
|
|
|
647
647
|
const LinkElement = as || Anchor;
|
|
648
648
|
return jsx(LinkElement, { ...props, className: twMerge(linkClasses, className) });
|
|
649
649
|
}
|
|
650
|
+
/**
|
|
651
|
+
* # createLink
|
|
652
|
+
* Creates an extended Link component with additional theme options.
|
|
653
|
+
*
|
|
654
|
+
* @param config - Configuration object defining new themes and defaults
|
|
655
|
+
* @returns A new Link component with extended theme support
|
|
656
|
+
*
|
|
657
|
+
* @example
|
|
658
|
+
* ```tsx
|
|
659
|
+
* const MyLink = createLink({
|
|
660
|
+
* as: NextLink,
|
|
661
|
+
* className: 'font-bold',
|
|
662
|
+
* type: 'fill',
|
|
663
|
+
* theme: {
|
|
664
|
+
* primary: {
|
|
665
|
+
* customTheme: {
|
|
666
|
+
* fill: 'after:[--theme-color:var(--color-primary-500)]',
|
|
667
|
+
* multilineFill: '[--theme-color:var(--color-primary-500)]'
|
|
668
|
+
* },
|
|
669
|
+
* className: 'text-white'
|
|
670
|
+
* }
|
|
671
|
+
* }
|
|
672
|
+
* })
|
|
673
|
+
* ```
|
|
674
|
+
*/
|
|
675
|
+
function createLink(config) {
|
|
676
|
+
return function ExtendedLink({ theme, className, customTheme, type, as, ...props }) {
|
|
677
|
+
const finalType = type !== undefined ? type : config.type, finalTheme = theme !== undefined ? theme : config.defaultTheme;
|
|
678
|
+
const configClassName = config.className;
|
|
679
|
+
const shouldOverrideElement = !Boolean(as) && Boolean(config.as);
|
|
680
|
+
const linkProps = {
|
|
681
|
+
...props,
|
|
682
|
+
className: undefined,
|
|
683
|
+
customTheme: undefined,
|
|
684
|
+
type: finalType,
|
|
685
|
+
};
|
|
686
|
+
if (shouldOverrideElement) {
|
|
687
|
+
linkProps.as = config.as;
|
|
688
|
+
}
|
|
689
|
+
else if (as) {
|
|
690
|
+
linkProps.as = as;
|
|
691
|
+
}
|
|
692
|
+
if (finalTheme && typeof finalTheme === 'string' && config.theme && finalTheme in config.theme) {
|
|
693
|
+
const extendedTheme = config.theme[finalTheme];
|
|
694
|
+
if (customTheme)
|
|
695
|
+
return (jsx(Link, { ...linkProps, theme: 'custom', customTheme: customTheme, className: twMerge(configClassName, extendedTheme.className, className) }));
|
|
696
|
+
let resolvedCustomTheme;
|
|
697
|
+
if (extendedTheme.customTheme.themeColor) {
|
|
698
|
+
const isMultilineType = finalType ? finalType.includes('multiline') : false;
|
|
699
|
+
resolvedCustomTheme = {
|
|
700
|
+
themeColor: isMultilineType
|
|
701
|
+
? extendedTheme.customTheme.themeColor.multilineFill
|
|
702
|
+
: extendedTheme.customTheme.themeColor.fill,
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
else {
|
|
706
|
+
resolvedCustomTheme = {
|
|
707
|
+
classes: extendedTheme.customTheme.classes,
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
return (jsx(Link, { ...linkProps, theme: 'custom', customTheme: resolvedCustomTheme, className: twMerge(configClassName, extendedTheme.className, className) }));
|
|
711
|
+
}
|
|
712
|
+
return (jsx(Link, { ...linkProps, theme: finalTheme, className: twMerge(configClassName, className), customTheme: customTheme }));
|
|
713
|
+
};
|
|
714
|
+
}
|
|
650
715
|
|
|
651
716
|
/**
|
|
652
717
|
* # Button
|
|
@@ -732,9 +797,76 @@ function Button({ className, customTheme, gradient = false, padding = 'md', roun
|
|
|
732
797
|
themeClasses,
|
|
733
798
|
className,
|
|
734
799
|
]);
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
return jsx(
|
|
800
|
+
if ('href' in props && !props.as && props.href)
|
|
801
|
+
return jsx(Button$1, { ...props, as: Anchor, className: buttonClasses });
|
|
802
|
+
return jsx(Button$1, { ...props, className: buttonClasses });
|
|
803
|
+
}
|
|
804
|
+
/**
|
|
805
|
+
* # createButton
|
|
806
|
+
* Creates an extended Button component with additional theme options.
|
|
807
|
+
*
|
|
808
|
+
* @param extendedThemes - Configuration object defining new themes
|
|
809
|
+
* @returns A new Button component with extended theme support
|
|
810
|
+
*
|
|
811
|
+
* @example
|
|
812
|
+
* ```tsx
|
|
813
|
+
* const MyButton = createButton({
|
|
814
|
+
* as: {
|
|
815
|
+
* default: 'div',
|
|
816
|
+
* link: NextLink
|
|
817
|
+
* },
|
|
818
|
+
* className: 'min-w-64',
|
|
819
|
+
* padding: 'sm',
|
|
820
|
+
* rounded: 'full',
|
|
821
|
+
* theme: {
|
|
822
|
+
* primary: {
|
|
823
|
+
* customTheme: { themeColor: '[--theme-color:var(--color-primary-500)]' },
|
|
824
|
+
* className: 'text-white'
|
|
825
|
+
* }
|
|
826
|
+
* }
|
|
827
|
+
* })
|
|
828
|
+
* ```
|
|
829
|
+
*/
|
|
830
|
+
function createButton(config) {
|
|
831
|
+
return function ExtendedButton({ theme, className, customTheme, gradient, padding, rounded, as, ...props }) {
|
|
832
|
+
const finalGradient = gradient !== undefined ? gradient : config.gradient, finalPadding = padding !== undefined ? padding : config.padding, finalRounded = rounded !== undefined ? rounded : config.rounded, finalTheme = theme !== undefined ? theme : config.defaultTheme;
|
|
833
|
+
const configClassName = config.className;
|
|
834
|
+
const shouldOverrideElement = !Boolean(as) && Boolean(config.as);
|
|
835
|
+
const getOverrideElement = () => {
|
|
836
|
+
if (!config.as)
|
|
837
|
+
return undefined;
|
|
838
|
+
if (typeof config.as === 'function' || typeof config.as === 'string')
|
|
839
|
+
return config.as;
|
|
840
|
+
const hasHref = 'href' in props && props.href;
|
|
841
|
+
if (hasHref && config.as.link) {
|
|
842
|
+
return config.as.link;
|
|
843
|
+
}
|
|
844
|
+
else if (!hasHref && config.as.default) {
|
|
845
|
+
return config.as.default;
|
|
846
|
+
}
|
|
847
|
+
return undefined;
|
|
848
|
+
};
|
|
849
|
+
const buttonProps = {
|
|
850
|
+
...props,
|
|
851
|
+
className: undefined,
|
|
852
|
+
customTheme: undefined,
|
|
853
|
+
gradient: finalGradient,
|
|
854
|
+
padding: finalPadding,
|
|
855
|
+
rounded: finalRounded,
|
|
856
|
+
};
|
|
857
|
+
if (shouldOverrideElement) {
|
|
858
|
+
const overrideElement = getOverrideElement();
|
|
859
|
+
if (overrideElement)
|
|
860
|
+
buttonProps.as = overrideElement;
|
|
861
|
+
}
|
|
862
|
+
else if (as)
|
|
863
|
+
buttonProps.as = as;
|
|
864
|
+
if (finalTheme && typeof finalTheme === 'string' && config.theme && finalTheme in config.theme) {
|
|
865
|
+
const extendedTheme = config.theme[finalTheme];
|
|
866
|
+
return (jsx(Button, { ...buttonProps, theme: 'custom', customTheme: customTheme || extendedTheme.customTheme, className: twMerge(configClassName, extendedTheme.className, className) }));
|
|
867
|
+
}
|
|
868
|
+
return (jsx(Button, { ...buttonProps, theme: finalTheme, className: twMerge(configClassName, className), customTheme: customTheme }));
|
|
869
|
+
};
|
|
738
870
|
}
|
|
739
871
|
|
|
740
872
|
function ChevronDown(props) {
|
|
@@ -749,10 +881,8 @@ function xmark(props) {
|
|
|
749
881
|
return (jsx("svg", { viewBox: '0 0 64 64', ...props, children: jsx("path", { d: 'M1,63c0.7,0.7,1.6,1,2.6,1s1.9-0.3,2.6-1L32,37.1L57.8,63c0.7,0.7,1.5,1,2.5,1c1,0,1.9-0.3,2.6-1c0.7-0.7,1-1.6,1-2.6 c0-1-0.3-1.8-1-2.5L37.1,32L63,6.2c0.7-0.7,1-1.6,1-2.6S63.7,1.7,63,1c-0.7-0.7-1.6-1-2.6-1c-1,0-1.8,0.3-2.5,1L32,26.9L6.2,1 C5.5,0.3,4.6,0,3.6,0C2.6,0,1.7,0.3,1,1C0.3,1.7,0,2.6,0,3.6c0,1,0.3,1.9,1,2.6L26.9,32L1,57.8c-0.7,0.7-1,1.5-1,2.6 C0,61.4,0.3,62.3,1,63z' }) }));
|
|
750
882
|
}
|
|
751
883
|
|
|
752
|
-
function DetailsSummary({ arrow = true,
|
|
753
|
-
return (
|
|
754
|
-
// @ts-expect-error Button has some extra props
|
|
755
|
-
jsx(DisclosureButton, { ...props, as: as || (Button), className: twMerge('w-full', className, Boolean(arrow) && 'grid grid-cols-[1fr_1rem] gap-2'), role: 'summary', children: bag => (jsxs(Fragment$1, { children: [typeof children === 'function' ? children(bag) : children, arrow &&
|
|
884
|
+
function DetailsSummary({ arrow = true, children, className, ...props }) {
|
|
885
|
+
return (jsx(DisclosureButton, { ...props, as: (Button), className: twMerge('w-full', className, Boolean(arrow) && 'grid grid-cols-[1fr_1rem] gap-2'), role: 'summary', children: bag => (jsxs(Fragment$1, { children: [typeof children === 'function' ? children(bag) : children, arrow &&
|
|
756
886
|
(typeof arrow === 'boolean' ? (jsx(ChevronDown, { className: 'absolute top-1/2 right-3 block w-4 -translate-y-1/2' })) : (arrow))] })) }));
|
|
757
887
|
}
|
|
758
888
|
function DetailsBody({ children, className, ...props }) {
|
|
@@ -769,7 +899,7 @@ function DropDownButton({ arrow = true, as, children, className, ...props }) {
|
|
|
769
899
|
function DropDownItem({ as, ...props }) {
|
|
770
900
|
return jsx(MenuItem, { as: as || 'div', ...props });
|
|
771
901
|
}
|
|
772
|
-
function DropDownItems({ anchor, children, className, style, ...props }) {
|
|
902
|
+
function DropDownItems({ anchor, children, className, containerClassName, style, ...props }) {
|
|
773
903
|
const getAnchorProps = () => {
|
|
774
904
|
let initialAnchor = { gap: '1rem', padding: '1rem', to: 'bottom start' };
|
|
775
905
|
if (anchor) {
|
|
@@ -781,11 +911,11 @@ function DropDownItems({ anchor, children, className, style, ...props }) {
|
|
|
781
911
|
return initialAnchor;
|
|
782
912
|
};
|
|
783
913
|
const anchorProps = getAnchorProps();
|
|
784
|
-
return (jsx(MenuItems, { ...props, anchor: anchorProps, className: 'grid grid-rows-1fr rounded-xl shadow-xl transition-rows duration-500 ease-exponential data-closed:grid-rows-0fr', transition: true, style: { ...style, minWidth: 'var(--button-width)' }, children: bag => (jsx("div", { className: 'overflow-y-
|
|
914
|
+
return (jsx(MenuItems, { ...props, anchor: anchorProps, className: twMerge('grid grid-rows-1fr rounded-xl shadow-xl transition-rows duration-500 ease-exponential data-closed:grid-rows-0fr', containerClassName), transition: true, style: { ...style, minWidth: 'var(--button-width)' }, children: bag => (jsx("div", { className: 'overflow-y-scroll', children: jsx("div", { className: twMerge('rounded-xl bg-neutral-50/20 px-6 py-5 backdrop-blur-md backdrop-brightness-150', className), children: typeof children === 'function' ? children(bag) : children }) })) }));
|
|
785
915
|
}
|
|
786
916
|
function DropDownSection({ children, label, labelProps, separatorAbove, separatorBelow, ...props }) {
|
|
787
917
|
const { labelClassName, ...restLabelProps } = { labelClassName: labelProps?.className || '', ...labelProps };
|
|
788
|
-
return (jsx(MenuSection, { ...props, children: sectionBag => (jsxs(Fragment$1, { children: [separatorAbove && jsx(DropDownSeparator, {}), jsx(MenuHeading, { ...restLabelProps, className: headingBag => twMerge('text-[size:larger] font-bold', typeof labelClassName === 'function' ? labelClassName(headingBag) : labelClassName), children: label }), typeof children === 'function' ? children(sectionBag) : children, separatorBelow && jsx(DropDownSeparator, {})] })) }));
|
|
918
|
+
return (jsx(MenuSection, { ...props, children: sectionBag => (jsxs(Fragment$1, { children: [separatorAbove && jsx(DropDownSeparator, {}), label && (jsx(MenuHeading, { ...restLabelProps, className: headingBag => twMerge('text-[size:larger] font-bold', typeof labelClassName === 'function' ? labelClassName(headingBag) : labelClassName), children: label })), typeof children === 'function' ? children(sectionBag) : children, separatorBelow && jsx(DropDownSeparator, {})] })) }));
|
|
789
919
|
}
|
|
790
920
|
function DropDownSeparator({ className, ...props }) {
|
|
791
921
|
return (jsx(MenuSeparator, { ...props, className: bag => twMerge('my-4 block h-px rounded-full bg-neutral-950/20', typeof className === 'function' ? className(bag) : className) }));
|
|
@@ -3210,7 +3340,7 @@ function Input({ checked, className, defaultValue, description, descriptionProps
|
|
|
3210
3340
|
: descriptionProps?.className), children: description }))] }));
|
|
3211
3341
|
}
|
|
3212
3342
|
|
|
3213
|
-
function SubmitButton({ children, className, customTheme, error, incomplete, loading, success, type
|
|
3343
|
+
function SubmitButton({ children, className, customTheme, error, incomplete, loading, success, type, ...props }) {
|
|
3214
3344
|
const [formStatus] = useFormStatus();
|
|
3215
3345
|
const getFormStatusButtonClasses = () => {
|
|
3216
3346
|
switch (formStatus) {
|
|
@@ -3258,9 +3388,9 @@ function SubmitButton({ children, className, customTheme, error, incomplete, loa
|
|
|
3258
3388
|
}
|
|
3259
3389
|
};
|
|
3260
3390
|
const dataFormState = getDataFormState();
|
|
3261
|
-
return (jsx(Button, { ...props, ...dataFormState,
|
|
3391
|
+
return (jsx(Button, { ...props, ...dataFormState, className: twMerge([formStatusButtonClasses, 'w-full text-white data-loading:text-black', className]), customTheme: {
|
|
3262
3392
|
themeColor: twMerge('data-error:[--theme-color:var(--color-ui-red)] data-incomplete:[--theme-color:var(--color-ui-grey)] data-loading:[--theme-color:var(--color-ui-yellow)] data-readonly:[--theme-color:var(--color-ui-grey)] data-ready:[--theme-color:var(--color-ui-blue)] data-success:[--theme-color:var(--color-ui-green)]', customTheme?.themeColor),
|
|
3263
|
-
}, theme: 'custom', type: type, children: buttonText }));
|
|
3393
|
+
}, theme: 'custom', type: type || 'submit', children: buttonText }));
|
|
3264
3394
|
}
|
|
3265
3395
|
|
|
3266
3396
|
function Textarea({ className, defaultValue, description, descriptionProps, disabled, fieldProps, invalid = true, label, labelProps, name, onBlur, onChange, placeholder, ref, required = true, value, ...props }) {
|
|
@@ -3602,5 +3732,5 @@ function Time({ children, dateObject, dateTime, day, hours, milliseconds, minute
|
|
|
3602
3732
|
return (jsx("time", { dateTime: dateAndTime, ref: ref, ...props, children: dateDisplay }));
|
|
3603
3733
|
}
|
|
3604
3734
|
|
|
3605
|
-
export { Anchor, Button, Details, DetailsBody, DetailsSummary, DropDown, DropDownButton, DropDownItem, DropDownItems, DropDownSection, DropDownSeparator, Fieldset, Form, Ghost, Heading, Input, Link, Modal, ModalDialog, ModalTrigger, SubmitButton, Textarea, Time, Tooltip, TooltipPanel, TooltipTrigger };
|
|
3735
|
+
export { Anchor, Button, Details, DetailsBody, DetailsSummary, DropDown, DropDownButton, DropDownItem, DropDownItems, DropDownSection, DropDownSeparator, Fieldset, Form, Ghost, Heading, Input, Link, Modal, ModalDialog, ModalTrigger, SubmitButton, Textarea, Time, Tooltip, TooltipPanel, TooltipTrigger, createButton, createLink };
|
|
3606
3736
|
//# sourceMappingURL=components.esm.js.map
|