@alto-avios/alto-ui 5.4.0 → 5.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/Accordion.css +1 -1
- package/dist/assets/Popover.css +1 -1
- package/dist/components/Accordion/Accordion.d.ts +16 -4
- package/dist/components/Accordion/Accordion.js +12 -12
- package/dist/components/Accordion/Accordion.js.map +1 -1
- package/dist/components/Popover/Popover.js +3 -3
- package/dist/components/Popover/Popover.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
.
|
|
1
|
+
._accordion_15993_1{--accordion-transition-duration:.2s;--accordion-transition-timing:cubic-bezier(.4,0,.2,1);align-items:center;align-self:stretch;background-color:var(--alto-sem-color-bg-white-vibrant-default);border:1px solid var(--alto-sem-color-border-secondary);border-radius:var(--alto-card-radius);box-sizing:border-box;display:flex;flex-direction:column;padding:0;width:100%}._accordion-group_15993_16,._accordion-group__stack_15993_22{display:flex;flex-direction:column;gap:var(--alto-sem-space-2xs)}._accordion-group__header_15993_28{display:flex;flex-direction:column;gap:var(--alto-sem-space-4xs);padding-bottom:var(--alto-sem-space-2xs)}._accordion__trigger_15993_35{background-color:var(--alto-sem-color-bg-white-vibrant-default);border:none;border-radius:var(--alto-card-radius);cursor:pointer;padding:var(--alto-sem-space-md) var(--alto-sem-space-sm);width:100%}._accordion__button-content_15993_44{align-items:center;display:flex;gap:var(--alto-sem-space-sm);justify-content:space-between;width:100%}._accordion__title-container_15993_52{align-items:center;display:flex;flex:1;gap:var(--alto-sem-space-2xs)}._accordion__title-wrapper_15993_59{display:flex;flex-direction:column}._accordion__end-container_15993_64{align-items:center;display:flex;gap:var(--alto-sem-space-sm)}._accordion__end-slot_15993_71,._accordion__start-slot_15993_70{align-items:center;display:flex}._accordion__title_15993_52{color:var(--alto-sem-color-fg-accent-secondary);flex:1;font-size:var(--alto-sem-text-body-lg-font-size);font-style:normal;font-weight:var(--alto-sem-text-body-bold-font-weight);letter-spacing:var(--alto-sem-text-body-lg-letter-spacing);line-height:var(--alto-sem-text-body-lg-line-height);word-break:break-word}._accordion__description_15993_90,._accordion__title_15993_52{font-family:var(--alto-sem-text-body-font-family);margin:0;text-align:left}._accordion__description_15993_90{color:var(--alto-sem-color-fg-secondary);font-size:var(--alto-sem-text-body-md-font-size);letter-spacing:var(--alto-sem-text-body-md-letter-spacing);line-height:var(--alto-sem-text-body-md-line-height)}._accordion__icon-wrapper_15993_100{align-items:center;color:var(--alto-sem-color-fg-secondary);display:flex;justify-content:center;transition:transform .25s cubic-bezier(.4,0,.2,1)}._accordion_15993_1[data-expanded=true] ._accordion__icon-wrapper_15993_100{transform:rotate(180deg)}._accordion_15993_1>[role=group]{height:0;overflow:hidden;visibility:hidden;width:100%}._accordion_15993_1>[role=group],._accordion_15993_1[data-expanded=true]>[role=group]{transition:height var(--accordion-transition-duration) var(--accordion-transition-timing),visibility 0s linear}._accordion_15993_1[data-expanded=true]>[role=group]{height:var(--group-height);visibility:visible}._accordion__panel-content_15993_132{padding:var(--alto-sem-space-xs) var(--alto-sem-space-sm) var(--alto-sem-space-2xl)}._accordion_15993_1[data-expanded=true],._accordion_15993_1[data-expanded=true] ._accordion__trigger_15993_35{background-color:var(--alto-sem-color-bg-layer1-default)}._accordion_15993_1 ._accordion__trigger_15993_35[data-hovered]{background-color:var(--alto-sem-color-overlay-state-darken-invert-hover)}._accordion_15993_1 ._accordion__trigger_15993_35[data-focus-visible]{box-shadow:0 0 0 2px var(--alto-sem-color-border-accent);outline:none}._accordion_15993_1 ._accordion__trigger_15993_35[data-pressed]{background-color:var(--alto-sem-color-overlay-state-darken-invert-active);outline:none}._accordion_15993_1[data-expanded=true] ._accordion__trigger_15993_35[data-hovered]{background-color:var(--alto-sem-color-overlay-state-darken-invert-hover);border-radius:var(--alto-card-radius) var(--alto-card-radius) 0 0}._accordion_15993_1 ._accordion__trigger_15993_35[data-focused]{outline:none}._accordion_15993_1 ._accordion__trigger_15993_35[data-disabled]{background-color:var(--alto-sem-color-bg-disabled-subtle);color:var(--alto-sem-color-fg-disabled-on-subtle);cursor:not-allowed}._accordion_15993_1 ._accordion__trigger_15993_35[data-disabled] svg,._accordion__trigger_15993_35[data-disabled] ._accordion__description_15993_90,._accordion__trigger_15993_35[data-disabled] ._accordion__title_15993_52{color:var(--alto-sem-color-fg-disabled-on-subtle)}._accordion_15993_1[data-disabled]{background-color:var(--alto-sem-color-bg-disabled-subtle);border-color:var(--alto-sem-color-border-disabled-subtle)}
|
package/dist/assets/Popover.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.
|
|
1
|
+
._popover_1de57_1{background:var(--alto-sem-color-bg-layer2-default);border:1px solid var(--alto-sem-color-border-tertiary);border-radius:var(--alto-card-radius,12px);box-shadow:0 4px 6px -1px var(--alto-sem-color-overlay-state-darken-active),0 2px 4px -2px var(--alto-sem-color-overlay-state-darken-active);position:relative}._arrow_1de57_11{background:url('data:image/svg+xml;utf8,<svg width="17" height="18" viewBox="0 0 17 18" fill="none" xmlns="http://www.w3.org/2000/svg"><mask id="path-1-inside-1_15337_1997" fill="white"><path d="M17 9.29999L8.51472 17.7853L0.0294347 9.29999L8.51472 0.814707L17 9.29999Z"/></mask><path d="M17 9.29999L8.51472 17.7853L0.0294347 9.29999L8.51472 0.814707L17 9.29999Z" fill="%23FEFEFE"/><path d="M8.51472 0.814707L9.22182 0.107601L8.51472 -0.599506L7.80761 0.107601L8.51472 0.814707ZM0.736542 10.0071L9.22182 1.52181L7.80761 0.107601L-0.677672 8.59288L0.736542 10.0071ZM7.80761 1.52181L16.2929 10.0071L17.7071 8.59288L9.22182 0.107601L7.80761 1.52181Z" fill="%239593A0" fill-opacity="0.25" mask="url(%23path-1-inside-1_15337_1997)"/></svg>') 50% no-repeat;height:16px;position:absolute;width:16px}._arrow_1de57_11[data-placement=top]{bottom:-9px;left:50%;margin-left:-8.5px;transform:rotate(180deg)}._arrow_1de57_11[data-placement=bottom]{left:50%;margin-left:-8.5px;top:-9px}._arrow_1de57_11[data-placement=left]{margin-top:-9px;right:-9px;top:50%;transform:rotate(90deg)}._arrow_1de57_11[data-placement=right]{left:-9px;margin-top:-9px;top:50%;transform:rotate(-90deg)}
|
|
@@ -34,12 +34,24 @@ export interface AccordionProps extends Omit<AriaDisclosureProps, 'children'> {
|
|
|
34
34
|
interface SlotProps {
|
|
35
35
|
children: React.ReactNode;
|
|
36
36
|
}
|
|
37
|
-
export declare const StartSlot:
|
|
38
|
-
|
|
37
|
+
export declare const StartSlot: {
|
|
38
|
+
({ children }: SlotProps): import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
displayName: string;
|
|
40
|
+
};
|
|
41
|
+
export declare const EndSlot: {
|
|
42
|
+
({ children }: SlotProps): import("react/jsx-runtime").JSX.Element;
|
|
43
|
+
displayName: string;
|
|
44
|
+
};
|
|
39
45
|
export declare const Accordion: {
|
|
40
46
|
({ title, description, children, defaultExpanded, className, titleStart, titleEnd, id, headingLevel, ...props }: AccordionProps): import("react/jsx-runtime").JSX.Element;
|
|
41
|
-
StartSlot:
|
|
42
|
-
|
|
47
|
+
StartSlot: {
|
|
48
|
+
({ children }: SlotProps): import("react/jsx-runtime").JSX.Element;
|
|
49
|
+
displayName: string;
|
|
50
|
+
};
|
|
51
|
+
EndSlot: {
|
|
52
|
+
({ children }: SlotProps): import("react/jsx-runtime").JSX.Element;
|
|
53
|
+
displayName: string;
|
|
54
|
+
};
|
|
43
55
|
};
|
|
44
56
|
export interface AccordionGroupProps {
|
|
45
57
|
/** Title for the accordion group - can be string or ReactNode */
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import{
|
|
2
|
-
return
|
|
3
|
-
/* @__PURE__ */
|
|
4
|
-
/* @__PURE__ */
|
|
5
|
-
/* @__PURE__ */
|
|
6
|
-
/* @__PURE__ */
|
|
7
|
-
/* @__PURE__ */
|
|
8
|
-
return
|
|
9
|
-
/* @__PURE__ */
|
|
10
|
-
/* @__PURE__ */
|
|
11
|
-
return
|
|
12
|
-
/* @__PURE__ */
|
|
1
|
+
import{jsx as o,Fragment as e,jsxs as n}from"react/jsx-runtime";import r from"react";import{Disclosure as c,DisclosureGroup as i,Button as t,DisclosurePanel as a}from"react-aria-components";import{Icon as d}from"../Icon/Icon.js";import '../../assets/Accordion.css';const l={accordion:"_accordion_15993_1","accordion-group":"_accordion-group_15993_16","accordion-group__stack":"_accordion-group__stack_15993_22","accordion-group__header":"_accordion-group__header_15993_28",accordion__trigger:"_accordion__trigger_15993_35","accordion__button-content":"_accordion__button-content_15993_44","accordion__title-container":"_accordion__title-container_15993_52","accordion__title-wrapper":"_accordion__title-wrapper_15993_59","accordion__end-container":"_accordion__end-container_15993_64","accordion__start-slot":"_accordion__start-slot_15993_70","accordion__end-slot":"_accordion__end-slot_15993_71",accordion__title:"_accordion__title_15993_52",accordion__description:"_accordion__description_15993_90","accordion__icon-wrapper":"_accordion__icon-wrapper_15993_100","accordion__panel-content":"_accordion__panel-content_15993_132"},_=({title:e,description:r,startSlot:c,endSlot:i,id:a,headingLevel:_="h3"})=>{const s=_;/* @__PURE__ */
|
|
2
|
+
return o(t,{slot:"trigger",className:l.accordion__trigger,...a?{id:a}:{},children:/* @__PURE__ */n("span",{className:l["accordion__button-content"],children:[
|
|
3
|
+
/* @__PURE__ */n("span",{className:l["accordion__title-container"],children:[c&&/* @__PURE__ */o("span",{className:l["accordion__start-slot"],children:c}),
|
|
4
|
+
/* @__PURE__ */n("div",{className:l["accordion__title-wrapper"],children:[
|
|
5
|
+
/* @__PURE__ */o(s,{className:l.accordion__title,children:e}),r&&/* @__PURE__ */o("p",{className:l.accordion__description,children:r})]})]}),
|
|
6
|
+
/* @__PURE__ */n("span",{className:l["accordion__end-container"],children:[i&&/* @__PURE__ */o("span",{className:l["accordion__end-slot"],children:i}),
|
|
7
|
+
/* @__PURE__ */o(d,{iconName:"chevron-down",iconPrefix:"fas",className:l["accordion__icon-wrapper"],color:"accentSecondary"})]})]})})},s=({children:e,...n})=>{const c=r.useRef(null);return r.useEffect(()=>{const o=c.current;if(!o)return;const e=o.closest('[role="group"]');if(!e)return;requestAnimationFrame(()=>{const n=o.scrollHeight;e.style.setProperty("--group-height",`${n}px`)});const n=()=>{const n=o.scrollHeight;e.style.setProperty("--group-height",`${n}px`)};n();const r=new ResizeObserver(()=>{n()});return r.observe(o),r.observe(e),window.addEventListener("resize",n),()=>{r.disconnect(),window.removeEventListener("resize",n)}},[]),/* @__PURE__ */o(a,{...n,children:/* @__PURE__ */o("div",{ref:c,className:l["accordion__panel-content"],children:e})})},p=({children:n})=>/* @__PURE__ */o(e,{children:n}),h=({children:n})=>/* @__PURE__ */o(e,{children:n}),u=({title:e,description:i,children:t,defaultExpanded:a=!1,className:d,titleStart:u,titleEnd:m,id:g,headingLevel:f="h3",...N})=>{const E=[l.accordion,d].filter(Boolean).join(" ");let v=u,w=m;const y=r.Children.map(t,o=>{const e=o;return e.type===p?(v=e.props.children,null):e.type===h?(w=e.props.children,null):e})?.filter(Boolean);/* @__PURE__ */
|
|
8
|
+
return n(c,{className:E,defaultExpanded:a,id:g,...N,children:[
|
|
9
|
+
/* @__PURE__ */o(_,{title:e,description:i,startSlot:v,endSlot:w,id:g,headingLevel:f}),
|
|
10
|
+
/* @__PURE__ */o(s,{children:y})]})},m=({title:e,description:c,children:t,className:a,allowsMultipleExpanded:d=!0})=>{const _=[l["accordion-group"],a].filter(Boolean).join(" "),s=r.Children.toArray(t).map((o,e)=>r.isValidElement(o)&&"object"==typeof o.props&&null!==o.props&&"defaultExpanded"in o.props&&o.props.defaultExpanded?"id"in o.props&&"string"==typeof o.props.id?o.props.id:`accordion-${e}`:null).filter(o=>null!==o);/* @__PURE__ */
|
|
11
|
+
return n("div",{className:_,children:[(e||c)&&/* @__PURE__ */n("div",{className:l["accordion-group__header"],children:[e,c]}),
|
|
12
|
+
/* @__PURE__ */o(i,{className:l["accordion-group__stack"],allowsMultipleExpanded:d,defaultExpandedKeys:s,children:r.Children.map(t,(o,e)=>r.isValidElement(o)?r.cloneElement(o,{key:`accordion-${e}`,id:o.props?.id||`accordion-${e}`}):o)})]})};u.StartSlot=p,u.EndSlot=h,p.displayName="Accordion.StartSlot",h.displayName="Accordion.EndSlot";export{u as Accordion,m as AccordionGroup,h as EndSlot,p as StartSlot,u as default};
|
|
13
13
|
//# sourceMappingURL=Accordion.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Accordion.js","sources":["../../../src/components/Accordion/Accordion.tsx"],"sourcesContent":["import React, { ReactElement } from 'react';\nimport {\n Disclosure as AriaDisclosure,\n type DisclosureProps as AriaDisclosureProps,\n Button as AriaButton,\n DisclosurePanel as AriaDisclosurePanel,\n DisclosureGroup as AriaDisclosureGroup,\n} from 'react-aria-components';\nimport { Icon } from '../Icon/Icon';\nimport styles from './Accordion.module.css';\n\ntype HeadingLevel = 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n\nexport interface AccordionProps extends Omit<AriaDisclosureProps, 'children'> {\n /** The title text displayed in the accordion header */\n title: string;\n\n /** Optional description text displayed below the title */\n description?: string;\n\n /** Content rendered inside the accordion when expanded */\n children: React.ReactNode;\n\n /** Controls if accordion is expanded on initial render */\n defaultExpanded?: boolean;\n\n /** Additional CSS class for custom styling */\n className?: string;\n\n /**\n * Content (typically an icon) rendered before the heading.\n * **Deprecated. Use `Accordion.StartSlot` instead**\n * @deprecated\n */\n titleStart?: React.ReactNode;\n\n /**\n * Content (typically an icon) rendered after the heading.\n * **Deprecated. Use `Accordion.EndSlot` instead**\n * @deprecated\n */\n titleEnd?: React.ReactNode;\n\n /** Unique identifier for the accordion */\n id?: string;\n\n /** The semantic heading level for the accordion title */\n headingLevel?: HeadingLevel;\n\n /** Whether the accordion is disabled and cannot be interacted with */\n isDisabled?: boolean;\n}\n\ninterface AccordionTriggerProps\n extends Pick<\n AccordionProps,\n 'title' | 'description' | 'id' | 'headingLevel'\n > {\n startSlot?: React.ReactNode;\n endSlot?: React.ReactNode;\n}\n\nconst AccordionTrigger = ({\n title,\n description,\n startSlot,\n endSlot,\n id,\n headingLevel = 'h3',\n}: AccordionTriggerProps) => {\n const HeadingElement = headingLevel;\n\n return (\n <AriaButton\n slot=\"trigger\"\n className={styles.accordion__trigger}\n {...(id ? { id } : {})}\n >\n <span className={styles['accordion__button-content']}>\n <span className={styles['accordion__title-container']}>\n {startSlot && (\n <span className={styles['accordion__start-slot']}>{startSlot}</span>\n )}\n <div className={styles['accordion__title-wrapper']}>\n <HeadingElement className={styles.accordion__title}>\n {title}\n </HeadingElement>\n {description && (\n <p className={styles.accordion__description}>{description}</p>\n )}\n </div>\n </span>\n <span className={styles['accordion__end-container']}>\n {endSlot && (\n <span className={styles['accordion__end-slot']}>{endSlot}</span>\n )}\n <Icon\n iconName=\"chevron-down\"\n iconPrefix=\"fas\"\n className={styles['accordion__icon-wrapper']}\n color=\"accentSecondary\"\n />\n </span>\n </span>\n </AriaButton>\n );\n};\n\nconst AccordionPanel = ({\n children,\n ...props\n}: React.ComponentProps<typeof AriaDisclosurePanel>) => {\n const contentRef = React.useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n const content = contentRef.current;\n if (!content) return;\n\n // Get the parent group element\n const group = content.closest('[role=\"group\"]') as HTMLElement;\n if (!group) return;\n\n requestAnimationFrame(() => {\n const height = content.scrollHeight;\n group.style.setProperty('--group-height', `${height}px`);\n });\n\n const updateHeight = () => {\n const height = content.scrollHeight;\n group.style.setProperty('--group-height', `${height}px`);\n };\n\n updateHeight();\n\n const resizeObserver = new ResizeObserver(() => {\n updateHeight();\n });\n\n resizeObserver.observe(content);\n resizeObserver.observe(group);\n\n window.addEventListener('resize', updateHeight);\n\n return () => {\n resizeObserver.disconnect();\n window.removeEventListener('resize', updateHeight);\n };\n }, []);\n\n return (\n <AriaDisclosurePanel {...props}>\n <div ref={contentRef} className={styles['accordion__panel-content']}>\n {children}\n </div>\n </AriaDisclosurePanel>\n );\n};\n\ninterface SlotProps {\n children: React.ReactNode;\n}\n\nexport const StartSlot = ({ children }: SlotProps) => <>{children}</>;\nexport const EndSlot = ({ children }: SlotProps) => <>{children}</>;\n\nexport const Accordion = ({\n title,\n description,\n children,\n defaultExpanded = false,\n className,\n titleStart,\n titleEnd,\n id,\n headingLevel = 'h3',\n ...props\n}: AccordionProps) => {\n const accordionClasses = [styles.accordion, className]\n .filter(Boolean)\n .join(' ');\n\n // Pick start and end content out of `children`\n let startSlot = titleStart;\n let endSlot = titleEnd;\n const panelContent = React.Children.map(children, (child) => {\n const childElement = child as ReactElement<SlotProps>;\n\n if (childElement.type === StartSlot) {\n startSlot = childElement.props.children;\n return null;\n }\n\n if (childElement.type === EndSlot) {\n endSlot = childElement.props.children;\n return null;\n }\n\n return childElement;\n })?.filter(Boolean);\n\n return (\n <AriaDisclosure\n className={accordionClasses}\n defaultExpanded={defaultExpanded}\n id={id}\n {...props}\n >\n <AccordionTrigger\n title={title}\n description={description}\n startSlot={startSlot}\n endSlot={endSlot}\n id={id}\n headingLevel={headingLevel}\n />\n <AccordionPanel>{panelContent}</AccordionPanel>\n </AriaDisclosure>\n );\n};\n\nexport interface AccordionGroupProps {\n /** Title for the accordion group - can be string or ReactNode */\n title?: string | React.ReactNode;\n\n /** Description for the accordion group - can be string or ReactNode */\n description?: string | React.ReactNode;\n\n /** Collection of Accordion components */\n children?: React.ReactNode;\n\n /** Additional CSS class for custom styling */\n className?: string;\n\n /** Whether multiple accordions can be expanded at once */\n allowsMultipleExpanded?: boolean;\n}\n\nexport const AccordionGroup = ({\n title,\n description,\n children,\n className,\n allowsMultipleExpanded = true,\n}: AccordionGroupProps) => {\n const groupClasses = [styles['accordion-group'], className]\n .filter(Boolean)\n .join(' ');\n\n // Find any children that have defaultExpanded={true}\n const defaultExpandedKeys = React.Children.toArray(children)\n .map((child, index) => {\n if (\n React.isValidElement(child) &&\n typeof child.props === 'object' &&\n child.props !== null &&\n 'defaultExpanded' in child.props &&\n child.props.defaultExpanded\n ) {\n return `accordion-${index}`;\n }\n return null;\n })\n .filter((key): key is string => key !== null);\n\n return (\n <div className={groupClasses}>\n {(title || description) && (\n <div className={styles['accordion-group__header']}>\n {title}\n {description}\n </div>\n )}\n <AriaDisclosureGroup\n className={styles['accordion-group__stack']}\n allowsMultipleExpanded={allowsMultipleExpanded}\n defaultExpandedKeys={defaultExpandedKeys}\n >\n {React.Children.map(children, (child, index) => {\n if (React.isValidElement<AccordionProps>(child)) {\n return React.cloneElement(child, {\n key: `accordion-${index}`,\n id: child.props?.id || `accordion-${index}`,\n } as Partial<AccordionProps>);\n }\n return child;\n })}\n </AriaDisclosureGroup>\n </div>\n );\n};\n\nAccordion.StartSlot = StartSlot;\nAccordion.EndSlot = EndSlot;\n\nexport default Accordion;\n"],"names":["AccordionTrigger","title","description","startSlot","endSlot","id","headingLevel","HeadingElement","jsx","AriaButton","slot","className","styles","accordion__trigger","children","accordion__title","accordion__description","Icon","iconName","iconPrefix","color","AccordionPanel","props","contentRef","React","useRef","useEffect","content","current","group","closest","requestAnimationFrame","height","scrollHeight","style","setProperty","updateHeight","resizeObserver","ResizeObserver","observe","window","addEventListener","disconnect","removeEventListener","AriaDisclosurePanel","ref","StartSlot","EndSlot","Accordion","defaultExpanded","titleStart","titleEnd","accordionClasses","accordion","filter","Boolean","join","panelContent","Children","map","child","childElement","type","jsxs","AriaDisclosure","AccordionGroup","allowsMultipleExpanded","groupClasses","defaultExpandedKeys","toArray","index","isValidElement","key","AriaDisclosureGroup","cloneElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Accordion.js","sources":["../../../src/components/Accordion/Accordion.tsx"],"sourcesContent":["import React, { ReactElement } from 'react';\nimport {\n Disclosure as AriaDisclosure,\n type DisclosureProps as AriaDisclosureProps,\n Button as AriaButton,\n DisclosurePanel as AriaDisclosurePanel,\n DisclosureGroup as AriaDisclosureGroup,\n} from 'react-aria-components';\nimport { Icon } from '../Icon/Icon';\nimport styles from './Accordion.module.css';\n\ntype HeadingLevel = 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n\nexport interface AccordionProps extends Omit<AriaDisclosureProps, 'children'> {\n /** The title text displayed in the accordion header */\n title: string;\n\n /** Optional description text displayed below the title */\n description?: string;\n\n /** Content rendered inside the accordion when expanded */\n children: React.ReactNode;\n\n /** Controls if accordion is expanded on initial render */\n defaultExpanded?: boolean;\n\n /** Additional CSS class for custom styling */\n className?: string;\n\n /**\n * Content (typically an icon) rendered before the heading.\n * **Deprecated. Use `Accordion.StartSlot` instead**\n * @deprecated\n */\n titleStart?: React.ReactNode;\n\n /**\n * Content (typically an icon) rendered after the heading.\n * **Deprecated. Use `Accordion.EndSlot` instead**\n * @deprecated\n */\n titleEnd?: React.ReactNode;\n\n /** Unique identifier for the accordion */\n id?: string;\n\n /** The semantic heading level for the accordion title */\n headingLevel?: HeadingLevel;\n\n /** Whether the accordion is disabled and cannot be interacted with */\n isDisabled?: boolean;\n}\n\ninterface AccordionTriggerProps\n extends Pick<\n AccordionProps,\n 'title' | 'description' | 'id' | 'headingLevel'\n > {\n startSlot?: React.ReactNode;\n endSlot?: React.ReactNode;\n}\n\nconst AccordionTrigger = ({\n title,\n description,\n startSlot,\n endSlot,\n id,\n headingLevel = 'h3',\n}: AccordionTriggerProps) => {\n const HeadingElement = headingLevel;\n\n return (\n <AriaButton\n slot=\"trigger\"\n className={styles.accordion__trigger}\n {...(id ? { id } : {})}\n >\n <span className={styles['accordion__button-content']}>\n <span className={styles['accordion__title-container']}>\n {startSlot && (\n <span className={styles['accordion__start-slot']}>{startSlot}</span>\n )}\n <div className={styles['accordion__title-wrapper']}>\n <HeadingElement className={styles.accordion__title}>\n {title}\n </HeadingElement>\n {description && (\n <p className={styles.accordion__description}>{description}</p>\n )}\n </div>\n </span>\n <span className={styles['accordion__end-container']}>\n {endSlot && (\n <span className={styles['accordion__end-slot']}>{endSlot}</span>\n )}\n <Icon\n iconName=\"chevron-down\"\n iconPrefix=\"fas\"\n className={styles['accordion__icon-wrapper']}\n color=\"accentSecondary\"\n />\n </span>\n </span>\n </AriaButton>\n );\n};\n\nconst AccordionPanel = ({\n children,\n ...props\n}: React.ComponentProps<typeof AriaDisclosurePanel>) => {\n const contentRef = React.useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n const content = contentRef.current;\n if (!content) return;\n\n // Get the parent group element\n const group = content.closest('[role=\"group\"]') as HTMLElement;\n if (!group) return;\n\n requestAnimationFrame(() => {\n const height = content.scrollHeight;\n group.style.setProperty('--group-height', `${height}px`);\n });\n\n const updateHeight = () => {\n const height = content.scrollHeight;\n group.style.setProperty('--group-height', `${height}px`);\n };\n\n updateHeight();\n\n const resizeObserver = new ResizeObserver(() => {\n updateHeight();\n });\n\n resizeObserver.observe(content);\n resizeObserver.observe(group);\n\n window.addEventListener('resize', updateHeight);\n\n return () => {\n resizeObserver.disconnect();\n window.removeEventListener('resize', updateHeight);\n };\n }, []);\n\n return (\n <AriaDisclosurePanel {...props}>\n <div ref={contentRef} className={styles['accordion__panel-content']}>\n {children}\n </div>\n </AriaDisclosurePanel>\n );\n};\n\ninterface SlotProps {\n children: React.ReactNode;\n}\n\nexport const StartSlot = ({ children }: SlotProps) => <>{children}</>;\nexport const EndSlot = ({ children }: SlotProps) => <>{children}</>;\n\nexport const Accordion = ({\n title,\n description,\n children,\n defaultExpanded = false,\n className,\n titleStart,\n titleEnd,\n id,\n headingLevel = 'h3',\n ...props\n}: AccordionProps) => {\n const accordionClasses = [styles.accordion, className]\n .filter(Boolean)\n .join(' ');\n\n // Pick start and end content out of `children`\n let startSlot = titleStart;\n let endSlot = titleEnd;\n const panelContent = React.Children.map(children, (child) => {\n const childElement = child as ReactElement<SlotProps>;\n\n if (childElement.type === StartSlot) {\n startSlot = childElement.props.children;\n return null;\n }\n\n if (childElement.type === EndSlot) {\n endSlot = childElement.props.children;\n return null;\n }\n\n return childElement;\n })?.filter(Boolean);\n\n return (\n <AriaDisclosure\n className={accordionClasses}\n defaultExpanded={defaultExpanded}\n id={id}\n {...props}\n >\n <AccordionTrigger\n title={title}\n description={description}\n startSlot={startSlot}\n endSlot={endSlot}\n id={id}\n headingLevel={headingLevel}\n />\n <AccordionPanel>{panelContent}</AccordionPanel>\n </AriaDisclosure>\n );\n};\n\nexport interface AccordionGroupProps {\n /** Title for the accordion group - can be string or ReactNode */\n title?: string | React.ReactNode;\n\n /** Description for the accordion group - can be string or ReactNode */\n description?: string | React.ReactNode;\n\n /** Collection of Accordion components */\n children?: React.ReactNode;\n\n /** Additional CSS class for custom styling */\n className?: string;\n\n /** Whether multiple accordions can be expanded at once */\n allowsMultipleExpanded?: boolean;\n}\n\nexport const AccordionGroup = ({\n title,\n description,\n children,\n className,\n allowsMultipleExpanded = true,\n}: AccordionGroupProps) => {\n const groupClasses = [styles['accordion-group'], className]\n .filter(Boolean)\n .join(' ');\n\n // Find any children that have defaultExpanded={true}\n const defaultExpandedKeys = React.Children.toArray(children)\n .map((child, index) => {\n if (\n React.isValidElement(child) &&\n typeof child.props === 'object' &&\n child.props !== null &&\n 'defaultExpanded' in child.props &&\n child.props.defaultExpanded\n ) {\n return 'id' in child.props && typeof child.props.id === 'string'\n ? child.props.id\n : `accordion-${index}`;\n }\n return null;\n })\n .filter((key): key is string => key !== null);\n\n return (\n <div className={groupClasses}>\n {(title || description) && (\n <div className={styles['accordion-group__header']}>\n {title}\n {description}\n </div>\n )}\n <AriaDisclosureGroup\n className={styles['accordion-group__stack']}\n allowsMultipleExpanded={allowsMultipleExpanded}\n defaultExpandedKeys={defaultExpandedKeys}\n >\n {React.Children.map(children, (child, index) => {\n if (React.isValidElement<AccordionProps>(child)) {\n return React.cloneElement(child, {\n key: `accordion-${index}`,\n id: child.props?.id || `accordion-${index}`,\n } as Partial<AccordionProps>);\n }\n return child;\n })}\n </AriaDisclosureGroup>\n </div>\n );\n};\n\nAccordion.StartSlot = StartSlot;\nAccordion.EndSlot = EndSlot;\nStartSlot.displayName = 'Accordion.StartSlot';\nEndSlot.displayName = 'Accordion.EndSlot';\n\nexport default Accordion;\n"],"names":["AccordionTrigger","title","description","startSlot","endSlot","id","headingLevel","HeadingElement","jsx","AriaButton","slot","className","styles","accordion__trigger","children","accordion__title","accordion__description","Icon","iconName","iconPrefix","color","AccordionPanel","props","contentRef","React","useRef","useEffect","content","current","group","closest","requestAnimationFrame","height","scrollHeight","style","setProperty","updateHeight","resizeObserver","ResizeObserver","observe","window","addEventListener","disconnect","removeEventListener","AriaDisclosurePanel","ref","StartSlot","EndSlot","Accordion","defaultExpanded","titleStart","titleEnd","accordionClasses","accordion","filter","Boolean","join","panelContent","Children","map","child","childElement","type","jsxs","AriaDisclosure","AccordionGroup","allowsMultipleExpanded","groupClasses","defaultExpandedKeys","toArray","index","isValidElement","key","AriaDisclosureGroup","cloneElement","displayName"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{jsx as e,jsxs as r}from"react/jsx-runtime";import o,{useRef as t,useEffect as a}from"react";import{usePopover as s,Overlay as i,DismissButton as n}from"@react-aria/overlays";import{FocusScope as
|
|
2
|
-
return e(i,{children:/* @__PURE__ */e(
|
|
3
|
-
/* @__PURE__ */e(n,{onDismiss:
|
|
1
|
+
import{jsx as e,jsxs as r}from"react/jsx-runtime";import o,{useRef as t,useEffect as a}from"react";import{usePopover as s,Overlay as i,DismissButton as n}from"@react-aria/overlays";import{FocusScope as c}from"@react-aria/focus";import '../../assets/Popover.css';const l="_popover_1de57_1",p="_arrow_1de57_11",m={top:"top",right:"right",bottom:"bottom",left:"left"},d=({children:d,state:u,arrowDirection:f="bottom",triggerRef:h,hasArrow:v=!0,placement:w,shouldFlip:g=!0,isNonModal:_=!1,allowTabOut:F=!1,autoFocus:b=!0})=>{const N=t(null),R=w||m[f],[x,z]=o.useState(R);a(()=>{const e=()=>{N.current&&h.current&&z(R)};return e(),window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)},[R,h]);const{popoverProps:D,arrowProps:E,placement:L}=s({popoverRef:N,triggerRef:h,offset:12,placement:x,shouldFlip:g,isNonModal:_},u);/* @__PURE__ */
|
|
2
|
+
return e(i,{children:/* @__PURE__ */e(c,{restoreFocus:!0,contain:!F,autoFocus:b,children:/* @__PURE__ */r("div",{...D,ref:N,className:l,children:[
|
|
3
|
+
/* @__PURE__ */e(n,{onDismiss:u.close}),d,v&&/* @__PURE__ */e("div",{...E,className:p,"data-placement":L})]})})})};export{d as Popover,d as default};
|
|
4
4
|
//# sourceMappingURL=Popover.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Popover.js","sources":["../../../src/components/Popover/Popover.tsx"],"sourcesContent":["import React, { useRef, useEffect } from 'react';\nimport { usePopover, DismissButton, Overlay } from '@react-aria/overlays';\nimport { FocusScope } from '@react-aria/focus';\nimport type { OverlayTriggerState } from 'react-stately';\nimport styles from './Popover.module.css';\n\n// Define all possible placement options for internal use (menu component)\ntype PlacementType =\n | 'top'\n | 'top start'\n | 'top end'\n | 'right'\n | 'right top'\n | 'right bottom'\n | 'bottom'\n | 'bottom start'\n | 'bottom end'\n | 'left'\n | 'left top'\n | 'left bottom';\n\n// Define the arrow direction options for the public use\ntype ArrowDirectionType = 'top' | 'right' | 'bottom' | 'left';\n\n// Mapping arrow direction to placement\nconst arrowDirectionToPlacement: Record<ArrowDirectionType, PlacementType> = {\n top: 'top',\n right: 'right',\n bottom: 'bottom',\n left: 'left',\n};\n\n// Internal props that should only be used by specific components like Menu\nexport interface InternalPopoverProps {\n /**\n * @private Internal use only - placement of the popover\n * This prop should only be used by internal components like Menu\n */\n placement?: PlacementType;\n\n /**\n * @private Internal use only - whether the popover should flip to fit in the viewport\n * This prop should only be used by internal components like Menu\n */\n shouldFlip?: boolean;\n\n /**\n * @private Internal use only - whether to allow elements outside the popover may be interacted with\n * This prop should only be used by internal components like Menu\n */\n isNonModal?: boolean;\n\n /**\n * @private Internal use only - whether to allow tabbing out of the popover\n * This prop should only be used by internal components like Menu\n */\n allowTabOut?: boolean;\n\n /**\n * @private Internal use only - whether to auto-focus elements within the popover\n * This prop should only be used by internal components like Menu\n */\n autoFocus?: boolean;\n}\n\n// Public props exposed to all component users\nexport interface PopoverProps {\n /** Content to be rendered inside the popover */\n children: React.ReactNode;\n\n /** State object controlling the overlay's open/closed status */\n state: OverlayTriggerState;\n\n /** Direction of the arrow that points to the trigger element */\n arrowDirection?: ArrowDirectionType;\n\n /** Reference to the trigger element that opens the popover */\n triggerRef:\n | React.RefObject<HTMLButtonElement | null>\n | { current: HTMLElement | null };\n\n /** Whether to show the directional arrow on the popover */\n hasArrow?: boolean;\n}\n\n// Combined props type for internal use\nexport type CombinedPopoverProps = PopoverProps & InternalPopoverProps;\n\nexport const Popover = ({\n children,\n state,\n arrowDirection = 'bottom',\n triggerRef,\n hasArrow = true,\n placement,\n shouldFlip = true,\n isNonModal = false,\n allowTabOut = false,\n autoFocus = true,\n}: CombinedPopoverProps) => {\n const popoverRef = useRef<HTMLDivElement>(null);\n\n // Determine the placement - either from direct placement (internal) or mapped from arrowDirection\n const initialPlacement =\n placement || arrowDirectionToPlacement[arrowDirection];\n const [optimalPlacement, setOptimalPlacement] =\n React.useState<PlacementType>(initialPlacement);\n\n useEffect(() => {\n const updatePlacement = () => {\n if (!popoverRef.current || !triggerRef.current) return;\n\n // When viewport constraints are encountered, the placement can change\n // React Aria's shouldFlip handles most of this logic now\n setOptimalPlacement(initialPlacement);\n };\n\n updatePlacement();\n window.addEventListener('resize', updatePlacement);\n return () => window.removeEventListener('resize', updatePlacement);\n }, [initialPlacement, triggerRef]);\n\n const {\n popoverProps,\n arrowProps,\n placement: finalPlacement,\n } = usePopover(\n {\n popoverRef,\n triggerRef,\n offset: 12,\n placement: optimalPlacement,\n shouldFlip,\n isNonModal,\n },\n state,\n );\n\n return (\n <Overlay>\n <
|
|
1
|
+
{"version":3,"file":"Popover.js","sources":["../../../src/components/Popover/Popover.tsx"],"sourcesContent":["import React, { useRef, useEffect } from 'react';\nimport { usePopover, DismissButton, Overlay } from '@react-aria/overlays';\nimport { FocusScope } from '@react-aria/focus';\nimport type { OverlayTriggerState } from 'react-stately';\nimport styles from './Popover.module.css';\n\n// Define all possible placement options for internal use (menu component)\ntype PlacementType =\n | 'top'\n | 'top start'\n | 'top end'\n | 'right'\n | 'right top'\n | 'right bottom'\n | 'bottom'\n | 'bottom start'\n | 'bottom end'\n | 'left'\n | 'left top'\n | 'left bottom';\n\n// Define the arrow direction options for the public use\ntype ArrowDirectionType = 'top' | 'right' | 'bottom' | 'left';\n\n// Mapping arrow direction to placement\nconst arrowDirectionToPlacement: Record<ArrowDirectionType, PlacementType> = {\n top: 'top',\n right: 'right',\n bottom: 'bottom',\n left: 'left',\n};\n\n// Internal props that should only be used by specific components like Menu\nexport interface InternalPopoverProps {\n /**\n * @private Internal use only - placement of the popover\n * This prop should only be used by internal components like Menu\n */\n placement?: PlacementType;\n\n /**\n * @private Internal use only - whether the popover should flip to fit in the viewport\n * This prop should only be used by internal components like Menu\n */\n shouldFlip?: boolean;\n\n /**\n * @private Internal use only - whether to allow elements outside the popover may be interacted with\n * This prop should only be used by internal components like Menu\n */\n isNonModal?: boolean;\n\n /**\n * @private Internal use only - whether to allow tabbing out of the popover\n * This prop should only be used by internal components like Menu\n */\n allowTabOut?: boolean;\n\n /**\n * @private Internal use only - whether to auto-focus elements within the popover\n * This prop should only be used by internal components like Menu\n */\n autoFocus?: boolean;\n}\n\n// Public props exposed to all component users\nexport interface PopoverProps {\n /** Content to be rendered inside the popover */\n children: React.ReactNode;\n\n /** State object controlling the overlay's open/closed status */\n state: OverlayTriggerState;\n\n /** Direction of the arrow that points to the trigger element */\n arrowDirection?: ArrowDirectionType;\n\n /** Reference to the trigger element that opens the popover */\n triggerRef:\n | React.RefObject<HTMLButtonElement | null>\n | { current: HTMLElement | null };\n\n /** Whether to show the directional arrow on the popover */\n hasArrow?: boolean;\n}\n\n// Combined props type for internal use\nexport type CombinedPopoverProps = PopoverProps & InternalPopoverProps;\n\nexport const Popover = ({\n children,\n state,\n arrowDirection = 'bottom',\n triggerRef,\n hasArrow = true,\n placement,\n shouldFlip = true,\n isNonModal = false,\n allowTabOut = false,\n autoFocus = true,\n}: CombinedPopoverProps) => {\n const popoverRef = useRef<HTMLDivElement>(null);\n\n // Determine the placement - either from direct placement (internal) or mapped from arrowDirection\n const initialPlacement =\n placement || arrowDirectionToPlacement[arrowDirection];\n const [optimalPlacement, setOptimalPlacement] =\n React.useState<PlacementType>(initialPlacement);\n\n useEffect(() => {\n const updatePlacement = () => {\n if (!popoverRef.current || !triggerRef.current) return;\n\n // When viewport constraints are encountered, the placement can change\n // React Aria's shouldFlip handles most of this logic now\n setOptimalPlacement(initialPlacement);\n };\n\n updatePlacement();\n window.addEventListener('resize', updatePlacement);\n return () => window.removeEventListener('resize', updatePlacement);\n }, [initialPlacement, triggerRef]);\n\n const {\n popoverProps,\n arrowProps,\n placement: finalPlacement,\n } = usePopover(\n {\n popoverRef,\n triggerRef,\n offset: 12,\n placement: optimalPlacement,\n shouldFlip,\n isNonModal,\n },\n state,\n );\n\n return (\n <Overlay>\n <FocusScope restoreFocus contain={!allowTabOut} autoFocus={autoFocus}>\n <div {...popoverProps} ref={popoverRef} className={styles.popover}>\n <DismissButton onDismiss={state.close} />\n {children}\n {hasArrow && (\n <div\n {...arrowProps}\n className={styles.arrow}\n data-placement={finalPlacement}\n />\n )}\n </div>\n </FocusScope>\n </Overlay>\n );\n};\n\nexport default Popover;\n"],"names":["arrowDirectionToPlacement","top","right","bottom","left","Popover","children","state","arrowDirection","triggerRef","hasArrow","placement","shouldFlip","isNonModal","allowTabOut","autoFocus","popoverRef","useRef","initialPlacement","optimalPlacement","setOptimalPlacement","React","useState","useEffect","updatePlacement","current","window","addEventListener","removeEventListener","popoverProps","arrowProps","finalPlacement","usePopover","offset","Overlay","jsx","FocusScope","restoreFocus","contain","jsxs","ref","className","styles","DismissButton","onDismiss","close"],"mappings":"mRAyBMA,EAAuE,CAC3EC,IAAK,MACLC,MAAO,QACPC,OAAQ,SACRC,KAAM,QA2DKC,EAAU,EACrBC,WACAC,QACAC,iBAAiB,SACjBC,aACAC,YAAW,EACXC,YACAC,cAAa,EACbC,cAAa,EACbC,eAAc,EACdC,aAAY,MAEZ,MAAMC,EAAaC,EAAuB,MAGpCC,EACJP,GAAaX,EAA0BQ,IAClCW,EAAkBC,GACvBC,EAAMC,SAAwBJ,GAEhCK,EAAU,KACR,MAAMC,EAAkB,KACjBR,EAAWS,SAAYhB,EAAWgB,SAIvCL,EAAoBF,IAKtB,OAFAM,IACAE,OAAOC,iBAAiB,SAAUH,GAC3B,IAAME,OAAOE,oBAAoB,SAAUJ,IACjD,CAACN,EAAkBT,IAEtB,MAAMoB,aACJA,EAAAC,WACAA,EACAnB,UAAWoB,GACTC,EACF,CACEhB,aACAP,aACAwB,OAAQ,GACRtB,UAAWQ,EACXP,aACAC,cAEFN;AAGF,SACG2B,EAAA,CACC5B,wBAAA6B,EAACC,GAAWC,cAAY,EAACC,SAAUxB,EAAaC,YAC9CT,wBAAAiC,EAAC,UAAQV,EAAcW,IAAKxB,EAAYyB,UAAWC,EACjDpC,SAAA;iBAACqC,EAAA,CAAcC,UAAWrC,EAAMsC,QAC/BvC,EACAI,kBACCyB,EAAC,MAAA,IACKL,EACJW,UAAWC,EACX,iBAAgBX"}
|