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.
@@ -366,7 +366,7 @@ const lineLiftClasses = tailwindMerge.twJoin([
366
366
  scaleYClasses,
367
367
  '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',
368
368
  ]);
369
- const fillClasses = tailwindMerge.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');
369
+ const fillClasses = tailwindMerge.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');
370
370
  // Define theme-specific fill color transition classes
371
371
  const getFillColorTransitionClasses = (theme = 'blue', customTheme) => {
372
372
  let fillColorTransitionClasses = tailwindMerge.twJoin(fillClasses, 'transition-transform after:bg-(--theme-color)');
@@ -419,7 +419,7 @@ const getFillColorTransitionClasses = (theme = 'blue', customTheme) => {
419
419
  };
420
420
  // Define theme-specific fill center classes
421
421
  const getFillCenterClasses = (theme = 'blue', customTheme) => {
422
- let fillCenterColorClasses = tailwindMerge.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)');
422
+ let fillCenterColorClasses = tailwindMerge.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)');
423
423
  switch (theme) {
424
424
  case 'blue':
425
425
  fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, 'after:[--theme-color:var(--color-ui-blue)]');
@@ -478,7 +478,7 @@ const multilineLineCenterClasses = tailwindMerge.twJoin([multilineXClasses, 'bg-
478
478
  const multilineLineLiftClasses = tailwindMerge.twJoin(multilineLineClasses, 'bg-[size:auto_0px] focus-visible:bg-[size:auto_2px] active:bg-[size:auto_2px] pointer-fine:hover:bg-[size:auto_2px]');
479
479
  const multilineFillBaseClasses = tailwindMerge.twJoin(multilineBaseClasses, 'rounded px-0.5 py-0.75 focus-visible:text-zinc-50 active:text-zinc-50 pointer-fine:hover:text-zinc-50');
480
480
  const getMultilineFillColorClasses = (theme = 'blue', customTheme) => {
481
- let multilineFillColorClasses = tailwindMerge.twJoin(multilineFillBaseClasses, 'from-(--theme-color) to-(--theme-color) transition-[background-size_color]');
481
+ let multilineFillColorClasses = tailwindMerge.twJoin(multilineFillBaseClasses, 'from-(--theme-color) to-(--theme-color) transition-[background-size,color]');
482
482
  switch (theme) {
483
483
  case 'blue':
484
484
  multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-blue)]');
@@ -527,7 +527,7 @@ const getMultilineFillColorClasses = (theme = 'blue', customTheme) => {
527
527
  return multilineFillColorClasses;
528
528
  };
529
529
  const getMultilineFillClasses = (theme = 'blue', customTheme) => {
530
- let multilineFillColorClasses = tailwindMerge.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%]');
530
+ let multilineFillColorClasses = tailwindMerge.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%]');
531
531
  switch (theme) {
532
532
  case 'blue':
533
533
  multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-blue)]');
@@ -667,6 +667,71 @@ function Link({ as, className, customTheme, theme = 'blue', type, ...props }) {
667
667
  const LinkElement = as || Anchor;
668
668
  return jsxRuntime.jsx(LinkElement, { ...props, className: twMerge(linkClasses, className) });
669
669
  }
670
+ /**
671
+ * # createLink
672
+ * Creates an extended Link component with additional theme options.
673
+ *
674
+ * @param config - Configuration object defining new themes and defaults
675
+ * @returns A new Link component with extended theme support
676
+ *
677
+ * @example
678
+ * ```tsx
679
+ * const MyLink = createLink({
680
+ * as: NextLink,
681
+ * className: 'font-bold',
682
+ * type: 'fill',
683
+ * theme: {
684
+ * primary: {
685
+ * customTheme: {
686
+ * fill: 'after:[--theme-color:var(--color-primary-500)]',
687
+ * multilineFill: '[--theme-color:var(--color-primary-500)]'
688
+ * },
689
+ * className: 'text-white'
690
+ * }
691
+ * }
692
+ * })
693
+ * ```
694
+ */
695
+ function createLink(config) {
696
+ return function ExtendedLink({ theme, className, customTheme, type, as, ...props }) {
697
+ const finalType = type !== undefined ? type : config.type, finalTheme = theme !== undefined ? theme : config.defaultTheme;
698
+ const configClassName = config.className;
699
+ const shouldOverrideElement = !Boolean(as) && Boolean(config.as);
700
+ const linkProps = {
701
+ ...props,
702
+ className: undefined,
703
+ customTheme: undefined,
704
+ type: finalType,
705
+ };
706
+ if (shouldOverrideElement) {
707
+ linkProps.as = config.as;
708
+ }
709
+ else if (as) {
710
+ linkProps.as = as;
711
+ }
712
+ if (finalTheme && typeof finalTheme === 'string' && config.theme && finalTheme in config.theme) {
713
+ const extendedTheme = config.theme[finalTheme];
714
+ if (customTheme)
715
+ return (jsxRuntime.jsx(Link, { ...linkProps, theme: 'custom', customTheme: customTheme, className: twMerge(configClassName, extendedTheme.className, className) }));
716
+ let resolvedCustomTheme;
717
+ if (extendedTheme.customTheme.themeColor) {
718
+ const isMultilineType = finalType ? finalType.includes('multiline') : false;
719
+ resolvedCustomTheme = {
720
+ themeColor: isMultilineType
721
+ ? extendedTheme.customTheme.themeColor.multilineFill
722
+ : extendedTheme.customTheme.themeColor.fill,
723
+ };
724
+ }
725
+ else {
726
+ resolvedCustomTheme = {
727
+ classes: extendedTheme.customTheme.classes,
728
+ };
729
+ }
730
+ return (jsxRuntime.jsx(Link, { ...linkProps, theme: 'custom', customTheme: resolvedCustomTheme, className: twMerge(configClassName, extendedTheme.className, className) }));
731
+ }
732
+ return (jsxRuntime.jsx(Link, { ...linkProps, theme: finalTheme, className: twMerge(configClassName, className), customTheme: customTheme }));
733
+ };
734
+ }
670
735
 
671
736
  /**
672
737
  * # Button
@@ -752,9 +817,76 @@ function Button({ className, customTheme, gradient = false, padding = 'md', roun
752
817
  themeClasses,
753
818
  className,
754
819
  ]);
755
- const ButtonElement = 'as' in props ? props.as : props.href ? Anchor : react.Button;
756
- const { as, ...restProps } = 'as' in props ? props : { ...props, as: undefined };
757
- return jsxRuntime.jsx(ButtonElement, { ...restProps, className: buttonClasses });
820
+ if ('href' in props && !props.as && props.href)
821
+ return jsxRuntime.jsx(react.Button, { ...props, as: Anchor, className: buttonClasses });
822
+ return jsxRuntime.jsx(react.Button, { ...props, className: buttonClasses });
823
+ }
824
+ /**
825
+ * # createButton
826
+ * Creates an extended Button component with additional theme options.
827
+ *
828
+ * @param extendedThemes - Configuration object defining new themes
829
+ * @returns A new Button component with extended theme support
830
+ *
831
+ * @example
832
+ * ```tsx
833
+ * const MyButton = createButton({
834
+ * as: {
835
+ * default: 'div',
836
+ * link: NextLink
837
+ * },
838
+ * className: 'min-w-64',
839
+ * padding: 'sm',
840
+ * rounded: 'full',
841
+ * theme: {
842
+ * primary: {
843
+ * customTheme: { themeColor: '[--theme-color:var(--color-primary-500)]' },
844
+ * className: 'text-white'
845
+ * }
846
+ * }
847
+ * })
848
+ * ```
849
+ */
850
+ function createButton(config) {
851
+ return function ExtendedButton({ theme, className, customTheme, gradient, padding, rounded, as, ...props }) {
852
+ 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;
853
+ const configClassName = config.className;
854
+ const shouldOverrideElement = !Boolean(as) && Boolean(config.as);
855
+ const getOverrideElement = () => {
856
+ if (!config.as)
857
+ return undefined;
858
+ if (typeof config.as === 'function' || typeof config.as === 'string')
859
+ return config.as;
860
+ const hasHref = 'href' in props && props.href;
861
+ if (hasHref && config.as.link) {
862
+ return config.as.link;
863
+ }
864
+ else if (!hasHref && config.as.default) {
865
+ return config.as.default;
866
+ }
867
+ return undefined;
868
+ };
869
+ const buttonProps = {
870
+ ...props,
871
+ className: undefined,
872
+ customTheme: undefined,
873
+ gradient: finalGradient,
874
+ padding: finalPadding,
875
+ rounded: finalRounded,
876
+ };
877
+ if (shouldOverrideElement) {
878
+ const overrideElement = getOverrideElement();
879
+ if (overrideElement)
880
+ buttonProps.as = overrideElement;
881
+ }
882
+ else if (as)
883
+ buttonProps.as = as;
884
+ if (finalTheme && typeof finalTheme === 'string' && config.theme && finalTheme in config.theme) {
885
+ const extendedTheme = config.theme[finalTheme];
886
+ return (jsxRuntime.jsx(Button, { ...buttonProps, theme: 'custom', customTheme: customTheme || extendedTheme.customTheme, className: twMerge(configClassName, extendedTheme.className, className) }));
887
+ }
888
+ return (jsxRuntime.jsx(Button, { ...buttonProps, theme: finalTheme, className: twMerge(configClassName, className), customTheme: customTheme }));
889
+ };
758
890
  }
759
891
 
760
892
  function ChevronDown(props) {
@@ -769,10 +901,8 @@ function xmark(props) {
769
901
  return (jsxRuntime.jsx("svg", { viewBox: '0 0 64 64', ...props, children: jsxRuntime.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' }) }));
770
902
  }
771
903
 
772
- function DetailsSummary({ arrow = true, as, children, className, ...props }) {
773
- return (
774
- // @ts-expect-error Button has some extra props
775
- jsxRuntime.jsx(react.DisclosureButton, { ...props, as: as || (Button), className: twMerge('w-full', className, Boolean(arrow) && 'grid grid-cols-[1fr_1rem] gap-2'), role: 'summary', children: bag => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [typeof children === 'function' ? children(bag) : children, arrow &&
904
+ function DetailsSummary({ arrow = true, children, className, ...props }) {
905
+ return (jsxRuntime.jsx(react.DisclosureButton, { ...props, as: (Button), className: twMerge('w-full', className, Boolean(arrow) && 'grid grid-cols-[1fr_1rem] gap-2'), role: 'summary', children: bag => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [typeof children === 'function' ? children(bag) : children, arrow &&
776
906
  (typeof arrow === 'boolean' ? (jsxRuntime.jsx(ChevronDown, { className: 'absolute top-1/2 right-3 block w-4 -translate-y-1/2' })) : (arrow))] })) }));
777
907
  }
778
908
  function DetailsBody({ children, className, ...props }) {
@@ -789,7 +919,7 @@ function DropDownButton({ arrow = true, as, children, className, ...props }) {
789
919
  function DropDownItem({ as, ...props }) {
790
920
  return jsxRuntime.jsx(react.MenuItem, { as: as || 'div', ...props });
791
921
  }
792
- function DropDownItems({ anchor, children, className, style, ...props }) {
922
+ function DropDownItems({ anchor, children, className, containerClassName, style, ...props }) {
793
923
  const getAnchorProps = () => {
794
924
  let initialAnchor = { gap: '1rem', padding: '1rem', to: 'bottom start' };
795
925
  if (anchor) {
@@ -801,11 +931,11 @@ function DropDownItems({ anchor, children, className, style, ...props }) {
801
931
  return initialAnchor;
802
932
  };
803
933
  const anchorProps = getAnchorProps();
804
- return (jsxRuntime.jsx(react.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 => (jsxRuntime.jsx("div", { className: 'overflow-y-hidden', children: jsxRuntime.jsx("div", { className: twMerge('bg-neutral-50/20 px-6 py-5 backdrop-blur-md backdrop-brightness-150', className), children: typeof children === 'function' ? children(bag) : children }) })) }));
934
+ return (jsxRuntime.jsx(react.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 => (jsxRuntime.jsx("div", { className: 'overflow-y-scroll', children: jsxRuntime.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 }) })) }));
805
935
  }
806
936
  function DropDownSection({ children, label, labelProps, separatorAbove, separatorBelow, ...props }) {
807
937
  const { labelClassName, ...restLabelProps } = { labelClassName: labelProps?.className || '', ...labelProps };
808
- return (jsxRuntime.jsx(react.MenuSection, { ...props, children: sectionBag => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [separatorAbove && jsxRuntime.jsx(DropDownSeparator, {}), jsxRuntime.jsx(react.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 && jsxRuntime.jsx(DropDownSeparator, {})] })) }));
938
+ return (jsxRuntime.jsx(react.MenuSection, { ...props, children: sectionBag => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [separatorAbove && jsxRuntime.jsx(DropDownSeparator, {}), label && (jsxRuntime.jsx(react.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 && jsxRuntime.jsx(DropDownSeparator, {})] })) }));
809
939
  }
810
940
  function DropDownSeparator({ className, ...props }) {
811
941
  return (jsxRuntime.jsx(react.MenuSeparator, { ...props, className: bag => twMerge('my-4 block h-px rounded-full bg-neutral-950/20', typeof className === 'function' ? className(bag) : className) }));
@@ -3230,7 +3360,7 @@ function Input({ checked, className, defaultValue, description, descriptionProps
3230
3360
  : descriptionProps?.className), children: description }))] }));
3231
3361
  }
3232
3362
 
3233
- function SubmitButton({ children, className, customTheme, error, incomplete, loading, success, type = 'submit', ...props }) {
3363
+ function SubmitButton({ children, className, customTheme, error, incomplete, loading, success, type, ...props }) {
3234
3364
  const [formStatus] = useFormStatus();
3235
3365
  const getFormStatusButtonClasses = () => {
3236
3366
  switch (formStatus) {
@@ -3278,9 +3408,9 @@ function SubmitButton({ children, className, customTheme, error, incomplete, loa
3278
3408
  }
3279
3409
  };
3280
3410
  const dataFormState = getDataFormState();
3281
- return (jsxRuntime.jsx(Button, { ...props, ...dataFormState, as: 'button', className: twMerge([formStatusButtonClasses, 'w-full text-white data-loading:text-black', className]), customTheme: {
3411
+ return (jsxRuntime.jsx(Button, { ...props, ...dataFormState, className: twMerge([formStatusButtonClasses, 'w-full text-white data-loading:text-black', className]), customTheme: {
3282
3412
  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),
3283
- }, theme: 'custom', type: type, children: buttonText }));
3413
+ }, theme: 'custom', type: type || 'submit', children: buttonText }));
3284
3414
  }
3285
3415
 
3286
3416
  function Textarea({ className, defaultValue, description, descriptionProps, disabled, fieldProps, invalid = true, label, labelProps, name, onBlur, onChange, placeholder, ref, required = true, value, ...props }) {
@@ -3648,4 +3778,6 @@ exports.Time = Time;
3648
3778
  exports.Tooltip = Tooltip;
3649
3779
  exports.TooltipPanel = TooltipPanel;
3650
3780
  exports.TooltipTrigger = TooltipTrigger;
3781
+ exports.createButton = createButton;
3782
+ exports.createLink = createLink;
3651
3783
  //# sourceMappingURL=components.js.map