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/dist/index.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-[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');
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-[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)');
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-size_color]');
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-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%]');
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
- const ButtonElement = 'as' in props ? props.as : props.href ? Anchor : Button$1;
736
- const { as, ...restProps } = 'as' in props ? props : { ...props, as: undefined };
737
- return jsx(ButtonElement, { ...restProps, className: buttonClasses });
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, as, children, className, ...props }) {
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-hidden', children: 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 }) })) }));
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 = 'submit', ...props }) {
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, as: 'button', className: twMerge([formStatusButtonClasses, 'w-full text-white data-loading:text-black', className]), customTheme: {
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=index.esm.js.map