@danske/sapphire-react-lab 0.106.1 → 0.106.3
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/build/cjs/index.js +133 -111
- package/build/cjs/index.js.map +1 -1
- package/build/esm/Accordion/src/Accordion.js +3 -2
- package/build/esm/Accordion/src/Accordion.js.map +1 -1
- package/build/esm/Accordion/src/AccordionHeading.js +1 -1
- package/build/esm/Accordion/src/AccordionHeading.js.map +1 -1
- package/build/esm/Accordion/src/AccordionItem.js +3 -2
- package/build/esm/Accordion/src/AccordionItem.js.map +1 -1
- package/build/esm/Accordion/src/AccordionPanel.js +1 -1
- package/build/esm/Accordion/src/AccordionPanel.js.map +1 -1
- package/build/esm/Alert/src/Alert.js +1 -1
- package/build/esm/Alert/src/Alert.js.map +1 -1
- package/build/esm/Amount/src/Amount.js +1 -1
- package/build/esm/Amount/src/Amount.js.map +1 -1
- package/build/esm/Autocomplete/src/Autocomplete.js +8 -2
- package/build/esm/Autocomplete/src/Autocomplete.js.map +1 -1
- package/build/esm/Breadcrumbs/src/BreadcrumbItem.js +2 -1
- package/build/esm/Breadcrumbs/src/BreadcrumbItem.js.map +1 -1
- package/build/esm/Breadcrumbs/src/BreadcrumbItemStatic.js +1 -1
- package/build/esm/Breadcrumbs/src/BreadcrumbItemStatic.js.map +1 -1
- package/build/esm/Breadcrumbs/src/Breadcrumbs.js +5 -3
- package/build/esm/Breadcrumbs/src/Breadcrumbs.js.map +1 -1
- package/build/esm/Breadcrumbs/src/useBreadcrumbThreshold.js +1 -1
- package/build/esm/Breadcrumbs/src/useBreadcrumbThreshold.js.map +1 -1
- package/build/esm/FileDropzone/src/FileDropzone.js +9 -4
- package/build/esm/FileDropzone/src/FileDropzone.js.map +1 -1
- package/build/esm/FileDropzone/src/FileTrigger.js +3 -2
- package/build/esm/FileDropzone/src/FileTrigger.js.map +1 -1
- package/build/esm/Filtering/src/FilterDropdown.js +4 -4
- package/build/esm/Filtering/src/FilterDropdown.js.map +1 -1
- package/build/esm/Filtering/src/SearchableSelectFilter.js +15 -12
- package/build/esm/Filtering/src/SearchableSelectFilter.js.map +1 -1
- package/build/esm/LabeledValue/src/LabeledValue.js +2 -2
- package/build/esm/LabeledValue/src/LabeledValue.js.map +1 -1
- package/build/esm/NumberField/src/NumberField.js +5 -3
- package/build/esm/NumberField/src/NumberField.js.map +1 -1
- package/build/esm/NumberField/src/StepperButton.js +4 -3
- package/build/esm/NumberField/src/StepperButton.js.map +1 -1
- package/build/esm/NumberField/src/useSapphireNumberField.js +3 -3
- package/build/esm/NumberField/src/useSapphireNumberField.js.map +1 -1
- package/build/esm/ProgressIndicator/src/ProgressIndicator.js +2 -2
- package/build/esm/ProgressIndicator/src/ProgressIndicator.js.map +1 -1
- package/build/esm/Sidebar/src/Body.js +1 -1
- package/build/esm/Sidebar/src/Body.js.map +1 -1
- package/build/esm/Sidebar/src/ExpandableItem.js +3 -2
- package/build/esm/Sidebar/src/ExpandableItem.js.map +1 -1
- package/build/esm/Sidebar/src/Header.js +1 -1
- package/build/esm/Sidebar/src/Header.js.map +1 -1
- package/build/esm/Sidebar/src/Item.js +1 -1
- package/build/esm/Sidebar/src/Item.js.map +1 -1
- package/build/esm/Sidebar/src/List.js +1 -1
- package/build/esm/Sidebar/src/List.js.map +1 -1
- package/build/esm/Sidebar/src/ResponsiveSidebarContext.js +1 -1
- package/build/esm/Sidebar/src/ResponsiveSidebarContext.js.map +1 -1
- package/build/esm/Sidebar/src/SecondarySidebarContext.js +1 -1
- package/build/esm/Sidebar/src/SecondarySidebarContext.js.map +1 -1
- package/build/esm/Sidebar/src/Section.js +2 -2
- package/build/esm/Sidebar/src/Section.js.map +1 -1
- package/build/esm/Sidebar/src/Sidebar.js +3 -2
- package/build/esm/Sidebar/src/Sidebar.js.map +1 -1
- package/build/esm/TagGroup/src/Tag.js +6 -5
- package/build/esm/TagGroup/src/Tag.js.map +1 -1
- package/build/esm/TagGroup/src/TagGroup.js +2 -2
- package/build/esm/TagGroup/src/TagGroup.js.map +1 -1
- package/build/esm/TagGroup/src/TagItem.js +1 -1
- package/build/esm/TagGroup/src/TagItem.js.map +1 -1
- package/build/esm/TimeField/src/TimeField.js +5 -4
- package/build/esm/TimeField/src/TimeField.js.map +1 -1
- package/build/esm/TimeField/src/TimeFieldSegment.js +1 -1
- package/build/esm/TimeField/src/TimeFieldSegment.js.map +1 -1
- package/build/esm/index.js +1 -1
- package/build/index.d.ts +7 -6
- package/package.json +13 -38
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterDropdown.js","sources":["../../../../src/Filtering/src/FilterDropdown.tsx"],"sourcesContent":["import React, { useRef, ReactNode, FormEvent } from 'react';\nimport clsx from 'clsx';\nimport { VisuallyHidden } from '
|
|
1
|
+
{"version":3,"file":"FilterDropdown.js","sources":["../../../../src/Filtering/src/FilterDropdown.tsx"],"sourcesContent":["import React, { useRef, ReactNode, FormEvent } from 'react';\nimport clsx from 'clsx';\nimport { VisuallyHidden } from 'react-aria/VisuallyHidden';\nimport { useEffectEvent } from 'react-aria/private/utils/useEffectEvent';\nimport { filterDOMProps } from 'react-aria/filterDOMProps';\nimport { useControlledState } from 'react-stately/useControlledState';\nimport {\n Button,\n ButtonGroup,\n PopoverTrigger,\n PopoverTriggerProps,\n SapphireStyleProps,\n ToggleButton,\n GlobalDomAttributes,\n useSapphireStyleProps,\n} from '@danske/sapphire-react';\nimport { ChevronDown, ChevronUp } from '@danske/sapphire-icons/react';\nimport { FocusableRefValue } from '@react-types/shared';\nimport styles from '@danske/sapphire-css/components/filterDropdown/filterDropdown.module.css';\n\nexport interface FilterDropdownProps\n extends GlobalDomAttributes,\n SapphireStyleProps,\n Pick<\n PopoverTriggerProps,\n 'defaultOpen' | 'isOpen' | 'onOpenChange' | 'noMaxWidth'\n > {\n /**\n * \"Filter by\" label, shown inside the trigger button.\n */\n label: ReactNode;\n /**\n * Filter value, shown inside the trigger button. `null`, `undefined` and empty string are\n * considered as unset value.\n */\n value: ReactNode;\n /**\n * Filtering UI controls, rendered in a popover.\n */\n children: ReactNode;\n /**\n * Called when:\n * - `Enter` is pressed on form fields rendered inside the popover.\n * - 'Apply' button is pressed (if `hasApplyButton` is true)\n */\n onApply?: () => void;\n /**\n * Whether to show the 'Apply' button.\n */\n hasApplyButton?: boolean;\n /**\n * Called when 'Clear' button is pressed.\n */\n onClear?: () => void;\n /**\n * Whether the button is disabled.\n */\n isDisabled?: boolean;\n /**\n * Whether the 'Apply' button is disabled.\n */\n isApplyDisabled?: boolean;\n /**\n * Whether the 'Clear' button is hidden.\n */\n hideClearButton?: boolean;\n /**\n * Whether the 'Clear' button is disabled.\n */\n isClearDisabled?: boolean;\n /**\n * The label of the 'Clear' button.\n * @default \"Clear\"\n */\n clearButtonLabel?: ReactNode;\n /**\n * The label of the 'Apply' button.\n * @default \"Apply\"\n */\n applyButtonLabel?: ReactNode;\n /**\n * The size of the buttons incl. the trigger itself.\n * @default 'md'\n */\n buttonSize?: 'sm' | 'md' | 'lg';\n}\n\n/**\n * A button with a dropdown, used for filtering UI.\n */\nexport function FilterDropdown({\n children,\n label,\n value,\n isDisabled = false,\n isApplyDisabled = false,\n isClearDisabled,\n isOpen: isOpenProp,\n applyButtonLabel = 'Apply',\n clearButtonLabel = 'Clear',\n hideClearButton = false,\n defaultOpen = false,\n hasApplyButton = false,\n noMaxWidth,\n onApply,\n onClear,\n onOpenChange,\n buttonSize = 'md',\n ...props\n}: FilterDropdownProps): JSX.Element {\n const triggerRef = useRef<FocusableRefValue>(null);\n const { styleProps } = useSapphireStyleProps(props);\n\n // We need to know if the dropdown is open or not, so we control the state here, still\n // allowing for both controlled and uncontrolled modes.\n const [isOpen, setIsOpen] = useControlledState(\n isOpenProp,\n defaultOpen,\n useEffectEvent(onOpenChange)\n );\n const hasValue = value != null && value !== '';\n const close = () => setIsOpen(false);\n const onSubmit = (e: FormEvent) => {\n e.preventDefault();\n onApply?.();\n close();\n };\n\n const applyButton = (\n <Button\n type=\"submit\"\n size={buttonSize}\n excludeFromTabOrder={!hasApplyButton}\n isDisabled={isApplyDisabled}\n >\n {applyButtonLabel}\n </Button>\n );\n\n return (\n <PopoverTrigger\n ref={triggerRef}\n placement=\"bottom left\"\n isOpen={isOpen}\n onOpenChange={setIsOpen}\n noMaxWidth={noMaxWidth}\n noPadding\n popoverContent={\n <form\n {...filterDOMProps(props, { global: true })}\n onSubmit={onSubmit}\n className={clsx(\n styles['sapphire-filter-dropdown'],\n styleProps.className\n )}\n style={{ ...styleProps.style }}\n >\n <div className={styles['sapphire-filter-dropdown__body']}>\n {children}\n </div>\n <div className={styles['sapphire-filter-dropdown__footer']}>\n <ButtonGroup align=\"right\">\n {!hideClearButton && (\n <Button\n size={buttonSize}\n variant=\"text\"\n onPress={() => {\n close();\n onClear?.();\n }}\n isDisabled={isClearDisabled ?? !hasValue}\n >\n {clearButtonLabel}\n </Button>\n )}\n {hasApplyButton ? (\n applyButton\n ) : (\n // The following is necessary to have the form submitted on \"Enter\", if there is more than one field\n <VisuallyHidden>{applyButton}</VisuallyHidden>\n )}\n </ButtonGroup>\n </div>\n </form>\n }\n >\n <ToggleButton\n icon={isOpen ? <ChevronUp /> : <ChevronDown />}\n iconAlign=\"right\"\n isSelected={hasValue}\n isDisabled={isDisabled}\n size={buttonSize}\n >\n {label}\n {value ? ': ' : ''}\n {value}\n </ToggleButton>\n </PopoverTrigger>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -4,31 +4,34 @@ import '../../Accordion/index.js';
|
|
|
4
4
|
import '@danske/sapphire-icons/react';
|
|
5
5
|
import '@danske/sapphire-css/components/alert/alert.module.css';
|
|
6
6
|
import 'clsx';
|
|
7
|
-
import
|
|
8
|
-
import '
|
|
7
|
+
import 'react-aria/filterDOMProps';
|
|
8
|
+
import 'react-aria/I18nProvider';
|
|
9
9
|
import '@danske/sapphire-css/components/amount/amount.module.css';
|
|
10
|
-
import '
|
|
10
|
+
import 'react-aria/useComboBox';
|
|
11
|
+
import '@react-aria/i18n';
|
|
11
12
|
import '@react-spectrum/utils';
|
|
12
13
|
import '../../Breadcrumbs/src/Breadcrumbs.js';
|
|
13
14
|
import '../../Breadcrumbs/src/BreadcrumbItem.js';
|
|
14
15
|
import '../../FileDropzone/src/FileDropzone.js';
|
|
15
16
|
import '../../FileDropzone/src/FileTrigger.js';
|
|
16
17
|
import { FilterDropdown } from './FilterDropdown.js';
|
|
17
|
-
import {
|
|
18
|
+
import { mergeRefs } from 'react-aria/mergeRefs';
|
|
19
|
+
import { useControlledState } from 'react-stately/useControlledState';
|
|
18
20
|
import '../../Flag/src/Flag.js';
|
|
19
|
-
import '
|
|
21
|
+
import 'react-aria/useField';
|
|
22
|
+
import 'react-aria/mergeProps';
|
|
20
23
|
import '../../NumberField/src/NumberField.js';
|
|
21
24
|
import '../../Sidebar/index.js';
|
|
22
25
|
import '@danske/sapphire-css/components/progressIndicator/progressIndicator.module.css';
|
|
23
|
-
import '
|
|
26
|
+
import 'react-aria/useProgressBar';
|
|
24
27
|
import '../../Slider/index.js';
|
|
25
|
-
import '
|
|
26
|
-
import '
|
|
28
|
+
import 'react-aria/useTagGroup';
|
|
29
|
+
import 'react-stately/useListState';
|
|
27
30
|
import '@danske/sapphire-css/components/tag/tag.module.css';
|
|
28
|
-
import '
|
|
29
|
-
import '
|
|
30
|
-
import '
|
|
31
|
-
import '
|
|
31
|
+
import 'react-aria/useButton';
|
|
32
|
+
import 'react-aria/useHover';
|
|
33
|
+
import 'react-aria/FocusRing';
|
|
34
|
+
import 'react-stately/Item';
|
|
32
35
|
import '../../TimeField/src/TimeField.js';
|
|
33
36
|
|
|
34
37
|
function SearchableSelectFilter(props) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchableSelectFilter.js","sources":["../../../../src/Filtering/src/SearchableSelectFilter.tsx"],"sourcesContent":["import React, { cloneElement, ReactElement, useRef } from 'react';\nimport {\n Flex,\n ListBoxProps,\n SapphireStyleProps,\n SearchFieldPropsWithRef,\n tokens,\n GlobalDomAttributes,\n} from '@danske/sapphire-react';\nimport { FilterDropdown, FilterDropdownProps } from '../..';\nimport { mergeRefs } from '
|
|
1
|
+
{"version":3,"file":"SearchableSelectFilter.js","sources":["../../../../src/Filtering/src/SearchableSelectFilter.tsx"],"sourcesContent":["import React, { cloneElement, ReactElement, useRef } from 'react';\nimport {\n Flex,\n ListBoxProps,\n SapphireStyleProps,\n SearchFieldPropsWithRef,\n tokens,\n GlobalDomAttributes,\n} from '@danske/sapphire-react';\nimport { FilterDropdown, FilterDropdownProps } from '../..';\nimport { mergeRefs } from 'react-aria/mergeRefs';\nimport { useControlledState } from 'react-stately/useControlledState';\n\nexport interface SearchableSelectFilterProps\n extends GlobalDomAttributes,\n SapphireStyleProps,\n Omit<FilterDropdownProps, 'children'> {\n /**\n * The SearchField to search items with.\n */\n searchField: ReactElement<SearchFieldPropsWithRef<object>>;\n /**\n * The ListBox to select items from.\n */\n listBox: ReactElement<ListBoxProps<object>>;\n /**\n * The Button size of the trigger\n * @default 'md'\n */\n size?: 'sm' | 'md' | 'lg';\n}\n\n/**\n * A button with a dropdown, used for filtering UI.\n */\nexport function SearchableSelectFilter(\n props: SearchableSelectFilterProps\n): JSX.Element {\n const { searchField, listBox, size = 'md', ...otherProps } = props;\n const searchFieldRef = useRef<HTMLInputElement>(null);\n\n const searchFieldProps = searchField.props;\n const listBoxProps = listBox.props;\n\n const [searchQuery, setSearchQuery] = useControlledState(\n searchFieldProps?.value,\n '',\n searchFieldProps.onChange\n );\n\n if (\n listBoxProps.connectedInputRef &&\n typeof process !== 'undefined' &&\n process.env?.NODE_ENV === 'development'\n ) {\n // eslint-disable-next-line no-console\n console.warn(\n 'The connectedInputRef prop on the ListBox in the SearchableSelectFilter component is not needed and will be ignored. The connectedInputRef is set automatically (to the passed SearchField) and should not be set manually.'\n );\n }\n\n const hasSelection =\n listBoxProps.selectedKeys === 'all' ||\n Array.from(listBoxProps.selectedKeys || []).length > 0;\n\n return (\n <FilterDropdown\n {...otherProps}\n noMaxWidth={otherProps.noMaxWidth ?? true}\n buttonSize={size}\n // Since useCollectionFocusProxy disables normal form submission behaviour on \"Enter\"\n // the apply button is the only way to submit, which is why we add it if an onApply function is passed\n hasApplyButton={Boolean(otherProps.onApply)}\n // In scenarios where selections are not applied immediately we want to allow cancelling\n // the filter selection via 'Clear' button as soon as at least 1 item is selected\n isClearDisabled={\n otherProps.isClearDisabled || (!hasSelection && !otherProps.value)\n }\n >\n <Flex flexDirection=\"column\" height=\"100%\">\n {cloneElement(searchField, {\n size: 'md',\n value: searchFieldProps.value || searchQuery,\n inputRef: mergeRefs(searchFieldRef, searchFieldProps.inputRef),\n width: searchFieldProps.width || '100%',\n marginBottom: searchFieldProps.marginBottom || tokens.size.spacingSm,\n onChange: setSearchQuery,\n })}\n {cloneElement(listBox, {\n connectedInputRef: searchFieldRef,\n selectionMode: listBoxProps.selectionMode || 'multiple',\n marginX: `calc(${tokens.size.spacingContainerHorizontalSm.value} * -1)`,\n hasScrollDividers: true,\n filter:\n // This is a way to also allow opting out of the internal filter with filter={undefined}\n // without us having to allow for more values on the ListBox filter prop\n 'filter' in listBoxProps\n ? listBoxProps.filter\n : (textValue: string) =>\n textValue.toLowerCase().includes(searchQuery.toLowerCase()),\n })}\n </Flex>\n </FilterDropdown>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCO,SAAS,uBACd,KAAA,EACa;AACb,EAAA,MAAM,EAAE,WAAA,EAAa,OAAA,EAAS,OAAO,IAAA,EAAM,GAAG,YAAW,GAAI,KAAA;AAC7D,EAAA,MAAM,cAAA,GAAiB,OAAyB,IAAI,CAAA;AAEpD,EAAA,MAAM,mBAAmB,WAAA,CAAY,KAAA;AACrC,EAAA,MAAM,eAAe,OAAA,CAAQ,KAAA;AAE7B,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,kBAAA;AAAA,IACpC,gBAAA,EAAkB,KAAA;AAAA,IAClB,EAAA;AAAA,IACA,gBAAA,CAAiB;AAAA,GACnB;AAEA,EAAA,IACE,YAAA,CAAa,qBACb,OAAO,OAAA,KAAY,eACnB,OAAA,CAAQ,GAAA,EAAK,aAAa,aAAA,EAC1B;AAEA,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,YAAA,GACJ,YAAA,CAAa,YAAA,KAAiB,KAAA,IAC9B,KAAA,CAAM,IAAA,CAAK,YAAA,CAAa,YAAA,IAAgB,EAAE,CAAA,CAAE,MAAA,GAAS,CAAA;AAEvD,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,cAAA;AAAA,IAAA;AAAA,MACE,GAAG,UAAA;AAAA,MACJ,UAAA,EAAY,WAAW,UAAA,IAAc,IAAA;AAAA,MACrC,UAAA,EAAY,IAAA;AAAA,MAGZ,cAAA,EAAgB,OAAA,CAAQ,UAAA,CAAW,OAAO,CAAA;AAAA,MAG1C,iBACE,UAAA,CAAW,eAAA,IAAoB,CAAC,YAAA,IAAgB,CAAC,UAAA,CAAW;AAAA,KAAA;AAAA,wCAG7D,IAAA,EAAA,EAAK,aAAA,EAAc,UAAS,MAAA,EAAO,MAAA,EAAA,EACjC,aAAa,WAAA,EAAa;AAAA,MACzB,IAAA,EAAM,IAAA;AAAA,MACN,KAAA,EAAO,iBAAiB,KAAA,IAAS,WAAA;AAAA,MACjC,QAAA,EAAU,SAAA,CAAU,cAAA,EAAgB,gBAAA,CAAiB,QAAQ,CAAA;AAAA,MAC7D,KAAA,EAAO,iBAAiB,KAAA,IAAS,MAAA;AAAA,MACjC,YAAA,EAAc,gBAAA,CAAiB,YAAA,IAAgB,MAAA,CAAO,IAAA,CAAK,SAAA;AAAA,MAC3D,QAAA,EAAU;AAAA,KACX,CAAA,EACA,YAAA,CAAa,OAAA,EAAS;AAAA,MACrB,iBAAA,EAAmB,cAAA;AAAA,MACnB,aAAA,EAAe,aAAa,aAAA,IAAiB,UAAA;AAAA,MAC7C,OAAA,EAAS,CAAA,KAAA,EAAQ,MAAA,CAAO,IAAA,CAAK,6BAA6B,KAAK,CAAA,MAAA,CAAA;AAAA,MAC/D,iBAAA,EAAmB,IAAA;AAAA,MACnB,MAAA;AAAA;AAAA;AAAA,QAGE,QAAA,IAAY,YAAA,GACR,YAAA,CAAa,MAAA,GACb,CAAC,SAAA,KACC,SAAA,CAAU,WAAA,EAAY,CAAE,QAAA,CAAS,WAAA,CAAY,WAAA,EAAa;AAAA;AAAA,KACnE,CACH;AAAA,GACF;AAEJ;;;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { useField } from '
|
|
2
|
+
import { useField } from 'react-aria/useField';
|
|
3
3
|
import { useThemeCheck, Field, Label } from '@danske/sapphire-react';
|
|
4
|
-
import { mergeProps } from '
|
|
4
|
+
import { mergeProps } from 'react-aria/mergeProps';
|
|
5
5
|
|
|
6
6
|
function LabeledValue({
|
|
7
7
|
children,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LabeledValue.js","sources":["../../../../src/LabeledValue/src/LabeledValue.tsx"],"sourcesContent":["import React, { ReactNode } from 'react';\nimport { useField } from '
|
|
1
|
+
{"version":3,"file":"LabeledValue.js","sources":["../../../../src/LabeledValue/src/LabeledValue.tsx"],"sourcesContent":["import React, { ReactNode } from 'react';\nimport { useField } from 'react-aria/useField';\nimport {\n Field,\n Label,\n SapphireStyleProps,\n useThemeCheck,\n GlobalDomAttributes,\n} from '@danske/sapphire-react';\nimport { mergeProps } from 'react-aria/mergeProps';\n\nexport interface LabeledValueProps\n extends SapphireStyleProps,\n GlobalDomAttributes {\n children?: React.ReactNode;\n /**\n * A HelpButton element to place next to the label.\n */\n contextualHelp?: ReactNode;\n /**\n * The content to display as a label.\n */\n label: ReactNode;\n /**\n * Places the label either above (default) or on the left side of tags.\n * @default 'above'\n */\n labelPlacement?: 'above' | 'side';\n /**\n * @default 'lg'\n */\n size?: 'lg' | 'md';\n}\n\nexport function LabeledValue({\n children,\n contextualHelp,\n label,\n labelPlacement = 'above',\n size = 'lg',\n ...otherProps\n}: LabeledValueProps): React.JSX.Element {\n useThemeCheck();\n const { fieldProps } = useField({ label });\n\n return (\n <Field\n {...mergeProps(fieldProps, otherProps)}\n labelPlacement={labelPlacement}\n size={size}\n noDefaultWidth\n >\n <Field.Label>\n <Label contextualHelp={contextualHelp} size={size}>\n {label}\n </Label>\n </Field.Label>\n <Field.Control>{children}</Field.Control>\n </Field>\n );\n}\n"],"names":[],"mappings":";;;;;AAkCO,SAAS,YAAA,CAAa;AAAA,EAC3B,QAAA;AAAA,EACA,cAAA;AAAA,EACA,KAAA;AAAA,EACA,cAAA,GAAiB,OAAA;AAAA,EACjB,IAAA,GAAO,IAAA;AAAA,EACP,GAAG;AACL,CAAA,EAAyC;AACvC,EAAA,aAAA,EAAc;AACd,EAAA,MAAM,EAAE,UAAA,EAAW,GAAI,QAAA,CAAS,EAAE,OAAO,CAAA;AAEzC,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,UAAA,CAAW,UAAA,EAAY,UAAU,CAAA;AAAA,MACrC,cAAA;AAAA,MACA,IAAA;AAAA,MACA,cAAA,EAAc;AAAA,KAAA;AAAA,oBAEd,KAAA,CAAA,aAAA,CAAC,MAAM,KAAA,EAAN,IAAA,sCACE,KAAA,EAAA,EAAM,cAAA,EAAgC,IAAA,EAAA,EACpC,KACH,CACF,CAAA;AAAA,oBACA,KAAA,CAAA,aAAA,CAAC,KAAA,CAAM,OAAA,EAAN,IAAA,EAAe,QAAS;AAAA,GAC3B;AAEJ;;;;"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import React, { forwardRef, useMemo, useRef, useImperativeHandle } from 'react';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
|
-
import { useFocusRing } from '
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { useFocusRing } from 'react-aria/useFocusRing';
|
|
4
|
+
import { useLocale } from 'react-aria/I18nProvider';
|
|
5
|
+
import { useMessageFormatter } from '@react-aria/i18n';
|
|
6
|
+
import { mergeProps } from 'react-aria/mergeProps';
|
|
7
|
+
import { useObjectRef } from 'react-aria/useObjectRef';
|
|
6
8
|
import { createFocusableRef } from '@react-spectrum/utils';
|
|
7
9
|
import textFieldStyles from '@danske/sapphire-css/components/textField/textField.module.css';
|
|
8
10
|
import { useThemeCheck, Field, Label, Separator } from '@danske/sapphire-react';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NumberField.js","sources":["../../../../src/NumberField/src/NumberField.tsx"],"sourcesContent":["import React, {\n forwardRef,\n ForwardedRef,\n ReactNode,\n RefObject,\n useImperativeHandle,\n useRef,\n useMemo,\n} from 'react';\nimport clsx from 'clsx';\nimport { useFocusRing } from '@react-aria/focus';\nimport { useLocale, useMessageFormatter } from '@react-aria/i18n';\nimport { mergeProps, useObjectRef } from '@react-aria/utils';\nimport { createFocusableRef } from '@react-spectrum/utils';\nimport { FocusableRefValue, PressEvents } from '@react-types/shared';\nimport textFieldStyles from '@danske/sapphire-css/components/textField/textField.module.css';\nimport {\n Field,\n Label,\n SapphireStyleProps,\n useThemeCheck,\n GlobalDomAttributes,\n Separator,\n} from '@danske/sapphire-react';\n\nimport intlMessages from '../i18n';\nimport { StepperButton } from './StepperButton';\nimport { useAutofillStyle } from './useAutofillStyle';\nimport { useNumberFieldFormatting } from './useNumberFieldFormatting';\nimport {\n SapphireNumberFieldProps,\n useSapphireNumberField,\n} from './useSapphireNumberField';\n\nexport type NumberFieldRef = FocusableRefValue<\n HTMLInputElement,\n HTMLDivElement\n> & {\n getInputElement(): HTMLInputElement | null;\n};\n\nexport interface NumberFieldProps\n extends SapphireNumberFieldProps,\n PressEvents,\n SapphireStyleProps,\n GlobalDomAttributes {\n /**\n * A string or element to show before / after the input value.\n *\n * By default (`'auto'`), the component will automatically extract currency/unit symbols\n * from the locale formatter and display them as prefix/postfix.\n * If you provide a custom prefix or postfix, those will be used instead and\n * the extracted symbols will be ignored.\n *\n * @default 'auto' - automatically extracts currency/unit symbols from locale formatter\n */\n affix?: 'auto' | { prefix?: ReactNode; postfix?: ReactNode };\n inputRef?: RefObject<HTMLInputElement | null>;\n /**\n * A note to show below the input.\n * If the input has an error message, this note will be replaced by that.\n */\n note?: ReactNode;\n /**\n * A HelpButton to render next to the label.\n */\n contextualHelp?: ReactNode;\n /**\n * To visually indicate if this field is required or optional.\n * @default false\n */\n necessityIndicator?: boolean;\n /**\n * @default 'lg'\n */\n size?: 'lg' | 'md';\n /**\n * Aligns the text inside the input fields without affecting the positioning of the label of the field.\n */\n alignInputRight?: boolean;\n /**\n * Places the label either above (default) or on the side of the control.\n * @default 'above'\n */\n labelPlacement?: 'side' | 'above';\n /**\n * To show the buttons for incrementing and decrementing the value.\n * @default false\n */\n showButtons?: boolean;\n /**\n * Enables automatic formatting of the input value as the user types, based on the provided formatter and affix.\n *\n * @default false\n */\n autoFormat?: boolean;\n}\n\nexport const NumberField = forwardRef(function NumberField(\n props: NumberFieldProps,\n ref: ForwardedRef<NumberFieldRef>\n) {\n const {\n label,\n isDisabled,\n error,\n note,\n isRequired,\n contextualHelp,\n affix = 'auto',\n size = 'lg',\n labelPlacement = 'above',\n necessityIndicator = false,\n alignInputRight,\n showButtons = false,\n incrementAriaLabel,\n decrementAriaLabel,\n autoFormat = false,\n ...otherProps\n } = props;\n\n // Extract prefix and postfix from affix prop\n const { prefix, postfix } = useMemo(() => {\n if (affix === 'auto') {\n return { prefix: undefined, postfix: undefined };\n }\n return { prefix: affix.prefix, postfix: affix.postfix };\n }, [affix]);\n useThemeCheck();\n const inputRef = useObjectRef<HTMLInputElement>(props.inputRef);\n const formatMessage = useMessageFormatter(intlMessages);\n\n const {\n inputProps,\n labelProps,\n incrementButtonProps,\n decrementButtonProps,\n descriptionProps,\n errorMessageProps,\n } = useSapphireNumberField(\n {\n ...props,\n incrementAriaLabel: incrementAriaLabel ?? formatMessage('increment'),\n decrementAriaLabel: decrementAriaLabel ?? formatMessage('decrement'),\n },\n inputRef\n );\n const { focusProps, isFocusVisible } = useFocusRing();\n const { autofillStyles, updateStyle } = useAutofillStyle<'input'>(inputRef);\n const { locale } = useLocale();\n\n const formatter = useMemo(\n () => new Intl.NumberFormat(locale, props.formatOptions),\n [locale, props.formatOptions]\n );\n\n const formattingResult = useNumberFieldFormatting({\n inputRef,\n formatter,\n inputValue: inputProps.value as string,\n prefix,\n postfix,\n onOriginalKeyDown: inputProps.onKeyDown,\n onChange: props.onChange,\n autoFormat,\n });\n\n const { extractedPrefix, extractedPostfix, handleInput, handleKeyDown } =\n autoFormat\n ? formattingResult\n : {\n extractedPrefix: formattingResult.extractedPrefix,\n extractedPostfix: formattingResult.extractedPostfix,\n handleInput: undefined,\n handleKeyDown: inputProps.onKeyDown,\n };\n\n const containerRef = useRef<HTMLDivElement>(null);\n\n useImperativeHandle(ref, () => ({\n ...createFocusableRef(containerRef, inputRef),\n /**\n * (This function is deprecated. Use `inputRef` prop)\n * @deprecated\n */\n getInputElement() {\n return inputRef.current;\n },\n }));\n\n return (\n <Field\n // otherProps contains some of the same props as inputProps. That is\n // intended, but some DOM props, like \"id\", should not be repeated\n {...removeUniqueDOMProps(otherProps)}\n ref={containerRef}\n size={size}\n labelPlacement={labelPlacement}\n >\n <Field.Context\n descriptionProps={error ? errorMessageProps : descriptionProps}\n >\n {label && (\n <Field.Label>\n <Label\n {...labelProps}\n size={size}\n necessityIndicator={\n isRequired && necessityIndicator\n ? 'required'\n : !isRequired && necessityIndicator\n ? 'optional'\n : undefined\n }\n contextualHelp={contextualHelp}\n >\n {label}\n </Label>\n </Field.Label>\n )}\n <Field.Control>\n <div\n className={clsx(textFieldStyles['sapphire-text-field'], {\n [textFieldStyles['is-focus']]: isFocusVisible,\n [textFieldStyles['sapphire-text-field--error']]:\n error === true || typeof error === 'string',\n [textFieldStyles['sapphire-text-field--md']]: size === 'md',\n })}\n >\n {extractedPrefix && (\n <span\n className={clsx(\n textFieldStyles['sapphire-text-field__prefix'],\n {\n [textFieldStyles['sapphire-text-field__prefix--icon']]:\n typeof extractedPrefix !== 'string',\n }\n )}\n >\n {extractedPrefix}\n </span>\n )}\n <input\n {...mergeProps(\n inputProps,\n focusProps,\n {\n onChange: updateStyle,\n onBlur: updateStyle,\n },\n autoFormat\n ? {\n onInput: handleInput,\n onKeyDown: handleKeyDown,\n }\n : {}\n )}\n value={formattingResult?.displayValue ?? inputProps.value}\n ref={inputRef}\n className={clsx(textFieldStyles['sapphire-text-field__input'], {\n [textFieldStyles['sapphire-text-field__input--align-right']]:\n !!alignInputRight,\n })}\n style={autofillStyles}\n />\n {extractedPostfix && (\n <span\n className={clsx(\n textFieldStyles['sapphire-text-field__postfix'],\n {\n [textFieldStyles['sapphire-text-field__postfix--icon']]:\n typeof extractedPostfix !== 'string',\n }\n )}\n >\n {extractedPostfix}\n </span>\n )}\n {showButtons && (\n <div className={textFieldStyles['sapphire-text-field__stepper']}>\n <StepperButton\n variant=\"decrement\"\n size={size}\n {...decrementButtonProps}\n />\n <Separator orientation=\"vertical\" />\n <StepperButton\n variant=\"increment\"\n size={size}\n {...incrementButtonProps}\n />\n </div>\n )}\n </div>\n </Field.Control>\n {((error && typeof error !== 'boolean') || note) && (\n <Field.Footer>\n {error && typeof error !== 'boolean' ? (\n <Field.Note variant=\"error\">{error}</Field.Note>\n ) : note ? (\n note\n ) : (\n <></>\n )}\n </Field.Footer>\n )}\n </Field.Context>\n </Field>\n );\n});\n\n// Once moved to the core package, this function should be removed and instead consume the one from TextFieldBase.\nconst removeUniqueDOMProps = (props: Record<any, any>): Record<any, any> =>\n Object.fromEntries(\n Object.entries(props).filter(\n ([name]) => name !== 'id' && !name.startsWith('data-')\n )\n );\n"],"names":["NumberField"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"NumberField.js","sources":["../../../../src/NumberField/src/NumberField.tsx"],"sourcesContent":["import React, {\n forwardRef,\n ForwardedRef,\n ReactNode,\n RefObject,\n useImperativeHandle,\n useRef,\n useMemo,\n} from 'react';\nimport clsx from 'clsx';\nimport { useFocusRing } from 'react-aria/useFocusRing';\nimport { useLocale } from 'react-aria/I18nProvider';\nimport { useMessageFormatter } from '@react-aria/i18n';\nimport { mergeProps } from 'react-aria/mergeProps';\nimport { useObjectRef } from 'react-aria/useObjectRef';\nimport { createFocusableRef } from '@react-spectrum/utils';\nimport { FocusableRefValue, PressEvents } from '@react-types/shared';\nimport textFieldStyles from '@danske/sapphire-css/components/textField/textField.module.css';\nimport {\n Field,\n Label,\n SapphireStyleProps,\n useThemeCheck,\n GlobalDomAttributes,\n Separator,\n} from '@danske/sapphire-react';\n\nimport intlMessages from '../i18n';\nimport { StepperButton } from './StepperButton';\nimport { useAutofillStyle } from './useAutofillStyle';\nimport { useNumberFieldFormatting } from './useNumberFieldFormatting';\nimport {\n SapphireNumberFieldProps,\n useSapphireNumberField,\n} from './useSapphireNumberField';\n\nexport type NumberFieldRef = FocusableRefValue<\n HTMLInputElement,\n HTMLDivElement\n> & {\n getInputElement(): HTMLInputElement | null;\n};\n\nexport interface NumberFieldProps\n extends SapphireNumberFieldProps,\n PressEvents,\n SapphireStyleProps,\n GlobalDomAttributes {\n /**\n * A string or element to show before / after the input value.\n *\n * By default (`'auto'`), the component will automatically extract currency/unit symbols\n * from the locale formatter and display them as prefix/postfix.\n * If you provide a custom prefix or postfix, those will be used instead and\n * the extracted symbols will be ignored.\n *\n * @default 'auto' - automatically extracts currency/unit symbols from locale formatter\n */\n affix?: 'auto' | { prefix?: ReactNode; postfix?: ReactNode };\n inputRef?: RefObject<HTMLInputElement | null>;\n /**\n * A note to show below the input.\n * If the input has an error message, this note will be replaced by that.\n */\n note?: ReactNode;\n /**\n * A HelpButton to render next to the label.\n */\n contextualHelp?: ReactNode;\n /**\n * To visually indicate if this field is required or optional.\n * @default false\n */\n necessityIndicator?: boolean;\n /**\n * @default 'lg'\n */\n size?: 'lg' | 'md';\n /**\n * Aligns the text inside the input fields without affecting the positioning of the label of the field.\n */\n alignInputRight?: boolean;\n /**\n * Places the label either above (default) or on the side of the control.\n * @default 'above'\n */\n labelPlacement?: 'side' | 'above';\n /**\n * To show the buttons for incrementing and decrementing the value.\n * @default false\n */\n showButtons?: boolean;\n /**\n * Enables automatic formatting of the input value as the user types, based on the provided formatter and affix.\n *\n * @default false\n */\n autoFormat?: boolean;\n}\n\nexport const NumberField = forwardRef(function NumberField(\n props: NumberFieldProps,\n ref: ForwardedRef<NumberFieldRef>\n) {\n const {\n label,\n isDisabled,\n error,\n note,\n isRequired,\n contextualHelp,\n affix = 'auto',\n size = 'lg',\n labelPlacement = 'above',\n necessityIndicator = false,\n alignInputRight,\n showButtons = false,\n incrementAriaLabel,\n decrementAriaLabel,\n autoFormat = false,\n ...otherProps\n } = props;\n\n // Extract prefix and postfix from affix prop\n const { prefix, postfix } = useMemo(() => {\n if (affix === 'auto') {\n return { prefix: undefined, postfix: undefined };\n }\n return { prefix: affix.prefix, postfix: affix.postfix };\n }, [affix]);\n useThemeCheck();\n const inputRef = useObjectRef<HTMLInputElement>(props.inputRef);\n const formatMessage = useMessageFormatter(intlMessages);\n\n const {\n inputProps,\n labelProps,\n incrementButtonProps,\n decrementButtonProps,\n descriptionProps,\n errorMessageProps,\n } = useSapphireNumberField(\n {\n ...props,\n incrementAriaLabel: incrementAriaLabel ?? formatMessage('increment'),\n decrementAriaLabel: decrementAriaLabel ?? formatMessage('decrement'),\n },\n inputRef\n );\n const { focusProps, isFocusVisible } = useFocusRing();\n const { autofillStyles, updateStyle } = useAutofillStyle<'input'>(inputRef);\n const { locale } = useLocale();\n\n const formatter = useMemo(\n () => new Intl.NumberFormat(locale, props.formatOptions),\n [locale, props.formatOptions]\n );\n\n const formattingResult = useNumberFieldFormatting({\n inputRef,\n formatter,\n inputValue: inputProps.value as string,\n prefix,\n postfix,\n onOriginalKeyDown: inputProps.onKeyDown,\n onChange: props.onChange,\n autoFormat,\n });\n\n const { extractedPrefix, extractedPostfix, handleInput, handleKeyDown } =\n autoFormat\n ? formattingResult\n : {\n extractedPrefix: formattingResult.extractedPrefix,\n extractedPostfix: formattingResult.extractedPostfix,\n handleInput: undefined,\n handleKeyDown: inputProps.onKeyDown,\n };\n\n const containerRef = useRef<HTMLDivElement>(null);\n\n useImperativeHandle(ref, () => ({\n ...createFocusableRef(containerRef, inputRef),\n /**\n * (This function is deprecated. Use `inputRef` prop)\n * @deprecated\n */\n getInputElement() {\n return inputRef.current;\n },\n }));\n\n return (\n <Field\n // otherProps contains some of the same props as inputProps. That is\n // intended, but some DOM props, like \"id\", should not be repeated\n {...removeUniqueDOMProps(otherProps)}\n ref={containerRef}\n size={size}\n labelPlacement={labelPlacement}\n >\n <Field.Context\n descriptionProps={error ? errorMessageProps : descriptionProps}\n >\n {label && (\n <Field.Label>\n <Label\n {...labelProps}\n size={size}\n necessityIndicator={\n isRequired && necessityIndicator\n ? 'required'\n : !isRequired && necessityIndicator\n ? 'optional'\n : undefined\n }\n contextualHelp={contextualHelp}\n >\n {label}\n </Label>\n </Field.Label>\n )}\n <Field.Control>\n <div\n className={clsx(textFieldStyles['sapphire-text-field'], {\n [textFieldStyles['is-focus']]: isFocusVisible,\n [textFieldStyles['sapphire-text-field--error']]:\n error === true || typeof error === 'string',\n [textFieldStyles['sapphire-text-field--md']]: size === 'md',\n })}\n >\n {extractedPrefix && (\n <span\n className={clsx(\n textFieldStyles['sapphire-text-field__prefix'],\n {\n [textFieldStyles['sapphire-text-field__prefix--icon']]:\n typeof extractedPrefix !== 'string',\n }\n )}\n >\n {extractedPrefix}\n </span>\n )}\n <input\n {...mergeProps(\n inputProps,\n focusProps,\n {\n onChange: updateStyle,\n onBlur: updateStyle,\n },\n autoFormat\n ? {\n onInput: handleInput,\n onKeyDown: handleKeyDown,\n }\n : {}\n )}\n value={formattingResult?.displayValue ?? inputProps.value}\n ref={inputRef}\n className={clsx(textFieldStyles['sapphire-text-field__input'], {\n [textFieldStyles['sapphire-text-field__input--align-right']]:\n !!alignInputRight,\n })}\n style={autofillStyles}\n />\n {extractedPostfix && (\n <span\n className={clsx(\n textFieldStyles['sapphire-text-field__postfix'],\n {\n [textFieldStyles['sapphire-text-field__postfix--icon']]:\n typeof extractedPostfix !== 'string',\n }\n )}\n >\n {extractedPostfix}\n </span>\n )}\n {showButtons && (\n <div className={textFieldStyles['sapphire-text-field__stepper']}>\n <StepperButton\n variant=\"decrement\"\n size={size}\n {...decrementButtonProps}\n />\n <Separator orientation=\"vertical\" />\n <StepperButton\n variant=\"increment\"\n size={size}\n {...incrementButtonProps}\n />\n </div>\n )}\n </div>\n </Field.Control>\n {((error && typeof error !== 'boolean') || note) && (\n <Field.Footer>\n {error && typeof error !== 'boolean' ? (\n <Field.Note variant=\"error\">{error}</Field.Note>\n ) : note ? (\n note\n ) : (\n <></>\n )}\n </Field.Footer>\n )}\n </Field.Context>\n </Field>\n );\n});\n\n// Once moved to the core package, this function should be removed and instead consume the one from TextFieldBase.\nconst removeUniqueDOMProps = (props: Record<any, any>): Record<any, any> =>\n Object.fromEntries(\n Object.entries(props).filter(\n ([name]) => name !== 'id' && !name.startsWith('data-')\n )\n );\n"],"names":["NumberField"],"mappings":";;;;;;;;;;;;;;;;AAoGO,MAAM,WAAA,GAAc,UAAA,CAAW,SAASA,YAAAA,CAC7C,OACA,GAAA,EACA;AACA,EAAA,MAAM;AAAA,IACJ,KAAA;AAAA,IACA,UAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,UAAA;AAAA,IACA,cAAA;AAAA,IACA,KAAA,GAAQ,MAAA;AAAA,IACR,IAAA,GAAO,IAAA;AAAA,IACP,cAAA,GAAiB,OAAA;AAAA,IACjB,kBAAA,GAAqB,KAAA;AAAA,IACrB,eAAA;AAAA,IACA,WAAA,GAAc,KAAA;AAAA,IACd,kBAAA;AAAA,IACA,kBAAA;AAAA,IACA,UAAA,GAAa,KAAA;AAAA,IACb,GAAG;AAAA,GACL,GAAI,KAAA;AAGJ,EAAA,MAAM,EAAE,MAAA,EAAQ,OAAA,EAAQ,GAAI,QAAQ,MAAM;AACxC,IAAA,IAAI,UAAU,MAAA,EAAQ;AACpB,MAAA,OAAO,EAAE,MAAA,EAAQ,MAAA,EAAW,OAAA,EAAS,MAAA,EAAU;AAAA,IACjD;AACA,IAAA,OAAO,EAAE,MAAA,EAAQ,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,MAAM,OAAA,EAAQ;AAAA,EACxD,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AACV,EAAA,aAAA,EAAc;AACd,EAAA,MAAM,QAAA,GAAW,YAAA,CAA+B,KAAA,CAAM,QAAQ,CAAA;AAC9D,EAAA,MAAM,aAAA,GAAgB,oBAAoB,YAAY,CAAA;AAEtD,EAAA,MAAM;AAAA,IACJ,UAAA;AAAA,IACA,UAAA;AAAA,IACA,oBAAA;AAAA,IACA,oBAAA;AAAA,IACA,gBAAA;AAAA,IACA;AAAA,GACF,GAAI,sBAAA;AAAA,IACF;AAAA,MACE,GAAG,KAAA;AAAA,MACH,kBAAA,EAAoB,kBAAA,IAAsB,aAAA,CAAc,WAAW,CAAA;AAAA,MACnE,kBAAA,EAAoB,kBAAA,IAAsB,aAAA,CAAc,WAAW;AAAA,KACrE;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,EAAE,UAAA,EAAY,cAAA,EAAe,GAAI,YAAA,EAAa;AACpD,EAAA,MAAM,EAAE,cAAA,EAAgB,WAAA,EAAY,GAAI,iBAA0B,QAAQ,CAAA;AAC1E,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,SAAA,EAAU;AAE7B,EAAA,MAAM,SAAA,GAAY,OAAA;AAAA,IAChB,MAAM,IAAI,IAAA,CAAK,YAAA,CAAa,MAAA,EAAQ,MAAM,aAAa,CAAA;AAAA,IACvD,CAAC,MAAA,EAAQ,KAAA,CAAM,aAAa;AAAA,GAC9B;AAEA,EAAA,MAAM,mBAAmB,wBAAA,CAAyB;AAAA,IAChD,QAAA;AAAA,IACA,SAAA;AAAA,IACA,YAAY,UAAA,CAAW,KAAA;AAAA,IACvB,MAAA;AAAA,IACA,OAAA;AAAA,IACA,mBAAmB,UAAA,CAAW,SAAA;AAAA,IAC9B,UAAU,KAAA,CAAM,QAAA;AAAA,IAChB;AAAA,GACD,CAAA;AAED,EAAA,MAAM,EAAE,eAAA,EAAiB,gBAAA,EAAkB,aAAa,aAAA,EAAc,GACpE,aACI,gBAAA,GACA;AAAA,IACE,iBAAiB,gBAAA,CAAiB,eAAA;AAAA,IAClC,kBAAkB,gBAAA,CAAiB,gBAAA;AAAA,IACnC,WAAA,EAAa,MAAA;AAAA,IACb,eAAe,UAAA,CAAW;AAAA,GAC5B;AAEN,EAAA,MAAM,YAAA,GAAe,OAAuB,IAAI,CAAA;AAEhD,EAAA,mBAAA,CAAoB,KAAK,OAAO;AAAA,IAC9B,GAAG,kBAAA,CAAmB,YAAA,EAAc,QAAQ,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAK5C,eAAA,GAAkB;AAChB,MAAA,OAAO,QAAA,CAAS,OAAA;AAAA,IAClB;AAAA,GACF,CAAE,CAAA;AAEF,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MAGE,GAAG,qBAAqB,UAAU,CAAA;AAAA,MACnC,GAAA,EAAK,YAAA;AAAA,MACL,IAAA;AAAA,MACA;AAAA,KAAA;AAAA,oBAEA,KAAA,CAAA,aAAA;AAAA,MAAC,KAAA,CAAM,OAAA;AAAA,MAAN;AAAA,QACC,gBAAA,EAAkB,QAAQ,iBAAA,GAAoB;AAAA,OAAA;AAAA,MAE7C,KAAA,oBACC,KAAA,CAAA,aAAA,CAAC,KAAA,CAAM,KAAA,EAAN,IAAA,kBACC,KAAA,CAAA,aAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACE,GAAG,UAAA;AAAA,UACJ,IAAA;AAAA,UACA,oBACE,UAAA,IAAc,kBAAA,GACV,aACA,CAAC,UAAA,IAAc,qBACf,UAAA,GACA,MAAA;AAAA,UAEN;AAAA,SAAA;AAAA,QAEC;AAAA,OAEL,CAAA;AAAA,sBAEF,KAAA,CAAA,aAAA,CAAC,KAAA,CAAM,OAAA,EAAN,IAAA,kBACC,KAAA,CAAA,aAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,IAAA,CAAK,eAAA,CAAgB,qBAAqB,CAAA,EAAG;AAAA,YACtD,CAAC,eAAA,CAAgB,UAAU,CAAC,GAAG,cAAA;AAAA,YAC/B,CAAC,gBAAgB,4BAA4B,CAAC,GAC5C,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,KAAU,QAAA;AAAA,YACrC,CAAC,eAAA,CAAgB,yBAAyB,CAAC,GAAG,IAAA,KAAS;AAAA,WACxD;AAAA,SAAA;AAAA,QAEA,eAAA,oBACC,KAAA,CAAA,aAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,IAAA;AAAA,cACT,gBAAgB,6BAA6B,CAAA;AAAA,cAC7C;AAAA,gBACE,CAAC,eAAA,CAAgB,mCAAmC,CAAC,GACnD,OAAO,eAAA,KAAoB;AAAA;AAC/B;AACF,WAAA;AAAA,UAEC;AAAA,SACH;AAAA,wBAEF,KAAA,CAAA,aAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACE,GAAG,UAAA;AAAA,cACF,UAAA;AAAA,cACA,UAAA;AAAA,cACA;AAAA,gBACE,QAAA,EAAU,WAAA;AAAA,gBACV,MAAA,EAAQ;AAAA,eACV;AAAA,cACA,UAAA,GACI;AAAA,gBACE,OAAA,EAAS,WAAA;AAAA,gBACT,SAAA,EAAW;AAAA,kBAEb;AAAC,aACP;AAAA,YACA,KAAA,EAAO,gBAAA,EAAkB,YAAA,IAAgB,UAAA,CAAW,KAAA;AAAA,YACpD,GAAA,EAAK,QAAA;AAAA,YACL,SAAA,EAAW,IAAA,CAAK,eAAA,CAAgB,4BAA4B,CAAA,EAAG;AAAA,cAC7D,CAAC,eAAA,CAAgB,yCAAyC,CAAC,GACzD,CAAC,CAAC;AAAA,aACL,CAAA;AAAA,YACD,KAAA,EAAO;AAAA;AAAA,SACT;AAAA,QACC,gBAAA,oBACC,KAAA,CAAA,aAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,IAAA;AAAA,cACT,gBAAgB,8BAA8B,CAAA;AAAA,cAC9C;AAAA,gBACE,CAAC,eAAA,CAAgB,oCAAoC,CAAC,GACpD,OAAO,gBAAA,KAAqB;AAAA;AAChC;AACF,WAAA;AAAA,UAEC;AAAA,SACH;AAAA,QAED,+BACC,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,eAAA,CAAgB,8BAA8B,CAAA,EAAA,kBAC5D,KAAA,CAAA,aAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAQ,WAAA;AAAA,YACR,IAAA;AAAA,YACC,GAAG;AAAA;AAAA,SACN,kBACA,KAAA,CAAA,aAAA,CAAC,SAAA,EAAA,EAAU,WAAA,EAAY,YAAW,CAAA,kBAClC,KAAA,CAAA,aAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAQ,WAAA;AAAA,YACR,IAAA;AAAA,YACC,GAAG;AAAA;AAAA,SAER;AAAA,OAGN,CAAA;AAAA,MAAA,CACG,KAAA,IAAS,OAAO,KAAA,KAAU,SAAA,IAAc,IAAA,yCACxC,KAAA,CAAM,MAAA,EAAN,IAAA,EACE,KAAA,IAAS,OAAO,KAAA,KAAU,4BACzB,KAAA,CAAA,aAAA,CAAC,KAAA,CAAM,IAAA,EAAN,EAAW,OAAA,EAAQ,OAAA,EAAA,EAAS,KAAM,CAAA,GACjC,IAAA,GACF,IAAA,mBAEA,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAE,CAEN;AAAA;AAEJ,GACF;AAEJ,CAAC;AAGD,MAAM,oBAAA,GAAuB,CAAC,KAAA,KAC5B,MAAA,CAAO,WAAA;AAAA,EACL,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,CAAE,MAAA;AAAA,IACpB,CAAC,CAAC,IAAI,CAAA,KAAM,SAAS,IAAA,IAAQ,CAAC,IAAA,CAAK,UAAA,CAAW,OAAO;AAAA;AAEzD,CAAA;;;;"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import React, { useRef } from 'react';
|
|
2
|
-
import { useHover } from '
|
|
3
|
-
import {
|
|
2
|
+
import { useHover } from 'react-aria/useHover';
|
|
3
|
+
import { filterDOMProps } from 'react-aria/filterDOMProps';
|
|
4
|
+
import { mergeProps } from 'react-aria/mergeProps';
|
|
4
5
|
import clsx from 'clsx';
|
|
5
6
|
import textFieldStyles from '@danske/sapphire-css/components/textField/textField.module.css';
|
|
6
7
|
import { useButton, Icon } from '@danske/sapphire-react';
|
|
7
8
|
import { Add, Subtract } from '@danske/sapphire-icons/react';
|
|
8
|
-
import { useFocusRing } from '
|
|
9
|
+
import { useFocusRing } from 'react-aria/useFocusRing';
|
|
9
10
|
|
|
10
11
|
const StepperButton = ({
|
|
11
12
|
variant,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StepperButton.js","sources":["../../../../src/NumberField/src/StepperButton.tsx"],"sourcesContent":["import React, { useRef } from 'react';\nimport { AriaButtonProps } from '
|
|
1
|
+
{"version":3,"file":"StepperButton.js","sources":["../../../../src/NumberField/src/StepperButton.tsx"],"sourcesContent":["import React, { useRef } from 'react';\nimport { AriaButtonProps } from 'react-aria/useButton';\nimport { useHover } from 'react-aria/useHover';\nimport { filterDOMProps } from 'react-aria/filterDOMProps';\nimport { mergeProps } from 'react-aria/mergeProps';\nimport clsx from 'clsx';\nimport styles from '@danske/sapphire-css/components/textField/textField.module.css';\nimport { Icon, useButton } from '@danske/sapphire-react';\nimport { Add, Subtract } from '@danske/sapphire-icons/react';\nimport { useFocusRing } from 'react-aria/useFocusRing';\n\n/**\n * @internal\n */\nexport const StepperButton = ({\n variant,\n size,\n ...props\n}: AriaButtonProps & {\n variant: 'increment' | 'decrement';\n size: 'lg' | 'md';\n}): React.JSX.Element => {\n const ref = useRef(null);\n const { buttonProps, isPressed } = useButton(props, ref);\n const { hoverProps, isHovered } = useHover({ isDisabled: props.isDisabled });\n const { focusProps, isFocusVisible } = useFocusRing();\n\n return (\n <button\n {...mergeProps(\n buttonProps,\n hoverProps,\n focusProps,\n filterDOMProps(props, { global: true })\n )}\n tabIndex={0} // tabIndex comes as \"-1\" from the react-aria hook\n ref={ref}\n className={clsx(\n styles['sapphire-text-field__stepper-button'],\n styles['js-hover'],\n {\n [styles['is-active']]: isPressed,\n [styles['is-hover']]: isHovered,\n [styles['is-focus']]: isFocusVisible,\n }\n )}\n >\n <Icon size={size === 'lg' ? 'md' : 'sm'}>\n {variant === 'increment' ? <Add /> : <Subtract />}\n </Icon>\n </button>\n );\n};\n"],"names":["styles"],"mappings":";;;;;;;;;;AAcO,MAAM,gBAAgB,CAAC;AAAA,EAC5B,OAAA;AAAA,EACA,IAAA;AAAA,EACA,GAAG;AACL,CAAA,KAGyB;AACvB,EAAA,MAAM,GAAA,GAAM,OAAO,IAAI,CAAA;AACvB,EAAA,MAAM,EAAE,WAAA,EAAa,SAAA,EAAU,GAAI,SAAA,CAAU,OAAO,GAAG,CAAA;AACvD,EAAA,MAAM,EAAE,YAAY,SAAA,EAAU,GAAI,SAAS,EAAE,UAAA,EAAY,KAAA,CAAM,UAAA,EAAY,CAAA;AAC3E,EAAA,MAAM,EAAE,UAAA,EAAY,cAAA,EAAe,GAAI,YAAA,EAAa;AAEpD,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACE,GAAG,UAAA;AAAA,QACF,WAAA;AAAA,QACA,UAAA;AAAA,QACA,UAAA;AAAA,QACA,cAAA,CAAe,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAM;AAAA,OACxC;AAAA,MACA,QAAA,EAAU,CAAA;AAAA,MACV,GAAA;AAAA,MACA,SAAA,EAAW,IAAA;AAAA,QACTA,gBAAO,qCAAqC,CAAA;AAAA,QAC5CA,gBAAO,UAAU,CAAA;AAAA,QACjB;AAAA,UACE,CAACA,eAAA,CAAO,WAAW,CAAC,GAAG,SAAA;AAAA,UACvB,CAACA,eAAA,CAAO,UAAU,CAAC,GAAG,SAAA;AAAA,UACtB,CAACA,eAAA,CAAO,UAAU,CAAC,GAAG;AAAA;AACxB;AACF,KAAA;AAAA,oBAEA,KAAA,CAAA,aAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAM,IAAA,KAAS,OAAO,IAAA,GAAO,IAAA,EAAA,EAChC,OAAA,KAAY,WAAA,mBAAc,KAAA,CAAA,aAAA,CAAC,GAAA,EAAA,IAAI,CAAA,mBAAK,KAAA,CAAA,aAAA,CAAC,cAAS,CACjD;AAAA,GACF;AAEJ;;;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useNumberField } from '
|
|
2
|
-
import { useNumberFieldState } from '
|
|
3
|
-
import { useLocale } from '
|
|
1
|
+
import { useNumberField } from 'react-aria/useNumberField';
|
|
2
|
+
import { useNumberFieldState } from 'react-stately/useNumberFieldState';
|
|
3
|
+
import { useLocale } from 'react-aria/I18nProvider';
|
|
4
4
|
|
|
5
5
|
const useSapphireNumberField = ({ error, ...numberFieldProps }, ref) => {
|
|
6
6
|
const { locale } = useLocale();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSapphireNumberField.js","sources":["../../../../src/NumberField/src/useSapphireNumberField.ts"],"sourcesContent":["import React, { RefObject } from 'react';\nimport {\n AriaNumberFieldProps,\n NumberFieldAria,\n useNumberField,\n} from '
|
|
1
|
+
{"version":3,"file":"useSapphireNumberField.js","sources":["../../../../src/NumberField/src/useSapphireNumberField.ts"],"sourcesContent":["import React, { RefObject } from 'react';\nimport {\n AriaNumberFieldProps,\n NumberFieldAria,\n useNumberField,\n} from 'react-aria/useNumberField';\nimport { useNumberFieldState } from 'react-stately/useNumberFieldState';\nimport { useLocale } from 'react-aria/I18nProvider';\n\nexport interface SapphireNumberFieldProps\n // TODO: when this is moved to `core`, we can replace the picked props with `ValueBasePropsKeys`\n extends Pick<\n AriaNumberFieldProps,\n | 'label'\n | 'isDisabled'\n | 'isRequired'\n | 'value'\n | 'defaultValue'\n | 'onChange'\n | 'incrementAriaLabel'\n | 'decrementAriaLabel'\n | 'onFocus'\n | 'onBlur'\n | 'formatOptions'\n | 'step'\n | 'minValue'\n | 'maxValue'\n | 'placeholder'\n | 'isReadOnly'\n | 'autoFocus'\n | 'onFocusChange'\n | 'onKeyUp'\n | 'onKeyDown'\n > {\n /**\n * Whether the input should render as having an error and an error message.\n * This also sets the appropriate `aria` attributes on the input.\n *\n * A `boolean` sets the error state.\n * A `ReactNode` sets the error state with an additional error message.\n *\n * **An error message is strongly recommended because an error should always have an explanation about how to fix it.**\n */\n error?: boolean | React.ReactNode;\n}\n\nexport const useSapphireNumberField = (\n { error, ...numberFieldProps }: SapphireNumberFieldProps,\n ref: RefObject<HTMLInputElement>\n): NumberFieldAria & { state: ReturnType<typeof useNumberFieldState> } => {\n const { locale } = useLocale();\n const numberFieldState = useNumberFieldState({\n ...numberFieldProps,\n locale,\n });\n const numberFieldAria = useNumberField(\n {\n ...numberFieldProps,\n validationState:\n error === false || error === undefined ? undefined : 'invalid',\n },\n numberFieldState,\n ref\n );\n\n return { ...numberFieldAria, state: numberFieldState };\n};\n"],"names":[],"mappings":";;;;AA8CO,MAAM,yBAAyB,CACpC,EAAE,OAAO,GAAG,gBAAA,IACZ,GAAA,KACwE;AACxE,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,SAAA,EAAU;AAC7B,EAAA,MAAM,mBAAmB,mBAAA,CAAoB;AAAA,IAC3C,GAAG,gBAAA;AAAA,IACH;AAAA,GACD,CAAA;AACD,EAAA,MAAM,eAAA,GAAkB,cAAA;AAAA,IACtB;AAAA,MACE,GAAG,gBAAA;AAAA,MACH,eAAA,EACE,KAAA,KAAU,KAAA,IAAS,KAAA,KAAU,SAAY,MAAA,GAAY;AAAA,KACzD;AAAA,IACA,gBAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,OAAO,EAAE,GAAG,eAAA,EAAiB,KAAA,EAAO,gBAAA,EAAiB;AACvD;;;;"}
|
|
@@ -2,8 +2,8 @@ import React from 'react';
|
|
|
2
2
|
import clsx from 'clsx';
|
|
3
3
|
import styles from '@danske/sapphire-css/components/progressIndicator/progressIndicator.module.css';
|
|
4
4
|
import { useThemeCheck, useSapphireStyleProps } from '@danske/sapphire-react';
|
|
5
|
-
import { useProgressBar } from '
|
|
6
|
-
import { filterDOMProps } from '
|
|
5
|
+
import { useProgressBar } from 'react-aria/useProgressBar';
|
|
6
|
+
import { filterDOMProps } from 'react-aria/filterDOMProps';
|
|
7
7
|
|
|
8
8
|
const ProgressIndicator = (props) => {
|
|
9
9
|
const {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProgressIndicator.js","sources":["../../../../src/ProgressIndicator/src/ProgressIndicator.tsx"],"sourcesContent":["import React from 'react';\nimport clsx from 'clsx';\nimport styles from '@danske/sapphire-css/components/progressIndicator/progressIndicator.module.css';\nimport {\n SapphireStyleProps,\n useThemeCheck,\n useSapphireStyleProps,\n GlobalDomAttributes,\n} from '@danske/sapphire-react';\nimport { useProgressBar } from '
|
|
1
|
+
{"version":3,"file":"ProgressIndicator.js","sources":["../../../../src/ProgressIndicator/src/ProgressIndicator.tsx"],"sourcesContent":["import React from 'react';\nimport clsx from 'clsx';\nimport styles from '@danske/sapphire-css/components/progressIndicator/progressIndicator.module.css';\nimport {\n SapphireStyleProps,\n useThemeCheck,\n useSapphireStyleProps,\n GlobalDomAttributes,\n} from '@danske/sapphire-react';\nimport { useProgressBar } from 'react-aria/useProgressBar';\nimport { filterDOMProps } from 'react-aria/filterDOMProps';\n\nexport type ProgressIndicatorProps = {\n /**\n * The maximum value for the progress bar. Will be used as:\n * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-valuemax\n *\n * @default 100\n */\n maxValue?: number;\n\n /**\n * The current value of the progress bar. Will be used as:\n * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-valuenow\n */\n value: number;\n\n /**\n * Defines how many segments the progress bar will have.\n *\n * @default 1\n */\n segments?: number;\n\n /**\n * Human-readable text alternative for the current value of the progress bar. Will be used as:\n * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-valuetext\n */\n 'aria-valuetext'?: string;\n} & SapphireStyleProps &\n GlobalDomAttributes &\n ({ 'aria-labelledby': string } | { 'aria-label': string });\n\nexport const ProgressIndicator = (\n props: ProgressIndicatorProps\n): JSX.Element => {\n const {\n maxValue = 100,\n value: realValue,\n segments = 1,\n 'aria-valuetext': ariaValueText,\n } = props;\n\n useThemeCheck();\n const { styleProps } = useSapphireStyleProps(props);\n const { progressBarProps } = useProgressBar({\n ...props,\n minValue: 0,\n valueLabel: ariaValueText,\n });\n\n const minValue = 0;\n\n const value = Math.min(Math.max(realValue, minValue), maxValue);\n const widthPercentage = (value / maxValue) * 100;\n\n return (\n <div\n {...filterDOMProps(props, { global: true })}\n className={clsx(styles['sapphire-progress'])}\n >\n <div\n {...progressBarProps}\n className={styles['sapphire-progress--indicator']}\n style={{ ...styleProps, width: `${widthPercentage}%` }}\n aria-label={'aria-label' in props ? props['aria-label'] : undefined}\n aria-labelledby={\n 'aria-labelledby' in props ? props['aria-labelledby'] : undefined\n }\n />\n {segments > 1 && (\n <div className={styles['sapphire-progress--segments']}>\n {Array.from({ length: segments }, (_, index) => (\n <span key={index}></span>\n ))}\n </div>\n )}\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;;AA2CO,MAAM,iBAAA,GAAoB,CAC/B,KAAA,KACgB;AAChB,EAAA,MAAM;AAAA,IACJ,QAAA,GAAW,GAAA;AAAA,IACX,KAAA,EAAO,SAAA;AAAA,IACP,QAAA,GAAW,CAAA;AAAA,IACX,gBAAA,EAAkB;AAAA,GACpB,GAAI,KAAA;AAEJ,EAAA,aAAA,EAAc;AACd,EAAA,MAAM,EAAE,UAAA,EAAW,GAAI,qBAAA,CAAsB,KAAK,CAAA;AAClD,EAAA,MAAM,EAAE,gBAAA,EAAiB,GAAI,cAAA,CAAe;AAAA,IAC1C,GAAG,KAAA;AAAA,IACH,QAAA,EAAU,CAAA;AAAA,IACV,UAAA,EAAY;AAAA,GACb,CAAA;AAED,EAAA,MAAM,QAAA,GAAW,CAAA;AAEjB,EAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,CAAI,IAAA,CAAK,IAAI,SAAA,EAAW,QAAQ,GAAG,QAAQ,CAAA;AAC9D,EAAA,MAAM,eAAA,GAAmB,QAAQ,QAAA,GAAY,GAAA;AAE7C,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,cAAA,CAAe,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAM,CAAA;AAAA,MAC1C,SAAA,EAAW,IAAA,CAAK,MAAA,CAAO,mBAAmB,CAAC;AAAA,KAAA;AAAA,oBAE3C,KAAA,CAAA,aAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACE,GAAG,gBAAA;AAAA,QACJ,SAAA,EAAW,OAAO,8BAA8B,CAAA;AAAA,QAChD,OAAO,EAAE,GAAG,YAAY,KAAA,EAAO,CAAA,EAAG,eAAe,CAAA,CAAA,CAAA,EAAI;AAAA,QACrD,YAAA,EAAY,YAAA,IAAgB,KAAA,GAAQ,KAAA,CAAM,YAAY,CAAA,GAAI,MAAA;AAAA,QAC1D,iBAAA,EACE,iBAAA,IAAqB,KAAA,GAAQ,KAAA,CAAM,iBAAiB,CAAA,GAAI;AAAA;AAAA,KAE5D;AAAA,IACC,QAAA,GAAW,qBACV,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,WAAW,MAAA,CAAO,6BAA6B,CAAA,EAAA,EACjD,KAAA,CAAM,IAAA,CAAK,EAAE,QAAQ,QAAA,EAAS,EAAG,CAAC,CAAA,EAAG,KAAA,yCACnC,MAAA,EAAA,EAAK,GAAA,EAAK,KAAA,EAAO,CACnB,CACH;AAAA,GAEJ;AAEJ;;;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useRef } from 'react';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
|
-
import { filterDOMProps } from '
|
|
3
|
+
import { filterDOMProps } from 'react-aria/filterDOMProps';
|
|
4
4
|
import styles from '@danske/sapphire-css/components/sidebar/sidebar.module.css';
|
|
5
5
|
import { useScrollCheck } from '@danske/sapphire-react';
|
|
6
6
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Body.js","sources":["../../../../src/Sidebar/src/Body.tsx"],"sourcesContent":["import React, { ReactNode, useRef } from 'react';\nimport clsx from 'clsx';\nimport { filterDOMProps } from '
|
|
1
|
+
{"version":3,"file":"Body.js","sources":["../../../../src/Sidebar/src/Body.tsx"],"sourcesContent":["import React, { ReactNode, useRef } from 'react';\nimport clsx from 'clsx';\nimport { filterDOMProps } from 'react-aria/filterDOMProps';\nimport { DOMProps } from '@react-types/shared';\nimport styles from '@danske/sapphire-css/components/sidebar/sidebar.module.css';\nimport { useScrollCheck } from '@danske/sapphire-react';\n\nexport interface SidebarBodyProps extends DOMProps {\n /**\n * Wrapping element type.\n * @default 'nav'\n */\n elementType?: string;\n children?: ReactNode;\n}\n\nexport const SidebarBody = ({\n elementType = 'nav',\n children,\n ...props\n}: SidebarBodyProps): React.JSX.Element => {\n const RootNode = elementType as any;\n const sidebarBody = useRef<HTMLElement>(null);\n const { isScrolled, scrollCheckProps } = useScrollCheck(sidebarBody);\n\n return (\n <RootNode\n ref={sidebarBody}\n tabIndex={\n -1 /* Some browsers will make this focusable because it overflows */\n }\n className={clsx(styles['sapphire-sidebar__body'], {\n [styles['sapphire-sidebar__body--scrolled']]: isScrolled,\n })}\n {...filterDOMProps(props, { global: true })}\n {...scrollCheckProps}\n >\n {children}\n </RootNode>\n );\n};\n"],"names":[],"mappings":";;;;;;AAgBO,MAAM,cAAc,CAAC;AAAA,EAC1B,WAAA,GAAc,KAAA;AAAA,EACd,QAAA;AAAA,EACA,GAAG;AACL,CAAA,KAA2C;AACzC,EAAA,MAAM,QAAA,GAAW,WAAA;AACjB,EAAA,MAAM,WAAA,GAAc,OAAoB,IAAI,CAAA;AAC5C,EAAA,MAAM,EAAE,UAAA,EAAY,gBAAA,EAAiB,GAAI,eAAe,WAAW,CAAA;AAEnE,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,WAAA;AAAA,MACL,QAAA,EACE,EAAA;AAAA,MAEF,SAAA,EAAW,IAAA,CAAK,MAAA,CAAO,wBAAwB,CAAA,EAAG;AAAA,QAChD,CAAC,MAAA,CAAO,kCAAkC,CAAC,GAAG;AAAA,OAC/C,CAAA;AAAA,MACA,GAAG,cAAA,CAAe,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAM,CAAA;AAAA,MACzC,GAAG;AAAA,KAAA;AAAA,IAEH;AAAA,GACH;AAEJ;;;;"}
|
|
@@ -3,10 +3,11 @@ import clsx from 'clsx';
|
|
|
3
3
|
import styles from '@danske/sapphire-css/components/sidebar/sidebar.module.css';
|
|
4
4
|
import buttonStyles from '@danske/sapphire-css/components/button/button.module.css';
|
|
5
5
|
import { Button } from '@danske/sapphire-react';
|
|
6
|
-
import { FocusScope } from '
|
|
6
|
+
import { FocusScope } from 'react-aria/FocusScope';
|
|
7
7
|
import { Transition } from 'react-transition-group';
|
|
8
8
|
import { Sidebar as _Sidebar } from '../index.js';
|
|
9
|
-
import {
|
|
9
|
+
import { mergeProps } from 'react-aria/mergeProps';
|
|
10
|
+
import { useId } from 'react-aria/useId';
|
|
10
11
|
import { useSidebar } from './useSidebar.js';
|
|
11
12
|
import { useSecondarySidebarContext } from './SecondarySidebarContext.js';
|
|
12
13
|
import { useIsSidebarCollapsed } from './ResponsiveSidebarContext.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpandableItem.js","sources":["../../../../src/Sidebar/src/ExpandableItem.tsx"],"sourcesContent":["import React, { ReactNode, useEffect, useLayoutEffect, useRef } from 'react';\nimport clsx from 'clsx';\nimport styles from '@danske/sapphire-css/components/sidebar/sidebar.module.css';\nimport buttonStyles from '@danske/sapphire-css/components/button/button.module.css';\nimport { Button, ButtonProps, ThemeVariant } from '@danske/sapphire-react';\nimport { FocusScope } from '
|
|
1
|
+
{"version":3,"file":"ExpandableItem.js","sources":["../../../../src/Sidebar/src/ExpandableItem.tsx"],"sourcesContent":["import React, { ReactNode, useEffect, useLayoutEffect, useRef } from 'react';\nimport clsx from 'clsx';\nimport styles from '@danske/sapphire-css/components/sidebar/sidebar.module.css';\nimport buttonStyles from '@danske/sapphire-css/components/button/button.module.css';\nimport { Button, ButtonProps, ThemeVariant } from '@danske/sapphire-react';\nimport { FocusScope } from 'react-aria/FocusScope';\nimport { FocusableRef } from '@react-types/shared';\nimport { Transition } from 'react-transition-group';\nimport { Sidebar } from '..';\nimport { mergeProps } from 'react-aria/mergeProps';\nimport { useId } from 'react-aria/useId';\nimport { useSidebar } from './useSidebar';\nimport { useSecondarySidebarContext } from './SecondarySidebarContext';\nimport { useIsSidebarCollapsed } from './ResponsiveSidebarContext';\n\nexport type SidebarExpandableItemProps = Omit<\n ButtonProps<'button'>,\n 'variant' | 'size' | 'elementType'\n> & {\n /**\n * If the link is currently active\n */\n isActive?: boolean;\n\n /**\n * The id of the group.\n * Used in `onSecondarySidebarChange` or when the sidebar is controlled\n */\n id?: string;\n\n /**\n * Heading used for secondary sidebar\n */\n header: ReactNode;\n\n /**\n * Subitems (secondary sidebar)\n */\n body: ReactNode;\n children?: ReactNode;\n};\n\nexport const SidebarExpandableItem = React.forwardRef(\n function SidebarExpandableItem(\n {\n id,\n isActive,\n body,\n header,\n children,\n ...props\n }: SidebarExpandableItemProps,\n ref: FocusableRef<HTMLAnchorElement>\n ): React.JSX.Element {\n const { openedId, setContent, themeVariant } = useSecondarySidebarContext();\n const isCollapsed = useIsSidebarCollapsed();\n const { getExpandableItemProps, secondarySidebarProps } = useSidebar();\n const itemId = useId(id);\n const isOpen = openedId === itemId;\n\n useLayoutEffect(() => {\n if (isOpen) {\n setContent({ header, body });\n }\n }, [isOpen]);\n\n return (\n <li className={clsx(styles['sapphire-sidebar__nav-item'])}>\n <Button\n variant=\"tertiary\"\n aria-current={isActive || undefined}\n ref={ref}\n {...mergeProps(\n getExpandableItemProps(itemId),\n props as ButtonProps<'button'>\n )}\n UNSAFE_className={clsx(\n buttonStyles['sapphire-button--stretch-left-align'],\n {\n [buttonStyles['sapphire-button--selected']]: isActive && !isOpen,\n [buttonStyles['is-active']]: isOpen,\n }\n )}\n >\n {children}\n </Button>\n <SecondarySidebar\n isOpen={isOpen && !isCollapsed}\n header={header}\n themeVariant={themeVariant}\n {...secondarySidebarProps}\n >\n {body}\n </SecondarySidebar>\n </li>\n );\n }\n);\n\nconst SecondarySidebar = ({\n isOpen,\n onClose,\n onCloseTransitionDone,\n themeVariant,\n header,\n children,\n}: {\n isOpen: boolean;\n onClose?: () => void;\n onCloseTransitionDone?: () => void;\n themeVariant?: ThemeVariant;\n header: ReactNode;\n children: ReactNode;\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n onClose?.();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [onClose]);\n\n return (\n <Transition\n in={isOpen}\n mountOnEnter\n nodeRef={ref}\n unmountOnExit\n onExited={onCloseTransitionDone}\n timeout={200}\n >\n {(transitionState) => (\n <div\n ref={ref}\n className={clsx(styles['sapphire-sidebar__secondary-container'], {\n [styles['sapphire-sidebar--slide-in']]: true,\n [styles['sapphire-sidebar--slide-out']]:\n transitionState === 'exiting',\n })}\n >\n <FocusScope restoreFocus autoFocus>\n <Sidebar\n themeVariant={themeVariant}\n closeOnBlurWithin={\n false /* no focus management on nested sidebars */\n }\n header={\n <Sidebar.Header\n closeButtonProps={{\n onPress: () => onClose?.(),\n }}\n >\n {header}\n </Sidebar.Header>\n }\n panelHeader={null}\n >\n {children}\n </Sidebar>\n </FocusScope>\n </div>\n )}\n </Transition>\n );\n};\n"],"names":["SidebarExpandableItem","Sidebar"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
|
-
import { filterDOMProps } from '
|
|
3
|
+
import { filterDOMProps } from 'react-aria/filterDOMProps';
|
|
4
4
|
import styles from '@danske/sapphire-css/components/sidebar/sidebar.module.css';
|
|
5
5
|
import { IconButton } from '@danske/sapphire-react';
|
|
6
6
|
import { CloseLarge } from '@danske/sapphire-icons/react';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Header.js","sources":["../../../../src/Sidebar/src/Header.tsx"],"sourcesContent":["import React, { ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { filterDOMProps } from '
|
|
1
|
+
{"version":3,"file":"Header.js","sources":["../../../../src/Sidebar/src/Header.tsx"],"sourcesContent":["import React, { ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { filterDOMProps } from 'react-aria/filterDOMProps';\nimport { DOMProps } from '@react-types/shared';\nimport styles from '@danske/sapphire-css/components/sidebar/sidebar.module.css';\nimport { IconButton, IconButtonProps } from '@danske/sapphire-react';\nimport { CloseLarge } from '@danske/sapphire-icons/react';\n\nexport interface SidebarHeaderProps extends DOMProps {\n children: ReactNode;\n /**\n * Props for the close button\n * If none provided, close button won't show\n */\n closeButtonProps?: Omit<\n IconButtonProps<'button'>,\n 'children' | 'aria-label' | 'aria-hidden'\n >;\n}\n\nexport const SidebarHeader = ({\n children,\n closeButtonProps,\n ...props\n}: SidebarHeaderProps): React.JSX.Element => {\n return (\n <div\n {...filterDOMProps(props)}\n className={clsx(styles['sapphire-sidebar__header'])}\n >\n {children}\n {closeButtonProps && (\n <IconButton {...closeButtonProps} aria-label=\"Close\">\n <CloseLarge />\n </IconButton>\n )}\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;;AAoBO,MAAM,gBAAgB,CAAC;AAAA,EAC5B,QAAA;AAAA,EACA,gBAAA;AAAA,EACA,GAAG;AACL,CAAA,KAA6C;AAC3C,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,eAAe,KAAK,CAAA;AAAA,MACxB,SAAA,EAAW,IAAA,CAAK,MAAA,CAAO,0BAA0B,CAAC;AAAA,KAAA;AAAA,IAEjD,QAAA;AAAA,IACA,gBAAA,wCACE,UAAA,EAAA,EAAY,GAAG,kBAAkB,YAAA,EAAW,OAAA,EAAA,kBAC3C,KAAA,CAAA,aAAA,CAAC,UAAA,EAAA,IAAW,CACd;AAAA,GAEJ;AAEJ;;;;"}
|
|
@@ -3,7 +3,7 @@ import clsx from 'clsx';
|
|
|
3
3
|
import styles from '@danske/sapphire-css/components/sidebar/sidebar.module.css';
|
|
4
4
|
import buttonStyles from '@danske/sapphire-css/components/button/button.module.css';
|
|
5
5
|
import { Button } from '@danske/sapphire-react';
|
|
6
|
-
import { mergeProps } from '
|
|
6
|
+
import { mergeProps } from 'react-aria/mergeProps';
|
|
7
7
|
import { useSidebar } from './useSidebar.js';
|
|
8
8
|
|
|
9
9
|
const SidebarItem = React.forwardRef(function SidebarItem2({ isActive, children, ...props }, ref) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Item.js","sources":["../../../../src/Sidebar/src/Item.tsx"],"sourcesContent":["import React, { ReactNode } from 'react';\nimport clsx from 'clsx';\nimport styles from '@danske/sapphire-css/components/sidebar/sidebar.module.css';\nimport buttonStyles from '@danske/sapphire-css/components/button/button.module.css';\nimport { Button, ButtonProps } from '@danske/sapphire-react';\nimport { FocusableRef } from '@react-types/shared';\nimport { mergeProps } from '
|
|
1
|
+
{"version":3,"file":"Item.js","sources":["../../../../src/Sidebar/src/Item.tsx"],"sourcesContent":["import React, { ReactNode } from 'react';\nimport clsx from 'clsx';\nimport styles from '@danske/sapphire-css/components/sidebar/sidebar.module.css';\nimport buttonStyles from '@danske/sapphire-css/components/button/button.module.css';\nimport { Button, ButtonProps } from '@danske/sapphire-react';\nimport { FocusableRef } from '@react-types/shared';\nimport { mergeProps } from 'react-aria/mergeProps';\nimport { useSidebar } from './useSidebar';\n\nexport type SidebarItemProps = Omit<\n ButtonProps<'a'>,\n 'variant' | 'size' | 'elementType'\n> & {\n /**\n * If the link is currently active\n */\n isActive?: boolean;\n children?: ReactNode;\n};\n\nexport const SidebarItem = React.forwardRef(function SidebarItem(\n { isActive, children, ...props }: SidebarItemProps,\n ref: FocusableRef<HTMLAnchorElement>\n): React.JSX.Element {\n const { itemProps } = useSidebar();\n\n return (\n <li className={clsx(styles['sapphire-sidebar__nav-item'])}>\n <Button\n ref={ref}\n variant=\"tertiary\"\n elementType=\"a\"\n aria-current={isActive ? 'page' : undefined}\n {...mergeProps(props as ButtonProps<'a'>, itemProps)}\n UNSAFE_className={clsx(\n buttonStyles['sapphire-button--stretch-left-align'],\n { [buttonStyles['sapphire-button--selected']]: isActive }\n )}\n >\n {children}\n </Button>\n </li>\n );\n});\n"],"names":["SidebarItem"],"mappings":";;;;;;;;AAoBO,MAAM,WAAA,GAAc,KAAA,CAAM,UAAA,CAAW,SAASA,YAAAA,CACnD,EAAE,QAAA,EAAU,QAAA,EAAU,GAAG,KAAA,EAAM,EAC/B,GAAA,EACmB;AACnB,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,UAAA,EAAW;AAEjC,EAAA,2CACG,IAAA,EAAA,EAAG,SAAA,EAAW,KAAK,MAAA,CAAO,4BAA4B,CAAC,CAAA,EAAA,kBACtD,KAAA,CAAA,aAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,OAAA,EAAQ,UAAA;AAAA,MACR,WAAA,EAAY,GAAA;AAAA,MACZ,cAAA,EAAc,WAAW,MAAA,GAAS,MAAA;AAAA,MACjC,GAAG,UAAA,CAAW,KAAA,EAA2B,SAAS,CAAA;AAAA,MACnD,gBAAA,EAAkB,IAAA;AAAA,QAChB,aAAa,qCAAqC,CAAA;AAAA,QAClD,EAAE,CAAC,YAAA,CAAa,2BAA2B,CAAC,GAAG,QAAA;AAAS;AAC1D,KAAA;AAAA,IAEC;AAAA,GAEL,CAAA;AAEJ,CAAC;;;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
|
-
import { filterDOMProps } from '
|
|
3
|
+
import { filterDOMProps } from 'react-aria/filterDOMProps';
|
|
4
4
|
import styles from '@danske/sapphire-css/components/sidebar/sidebar.module.css';
|
|
5
5
|
|
|
6
6
|
const SidebarList = ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"List.js","sources":["../../../../src/Sidebar/src/List.tsx"],"sourcesContent":["import React, { ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { filterDOMProps } from '
|
|
1
|
+
{"version":3,"file":"List.js","sources":["../../../../src/Sidebar/src/List.tsx"],"sourcesContent":["import React, { ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { filterDOMProps } from 'react-aria/filterDOMProps';\nimport { DOMProps } from '@react-types/shared';\nimport styles from '@danske/sapphire-css/components/sidebar/sidebar.module.css';\n\nexport interface SidebarListProps extends DOMProps {\n /**\n * Wrapping element type.\n * @default 'ul'\n */\n elementType?: 'ul' | 'ol';\n children?: ReactNode;\n}\n\nexport const SidebarList = ({\n elementType = 'ul',\n children,\n ...props\n}: SidebarListProps): React.JSX.Element => {\n const RootNode = elementType as any;\n\n return (\n <RootNode\n {...filterDOMProps(props, { global: true })}\n className={clsx(styles['sapphire-sidebar__nav-list'])}\n >\n {children}\n </RootNode>\n );\n};\n"],"names":[],"mappings":";;;;;AAeO,MAAM,cAAc,CAAC;AAAA,EAC1B,WAAA,GAAc,IAAA;AAAA,EACd,QAAA;AAAA,EACA,GAAG;AACL,CAAA,KAA2C;AACzC,EAAA,MAAM,QAAA,GAAW,WAAA;AAEjB,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACE,GAAG,cAAA,CAAe,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAM,CAAA;AAAA,MAC1C,SAAA,EAAW,IAAA,CAAK,MAAA,CAAO,4BAA4B,CAAC;AAAA,KAAA;AAAA,IAEnD;AAAA,GACH;AAEJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResponsiveSidebarContext.js","sources":["../../../../src/Sidebar/src/ResponsiveSidebarContext.tsx"],"sourcesContent":["import { useControlledState } from '
|
|
1
|
+
{"version":3,"file":"ResponsiveSidebarContext.js","sources":["../../../../src/Sidebar/src/ResponsiveSidebarContext.tsx"],"sourcesContent":["import { useControlledState } from 'react-stately/useControlledState';\nimport { BreakpointKey, useMatchedBreakpoints } from '@danske/sapphire-react';\nimport React, { ReactNode, useContext } from 'react';\n\nexport interface ResponsiveSidebarContextValue {\n isPanelOpen: boolean;\n setPanelOpen: (open: boolean) => void;\n collapsed: boolean | BreakpointKey | undefined;\n}\n\nexport const ResponsiveSidebarContext =\n React.createContext<ResponsiveSidebarContextValue | null>(null);\n\nexport function useResponsiveSidebarContext() {\n return useContext(ResponsiveSidebarContext);\n}\n\n/**\n * Hook to determine if the sidebar should be collapsed.\n * Returns true if collapsed, false if expanded, or null if not in responsive mode.\n */\nexport function useIsSidebarCollapsed(): boolean | null {\n const context = useContext(ResponsiveSidebarContext);\n const matchedBreakpoints: string[] = useMatchedBreakpoints();\n\n if (!context) {\n return null;\n }\n\n const { collapsed } = context;\n\n // If collapsed is a boolean, use it directly\n if (typeof collapsed === 'boolean') {\n return collapsed;\n }\n\n // If collapsed is a breakpoint string, check if we're below that breakpoint\n if (typeof collapsed === 'string') {\n return !matchedBreakpoints.includes(collapsed);\n }\n\n // If collapsed is undefined, default to 'md' breakpoint behavior\n return !matchedBreakpoints.includes('md');\n}\n\nexport const ResponsiveSidebarProvider = ({\n collapsed,\n isPanelOpen,\n defaultIsPanelOpen,\n onPanelOpenChange,\n children,\n}: {\n /**\n * Controls whether the sidebar is collapsed.\n * - When `true`: sidebar is always collapsed (shows as panel)\n * - When `false`: sidebar is always expanded (shows as sidebar)\n * - When a breakpoint string (e.g., 'md', 'lg'): automatically collapses below that breakpoint\n * - When `undefined`: defaults to 'md' breakpoint behavior (collapses below medium screens)\n * @default undefined (equivalent to 'md')\n */\n collapsed?: boolean | BreakpointKey;\n\n /**\n * If the sidebar panel is open (controlled)\n */\n isPanelOpen?: boolean;\n\n /**\n * The default state of the panel (uncontrolled)\n */\n defaultIsPanelOpen?: boolean;\n\n /**\n * Callback for when the state of the panel changes\n */\n onPanelOpenChange?: (open: boolean) => void;\n children: ReactNode;\n}) => {\n const [isOpen, setOpen] = useControlledState<boolean>(\n isPanelOpen,\n defaultIsPanelOpen ?? false,\n onPanelOpenChange\n );\n\n return (\n <ResponsiveSidebarContext.Provider\n value={{\n isPanelOpen: isOpen,\n setPanelOpen: setOpen,\n collapsed,\n }}\n >\n {children}\n </ResponsiveSidebarContext.Provider>\n );\n};\n"],"names":[],"mappings":";;;;AAUO,MAAM,wBAAA,GACX,KAAA,CAAM,aAAA,CAAoD,IAAI;AAEzD,SAAS,2BAAA,GAA8B;AAC5C,EAAA,OAAO,WAAW,wBAAwB,CAAA;AAC5C;AAMO,SAAS,qBAAA,GAAwC;AACtD,EAAA,MAAM,OAAA,GAAU,WAAW,wBAAwB,CAAA;AACnD,EAAA,MAAM,qBAA+B,qBAAA,EAAsB;AAE3D,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,EAAE,WAAU,GAAI,OAAA;AAGtB,EAAA,IAAI,OAAO,cAAc,SAAA,EAAW;AAClC,IAAA,OAAO,SAAA;AAAA,EACT;AAGA,EAAA,IAAI,OAAO,cAAc,QAAA,EAAU;AACjC,IAAA,OAAO,CAAC,kBAAA,CAAmB,QAAA,CAAS,SAAS,CAAA;AAAA,EAC/C;AAGA,EAAA,OAAO,CAAC,kBAAA,CAAmB,QAAA,CAAS,IAAI,CAAA;AAC1C;AAEO,MAAM,4BAA4B,CAAC;AAAA,EACxC,SAAA;AAAA,EACA,WAAA;AAAA,EACA,kBAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACF,CAAA,KA0BM;AACJ,EAAA,MAAM,CAAC,MAAA,EAAQ,OAAO,CAAA,GAAI,kBAAA;AAAA,IACxB,WAAA;AAAA,IACA,kBAAA,IAAsB,KAAA;AAAA,IACtB;AAAA,GACF;AAEA,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,wBAAA,CAAyB,QAAA;AAAA,IAAzB;AAAA,MACC,KAAA,EAAO;AAAA,QACL,WAAA,EAAa,MAAA;AAAA,QACb,YAAA,EAAc,OAAA;AAAA,QACd;AAAA;AACF,KAAA;AAAA,IAEC;AAAA,GACH;AAEJ;;;;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useContext, useState } from 'react';
|
|
2
|
-
import { useControlledState } from '
|
|
2
|
+
import { useControlledState } from 'react-stately/useControlledState';
|
|
3
3
|
|
|
4
4
|
const SecondarySidebarContext = React.createContext(null);
|
|
5
5
|
const useSecondarySidebarContext = () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecondarySidebarContext.js","sources":["../../../../src/Sidebar/src/SecondarySidebarContext.tsx"],"sourcesContent":["import React, { ReactNode, useContext, useState } from 'react';\nimport { ThemeVariant } from '@danske/sapphire-react';\nimport { useControlledState } from '
|
|
1
|
+
{"version":3,"file":"SecondarySidebarContext.js","sources":["../../../../src/Sidebar/src/SecondarySidebarContext.tsx"],"sourcesContent":["import React, { ReactNode, useContext, useState } from 'react';\nimport { ThemeVariant } from '@danske/sapphire-react';\nimport { useControlledState } from 'react-stately/useControlledState';\n\nexport type SecondarySidebarContent = {\n header: ReactNode;\n body: ReactNode;\n} | null;\n\nexport interface SecondarySidebarContextValue {\n content: SecondarySidebarContent;\n setContent: (content: SecondarySidebarContent) => void;\n openedId: string | null;\n setOpenedId: (id: string | null) => void;\n themeVariant: ThemeVariant | undefined;\n}\n\nexport const SecondarySidebarContext =\n React.createContext<SecondarySidebarContextValue | null>(null);\n\nexport const useSecondarySidebarContext = (): SecondarySidebarContextValue => {\n const context = useContext(SecondarySidebarContext);\n if (context) {\n return context;\n }\n throw new Error('This should be rendered inside a <Sidebar />.');\n};\n\nexport const SecondarySidebarProvider = ({\n openedId,\n defaultOpenedId,\n onOpenedIdChange,\n themeVariant,\n children,\n}: {\n openedId?: string | null;\n defaultOpenedId?: string | null;\n onOpenedIdChange?: (id: string | null) => void;\n themeVariant?: ThemeVariant;\n children: ReactNode;\n}) => {\n const context = useContext(SecondarySidebarContext);\n\n const [secondarySidebarId, setSecondarySidebarId] = useControlledState<\n string | null\n >(openedId, defaultOpenedId ?? null, onOpenedIdChange);\n\n const [content, setContent] = useState<SecondarySidebarContent>(null);\n\n return (\n <SecondarySidebarContext.Provider\n value={{\n openedId: context?.openedId ?? secondarySidebarId,\n setOpenedId: context?.setOpenedId ?? setSecondarySidebarId,\n content: context?.content ?? content,\n setContent: context?.setContent ?? setContent,\n themeVariant: themeVariant ?? context?.themeVariant,\n }}\n >\n {children}\n </SecondarySidebarContext.Provider>\n );\n};\n"],"names":[],"mappings":";;;AAiBO,MAAM,uBAAA,GACX,KAAA,CAAM,aAAA,CAAmD,IAAI;AAExD,MAAM,6BAA6B,MAAoC;AAC5E,EAAA,MAAM,OAAA,GAAU,WAAW,uBAAuB,CAAA;AAClD,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,OAAO,OAAA;AAAA,EACT;AACA,EAAA,MAAM,IAAI,MAAM,+CAA+C,CAAA;AACjE;AAEO,MAAM,2BAA2B,CAAC;AAAA,EACvC,QAAA;AAAA,EACA,eAAA;AAAA,EACA,gBAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF,CAAA,KAMM;AACJ,EAAA,MAAM,OAAA,GAAU,WAAW,uBAAuB,CAAA;AAElD,EAAA,MAAM,CAAC,oBAAoB,qBAAqB,CAAA,GAAI,mBAElD,QAAA,EAAU,eAAA,IAAmB,MAAM,gBAAgB,CAAA;AAErD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAkC,IAAI,CAAA;AAEpE,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,uBAAA,CAAwB,QAAA;AAAA,IAAxB;AAAA,MACC,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,SAAS,QAAA,IAAY,kBAAA;AAAA,QAC/B,WAAA,EAAa,SAAS,WAAA,IAAe,qBAAA;AAAA,QACrC,OAAA,EAAS,SAAS,OAAA,IAAW,OAAA;AAAA,QAC7B,UAAA,EAAY,SAAS,UAAA,IAAc,UAAA;AAAA,QACnC,YAAA,EAAc,gBAAgB,OAAA,EAAS;AAAA;AACzC,KAAA;AAAA,IAEC;AAAA,GACH;AAEJ;;;;"}
|
|
@@ -2,8 +2,8 @@ import React from 'react';
|
|
|
2
2
|
import clsx from 'clsx';
|
|
3
3
|
import styles from '@danske/sapphire-css/components/sidebar/sidebar.module.css';
|
|
4
4
|
import { useThemeCheck, useSapphireStyleProps } from '@danske/sapphire-react';
|
|
5
|
-
import { useListBoxSection } from '
|
|
6
|
-
import { filterDOMProps } from '
|
|
5
|
+
import { useListBoxSection } from 'react-aria/useListBox';
|
|
6
|
+
import { filterDOMProps } from 'react-aria/filterDOMProps';
|
|
7
7
|
|
|
8
8
|
const SidebarSection = ({
|
|
9
9
|
title,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Section.js","sources":["../../../../src/Sidebar/src/Section.tsx"],"sourcesContent":["import React, { ReactNode } from 'react';\nimport clsx from 'clsx';\nimport styles from '@danske/sapphire-css/components/sidebar/sidebar.module.css';\nimport {\n SapphireStyleProps,\n useSapphireStyleProps,\n useThemeCheck,\n} from '@danske/sapphire-react';\nimport { useListBoxSection } from '
|
|
1
|
+
{"version":3,"file":"Section.js","sources":["../../../../src/Sidebar/src/Section.tsx"],"sourcesContent":["import React, { ReactNode } from 'react';\nimport clsx from 'clsx';\nimport styles from '@danske/sapphire-css/components/sidebar/sidebar.module.css';\nimport {\n SapphireStyleProps,\n useSapphireStyleProps,\n useThemeCheck,\n} from '@danske/sapphire-react';\nimport { useListBoxSection } from 'react-aria/useListBox';\nimport { filterDOMProps } from 'react-aria/filterDOMProps';\nimport { DOMProps } from '@react-types/shared';\n\nexport type SidebarSectionProps = DOMProps &\n SapphireStyleProps & {\n /**\n * Section title\n * If not provided, please pass the `aria-label`\n */\n title?: string;\n\n /**\n * Section aria title\n */\n 'aria-label'?: string;\n\n children?: ReactNode;\n };\n\nexport const SidebarSection = ({\n title,\n 'aria-label': label,\n children,\n ...props\n}: SidebarSectionProps) => {\n useThemeCheck();\n const { styleProps } = useSapphireStyleProps(props);\n const { itemProps, headingProps, groupProps } = useListBoxSection({\n heading: title,\n 'aria-label': label,\n });\n\n return (\n <>\n <li\n role=\"separator\"\n className={clsx(styles['sapphire-sidebar__separator'])}\n ></li>\n <li\n {...itemProps}\n {...styleProps}\n {...filterDOMProps(props, { global: true })}\n >\n {title && (\n <div\n {...headingProps}\n className={clsx(styles['sapphire-sidebar__section-header'])}\n >\n {title}\n </div>\n )}\n <ul\n {...groupProps}\n className={clsx(styles['sapphire-sidebar__section'])}\n >\n {children}\n </ul>\n </li>\n </>\n );\n};\n"],"names":[],"mappings":";;;;;;;AA4BO,MAAM,iBAAiB,CAAC;AAAA,EAC7B,KAAA;AAAA,EACA,YAAA,EAAc,KAAA;AAAA,EACd,QAAA;AAAA,EACA,GAAG;AACL,CAAA,KAA2B;AACzB,EAAA,aAAA,EAAc;AACd,EAAA,MAAM,EAAE,UAAA,EAAW,GAAI,qBAAA,CAAsB,KAAK,CAAA;AAClD,EAAA,MAAM,EAAE,SAAA,EAAW,YAAA,EAAc,UAAA,KAAe,iBAAA,CAAkB;AAAA,IAChE,OAAA,EAAS,KAAA;AAAA,IACT,YAAA,EAAc;AAAA,GACf,CAAA;AAED,EAAA,uBACE,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,kBACE,KAAA,CAAA,aAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,WAAA;AAAA,MACL,SAAA,EAAW,IAAA,CAAK,MAAA,CAAO,6BAA6B,CAAC;AAAA;AAAA,GACtD,kBACD,KAAA,CAAA,aAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACE,GAAG,SAAA;AAAA,MACH,GAAG,UAAA;AAAA,MACH,GAAG,cAAA,CAAe,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAM;AAAA,KAAA;AAAA,IAEzC,KAAA,oBACC,KAAA,CAAA,aAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACE,GAAG,YAAA;AAAA,QACJ,SAAA,EAAW,IAAA,CAAK,MAAA,CAAO,kCAAkC,CAAC;AAAA,OAAA;AAAA,MAEzD;AAAA,KACH;AAAA,oBAEF,KAAA,CAAA,aAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACE,GAAG,UAAA;AAAA,QACJ,SAAA,EAAW,IAAA,CAAK,MAAA,CAAO,2BAA2B,CAAC;AAAA,OAAA;AAAA,MAElD;AAAA;AACH,GAEJ,CAAA;AAEJ;;;;"}
|