@ably/ui 17.14.0 → 18.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/Badge.js +1 -1
- package/core/Badge.js.map +1 -1
- package/core/FeaturedLink.js +1 -1
- package/core/FeaturedLink.js.map +1 -1
- package/core/Flash.js +1 -1
- package/core/Flash.js.map +1 -1
- package/core/ProductTile/ProductLabel.js +1 -1
- package/core/ProductTile/ProductLabel.js.map +1 -1
- package/core/ProductTile/data.js +1 -1
- package/core/ProductTile/data.js.map +1 -1
- package/core/SegmentedControl.js +1 -1
- package/core/SegmentedControl.js.map +1 -1
- package/core/SessionData.js +2 -0
- package/core/SessionData.js.map +1 -0
- package/core/TabMenu.js +1 -1
- package/core/TabMenu.js.map +1 -1
- package/core/Toggle.js +1 -1
- package/core/Toggle.js.map +1 -1
- package/core/scripts.js +1 -1
- package/core/scripts.js.map +1 -1
- package/core/styles/buttons.css +6 -6
- package/core/styles/colors/types.js +1 -1
- package/core/styles/colors/types.js.map +1 -1
- package/core/styles/forms.css +5 -5
- package/core/styles/legacy-buttons.css +8 -8
- package/core/styles/properties.css +2 -2
- package/core/styles/text.css +2 -2
- package/index.d.ts +91 -63
- package/package.json +9 -9
- package/tailwind.config.js +2 -2
- package/core/ConnectStateWrapper.js +0 -2
- package/core/ConnectStateWrapper.js.map +0 -1
- package/core/remote-blogs-posts.js +0 -2
- package/core/remote-blogs-posts.js.map +0 -1
- package/core/remote-data-store.js +0 -2
- package/core/remote-data-store.js.map +0 -1
- package/core/remote-session-data.js +0 -2
- package/core/remote-session-data.js.map +0 -1
package/core/Badge.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useMemo}from"react";import Icon from"./Icon";import cn from"./utils/cn";const defaultIconSizeByBadgeSize={lg:"16px",md:"15px",sm:"14px",xs:"13px"};const Badge=({size="md",color="neutral",iconBefore,iconAfter,className,childClassName,children,disabled=false,focusable=false,hoverable=false,iconSize,ariaLabel})=>{const sizeClass=useMemo(()=>{switch(size){case"xs":return"px-2 py-0 text-[10px] leading-tight";case"sm":return"px-2 py-0.5 text-[10px] leading-tight";case"md":return"px-2.5 py-0.5 text-[11px] leading-normal";case"lg":return"px-3 py-[0.1875rem] text-[12px] leading-normal"}},[size]);const childClass=useMemo(()=>{switch(size){case"xs":case"sm":return"leading-[18px]";case"md":case"lg":return"leading-[20px]"}},[size]);const colorClass=useMemo(()=>{switch(color){case"neutral":return"text-neutral-900 dark:text-neutral-400";case"violet":return"text-violet-400";case"orange":return"text-orange-600";case"yellow":return"text-yellow-600";case"green":return"text-green-600";case"blue":return"text-blue-600";case"pink":return"text-pink-600";case"red":return"text-orange-700"}},[color]);const computedIconSize=iconSize??defaultIconSizeByBadgeSize[size];return React.createElement("div",{className:cn("inline-flex bg-neutral-100 dark:bg-neutral-1200 rounded-2xl gap-1 items-center focus-base transition-colors select-none font-semibold",sizeClass,colorClass,{"focus-base":focusable},{"hover:bg-neutral-300 hover:dark:bg-neutral-1000 active:bg-neutral-300 dark:active:bg-neutral-1000":hoverable},{"cursor-not-allowed disabled:text-gui-
|
|
1
|
+
import React,{useMemo}from"react";import Icon from"./Icon";import cn from"./utils/cn";const defaultIconSizeByBadgeSize={lg:"16px",md:"15px",sm:"14px",xs:"13px"};const Badge=({size="md",color="neutral",iconBefore,iconAfter,className,childClassName,children,disabled=false,focusable=false,hoverable=false,iconSize,ariaLabel})=>{const sizeClass=useMemo(()=>{switch(size){case"xs":return"px-2 py-0 text-[10px] leading-tight";case"sm":return"px-2 py-0.5 text-[10px] leading-tight";case"md":return"px-2.5 py-0.5 text-[11px] leading-normal";case"lg":return"px-3 py-[0.1875rem] text-[12px] leading-normal"}},[size]);const childClass=useMemo(()=>{switch(size){case"xs":case"sm":return"leading-[18px]";case"md":case"lg":return"leading-[20px]"}},[size]);const colorClass=useMemo(()=>{switch(color){case"neutral":return"text-neutral-900 dark:text-neutral-400";case"violet":return"text-violet-400";case"orange":return"text-orange-600";case"yellow":return"text-yellow-600";case"green":return"text-green-600";case"blue":return"text-blue-600";case"pink":return"text-pink-600";case"red":return"text-orange-700"}},[color]);const computedIconSize=iconSize??defaultIconSizeByBadgeSize[size];return React.createElement("div",{className:cn("inline-flex bg-neutral-100 dark:bg-neutral-1200 rounded-2xl gap-1 items-center focus-base transition-colors select-none font-semibold",sizeClass,colorClass,{"focus-base":focusable},{"hover:bg-neutral-300 hover:dark:bg-neutral-1000 active:bg-neutral-300 dark:active:bg-neutral-1000":hoverable},{"cursor-not-allowed disabled:text-gui-disabled-light dark:disabled:text-gui-disabled-dark":disabled},className),tabIndex:focusable?0:undefined,role:focusable?"button":undefined,"aria-label":focusable||hoverable?ariaLabel:undefined},iconBefore?React.createElement(Icon,{name:iconBefore,size:computedIconSize,color:colorClass}):null,React.createElement("span",{className:cn("whitespace-nowrap tracking-[0.04em]",childClass,childClassName)},children),iconAfter?React.createElement(Icon,{name:iconAfter,size:computedIconSize,color:colorClass}):null)};export default Badge;
|
|
2
2
|
//# sourceMappingURL=Badge.js.map
|
package/core/Badge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Badge.tsx"],"sourcesContent":["import React, { PropsWithChildren, useMemo } from \"react\";\nimport { IconName, IconSize } from \"./Icon/types\";\nimport Icon from \"./Icon\";\nimport cn from \"./utils/cn\";\nimport { ColorClassColorGroups } from \"./styles/colors/types\";\n\n/**\n * Props for the Badge component.\n */\nexport interface BadgeProps {\n /**\n * The size of the badge. Can be one of \"xs\", \"sm\", \"md\", or \"lg\".\n */\n size?: \"xs\" | \"sm\" | \"md\" | \"lg\";\n\n /**\n * The color of the badge. Can be a value from ColorClassColorGroups or \"red\".\n */\n color?: ColorClassColorGroups | \"red\";\n\n /**\n * The name of the icon to be displayed before the children in the badge.\n */\n iconBefore?: IconName;\n\n /**\n * The name of the icon to be displayed after the children in the badge.\n */\n iconAfter?: IconName;\n\n /**\n * Additional CSS class names to apply to the badge.\n */\n className?: string;\n\n /**\n * Whether the badge is disabled. Defaults to false.\n */\n disabled?: boolean;\n\n /**\n * Whether the badge is focusable. Defaults to false.\n */\n focusable?: boolean;\n\n /**\n * Whether the badge is hoverable. Defaults to false.\n */\n hoverable?: boolean;\n\n /**\n * The size of the icons in the badge. If not provided, it will be derived from the badge size.\n */\n iconSize?: IconSize;\n\n /**\n * Accessible label for the badge when interactive\n */\n ariaLabel?: string;\n\n /**\n * Additional CSS class names to apply to the children of the badge.\n */\n childClassName?: string;\n}\n\nconst defaultIconSizeByBadgeSize: Record<\n NonNullable<BadgeProps[\"size\"]>,\n IconSize\n> = {\n lg: \"16px\",\n md: \"15px\",\n sm: \"14px\",\n xs: \"13px\",\n};\n\nconst Badge: React.FC<PropsWithChildren<BadgeProps>> = ({\n size = \"md\",\n color = \"neutral\",\n iconBefore,\n iconAfter,\n className,\n childClassName,\n children,\n disabled = false,\n focusable = false,\n hoverable = false,\n iconSize,\n ariaLabel,\n}) => {\n const sizeClass = useMemo(() => {\n switch (size) {\n case \"xs\":\n return \"px-2 py-0 text-[10px] leading-tight\";\n case \"sm\":\n return \"px-2 py-0.5 text-[10px] leading-tight\";\n case \"md\":\n return \"px-2.5 py-0.5 text-[11px] leading-normal\";\n case \"lg\":\n return \"px-3 py-[0.1875rem] text-[12px] leading-normal\";\n }\n }, [size]);\n\n const childClass = useMemo(() => {\n switch (size) {\n case \"xs\":\n case \"sm\":\n return \"leading-[18px]\";\n case \"md\":\n case \"lg\":\n return \"leading-[20px]\";\n }\n }, [size]);\n\n const colorClass = useMemo(() => {\n switch (color) {\n case \"neutral\":\n return \"text-neutral-900 dark:text-neutral-400\";\n case \"violet\":\n return \"text-violet-400\";\n case \"orange\":\n return \"text-orange-600\";\n case \"yellow\":\n return \"text-yellow-600\";\n case \"green\":\n return \"text-green-600\";\n case \"blue\":\n return \"text-blue-600\";\n case \"pink\":\n return \"text-pink-600\";\n case \"red\":\n return \"text-orange-700\";\n }\n }, [color]);\n\n const computedIconSize = iconSize ?? defaultIconSizeByBadgeSize[size];\n\n return (\n <div\n className={cn(\n \"inline-flex bg-neutral-100 dark:bg-neutral-1200 rounded-2xl gap-1 items-center focus-base transition-colors select-none font-semibold\",\n sizeClass,\n colorClass,\n { \"focus-base\": focusable },\n {\n \"hover:bg-neutral-300 hover:dark:bg-neutral-1000 active:bg-neutral-300 dark:active:bg-neutral-1000\":\n hoverable,\n },\n {\n \"cursor-not-allowed disabled:text-gui-
|
|
1
|
+
{"version":3,"sources":["../../src/core/Badge.tsx"],"sourcesContent":["import React, { PropsWithChildren, useMemo } from \"react\";\nimport { IconName, IconSize } from \"./Icon/types\";\nimport Icon from \"./Icon\";\nimport cn from \"./utils/cn\";\nimport { ColorClassColorGroups } from \"./styles/colors/types\";\n\n/**\n * Props for the Badge component.\n */\nexport interface BadgeProps {\n /**\n * The size of the badge. Can be one of \"xs\", \"sm\", \"md\", or \"lg\".\n */\n size?: \"xs\" | \"sm\" | \"md\" | \"lg\";\n\n /**\n * The color of the badge. Can be a value from ColorClassColorGroups or \"red\".\n */\n color?: ColorClassColorGroups | \"red\";\n\n /**\n * The name of the icon to be displayed before the children in the badge.\n */\n iconBefore?: IconName;\n\n /**\n * The name of the icon to be displayed after the children in the badge.\n */\n iconAfter?: IconName;\n\n /**\n * Additional CSS class names to apply to the badge.\n */\n className?: string;\n\n /**\n * Whether the badge is disabled. Defaults to false.\n */\n disabled?: boolean;\n\n /**\n * Whether the badge is focusable. Defaults to false.\n */\n focusable?: boolean;\n\n /**\n * Whether the badge is hoverable. Defaults to false.\n */\n hoverable?: boolean;\n\n /**\n * The size of the icons in the badge. If not provided, it will be derived from the badge size.\n */\n iconSize?: IconSize;\n\n /**\n * Accessible label for the badge when interactive\n */\n ariaLabel?: string;\n\n /**\n * Additional CSS class names to apply to the children of the badge.\n */\n childClassName?: string;\n}\n\nconst defaultIconSizeByBadgeSize: Record<\n NonNullable<BadgeProps[\"size\"]>,\n IconSize\n> = {\n lg: \"16px\",\n md: \"15px\",\n sm: \"14px\",\n xs: \"13px\",\n};\n\nconst Badge: React.FC<PropsWithChildren<BadgeProps>> = ({\n size = \"md\",\n color = \"neutral\",\n iconBefore,\n iconAfter,\n className,\n childClassName,\n children,\n disabled = false,\n focusable = false,\n hoverable = false,\n iconSize,\n ariaLabel,\n}) => {\n const sizeClass = useMemo(() => {\n switch (size) {\n case \"xs\":\n return \"px-2 py-0 text-[10px] leading-tight\";\n case \"sm\":\n return \"px-2 py-0.5 text-[10px] leading-tight\";\n case \"md\":\n return \"px-2.5 py-0.5 text-[11px] leading-normal\";\n case \"lg\":\n return \"px-3 py-[0.1875rem] text-[12px] leading-normal\";\n }\n }, [size]);\n\n const childClass = useMemo(() => {\n switch (size) {\n case \"xs\":\n case \"sm\":\n return \"leading-[18px]\";\n case \"md\":\n case \"lg\":\n return \"leading-[20px]\";\n }\n }, [size]);\n\n const colorClass = useMemo(() => {\n switch (color) {\n case \"neutral\":\n return \"text-neutral-900 dark:text-neutral-400\";\n case \"violet\":\n return \"text-violet-400\";\n case \"orange\":\n return \"text-orange-600\";\n case \"yellow\":\n return \"text-yellow-600\";\n case \"green\":\n return \"text-green-600\";\n case \"blue\":\n return \"text-blue-600\";\n case \"pink\":\n return \"text-pink-600\";\n case \"red\":\n return \"text-orange-700\";\n }\n }, [color]);\n\n const computedIconSize = iconSize ?? defaultIconSizeByBadgeSize[size];\n\n return (\n <div\n className={cn(\n \"inline-flex bg-neutral-100 dark:bg-neutral-1200 rounded-2xl gap-1 items-center focus-base transition-colors select-none font-semibold\",\n sizeClass,\n colorClass,\n { \"focus-base\": focusable },\n {\n \"hover:bg-neutral-300 hover:dark:bg-neutral-1000 active:bg-neutral-300 dark:active:bg-neutral-1000\":\n hoverable,\n },\n {\n \"cursor-not-allowed disabled:text-gui-disabled-light dark:disabled:text-gui-disabled-dark\":\n disabled,\n },\n className,\n )}\n tabIndex={focusable ? 0 : undefined}\n role={focusable ? \"button\" : undefined}\n aria-label={focusable || hoverable ? ariaLabel : undefined}\n >\n {iconBefore ? (\n <Icon name={iconBefore} size={computedIconSize} color={colorClass} />\n ) : null}\n\n <span\n className={cn(\n \"whitespace-nowrap tracking-[0.04em]\",\n childClass,\n childClassName,\n )}\n >\n {children}\n </span>\n\n {iconAfter ? (\n <Icon name={iconAfter} size={computedIconSize} color={colorClass} />\n ) : null}\n </div>\n );\n};\n\nexport default Badge;\n"],"names":["React","useMemo","Icon","cn","defaultIconSizeByBadgeSize","lg","md","sm","xs","Badge","size","color","iconBefore","iconAfter","className","childClassName","children","disabled","focusable","hoverable","iconSize","ariaLabel","sizeClass","childClass","colorClass","computedIconSize","div","tabIndex","undefined","role","aria-label","name","span"],"mappings":"AAAA,OAAOA,OAA4BC,OAAO,KAAQ,OAAQ,AAE1D,QAAOC,SAAU,QAAS,AAC1B,QAAOC,OAAQ,YAAa,CA+D5B,MAAMC,2BAGF,CACFC,GAAI,OACJC,GAAI,OACJC,GAAI,OACJC,GAAI,MACN,EAEA,MAAMC,MAAiD,CAAC,CACtDC,KAAO,IAAI,CACXC,MAAQ,SAAS,CACjBC,UAAU,CACVC,SAAS,CACTC,SAAS,CACTC,cAAc,CACdC,QAAQ,CACRC,SAAW,KAAK,CAChBC,UAAY,KAAK,CACjBC,UAAY,KAAK,CACjBC,QAAQ,CACRC,SAAS,CACV,IACC,MAAMC,UAAYrB,QAAQ,KACxB,OAAQS,MACN,IAAK,KACH,MAAO,qCACT,KAAK,KACH,MAAO,uCACT,KAAK,KACH,MAAO,0CACT,KAAK,KACH,MAAO,gDACX,CACF,EAAG,CAACA,KAAK,EAET,MAAMa,WAAatB,QAAQ,KACzB,OAAQS,MACN,IAAK,KACL,IAAK,KACH,MAAO,gBACT,KAAK,KACL,IAAK,KACH,MAAO,gBACX,CACF,EAAG,CAACA,KAAK,EAET,MAAMc,WAAavB,QAAQ,KACzB,OAAQU,OACN,IAAK,UACH,MAAO,wCACT,KAAK,SACH,MAAO,iBACT,KAAK,SACH,MAAO,iBACT,KAAK,SACH,MAAO,iBACT,KAAK,QACH,MAAO,gBACT,KAAK,OACH,MAAO,eACT,KAAK,OACH,MAAO,eACT,KAAK,MACH,MAAO,iBACX,CACF,EAAG,CAACA,MAAM,EAEV,MAAMc,iBAAmBL,UAAYhB,0BAA0B,CAACM,KAAK,CAErE,OACE,oBAACgB,OACCZ,UAAWX,GACT,wIACAmB,UACAE,WACA,CAAE,aAAcN,SAAU,EAC1B,CACE,oGACEC,SACJ,EACA,CACE,2FACEF,QACJ,EACAH,WAEFa,SAAUT,UAAY,EAAIU,UAC1BC,KAAMX,UAAY,SAAWU,UAC7BE,aAAYZ,WAAaC,UAAYE,UAAYO,WAEhDhB,WACC,oBAACV,MAAK6B,KAAMnB,WAAYF,KAAMe,iBAAkBd,MAAOa,aACrD,KAEJ,oBAACQ,QACClB,UAAWX,GACT,sCACAoB,WACAR,iBAGDC,UAGFH,UACC,oBAACX,MAAK6B,KAAMlB,UAAWH,KAAMe,iBAAkBd,MAAOa,aACpD,KAGV,CAEA,gBAAef,KAAM"}
|
package/core/FeaturedLink.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React from"react";import Icon from"./Icon";import cn from"./utils/cn";const buildTargetAndRel=(url,newWindow)=>{const props={};if(newWindow){props.target="_blank";if(url.startsWith("/")&&!url.startsWith("//")){props.rel="noopener"}else{props.rel="noopenner noreferrer"}}return props};const FeaturedLink=({url,textSize="text-p2",iconColor,flush=false,reverse=false,additionalCSS="",newWindow=false,onClick=undefined,children,disabled=false,iconClassName=""})=>{const targetAndRel=buildTargetAndRel(url,newWindow);return React.createElement("a",{...onClick?{}:{href:url},className:cn("font-sans font-bold block group/featured-link",{"text-gui-
|
|
1
|
+
import React from"react";import Icon from"./Icon";import cn from"./utils/cn";const buildTargetAndRel=(url,newWindow)=>{const props={};if(newWindow){props.target="_blank";if(url.startsWith("/")&&!url.startsWith("//")){props.rel="noopener"}else{props.rel="noopenner noreferrer"}}return props};const FeaturedLink=({url,textSize="text-p2",iconColor,flush=false,reverse=false,additionalCSS="",newWindow=false,onClick=undefined,children,disabled=false,iconClassName=""})=>{const targetAndRel=buildTargetAndRel(url,newWindow);return React.createElement("a",{...onClick?{}:{href:url},className:cn("font-sans font-bold block group/featured-link",{"text-gui-disabled-light dark:text-gui-disabled-dark pointer-events-none":disabled},{"text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus":!disabled},{"py-2":!flush},`ui-${textSize}`,additionalCSS),style:{"--featured-link-icon-size":`var(${textSize.replace("text","--fs")})`},...targetAndRel,onClick:onClick,onKeyDown:onClick?e=>{if(e.key==="Enter"||e.key===" "){e.preventDefault();onClick()}}:undefined,role:onClick&&!url?"button":undefined},reverse?React.createElement(React.Fragment,null,React.createElement(Icon,{name:"icon-gui-arrow-long-right-outline",size:`calc(var(--featured-link-icon-size) * 1.25)`,color:iconColor,additionalCSS:cn("align-middle mr-2 relative -top-px -right-1 transition-[right] transform rotate-180",{"group-hover/featured-link:right-0":!disabled},iconClassName)}),children):React.createElement(React.Fragment,null,children,React.createElement(Icon,{name:"icon-gui-arrow-long-right-outline",size:`calc(var(--featured-link-icon-size) * 1.25)`,color:iconColor,additionalCSS:cn("align-middle ml-2 relative -top-px -left-1 transition-[left]",{"group-hover/featured-link:left-0":!disabled},iconClassName)})))};export default FeaturedLink;
|
|
2
2
|
//# sourceMappingURL=FeaturedLink.js.map
|
package/core/FeaturedLink.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/FeaturedLink.tsx"],"sourcesContent":["import React, { CSSProperties, ReactNode } from \"react\";\n\nimport Icon from \"./Icon\";\nimport { ColorClass, ColorThemeSet } from \"./styles/colors/types\";\nimport cn from \"./utils/cn\";\n\ntype FeaturedLinkProps = {\n url: string;\n children: ReactNode;\n textSize?: string;\n iconColor?: ColorClass | ColorThemeSet;\n flush?: boolean;\n reverse?: boolean;\n additionalCSS?: string;\n newWindow?: boolean;\n onClick?: () => void;\n disabled?: boolean;\n /**\n * Optional class name for the icon.\n */\n iconClassName?: string;\n};\n\ntype TargetProps = { target?: string; rel?: string };\n\n// When generating links with target=_blank, we only add `noreferrer` to\n// links that don't start with `/`, so we can continue tracking referrers\n// across our own domains\nconst buildTargetAndRel = (url: string, newWindow: boolean) => {\n const props: TargetProps = {};\n\n if (newWindow) {\n props.target = \"_blank\";\n\n if (url.startsWith(\"/\") && !url.startsWith(\"//\")) {\n props.rel = \"noopener\";\n } else {\n props.rel = \"noopenner noreferrer\";\n }\n }\n\n return props;\n};\n\nconst FeaturedLink = ({\n url,\n textSize = \"text-p2\",\n iconColor,\n flush = false,\n reverse = false,\n additionalCSS = \"\",\n newWindow = false,\n onClick = undefined,\n children,\n disabled = false,\n iconClassName = \"\",\n}: FeaturedLinkProps) => {\n const targetAndRel = buildTargetAndRel(url, newWindow);\n\n return (\n <a\n {...(onClick ? {} : { href: url })}\n className={cn(\n \"font-sans font-bold block group/featured-link\",\n {
|
|
1
|
+
{"version":3,"sources":["../../src/core/FeaturedLink.tsx"],"sourcesContent":["import React, { CSSProperties, ReactNode } from \"react\";\n\nimport Icon from \"./Icon\";\nimport { ColorClass, ColorThemeSet } from \"./styles/colors/types\";\nimport cn from \"./utils/cn\";\n\ntype FeaturedLinkProps = {\n url: string;\n children: ReactNode;\n textSize?: string;\n iconColor?: ColorClass | ColorThemeSet;\n flush?: boolean;\n reverse?: boolean;\n additionalCSS?: string;\n newWindow?: boolean;\n onClick?: () => void;\n disabled?: boolean;\n /**\n * Optional class name for the icon.\n */\n iconClassName?: string;\n};\n\ntype TargetProps = { target?: string; rel?: string };\n\n// When generating links with target=_blank, we only add `noreferrer` to\n// links that don't start with `/`, so we can continue tracking referrers\n// across our own domains\nconst buildTargetAndRel = (url: string, newWindow: boolean) => {\n const props: TargetProps = {};\n\n if (newWindow) {\n props.target = \"_blank\";\n\n if (url.startsWith(\"/\") && !url.startsWith(\"//\")) {\n props.rel = \"noopener\";\n } else {\n props.rel = \"noopenner noreferrer\";\n }\n }\n\n return props;\n};\n\nconst FeaturedLink = ({\n url,\n textSize = \"text-p2\",\n iconColor,\n flush = false,\n reverse = false,\n additionalCSS = \"\",\n newWindow = false,\n onClick = undefined,\n children,\n disabled = false,\n iconClassName = \"\",\n}: FeaturedLinkProps) => {\n const targetAndRel = buildTargetAndRel(url, newWindow);\n\n return (\n <a\n {...(onClick ? {} : { href: url })}\n className={cn(\n \"font-sans font-bold block group/featured-link\",\n {\n \"text-gui-disabled-light dark:text-gui-disabled-dark pointer-events-none\":\n disabled,\n },\n {\n \"text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus\":\n !disabled,\n },\n { \"py-2\": !flush },\n `ui-${textSize}`,\n additionalCSS,\n )}\n style={\n {\n \"--featured-link-icon-size\": `var(${textSize.replace(\n \"text\",\n \"--fs\",\n )})`,\n } as CSSProperties\n }\n {...targetAndRel}\n onClick={onClick}\n onKeyDown={\n onClick\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onClick();\n }\n }\n : undefined\n }\n role={onClick && !url ? \"button\" : undefined}\n >\n {reverse ? (\n <>\n <Icon\n name=\"icon-gui-arrow-long-right-outline\"\n size={`calc(var(--featured-link-icon-size) * 1.25)`}\n color={iconColor}\n additionalCSS={cn(\n \"align-middle mr-2 relative -top-px -right-1 transition-[right] transform rotate-180\",\n { \"group-hover/featured-link:right-0\": !disabled },\n iconClassName,\n )}\n />\n {children}\n </>\n ) : (\n <>\n {children}\n <Icon\n name=\"icon-gui-arrow-long-right-outline\"\n size={`calc(var(--featured-link-icon-size) * 1.25)`}\n color={iconColor}\n additionalCSS={cn(\n \"align-middle ml-2 relative -top-px -left-1 transition-[left]\",\n {\n \"group-hover/featured-link:left-0\": !disabled,\n },\n iconClassName,\n )}\n />\n </>\n )}\n </a>\n );\n};\n\nexport default FeaturedLink;\n"],"names":["React","Icon","cn","buildTargetAndRel","url","newWindow","props","target","startsWith","rel","FeaturedLink","textSize","iconColor","flush","reverse","additionalCSS","onClick","undefined","children","disabled","iconClassName","targetAndRel","a","href","className","style","replace","onKeyDown","e","key","preventDefault","role","name","size","color"],"mappings":"AAAA,OAAOA,UAAyC,OAAQ,AAExD,QAAOC,SAAU,QAAS,AAE1B,QAAOC,OAAQ,YAAa,CAwB5B,MAAMC,kBAAoB,CAACC,IAAaC,aACtC,MAAMC,MAAqB,CAAC,EAE5B,GAAID,UAAW,CACbC,MAAMC,MAAM,CAAG,SAEf,GAAIH,IAAII,UAAU,CAAC,MAAQ,CAACJ,IAAII,UAAU,CAAC,MAAO,CAChDF,MAAMG,GAAG,CAAG,UACd,KAAO,CACLH,MAAMG,GAAG,CAAG,sBACd,CACF,CAEA,OAAOH,KACT,EAEA,MAAMI,aAAe,CAAC,CACpBN,GAAG,CACHO,SAAW,SAAS,CACpBC,SAAS,CACTC,MAAQ,KAAK,CACbC,QAAU,KAAK,CACfC,cAAgB,EAAE,CAClBV,UAAY,KAAK,CACjBW,QAAUC,SAAS,CACnBC,QAAQ,CACRC,SAAW,KAAK,CAChBC,cAAgB,EAAE,CACA,IAClB,MAAMC,aAAelB,kBAAkBC,IAAKC,WAE5C,OACE,oBAACiB,KACE,GAAIN,QAAU,CAAC,EAAI,CAAEO,KAAMnB,GAAI,CAAC,CACjCoB,UAAWtB,GACT,gDACA,CACE,0EACEiB,QACJ,EACA,CACE,gHACE,CAACA,QACL,EACA,CAAE,OAAQ,CAACN,KAAM,EACjB,CAAC,GAAG,EAAEF,SAAS,CAAC,CAChBI,eAEFU,MACE,CACE,4BAA6B,CAAC,IAAI,EAAEd,SAASe,OAAO,CAClD,OACA,QACA,CAAC,CAAC,AACN,EAED,GAAGL,YAAY,CAChBL,QAASA,QACTW,UACEX,QACI,AAACY,IACC,GAAIA,EAAEC,GAAG,GAAK,SAAWD,EAAEC,GAAG,GAAK,IAAK,CACtCD,EAAEE,cAAc,GAChBd,SACF,CACF,EACAC,UAENc,KAAMf,SAAW,CAACZ,IAAM,SAAWa,WAElCH,QACC,wCACE,oBAACb,MACC+B,KAAK,oCACLC,KAAM,CAAC,2CAA2C,CAAC,CACnDC,MAAOtB,UACPG,cAAeb,GACb,sFACA,CAAE,oCAAqC,CAACiB,QAAS,EACjDC,iBAGHF,UAGH,wCACGA,SACD,oBAACjB,MACC+B,KAAK,oCACLC,KAAM,CAAC,2CAA2C,CAAC,CACnDC,MAAOtB,UACPG,cAAeb,GACb,+DACA,CACE,mCAAoC,CAACiB,QACvC,EACAC,kBAOd,CAEA,gBAAeV,YAAa"}
|
package/core/Flash.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useEffect,useState,useRef}from"react";import DOMPurify from"dompurify";import
|
|
1
|
+
import React,{useEffect,useState,useRef,createContext,useContext,useCallback,useMemo}from"react";import DOMPurify from"dompurify";import Icon from"./Icon";const FLASH_DATA_ID="ui-flashes";const FlashContext=createContext(undefined);const FlashProvider=({children})=>{const[flashes,setFlashes]=useState([]);const removeFlash=useCallback(flashId=>{setFlashes(prev=>prev.filter(item=>item.id!==flashId))},[]);const addFlashes=useCallback(newFlashes=>{setFlashes(prev=>{const withIds=newFlashes.filter(flash=>!prev.some(existing=>existing.content===flash.content&&existing.type===flash.type)).map(flash=>({...flash,id:Math.random().toString(36).slice(2),removed:false,removeFlash}));return[...prev,...withIds]})},[removeFlash]);const contextValue=useMemo(()=>({flashes,addFlashes,removeFlash}),[flashes,addFlashes,removeFlash]);return React.createElement(FlashContext.Provider,{value:contextValue},children)};const useFlashContext=()=>{const context=useContext(FlashContext);if(context===undefined){throw new Error("useFlashContext must be used within FlashProvider")}return context};const FLASH_BG_COLOR={error:"bg-gui-error",success:"bg-zingy-green",notice:"bg-electric-cyan",info:"bg-electric-cyan",alert:"bg-active-orange"};const FLASH_TEXT_COLOR={error:"text-white",success:"text-cool-black",notice:"text-cool-black",info:"text-cool-black",alert:"text-white"};const AUTO_HIDE=["success","info","notice"];const AUTO_HIDE_TIME=8e3;const useAutoHide=(type,closeFlash)=>{const timeoutId=useRef(null);useEffect(()=>{if(AUTO_HIDE.includes(type)){timeoutId.current=setTimeout(()=>{closeFlash()},AUTO_HIDE_TIME)}return()=>{if(timeoutId.current){clearTimeout(timeoutId.current)}}},[type,closeFlash])};const Flash=({id,type,content,removeFlash})=>{const ref=useRef(null);const[closed,setClosed]=useState(false);const[flashHeight,setFlashHeight]=useState(0);const closeFlash=()=>{if(ref.current){setFlashHeight(ref.current.getBoundingClientRect().height)}setClosed(true);setTimeout(()=>{if(id){removeFlash(id)}},100)};useAutoHide(type,closeFlash);const animateEntry=!closed;let style;if(flashHeight&&!closed){style={height:`${flashHeight}px`}}else if(closed){style={height:0,marginTop:0,zIndex:-1}}else{style={}}const safeContent=DOMPurify.sanitize(content,{ALLOWED_TAGS:["a"],ALLOWED_ATTR:["href","data-method"],ALLOWED_URI_REGEXP:/^\/[^/]/});const withIcons={notice:"icon-gui-ably-badge",success:"icon-gui-check-outline",error:"icon-gui-exclamation-triangle-outline",alert:"icon-gui-exclamation-triangle-outline",info:""};const iconColor={notice:"text-cool-black",success:"text-cool-black",error:"text-white",alert:"text-white",info:""};return React.createElement("div",{className:`ui-flash-message ui-grid-px ${animateEntry?"ui-flash-message-enter":""}`,style:style,ref:ref,"data-id":"ui-flash","data-testid":"ui-flash"},React.createElement("div",{className:`${FLASH_BG_COLOR[type]} p-8 flex align-center rounded shadow-container-subtle`},withIcons[type]&&iconColor[type]&&React.createElement(Icon,{name:withIcons[type],color:iconColor[type],size:"1.5rem",additionalCSS:"mr-4 self-baseline"}),React.createElement("p",{className:`ui-text-p1 mr-4 ${FLASH_TEXT_COLOR[type]}`,dangerouslySetInnerHTML:{__html:safeContent}}),React.createElement("button",{type:"button",className:"p-0 ml-auto self-start focus:outline-none focus-base",onClick:closeFlash},iconColor[type]&&React.createElement(Icon,{name:"icon-gui-x-mark-outline",color:iconColor[type],size:"1.5rem",additionalCSS:"transition-colors"}))))};const Flashes=()=>{const{flashes}=useFlashContext();return React.createElement("div",{className:"ui-flash","data-id":FLASH_DATA_ID},flashes.filter(item=>!item.removed).map(flash=>React.createElement(Flash,{key:flash.id,...flash})))};const BackendFlashes=({flashes})=>{const context=useContext(FlashContext);const addFlashes=context?.addFlashes;useEffect(()=>{if(!addFlashes){console.warn("BackendFlashes must be used within FlashProvider");return}const transformedFlashes=flashes.map(flash=>{const[type,content]=flash;return{type:type,content}});if(transformedFlashes.length>0){addFlashes(transformedFlashes)}},[flashes,addFlashes]);if(!context)return null;return React.createElement(Flashes,null)};export{FLASH_DATA_ID,Flashes,FlashProvider,useFlashContext};export default BackendFlashes;
|
|
2
2
|
//# sourceMappingURL=Flash.js.map
|
package/core/Flash.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Flash.tsx"],"sourcesContent":["import React, { useEffect, useState, useRef } from \"react\";\nimport DOMPurify from \"dompurify\";\nimport { getRemoteDataStore } from \"./remote-data-store.js\";\nimport ConnectStateWrapper from \"./ConnectStateWrapper\";\nimport Icon from \"./Icon\";\nimport { ColorClass } from \"./styles/colors/types\";\nimport { IconName } from \"./Icon/types\";\n\ntype FlashPropsType = \"error\" | \"success\" | \"notice\" | \"info\" | \"alert\";\n\ntype FlashProps = {\n id: string;\n removed: boolean;\n type: FlashPropsType;\n content: string;\n removeFlash: (id: string) => void;\n};\n\ntype FlashesProps = {\n flashes: { items: Pick<FlashProps, \"type\" | \"content\">[] };\n};\n\ntype BackendFlashesProps = {\n flashes: string[][];\n};\n\nconst REDUCER_KEY = \"flashes\";\nconst FLASH_DATA_ID = \"ui-flashes\";\n\nconst initialState = { items: [] };\n\nconst reducerFlashes = {\n [REDUCER_KEY]: (\n state: {\n items: FlashProps[];\n } = initialState,\n action: { type: string; payload: FlashProps | FlashProps[] },\n ) => {\n switch (action.type) {\n case \"flash/push\": {\n const flashes = Array.isArray(action.payload)\n ? action.payload\n : [action.payload];\n return { items: [...state.items, ...flashes] };\n }\n default:\n return state;\n }\n },\n};\n\n// Not cool but redux isn't a long term plan here\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst selectFlashes = (store: any): { items: FlashProps[] } =>\n store.getState()[REDUCER_KEY];\n\nconst FLASH_BG_COLOR = {\n error: \"bg-gui-error\",\n success: \"bg-zingy-green\",\n notice: \"bg-electric-cyan\",\n info: \"bg-electric-cyan\",\n alert: \"bg-active-orange\",\n};\n\nconst FLASH_TEXT_COLOR = {\n error: \"text-white\",\n success: \"text-cool-black\",\n notice: \"text-cool-black\",\n info: \"text-cool-black\",\n alert: \"text-white\",\n};\n\nconst AUTO_HIDE = [\"success\", \"info\", \"notice\"];\nconst AUTO_HIDE_TIME = 8000;\n\nconst useAutoHide = (type: string, closeFlash: () => void) => {\n const timeoutId = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (AUTO_HIDE.includes(type)) {\n timeoutId.current = setTimeout(() => {\n closeFlash();\n }, AUTO_HIDE_TIME);\n }\n\n return () => {\n if (timeoutId.current) {\n clearTimeout(timeoutId.current);\n }\n };\n }, [type, closeFlash]);\n};\n\nconst Flash = ({ id, type, content, removeFlash }: FlashProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const [closed, setClosed] = useState(false);\n const [flashHeight, setFlashHeight] = useState(0);\n\n const closeFlash = () => {\n if (ref.current) {\n setFlashHeight(ref.current.getBoundingClientRect().height);\n }\n\n setClosed(true);\n\n setTimeout(() => {\n if (id) {\n removeFlash(id);\n }\n }, 100);\n };\n\n useAutoHide(type, closeFlash);\n\n const animateEntry = !closed;\n\n let style;\n\n if (flashHeight && !closed) {\n style = { height: `${flashHeight}px` };\n } else if (closed) {\n style = { height: 0, marginTop: 0, zIndex: -1 };\n } else {\n style = {};\n }\n\n const safeContent = DOMPurify.sanitize(content, {\n ALLOWED_TAGS: [\"a\"],\n ALLOWED_ATTR: [\"href\", \"data-method\"],\n ALLOWED_URI_REGEXP: /^\\/[^/]/,\n });\n\n const withIcons: Record<FlashPropsType, IconName | \"\"> = {\n notice: \"icon-gui-ably-badge\",\n success: \"icon-gui-check-outline\",\n error: \"icon-gui-exclamation-triangle-outline\",\n alert: \"icon-gui-exclamation-triangle-outline\",\n info: \"\",\n };\n\n const iconColor: Record<FlashPropsType, ColorClass | \"\"> = {\n notice: \"text-cool-black\",\n success: \"text-cool-black\",\n error: \"text-white\",\n alert: \"text-white\",\n info: \"\",\n };\n\n return (\n <div\n className={`ui-flash-message ui-grid-px ${\n animateEntry ? \"ui-flash-message-enter\" : \"\"\n }`}\n style={style}\n ref={ref}\n data-id=\"ui-flash\"\n data-testid=\"ui-flash\"\n >\n <div\n className={`${FLASH_BG_COLOR[type]} p-8 flex align-center rounded shadow-container-subtle`}\n >\n {withIcons[type] && iconColor[type] && (\n <Icon\n name={withIcons[type]}\n color={iconColor[type]}\n size=\"1.5rem\"\n additionalCSS=\"mr-4 self-baseline\"\n />\n )}\n <p\n className={`ui-text-p1 mr-4 ${FLASH_TEXT_COLOR[type]}`}\n dangerouslySetInnerHTML={{ __html: safeContent }}\n />\n <button\n type=\"button\"\n className=\"p-0 ml-auto self-start focus:outline-none\"\n onClick={closeFlash}\n >\n {iconColor[type] && (\n <Icon\n name=\"icon-gui-x-mark-outline\"\n color={iconColor[type]}\n size=\"1.5rem\"\n additionalCSS=\"transition-colors\"\n />\n )}\n </button>\n </div>\n </div>\n );\n};\n\nconst Flashes = ({ flashes }: FlashesProps) => {\n const [flashesWithIds, setFlashesWithIds] = useState<FlashProps[]>([]);\n\n const removeFlash = (flashId: string) =>\n setFlashesWithIds((items) => items.filter((item) => item.id !== flashId));\n\n useEffect(() => {\n if (!flashes?.items?.length) return;\n\n setFlashesWithIds((state) => {\n const newFlashes = (flashes.items ?? [])\n .filter(\n (flash) =>\n !state.some(\n (existing) =>\n existing.content === flash.content &&\n existing.type === flash.type,\n ),\n )\n .map((flash) => ({\n ...flash,\n id: Math.random().toString(36).slice(2),\n removed: false,\n removeFlash,\n }));\n\n return newFlashes.length > 0 ? [...state, ...newFlashes] : state;\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [flashes]);\n\n return (\n <div className=\"ui-flash\" data-id={FLASH_DATA_ID}>\n {flashesWithIds\n .filter((item) => !item.removed)\n .map((flash) => (\n <Flash key={flash.id} {...flash} />\n ))}\n </div>\n );\n};\n\nconst BackendFlashes = ({ flashes }: BackendFlashesProps) => {\n useEffect(() => {\n const transformedFlashes =\n flashes.map((flash) => {\n const [type, content] = flash;\n return { type, content };\n }) || [];\n\n if (transformedFlashes.length > 0) {\n const store = getRemoteDataStore();\n\n store.dispatch({\n type: \"flash/push\",\n payload: transformedFlashes,\n });\n }\n }, [flashes]);\n\n const WrappedFlashes = ConnectStateWrapper(Flashes, {\n flashes: selectFlashes,\n });\n\n return <WrappedFlashes />;\n};\n\nexport { reducerFlashes, FLASH_DATA_ID, Flashes };\nexport default BackendFlashes;\n"],"names":["React","useEffect","useState","useRef","DOMPurify","getRemoteDataStore","ConnectStateWrapper","Icon","REDUCER_KEY","FLASH_DATA_ID","initialState","items","reducerFlashes","state","action","type","flashes","Array","isArray","payload","selectFlashes","store","getState","FLASH_BG_COLOR","error","success","notice","info","alert","FLASH_TEXT_COLOR","AUTO_HIDE","AUTO_HIDE_TIME","useAutoHide","closeFlash","timeoutId","includes","current","setTimeout","clearTimeout","Flash","id","content","removeFlash","ref","closed","setClosed","flashHeight","setFlashHeight","getBoundingClientRect","height","animateEntry","style","marginTop","zIndex","safeContent","sanitize","ALLOWED_TAGS","ALLOWED_ATTR","ALLOWED_URI_REGEXP","withIcons","iconColor","div","className","data-id","data-testid","name","color","size","additionalCSS","p","dangerouslySetInnerHTML","__html","button","onClick","Flashes","flashesWithIds","setFlashesWithIds","flashId","filter","item","length","newFlashes","flash","some","existing","map","Math","random","toString","slice","removed","key","BackendFlashes","transformedFlashes","dispatch","WrappedFlashes"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/core/Flash.tsx"],"sourcesContent":["import React, {\n useEffect,\n useState,\n useRef,\n createContext,\n useContext,\n useCallback,\n useMemo,\n PropsWithChildren,\n} from \"react\";\nimport DOMPurify from \"dompurify\";\nimport Icon from \"./Icon\";\nimport { ColorClass } from \"./styles/colors/types\";\nimport { IconName } from \"./Icon/types\";\n\ntype FlashPropsType = \"error\" | \"success\" | \"notice\" | \"info\" | \"alert\";\n\ntype FlashProps = {\n id: string;\n removed: boolean;\n type: FlashPropsType;\n content: string;\n removeFlash: (id: string) => void;\n};\n\ntype BackendFlashesProps = {\n flashes: string[][];\n};\n\nconst FLASH_DATA_ID = \"ui-flashes\";\n\ntype FlashContextType = {\n flashes: FlashProps[];\n addFlashes: (flashes: Pick<FlashProps, \"type\" | \"content\">[]) => void;\n removeFlash: (id: string) => void;\n};\n\nconst FlashContext = createContext<FlashContextType | undefined>(undefined);\n\ntype FlashProviderProps = PropsWithChildren;\n\n/**\n * FlashProvider - Context provider for managing flash messages throughout the application.\n *\n * Maintains a global list of flash messages and provides methods to add/remove them.\n * Automatically deduplicates messages with the same type and content to prevent duplicates.\n * Use this at the app root level and access via useFlashContext() in child components.\n */\nconst FlashProvider = ({ children }: FlashProviderProps) => {\n const [flashes, setFlashes] = useState<FlashProps[]>([]);\n\n const removeFlash = useCallback((flashId: string) => {\n setFlashes((prev) => prev.filter((item) => item.id !== flashId));\n }, []);\n\n const addFlashes = useCallback(\n (newFlashes: Pick<FlashProps, \"type\" | \"content\">[]) => {\n setFlashes((prev) => {\n const withIds = newFlashes\n .filter(\n (flash) =>\n !prev.some(\n (existing) =>\n existing.content === flash.content &&\n existing.type === flash.type,\n ),\n )\n .map((flash) => ({\n ...flash,\n id: Math.random().toString(36).slice(2),\n removed: false,\n removeFlash,\n }));\n\n return [...prev, ...withIds];\n });\n },\n [removeFlash],\n );\n\n const contextValue = useMemo(\n () => ({ flashes, addFlashes, removeFlash }),\n [flashes, addFlashes, removeFlash],\n );\n\n return (\n <FlashContext.Provider value={contextValue}>\n {children}\n </FlashContext.Provider>\n );\n};\n\nconst useFlashContext = () => {\n const context = useContext(FlashContext);\n if (context === undefined) {\n throw new Error(\"useFlashContext must be used within FlashProvider\");\n }\n return context;\n};\n\nconst FLASH_BG_COLOR = {\n error: \"bg-gui-error\",\n success: \"bg-zingy-green\",\n notice: \"bg-electric-cyan\",\n info: \"bg-electric-cyan\",\n alert: \"bg-active-orange\",\n};\n\nconst FLASH_TEXT_COLOR = {\n error: \"text-white\",\n success: \"text-cool-black\",\n notice: \"text-cool-black\",\n info: \"text-cool-black\",\n alert: \"text-white\",\n};\n\nconst AUTO_HIDE = [\"success\", \"info\", \"notice\"];\nconst AUTO_HIDE_TIME = 8000;\n\nconst useAutoHide = (type: string, closeFlash: () => void) => {\n const timeoutId = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (AUTO_HIDE.includes(type)) {\n timeoutId.current = setTimeout(() => {\n closeFlash();\n }, AUTO_HIDE_TIME);\n }\n\n return () => {\n if (timeoutId.current) {\n clearTimeout(timeoutId.current);\n }\n };\n }, [type, closeFlash]);\n};\n\n/**\n * Flash - Individual flash message component with animations and auto-dismiss.\n *\n * Displays a colored notification banner with an icon, message content, and close button.\n * Success/info/notice messages auto-hide after 8 seconds. Error/alert messages require\n * manual dismissal. Uses CSS animations for smooth entry/exit and height transitions\n * on close. Content is sanitized with DOMPurify to allow safe HTML links from backend.\n */\nconst Flash = ({ id, type, content, removeFlash }: FlashProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const [closed, setClosed] = useState(false);\n const [flashHeight, setFlashHeight] = useState(0);\n\n const closeFlash = () => {\n if (ref.current) {\n setFlashHeight(ref.current.getBoundingClientRect().height);\n }\n\n setClosed(true);\n\n setTimeout(() => {\n if (id) {\n removeFlash(id);\n }\n }, 100);\n };\n\n useAutoHide(type, closeFlash);\n\n const animateEntry = !closed;\n\n let style;\n\n if (flashHeight && !closed) {\n style = { height: `${flashHeight}px` };\n } else if (closed) {\n style = { height: 0, marginTop: 0, zIndex: -1 };\n } else {\n style = {};\n }\n\n const safeContent = DOMPurify.sanitize(content, {\n ALLOWED_TAGS: [\"a\"],\n ALLOWED_ATTR: [\"href\", \"data-method\"],\n ALLOWED_URI_REGEXP: /^\\/[^/]/,\n });\n\n const withIcons: Record<FlashPropsType, IconName | \"\"> = {\n notice: \"icon-gui-ably-badge\",\n success: \"icon-gui-check-outline\",\n error: \"icon-gui-exclamation-triangle-outline\",\n alert: \"icon-gui-exclamation-triangle-outline\",\n info: \"\",\n };\n\n const iconColor: Record<FlashPropsType, ColorClass | \"\"> = {\n notice: \"text-cool-black\",\n success: \"text-cool-black\",\n error: \"text-white\",\n alert: \"text-white\",\n info: \"\",\n };\n\n return (\n <div\n className={`ui-flash-message ui-grid-px ${\n animateEntry ? \"ui-flash-message-enter\" : \"\"\n }`}\n style={style}\n ref={ref}\n data-id=\"ui-flash\"\n data-testid=\"ui-flash\"\n >\n <div\n className={`${FLASH_BG_COLOR[type]} p-8 flex align-center rounded shadow-container-subtle`}\n >\n {withIcons[type] && iconColor[type] && (\n <Icon\n name={withIcons[type]}\n color={iconColor[type]}\n size=\"1.5rem\"\n additionalCSS=\"mr-4 self-baseline\"\n />\n )}\n <p\n className={`ui-text-p1 mr-4 ${FLASH_TEXT_COLOR[type]}`}\n dangerouslySetInnerHTML={{ __html: safeContent }}\n />\n <button\n type=\"button\"\n className=\"p-0 ml-auto self-start focus:outline-none focus-base\"\n onClick={closeFlash}\n >\n {iconColor[type] && (\n <Icon\n name=\"icon-gui-x-mark-outline\"\n color={iconColor[type]}\n size=\"1.5rem\"\n additionalCSS=\"transition-colors\"\n />\n )}\n </button>\n </div>\n </div>\n );\n};\n\n/**\n * Flashes - Container component that renders all active flash messages.\n *\n * Reads from FlashContext and displays each flash message in order.\n * Use this component where you want flash messages to appear in your layout\n * (typically near the top of the page). Filters out removed messages.\n */\nconst Flashes = () => {\n const { flashes } = useFlashContext();\n\n return (\n <div className=\"ui-flash\" data-id={FLASH_DATA_ID}>\n {flashes\n .filter((item) => !item.removed)\n .map((flash) => (\n <Flash key={flash.id} {...flash} />\n ))}\n </div>\n );\n};\n\n/**\n * BackendFlashes - Integration component for server-side flash messages (default export).\n *\n * Receives flash messages from backend as an array of [type, content] tuples and adds\n * them to the FlashContext on mount. Primary use case is hydrating flash messages from\n * Rails or other backend frameworks. Renders the Flashes component to display messages.\n * Must be used within FlashProvider.\n */\nconst BackendFlashes = ({ flashes }: BackendFlashesProps) => {\n const context = useContext(FlashContext);\n const addFlashes = context?.addFlashes;\n\n useEffect(() => {\n if (!addFlashes) {\n console.warn(\"BackendFlashes must be used within FlashProvider\");\n return;\n }\n\n const transformedFlashes = flashes.map((flash) => {\n const [type, content] = flash;\n return { type: type as FlashPropsType, content };\n });\n\n if (transformedFlashes.length > 0) {\n addFlashes(transformedFlashes);\n }\n }, [flashes, addFlashes]);\n\n if (!context) return null;\n\n return <Flashes />;\n};\n\nexport { FLASH_DATA_ID, Flashes, FlashProvider, useFlashContext };\nexport default BackendFlashes;\n"],"names":["React","useEffect","useState","useRef","createContext","useContext","useCallback","useMemo","DOMPurify","Icon","FLASH_DATA_ID","FlashContext","undefined","FlashProvider","children","flashes","setFlashes","removeFlash","flashId","prev","filter","item","id","addFlashes","newFlashes","withIds","flash","some","existing","content","type","map","Math","random","toString","slice","removed","contextValue","Provider","value","useFlashContext","context","Error","FLASH_BG_COLOR","error","success","notice","info","alert","FLASH_TEXT_COLOR","AUTO_HIDE","AUTO_HIDE_TIME","useAutoHide","closeFlash","timeoutId","includes","current","setTimeout","clearTimeout","Flash","ref","closed","setClosed","flashHeight","setFlashHeight","getBoundingClientRect","height","animateEntry","style","marginTop","zIndex","safeContent","sanitize","ALLOWED_TAGS","ALLOWED_ATTR","ALLOWED_URI_REGEXP","withIcons","iconColor","div","className","data-id","data-testid","name","color","size","additionalCSS","p","dangerouslySetInnerHTML","__html","button","onClick","Flashes","key","BackendFlashes","console","warn","transformedFlashes","length"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React from"react";import cn from"../utils/cn";const LABEL_FONT_SIZE_RATIO=4;const DESCRIPTION_FONT_SIZE_RATIO=2.6;const ProductLabel=({label,unavailable,selected,numericalSize,showLabel,showAblyText=true,className})=>{if(!label||!showLabel){return null}const dynamicFontSize=numericalSize/LABEL_FONT_SIZE_RATIO;return React.createElement("span",{className:"flex flex-col justify-center"},unavailable?React.createElement("span",{className:"block"},React.createElement("span",{className:"table-cell font-sans bg-neutral-300 dark:bg-neutral-1000 rounded-full text-gui-
|
|
1
|
+
import React from"react";import cn from"../utils/cn";const LABEL_FONT_SIZE_RATIO=4;const DESCRIPTION_FONT_SIZE_RATIO=2.6;const ProductLabel=({label,unavailable,selected,numericalSize,showLabel,showAblyText=true,className})=>{if(!label||!showLabel){return null}const dynamicFontSize=numericalSize/LABEL_FONT_SIZE_RATIO;return React.createElement("span",{className:"flex flex-col justify-center"},unavailable?React.createElement("span",{className:"block"},React.createElement("span",{className:"table-cell font-sans bg-neutral-300 dark:bg-neutral-1000 rounded-full text-gui-disabled-light dark:text-gui-disabled-dark tracking-[0.04em] font-bold leading-snug",style:{fontSize:dynamicFontSize*.6,padding:`${dynamicFontSize*.25}px ${dynamicFontSize*.5}px`}},"COMING SOON")):showAblyText&&React.createElement("span",{className:cn("block font-bold uppercase ui-text-p2 leading-snug",{"text-neutral-500 dark:text-neutral-700":selected},{"text-neutral-700 dark:text-neutral-500":!selected}),style:{fontSize:dynamicFontSize,letterSpacing:"0.06em"}},"Ably"),React.createElement("span",{className:cn("block ui-text-p2 font-bold",{"text-neutral-000 dark:text-neutral-1300":selected===true&&!unavailable},{"text-neutral-1000 dark:text-neutral-300 group-hover/product-tile:text-neutral-1300 dark:group-hover/product-tile:text-neutral-000":selected===false&&!unavailable},{"text-neutral-1300 dark:text-neutral-000":selected===undefined&&!unavailable},{"text-neutral-700 dark:text-neutral-600":unavailable},{"mt-[-3px]":!unavailable},className),style:{fontSize:numericalSize/DESCRIPTION_FONT_SIZE_RATIO}},label))};export default ProductLabel;
|
|
2
2
|
//# sourceMappingURL=ProductLabel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/ProductTile/ProductLabel.tsx"],"sourcesContent":["import React from \"react\";\nimport cn from \"../utils/cn\";\n\ntype ProductLabelProps = {\n label: string;\n unavailable: boolean;\n selected?: boolean;\n numericalSize: number;\n showLabel?: boolean;\n showAblyText?: boolean;\n className?: string;\n};\n\nconst LABEL_FONT_SIZE_RATIO = 4;\nconst DESCRIPTION_FONT_SIZE_RATIO = 2.6;\n\nconst ProductLabel = ({\n label,\n unavailable,\n selected,\n numericalSize,\n showLabel,\n showAblyText = true,\n className,\n}: ProductLabelProps) => {\n if (!label || !showLabel) {\n return null;\n }\n\n const dynamicFontSize = numericalSize / LABEL_FONT_SIZE_RATIO;\n\n return (\n <span className=\"flex flex-col justify-center\">\n {unavailable ? (\n <span className=\"block\">\n <span\n className=\"table-cell font-sans bg-neutral-300 dark:bg-neutral-1000 rounded-full text-gui-
|
|
1
|
+
{"version":3,"sources":["../../../src/core/ProductTile/ProductLabel.tsx"],"sourcesContent":["import React from \"react\";\nimport cn from \"../utils/cn\";\n\ntype ProductLabelProps = {\n label: string;\n unavailable: boolean;\n selected?: boolean;\n numericalSize: number;\n showLabel?: boolean;\n showAblyText?: boolean;\n className?: string;\n};\n\nconst LABEL_FONT_SIZE_RATIO = 4;\nconst DESCRIPTION_FONT_SIZE_RATIO = 2.6;\n\nconst ProductLabel = ({\n label,\n unavailable,\n selected,\n numericalSize,\n showLabel,\n showAblyText = true,\n className,\n}: ProductLabelProps) => {\n if (!label || !showLabel) {\n return null;\n }\n\n const dynamicFontSize = numericalSize / LABEL_FONT_SIZE_RATIO;\n\n return (\n <span className=\"flex flex-col justify-center\">\n {unavailable ? (\n <span className=\"block\">\n <span\n className=\"table-cell font-sans bg-neutral-300 dark:bg-neutral-1000 rounded-full text-gui-disabled-light dark:text-gui-disabled-dark tracking-[0.04em] font-bold leading-snug\"\n style={{\n fontSize: dynamicFontSize * 0.6,\n padding: `${dynamicFontSize * 0.25}px ${dynamicFontSize * 0.5}px`,\n }}\n >\n COMING SOON\n </span>\n </span>\n ) : (\n showAblyText && (\n <span\n className={cn(\n \"block font-bold uppercase ui-text-p2 leading-snug\",\n { \"text-neutral-500 dark:text-neutral-700\": selected },\n { \"text-neutral-700 dark:text-neutral-500\": !selected },\n )}\n style={{\n fontSize: dynamicFontSize,\n letterSpacing: \"0.06em\",\n }}\n >\n Ably\n </span>\n )\n )}\n <span\n className={cn(\n \"block ui-text-p2 font-bold\",\n {\n \"text-neutral-000 dark:text-neutral-1300\":\n selected === true && !unavailable,\n },\n {\n \"text-neutral-1000 dark:text-neutral-300 group-hover/product-tile:text-neutral-1300 dark:group-hover/product-tile:text-neutral-000\":\n selected === false && !unavailable,\n },\n {\n \"text-neutral-1300 dark:text-neutral-000\":\n selected === undefined && !unavailable,\n },\n {\n \"text-neutral-700 dark:text-neutral-600\": unavailable,\n },\n { \"mt-[-3px]\": !unavailable },\n className,\n )}\n style={{ fontSize: numericalSize / DESCRIPTION_FONT_SIZE_RATIO }}\n >\n {label}\n </span>\n </span>\n );\n};\n\nexport default ProductLabel;\n"],"names":["React","cn","LABEL_FONT_SIZE_RATIO","DESCRIPTION_FONT_SIZE_RATIO","ProductLabel","label","unavailable","selected","numericalSize","showLabel","showAblyText","className","dynamicFontSize","span","style","fontSize","padding","letterSpacing","undefined"],"mappings":"AAAA,OAAOA,UAAW,OAAQ,AAC1B,QAAOC,OAAQ,aAAc,CAY7B,MAAMC,sBAAwB,EAC9B,MAAMC,4BAA8B,IAEpC,MAAMC,aAAe,CAAC,CACpBC,KAAK,CACLC,WAAW,CACXC,QAAQ,CACRC,aAAa,CACbC,SAAS,CACTC,aAAe,IAAI,CACnBC,SAAS,CACS,IAClB,GAAI,CAACN,OAAS,CAACI,UAAW,CACxB,OAAO,IACT,CAEA,MAAMG,gBAAkBJ,cAAgBN,sBAExC,OACE,oBAACW,QAAKF,UAAU,gCACbL,YACC,oBAACO,QAAKF,UAAU,SACd,oBAACE,QACCF,UAAU,qKACVG,MAAO,CACLC,SAAUH,gBAAkB,GAC5BI,QAAS,CAAC,EAAEJ,gBAAkB,IAAK,GAAG,EAAEA,gBAAkB,GAAI,EAAE,CAAC,AACnE,GACD,gBAKHF,cACE,oBAACG,QACCF,UAAWV,GACT,oDACA,CAAE,yCAA0CM,QAAS,EACrD,CAAE,yCAA0C,CAACA,QAAS,GAExDO,MAAO,CACLC,SAAUH,gBACVK,cAAe,QACjB,GACD,QAKL,oBAACJ,QACCF,UAAWV,GACT,6BACA,CACE,0CACEM,WAAa,MAAQ,CAACD,WAC1B,EACA,CACE,oIACEC,WAAa,OAAS,CAACD,WAC3B,EACA,CACE,0CACEC,WAAaW,WAAa,CAACZ,WAC/B,EACA,CACE,yCAA0CA,WAC5C,EACA,CAAE,YAAa,CAACA,WAAY,EAC5BK,WAEFG,MAAO,CAAEC,SAAUP,cAAgBL,2BAA4B,GAE9DE,OAIT,CAEA,gBAAeD,YAAa"}
|
package/core/ProductTile/data.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const productNames=["pubsub","chat","aiTransport","liveObjects","spaces","liveSync"];export const products={pubsub:{label:"Pub/Sub",description:"Low-level APIs to build any realtime experience.",icon:"icon-product-pubsub-mono",hoverIcon:"icon-product-pubsub",link:"/docs/channels"},chat:{label:"Chat",description:"Rapidly build chat features and roll-out at scale.",icon:"icon-product-chat-mono",hoverIcon:"icon-product-chat",link:"/docs/chat"},aiTransport:{label:"AI Transport",description:"
|
|
1
|
+
export const productNames=["pubsub","chat","aiTransport","liveObjects","spaces","liveSync"];export const products={pubsub:{label:"Pub/Sub",description:"Low-level APIs to build any realtime experience.",icon:"icon-product-pubsub-mono",hoverIcon:"icon-product-pubsub",link:"/docs/channels"},chat:{label:"Chat",description:"Rapidly build chat features and roll-out at scale.",icon:"icon-product-chat-mono",hoverIcon:"icon-product-chat",link:"/docs/chat"},aiTransport:{label:"AI Transport",description:"A drop-in infrastructure layer for a durable AI UX.",icon:"icon-product-ai-transport-mono",hoverIcon:"icon-product-ai-transport"},liveObjects:{label:"LiveObjects",description:"Sync application state across multiple devices.",icon:"icon-product-liveobjects-mono",hoverIcon:"icon-product-liveobjects",link:"/docs/liveobjects"},spaces:{label:"Spaces",description:"Create collaborative environments in a few lines of code.",icon:"icon-product-spaces-mono",hoverIcon:"icon-product-spaces",link:"/docs/spaces"},liveSync:{label:"LiveSync",description:"Sync database changes with frontend clients.",icon:"icon-product-livesync-mono",hoverIcon:"icon-product-livesync",link:"/docs/livesync"}};
|
|
2
2
|
//# sourceMappingURL=data.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/ProductTile/data.ts"],"sourcesContent":["import { IconName } from \"../Icon/types\";\n\nexport const productNames = [\n \"pubsub\",\n \"chat\",\n \"aiTransport\",\n \"liveObjects\",\n \"spaces\",\n \"liveSync\",\n] as const;\n\nexport type ProductName = (typeof productNames)[number];\n\ntype Products = Record<\n ProductName,\n {\n label: string;\n description: string;\n link?: string;\n icon?: IconName;\n hoverIcon?: IconName;\n unavailable?: boolean;\n }\n>;\n\nexport const products: Products = {\n pubsub: {\n label: \"Pub/Sub\",\n description: \"Low-level APIs to build any realtime experience.\",\n icon: \"icon-product-pubsub-mono\",\n hoverIcon: \"icon-product-pubsub\",\n link: \"/docs/channels\",\n },\n chat: {\n label: \"Chat\",\n description: \"Rapidly build chat features and roll-out at scale.\",\n icon: \"icon-product-chat-mono\",\n hoverIcon: \"icon-product-chat\",\n link: \"/docs/chat\",\n },\n aiTransport: {\n label: \"AI Transport\",\n description: \"
|
|
1
|
+
{"version":3,"sources":["../../../src/core/ProductTile/data.ts"],"sourcesContent":["import { IconName } from \"../Icon/types\";\n\nexport const productNames = [\n \"pubsub\",\n \"chat\",\n \"aiTransport\",\n \"liveObjects\",\n \"spaces\",\n \"liveSync\",\n] as const;\n\nexport type ProductName = (typeof productNames)[number];\n\ntype Products = Record<\n ProductName,\n {\n label: string;\n description: string;\n link?: string;\n icon?: IconName;\n hoverIcon?: IconName;\n unavailable?: boolean;\n }\n>;\n\nexport const products: Products = {\n pubsub: {\n label: \"Pub/Sub\",\n description: \"Low-level APIs to build any realtime experience.\",\n icon: \"icon-product-pubsub-mono\",\n hoverIcon: \"icon-product-pubsub\",\n link: \"/docs/channels\",\n },\n chat: {\n label: \"Chat\",\n description: \"Rapidly build chat features and roll-out at scale.\",\n icon: \"icon-product-chat-mono\",\n hoverIcon: \"icon-product-chat\",\n link: \"/docs/chat\",\n },\n aiTransport: {\n label: \"AI Transport\",\n description: \"A drop-in infrastructure layer for a durable AI UX.\",\n icon: \"icon-product-ai-transport-mono\",\n hoverIcon: \"icon-product-ai-transport\",\n },\n liveObjects: {\n label: \"LiveObjects\",\n description: \"Sync application state across multiple devices.\",\n icon: \"icon-product-liveobjects-mono\",\n hoverIcon: \"icon-product-liveobjects\",\n link: \"/docs/liveobjects\",\n },\n spaces: {\n label: \"Spaces\",\n description: \"Create collaborative environments in a few lines of code.\",\n icon: \"icon-product-spaces-mono\",\n hoverIcon: \"icon-product-spaces\",\n link: \"/docs/spaces\",\n },\n liveSync: {\n label: \"LiveSync\",\n description: \"Sync database changes with frontend clients.\",\n icon: \"icon-product-livesync-mono\",\n hoverIcon: \"icon-product-livesync\",\n link: \"/docs/livesync\",\n },\n};\n"],"names":["productNames","products","pubsub","label","description","icon","hoverIcon","link","chat","aiTransport","liveObjects","spaces","liveSync"],"mappings":"AAEA,OAAO,MAAMA,aAAe,CAC1B,SACA,OACA,cACA,cACA,SACA,WACD,AAAU,AAgBX,QAAO,MAAMC,SAAqB,CAChCC,OAAQ,CACNC,MAAO,UACPC,YAAa,mDACbC,KAAM,2BACNC,UAAW,sBACXC,KAAM,gBACR,EACAC,KAAM,CACJL,MAAO,OACPC,YAAa,qDACbC,KAAM,yBACNC,UAAW,oBACXC,KAAM,YACR,EACAE,YAAa,CACXN,MAAO,eACPC,YAAa,sDACbC,KAAM,iCACNC,UAAW,2BACb,EACAI,YAAa,CACXP,MAAO,cACPC,YAAa,kDACbC,KAAM,gCACNC,UAAW,2BACXC,KAAM,mBACR,EACAI,OAAQ,CACNR,MAAO,SACPC,YAAa,4DACbC,KAAM,2BACNC,UAAW,sBACXC,KAAM,cACR,EACAK,SAAU,CACRT,MAAO,WACPC,YAAa,+CACbC,KAAM,6BACNC,UAAW,wBACXC,KAAM,gBACR,CACF,CAAE"}
|
package/core/SegmentedControl.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React from"react";import cn from"./utils/cn";import Icon from"./Icon";const SegmentedControl=({className,rounded=false,leftIcon,rightIcon,active=false,variant="default",size="md",children,onClick,disabled})=>{const colorStyles={default:{active:"bg-neutral-200 dark:bg-neutral-1100",inactive:"bg-neutral-000 dark:bg-neutral-1300 hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-100 dark:active:bg-neutral-1200"},subtle:{active:"bg-neutral-000 dark:bg-neutral-1000",inactive:"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-200 dark:active:bg-neutral-1100"},strong:{active:"bg-neutral-1000 dark:bg-neutral-300",inactive:"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-200 dark:active:bg-neutral-1100"}};const contentColorStyles={default:{active:"text-neutral-1300 dark:text-neutral-000",inactive:"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000"},subtle:{active:"text-neutral-1300 dark:text-neutral-000",inactive:"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000"},strong:{active:"text-neutral-000 dark:text-neutral-1300",inactive:"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000"}};const sizeStyles={md:cn("h-12 p-3 gap-2.5",rounded&&"px-[1.125rem]"),sm:cn("h-10 p-[0.5625rem] gap-[0.5625rem]",rounded&&"px-3.5"),xs:cn("h-9 p-2 gap-2",rounded&&"px-3")};const textStyles={md:"ui-text-label2",sm:"ui-text-label3",xs:"ui-text-label4"};const iconSizes={md:"23px",sm:"22px",xs:"20px"};const activeKey=active?"active":"inactive";return React.createElement("div",{onClick:!disabled?onClick:undefined,onKeyDown:e=>{if((e.key==="Enter"||e.key===" ")&&!disabled&&onClick){e.preventDefault();onClick()}},className:cn("focus-base flex items-center justify-center cursor-pointer select-none transition-colors",colorStyles[variant][activeKey],contentColorStyles[variant][activeKey],sizeStyles[size],textStyles[size],disabled&&"cursor-not-allowed hover:bg-inherit dark:hover:bg-inherit active:bg-inherit dark:active:bg-inherit",rounded?"rounded-full":"rounded-lg",className),tabIndex:disabled?-1:0,role:"button","aria-pressed":active,"aria-disabled":disabled},leftIcon&&React.createElement(Icon,{name:leftIcon,size:iconSizes[size],"aria-hidden":"true",color:contentColorStyles[variant][activeKey]}),children&&React.createElement("span",{className:cn("font-semibold transition-colors",contentColorStyles[variant][activeKey],disabled&&"text-gui-
|
|
1
|
+
import React from"react";import cn from"./utils/cn";import Icon from"./Icon";const SegmentedControl=({className,rounded=false,leftIcon,rightIcon,active=false,variant="default",size="md",children,onClick,disabled})=>{const colorStyles={default:{active:"bg-neutral-200 dark:bg-neutral-1100",inactive:"bg-neutral-000 dark:bg-neutral-1300 hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-100 dark:active:bg-neutral-1200"},subtle:{active:"bg-neutral-000 dark:bg-neutral-1000",inactive:"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-200 dark:active:bg-neutral-1100"},strong:{active:"bg-neutral-1000 dark:bg-neutral-300",inactive:"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-200 dark:active:bg-neutral-1100"}};const contentColorStyles={default:{active:"text-neutral-1300 dark:text-neutral-000",inactive:"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000"},subtle:{active:"text-neutral-1300 dark:text-neutral-000",inactive:"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000"},strong:{active:"text-neutral-000 dark:text-neutral-1300",inactive:"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000"}};const sizeStyles={md:cn("h-12 p-3 gap-2.5",rounded&&"px-[1.125rem]"),sm:cn("h-10 p-[0.5625rem] gap-[0.5625rem]",rounded&&"px-3.5"),xs:cn("h-9 p-2 gap-2",rounded&&"px-3")};const textStyles={md:"ui-text-label2",sm:"ui-text-label3",xs:"ui-text-label4"};const iconSizes={md:"23px",sm:"22px",xs:"20px"};const activeKey=active?"active":"inactive";return React.createElement("div",{onClick:!disabled?onClick:undefined,onKeyDown:e=>{if((e.key==="Enter"||e.key===" ")&&!disabled&&onClick){e.preventDefault();onClick()}},className:cn("focus-base flex items-center justify-center cursor-pointer select-none transition-colors",colorStyles[variant][activeKey],contentColorStyles[variant][activeKey],sizeStyles[size],textStyles[size],disabled&&"cursor-not-allowed hover:bg-inherit dark:hover:bg-inherit active:bg-inherit dark:active:bg-inherit",rounded?"rounded-full":"rounded-lg",className),tabIndex:disabled?-1:0,role:"button","aria-pressed":active,"aria-disabled":disabled},leftIcon&&React.createElement(Icon,{name:leftIcon,size:iconSizes[size],"aria-hidden":"true",color:contentColorStyles[variant][activeKey]}),children&&React.createElement("span",{className:cn("font-semibold transition-colors",contentColorStyles[variant][activeKey],disabled&&"text-gui-disabled-light dark:text-gui-disabled-dark hover:text-gui-disabled-light dark:hover:text-gui-disabled-dark")},children),rightIcon&&React.createElement(Icon,{name:rightIcon,size:iconSizes[size],"aria-hidden":"true",color:contentColorStyles[variant][activeKey]}))};export default SegmentedControl;
|
|
2
2
|
//# sourceMappingURL=SegmentedControl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/SegmentedControl.tsx"],"sourcesContent":["import React, { PropsWithChildren } from \"react\";\nimport cn from \"./utils/cn\";\nimport Icon from \"./Icon\";\nimport type { IconName, IconSize } from \"./Icon/types\";\nimport { ColorClass } from \"./styles/colors/types\";\n\nexport type SegmentedControlSize = \"md\" | \"sm\" | \"xs\";\n\nexport type SegmentedControlProps = {\n className?: string;\n rounded?: boolean;\n leftIcon?: IconName;\n rightIcon?: IconName;\n active?: boolean;\n variant?: \"default\" | \"subtle\" | \"strong\";\n size?: SegmentedControlSize;\n onClick?: () => void;\n disabled?: boolean;\n};\n\nconst SegmentedControl: React.FC<PropsWithChildren<SegmentedControlProps>> = ({\n className,\n rounded = false,\n leftIcon,\n rightIcon,\n active = false,\n variant = \"default\",\n size = \"md\",\n children,\n onClick,\n disabled,\n}) => {\n const colorStyles = {\n default: {\n active: \"bg-neutral-200 dark:bg-neutral-1100\",\n inactive:\n \"bg-neutral-000 dark:bg-neutral-1300 hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-100 dark:active:bg-neutral-1200\",\n },\n subtle: {\n active: \"bg-neutral-000 dark:bg-neutral-1000\",\n inactive:\n \"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-200 dark:active:bg-neutral-1100\",\n },\n strong: {\n active: \"bg-neutral-1000 dark:bg-neutral-300\",\n inactive:\n \"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-200 dark:active:bg-neutral-1100\",\n },\n };\n\n const contentColorStyles = {\n default: {\n active: \"text-neutral-1300 dark:text-neutral-000\",\n inactive:\n \"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000\",\n },\n subtle: {\n active: \"text-neutral-1300 dark:text-neutral-000\",\n inactive:\n \"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000\",\n },\n strong: {\n active: \"text-neutral-000 dark:text-neutral-1300\",\n inactive:\n \"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000\",\n },\n };\n\n const sizeStyles = {\n md: cn(\"h-12 p-3 gap-2.5\", rounded && \"px-[1.125rem]\"),\n sm: cn(\"h-10 p-[0.5625rem] gap-[0.5625rem]\", rounded && \"px-3.5\"),\n xs: cn(\"h-9 p-2 gap-2\", rounded && \"px-3\"),\n };\n\n const textStyles = {\n md: \"ui-text-label2\",\n sm: \"ui-text-label3\",\n xs: \"ui-text-label4\",\n };\n\n const iconSizes: Record<SegmentedControlSize, IconSize> = {\n md: \"23px\",\n sm: \"22px\",\n xs: \"20px\",\n };\n\n const activeKey = active ? \"active\" : \"inactive\";\n\n return (\n <div\n onClick={!disabled ? onClick : undefined}\n onKeyDown={(e) => {\n if ((e.key === \"Enter\" || e.key === \" \") && !disabled && onClick) {\n e.preventDefault();\n onClick();\n }\n }}\n className={cn(\n \"focus-base flex items-center justify-center cursor-pointer select-none transition-colors\",\n colorStyles[variant][activeKey],\n contentColorStyles[variant][activeKey],\n sizeStyles[size],\n textStyles[size],\n disabled &&\n \"cursor-not-allowed hover:bg-inherit dark:hover:bg-inherit active:bg-inherit dark:active:bg-inherit\",\n rounded ? \"rounded-full\" : \"rounded-lg\",\n className,\n )}\n tabIndex={disabled ? -1 : 0}\n role=\"button\"\n aria-pressed={active}\n aria-disabled={disabled}\n >\n {leftIcon && (\n <Icon\n name={leftIcon}\n size={iconSizes[size]}\n aria-hidden=\"true\"\n color={contentColorStyles[variant][activeKey] as ColorClass}\n />\n )}\n {children && (\n <span\n className={cn(\n \"font-semibold transition-colors\",\n contentColorStyles[variant][activeKey],\n disabled &&\n \"text-gui-
|
|
1
|
+
{"version":3,"sources":["../../src/core/SegmentedControl.tsx"],"sourcesContent":["import React, { PropsWithChildren } from \"react\";\nimport cn from \"./utils/cn\";\nimport Icon from \"./Icon\";\nimport type { IconName, IconSize } from \"./Icon/types\";\nimport { ColorClass } from \"./styles/colors/types\";\n\nexport type SegmentedControlSize = \"md\" | \"sm\" | \"xs\";\n\nexport type SegmentedControlProps = {\n className?: string;\n rounded?: boolean;\n leftIcon?: IconName;\n rightIcon?: IconName;\n active?: boolean;\n variant?: \"default\" | \"subtle\" | \"strong\";\n size?: SegmentedControlSize;\n onClick?: () => void;\n disabled?: boolean;\n};\n\nconst SegmentedControl: React.FC<PropsWithChildren<SegmentedControlProps>> = ({\n className,\n rounded = false,\n leftIcon,\n rightIcon,\n active = false,\n variant = \"default\",\n size = \"md\",\n children,\n onClick,\n disabled,\n}) => {\n const colorStyles = {\n default: {\n active: \"bg-neutral-200 dark:bg-neutral-1100\",\n inactive:\n \"bg-neutral-000 dark:bg-neutral-1300 hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-100 dark:active:bg-neutral-1200\",\n },\n subtle: {\n active: \"bg-neutral-000 dark:bg-neutral-1000\",\n inactive:\n \"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-200 dark:active:bg-neutral-1100\",\n },\n strong: {\n active: \"bg-neutral-1000 dark:bg-neutral-300\",\n inactive:\n \"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-200 dark:active:bg-neutral-1100\",\n },\n };\n\n const contentColorStyles = {\n default: {\n active: \"text-neutral-1300 dark:text-neutral-000\",\n inactive:\n \"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000\",\n },\n subtle: {\n active: \"text-neutral-1300 dark:text-neutral-000\",\n inactive:\n \"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000\",\n },\n strong: {\n active: \"text-neutral-000 dark:text-neutral-1300\",\n inactive:\n \"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000\",\n },\n };\n\n const sizeStyles = {\n md: cn(\"h-12 p-3 gap-2.5\", rounded && \"px-[1.125rem]\"),\n sm: cn(\"h-10 p-[0.5625rem] gap-[0.5625rem]\", rounded && \"px-3.5\"),\n xs: cn(\"h-9 p-2 gap-2\", rounded && \"px-3\"),\n };\n\n const textStyles = {\n md: \"ui-text-label2\",\n sm: \"ui-text-label3\",\n xs: \"ui-text-label4\",\n };\n\n const iconSizes: Record<SegmentedControlSize, IconSize> = {\n md: \"23px\",\n sm: \"22px\",\n xs: \"20px\",\n };\n\n const activeKey = active ? \"active\" : \"inactive\";\n\n return (\n <div\n onClick={!disabled ? onClick : undefined}\n onKeyDown={(e) => {\n if ((e.key === \"Enter\" || e.key === \" \") && !disabled && onClick) {\n e.preventDefault();\n onClick();\n }\n }}\n className={cn(\n \"focus-base flex items-center justify-center cursor-pointer select-none transition-colors\",\n colorStyles[variant][activeKey],\n contentColorStyles[variant][activeKey],\n sizeStyles[size],\n textStyles[size],\n disabled &&\n \"cursor-not-allowed hover:bg-inherit dark:hover:bg-inherit active:bg-inherit dark:active:bg-inherit\",\n rounded ? \"rounded-full\" : \"rounded-lg\",\n className,\n )}\n tabIndex={disabled ? -1 : 0}\n role=\"button\"\n aria-pressed={active}\n aria-disabled={disabled}\n >\n {leftIcon && (\n <Icon\n name={leftIcon}\n size={iconSizes[size]}\n aria-hidden=\"true\"\n color={contentColorStyles[variant][activeKey] as ColorClass}\n />\n )}\n {children && (\n <span\n className={cn(\n \"font-semibold transition-colors\",\n contentColorStyles[variant][activeKey],\n disabled &&\n \"text-gui-disabled-light dark:text-gui-disabled-dark hover:text-gui-disabled-light dark:hover:text-gui-disabled-dark\",\n )}\n >\n {children}\n </span>\n )}\n {rightIcon && (\n <Icon\n name={rightIcon}\n size={iconSizes[size]}\n aria-hidden=\"true\"\n color={contentColorStyles[variant][activeKey] as ColorClass}\n />\n )}\n </div>\n );\n};\n\nexport default SegmentedControl;\n"],"names":["React","cn","Icon","SegmentedControl","className","rounded","leftIcon","rightIcon","active","variant","size","children","onClick","disabled","colorStyles","default","inactive","subtle","strong","contentColorStyles","sizeStyles","md","sm","xs","textStyles","iconSizes","activeKey","div","undefined","onKeyDown","e","key","preventDefault","tabIndex","role","aria-pressed","aria-disabled","name","aria-hidden","color","span"],"mappings":"AAAA,OAAOA,UAAkC,OAAQ,AACjD,QAAOC,OAAQ,YAAa,AAC5B,QAAOC,SAAU,QAAS,CAkB1B,MAAMC,iBAAuE,CAAC,CAC5EC,SAAS,CACTC,QAAU,KAAK,CACfC,QAAQ,CACRC,SAAS,CACTC,OAAS,KAAK,CACdC,QAAU,SAAS,CACnBC,KAAO,IAAI,CACXC,QAAQ,CACRC,OAAO,CACPC,QAAQ,CACT,IACC,MAAMC,YAAc,CAClBC,QAAS,CACPP,OAAQ,sCACRQ,SACE,uIACJ,EACAC,OAAQ,CACNT,OAAQ,sCACRQ,SACE,uIACJ,EACAE,OAAQ,CACNV,OAAQ,sCACRQ,SACE,uIACJ,CACF,EAEA,MAAMG,mBAAqB,CACzBJ,QAAS,CACPP,OAAQ,0CACRQ,SACE,6FACJ,EACAC,OAAQ,CACNT,OAAQ,0CACRQ,SACE,6FACJ,EACAE,OAAQ,CACNV,OAAQ,0CACRQ,SACE,6FACJ,CACF,EAEA,MAAMI,WAAa,CACjBC,GAAIpB,GAAG,mBAAoBI,SAAW,iBACtCiB,GAAIrB,GAAG,qCAAsCI,SAAW,UACxDkB,GAAItB,GAAG,gBAAiBI,SAAW,OACrC,EAEA,MAAMmB,WAAa,CACjBH,GAAI,iBACJC,GAAI,iBACJC,GAAI,gBACN,EAEA,MAAME,UAAoD,CACxDJ,GAAI,OACJC,GAAI,OACJC,GAAI,MACN,EAEA,MAAMG,UAAYlB,OAAS,SAAW,WAEtC,OACE,oBAACmB,OACCf,QAAS,CAACC,SAAWD,QAAUgB,UAC/BC,UAAW,AAACC,IACV,GAAI,AAACA,CAAAA,EAAEC,GAAG,GAAK,SAAWD,EAAEC,GAAG,GAAK,GAAE,GAAM,CAAClB,UAAYD,QAAS,CAChEkB,EAAEE,cAAc,GAChBpB,SACF,CACF,EACAR,UAAWH,GACT,2FACAa,WAAW,CAACL,QAAQ,CAACiB,UAAU,CAC/BP,kBAAkB,CAACV,QAAQ,CAACiB,UAAU,CACtCN,UAAU,CAACV,KAAK,CAChBc,UAAU,CAACd,KAAK,CAChBG,UACE,qGACFR,QAAU,eAAiB,aAC3BD,WAEF6B,SAAUpB,SAAW,CAAC,EAAI,EAC1BqB,KAAK,SACLC,eAAc3B,OACd4B,gBAAevB,UAEdP,UACC,oBAACJ,MACCmC,KAAM/B,SACNI,KAAMe,SAAS,CAACf,KAAK,CACrB4B,cAAY,OACZC,MAAOpB,kBAAkB,CAACV,QAAQ,CAACiB,UAAU,GAGhDf,UACC,oBAAC6B,QACCpC,UAAWH,GACT,kCACAkB,kBAAkB,CAACV,QAAQ,CAACiB,UAAU,CACtCb,UACE,wHAGHF,UAGJJ,WACC,oBAACL,MACCmC,KAAM9B,UACNG,KAAMe,SAAS,CAACf,KAAK,CACrB4B,cAAY,OACZC,MAAOpB,kBAAkB,CAACV,QAAQ,CAACiB,UAAU,GAKvD,CAEA,gBAAevB,gBAAiB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import React,{createContext,useContext,useMemo}from"react";import useSWR from"swr";const SessionDataContext=createContext(undefined);const fetcher=async url=>{const options={headers:{accept:"application/json"},cache:"no-cache"};if(typeof false!=="undefined"&&false){options.credentials="include"}const res=await fetch(url,options);if(!res.ok){throw new Error("Failed to fetch session data")}const contentType=res.headers.get("content-type");if(!contentType?.includes("application/json")){throw new Error("Session endpoint is not serving json")}const data=await res.json();if(data.error==="not-found"){return null}return data};const SESSION_SWR_OPTIONS={revalidateOnFocus:false,revalidateOnReconnect:false,shouldRetryOnError:false,onError:err=>{console.warn("Could not fetch session data due to error:",err)}};export const SessionDataProvider=({children,sessionDataUrl})=>{const{data,error,isLoading}=useSWR(sessionDataUrl||null,fetcher,SESSION_SWR_OPTIONS);const contextValue=useMemo(()=>({sessionData:data??null,isLoading,error}),[data,isLoading,error]);return React.createElement(SessionDataContext.Provider,{value:contextValue},children)};export const useSessionData=()=>{const context=useContext(SessionDataContext);if(context===undefined){throw new Error("useSessionData must be used within SessionDataProvider")}return context};export const useSessionDataDirect=sessionDataUrl=>{const{data,error,isLoading}=useSWR(sessionDataUrl||null,fetcher,SESSION_SWR_OPTIONS);return{sessionData:data??null,isLoading,error}};
|
|
2
|
+
//# sourceMappingURL=SessionData.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/SessionData.tsx"],"sourcesContent":["import React, {\n createContext,\n useContext,\n PropsWithChildren,\n useMemo,\n} from \"react\";\nimport useSWR from \"swr\";\n\n// Feature flag for enabling credentials in fetch requests\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ndeclare const __ENABLE_FETCH_WITH_CREDENTIALS__: boolean | undefined;\n\ntype SessionUser = {\n firstName?: string;\n lastName?: string;\n email?: string;\n};\n\ntype SessionData = {\n user?: SessionUser;\n} | null;\n\ntype SessionDataContextType = {\n sessionData: SessionData;\n isLoading: boolean;\n error: Error | undefined;\n};\n\nconst SessionDataContext = createContext<SessionDataContextType | undefined>(\n undefined,\n);\n\ntype SessionDataProviderProps = PropsWithChildren<{\n sessionDataUrl?: string;\n}>;\n\n/**\n * fetcher - Retrieves session data from a backend API endpoint.\n *\n * Makes a JSON request to fetch current user session information. Optionally includes\n * credentials (cookies) based on the __ENABLE_FETCH_WITH_CREDENTIALS__ feature flag.\n * Handles \"not-found\" responses gracefully by returning null instead of throwing.\n * Validates response is JSON to prevent parsing errors.\n */\nconst fetcher = async (url: string): Promise<SessionData> => {\n const options: RequestInit = {\n headers: {\n accept: \"application/json\",\n },\n cache: \"no-cache\",\n };\n\n // Check if credentials should be included (feature flag)\n if (\n typeof __ENABLE_FETCH_WITH_CREDENTIALS__ !== \"undefined\" &&\n __ENABLE_FETCH_WITH_CREDENTIALS__\n ) {\n options.credentials = \"include\";\n }\n\n const res = await fetch(url, options);\n\n if (!res.ok) {\n throw new Error(\"Failed to fetch session data\");\n }\n\n const contentType = res.headers.get(\"content-type\");\n if (!contentType?.includes(\"application/json\")) {\n throw new Error(\"Session endpoint is not serving json\");\n }\n\n const data = await res.json();\n\n // Handle \"not found\" error gracefully\n if (data.error === \"not-found\") {\n return null;\n }\n\n return data;\n};\n\nconst SESSION_SWR_OPTIONS = {\n revalidateOnFocus: false,\n revalidateOnReconnect: false,\n shouldRetryOnError: false,\n onError: (err: Error) => {\n console.warn(\"Could not fetch session data due to error:\", err);\n },\n};\n\n/**\n * SessionDataProvider - Context provider for managing user session data throughout the app.\n *\n * Fetches and caches session data using SWR (stale-while-revalidate) from the provided URL.\n * Exposes session data, loading state, and errors through context. Use this at the app root\n * level and access via useSessionData() hook in child components. Disables auto-revalidation\n * to avoid excessive network requests - session data is fetched once on mount.\n */\nexport const SessionDataProvider = ({\n children,\n sessionDataUrl,\n}: SessionDataProviderProps) => {\n const { data, error, isLoading } = useSWR<SessionData>(\n sessionDataUrl || null,\n fetcher,\n SESSION_SWR_OPTIONS,\n );\n\n const contextValue = useMemo(\n () => ({\n sessionData: data ?? null,\n isLoading,\n error,\n }),\n [data, isLoading, error],\n );\n\n return (\n <SessionDataContext.Provider value={contextValue}>\n {children}\n </SessionDataContext.Provider>\n );\n};\n\n/**\n * useSessionData - Hook to access session data from SessionDataProvider context.\n *\n * Returns the current user session data, loading state, and any errors from the provider.\n * Must be used within a SessionDataProvider or will throw an error. Use this hook in\n * components that need to read or display user session information.\n */\nexport const useSessionData = () => {\n const context = useContext(SessionDataContext);\n if (context === undefined) {\n throw new Error(\"useSessionData must be used within SessionDataProvider\");\n }\n return context;\n};\n\n/**\n * useSessionDataDirect - Direct session data hook without requiring a provider (legacy).\n *\n * Fetches session data using SWR directly, bypassing the context provider pattern.\n * Provided for backward compatibility with code that doesn't use SessionDataProvider.\n * For new code, prefer using SessionDataProvider + useSessionData() for better\n * performance and centralized session management.\n */\nexport const useSessionDataDirect = (sessionDataUrl?: string) => {\n const { data, error, isLoading } = useSWR<SessionData>(\n sessionDataUrl || null,\n fetcher,\n SESSION_SWR_OPTIONS,\n );\n\n return {\n sessionData: data ?? null,\n isLoading,\n error,\n };\n};\n"],"names":["React","createContext","useContext","useMemo","useSWR","SessionDataContext","undefined","fetcher","url","options","headers","accept","cache","credentials","res","fetch","ok","Error","contentType","get","includes","data","json","error","SESSION_SWR_OPTIONS","revalidateOnFocus","revalidateOnReconnect","shouldRetryOnError","onError","err","console","warn","SessionDataProvider","children","sessionDataUrl","isLoading","contextValue","sessionData","Provider","value","useSessionData","context","useSessionDataDirect"],"mappings":"AAAA,OAAOA,OACLC,aAAa,CACbC,UAAU,CAEVC,OAAO,KACF,OAAQ,AACf,QAAOC,WAAY,KAAM,CAsBzB,MAAMC,mBAAqBJ,cACzBK,WAeF,MAAMC,QAAU,MAAOC,MACrB,MAAMC,QAAuB,CAC3BC,QAAS,CACPC,OAAQ,kBACV,EACAC,MAAO,UACT,EAGA,GACE,OAgGD,QAhG8C,aAgG9C,MA9FC,CACAH,QAAQI,WAAW,CAAG,SACxB,CAEA,MAAMC,IAAM,MAAMC,MAAMP,IAAKC,SAE7B,GAAI,CAACK,IAAIE,EAAE,CAAE,CACX,MAAM,IAAIC,MAAM,+BAClB,CAEA,MAAMC,YAAcJ,IAAIJ,OAAO,CAACS,GAAG,CAAC,gBACpC,GAAI,CAACD,aAAaE,SAAS,oBAAqB,CAC9C,MAAM,IAAIH,MAAM,uCAClB,CAEA,MAAMI,KAAO,MAAMP,IAAIQ,IAAI,GAG3B,GAAID,KAAKE,KAAK,GAAK,YAAa,CAC9B,OAAO,IACT,CAEA,OAAOF,IACT,EAEA,MAAMG,oBAAsB,CAC1BC,kBAAmB,MACnBC,sBAAuB,MACvBC,mBAAoB,MACpBC,QAAS,AAACC,MACRC,QAAQC,IAAI,CAAC,6CAA8CF,IAC7D,CACF,CAUA,QAAO,MAAMG,oBAAsB,CAAC,CAClCC,QAAQ,CACRC,cAAc,CACW,IACzB,KAAM,CAAEb,IAAI,CAAEE,KAAK,CAAEY,SAAS,CAAE,CAAG/B,OACjC8B,gBAAkB,KAClB3B,QACAiB,qBAGF,MAAMY,aAAejC,QACnB,IAAO,CAAA,CACLkC,YAAahB,MAAQ,KACrBc,UACAZ,KACF,CAAA,EACA,CAACF,KAAMc,UAAWZ,MAAM,EAG1B,OACE,oBAAClB,mBAAmBiC,QAAQ,EAACC,MAAOH,cACjCH,SAGP,CAAE,AASF,QAAO,MAAMO,eAAiB,KAC5B,MAAMC,QAAUvC,WAAWG,oBAC3B,GAAIoC,UAAYnC,UAAW,CACzB,MAAM,IAAIW,MAAM,yDAClB,CACA,OAAOwB,OACT,CAAE,AAUF,QAAO,MAAMC,qBAAuB,AAACR,iBACnC,KAAM,CAAEb,IAAI,CAAEE,KAAK,CAAEY,SAAS,CAAE,CAAG/B,OACjC8B,gBAAkB,KAClB3B,QACAiB,qBAGF,MAAO,CACLa,YAAahB,MAAQ,KACrBc,UACAZ,KACF,CACF,CAAE"}
|
package/core/TabMenu.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useEffect}from"react";import*as Tabs from"@radix-ui/react-tabs";import{throttle}from"es-toolkit/compat";import cn from"./utils/cn";const DEFAULT_TAILWIND_ANIMATION_DURATION=150;const TabMenu=({tabs=[],contents=[],tabOnClick,tabClassName,rootClassName,contentClassName,options})=>{const{defaultTabIndex=0,underline=true,animated:animatedOption=true,flexibleTabWidth=false,flexibleTabHeight=false}=options??{};const listRef=React.useRef(null);const[animated,setAnimated]=React.useState(false);const[highlight,setHighlight]=React.useState({offset:0,width:0});useEffect(()=>{if(animatedOption&&highlight.width>0){setTimeout(()=>{setAnimated(true)},DEFAULT_TAILWIND_ANIMATION_DURATION)}},[animatedOption,highlight.width]);const updateHighlightDimensions=element=>{const{left:parentLeft}=listRef.current?.getBoundingClientRect()??{};const{left,width}=element.getBoundingClientRect()??{};setHighlight({offset:(left??0)-(parentLeft??0),width:width??0})};useEffect(()=>{const handleResize=throttle(()=>{const activeTabElement=listRef.current?.querySelector(`[data-state="active"]`);if(activeTabElement){updateHighlightDimensions(activeTabElement)}},100);handleResize();window.addEventListener("resize",handleResize);return()=>{window.removeEventListener("resize",handleResize)}},[]);const handleTabClick=(event,index)=>{tabOnClick?.(index);updateHighlightDimensions(event.currentTarget)};const tabTriggerContent=tab=>{if(!tab){return null}if(React.isValidElement(tab)||typeof tab==="string"){return tab}if(typeof tab==="object"&&"label"in tab){return tab.label}return null};return React.createElement(Tabs.Root,{defaultValue:`tab-${defaultTabIndex}`,className:cn({"h-full":flexibleTabHeight},rootClassName)},React.createElement(Tabs.List,{ref:listRef,className:cn("relative",{"flex border-b border-neutral-300 dark:border-neutral-1000":underline},{"h-full":flexibleTabHeight})},tabs.map((tab,index)=>tab&&React.createElement(Tabs.Trigger,{key:`tab-${index}`,className:cn("lg:px-6 md:px-5 px-4 py-4 ui-text-label1 font-bold data-[state=active]:text-neutral-1300 text-neutral-1000 dark:data-[state=active]:text-neutral-000 dark:text-neutral-300 focus:outline-none focus-visible:outline-gui-focus transition-colors hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-900 dark:active:text-neutral-400 disabled:text-gui-
|
|
1
|
+
import React,{useEffect}from"react";import*as Tabs from"@radix-ui/react-tabs";import{throttle}from"es-toolkit/compat";import cn from"./utils/cn";const DEFAULT_TAILWIND_ANIMATION_DURATION=150;const TabMenu=({tabs=[],contents=[],tabOnClick,tabClassName,rootClassName,contentClassName,options})=>{const{defaultTabIndex=0,underline=true,animated:animatedOption=true,flexibleTabWidth=false,flexibleTabHeight=false}=options??{};const listRef=React.useRef(null);const[animated,setAnimated]=React.useState(false);const[highlight,setHighlight]=React.useState({offset:0,width:0});useEffect(()=>{if(animatedOption&&highlight.width>0){setTimeout(()=>{setAnimated(true)},DEFAULT_TAILWIND_ANIMATION_DURATION)}},[animatedOption,highlight.width]);const updateHighlightDimensions=element=>{const{left:parentLeft}=listRef.current?.getBoundingClientRect()??{};const{left,width}=element.getBoundingClientRect()??{};setHighlight({offset:(left??0)-(parentLeft??0),width:width??0})};useEffect(()=>{const handleResize=throttle(()=>{const activeTabElement=listRef.current?.querySelector(`[data-state="active"]`);if(activeTabElement){updateHighlightDimensions(activeTabElement)}},100);handleResize();window.addEventListener("resize",handleResize);return()=>{window.removeEventListener("resize",handleResize)}},[]);const handleTabClick=(event,index)=>{tabOnClick?.(index);updateHighlightDimensions(event.currentTarget)};const tabTriggerContent=tab=>{if(!tab){return null}if(React.isValidElement(tab)||typeof tab==="string"){return tab}if(typeof tab==="object"&&"label"in tab){return tab.label}return null};return React.createElement(Tabs.Root,{defaultValue:`tab-${defaultTabIndex}`,className:cn({"h-full":flexibleTabHeight},rootClassName)},React.createElement(Tabs.List,{ref:listRef,className:cn("relative",{"flex border-b border-neutral-300 dark:border-neutral-1000":underline},{"h-full":flexibleTabHeight})},tabs.map((tab,index)=>tab&&React.createElement(Tabs.Trigger,{key:`tab-${index}`,className:cn("lg:px-6 md:px-5 px-4 py-4 ui-text-label1 font-bold data-[state=active]:text-neutral-1300 text-neutral-1000 dark:data-[state=active]:text-neutral-000 dark:text-neutral-300 focus:outline-none focus-visible:outline-gui-focus transition-colors hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-900 dark:active:text-neutral-400 disabled:text-gui-disabled-light dark:disabled:text-gui-disabled-dark disabled:cursor-not-allowed",{"flex-1":flexibleTabWidth},{"h-full":flexibleTabHeight},tabClassName),value:`tab-${index}`,onClick:event=>handleTabClick(event,index),disabled:typeof tab==="object"&&"disabled"in tab?tab.disabled:false},tabTriggerContent(tab))),React.createElement("div",{className:cn("absolute bottom-0 bg-neutral-1300 dark:bg-neutral-000 h-[0.1875rem] w-6",{"transition-[transform,width]":animated}),style:{transform:`translateX(${highlight.offset}px)`,width:`${highlight.width}px`}})),contents.map((content,index)=>React.createElement(Tabs.Content,{key:`tab-${index}`,value:`tab-${index}`,className:contentClassName},content)))};export default TabMenu;
|
|
2
2
|
//# sourceMappingURL=TabMenu.js.map
|
package/core/TabMenu.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/TabMenu.tsx"],"sourcesContent":["import React, { ReactNode, useEffect } from \"react\";\nimport * as Tabs from \"@radix-ui/react-tabs\";\nimport { throttle } from \"es-toolkit/compat\";\nimport cn from \"./utils/cn\";\n\ntype TabTriggerContent =\n | string\n | { label: string; disabled?: boolean }\n | ReactNode;\n\n/**\n * Props for the TabMenu component.\n */\n\nexport type TabMenuProps = {\n /**\n * An array of tabs, which can be either a string or an object with a label and an optional disabled state.\n */\n tabs: TabTriggerContent[];\n\n /**\n * An optional array of React nodes representing the content for each tab.\n */\n contents?: ReactNode[];\n\n /**\n * An optional callback function that is called when a tab is clicked, receiving the index of the clicked tab.\n */\n tabOnClick?: (index: number) => void;\n\n /**\n * An optional class name to apply to each tab.\n */\n tabClassName?: string;\n\n /**\n * An optional class name to apply to the Tabs.Root element.\n */\n rootClassName?: string;\n\n /**\n * An optional class name to apply to the Tabs.Content element.\n */\n contentClassName?: string;\n\n /**\n * Optional configuration options for the TabMenu.\n */\n options?: {\n /**\n * The index of the tab that should be selected by default.\n */\n defaultTabIndex?: number;\n\n /**\n * Whether to show an underline below the selected tab.\n */\n underline?: boolean;\n\n /**\n * Whether to animate the transition between tabs.\n */\n animated?: boolean;\n\n /**\n * Whether the tab width should be flexible.\n */\n flexibleTabWidth?: boolean;\n\n /**\n * Whether the tab height should be flexible.\n */\n flexibleTabHeight?: boolean;\n };\n};\n\nconst DEFAULT_TAILWIND_ANIMATION_DURATION = 150;\n\nconst TabMenu: React.FC<TabMenuProps> = ({\n tabs = [],\n contents = [],\n tabOnClick,\n tabClassName,\n rootClassName,\n contentClassName,\n options,\n}) => {\n const {\n defaultTabIndex = 0,\n underline = true,\n animated: animatedOption = true,\n flexibleTabWidth = false,\n flexibleTabHeight = false,\n } = options ?? {};\n\n const listRef = React.useRef<HTMLDivElement>(null);\n const [animated, setAnimated] = React.useState(false);\n const [highlight, setHighlight] = React.useState({ offset: 0, width: 0 });\n\n useEffect(() => {\n if (animatedOption && highlight.width > 0) {\n setTimeout(() => {\n setAnimated(true);\n }, DEFAULT_TAILWIND_ANIMATION_DURATION);\n }\n }, [animatedOption, highlight.width]);\n\n const updateHighlightDimensions = (element: HTMLButtonElement) => {\n const { left: parentLeft } = listRef.current?.getBoundingClientRect() ?? {};\n const { left, width } = element.getBoundingClientRect() ?? {};\n\n setHighlight({\n offset: (left ?? 0) - (parentLeft ?? 0),\n width: width ?? 0,\n });\n };\n\n useEffect(() => {\n const handleResize = throttle(() => {\n const activeTabElement =\n listRef.current?.querySelector<HTMLButtonElement>(\n `[data-state=\"active\"]`,\n );\n\n if (activeTabElement) {\n updateHighlightDimensions(activeTabElement);\n }\n }, 100);\n\n handleResize();\n\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n };\n }, []);\n\n const handleTabClick = (\n event: React.MouseEvent<HTMLButtonElement>,\n index: number,\n ) => {\n tabOnClick?.(index);\n updateHighlightDimensions(event.currentTarget as HTMLButtonElement);\n };\n\n const tabTriggerContent = (tab: TabTriggerContent) => {\n if (!tab) {\n return null;\n }\n\n if (React.isValidElement(tab) || typeof tab === \"string\") {\n return tab;\n }\n\n if (typeof tab === \"object\" && \"label\" in tab) {\n return tab.label;\n }\n\n return null;\n };\n\n return (\n <Tabs.Root\n defaultValue={`tab-${defaultTabIndex}`}\n className={cn({ \"h-full\": flexibleTabHeight }, rootClassName)}\n >\n <Tabs.List\n ref={listRef}\n className={cn(\n \"relative\",\n {\n \"flex border-b border-neutral-300 dark:border-neutral-1000\":\n underline,\n },\n { \"h-full\": flexibleTabHeight },\n )}\n >\n {tabs.map(\n (tab, index) =>\n tab && (\n <Tabs.Trigger\n key={`tab-${index}`}\n className={cn(\n \"lg:px-6 md:px-5 px-4 py-4 ui-text-label1 font-bold data-[state=active]:text-neutral-1300 text-neutral-1000 dark:data-[state=active]:text-neutral-000 dark:text-neutral-300 focus:outline-none focus-visible:outline-gui-focus transition-colors hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-900 dark:active:text-neutral-400 disabled:text-gui-
|
|
1
|
+
{"version":3,"sources":["../../src/core/TabMenu.tsx"],"sourcesContent":["import React, { ReactNode, useEffect } from \"react\";\nimport * as Tabs from \"@radix-ui/react-tabs\";\nimport { throttle } from \"es-toolkit/compat\";\nimport cn from \"./utils/cn\";\n\ntype TabTriggerContent =\n | string\n | { label: string; disabled?: boolean }\n | ReactNode;\n\n/**\n * Props for the TabMenu component.\n */\n\nexport type TabMenuProps = {\n /**\n * An array of tabs, which can be either a string or an object with a label and an optional disabled state.\n */\n tabs: TabTriggerContent[];\n\n /**\n * An optional array of React nodes representing the content for each tab.\n */\n contents?: ReactNode[];\n\n /**\n * An optional callback function that is called when a tab is clicked, receiving the index of the clicked tab.\n */\n tabOnClick?: (index: number) => void;\n\n /**\n * An optional class name to apply to each tab.\n */\n tabClassName?: string;\n\n /**\n * An optional class name to apply to the Tabs.Root element.\n */\n rootClassName?: string;\n\n /**\n * An optional class name to apply to the Tabs.Content element.\n */\n contentClassName?: string;\n\n /**\n * Optional configuration options for the TabMenu.\n */\n options?: {\n /**\n * The index of the tab that should be selected by default.\n */\n defaultTabIndex?: number;\n\n /**\n * Whether to show an underline below the selected tab.\n */\n underline?: boolean;\n\n /**\n * Whether to animate the transition between tabs.\n */\n animated?: boolean;\n\n /**\n * Whether the tab width should be flexible.\n */\n flexibleTabWidth?: boolean;\n\n /**\n * Whether the tab height should be flexible.\n */\n flexibleTabHeight?: boolean;\n };\n};\n\nconst DEFAULT_TAILWIND_ANIMATION_DURATION = 150;\n\nconst TabMenu: React.FC<TabMenuProps> = ({\n tabs = [],\n contents = [],\n tabOnClick,\n tabClassName,\n rootClassName,\n contentClassName,\n options,\n}) => {\n const {\n defaultTabIndex = 0,\n underline = true,\n animated: animatedOption = true,\n flexibleTabWidth = false,\n flexibleTabHeight = false,\n } = options ?? {};\n\n const listRef = React.useRef<HTMLDivElement>(null);\n const [animated, setAnimated] = React.useState(false);\n const [highlight, setHighlight] = React.useState({ offset: 0, width: 0 });\n\n useEffect(() => {\n if (animatedOption && highlight.width > 0) {\n setTimeout(() => {\n setAnimated(true);\n }, DEFAULT_TAILWIND_ANIMATION_DURATION);\n }\n }, [animatedOption, highlight.width]);\n\n const updateHighlightDimensions = (element: HTMLButtonElement) => {\n const { left: parentLeft } = listRef.current?.getBoundingClientRect() ?? {};\n const { left, width } = element.getBoundingClientRect() ?? {};\n\n setHighlight({\n offset: (left ?? 0) - (parentLeft ?? 0),\n width: width ?? 0,\n });\n };\n\n useEffect(() => {\n const handleResize = throttle(() => {\n const activeTabElement =\n listRef.current?.querySelector<HTMLButtonElement>(\n `[data-state=\"active\"]`,\n );\n\n if (activeTabElement) {\n updateHighlightDimensions(activeTabElement);\n }\n }, 100);\n\n handleResize();\n\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n };\n }, []);\n\n const handleTabClick = (\n event: React.MouseEvent<HTMLButtonElement>,\n index: number,\n ) => {\n tabOnClick?.(index);\n updateHighlightDimensions(event.currentTarget as HTMLButtonElement);\n };\n\n const tabTriggerContent = (tab: TabTriggerContent) => {\n if (!tab) {\n return null;\n }\n\n if (React.isValidElement(tab) || typeof tab === \"string\") {\n return tab;\n }\n\n if (typeof tab === \"object\" && \"label\" in tab) {\n return tab.label;\n }\n\n return null;\n };\n\n return (\n <Tabs.Root\n defaultValue={`tab-${defaultTabIndex}`}\n className={cn({ \"h-full\": flexibleTabHeight }, rootClassName)}\n >\n <Tabs.List\n ref={listRef}\n className={cn(\n \"relative\",\n {\n \"flex border-b border-neutral-300 dark:border-neutral-1000\":\n underline,\n },\n { \"h-full\": flexibleTabHeight },\n )}\n >\n {tabs.map(\n (tab, index) =>\n tab && (\n <Tabs.Trigger\n key={`tab-${index}`}\n className={cn(\n \"lg:px-6 md:px-5 px-4 py-4 ui-text-label1 font-bold data-[state=active]:text-neutral-1300 text-neutral-1000 dark:data-[state=active]:text-neutral-000 dark:text-neutral-300 focus:outline-none focus-visible:outline-gui-focus transition-colors hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-900 dark:active:text-neutral-400 disabled:text-gui-disabled-light dark:disabled:text-gui-disabled-dark disabled:cursor-not-allowed\",\n { \"flex-1\": flexibleTabWidth },\n { \"h-full\": flexibleTabHeight },\n tabClassName,\n )}\n value={`tab-${index}`}\n onClick={(event) => handleTabClick(event, index)}\n disabled={\n typeof tab === \"object\" && \"disabled\" in tab\n ? tab.disabled\n : false\n }\n >\n {tabTriggerContent(tab)}\n </Tabs.Trigger>\n ),\n )}\n <div\n className={cn(\n \"absolute bottom-0 bg-neutral-1300 dark:bg-neutral-000 h-[0.1875rem] w-6\",\n { \"transition-[transform,width]\": animated },\n )}\n style={{\n transform: `translateX(${highlight.offset}px)`,\n width: `${highlight.width}px`,\n }}\n ></div>\n </Tabs.List>\n {contents.map((content, index) => (\n <Tabs.Content\n key={`tab-${index}`}\n value={`tab-${index}`}\n className={contentClassName}\n >\n {content}\n </Tabs.Content>\n ))}\n </Tabs.Root>\n );\n};\n\nexport default TabMenu;\n"],"names":["React","useEffect","Tabs","throttle","cn","DEFAULT_TAILWIND_ANIMATION_DURATION","TabMenu","tabs","contents","tabOnClick","tabClassName","rootClassName","contentClassName","options","defaultTabIndex","underline","animated","animatedOption","flexibleTabWidth","flexibleTabHeight","listRef","useRef","setAnimated","useState","highlight","setHighlight","offset","width","setTimeout","updateHighlightDimensions","element","left","parentLeft","current","getBoundingClientRect","handleResize","activeTabElement","querySelector","window","addEventListener","removeEventListener","handleTabClick","event","index","currentTarget","tabTriggerContent","tab","isValidElement","label","Root","defaultValue","className","List","ref","map","Trigger","key","value","onClick","disabled","div","style","transform","content","Content"],"mappings":"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"}
|
package/core/Toggle.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import*as Switch from"@radix-ui/react-switch";import React from"react";import cn from"./utils/cn";const Toggle=({id,size="lg",label,className,...props})=>{const rootSize=size==="sm"?"w-[2.625rem] h-6":"w-14 h-8";const thumbSize=size==="sm"?"w-[1.3125rem] h-[1.3125rem] translate-x-px data-[state=checked]:translate-x-5":"h-7 w-7 translate-x-0.5 data-[state=checked]:translate-x-[1.625rem]";return React.createElement("div",{className:"flex items-center"},React.createElement(Switch.Root,{className:cn("p-0 bg-neutral-600 rounded-full relative inline-block transition-colors data-[disabled]:bg-gui-
|
|
1
|
+
import*as Switch from"@radix-ui/react-switch";import React from"react";import cn from"./utils/cn";const Toggle=({id,size="lg",label,className,...props})=>{const rootSize=size==="sm"?"w-[2.625rem] h-6":"w-14 h-8";const thumbSize=size==="sm"?"w-[1.3125rem] h-[1.3125rem] translate-x-px data-[state=checked]:translate-x-5":"h-7 w-7 translate-x-0.5 data-[state=checked]:translate-x-[1.625rem]";return React.createElement("div",{className:"flex items-center"},React.createElement(Switch.Root,{className:cn("p-0 bg-neutral-600 rounded-full relative inline-block transition-colors data-[disabled]:bg-gui-disabled-light dark:data-[disabled]:bg-gui-disabled-dark data-[disabled]:cursor-not-allowed data-[state=checked]:bg-orange-600 focus-base",className,rootSize),id:id,...props},React.createElement(Switch.Thumb,{className:cn(`block bg-white data-[disabled]:bg-neutral-500 dark:data-[disabled]:bg-neutral-800 rounded-full drop-shadow-toggle transition-transform`,thumbSize)})),label?React.createElement("label",{className:"ml-4",htmlFor:id},label):null)};export default Toggle;
|
|
2
2
|
//# sourceMappingURL=Toggle.js.map
|
package/core/Toggle.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Toggle.tsx"],"sourcesContent":["import * as Switch from \"@radix-ui/react-switch\";\nimport React from \"react\";\nimport cn from \"./utils/cn\";\n\ntype ToggleProps = {\n id: string;\n size?: \"sm\" | \"lg\";\n label?: string;\n className?: string;\n onCheckedChange?: (checked: boolean) => void;\n} & React.ButtonHTMLAttributes<HTMLButtonElement>;\n\nconst Toggle: React.FC<ToggleProps> = ({\n id,\n size = \"lg\",\n label,\n className,\n ...props\n}) => {\n const rootSize = size === \"sm\" ? \"w-[2.625rem] h-6\" : \"w-14 h-8\";\n const thumbSize =\n size === \"sm\"\n ? \"w-[1.3125rem] h-[1.3125rem] translate-x-px data-[state=checked]:translate-x-5\"\n : \"h-7 w-7 translate-x-0.5 data-[state=checked]:translate-x-[1.625rem]\";\n\n return (\n <div className=\"flex items-center\">\n <Switch.Root\n className={cn(\n \"p-0 bg-neutral-600 rounded-full relative inline-block transition-colors data-[disabled]:bg-gui-
|
|
1
|
+
{"version":3,"sources":["../../src/core/Toggle.tsx"],"sourcesContent":["import * as Switch from \"@radix-ui/react-switch\";\nimport React from \"react\";\nimport cn from \"./utils/cn\";\n\ntype ToggleProps = {\n id: string;\n size?: \"sm\" | \"lg\";\n label?: string;\n className?: string;\n onCheckedChange?: (checked: boolean) => void;\n} & React.ButtonHTMLAttributes<HTMLButtonElement>;\n\nconst Toggle: React.FC<ToggleProps> = ({\n id,\n size = \"lg\",\n label,\n className,\n ...props\n}) => {\n const rootSize = size === \"sm\" ? \"w-[2.625rem] h-6\" : \"w-14 h-8\";\n const thumbSize =\n size === \"sm\"\n ? \"w-[1.3125rem] h-[1.3125rem] translate-x-px data-[state=checked]:translate-x-5\"\n : \"h-7 w-7 translate-x-0.5 data-[state=checked]:translate-x-[1.625rem]\";\n\n return (\n <div className=\"flex items-center\">\n <Switch.Root\n className={cn(\n \"p-0 bg-neutral-600 rounded-full relative inline-block transition-colors data-[disabled]:bg-gui-disabled-light dark:data-[disabled]:bg-gui-disabled-dark data-[disabled]:cursor-not-allowed data-[state=checked]:bg-orange-600 focus-base\",\n className,\n rootSize,\n )}\n id={id}\n {...props}\n >\n <Switch.Thumb\n className={cn(\n `block bg-white data-[disabled]:bg-neutral-500 dark:data-[disabled]:bg-neutral-800 rounded-full drop-shadow-toggle transition-transform`,\n thumbSize,\n )}\n />\n </Switch.Root>\n {label ? (\n <label className=\"ml-4\" htmlFor={id}>\n {label}\n </label>\n ) : null}\n </div>\n );\n};\n\nexport default Toggle;\n"],"names":["Switch","React","cn","Toggle","id","size","label","className","props","rootSize","thumbSize","div","Root","Thumb","htmlFor"],"mappings":"AAAA,UAAYA,WAAY,wBAAyB,AACjD,QAAOC,UAAW,OAAQ,AAC1B,QAAOC,OAAQ,YAAa,CAU5B,MAAMC,OAAgC,CAAC,CACrCC,EAAE,CACFC,KAAO,IAAI,CACXC,KAAK,CACLC,SAAS,CACT,GAAGC,MACJ,IACC,MAAMC,SAAWJ,OAAS,KAAO,mBAAqB,WACtD,MAAMK,UACJL,OAAS,KACL,gFACA,sEAEN,OACE,oBAACM,OAAIJ,UAAU,qBACb,oBAACP,OAAOY,IAAI,EACVL,UAAWL,GACT,2OACAK,UACAE,UAEFL,GAAIA,GACH,GAAGI,KAAK,EAET,oBAACR,OAAOa,KAAK,EACXN,UAAWL,GACT,CAAC,sIAAsI,CAAC,CACxIQ,cAILJ,MACC,oBAACA,SAAMC,UAAU,OAAOO,QAASV,IAC9BE,OAED,KAGV,CAEA,gBAAeH,MAAO"}
|
package/core/scripts.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"array-flat-polyfill";export{default as reactRenderer,renderComponent}from"./react-renderer";export{default as loadSprites}from"./load-sprites";export*from"./
|
|
1
|
+
import"array-flat-polyfill";export{default as reactRenderer,renderComponent}from"./react-renderer";export{default as loadSprites}from"./load-sprites";export*from"./SessionData";export*from"./dom-query";
|
|
2
2
|
//# sourceMappingURL=scripts.js.map
|
package/core/scripts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/scripts.js"],"sourcesContent":["import \"array-flat-polyfill\";\n\nexport { default as reactRenderer, renderComponent } from \"./react-renderer\";\nexport { default as loadSprites } from \"./load-sprites\";\n\nexport * from \"./
|
|
1
|
+
{"version":3,"sources":["../../src/core/scripts.js"],"sourcesContent":["import \"array-flat-polyfill\";\n\nexport { default as reactRenderer, renderComponent } from \"./react-renderer\";\nexport { default as loadSprites } from \"./load-sprites\";\n\nexport * from \"./SessionData\";\nexport * from \"./dom-query\";\n"],"names":["default","reactRenderer","renderComponent","loadSprites"],"mappings":"AAAA,MAAO,qBAAsB,AAE7B,QAASA,WAAWC,aAAa,CAAEC,eAAe,KAAQ,kBAAmB,AAC7E,QAASF,WAAWG,WAAW,KAAQ,gBAAiB,AAExD,YAAc,eAAgB,AAC9B,YAAc,aAAc"}
|
package/core/styles/buttons.css
CHANGED
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
.ui-button-disabled-base {
|
|
23
|
-
@apply disabled:cursor-not-allowed disabled:bg-gui-
|
|
23
|
+
@apply disabled:cursor-not-allowed disabled:bg-gui-disabled-light disabled:text-gui-disabled-dark disabled:hover:bg-gui-disabled-light;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
.ui-button-disabled-base-dark {
|
|
27
|
-
@apply disabled:cursor-not-allowed disabled:bg-gui-
|
|
27
|
+
@apply disabled:cursor-not-allowed disabled:bg-gui-disabled-dark disabled:text-gui-disabled-light disabled:hover:bg-gui-disabled-dark;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
.ui-button-priority-base {
|
|
@@ -44,11 +44,11 @@
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
.ui-button-secondary-base {
|
|
47
|
-
@apply text-neutral-1300 active:text-neutral-1000 border border-neutral-400 hover:border-neutral-600 active:border-neutral-500 disabled:border-gui-
|
|
47
|
+
@apply text-neutral-1300 active:text-neutral-1000 border border-neutral-400 hover:border-neutral-600 active:border-neutral-500 disabled:border-gui-disabled-light disabled:text-gui-disabled-light;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
.ui-theme-dark .ui-button-secondary-base {
|
|
51
|
-
@apply text-neutral-000 active:text-neutral-300 border-neutral-900 hover:border-neutral-700 active:border-neutral-800 disabled:border-gui-
|
|
51
|
+
@apply text-neutral-000 active:text-neutral-300 border-neutral-900 hover:border-neutral-700 active:border-neutral-800 disabled:border-gui-disabled-dark disabled:text-gui-disabled-dark;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
.ui-button-priority-lg {
|
|
@@ -124,10 +124,10 @@
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
.ui-button-disabled {
|
|
127
|
-
@apply select-none pointer-events-none bg-gui-
|
|
127
|
+
@apply select-none pointer-events-none bg-gui-disabled-light text-gui-disabled-dark hover:bg-gui-disabled-light;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
.ui-theme-dark .ui-button-disabled {
|
|
131
|
-
@apply select-none pointer-events-none bg-gui-
|
|
131
|
+
@apply select-none pointer-events-none bg-gui-disabled-dark text-gui-disabled-light hover:bg-gui-disabled-dark;
|
|
132
132
|
}
|
|
133
133
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const variants=["","dark:"];export const prefixes=["text","bg","from","to","border"];export const colors=["neutral","orange","blue","yellow","green","violet","pink"];export const neutralColors=["neutral-000","neutral-100","neutral-200","neutral-300","neutral-400","neutral-500","neutral-600","neutral-700","neutral-800","neutral-900","neutral-1000","neutral-1100","neutral-1200","neutral-1300"];export const orangeColors=["orange-100","orange-200","orange-300","orange-400","orange-500","orange-600","orange-700","orange-800","orange-900","orange-1000","orange-1100"];export const yellowColors=["yellow-100","yellow-200","yellow-300","yellow-400","yellow-500","yellow-600","yellow-700","yellow-800","yellow-900"];export const greenColors=["green-100","green-200","green-300","green-400","green-500","green-600","green-700","green-800","green-900"];export const blueColors=["blue-100","blue-200","blue-300","blue-400","blue-500","blue-600","blue-700","blue-800","blue-900"];export const violetColors=["violet-100","violet-200","violet-300","violet-400","violet-500","violet-600","violet-700","violet-800","violet-900"];export const pinkColors=["pink-100","pink-200","pink-300","pink-400","pink-500","pink-600","pink-700","pink-800","pink-900"];export const secondaryColors=[...yellowColors,...greenColors,...blueColors,...violetColors,...pinkColors];export const guiColors=["gui-blue-default-light","gui-blue-hover-light","gui-blue-active-light","gui-blue-default-dark","gui-blue-hover-dark","gui-blue-active-dark","gui-blue-focus","gui-
|
|
1
|
+
export const variants=["","dark:"];export const prefixes=["text","bg","from","to","border"];export const colors=["neutral","orange","blue","yellow","green","violet","pink"];export const neutralColors=["neutral-000","neutral-100","neutral-200","neutral-300","neutral-400","neutral-500","neutral-600","neutral-700","neutral-800","neutral-900","neutral-1000","neutral-1100","neutral-1200","neutral-1300"];export const orangeColors=["orange-100","orange-200","orange-300","orange-400","orange-500","orange-600","orange-700","orange-800","orange-900","orange-1000","orange-1100"];export const yellowColors=["yellow-100","yellow-200","yellow-300","yellow-400","yellow-500","yellow-600","yellow-700","yellow-800","yellow-900"];export const greenColors=["green-100","green-200","green-300","green-400","green-500","green-600","green-700","green-800","green-900"];export const blueColors=["blue-100","blue-200","blue-300","blue-400","blue-500","blue-600","blue-700","blue-800","blue-900"];export const violetColors=["violet-100","violet-200","violet-300","violet-400","violet-500","violet-600","violet-700","violet-800","violet-900"];export const pinkColors=["pink-100","pink-200","pink-300","pink-400","pink-500","pink-600","pink-700","pink-800","pink-900"];export const secondaryColors=[...yellowColors,...greenColors,...blueColors,...violetColors,...pinkColors];export const guiColors=["gui-blue-default-light","gui-blue-hover-light","gui-blue-active-light","gui-blue-default-dark","gui-blue-hover-dark","gui-blue-active-dark","gui-blue-focus","gui-disabled-light","gui-disabled-dark","gui-success-green","gui-error-red","gui-focus","gui-focus-outline","gui-visited"];export const aliasedColors=["white","extra-light-grey","light-grey","mid-grey","dark-grey","charcoal-grey","cool-black","active-orange","bright-red","red-orange","electric-cyan","zingy-green","jazzy-pink","gui-default","gui-hover","gui-active","gui-error","gui-success","gui-default-dark","gui-hover-dark","gui-active-dark","transparent"];export const colorRoles={neutral:neutralColors,orange:orangeColors,secondary:secondaryColors,gui:guiColors};export const colorGroupLengths={neutral:neutralColors.length,orange:orangeColors.length,blue:blueColors.length,yellow:yellowColors.length,green:greenColors.length,violet:violetColors.length,pink:pinkColors.length};
|
|
2
2
|
//# sourceMappingURL=types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/core/styles/colors/types.ts"],"sourcesContent":["export type ColorName =\n | (typeof neutralColors)[number]\n | (typeof orangeColors)[number]\n | (typeof secondaryColors)[number]\n | (typeof guiColors)[number]\n | (typeof aliasedColors)[number];\n\nexport const variants = [\"\", \"dark:\"] as const;\n\ntype ColorClassVariants = (typeof variants)[number];\n\nexport const prefixes = [\"text\", \"bg\", \"from\", \"to\", \"border\"] as const;\n\ntype ColorClassPrefixes = (typeof prefixes)[number];\n\nexport const colors = [\n \"neutral\",\n \"orange\",\n \"blue\",\n \"yellow\",\n \"green\",\n \"violet\",\n \"pink\",\n] as const;\n\nexport type ColorClassColorGroups = (typeof colors)[number];\n\nexport type Theme = \"light\" | \"dark\";\n\nexport type ColorClass =\n `${ColorClassVariants}${ColorClassPrefixes}-${ColorName}`;\n\nexport type ColorThemeSet = `${string} dark:${string}`;\n\nexport const neutralColors = [\n \"neutral-000\",\n \"neutral-100\",\n \"neutral-200\",\n \"neutral-300\",\n \"neutral-400\",\n \"neutral-500\",\n \"neutral-600\",\n \"neutral-700\",\n \"neutral-800\",\n \"neutral-900\",\n \"neutral-1000\",\n \"neutral-1100\",\n \"neutral-1200\",\n \"neutral-1300\",\n] as const;\n\nexport const orangeColors = [\n \"orange-100\",\n \"orange-200\",\n \"orange-300\",\n \"orange-400\",\n \"orange-500\",\n \"orange-600\",\n \"orange-700\",\n \"orange-800\",\n \"orange-900\",\n \"orange-1000\",\n \"orange-1100\",\n] as const;\n\nexport const yellowColors = [\n \"yellow-100\",\n \"yellow-200\",\n \"yellow-300\",\n \"yellow-400\",\n \"yellow-500\",\n \"yellow-600\",\n \"yellow-700\",\n \"yellow-800\",\n \"yellow-900\",\n] as const;\n\nexport const greenColors = [\n \"green-100\",\n \"green-200\",\n \"green-300\",\n \"green-400\",\n \"green-500\",\n \"green-600\",\n \"green-700\",\n \"green-800\",\n \"green-900\",\n] as const;\n\nexport const blueColors = [\n \"blue-100\",\n \"blue-200\",\n \"blue-300\",\n \"blue-400\",\n \"blue-500\",\n \"blue-600\",\n \"blue-700\",\n \"blue-800\",\n \"blue-900\",\n] as const;\n\nexport const violetColors = [\n \"violet-100\",\n \"violet-200\",\n \"violet-300\",\n \"violet-400\",\n \"violet-500\",\n \"violet-600\",\n \"violet-700\",\n \"violet-800\",\n \"violet-900\",\n] as const;\n\nexport const pinkColors = [\n \"pink-100\",\n \"pink-200\",\n \"pink-300\",\n \"pink-400\",\n \"pink-500\",\n \"pink-600\",\n \"pink-700\",\n \"pink-800\",\n \"pink-900\",\n] as const;\n\nexport const secondaryColors = [\n ...yellowColors,\n ...greenColors,\n ...blueColors,\n ...violetColors,\n ...pinkColors,\n] as const;\n\nexport const guiColors = [\n \"gui-blue-default-light\",\n \"gui-blue-hover-light\",\n \"gui-blue-active-light\",\n \"gui-blue-default-dark\",\n \"gui-blue-hover-dark\",\n \"gui-blue-active-dark\",\n \"gui-blue-focus\",\n \"gui-
|
|
1
|
+
{"version":3,"sources":["../../../../src/core/styles/colors/types.ts"],"sourcesContent":["export type ColorName =\n | (typeof neutralColors)[number]\n | (typeof orangeColors)[number]\n | (typeof secondaryColors)[number]\n | (typeof guiColors)[number]\n | (typeof aliasedColors)[number];\n\nexport const variants = [\"\", \"dark:\"] as const;\n\ntype ColorClassVariants = (typeof variants)[number];\n\nexport const prefixes = [\"text\", \"bg\", \"from\", \"to\", \"border\"] as const;\n\ntype ColorClassPrefixes = (typeof prefixes)[number];\n\nexport const colors = [\n \"neutral\",\n \"orange\",\n \"blue\",\n \"yellow\",\n \"green\",\n \"violet\",\n \"pink\",\n] as const;\n\nexport type ColorClassColorGroups = (typeof colors)[number];\n\nexport type Theme = \"light\" | \"dark\";\n\nexport type ColorClass =\n `${ColorClassVariants}${ColorClassPrefixes}-${ColorName}`;\n\nexport type ColorThemeSet = `${string} dark:${string}`;\n\nexport const neutralColors = [\n \"neutral-000\",\n \"neutral-100\",\n \"neutral-200\",\n \"neutral-300\",\n \"neutral-400\",\n \"neutral-500\",\n \"neutral-600\",\n \"neutral-700\",\n \"neutral-800\",\n \"neutral-900\",\n \"neutral-1000\",\n \"neutral-1100\",\n \"neutral-1200\",\n \"neutral-1300\",\n] as const;\n\nexport const orangeColors = [\n \"orange-100\",\n \"orange-200\",\n \"orange-300\",\n \"orange-400\",\n \"orange-500\",\n \"orange-600\",\n \"orange-700\",\n \"orange-800\",\n \"orange-900\",\n \"orange-1000\",\n \"orange-1100\",\n] as const;\n\nexport const yellowColors = [\n \"yellow-100\",\n \"yellow-200\",\n \"yellow-300\",\n \"yellow-400\",\n \"yellow-500\",\n \"yellow-600\",\n \"yellow-700\",\n \"yellow-800\",\n \"yellow-900\",\n] as const;\n\nexport const greenColors = [\n \"green-100\",\n \"green-200\",\n \"green-300\",\n \"green-400\",\n \"green-500\",\n \"green-600\",\n \"green-700\",\n \"green-800\",\n \"green-900\",\n] as const;\n\nexport const blueColors = [\n \"blue-100\",\n \"blue-200\",\n \"blue-300\",\n \"blue-400\",\n \"blue-500\",\n \"blue-600\",\n \"blue-700\",\n \"blue-800\",\n \"blue-900\",\n] as const;\n\nexport const violetColors = [\n \"violet-100\",\n \"violet-200\",\n \"violet-300\",\n \"violet-400\",\n \"violet-500\",\n \"violet-600\",\n \"violet-700\",\n \"violet-800\",\n \"violet-900\",\n] as const;\n\nexport const pinkColors = [\n \"pink-100\",\n \"pink-200\",\n \"pink-300\",\n \"pink-400\",\n \"pink-500\",\n \"pink-600\",\n \"pink-700\",\n \"pink-800\",\n \"pink-900\",\n] as const;\n\nexport const secondaryColors = [\n ...yellowColors,\n ...greenColors,\n ...blueColors,\n ...violetColors,\n ...pinkColors,\n] as const;\n\nexport const guiColors = [\n \"gui-blue-default-light\",\n \"gui-blue-hover-light\",\n \"gui-blue-active-light\",\n \"gui-blue-default-dark\",\n \"gui-blue-hover-dark\",\n \"gui-blue-active-dark\",\n \"gui-blue-focus\",\n \"gui-disabled-light\",\n \"gui-disabled-dark\",\n \"gui-success-green\",\n \"gui-error-red\",\n \"gui-focus\",\n \"gui-focus-outline\",\n \"gui-visited\",\n] as const;\n\nexport const aliasedColors = [\n \"white\",\n \"extra-light-grey\",\n \"light-grey\",\n \"mid-grey\",\n \"dark-grey\",\n \"charcoal-grey\",\n \"cool-black\",\n \"active-orange\",\n \"bright-red\",\n \"red-orange\",\n \"electric-cyan\",\n \"zingy-green\",\n \"jazzy-pink\",\n \"gui-default\",\n \"gui-hover\",\n \"gui-active\",\n \"gui-error\",\n \"gui-success\",\n \"gui-default-dark\",\n \"gui-hover-dark\",\n \"gui-active-dark\",\n \"transparent\",\n] as const;\n\nexport const colorRoles = {\n neutral: neutralColors,\n orange: orangeColors,\n secondary: secondaryColors,\n gui: guiColors,\n};\n\nexport const colorGroupLengths = {\n neutral: neutralColors.length,\n orange: orangeColors.length,\n blue: blueColors.length,\n yellow: yellowColors.length,\n green: greenColors.length,\n violet: violetColors.length,\n pink: pinkColors.length,\n};\n"],"names":["variants","prefixes","colors","neutralColors","orangeColors","yellowColors","greenColors","blueColors","violetColors","pinkColors","secondaryColors","guiColors","aliasedColors","colorRoles","neutral","orange","secondary","gui","colorGroupLengths","length","blue","yellow","green","violet","pink"],"mappings":"AAOA,OAAO,MAAMA,SAAW,CAAC,GAAI,QAAQ,AAAU,AAI/C,QAAO,MAAMC,SAAW,CAAC,OAAQ,KAAM,OAAQ,KAAM,SAAS,AAAU,AAIxE,QAAO,MAAMC,OAAS,CACpB,UACA,SACA,OACA,SACA,QACA,SACA,OACD,AAAU,AAWX,QAAO,MAAMC,cAAgB,CAC3B,cACA,cACA,cACA,cACA,cACA,cACA,cACA,cACA,cACA,cACA,eACA,eACA,eACA,eACD,AAAU,AAEX,QAAO,MAAMC,aAAe,CAC1B,aACA,aACA,aACA,aACA,aACA,aACA,aACA,aACA,aACA,cACA,cACD,AAAU,AAEX,QAAO,MAAMC,aAAe,CAC1B,aACA,aACA,aACA,aACA,aACA,aACA,aACA,aACA,aACD,AAAU,AAEX,QAAO,MAAMC,YAAc,CACzB,YACA,YACA,YACA,YACA,YACA,YACA,YACA,YACA,YACD,AAAU,AAEX,QAAO,MAAMC,WAAa,CACxB,WACA,WACA,WACA,WACA,WACA,WACA,WACA,WACA,WACD,AAAU,AAEX,QAAO,MAAMC,aAAe,CAC1B,aACA,aACA,aACA,aACA,aACA,aACA,aACA,aACA,aACD,AAAU,AAEX,QAAO,MAAMC,WAAa,CACxB,WACA,WACA,WACA,WACA,WACA,WACA,WACA,WACA,WACD,AAAU,AAEX,QAAO,MAAMC,gBAAkB,IAC1BL,gBACAC,eACAC,cACAC,gBACAC,WACJ,AAAU,AAEX,QAAO,MAAME,UAAY,CACvB,yBACA,uBACA,wBACA,wBACA,sBACA,uBACA,iBACA,qBACA,oBACA,oBACA,gBACA,YACA,oBACA,cACD,AAAU,AAEX,QAAO,MAAMC,cAAgB,CAC3B,QACA,mBACA,aACA,WACA,YACA,gBACA,aACA,gBACA,aACA,aACA,gBACA,cACA,aACA,cACA,YACA,aACA,YACA,cACA,mBACA,iBACA,kBACA,cACD,AAAU,AAEX,QAAO,MAAMC,WAAa,CACxBC,QAASX,cACTY,OAAQX,aACRY,UAAWN,gBACXO,IAAKN,SACP,CAAE,AAEF,QAAO,MAAMO,kBAAoB,CAC/BJ,QAASX,cAAcgB,MAAM,CAC7BJ,OAAQX,aAAae,MAAM,CAC3BC,KAAMb,WAAWY,MAAM,CACvBE,OAAQhB,aAAac,MAAM,CAC3BG,MAAOhB,YAAYa,MAAM,CACzBI,OAAQf,aAAaW,MAAM,CAC3BK,KAAMf,WAAWU,MAAM,AACzB,CAAE"}
|