@helsenorge/designsystem-react 12.8.0 → 12.9.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/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## [12.9.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv12.8.0&targetVersion=GTv12.9.0) (2025-10-29)
2
+
3
+ ### Bug Fixes
4
+
5
+ - dropdown fokus styling fiks og aschildslot story forbedret
6
+ ([08d1658](https://github.com/helsenorge/designsystem/commit/08d165819fa9295ae16c6c77316735cc15172a32)), closes
7
+ [#358846](https://github.com/helsenorge/designsystem/issues/358846)
8
+ - **panel:** fiks controlled med state i callback
9
+ ([49d7398](https://github.com/helsenorge/designsystem/commit/49d73985164dfe571fcf9c3af9ba68d54988c259)), closes
10
+ [#363208](https://github.com/helsenorge/designsystem/issues/363208)
11
+
1
12
  ## [12.8.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv12.7.0&targetVersion=GTv12.8.0) (2025-10-28)
2
13
 
3
14
  ### Features
package/Panel.js CHANGED
@@ -192,7 +192,6 @@ const PanelRoot = React__default.forwardRef(function PanelForwardedRef({
192
192
  });
193
193
  const handleExpandClick = () => {
194
194
  setIsExpanded(!isExpanded);
195
- if (onExpand) onExpand();
196
195
  };
197
196
  return expandableContent.length > 0 ? /* @__PURE__ */ jsx("div", { className: outerClassnames, children: /* @__PURE__ */ jsx("div", { className: classNames({
198
197
  [styles["panel__border--outline--inner"]]: variant === "outline"
package/Panel.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Panel.js","sources":["../src/components/Panel/resourceHelper.ts","../src/components/Panel/Panel.tsx"],"sourcesContent":["import { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Panel.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Panel.nb-NO.json';\nimport { HNDesignsystemPanel } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemPanel => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { LanguageLocales } from '../../constants';\nimport { useExpand } from '../../hooks/useExpand';\nimport { PaletteNames } from '../../theme/palette';\nimport Button from '../Button';\nimport Icon, { IconSize } from '../Icon';\nimport PanelTitle, { PanelTitleProps } from './PanelTitle';\nimport { getResources } from './resourceHelper';\nimport { HNDesignsystemPanel } from '../../resources/Resources';\nimport { useLanguage } from '../../utils/language';\nimport Highlighter from '../Highlighter';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronRight from '../Icons/ChevronRight';\nimport ChevronUp from '../Icons/ChevronUp';\n\nimport styles from './styles.module.scss';\n\nexport enum PanelLayout {\n vertical = 'vertical',\n horizontal = 'horizontal',\n combined = 'combined',\n bAsRightCol = 'bAsRightCol',\n}\n\nexport type PanelColors = Extract<PaletteNames, 'white' | 'neutral'>;\n\nexport enum PanelVariant {\n fill = 'fill',\n line = 'line',\n outline = 'outline',\n}\n\nexport enum PanelStacking {\n default = 'default',\n bFirst = 'bFirst',\n}\n\nexport enum PanelStatus {\n none = 'none',\n new = 'new',\n error = 'error',\n draft = 'draft',\n}\n\nexport interface PanelProps {\n /** Aria label on call to action button */\n buttonBottomAriaLabel?: string;\n /** Sets the text on the bottom call to action button */\n buttonBottomText?: string;\n /** Sets the action on the bottom call to action button */\n buttonBottomOnClick?: () => void;\n /** Expands or collapses the panel. Only applicable when ExpandedContent is used */\n expanded?: boolean;\n /** Sets the layout and order of the content boxes */\n layout?: PanelLayout;\n /** Sets the visual variant of panel */\n variant?: PanelVariant;\n /** Sets the color for panel if it has variant fill */\n color?: PanelColors;\n /** Sets classes on the outermost container of the panel */\n className?: string;\n /** Action called when toggling expansion of ExpandedContent */\n onExpand?: () => void;\n /** Sets the stacking order of the content boxes */\n stacking?: PanelStacking;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Children elements to be rendered inside the panel */\n children?: React.ReactNode;\n /** Displays a status on the left side: default normal */\n status?: PanelStatus;\n /** Resources for component */\n resources?: Partial<HNDesignsystemPanel>;\n /** Highlights text in title and content. Used for search results */\n highlightText?: string;\n}\n\nconst ExpandButton = ({\n onClick,\n isExpanded,\n resources,\n}: {\n onClick: () => void;\n isExpanded: boolean | undefined;\n resources: Partial<HNDesignsystemPanel>;\n}): React.JSX.Element => {\n const buttonClassName = classNames(styles['expander__button'], isExpanded && styles['expander__button--expanded']);\n\n return (\n <Button\n variant=\"borderless\"\n textClassName={styles['expander__button__text']}\n wrapperClassName={buttonClassName}\n aria-expanded={isExpanded}\n onClick={onClick}\n >\n <Icon svgIcon={isExpanded ? ChevronUp : ChevronDown} size={IconSize.XSmall} />\n <span>{isExpanded ? resources.expandButtonClose : resources.expandButtonOpen}</span>\n </Button>\n );\n};\nconst PanelRoot = React.forwardRef(function PanelForwardedRef(\n {\n layout = PanelLayout.vertical,\n variant = PanelVariant.fill,\n color = 'neutral',\n stacking = PanelStacking.default,\n testId,\n children,\n expanded = false,\n status = PanelStatus.none,\n buttonBottomAriaLabel,\n buttonBottomOnClick,\n buttonBottomText,\n className,\n resources,\n onExpand,\n highlightText,\n }: PanelProps,\n ref: React.ForwardedRef<HTMLDivElement>\n) {\n const [preContainer, setPreContainer] = React.useState<React.ReactNode[]>([]);\n const [title, setTitle] = React.useState<React.ReactNode[]>([]);\n const [content, setContent] = React.useState<React.ReactNode[]>([]);\n const [expandableContent, setExpandableContent] = React.useState<React.ReactNode[]>([]);\n const [hasIcon, setHasIcon] = React.useState(false);\n const [isExpanded, setIsExpanded] = useExpand(expanded, onExpand);\n const localRef = React.useRef<HTMLDivElement>(null);\n const panelRef = ref ?? localRef;\n const expandedContentRef = React.useRef<HTMLDivElement>(null);\n const defaultScroll = 100;\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemPanel = {\n ...defaultResources,\n ...resources,\n };\n\n React.useEffect(() => {\n let localHasIcon = false;\n const newPreContainer: React.ReactNode[] = [];\n const newTitle: React.ReactNode[] = [];\n const newContent: React.ReactNode[] = [];\n const newExpandableContent: React.ReactNode[] = [];\n\n React.Children.forEach(children, child => {\n if (React.isValidElement(child)) {\n if (child.type === PreContainer) {\n newPreContainer.push(child);\n } else if (child.type === PanelTitle) {\n newTitle.push(\n React.cloneElement(child as React.ReactElement<PanelTitleProps>, { highlightText: child.props.highlightText || highlightText })\n );\n if (child.props.icon) {\n localHasIcon = true;\n }\n } else if (child.type === A || child.type === B || child.type === C) {\n newContent.push(child);\n } else if (child.type === ExpandedContent) {\n newExpandableContent.push(child);\n }\n }\n });\n\n setPreContainer(newPreContainer);\n setTitle(newTitle);\n setContent(newContent);\n setExpandableContent(newExpandableContent);\n setHasIcon(localHasIcon);\n }, [children]);\n\n React.useEffect(() => {\n if (expanded) {\n // Hvis panel åpnes controlled skal ikke scroll skje\n return;\n }\n // Scroller oppover når expanded content åpnes uncontrolled\n if (isExpanded) {\n if ('current' in panelRef && panelRef.current && expandedContentRef.current) {\n const panelRect = panelRef.current.getBoundingClientRect();\n const expandedContentRect = expandedContentRef.current.getBoundingClientRect();\n\n const scrollAmount = Math.min(defaultScroll, panelRect.top - 20);\n\n // Scroller kun oppover, og kun dersom expandedContent havner utenfor skjermen når åpnet\n if (scrollAmount > 0 && expandedContentRect.bottom > window.innerHeight) {\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) {\n return;\n }\n window.scrollBy({\n top: scrollAmount,\n behavior: 'smooth',\n });\n }\n }\n }\n }, [isExpanded]);\n\n const colorScheme = variant === PanelVariant.fill ? color : 'white';\n\n const outerClassnames = classNames(className, {\n [styles['panel__border--outline--outer']]: variant === PanelVariant.outline,\n [styles['panel__border--line']]: variant === PanelVariant.line,\n [styles['panel__border--fill--neutral']]: variant === PanelVariant.fill && colorScheme === 'neutral',\n [styles['panel__border--fill--new']]: variant === PanelVariant.fill && status === PanelStatus.new,\n [styles['panel__border--fill--status']]: variant === PanelVariant.fill && status !== PanelStatus.none,\n });\n const panelClassnames = classNames(styles['panel'], styles[`panel--${colorScheme}`], styles['panel--status'], {\n [styles['panel--line']]: variant === PanelVariant.line,\n [styles['panel--new']]: status === PanelStatus.new,\n [styles['panel--draft']]: status === PanelStatus.draft,\n [styles['panel--error']]: status === PanelStatus.error,\n [styles['panel--icon']]: hasIcon,\n });\n const contentContainerLayout = classNames(styles['panel__content'], styles[`panel__content--${layout}`], {\n [styles[`panel__content--b-first`]]: stacking === PanelStacking.bFirst,\n });\n const expanderBorderLayout = classNames({\n [styles['panel__expander__border--expanded']]: isExpanded && status === PanelStatus.none,\n [styles[`panel__expander__border--not-expanded--${colorScheme}`]]: !isExpanded && status === PanelStatus.none,\n [styles[`panel__expander__border--not-expanded--line`]]: !isExpanded && status === PanelStatus.none && variant === PanelVariant.line,\n });\n\n const handleExpandClick = (): void => {\n setIsExpanded(!isExpanded);\n if (onExpand) onExpand();\n };\n\n return expandableContent.length > 0 ? (\n <div className={outerClassnames}>\n <div className={classNames({ [styles['panel__border--outline--inner']]: variant === PanelVariant.outline })}>\n <div className={expanderBorderLayout}>\n <div className={panelClassnames} data-testid={testId} ref={panelRef}>\n <Highlighter searchText={highlightText}>\n {preContainer}\n {title}\n </Highlighter>\n <div className={contentContainerLayout}>\n <Highlighter searchText={highlightText}>{content}</Highlighter>\n </div>\n <ExpandButton onClick={handleExpandClick} isExpanded={isExpanded} resources={mergedResources} />\n {isExpanded && (\n <div ref={expandedContentRef} data-testid={testId + '-details'}>\n <div className={styles['panel__expander__separator']} />\n <Highlighter searchText={highlightText}>{expandableContent}</Highlighter>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n ) : (\n <div className={outerClassnames}>\n <div className={classNames({ [styles['panel__border--outline--inner']]: variant === PanelVariant.outline })}>\n <div className={panelClassnames} data-testid={testId} ref={panelRef}>\n <Highlighter searchText={highlightText}>\n {preContainer}\n {title}\n </Highlighter>\n <div className={contentContainerLayout}>\n <Highlighter searchText={highlightText}>{content}</Highlighter>\n </div>\n {buttonBottomText && buttonBottomOnClick && (\n <div className={styles['panel__button-bottom']}>\n <Button variant=\"borderless\" type=\"button\" size=\"medium\" onClick={buttonBottomOnClick} aria-label={buttonBottomAriaLabel}>\n {buttonBottomText}\n <Icon svgIcon={ChevronRight} size={IconSize.XSmall} />\n </Button>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n});\n\nexport interface ContentProps {\n /** Children elements to be rendered inside the content box */\n children?: React.ReactNode;\n}\n\nexport const PreContainer: React.FC<ContentProps> = ({ children }) => {\n return <div className={styles['panel__pre-container']}>{children}</div>;\n};\n\nexport const A: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--a']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const B: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--b']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const C: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--c']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const ExpandedContent: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__expander__content']);\n return <div className={styling}>{children}</div>;\n};\n\ntype PanelComponent = typeof PanelRoot & {\n PreContainer: React.FC<ContentProps>;\n Title: React.FC<PanelTitleProps>;\n A: React.FC<ContentProps>;\n B: React.FC<ContentProps>;\n C: React.FC<ContentProps>;\n ExpandedContent: React.FC<ContentProps>;\n};\nPanelRoot.displayName = 'Panel';\nconst Panel = PanelRoot as PanelComponent;\nPanel.PreContainer = PreContainer;\nPanel.Title = PanelTitle;\nPanel.A = A;\nPanel.B = B;\nPanel.C = C;\nPanel.ExpandedContent = ExpandedContent;\n\nexport default Panel;\n"],"names":["PanelLayout","PanelVariant","PanelStacking","PanelStatus","React"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAKO,MAAM,eAAe,CAAC,aAAmD;AAC9E,UAAQ,UAAA;AAAA,IACN,KAAK,gBAAgB;AACnB,aAAO;AAAA,IACT,KAAK,gBAAgB;AAAA,IACrB;AACE,aAAO;AAAA,EAAA;AAEb;ACOO,IAAK,gCAAAA,iBAAL;AACLA,eAAA,UAAA,IAAW;AACXA,eAAA,YAAA,IAAa;AACbA,eAAA,UAAA,IAAW;AACXA,eAAA,aAAA,IAAc;AAJJ,SAAAA;AAAA,GAAA,eAAA,CAAA,CAAA;AASL,IAAK,iCAAAC,kBAAL;AACLA,gBAAA,MAAA,IAAO;AACPA,gBAAA,MAAA,IAAO;AACPA,gBAAA,SAAA,IAAU;AAHA,SAAAA;AAAA,GAAA,gBAAA,CAAA,CAAA;AAML,IAAK,kCAAAC,mBAAL;AACLA,iBAAA,SAAA,IAAU;AACVA,iBAAA,QAAA,IAAS;AAFC,SAAAA;AAAA,GAAA,iBAAA,CAAA,CAAA;AAKL,IAAK,gCAAAC,iBAAL;AACLA,eAAA,MAAA,IAAO;AACPA,eAAA,KAAA,IAAM;AACNA,eAAA,OAAA,IAAQ;AACRA,eAAA,OAAA,IAAQ;AAJE,SAAAA;AAAA,GAAA,eAAA,CAAA,CAAA;AAwCZ,MAAM,eAAe,CAAC;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AACF,MAIyB;AACvB,QAAM,kBAAkB,WAAW,OAAO,kBAAkB,GAAG,cAAc,OAAO,4BAA4B,CAAC;AAEjH,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,SAAQ;AAAA,MACR,eAAe,OAAO,wBAAwB;AAAA,MAC9C,kBAAkB;AAAA,MAClB,iBAAe;AAAA,MACf;AAAA,MAEA,UAAA;AAAA,QAAA,oBAAC,QAAK,SAAS,aAAa,YAAY,aAAa,MAAM,SAAS,QAAQ;AAAA,4BAC3E,QAAA,EAAM,UAAA,aAAa,UAAU,oBAAoB,UAAU,iBAAA,CAAiB;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGnF;AACA,MAAM,YAAYC,eAAM,WAAW,SAAS,kBAC1C;AAAA,EACE,SAAS;AAAA,EACT,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GACA,KACA;AACA,QAAM,CAAC,cAAc,eAAe,IAAIA,eAAM,SAA4B,CAAA,CAAE;AAC5E,QAAM,CAAC,OAAO,QAAQ,IAAIA,eAAM,SAA4B,CAAA,CAAE;AAC9D,QAAM,CAAC,SAAS,UAAU,IAAIA,eAAM,SAA4B,CAAA,CAAE;AAClE,QAAM,CAAC,mBAAmB,oBAAoB,IAAIA,eAAM,SAA4B,CAAA,CAAE;AACtF,QAAM,CAAC,SAAS,UAAU,IAAIA,eAAM,SAAS,KAAK;AAClD,QAAM,CAAC,YAAY,aAAa,IAAI,UAAU,UAAU,QAAQ;AAChE,QAAM,WAAWA,eAAM,OAAuB,IAAI;AAClD,QAAM,WAAW,OAAO;AACxB,QAAM,qBAAqBA,eAAM,OAAuB,IAAI;AAC5D,QAAM,gBAAgB;AAEtB,QAAM,EAAE,SAAA,IAAa,YAA6B,gBAAgB,SAAS;AAC3E,QAAM,mBAAmB,aAAa,QAAQ;AAE9C,QAAM,kBAAuC;AAAA,IAC3C,GAAG;AAAA,IACH,GAAG;AAAA,EAAA;AAGLA,iBAAM,UAAU,MAAM;AACpB,QAAI,eAAe;AACnB,UAAM,kBAAqC,CAAA;AAC3C,UAAM,WAA8B,CAAA;AACpC,UAAM,aAAgC,CAAA;AACtC,UAAM,uBAA0C,CAAA;AAEhDA,mBAAM,SAAS,QAAQ,UAAU,CAAA,UAAS;AACxC,UAAIA,eAAM,eAAe,KAAK,GAAG;AAC/B,YAAI,MAAM,SAAS,cAAc;AAC/B,0BAAgB,KAAK,KAAK;AAAA,QAC5B,WAAW,MAAM,SAAS,YAAY;AACpC,mBAAS;AAAA,YACPA,eAAM,aAAa,OAA8C,EAAE,eAAe,MAAM,MAAM,iBAAiB,cAAA,CAAe;AAAA,UAAA;AAEhI,cAAI,MAAM,MAAM,MAAM;AACpB,2BAAe;AAAA,UACjB;AAAA,QACF,WAAW,MAAM,SAAS,KAAK,MAAM,SAAS,KAAK,MAAM,SAAS,GAAG;AACnE,qBAAW,KAAK,KAAK;AAAA,QACvB,WAAW,MAAM,SAAS,iBAAiB;AACzC,+BAAqB,KAAK,KAAK;AAAA,QACjC;AAAA,MACF;AAAA,IACF,CAAC;AAED,oBAAgB,eAAe;AAC/B,aAAS,QAAQ;AACjB,eAAW,UAAU;AACrB,yBAAqB,oBAAoB;AACzC,eAAW,YAAY;AAAA,EACzB,GAAG,CAAC,QAAQ,CAAC;AAEbA,iBAAM,UAAU,MAAM;AACpB,QAAI,UAAU;AAEZ;AAAA,IACF;AAEA,QAAI,YAAY;AACd,UAAI,aAAa,YAAY,SAAS,WAAW,mBAAmB,SAAS;AAC3E,cAAM,YAAY,SAAS,QAAQ,sBAAA;AACnC,cAAM,sBAAsB,mBAAmB,QAAQ,sBAAA;AAEvD,cAAM,eAAe,KAAK,IAAI,eAAe,UAAU,MAAM,EAAE;AAG/D,YAAI,eAAe,KAAK,oBAAoB,SAAS,OAAO,aAAa;AACvE,gBAAM,uBAAuB,OAAO,WAAW,kCAAkC,EAAE;AACnF,cAAI,sBAAsB;AACxB;AAAA,UACF;AACA,iBAAO,SAAS;AAAA,YACd,KAAK;AAAA,YACL,UAAU;AAAA,UAAA,CACX;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,cAAc,YAAY,SAAoB,QAAQ;AAE5D,QAAM,kBAAkB,WAAW,WAAW;AAAA,IAC5C,CAAC,OAAO,+BAA+B,CAAC,GAAG,YAAY;AAAA,IACvD,CAAC,OAAO,qBAAqB,CAAC,GAAG,YAAY;AAAA,IAC7C,CAAC,OAAO,8BAA8B,CAAC,GAAG,YAAY,UAAqB,gBAAgB;AAAA,IAC3F,CAAC,OAAO,0BAA0B,CAAC,GAAG,YAAY,UAAqB,WAAW;AAAA,IAClF,CAAC,OAAO,6BAA6B,CAAC,GAAG,YAAY,UAAqB,WAAW;AAAA;AAAA,EAAA,CACtF;AACD,QAAM,kBAAkB,WAAW,OAAO,OAAO,GAAG,OAAO,UAAU,WAAW,EAAE,GAAG,OAAO,eAAe,GAAG;AAAA,IAC5G,CAAC,OAAO,aAAa,CAAC,GAAG,YAAY;AAAA,IACrC,CAAC,OAAO,YAAY,CAAC,GAAG,WAAW;AAAA,IACnC,CAAC,OAAO,cAAc,CAAC,GAAG,WAAW;AAAA,IACrC,CAAC,OAAO,cAAc,CAAC,GAAG,WAAW;AAAA,IACrC,CAAC,OAAO,aAAa,CAAC,GAAG;AAAA,EAAA,CAC1B;AACD,QAAM,yBAAyB,WAAW,OAAO,gBAAgB,GAAG,OAAO,mBAAmB,MAAM,EAAE,GAAG;AAAA,IACvG,CAAC,OAAO,yBAAyB,CAAC,GAAG,aAAa;AAAA;AAAA,EAAA,CACnD;AACD,QAAM,uBAAuB,WAAW;AAAA,IACtC,CAAC,OAAO,mCAAmC,CAAC,GAAG,cAAc,WAAW;AAAA,IACxE,CAAC,OAAO,0CAA0C,WAAW,EAAE,CAAC,GAAG,CAAC,cAAc,WAAW;AAAA,IAC7F,CAAC,OAAO,6CAA6C,CAAC,GAAG,CAAC,cAAc,WAAW,UAAoB,YAAY;AAAA;AAAA,EAAA,CACpH;AAED,QAAM,oBAAoB,MAAY;AACpC,kBAAc,CAAC,UAAU;AACzB,QAAI,SAAU,UAAA;AAAA,EAChB;AAEA,SAAO,kBAAkB,SAAS,IAChC,oBAAC,SAAI,WAAW,iBACd,UAAA,oBAAC,OAAA,EAAI,WAAW,WAAW;AAAA,IAAE,CAAC,OAAO,+BAA+B,CAAC,GAAG,YAAY;AAAA;AAAA,EAAA,CAAsB,GACxG,UAAA,oBAAC,SAAI,WAAW,sBACd,UAAA,qBAAC,OAAA,EAAI,WAAW,iBAAiB,eAAa,QAAQ,KAAK,UACzD,UAAA;AAAA,IAAA,qBAAC,aAAA,EAAY,YAAY,eACtB,UAAA;AAAA,MAAA;AAAA,MACA;AAAA,IAAA,GACH;AAAA,IACA,oBAAC,SAAI,WAAW,wBACd,8BAAC,aAAA,EAAY,YAAY,eAAgB,UAAA,QAAA,CAAQ,EAAA,CACnD;AAAA,wBACC,cAAA,EAAa,SAAS,mBAAmB,YAAwB,WAAW,iBAAiB;AAAA,IAC7F,cACC,qBAAC,OAAA,EAAI,KAAK,oBAAoB,eAAa,SAAS,YAClD,UAAA;AAAA,MAAA,oBAAC,OAAA,EAAI,WAAW,OAAO,4BAA4B,EAAA,CAAG;AAAA,MACtD,oBAAC,aAAA,EAAY,YAAY,eAAgB,UAAA,kBAAA,CAAkB;AAAA,IAAA,EAAA,CAC7D;AAAA,EAAA,EAAA,CAEJ,EAAA,CACF,EAAA,CACF,EAAA,CACF,IAEA,oBAAC,OAAA,EAAI,WAAW,iBACd,UAAA,oBAAC,OAAA,EAAI,WAAW,WAAW;AAAA,IAAE,CAAC,OAAO,+BAA+B,CAAC,GAAG,YAAY;AAAA;AAAA,EAAA,CAAsB,GACxG,UAAA,qBAAC,OAAA,EAAI,WAAW,iBAAiB,eAAa,QAAQ,KAAK,UACzD,UAAA;AAAA,IAAA,qBAAC,aAAA,EAAY,YAAY,eACtB,UAAA;AAAA,MAAA;AAAA,MACA;AAAA,IAAA,GACH;AAAA,IACA,oBAAC,SAAI,WAAW,wBACd,8BAAC,aAAA,EAAY,YAAY,eAAgB,UAAA,QAAA,CAAQ,EAAA,CACnD;AAAA,IACC,oBAAoB,uBACnB,oBAAC,SAAI,WAAW,OAAO,sBAAsB,GAC3C,UAAA,qBAAC,UAAO,SAAQ,cAAa,MAAK,UAAS,MAAK,UAAS,SAAS,qBAAqB,cAAY,uBAChG,UAAA;AAAA,MAAA;AAAA,0BACA,MAAA,EAAK,SAAS,cAAc,MAAM,SAAS,OAAA,CAAQ;AAAA,IAAA,EAAA,CACtD,EAAA,CACF;AAAA,EAAA,EAAA,CAEJ,GACF,GACF;AAEJ,CAAC;AAOM,MAAM,eAAuC,CAAC,EAAE,eAAe;AACpE,6BAAQ,OAAA,EAAI,WAAW,OAAO,sBAAsB,GAAI,UAAS;AACnE;AAEO,MAAM,IAA4B,CAAC,EAAE,eAAe;AACzD,QAAM,UAAU,WAAW,OAAO,sBAAsB,GAAG,OAAO,yBAAyB,CAAC;AAC5F,SAAO,oBAAC,OAAA,EAAI,WAAW,SAAU,SAAA,CAAS;AAC5C;AAEO,MAAM,IAA4B,CAAC,EAAE,eAAe;AACzD,QAAM,UAAU,WAAW,OAAO,sBAAsB,GAAG,OAAO,yBAAyB,CAAC;AAC5F,SAAO,oBAAC,OAAA,EAAI,WAAW,SAAU,SAAA,CAAS;AAC5C;AAEO,MAAM,IAA4B,CAAC,EAAE,eAAe;AACzD,QAAM,UAAU,WAAW,OAAO,sBAAsB,GAAG,OAAO,yBAAyB,CAAC;AAC5F,SAAO,oBAAC,OAAA,EAAI,WAAW,SAAU,SAAA,CAAS;AAC5C;AAEO,MAAM,kBAA0C,CAAC,EAAE,eAAe;AACvE,QAAM,UAAU,WAAW,OAAO,0BAA0B,CAAC;AAC7D,SAAO,oBAAC,OAAA,EAAI,WAAW,SAAU,SAAA,CAAS;AAC5C;AAUA,UAAU,cAAc;AACxB,MAAM,QAAQ;AACd,MAAM,eAAe;AACrB,MAAM,QAAQ;AACd,MAAM,IAAI;AACV,MAAM,IAAI;AACV,MAAM,IAAI;AACV,MAAM,kBAAkB;"}
1
+ {"version":3,"file":"Panel.js","sources":["../src/components/Panel/resourceHelper.ts","../src/components/Panel/Panel.tsx"],"sourcesContent":["import { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Panel.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Panel.nb-NO.json';\nimport { HNDesignsystemPanel } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemPanel => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { LanguageLocales } from '../../constants';\nimport { useExpand } from '../../hooks/useExpand';\nimport { PaletteNames } from '../../theme/palette';\nimport Button from '../Button';\nimport Icon, { IconSize } from '../Icon';\nimport PanelTitle, { PanelTitleProps } from './PanelTitle';\nimport { getResources } from './resourceHelper';\nimport { HNDesignsystemPanel } from '../../resources/Resources';\nimport { useLanguage } from '../../utils/language';\nimport Highlighter from '../Highlighter';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronRight from '../Icons/ChevronRight';\nimport ChevronUp from '../Icons/ChevronUp';\n\nimport styles from './styles.module.scss';\n\nexport enum PanelLayout {\n vertical = 'vertical',\n horizontal = 'horizontal',\n combined = 'combined',\n bAsRightCol = 'bAsRightCol',\n}\n\nexport type PanelColors = Extract<PaletteNames, 'white' | 'neutral'>;\n\nexport enum PanelVariant {\n fill = 'fill',\n line = 'line',\n outline = 'outline',\n}\n\nexport enum PanelStacking {\n default = 'default',\n bFirst = 'bFirst',\n}\n\nexport enum PanelStatus {\n none = 'none',\n new = 'new',\n error = 'error',\n draft = 'draft',\n}\n\nexport interface PanelProps {\n /** Aria label on call to action button */\n buttonBottomAriaLabel?: string;\n /** Sets the text on the bottom call to action button */\n buttonBottomText?: string;\n /** Sets the action on the bottom call to action button */\n buttonBottomOnClick?: () => void;\n /** Expands or collapses the panel. Only applicable when ExpandedContent is used */\n expanded?: boolean;\n /** Sets the layout and order of the content boxes */\n layout?: PanelLayout;\n /** Sets the visual variant of panel */\n variant?: PanelVariant;\n /** Sets the color for panel if it has variant fill */\n color?: PanelColors;\n /** Sets classes on the outermost container of the panel */\n className?: string;\n /** Action called when toggling expansion of ExpandedContent */\n onExpand?: (isExpanded?: boolean) => void;\n /** Sets the stacking order of the content boxes */\n stacking?: PanelStacking;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Children elements to be rendered inside the panel */\n children?: React.ReactNode;\n /** Displays a status on the left side: default normal */\n status?: PanelStatus;\n /** Resources for component */\n resources?: Partial<HNDesignsystemPanel>;\n /** Highlights text in title and content. Used for search results */\n highlightText?: string;\n}\n\nconst ExpandButton = ({\n onClick,\n isExpanded,\n resources,\n}: {\n onClick: () => void;\n isExpanded: boolean | undefined;\n resources: Partial<HNDesignsystemPanel>;\n}): React.JSX.Element => {\n const buttonClassName = classNames(styles['expander__button'], isExpanded && styles['expander__button--expanded']);\n\n return (\n <Button\n variant=\"borderless\"\n textClassName={styles['expander__button__text']}\n wrapperClassName={buttonClassName}\n aria-expanded={isExpanded}\n onClick={onClick}\n >\n <Icon svgIcon={isExpanded ? ChevronUp : ChevronDown} size={IconSize.XSmall} />\n <span>{isExpanded ? resources.expandButtonClose : resources.expandButtonOpen}</span>\n </Button>\n );\n};\nconst PanelRoot = React.forwardRef(function PanelForwardedRef(\n {\n layout = PanelLayout.vertical,\n variant = PanelVariant.fill,\n color = 'neutral',\n stacking = PanelStacking.default,\n testId,\n children,\n expanded = false,\n status = PanelStatus.none,\n buttonBottomAriaLabel,\n buttonBottomOnClick,\n buttonBottomText,\n className,\n resources,\n onExpand,\n highlightText,\n }: PanelProps,\n ref: React.ForwardedRef<HTMLDivElement>\n) {\n const [preContainer, setPreContainer] = React.useState<React.ReactNode[]>([]);\n const [title, setTitle] = React.useState<React.ReactNode[]>([]);\n const [content, setContent] = React.useState<React.ReactNode[]>([]);\n const [expandableContent, setExpandableContent] = React.useState<React.ReactNode[]>([]);\n const [hasIcon, setHasIcon] = React.useState(false);\n const [isExpanded, setIsExpanded] = useExpand(expanded, onExpand);\n const localRef = React.useRef<HTMLDivElement>(null);\n const panelRef = ref ?? localRef;\n const expandedContentRef = React.useRef<HTMLDivElement>(null);\n const defaultScroll = 100;\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemPanel = {\n ...defaultResources,\n ...resources,\n };\n\n React.useEffect(() => {\n let localHasIcon = false;\n const newPreContainer: React.ReactNode[] = [];\n const newTitle: React.ReactNode[] = [];\n const newContent: React.ReactNode[] = [];\n const newExpandableContent: React.ReactNode[] = [];\n\n React.Children.forEach(children, child => {\n if (React.isValidElement(child)) {\n if (child.type === PreContainer) {\n newPreContainer.push(child);\n } else if (child.type === PanelTitle) {\n newTitle.push(\n React.cloneElement(child as React.ReactElement<PanelTitleProps>, { highlightText: child.props.highlightText || highlightText })\n );\n if (child.props.icon) {\n localHasIcon = true;\n }\n } else if (child.type === A || child.type === B || child.type === C) {\n newContent.push(child);\n } else if (child.type === ExpandedContent) {\n newExpandableContent.push(child);\n }\n }\n });\n\n setPreContainer(newPreContainer);\n setTitle(newTitle);\n setContent(newContent);\n setExpandableContent(newExpandableContent);\n setHasIcon(localHasIcon);\n }, [children]);\n\n React.useEffect(() => {\n if (expanded) {\n // Hvis panel åpnes controlled skal ikke scroll skje\n return;\n }\n // Scroller oppover når expanded content åpnes uncontrolled\n if (isExpanded) {\n if ('current' in panelRef && panelRef.current && expandedContentRef.current) {\n const panelRect = panelRef.current.getBoundingClientRect();\n const expandedContentRect = expandedContentRef.current.getBoundingClientRect();\n\n const scrollAmount = Math.min(defaultScroll, panelRect.top - 20);\n\n // Scroller kun oppover, og kun dersom expandedContent havner utenfor skjermen når åpnet\n if (scrollAmount > 0 && expandedContentRect.bottom > window.innerHeight) {\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) {\n return;\n }\n window.scrollBy({\n top: scrollAmount,\n behavior: 'smooth',\n });\n }\n }\n }\n }, [isExpanded]);\n\n const colorScheme = variant === PanelVariant.fill ? color : 'white';\n\n const outerClassnames = classNames(className, {\n [styles['panel__border--outline--outer']]: variant === PanelVariant.outline,\n [styles['panel__border--line']]: variant === PanelVariant.line,\n [styles['panel__border--fill--neutral']]: variant === PanelVariant.fill && colorScheme === 'neutral',\n [styles['panel__border--fill--new']]: variant === PanelVariant.fill && status === PanelStatus.new,\n [styles['panel__border--fill--status']]: variant === PanelVariant.fill && status !== PanelStatus.none,\n });\n const panelClassnames = classNames(styles['panel'], styles[`panel--${colorScheme}`], styles['panel--status'], {\n [styles['panel--line']]: variant === PanelVariant.line,\n [styles['panel--new']]: status === PanelStatus.new,\n [styles['panel--draft']]: status === PanelStatus.draft,\n [styles['panel--error']]: status === PanelStatus.error,\n [styles['panel--icon']]: hasIcon,\n });\n const contentContainerLayout = classNames(styles['panel__content'], styles[`panel__content--${layout}`], {\n [styles[`panel__content--b-first`]]: stacking === PanelStacking.bFirst,\n });\n const expanderBorderLayout = classNames({\n [styles['panel__expander__border--expanded']]: isExpanded && status === PanelStatus.none,\n [styles[`panel__expander__border--not-expanded--${colorScheme}`]]: !isExpanded && status === PanelStatus.none,\n [styles[`panel__expander__border--not-expanded--line`]]: !isExpanded && status === PanelStatus.none && variant === PanelVariant.line,\n });\n\n const handleExpandClick = (): void => {\n setIsExpanded(!isExpanded);\n };\n\n return expandableContent.length > 0 ? (\n <div className={outerClassnames}>\n <div className={classNames({ [styles['panel__border--outline--inner']]: variant === PanelVariant.outline })}>\n <div className={expanderBorderLayout}>\n <div className={panelClassnames} data-testid={testId} ref={panelRef}>\n <Highlighter searchText={highlightText}>\n {preContainer}\n {title}\n </Highlighter>\n <div className={contentContainerLayout}>\n <Highlighter searchText={highlightText}>{content}</Highlighter>\n </div>\n <ExpandButton onClick={handleExpandClick} isExpanded={isExpanded} resources={mergedResources} />\n {isExpanded && (\n <div ref={expandedContentRef} data-testid={testId + '-details'}>\n <div className={styles['panel__expander__separator']} />\n <Highlighter searchText={highlightText}>{expandableContent}</Highlighter>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n ) : (\n <div className={outerClassnames}>\n <div className={classNames({ [styles['panel__border--outline--inner']]: variant === PanelVariant.outline })}>\n <div className={panelClassnames} data-testid={testId} ref={panelRef}>\n <Highlighter searchText={highlightText}>\n {preContainer}\n {title}\n </Highlighter>\n <div className={contentContainerLayout}>\n <Highlighter searchText={highlightText}>{content}</Highlighter>\n </div>\n {buttonBottomText && buttonBottomOnClick && (\n <div className={styles['panel__button-bottom']}>\n <Button variant=\"borderless\" type=\"button\" size=\"medium\" onClick={buttonBottomOnClick} aria-label={buttonBottomAriaLabel}>\n {buttonBottomText}\n <Icon svgIcon={ChevronRight} size={IconSize.XSmall} />\n </Button>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n});\n\nexport interface ContentProps {\n /** Children elements to be rendered inside the content box */\n children?: React.ReactNode;\n}\n\nexport const PreContainer: React.FC<ContentProps> = ({ children }) => {\n return <div className={styles['panel__pre-container']}>{children}</div>;\n};\n\nexport const A: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--a']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const B: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--b']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const C: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__content__item'], styles['panel__content__item--c']);\n return <div className={styling}>{children}</div>;\n};\n\nexport const ExpandedContent: React.FC<ContentProps> = ({ children }) => {\n const styling = classNames(styles['panel__expander__content']);\n return <div className={styling}>{children}</div>;\n};\n\ntype PanelComponent = typeof PanelRoot & {\n PreContainer: React.FC<ContentProps>;\n Title: React.FC<PanelTitleProps>;\n A: React.FC<ContentProps>;\n B: React.FC<ContentProps>;\n C: React.FC<ContentProps>;\n ExpandedContent: React.FC<ContentProps>;\n};\nPanelRoot.displayName = 'Panel';\nconst Panel = PanelRoot as PanelComponent;\nPanel.PreContainer = PreContainer;\nPanel.Title = PanelTitle;\nPanel.A = A;\nPanel.B = B;\nPanel.C = C;\nPanel.ExpandedContent = ExpandedContent;\n\nexport default Panel;\n"],"names":["PanelLayout","PanelVariant","PanelStacking","PanelStatus","React"],"mappings":"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"}
@@ -4,7 +4,7 @@ import { u as useFloating, f as autoUpdate, o as offset, s as shift, j as size }
4
4
  import classNames from "classnames";
5
5
  import "../../theme/grid.js";
6
6
  import "../../hooks/useBreakpoint.js";
7
- import { useHover } from "../../hooks/useHover.js";
7
+ import { usePseudoClasses } from "../../hooks/usePseudoClasses.js";
8
8
  import { useToggle } from "../../hooks/useToggle.js";
9
9
  import { useKeyboardEvent } from "../../hooks/useKeyboardEvent.js";
10
10
  import { useOutsideEvent } from "../../hooks/useOutsideEvent.js";
@@ -53,7 +53,8 @@ const DropdownBase = (props) => {
53
53
  const dropdownRef = useRef(null);
54
54
  const optionsRef = useRef(null);
55
55
  const childrenRefList = useRef(React__default.Children.map(children, () => React__default.createRef()));
56
- const { hoverRef: buttonRef, isHovered } = useHover();
56
+ const buttonRef = React__default.useRef(null);
57
+ const { isHovered } = usePseudoClasses(buttonRef);
57
58
  const openedByKeyboard = useRef(false);
58
59
  const { value: isOpen, toggleValue: toggleIsOpen } = useToggle(!disabled && open, onToggle);
59
60
  const isMobile = useIsMobileBreakpoint();
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/components/Dropdown/resourceHelper.ts","../../../src/components/Dropdown/Dropdown.tsx"],"sourcesContent":["import { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Dropdown.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Dropdown.nb-NO.json';\nimport { HNDesignsystemDropdown } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemDropdown => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React, { useEffect, useRef, useId, ComponentType } from 'react';\n\nimport { autoUpdate, offset, shift, size, useFloating } from '@floating-ui/react';\nimport classNames from 'classnames';\nimport { clamp } from 'motion/react';\n\nimport {\n AnalyticsId,\n IconSize,\n KeyboardEventKey,\n LanguageLocales,\n ZIndex,\n useHover,\n useKeyboardEvent,\n useOutsideEvent,\n useToggle,\n} from '../..';\nimport { getResources } from './resourceHelper';\nimport { SingleSelectItem, SingleSelectItemProps } from './SingleSelect/SingleSelectItem';\nimport { useIsMobileBreakpoint } from '../../hooks/useIsMobileBreakpoint';\nimport { HNDesignsystemDropdown } from '../../resources/Resources';\nimport { isComponent } from '../../utils/component';\nimport { useLanguage } from '../../utils/language';\nimport { mergeRefs } from '../../utils/refs';\nimport Button from '../Button';\nimport Checkbox, { CheckboxProps } from '../Checkbox';\nimport Icon, { SvgIcon } from '../Icon';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronUp from '../Icons/ChevronUp';\nimport { IconName } from '../Icons/IconNames';\nimport PlusSmall from '../Icons/PlusSmall';\nimport Label, { LabelProps } from '../Label';\nimport LazyIcon from '../LazyIcon';\nimport { SingleSelect } from './SingleSelect/SingleSelect';\n\nimport styles from './styles.module.scss';\n\ntype DropdownVariants = 'fill' | 'transparent' | 'borderless';\n\nexport interface DropdownProps {\n /** Text on the trigger button that opens the dropdown */\n triggerText: string;\n /** Sets the dropdown content */\n children: React.ReactNode;\n /** Minimum width for the dropdown in pixels. Does not affect trigger button. */\n dropdownMinWidth?: number;\n /** Minimum width for the trigger in pixels. Does not apply for borderless variant */\n triggerMinWidth?: number;\n /** Disables rendring of the close button in the list */\n noCloseButton?: boolean;\n /** Called when dropdown is open/closed */\n onToggle?: (isOpen: boolean) => void;\n /** Whether the dropdown is open or not */\n open?: boolean;\n /** Makes the dropdown disabled */\n disabled?: boolean;\n /** Sets the data-testid attribute on the dropdown button */\n testId?: string;\n /** Overrides the default z-index of the DropDownContent */\n zIndex?: number;\n /** Resources for component */\n resources?: Partial<HNDesignsystemDropdown>;\n /** Adds an icon to the trigger */\n svgIcon?: SvgIcon | IconName;\n /** Sets the visual variant of the Dropdown */\n variant?: DropdownVariants;\n}\n\nexport const DropdownBase: React.FC<DropdownProps> = props => {\n const {\n triggerText,\n noCloseButton = false,\n onToggle,\n dropdownMinWidth,\n triggerMinWidth,\n open = false,\n children,\n testId,\n disabled,\n zIndex = ZIndex.PopOver,\n resources,\n svgIcon,\n variant = 'fill',\n } = props;\n\n const dropdownRef = useRef<HTMLDivElement>(null);\n const optionsRef = useRef<HTMLUListElement>(null);\n const childrenRefList = useRef(React.Children.map(children, () => React.createRef<HTMLElement>()));\n const { hoverRef: buttonRef, isHovered } = useHover<HTMLButtonElement>();\n const openedByKeyboard = useRef<boolean>(false);\n const { value: isOpen, toggleValue: toggleIsOpen } = useToggle(!disabled && open, onToggle);\n const isMobile = useIsMobileBreakpoint();\n const triggerActualMinWidth = variant !== 'borderless' && typeof triggerMinWidth != 'undefined' ? `${triggerMinWidth}px` : 'auto';\n const triggerMinWidthLimit = isMobile ? 96 : 112;\n const maxWidth = isMobile ? 384 : 400;\n const toggleTextId = useId();\n const optionIdPrefix = useId();\n const contentId = useId();\n const leftIconProps = {\n className: styles['dropdown__left-icon'],\n size: IconSize.XSmall,\n isHovered: !disabled && isHovered,\n };\n\n const isSingleSelect = React.Children.toArray(children).every(\n child => React.isValidElement(child) && isComponent<SingleSelectItemProps>(child, SingleSelectItem)\n );\n const isMultiSelect = React.Children.toArray(children).every(\n child => React.isValidElement(child) && isComponent<CheckboxProps>(child, Checkbox)\n );\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n const mergedResources: HNDesignsystemDropdown = {\n ...defaultResources,\n ...resources,\n };\n\n const toggleClasses = classNames(styles.dropdown__toggle, {\n [styles['dropdown__toggle--open']]: isOpen && !disabled,\n [styles['dropdown__toggle--with-icon']]: typeof svgIcon !== 'undefined',\n [styles['dropdown__toggle--transparent']]: variant === 'transparent',\n [styles['dropdown__toggle--borderless']]: variant === 'borderless',\n });\n const contentClasses = classNames(styles.dropdown__content, isOpen && styles['dropdown__content--open']);\n const listItemClasses = classNames(styles['dropdown__list-item'], { [styles['dropdown__list-item--single-select']]: isSingleSelect });\n\n const { refs, floatingStyles } = useFloating({\n placement: 'bottom',\n middleware: [\n offset(8),\n shift({ padding: 8 }),\n size({\n apply({ availableWidth, availableHeight, elements, rects }) {\n const triggerW = rects.reference.width;\n const minProp = typeof dropdownMinWidth !== 'undefined' ? clamp(0, maxWidth, dropdownMinWidth) : 0;\n const targetW = Math.max(triggerW, minProp);\n const finalW = Math.min(availableWidth, targetW);\n\n Object.assign(elements.floating.style, {\n width: `${finalW}px`,\n maxHeight: `${availableHeight}px`,\n overflowY: 'auto',\n overflowX: 'hidden',\n });\n },\n }),\n ],\n whileElementsMounted: autoUpdate,\n });\n\n const handleOpen = (isKeyboard: boolean): void => {\n openedByKeyboard.current = isKeyboard;\n toggleIsOpen();\n };\n\n const handleClose = (): void => {\n toggleIsOpen();\n buttonRef.current?.focus();\n };\n\n useEffect(() => {\n if (isOpen && openedByKeyboard.current) {\n const firstEnabled = childrenRefList.current?.find(r => r.current && !r.current.hasAttribute('disabled'));\n firstEnabled?.current?.focus();\n openedByKeyboard.current = false;\n }\n }, [isOpen]);\n\n const focusByIndex = (nextIndex: number): void => {\n childrenRefList.current?.[nextIndex]?.current?.focus();\n };\n\n const isListNavKey = (key: string): boolean =>\n key === KeyboardEventKey.ArrowDown || key === KeyboardEventKey.ArrowUp || key === KeyboardEventKey.Home || key === KeyboardEventKey.End;\n\n const handleKeyboardNavigation = (event: KeyboardEvent): void => {\n if (!childrenRefList.current) return;\n\n const key = event.key as KeyboardEventKey;\n\n if (key === KeyboardEventKey.Escape) {\n if (isOpen) {\n event.preventDefault();\n handleClose();\n }\n return;\n }\n\n if (!isOpen) {\n if (isListNavKey(key)) {\n event.preventDefault();\n handleOpen(true);\n }\n return;\n }\n\n if (!isListNavKey(key)) {\n return;\n }\n\n const index = childrenRefList.current.findIndex(x => x.current === (event.target as HTMLElement));\n let nextIndex = index;\n\n if (key === KeyboardEventKey.Home) {\n nextIndex = 0;\n } else if (key === KeyboardEventKey.End) {\n nextIndex = childrenRefList.current.length - 1;\n } else if (key === KeyboardEventKey.ArrowDown && index < childrenRefList.current.length - 1) {\n nextIndex = index + 1;\n } else if (key === KeyboardEventKey.ArrowUp && index > 0) {\n nextIndex = index - 1;\n }\n\n if (nextIndex !== -1) {\n event.preventDefault();\n focusByIndex(nextIndex);\n }\n };\n\n useKeyboardEvent(dropdownRef, handleKeyboardNavigation, [\n KeyboardEventKey.ArrowDown,\n KeyboardEventKey.ArrowUp,\n KeyboardEventKey.End,\n KeyboardEventKey.Enter,\n KeyboardEventKey.Escape,\n KeyboardEventKey.Home,\n KeyboardEventKey.Space,\n ]);\n\n useOutsideEvent(dropdownRef, () => isOpen && handleClose());\n\n const renderChildren = React.Children.map(children, (child, index) => {\n return (\n <li className={listItemClasses} id={`${optionIdPrefix}-${index}`}>\n {React.isValidElement(child) && childrenRefList.current && childrenRefList.current[index]\n ? ((): React.ReactElement => {\n const baseProps: { ref: React.Ref<HTMLElement> } = {\n ref: mergeRefs([child.props.ref, childrenRefList.current[index]]),\n };\n\n if (isMultiSelect) {\n const label = (child.props as CheckboxProps).label as React.ReactNode;\n if (React.isValidElement(label) && isComponent<LabelProps>(label, Label)) {\n return React.cloneElement(child as React.ReactElement<CheckboxProps>, {\n ...baseProps,\n label: React.cloneElement(label, {\n labelClassName: classNames((label.props as LabelProps)?.labelClassName, styles['dropdown__multiselect-item']),\n }),\n });\n }\n }\n\n return React.cloneElement(child as React.ReactElement<Record<string, unknown>>, baseProps);\n })()\n : child}\n </li>\n );\n });\n\n return (\n <div className={styles.dropdown} ref={dropdownRef}>\n <button\n type=\"button\"\n onClick={(): false | void => handleOpen(false)}\n className={toggleClasses}\n ref={mergeRefs([buttonRef, refs.setReference])}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Dropdown}\n disabled={disabled}\n aria-labelledby={toggleTextId}\n aria-haspopup={true}\n aria-controls={contentId}\n aria-expanded={isOpen}\n style={{\n width: triggerActualMinWidth,\n maxWidth: '100%',\n minWidth: `${triggerMinWidthLimit}px`,\n }}\n >\n {svgIcon && (\n <>\n {typeof svgIcon === 'string' ? (\n <LazyIcon {...leftIconProps} iconName={svgIcon} />\n ) : (\n <Icon {...leftIconProps} svgIcon={svgIcon} />\n )}\n </>\n )}\n <span id={toggleTextId} className={styles.dropdown__toggle__text}>\n {triggerText}\n </span>\n <Icon\n svgIcon={!isSingleSelect ? PlusSmall : isOpen ? ChevronUp : ChevronDown}\n className={styles['dropdown__right-icon']}\n isHovered={!disabled && isHovered}\n size={IconSize.XSmall}\n />\n </button>\n <div\n key={dropdownMinWidth ?? 'auto'}\n id={contentId}\n className={contentClasses}\n ref={refs.setFloating}\n style={{\n ...floatingStyles,\n zIndex: zIndex,\n }}\n >\n <ul className={styles.dropdown__options} role=\"group\" aria-labelledby={toggleTextId} tabIndex={-1} ref={optionsRef}>\n {isSingleSelect && <SingleSelect onValueChange={() => handleClose()}>{renderChildren}</SingleSelect>}\n {isMultiSelect && renderChildren}\n </ul>\n {!isSingleSelect && !noCloseButton && (\n <div className={styles.dropdown__close}>\n <Button onClick={handleClose}>{mergedResources.closeText}</Button>\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport interface DropdownCompound extends React.FC<DropdownProps> {\n SingleSelectItem: ComponentType<SingleSelectItemProps>;\n}\nconst Dropdown = DropdownBase as DropdownCompound;\nDropdown.SingleSelectItem = SingleSelectItem;\nDropdownBase.displayName = 'Dropdown';\n\nexport default Dropdown;\n"],"names":["React"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/components/Dropdown/resourceHelper.ts","../../../src/components/Dropdown/Dropdown.tsx"],"sourcesContent":["import { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Dropdown.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Dropdown.nb-NO.json';\nimport { HNDesignsystemDropdown } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemDropdown => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React, { useEffect, useRef, useId, ComponentType } from 'react';\n\nimport { autoUpdate, offset, shift, size, useFloating } from '@floating-ui/react';\nimport classNames from 'classnames';\nimport { clamp } from 'motion/react';\n\nimport {\n AnalyticsId,\n IconSize,\n KeyboardEventKey,\n LanguageLocales,\n ZIndex,\n usePseudoClasses,\n useKeyboardEvent,\n useOutsideEvent,\n useToggle,\n} from '../..';\nimport { getResources } from './resourceHelper';\nimport { SingleSelectItem, SingleSelectItemProps } from './SingleSelect/SingleSelectItem';\nimport { useIsMobileBreakpoint } from '../../hooks/useIsMobileBreakpoint';\nimport { HNDesignsystemDropdown } from '../../resources/Resources';\nimport { isComponent } from '../../utils/component';\nimport { useLanguage } from '../../utils/language';\nimport { mergeRefs } from '../../utils/refs';\nimport Button from '../Button';\nimport Checkbox, { CheckboxProps } from '../Checkbox';\nimport Icon, { SvgIcon } from '../Icon';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronUp from '../Icons/ChevronUp';\nimport { IconName } from '../Icons/IconNames';\nimport PlusSmall from '../Icons/PlusSmall';\nimport Label, { LabelProps } from '../Label';\nimport LazyIcon from '../LazyIcon';\nimport { SingleSelect } from './SingleSelect/SingleSelect';\n\nimport styles from './styles.module.scss';\n\ntype DropdownVariants = 'fill' | 'transparent' | 'borderless';\n\nexport interface DropdownProps {\n /** Text on the trigger button that opens the dropdown */\n triggerText: string;\n /** Sets the dropdown content */\n children: React.ReactNode;\n /** Minimum width for the dropdown in pixels. Does not affect trigger button. */\n dropdownMinWidth?: number;\n /** Minimum width for the trigger in pixels. Does not apply for borderless variant */\n triggerMinWidth?: number;\n /** Disables rendring of the close button in the list */\n noCloseButton?: boolean;\n /** Called when dropdown is open/closed */\n onToggle?: (isOpen: boolean) => void;\n /** Whether the dropdown is open or not */\n open?: boolean;\n /** Makes the dropdown disabled */\n disabled?: boolean;\n /** Sets the data-testid attribute on the dropdown button */\n testId?: string;\n /** Overrides the default z-index of the DropDownContent */\n zIndex?: number;\n /** Resources for component */\n resources?: Partial<HNDesignsystemDropdown>;\n /** Adds an icon to the trigger */\n svgIcon?: SvgIcon | IconName;\n /** Sets the visual variant of the Dropdown */\n variant?: DropdownVariants;\n}\n\nexport const DropdownBase: React.FC<DropdownProps> = props => {\n const {\n triggerText,\n noCloseButton = false,\n onToggle,\n dropdownMinWidth,\n triggerMinWidth,\n open = false,\n children,\n testId,\n disabled,\n zIndex = ZIndex.PopOver,\n resources,\n svgIcon,\n variant = 'fill',\n } = props;\n\n const dropdownRef = useRef<HTMLDivElement>(null);\n const optionsRef = useRef<HTMLUListElement>(null);\n const childrenRefList = useRef(React.Children.map(children, () => React.createRef<HTMLElement>()));\n const buttonRef = React.useRef<HTMLButtonElement>(null);\n const { isHovered } = usePseudoClasses<HTMLButtonElement>(buttonRef);\n const openedByKeyboard = useRef<boolean>(false);\n const { value: isOpen, toggleValue: toggleIsOpen } = useToggle(!disabled && open, onToggle);\n const isMobile = useIsMobileBreakpoint();\n const triggerActualMinWidth = variant !== 'borderless' && typeof triggerMinWidth != 'undefined' ? `${triggerMinWidth}px` : 'auto';\n const triggerMinWidthLimit = isMobile ? 96 : 112;\n const maxWidth = isMobile ? 384 : 400;\n const toggleTextId = useId();\n const optionIdPrefix = useId();\n const contentId = useId();\n const leftIconProps = {\n className: styles['dropdown__left-icon'],\n size: IconSize.XSmall,\n isHovered: !disabled && isHovered,\n };\n\n const isSingleSelect = React.Children.toArray(children).every(\n child => React.isValidElement(child) && isComponent<SingleSelectItemProps>(child, SingleSelectItem)\n );\n const isMultiSelect = React.Children.toArray(children).every(\n child => React.isValidElement(child) && isComponent<CheckboxProps>(child, Checkbox)\n );\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n const mergedResources: HNDesignsystemDropdown = {\n ...defaultResources,\n ...resources,\n };\n\n const toggleClasses = classNames(styles.dropdown__toggle, {\n [styles['dropdown__toggle--open']]: isOpen && !disabled,\n [styles['dropdown__toggle--with-icon']]: typeof svgIcon !== 'undefined',\n [styles['dropdown__toggle--transparent']]: variant === 'transparent',\n [styles['dropdown__toggle--borderless']]: variant === 'borderless',\n });\n const contentClasses = classNames(styles.dropdown__content, isOpen && styles['dropdown__content--open']);\n const listItemClasses = classNames(styles['dropdown__list-item'], { [styles['dropdown__list-item--single-select']]: isSingleSelect });\n\n const { refs, floatingStyles } = useFloating({\n placement: 'bottom',\n middleware: [\n offset(8),\n shift({ padding: 8 }),\n size({\n apply({ availableWidth, availableHeight, elements, rects }) {\n const triggerW = rects.reference.width;\n const minProp = typeof dropdownMinWidth !== 'undefined' ? clamp(0, maxWidth, dropdownMinWidth) : 0;\n const targetW = Math.max(triggerW, minProp);\n const finalW = Math.min(availableWidth, targetW);\n\n Object.assign(elements.floating.style, {\n width: `${finalW}px`,\n maxHeight: `${availableHeight}px`,\n overflowY: 'auto',\n overflowX: 'hidden',\n });\n },\n }),\n ],\n whileElementsMounted: autoUpdate,\n });\n\n const handleOpen = (isKeyboard: boolean): void => {\n openedByKeyboard.current = isKeyboard;\n toggleIsOpen();\n };\n\n const handleClose = (): void => {\n toggleIsOpen();\n buttonRef.current?.focus();\n };\n\n useEffect(() => {\n if (isOpen && openedByKeyboard.current) {\n const firstEnabled = childrenRefList.current?.find(r => r.current && !r.current.hasAttribute('disabled'));\n firstEnabled?.current?.focus();\n openedByKeyboard.current = false;\n }\n }, [isOpen]);\n\n const focusByIndex = (nextIndex: number): void => {\n childrenRefList.current?.[nextIndex]?.current?.focus();\n };\n\n const isListNavKey = (key: string): boolean =>\n key === KeyboardEventKey.ArrowDown || key === KeyboardEventKey.ArrowUp || key === KeyboardEventKey.Home || key === KeyboardEventKey.End;\n\n const handleKeyboardNavigation = (event: KeyboardEvent): void => {\n if (!childrenRefList.current) return;\n\n const key = event.key as KeyboardEventKey;\n\n if (key === KeyboardEventKey.Escape) {\n if (isOpen) {\n event.preventDefault();\n handleClose();\n }\n return;\n }\n\n if (!isOpen) {\n if (isListNavKey(key)) {\n event.preventDefault();\n handleOpen(true);\n }\n return;\n }\n\n if (!isListNavKey(key)) {\n return;\n }\n\n const index = childrenRefList.current.findIndex(x => x.current === (event.target as HTMLElement));\n let nextIndex = index;\n\n if (key === KeyboardEventKey.Home) {\n nextIndex = 0;\n } else if (key === KeyboardEventKey.End) {\n nextIndex = childrenRefList.current.length - 1;\n } else if (key === KeyboardEventKey.ArrowDown && index < childrenRefList.current.length - 1) {\n nextIndex = index + 1;\n } else if (key === KeyboardEventKey.ArrowUp && index > 0) {\n nextIndex = index - 1;\n }\n\n if (nextIndex !== -1) {\n event.preventDefault();\n focusByIndex(nextIndex);\n }\n };\n\n useKeyboardEvent(dropdownRef, handleKeyboardNavigation, [\n KeyboardEventKey.ArrowDown,\n KeyboardEventKey.ArrowUp,\n KeyboardEventKey.End,\n KeyboardEventKey.Enter,\n KeyboardEventKey.Escape,\n KeyboardEventKey.Home,\n KeyboardEventKey.Space,\n ]);\n\n useOutsideEvent(dropdownRef, () => isOpen && handleClose());\n\n const renderChildren = React.Children.map(children, (child, index) => {\n return (\n <li className={listItemClasses} id={`${optionIdPrefix}-${index}`}>\n {React.isValidElement(child) && childrenRefList.current && childrenRefList.current[index]\n ? ((): React.ReactElement => {\n const baseProps: { ref: React.Ref<HTMLElement> } = {\n ref: mergeRefs([child.props.ref, childrenRefList.current[index]]),\n };\n\n if (isMultiSelect) {\n const label = (child.props as CheckboxProps).label as React.ReactNode;\n if (React.isValidElement(label) && isComponent<LabelProps>(label, Label)) {\n return React.cloneElement(child as React.ReactElement<CheckboxProps>, {\n ...baseProps,\n label: React.cloneElement(label, {\n labelClassName: classNames((label.props as LabelProps)?.labelClassName, styles['dropdown__multiselect-item']),\n }),\n });\n }\n }\n\n return React.cloneElement(child as React.ReactElement<Record<string, unknown>>, baseProps);\n })()\n : child}\n </li>\n );\n });\n\n return (\n <div className={styles.dropdown} ref={dropdownRef}>\n <button\n type=\"button\"\n onClick={(): false | void => handleOpen(false)}\n className={toggleClasses}\n ref={mergeRefs([buttonRef, refs.setReference])}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Dropdown}\n disabled={disabled}\n aria-labelledby={toggleTextId}\n aria-haspopup={true}\n aria-controls={contentId}\n aria-expanded={isOpen}\n style={{\n width: triggerActualMinWidth,\n maxWidth: '100%',\n minWidth: `${triggerMinWidthLimit}px`,\n }}\n >\n {svgIcon && (\n <>\n {typeof svgIcon === 'string' ? (\n <LazyIcon {...leftIconProps} iconName={svgIcon} />\n ) : (\n <Icon {...leftIconProps} svgIcon={svgIcon} />\n )}\n </>\n )}\n <span id={toggleTextId} className={styles.dropdown__toggle__text}>\n {triggerText}\n </span>\n <Icon\n svgIcon={!isSingleSelect ? PlusSmall : isOpen ? ChevronUp : ChevronDown}\n className={styles['dropdown__right-icon']}\n isHovered={!disabled && isHovered}\n size={IconSize.XSmall}\n />\n </button>\n <div\n key={dropdownMinWidth ?? 'auto'}\n id={contentId}\n className={contentClasses}\n ref={refs.setFloating}\n style={{\n ...floatingStyles,\n zIndex: zIndex,\n }}\n >\n <ul className={styles.dropdown__options} role=\"group\" aria-labelledby={toggleTextId} tabIndex={-1} ref={optionsRef}>\n {isSingleSelect && <SingleSelect onValueChange={() => handleClose()}>{renderChildren}</SingleSelect>}\n {isMultiSelect && renderChildren}\n </ul>\n {!isSingleSelect && !noCloseButton && (\n <div className={styles.dropdown__close}>\n <Button onClick={handleClose}>{mergedResources.closeText}</Button>\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport interface DropdownCompound extends React.FC<DropdownProps> {\n SingleSelectItem: ComponentType<SingleSelectItemProps>;\n}\nconst Dropdown = DropdownBase as DropdownCompound;\nDropdown.SingleSelectItem = SingleSelectItem;\nDropdownBase.displayName = 'Dropdown';\n\nexport default Dropdown;\n"],"names":["React"],"mappings":"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"}
@@ -42,7 +42,7 @@ export interface PanelProps {
42
42
  /** Sets classes on the outermost container of the panel */
43
43
  className?: string;
44
44
  /** Action called when toggling expansion of ExpandedContent */
45
- onExpand?: () => void;
45
+ onExpand?: (isExpanded?: boolean) => void;
46
46
  /** Sets the stacking order of the content boxes */
47
47
  stacking?: PanelStacking;
48
48
  /** Sets the data-testid attribute. */
package/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export { useBreakpoint, Breakpoint } from './hooks/useBreakpoint';
3
3
  export { useFocusToggle } from './hooks/useFocusToggle';
4
4
  export { useFocusTrap } from './hooks/useFocusTrap';
5
5
  export { useHover } from './hooks/useHover';
6
+ export { usePseudoClasses } from './hooks/usePseudoClasses';
6
7
  export { useIntersectionObserver } from './hooks/useIntersectionObserver';
7
8
  export { useIsVisible } from './hooks/useIsVisible';
8
9
  export { useLayoutEvent } from './hooks/useLayoutEvent';
package/index.js CHANGED
@@ -3,6 +3,7 @@ import { Breakpoint, useBreakpoint } from "./hooks/useBreakpoint.js";
3
3
  import { useFocusToggle } from "./hooks/useFocusToggle.js";
4
4
  import { useFocusTrap } from "./hooks/useFocusTrap.js";
5
5
  import { useHover } from "./hooks/useHover.js";
6
+ import { usePseudoClasses } from "./hooks/usePseudoClasses.js";
6
7
  import { useIntersectionObserver } from "./hooks/useIntersectionObserver.js";
7
8
  import { useIsVisible } from "./hooks/useIsVisible.js";
8
9
  import { useLayoutEvent } from "./hooks/useLayoutEvent.js";
@@ -38,6 +39,7 @@ export {
38
39
  useLayoutEvent,
39
40
  useOutsideEvent,
40
41
  usePrevious,
42
+ usePseudoClasses,
41
43
  useResizeObserver,
42
44
  useSize,
43
45
  useToggle,
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "url": "git+https://github.com/helsenorge/designsystem.git"
8
8
  },
9
9
  "homepage": "https://helsenorge.design",
10
- "version": "12.8.0",
10
+ "version": "12.9.0",
11
11
  "author": "Helsenorge",
12
12
  "license": "MIT",
13
13
  "dependencies": {