@helsenorge/designsystem-react 12.7.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/AsChildSlot.js +74 -0
- package/AsChildSlot.js.map +1 -0
- package/CHANGELOG.md +48 -5
- package/Drawer.js +58 -4
- package/Drawer.js.map +1 -1
- package/HN.Designsystem.Dropdown.nb-NO.js +13 -0
- package/HN.Designsystem.Dropdown.nb-NO.js.map +1 -0
- package/HelpDetails.js +1 -1
- package/LinkList.js +1 -0
- package/LinkList.js.map +1 -1
- package/Panel.js +0 -1
- package/Panel.js.map +1 -1
- package/SingleSelectItem.js +96 -0
- package/SingleSelectItem.js.map +1 -0
- package/clamp.js +11 -0
- package/clamp.js.map +1 -0
- package/components/ArticleTeaser/styles.module.scss +3 -5
- package/components/AsChildSlot/AsChildSlot.d.ts +23 -0
- package/components/AsChildSlot/AsChildSlot.test.d.ts +1 -0
- package/components/AsChildSlot/index.d.ts +3 -0
- package/components/AsChildSlot/index.js +6 -0
- package/components/AsChildSlot/index.js.map +1 -0
- package/components/AsChildSlot/styles.module.scss +13 -0
- package/components/AsChildSlot/styles.module.scss.d.ts +9 -0
- package/components/Drawer/styles.module.scss +45 -26
- package/components/Drawer/styles.module.scss.d.ts +5 -0
- package/components/Dropdown/Dropdown.d.ts +19 -21
- package/components/Dropdown/Dropdown.test.d.ts +1 -0
- package/components/Dropdown/SingleSelect/SingleSelect.d.ts +18 -0
- package/components/Dropdown/SingleSelect/SingleSelect.test.d.ts +1 -0
- package/components/Dropdown/SingleSelect/SingleSelectItem.d.ts +21 -0
- package/components/Dropdown/SingleSelect/index.d.ts +3 -0
- package/components/Dropdown/SingleSelect/index.js +6 -0
- package/components/Dropdown/SingleSelect/index.js.map +1 -0
- package/components/Dropdown/SingleSelect/styles.module.scss +54 -0
- package/components/Dropdown/SingleSelect/styles.module.scss.d.ts +14 -0
- package/components/Dropdown/index.js +143 -78
- package/components/Dropdown/index.js.map +1 -1
- package/components/Dropdown/styles.module.scss +90 -136
- package/components/Dropdown/styles.module.scss.d.ts +8 -9
- package/components/DropdownOld/DropdownOld.d.ts +42 -0
- package/components/DropdownOld/index.d.ts +3 -0
- package/components/DropdownOld/index.js +194 -0
- package/components/DropdownOld/index.js.map +1 -0
- package/components/DropdownOld/resourceHelper.d.ts +3 -0
- package/components/DropdownOld/styles.module.scss +230 -0
- package/components/DropdownOld/styles.module.scss.d.ts +25 -0
- package/components/Icons/EmoticonAnnoyed.js +8 -11
- package/components/Icons/EmoticonAnnoyed.js.map +1 -1
- package/components/Icons/EmoticonDelighted.js +8 -4
- package/components/Icons/EmoticonDelighted.js.map +1 -1
- package/components/Icons/EmoticonDisappointed.js +8 -4
- package/components/Icons/EmoticonDisappointed.js.map +1 -1
- package/components/Icons/EmoticonHappy.js +8 -4
- package/components/Icons/EmoticonHappy.js.map +1 -1
- package/components/Icons/EmoticonMeh.js +8 -4
- package/components/Icons/EmoticonMeh.js.map +1 -1
- package/components/LinkList/styles.module.scss +47 -61
- package/components/LinkList/styles.module.scss.d.ts +1 -0
- package/components/ListEditMode/styles.module.scss +1 -0
- package/components/NotificationPanel/index.js +3 -1
- package/components/NotificationPanel/index.js.map +1 -1
- package/components/NotificationPanel/styles.module.scss +10 -5
- package/components/Panel/Panel.d.ts +1 -1
- package/designsystem-react.css +10 -0
- package/index.d.ts +1 -0
- package/index.js +2 -0
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/scss/supernova/styles/colors.css +10 -0
- package/use-animate.js +1 -7
- package/use-animate.js.map +1 -1
- /package/{resources/index.d.ts → components/DropdownOld/DropdownOld.test.d.ts} +0 -0
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":"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"}
|
|
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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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import React__default, { useId } from "react";
|
|
3
|
+
import classNames from "classnames";
|
|
4
|
+
import { A as AsChildSlot } from "./AsChildSlot.js";
|
|
5
|
+
import styles from "./components/Dropdown/SingleSelect/styles.module.scss";
|
|
6
|
+
const SingleSelectContext = React__default.createContext(null);
|
|
7
|
+
const SingleSelect = ({ name, disabled, defaultValue, onValueChange, children }) => {
|
|
8
|
+
const [selected, setSelected] = React__default.useState(defaultValue);
|
|
9
|
+
const context = React__default.useMemo(
|
|
10
|
+
() => ({
|
|
11
|
+
name,
|
|
12
|
+
disabled,
|
|
13
|
+
value: selected,
|
|
14
|
+
onValueChange: (v, e) => {
|
|
15
|
+
setSelected(v);
|
|
16
|
+
onValueChange == null ? void 0 : onValueChange(v, e);
|
|
17
|
+
}
|
|
18
|
+
}),
|
|
19
|
+
[name, disabled, selected, onValueChange]
|
|
20
|
+
);
|
|
21
|
+
return /* @__PURE__ */ jsx(SingleSelectContext.Provider, { value: context, children });
|
|
22
|
+
};
|
|
23
|
+
const useSingleSelect = () => React__default.useContext(SingleSelectContext);
|
|
24
|
+
const SingleSelectItem = React__default.forwardRef((props, ref) => {
|
|
25
|
+
const { text, value, testId, asChild = false, children, disabled, defaultSelected, ...rest } = props;
|
|
26
|
+
const generatedId = useId();
|
|
27
|
+
const inputId = props.inputId ?? generatedId;
|
|
28
|
+
const group = useSingleSelect();
|
|
29
|
+
const optionValue = typeof value === "string" && value.length > 0 ? value : inputId;
|
|
30
|
+
const isSelected = group ? group.value === optionValue : false;
|
|
31
|
+
const isDisabled = !!disabled || !!(group == null ? void 0 : group.disabled);
|
|
32
|
+
const asChildSlotRef = React__default.useRef(null);
|
|
33
|
+
React__default.useEffect(() => {
|
|
34
|
+
var _a;
|
|
35
|
+
if (defaultSelected && group && typeof group.value === "undefined") {
|
|
36
|
+
(_a = group.onValueChange) == null ? void 0 : _a.call(group, optionValue);
|
|
37
|
+
}
|
|
38
|
+
}, [defaultSelected, group, optionValue]);
|
|
39
|
+
const contentClasses = classNames(styles["single-select-item__content"], {
|
|
40
|
+
[styles["single-select-item__content--disabled"]]: isDisabled
|
|
41
|
+
});
|
|
42
|
+
const dotClasses = classNames(styles["single-select-item__dot"], {
|
|
43
|
+
[styles["single-select-item__dot--disabled"]]: isDisabled,
|
|
44
|
+
[styles["single-select-item__dot--checked"]]: isSelected
|
|
45
|
+
});
|
|
46
|
+
const childArray = React__default.Children.toArray(children).filter(React__default.isValidElement);
|
|
47
|
+
const childElement = childArray[0] ?? null;
|
|
48
|
+
const selectThis = (e) => {
|
|
49
|
+
var _a;
|
|
50
|
+
if (isDisabled) return;
|
|
51
|
+
if (group && group.value !== optionValue) {
|
|
52
|
+
(_a = group.onValueChange) == null ? void 0 : _a.call(group, optionValue, e);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
56
|
+
/* @__PURE__ */ jsx("span", { className: dotClasses, "aria-hidden": true }),
|
|
57
|
+
/* @__PURE__ */ jsx("span", { children: text })
|
|
58
|
+
] });
|
|
59
|
+
const Component = asChild ? AsChildSlot : "button";
|
|
60
|
+
const componentProps = asChild ? {
|
|
61
|
+
ref: asChildSlotRef,
|
|
62
|
+
elementRef: ref,
|
|
63
|
+
className: contentClasses,
|
|
64
|
+
disabled: isDisabled,
|
|
65
|
+
onSelect: (e) => selectThis(e),
|
|
66
|
+
ariaCurrent: isSelected ? "true" : void 0,
|
|
67
|
+
children: childElement,
|
|
68
|
+
content
|
|
69
|
+
} : {
|
|
70
|
+
...rest,
|
|
71
|
+
type: "button",
|
|
72
|
+
className: contentClasses,
|
|
73
|
+
disabled: isDisabled,
|
|
74
|
+
onClick: (e) => {
|
|
75
|
+
e.preventDefault();
|
|
76
|
+
selectThis(e);
|
|
77
|
+
},
|
|
78
|
+
onKeyDown: (e) => {
|
|
79
|
+
if (e.key === "Enter") {
|
|
80
|
+
e.preventDefault();
|
|
81
|
+
selectThis(e);
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
ref,
|
|
85
|
+
"aria-disabled": isDisabled || void 0,
|
|
86
|
+
"aria-current": isSelected ? "true" : void 0,
|
|
87
|
+
children: content
|
|
88
|
+
};
|
|
89
|
+
return /* @__PURE__ */ jsx("div", { "data-testid": testId, className: styles["single-select-item"], children: /* @__PURE__ */ jsx(Component, { ...componentProps }) });
|
|
90
|
+
});
|
|
91
|
+
SingleSelectItem.displayName = "Dropdown.SingleSelectItem";
|
|
92
|
+
export {
|
|
93
|
+
SingleSelectItem as S,
|
|
94
|
+
SingleSelect as a
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=SingleSelectItem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SingleSelectItem.js","sources":["../src/components/Dropdown/SingleSelect/SingleSelect.tsx","../src/components/Dropdown/SingleSelect/SingleSelectItem.tsx"],"sourcesContent":["import React from 'react';\n\ntype SingleSelectContextType = {\n name?: string;\n disabled?: boolean;\n required?: boolean;\n value?: string;\n onValueChange?: (newValue: string, e?: React.SyntheticEvent) => void;\n};\n\nconst SingleSelectContext = React.createContext<SingleSelectContextType | null>(null);\n\nexport interface SingleSelectProps {\n name?: string;\n disabled?: boolean;\n defaultValue?: string;\n onValueChange?: (newValue: string, e?: React.SyntheticEvent) => void;\n children: React.ReactNode;\n}\n\nexport const SingleSelect: React.FC<SingleSelectProps> = ({ name, disabled, defaultValue, onValueChange, children }) => {\n const [selected, setSelected] = React.useState<string | undefined>(defaultValue);\n\n const context = React.useMemo<SingleSelectContextType>(\n () => ({\n name,\n disabled,\n value: selected,\n onValueChange: (v, e): void => {\n setSelected(v);\n onValueChange?.(v, e);\n },\n }),\n [name, disabled, selected, onValueChange]\n );\n\n return <SingleSelectContext.Provider value={context}>{children}</SingleSelectContext.Provider>;\n};\n\nexport const useSingleSelect = (): SingleSelectContextType | null => React.useContext(SingleSelectContext);\n","import React, { useId } from 'react';\n\nimport classNames from 'classnames';\n\nimport { useSingleSelect } from './SingleSelect';\nimport AsChildSlot, { AsChildSlotHandle } from '../../AsChildSlot';\n\nimport styles from './styles.module.scss';\n\nexport interface SingleSelectItemProps extends Pick<React.ButtonHTMLAttributes<HTMLButtonElement>, 'disabled'> {\n /** The text to the singleSelectItem */\n text?: string;\n /** input id of the singleSelectItem */\n inputId?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** When true, onclick and keyboard events will be passed to the child Button or AnchorLink. */\n asChild?: boolean;\n /** Only use when asChild is set to true and only pass one child */\n children?: React.ReactNode;\n /** Value for this singleSelectItem option - used by the parent wrapper to keep track of the context */\n value?: string;\n /** aria-describedby passthrough if needed */\n ['aria-describedby']?: string;\n /** Marks this option as initially selected */\n defaultSelected?: boolean;\n}\n\nexport const SingleSelectItem = React.forwardRef((props: SingleSelectItemProps, ref: React.Ref<HTMLElement>) => {\n const { text, value, testId, asChild = false, children, disabled, defaultSelected, ...rest } = props;\n\n const generatedId = useId();\n const inputId = props.inputId ?? generatedId;\n const group = useSingleSelect();\n const optionValue = typeof value === 'string' && value.length > 0 ? value : inputId;\n const isSelected = group ? group.value === optionValue : false;\n const isDisabled = !!disabled || !!group?.disabled;\n const asChildSlotRef = React.useRef<AsChildSlotHandle | null>(null);\n\n React.useEffect(() => {\n if (defaultSelected && group && typeof group.value === 'undefined') {\n group.onValueChange?.(optionValue);\n }\n }, [defaultSelected, group, optionValue]);\n\n const contentClasses = classNames(styles['single-select-item__content'], {\n [styles['single-select-item__content--disabled']]: isDisabled,\n });\n const dotClasses = classNames(styles['single-select-item__dot'], {\n [styles['single-select-item__dot--disabled']]: isDisabled,\n [styles['single-select-item__dot--checked']]: isSelected,\n });\n\n const childArray = React.Children.toArray(children).filter(React.isValidElement) as React.ReactElement[];\n const childElement = childArray[0] ?? null;\n\n const selectThis = (e?: React.SyntheticEvent): void => {\n if (isDisabled) return;\n if (group && group.value !== optionValue) {\n group.onValueChange?.(optionValue, e);\n }\n };\n\n const content = (\n <>\n <span className={dotClasses} aria-hidden />\n <span>{text}</span>\n </>\n );\n\n const Component = (asChild ? AsChildSlot : 'button') as React.ElementType;\n\n const componentProps = asChild\n ? {\n ref: asChildSlotRef,\n elementRef: ref as React.Ref<HTMLElement>,\n className: contentClasses,\n disabled: isDisabled,\n onSelect: (e: React.SyntheticEvent): void => selectThis(e),\n ariaCurrent: isSelected ? 'true' : undefined,\n children: childElement,\n content,\n }\n : {\n ...rest,\n type: 'button' as const,\n className: contentClasses,\n disabled: isDisabled,\n onClick: (e: React.MouseEvent<HTMLButtonElement>): void => {\n e.preventDefault();\n selectThis(e);\n },\n onKeyDown: (e: React.KeyboardEvent<HTMLButtonElement>): void => {\n if (e.key === 'Enter') {\n e.preventDefault();\n selectThis(e);\n }\n },\n ref: ref as React.Ref<HTMLButtonElement>,\n 'aria-disabled': isDisabled || undefined,\n 'aria-current': isSelected ? 'true' : undefined,\n children: content,\n };\n\n return (\n <div data-testid={testId} className={styles['single-select-item']}>\n <Component {...componentProps} />\n </div>\n );\n});\n\nSingleSelectItem.displayName = 'Dropdown.SingleSelectItem';\n\nexport default SingleSelectItem;\n"],"names":["React"],"mappings":"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"}
|
package/clamp.js
ADDED
package/clamp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clamp.js","sources":["../../../node_modules/motion/dist/es/framer-motion/dist/es/utils/clamp.mjs"],"sourcesContent":["const clamp = (min, max, v) => {\n if (v > max)\n return max;\n if (v < min)\n return min;\n return v;\n};\n\nexport { clamp };\n"],"names":[],"mappings":"AAAK,MAAC,QAAQ,CAAC,KAAK,KAAK,MAAM;AAC3B,MAAI,IAAI;AACJ,WAAO;AACX,MAAI,IAAI;AACJ,WAAO;AACX,SAAO;AACX;","x_google_ignoreList":[0]}
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
&:active {
|
|
64
|
-
background-color: var(--
|
|
64
|
+
background-color: var(--color-action-background-onlight-active);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
&--expanded {
|
|
@@ -70,13 +70,11 @@
|
|
|
70
70
|
border: 1px solid var(--color-action-border-onlight);
|
|
71
71
|
|
|
72
72
|
&:hover {
|
|
73
|
-
|
|
74
|
-
background-color: var(--color-action-graphics-ondark-hover);
|
|
73
|
+
background-color: var(--color-action-background-like-transparent-but-opaque-onlight-hover);
|
|
75
74
|
}
|
|
76
75
|
|
|
77
76
|
&:active {
|
|
78
|
-
|
|
79
|
-
background-color: var(--color-action-graphics-ondark);
|
|
77
|
+
background-color: var(--color-action-background-like-transparent-but-opaque-onlight-hoverselected);
|
|
80
78
|
}
|
|
81
79
|
}
|
|
82
80
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export interface AsChildSlotHandle {
|
|
3
|
+
/** Click the child’s DOM node */
|
|
4
|
+
click: () => void;
|
|
5
|
+
}
|
|
6
|
+
export interface AsChildSlotProps {
|
|
7
|
+
/** Pass one element/component that we will map to a DOM element (<a>, <button>, React Router <Link>) */
|
|
8
|
+
children?: React.ReactNode;
|
|
9
|
+
/** Class names to apply to the visible element */
|
|
10
|
+
className?: string;
|
|
11
|
+
/** Content to render inside the visible element - For example the text and icons of the parent component that renders AsChildSlot */
|
|
12
|
+
content?: React.ReactNode;
|
|
13
|
+
/** Disabled state passed down (merged with child’s disabled/aria-disabled) */
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
/** Called before the child’s onClick when visible */
|
|
16
|
+
onSelect?: (e: React.SyntheticEvent) => void;
|
|
17
|
+
/** Optional states to apply to the DOM element */
|
|
18
|
+
ariaCurrent?: 'page' | 'true';
|
|
19
|
+
/** DOM ref for the element we end up rendering */
|
|
20
|
+
elementRef?: React.Ref<HTMLElement>;
|
|
21
|
+
}
|
|
22
|
+
export declare const AsChildSlot: React.ForwardRefExoticComponent<AsChildSlotProps & React.RefAttributes<AsChildSlotHandle>>;
|
|
23
|
+
export default AsChildSlot;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -5,23 +5,6 @@
|
|
|
5
5
|
@use '../../scss/breakpoints' as breakpoints;
|
|
6
6
|
@import '../../scss/supernova/styles/colors.css';
|
|
7
7
|
|
|
8
|
-
@mixin drawer-scroll-shadow {
|
|
9
|
-
// Scroll shadow
|
|
10
|
-
// Inspired by: https://css-tricks.com/books/greatest-css-tricks/scroll-shadows/
|
|
11
|
-
background:
|
|
12
|
-
linear-gradient(white 30%, rgb(255 255 255 / 0%)) center top,
|
|
13
|
-
linear-gradient(rgb(255 255 255 / 0%), white 70%) center bottom,
|
|
14
|
-
linear-gradient(rgb(0 0 0 / 46%), rgb(0 0 0 / 0%)) center top,
|
|
15
|
-
linear-gradient(rgb(0 0 0 / 0%), rgb(0 0 0 / 46%)) center bottom;
|
|
16
|
-
background-repeat: no-repeat;
|
|
17
|
-
background-size:
|
|
18
|
-
100% 40px,
|
|
19
|
-
100% 40px,
|
|
20
|
-
100% 16px,
|
|
21
|
-
100% 16px;
|
|
22
|
-
background-attachment: local, local, scroll, scroll;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
8
|
.drawer {
|
|
26
9
|
position: fixed;
|
|
27
10
|
inset: 0;
|
|
@@ -43,7 +26,6 @@
|
|
|
43
26
|
position: fixed;
|
|
44
27
|
width: 100%;
|
|
45
28
|
max-height: 90dvh;
|
|
46
|
-
overflow: hidden;
|
|
47
29
|
transform: translateY(100%);
|
|
48
30
|
background-color: var(--core-color-white);
|
|
49
31
|
border-radius: 0.75rem 0.75rem 0 0;
|
|
@@ -81,8 +63,6 @@
|
|
|
81
63
|
@include breakpoints.tiny-screens-media-query {
|
|
82
64
|
overflow-y: auto;
|
|
83
65
|
|
|
84
|
-
@include drawer-scroll-shadow;
|
|
85
|
-
|
|
86
66
|
&:focus-visible {
|
|
87
67
|
outline: 1px solid palette.$black;
|
|
88
68
|
outline-offset: -1px;
|
|
@@ -130,22 +110,61 @@
|
|
|
130
110
|
|
|
131
111
|
&__content {
|
|
132
112
|
overflow-y: auto;
|
|
133
|
-
padding: spacers.getSpacer(xs) spacers.getSpacer(2xs);
|
|
134
113
|
|
|
135
114
|
&:focus-visible {
|
|
136
115
|
outline: 1px solid palette.$black;
|
|
137
116
|
outline-offset: -1px;
|
|
138
117
|
}
|
|
139
118
|
|
|
140
|
-
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
141
|
-
padding: spacers.getSpacer(s) spacers.getSpacer(xs);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
119
|
@include breakpoints.tiny-screens-media-query {
|
|
145
120
|
overflow-y: unset;
|
|
146
121
|
}
|
|
147
122
|
|
|
148
|
-
|
|
123
|
+
&__children {
|
|
124
|
+
padding: spacers.getSpacer(xs) spacers.getSpacer(2xs);
|
|
125
|
+
|
|
126
|
+
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
127
|
+
padding: spacers.getSpacer(s) spacers.getSpacer(xs);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
&__shadow {
|
|
132
|
+
position: absolute;
|
|
133
|
+
z-index: 10;
|
|
134
|
+
height: 16px;
|
|
135
|
+
width: 100%;
|
|
136
|
+
transition: opacity 0.5s;
|
|
137
|
+
opacity: 0;
|
|
138
|
+
pointer-events: none;
|
|
139
|
+
|
|
140
|
+
@include breakpoints.tiny-screens-media-query {
|
|
141
|
+
display: none;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
&--top {
|
|
145
|
+
top: 0;
|
|
146
|
+
margin-bottom: calc(0rem - spacers.getSpacer(xs));
|
|
147
|
+
background: linear-gradient(0deg, rgb(0 0 0 / 0%) 0%, rgb(0 0 0 / 45.7%) 100%);
|
|
148
|
+
|
|
149
|
+
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
150
|
+
margin-bottom: calc(0rem - spacers.getSpacer(s));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
&--bottom {
|
|
155
|
+
bottom: 0;
|
|
156
|
+
background: linear-gradient(180deg, rgb(0 0 0 / 0%) 0%, rgb(0 0 0 / 45.7%) 100%);
|
|
157
|
+
margin-top: calc(0rem - spacers.getSpacer(xs));
|
|
158
|
+
|
|
159
|
+
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
160
|
+
margin-top: calc(0rem - spacers.getSpacer(s));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
&--show {
|
|
165
|
+
opacity: 1;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
149
168
|
}
|
|
150
169
|
|
|
151
170
|
&__footer {
|
|
@@ -4,6 +4,11 @@ export type Styles = {
|
|
|
4
4
|
drawer__container__inner: string;
|
|
5
5
|
'drawer__container--right': string;
|
|
6
6
|
drawer__content: string;
|
|
7
|
+
drawer__content__children: string;
|
|
8
|
+
drawer__content__shadow: string;
|
|
9
|
+
'drawer__content__shadow--bottom': string;
|
|
10
|
+
'drawer__content__shadow--show': string;
|
|
11
|
+
'drawer__content__shadow--top': string;
|
|
7
12
|
drawer__footer: string;
|
|
8
13
|
drawer__header: string;
|
|
9
14
|
'drawer__header__close-button': string;
|
|
@@ -1,34 +1,24 @@
|
|
|
1
|
-
import { default as React } from 'react';
|
|
1
|
+
import { default as React, ComponentType } from 'react';
|
|
2
|
+
import { SingleSelectItemProps } from './SingleSelect/SingleSelectItem';
|
|
2
3
|
import { HNDesignsystemDropdown } from '../../resources/Resources';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
onblueberry = "onblueberry",
|
|
7
|
-
oncherry = "oncherry"
|
|
8
|
-
}
|
|
4
|
+
import { SvgIcon } from '../Icon';
|
|
5
|
+
import { IconName } from '../Icons/IconNames';
|
|
6
|
+
type DropdownVariants = 'fill' | 'transparent' | 'borderless';
|
|
9
7
|
export interface DropdownProps {
|
|
10
|
-
/** Label for dropdown. Visible for screen readers */
|
|
11
|
-
label: string;
|
|
12
8
|
/** Text on the trigger button that opens the dropdown */
|
|
13
|
-
|
|
9
|
+
triggerText: string;
|
|
14
10
|
/** Sets the dropdown content */
|
|
15
11
|
children: React.ReactNode;
|
|
16
|
-
/**
|
|
17
|
-
closeText?: string;
|
|
18
|
-
/** Minimum width for the dropdown in pixels. Does not affect trigger button */
|
|
12
|
+
/** Minimum width for the dropdown in pixels. Does not affect trigger button. */
|
|
19
13
|
dropdownMinWidth?: number;
|
|
20
|
-
/**
|
|
14
|
+
/** Minimum width for the trigger in pixels. Does not apply for borderless variant */
|
|
15
|
+
triggerMinWidth?: number;
|
|
16
|
+
/** Disables rendring of the close button in the list */
|
|
21
17
|
noCloseButton?: boolean;
|
|
22
18
|
/** Called when dropdown is open/closed */
|
|
23
19
|
onToggle?: (isOpen: boolean) => void;
|
|
24
20
|
/** Whether the dropdown is open or not */
|
|
25
21
|
open?: boolean;
|
|
26
|
-
/** Changes the visuals of the dropdown */
|
|
27
|
-
onColor?: keyof typeof DropdownOnColor;
|
|
28
|
-
/** Makes the background of the trigger transparent */
|
|
29
|
-
transparent?: boolean;
|
|
30
|
-
/** Makes the width of the full component adjust to its parent */
|
|
31
|
-
fluid?: boolean;
|
|
32
22
|
/** Makes the dropdown disabled */
|
|
33
23
|
disabled?: boolean;
|
|
34
24
|
/** Sets the data-testid attribute on the dropdown button */
|
|
@@ -37,6 +27,14 @@ export interface DropdownProps {
|
|
|
37
27
|
zIndex?: number;
|
|
38
28
|
/** Resources for component */
|
|
39
29
|
resources?: Partial<HNDesignsystemDropdown>;
|
|
30
|
+
/** Adds an icon to the trigger */
|
|
31
|
+
svgIcon?: SvgIcon | IconName;
|
|
32
|
+
/** Sets the visual variant of the Dropdown */
|
|
33
|
+
variant?: DropdownVariants;
|
|
34
|
+
}
|
|
35
|
+
export declare const DropdownBase: React.FC<DropdownProps>;
|
|
36
|
+
export interface DropdownCompound extends React.FC<DropdownProps> {
|
|
37
|
+
SingleSelectItem: ComponentType<SingleSelectItemProps>;
|
|
40
38
|
}
|
|
41
|
-
declare const Dropdown:
|
|
39
|
+
declare const Dropdown: DropdownCompound;
|
|
42
40
|
export default Dropdown;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
type SingleSelectContextType = {
|
|
3
|
+
name?: string;
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
required?: boolean;
|
|
6
|
+
value?: string;
|
|
7
|
+
onValueChange?: (newValue: string, e?: React.SyntheticEvent) => void;
|
|
8
|
+
};
|
|
9
|
+
export interface SingleSelectProps {
|
|
10
|
+
name?: string;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
defaultValue?: string;
|
|
13
|
+
onValueChange?: (newValue: string, e?: React.SyntheticEvent) => void;
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
}
|
|
16
|
+
export declare const SingleSelect: React.FC<SingleSelectProps>;
|
|
17
|
+
export declare const useSingleSelect: () => SingleSelectContextType | null;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export interface SingleSelectItemProps extends Pick<React.ButtonHTMLAttributes<HTMLButtonElement>, 'disabled'> {
|
|
3
|
+
/** The text to the singleSelectItem */
|
|
4
|
+
text?: string;
|
|
5
|
+
/** input id of the singleSelectItem */
|
|
6
|
+
inputId?: string;
|
|
7
|
+
/** Sets the data-testid attribute. */
|
|
8
|
+
testId?: string;
|
|
9
|
+
/** When true, onclick and keyboard events will be passed to the child Button or AnchorLink. */
|
|
10
|
+
asChild?: boolean;
|
|
11
|
+
/** Only use when asChild is set to true and only pass one child */
|
|
12
|
+
children?: React.ReactNode;
|
|
13
|
+
/** Value for this singleSelectItem option - used by the parent wrapper to keep track of the context */
|
|
14
|
+
value?: string;
|
|
15
|
+
/** aria-describedby passthrough if needed */
|
|
16
|
+
['aria-describedby']?: string;
|
|
17
|
+
/** Marks this option as initially selected */
|
|
18
|
+
defaultSelected?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare const SingleSelectItem: React.ForwardRefExoticComponent<SingleSelectItemProps & React.RefAttributes<HTMLElement>>;
|
|
21
|
+
export default SingleSelectItem;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
@use 'sass:meta';
|
|
3
|
+
@use 'sass:string';
|
|
4
|
+
@import '../../../scss/supernova/styles/colors.css';
|
|
5
|
+
@import '../../../scss/supernova/styles/spacers.css';
|
|
6
|
+
|
|
7
|
+
.single-select-item {
|
|
8
|
+
cursor: pointer;
|
|
9
|
+
|
|
10
|
+
:focus-visible {
|
|
11
|
+
outline: none;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
&__content {
|
|
15
|
+
all: unset;
|
|
16
|
+
width: 100%;
|
|
17
|
+
box-sizing: border-box;
|
|
18
|
+
display: flex;
|
|
19
|
+
align-items: baseline;
|
|
20
|
+
cursor: pointer;
|
|
21
|
+
padding: var(--core-space-2xs) 0 var(--core-space-2xs) var(--core-space-s);
|
|
22
|
+
line-height: 1.75rem;
|
|
23
|
+
|
|
24
|
+
&--disabled {
|
|
25
|
+
cursor: default;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&__dot {
|
|
30
|
+
appearance: none;
|
|
31
|
+
cursor: pointer;
|
|
32
|
+
display: flex;
|
|
33
|
+
justify-content: center;
|
|
34
|
+
align-items: center;
|
|
35
|
+
margin: 0 0.667rem 0 0;
|
|
36
|
+
background-color: transparent;
|
|
37
|
+
min-width: 0.67rem;
|
|
38
|
+
min-height: 0.67rem;
|
|
39
|
+
border-radius: 10rem;
|
|
40
|
+
outline: none;
|
|
41
|
+
|
|
42
|
+
&:checked {
|
|
43
|
+
background-color: var(--core-color-black);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&--checked {
|
|
47
|
+
background-color: var(--core-color-black);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
&--disabled {
|
|
51
|
+
cursor: default;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type Styles = {
|
|
2
|
+
'single-select-item': string;
|
|
3
|
+
'single-select-item__content': string;
|
|
4
|
+
'single-select-item__content--disabled': string;
|
|
5
|
+
'single-select-item__dot': string;
|
|
6
|
+
'single-select-item__dot--checked': string;
|
|
7
|
+
'single-select-item__dot--disabled': string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type ClassNames = keyof Styles;
|
|
11
|
+
|
|
12
|
+
declare const styles: Styles;
|
|
13
|
+
|
|
14
|
+
export default styles;
|