@danske/sapphire-react-lab 0.96.2 → 0.97.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.
@@ -0,0 +1,74 @@
1
+ import React from 'react';
2
+ import { useThemeCheck, useSapphireStyleProps, Icon, Typography } from '@danske/sapphire-react';
3
+ import { Information, Error, CheckmarkOutline, Warning } from '@danske/sapphire-icons/react';
4
+ import alertStyles from '@danske/sapphire-css/components/alert/alert.module.css';
5
+ import { clsx } from 'clsx';
6
+
7
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
+ var __objRest = (source, exclude) => {
11
+ var target = {};
12
+ for (var prop in source)
13
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
14
+ target[prop] = source[prop];
15
+ if (source != null && __getOwnPropSymbols)
16
+ for (var prop of __getOwnPropSymbols(source)) {
17
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
18
+ target[prop] = source[prop];
19
+ }
20
+ return target;
21
+ };
22
+ function Alert(_a) {
23
+ var _b = _a, {
24
+ children,
25
+ title,
26
+ variant = "info"
27
+ } = _b, props = __objRest(_b, [
28
+ "children",
29
+ "title",
30
+ "variant"
31
+ ]);
32
+ useThemeCheck();
33
+ const {
34
+ styleProps: { style, className }
35
+ } = useSapphireStyleProps(props);
36
+ const getIcon = (variant2) => {
37
+ switch (variant2) {
38
+ case "warning":
39
+ return /* @__PURE__ */ React.createElement(Warning, null);
40
+ case "positive":
41
+ return /* @__PURE__ */ React.createElement(CheckmarkOutline, null);
42
+ case "negative":
43
+ return /* @__PURE__ */ React.createElement(Error, null);
44
+ default:
45
+ return /* @__PURE__ */ React.createElement(Information, null);
46
+ }
47
+ };
48
+ return /* @__PURE__ */ React.createElement("div", {
49
+ className: clsx(alertStyles["sapphire-alert"], {
50
+ [alertStyles["sapphire-alert--positive"]]: variant === "positive",
51
+ [alertStyles["sapphire-alert--negative"]]: variant === "negative",
52
+ [alertStyles["sapphire-alert--warning"]]: variant === "warning"
53
+ }, className),
54
+ style,
55
+ role: "alert"
56
+ }, /* @__PURE__ */ React.createElement("span", {
57
+ className: alertStyles["sapphire-alert__icon"]
58
+ }, /* @__PURE__ */ React.createElement(Icon, {
59
+ size: "sm"
60
+ }, getIcon(variant))), /* @__PURE__ */ React.createElement("div", {
61
+ className: alertStyles["sapphire-alert__title"]
62
+ }, /* @__PURE__ */ React.createElement(Typography.Body, {
63
+ size: "sm",
64
+ isSemibold: true
65
+ }, title)), /* @__PURE__ */ React.createElement("div", {
66
+ className: alertStyles["sapphire-alert__content"]
67
+ }, /* @__PURE__ */ React.createElement(Typography.Body, {
68
+ elementType: "section",
69
+ size: "md"
70
+ }, children)));
71
+ }
72
+
73
+ export { Alert };
74
+ //# sourceMappingURL=Alert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Alert.js","sources":["../../../../src/Alert/src/Alert.tsx"],"sourcesContent":["import React, { ReactNode } from 'react';\nimport {\n SapphireStyleProps,\n useThemeCheck,\n useSapphireStyleProps,\n Typography,\n Icon,\n} from '@danske/sapphire-react';\nimport {\n CheckmarkOutline,\n Information,\n Warning,\n Error,\n} from '@danske/sapphire-icons/react';\nimport alertStyles from '@danske/sapphire-css/components/alert/alert.module.css';\nimport { clsx } from 'clsx';\n\nexport interface SapphireAlertProps extends SapphireStyleProps {\n /**\n * The content of the alert.\n */\n children?: ReactNode;\n\n /**\n * The title of the alert.\n */\n title?: ReactNode;\n\n /**\n * @default 'info'\n */\n variant?: 'info' | 'positive' | 'negative' | 'warning';\n}\n\nexport function Alert({\n children,\n title,\n variant = 'info',\n ...props\n}: SapphireAlertProps) {\n useThemeCheck();\n const {\n styleProps: { style, className },\n } = useSapphireStyleProps(props);\n\n const getIcon = (variant: string) => {\n switch (variant) {\n case 'warning':\n return <Warning />;\n case 'positive':\n return <CheckmarkOutline />;\n case 'negative':\n return <Error />;\n default:\n return <Information />;\n }\n };\n\n return (\n <div\n className={clsx(\n alertStyles['sapphire-alert'],\n {\n [alertStyles['sapphire-alert--positive']]: variant === 'positive',\n [alertStyles['sapphire-alert--negative']]: variant === 'negative',\n [alertStyles['sapphire-alert--warning']]: variant === 'warning',\n },\n className\n )}\n style={style}\n role=\"alert\"\n >\n <span className={alertStyles['sapphire-alert__icon']}>\n <Icon size=\"sm\">{getIcon(variant)}</Icon>\n </span>\n <div className={alertStyles['sapphire-alert__title']}>\n <Typography.Body size=\"sm\" isSemibold>\n {title}\n </Typography.Body>\n </div>\n <div className={alertStyles['sapphire-alert__content']}>\n <Typography.Body elementType=\"section\" size=\"md\">\n {children}\n </Typography.Body>\n </div>\n </div>\n );\n}\n"],"names":["Error2"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAkCO,SAAA,KAAA,CAAe,EAKC,EAAA;AALD,EACpB,IAAA,EAAA,GAAA,EAAA,EAAA;AAAA,IAAA,QAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAU,GAAA,MAAA;AAAA,GAHU,GAAA,EAAA,EAIjB,kBAJiB,EAIjB,EAAA;AAAA,IAHH,UAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAA;AAAA,GAAA,CAAA,CAAA;AAGA,EAAA,aAAA,EAAA,CAAA;AACA,EAAM,MAAA;AAAA,IACJ,UAAA,EAAY,EAAE,KAAO,EAAA,SAAA,EAAA;AAAA,GAAA,GACnB,qBAAsB,CAAA,KAAA,CAAA,CAAA;AAE1B,EAAM,MAAA,OAAA,GAAU,CAAC,QAAoB,KAAA;AACnC,IAAQ,QAAA,QAAA;AAAA,MACD,KAAA,SAAA;AACH,QAAA,2CAAQ,OAAD,EAAA,IAAA,CAAA,CAAA;AAAA,MACJ,KAAA,UAAA;AACH,QAAA,2CAAQ,gBAAD,EAAA,IAAA,CAAA,CAAA;AAAA,MACJ,KAAA,UAAA;AACH,QAAA,2CAAQA,KAAD,EAAA,IAAA,CAAA,CAAA;AAAA,MAAA;AAEP,QAAA,2CAAQ,WAAD,EAAA,IAAA,CAAA,CAAA;AAAA,KAAA;AAAA,GAAA,CAAA;AAIb,EAAA,2CACG,KAAD,EAAA;AAAA,IACE,SAAA,EAAW,IACT,CAAA,WAAA,CAAY,gBACZ,CAAA,EAAA;AAAA,MACG,CAAA,WAAA,CAAY,8BAA8B,OAAY,KAAA,UAAA;AAAA,MACtD,CAAA,WAAA,CAAY,8BAA8B,OAAY,KAAA,UAAA;AAAA,MACtD,CAAA,WAAA,CAAY,6BAA6B,OAAY,KAAA,SAAA;AAAA,KAExD,EAAA,SAAA,CAAA;AAAA,IAEF,KAAA;AAAA,IACA,IAAK,EAAA,OAAA;AAAA,GAAA,sCAEJ,MAAD,EAAA;AAAA,IAAM,WAAW,WAAY,CAAA,sBAAA,CAAA;AAAA,GAAA,sCAC1B,IAAD,EAAA;AAAA,IAAM,IAAK,EAAA,IAAA;AAAA,GAAM,EAAA,OAAA,CAAQ,OAE3B,CAAA,CAAA,CAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,KAAD,EAAA;AAAA,IAAK,WAAW,WAAY,CAAA,uBAAA,CAAA;AAAA,GAC1B,kBAAA,KAAA,CAAA,aAAA,CAAC,WAAW,IAAZ,EAAA;AAAA,IAAiB,IAAK,EAAA,IAAA;AAAA,IAAK,UAAU,EAAA,IAAA;AAAA,GAClC,EAAA,KAAA,CAAA,CAAA,sCAGJ,KAAD,EAAA;AAAA,IAAK,WAAW,WAAY,CAAA,yBAAA,CAAA;AAAA,GAC1B,kBAAA,KAAA,CAAA,aAAA,CAAC,WAAW,IAAZ,EAAA;AAAA,IAAiB,WAAY,EAAA,SAAA;AAAA,IAAU,IAAK,EAAA,IAAA;AAAA,GACzC,EAAA,QAAA,CAAA,CAAA,CAAA,CAAA;AAAA;;;;"}
@@ -2,7 +2,7 @@ import React, { useRef } from 'react';
2
2
  import { VisuallyHidden } from '@react-aria/visually-hidden';
3
3
  import { useEffectEvent } from '@react-aria/utils';
4
4
  import { useControlledState } from '@react-stately/utils';
5
- import { PopoverTrigger, Button, ToggleButton } from '@danske/sapphire-react';
5
+ import { PopoverTrigger, ButtonGroup, Button, ToggleButton } from '@danske/sapphire-react';
6
6
  import { ChevronUp, ChevronDown } from '@danske/sapphire-icons/react';
7
7
  import styles from '@danske/sapphire-css/components/filterDropdown/filterDropdown.module.css';
8
8
 
@@ -54,15 +54,17 @@ function FilterDropdown({
54
54
  className: styles["sapphire-filter-dropdown__body"]
55
55
  }, children), /* @__PURE__ */ React.createElement("div", {
56
56
  className: styles["sapphire-filter-dropdown__footer"]
57
+ }, /* @__PURE__ */ React.createElement(ButtonGroup, {
58
+ align: "right"
57
59
  }, /* @__PURE__ */ React.createElement(Button, {
58
60
  size: buttonSize,
59
- variant: "secondary",
61
+ variant: "text",
60
62
  onPress: () => {
61
63
  close();
62
64
  onClear == null ? void 0 : onClear();
63
65
  },
64
66
  isDisabled: isClearDisabled != null ? isClearDisabled : !hasValue
65
- }, clearButtonLabel), hasApplyButton ? applyButton : /* @__PURE__ */ React.createElement(VisuallyHidden, null, applyButton)))
67
+ }, clearButtonLabel), hasApplyButton ? applyButton : /* @__PURE__ */ React.createElement(VisuallyHidden, null, applyButton))))
66
68
  }, /* @__PURE__ */ React.createElement(ToggleButton, {
67
69
  icon: isOpen ? /* @__PURE__ */ React.createElement(ChevronUp, null) : /* @__PURE__ */ React.createElement(ChevronDown, null),
68
70
  iconAlign: "right",
@@ -1 +1 @@
1
- {"version":3,"file":"FilterDropdown.js","sources":["../../../../src/Filtering/src/FilterDropdown.tsx"],"sourcesContent":["import React, { useRef, ReactNode } from 'react';\nimport { VisuallyHidden } from '@react-aria/visually-hidden';\nimport { useEffectEvent } from '@react-aria/utils';\nimport { useControlledState } from '@react-stately/utils';\nimport {\n Button,\n PopoverTrigger,\n PopoverTriggerProps,\n SapphireStyleProps,\n ToggleButton,\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 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 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 defaultOpen = false,\n hasApplyButton = false,\n noMaxWidth,\n onApply,\n onClear,\n onOpenChange,\n buttonSize = 'md',\n}: FilterDropdownProps): JSX.Element {\n const triggerRef = useRef<FocusableRefValue>(null);\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 apply = () => {\n onApply?.();\n close();\n // We need to manually restore focus to trigger as apply button is a form submit button\n triggerRef.current?.focus();\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 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 onSubmit={apply} className={styles['sapphire-filter-dropdown']}>\n <div className={styles['sapphire-filter-dropdown__body']}>\n {children}\n </div>\n <div className={styles['sapphire-filter-dropdown__footer']}>\n <Button\n size={buttonSize}\n variant=\"secondary\"\n onPress={() => {\n close();\n onClear?.();\n }}\n isDisabled={isClearDisabled ?? !hasValue}\n >\n {clearButtonLabel}\n </Button>\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 </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":";;;;;;;;AAgF+B,SAAA,cAAA,CAAA;AAAA,EAC7B,QAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAa,GAAA,KAAA;AAAA,EACb,eAAkB,GAAA,KAAA;AAAA,EAClB,eAAA;AAAA,EACA,MAAQ,EAAA,UAAA;AAAA,EACR,gBAAmB,GAAA,OAAA;AAAA,EACnB,gBAAmB,GAAA,OAAA;AAAA,EACnB,WAAc,GAAA,KAAA;AAAA,EACd,cAAiB,GAAA,KAAA;AAAA,EACjB,UAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,UAAa,GAAA,IAAA;AAAA,CACsB,EAAA;AACnC,EAAA,MAAM,aAAa,MAA0B,CAAA,IAAA,CAAA,CAAA;AAI7C,EAAA,MAAM,CAAC,MAAQ,EAAA,SAAA,CAAA,GAAa,kBAC1B,CAAA,UAAA,EACA,aACA,cAAe,CAAA,YAAA,CAAA,CAAA,CAAA;AAEjB,EAAM,MAAA,QAAA,GAAW,KAAS,IAAA,IAAA,IAAQ,KAAU,KAAA,EAAA,CAAA;AAC5C,EAAM,MAAA,KAAA,GAAQ,MAAM,SAAU,CAAA,KAAA,CAAA,CAAA;AAC9B,EAAA,MAAM,QAAQ,MAAM;AA7GtB,IAAA,IAAA,EAAA,CAAA;AA8GI,IAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,EAAA,CAAA;AACA,IAAA,KAAA,EAAA,CAAA;AAEA,IAAA,CAAA,EAAA,GAAA,UAAA,CAAW,YAAX,IAAoB,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,KAAA,EAAA,CAAA;AAAA,GAAA,CAAA;AAGtB,EAAM,MAAA,WAAA,uCACH,MAAD,EAAA;AAAA,IACE,IAAK,EAAA,QAAA;AAAA,IACL,IAAM,EAAA,UAAA;AAAA,IACN,qBAAqB,CAAC,cAAA;AAAA,IACtB,UAAY,EAAA,eAAA;AAAA,GAEX,EAAA,gBAAA,CAAA,CAAA;AAGL,EAAA,2CACG,cAAD,EAAA;AAAA,IACE,GAAK,EAAA,UAAA;AAAA,IACL,SAAU,EAAA,aAAA;AAAA,IACV,MAAA;AAAA,IACA,YAAc,EAAA,SAAA;AAAA,IACd,UAAA;AAAA,IACA,SAAS,EAAA,IAAA;AAAA,IACT,cAAA,sCACG,MAAD,EAAA;AAAA,MAAM,QAAU,EAAA,KAAA;AAAA,MAAO,WAAW,MAAO,CAAA,0BAAA,CAAA;AAAA,KAAA,sCACtC,KAAD,EAAA;AAAA,MAAK,WAAW,MAAO,CAAA,gCAAA,CAAA;AAAA,KACpB,EAAA,QAAA,CAAA,sCAEF,KAAD,EAAA;AAAA,MAAK,WAAW,MAAO,CAAA,kCAAA,CAAA;AAAA,KAAA,sCACpB,MAAD,EAAA;AAAA,MACE,IAAM,EAAA,UAAA;AAAA,MACN,OAAQ,EAAA,WAAA;AAAA,MACR,SAAS,MAAM;AACb,QAAA,KAAA,EAAA,CAAA;AACA,QAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,EAAA,CAAA;AAAA,OAAA;AAAA,MAEF,UAAA,EAAY,4CAAmB,CAAC,QAAA;AAAA,KAAA,EAE/B,gBAEF,CAAA,EAAA,cAAA,GACC,WAGA,mBAAA,KAAA,CAAA,aAAA,CAAC,gBAAD,IAAiB,EAAA,WAAA,CAAA,CAAA,CAAA;AAAA,GAAA,sCAMxB,YAAD,EAAA;AAAA,IACE,MAAM,MAAS,mBAAA,KAAA,CAAA,aAAA,CAAC,SAAD,EAAA,IAAA,CAAA,uCAAiB,WAAD,EAAA,IAAA,CAAA;AAAA,IAC/B,SAAU,EAAA,OAAA;AAAA,IACV,UAAY,EAAA,QAAA;AAAA,IACZ,UAAA;AAAA,IACA,IAAM,EAAA,UAAA;AAAA,GAEL,EAAA,KAAA,EACA,KAAQ,GAAA,IAAA,GAAO,EACf,EAAA,KAAA,CAAA,CAAA,CAAA;AAAA;;;;"}
1
+ {"version":3,"file":"FilterDropdown.js","sources":["../../../../src/Filtering/src/FilterDropdown.tsx"],"sourcesContent":["import React, { useRef, ReactNode } from 'react';\nimport { VisuallyHidden } from '@react-aria/visually-hidden';\nimport { useEffectEvent } from '@react-aria/utils';\nimport { useControlledState } from '@react-stately/utils';\nimport {\n Button,\n ButtonGroup,\n PopoverTrigger,\n PopoverTriggerProps,\n SapphireStyleProps,\n ToggleButton,\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 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 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 defaultOpen = false,\n hasApplyButton = false,\n noMaxWidth,\n onApply,\n onClear,\n onOpenChange,\n buttonSize = 'md',\n}: FilterDropdownProps): JSX.Element {\n const triggerRef = useRef<FocusableRefValue>(null);\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 apply = () => {\n onApply?.();\n close();\n // We need to manually restore focus to trigger as apply button is a form submit button\n triggerRef.current?.focus();\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 onSubmit={apply} className={styles['sapphire-filter-dropdown']}>\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 <Button\n size={buttonSize}\n variant=\"text\"\n onPress={() => {\n close();\n onClear?.();\n }}\n isDisabled={isClearDisabled ?? !hasValue}\n >\n {clearButtonLabel}\n </Button>\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":";;;;;;;;AAiF+B,SAAA,cAAA,CAAA;AAAA,EAC7B,QAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAa,GAAA,KAAA;AAAA,EACb,eAAkB,GAAA,KAAA;AAAA,EAClB,eAAA;AAAA,EACA,MAAQ,EAAA,UAAA;AAAA,EACR,gBAAmB,GAAA,OAAA;AAAA,EACnB,gBAAmB,GAAA,OAAA;AAAA,EACnB,WAAc,GAAA,KAAA;AAAA,EACd,cAAiB,GAAA,KAAA;AAAA,EACjB,UAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,UAAa,GAAA,IAAA;AAAA,CACsB,EAAA;AACnC,EAAA,MAAM,aAAa,MAA0B,CAAA,IAAA,CAAA,CAAA;AAI7C,EAAA,MAAM,CAAC,MAAQ,EAAA,SAAA,CAAA,GAAa,kBAC1B,CAAA,UAAA,EACA,aACA,cAAe,CAAA,YAAA,CAAA,CAAA,CAAA;AAEjB,EAAM,MAAA,QAAA,GAAW,KAAS,IAAA,IAAA,IAAQ,KAAU,KAAA,EAAA,CAAA;AAC5C,EAAM,MAAA,KAAA,GAAQ,MAAM,SAAU,CAAA,KAAA,CAAA,CAAA;AAC9B,EAAA,MAAM,QAAQ,MAAM;AA9GtB,IAAA,IAAA,EAAA,CAAA;AA+GI,IAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,EAAA,CAAA;AACA,IAAA,KAAA,EAAA,CAAA;AAEA,IAAA,CAAA,EAAA,GAAA,UAAA,CAAW,YAAX,IAAoB,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,KAAA,EAAA,CAAA;AAAA,GAAA,CAAA;AAGtB,EAAM,MAAA,WAAA,uCACH,MAAD,EAAA;AAAA,IACE,IAAK,EAAA,QAAA;AAAA,IACL,IAAM,EAAA,UAAA;AAAA,IACN,qBAAqB,CAAC,cAAA;AAAA,IACtB,UAAY,EAAA,eAAA;AAAA,GAEX,EAAA,gBAAA,CAAA,CAAA;AAIL,EAAA,2CACG,cAAD,EAAA;AAAA,IACE,GAAK,EAAA,UAAA;AAAA,IACL,SAAU,EAAA,aAAA;AAAA,IACV,MAAA;AAAA,IACA,YAAc,EAAA,SAAA;AAAA,IACd,UAAA;AAAA,IACA,SAAS,EAAA,IAAA;AAAA,IACT,cAAA,sCACG,MAAD,EAAA;AAAA,MAAM,QAAU,EAAA,KAAA;AAAA,MAAO,WAAW,MAAO,CAAA,0BAAA,CAAA;AAAA,KAAA,sCACtC,KAAD,EAAA;AAAA,MAAK,WAAW,MAAO,CAAA,gCAAA,CAAA;AAAA,KACpB,EAAA,QAAA,CAAA,sCAEF,KAAD,EAAA;AAAA,MAAK,WAAW,MAAO,CAAA,kCAAA,CAAA;AAAA,KAAA,sCACpB,WAAD,EAAA;AAAA,MAAa,KAAM,EAAA,OAAA;AAAA,KAAA,sCAChB,MAAD,EAAA;AAAA,MACE,IAAM,EAAA,UAAA;AAAA,MACN,OAAQ,EAAA,MAAA;AAAA,MACR,SAAS,MAAM;AACb,QAAA,KAAA,EAAA,CAAA;AACA,QAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,EAAA,CAAA;AAAA,OAAA;AAAA,MAEF,UAAA,EAAY,4CAAmB,CAAC,QAAA;AAAA,KAAA,EAE/B,gBAEF,CAAA,EAAA,cAAA,GACC,WAGA,mBAAA,KAAA,CAAA,aAAA,CAAC,gBAAD,IAAiB,EAAA,WAAA,CAAA,CAAA,CAAA,CAAA;AAAA,GAAA,sCAO1B,YAAD,EAAA;AAAA,IACE,MAAM,MAAS,mBAAA,KAAA,CAAA,aAAA,CAAC,SAAD,EAAA,IAAA,CAAA,uCAAiB,WAAD,EAAA,IAAA,CAAA;AAAA,IAC/B,SAAU,EAAA,OAAA;AAAA,IACV,UAAY,EAAA,QAAA;AAAA,IACZ,UAAA;AAAA,IACA,IAAM,EAAA,UAAA;AAAA,GAEL,EAAA,KAAA,EACA,KAAQ,GAAA,IAAA,GAAO,EACf,EAAA,KAAA,CAAA,CAAA,CAAA;AAAA;;;;"}
@@ -8,16 +8,19 @@ import '../../FileDropzone/src/FileDropzone.js';
8
8
  import '../../FileDropzone/src/FileTrigger.js';
9
9
  import '../../Flag/src/Flag.js';
10
10
  import '../../NumberField/src/NumberField.js';
11
+ import 'clsx';
12
+ import '@danske/sapphire-css/components/progressIndicator/progressIndicator.module.css';
13
+ import '@react-aria/progress';
11
14
  import '@react-aria/tag';
12
15
  import '@react-stately/list';
13
16
  import '@danske/sapphire-css/components/tag/tag.module.css';
14
- import 'clsx';
15
17
  import '@react-aria/button';
16
18
  import '@react-aria/interactions';
17
19
  import '@danske/sapphire-icons/react';
18
20
  import '@react-aria/focus';
19
21
  import '@react-stately/collections';
20
22
  import '@react-aria/label';
23
+ import '@danske/sapphire-css/components/alert/alert.module.css';
21
24
  import '@react-aria/i18n';
22
25
 
23
26
  var __defProp = Object.defineProperty;
@@ -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} from '@danske/sapphire-react';\nimport { FilterDropdown, FilterDropdownProps } from '../..';\nimport { mergeRefs } from '@react-aria/utils';\nimport { useControlledState } from '@react-stately/utils';\n\nexport interface SearchableSelectFilterProps\n extends 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCO,SAAA,sBAAA,CACL,KACa,EAAA;AAnCf,EAAA,IAAA,EAAA,EAAA,EAAA,CAAA;AAoCE,EAA6D,MAAA,EAAA,GAAA,KAAA,EAArD,EAAa,WAAA,EAAA,OAAA,EAAS,IAAO,GAAA,IAAA,EAAA,GAAwB,IAAf,UAAe,GAAA,SAAA,CAAA,EAAA,EAAf,CAAtC,aAAA,EAAa,SAAS,EAAA,MAAA,CAAA,CAAA,CAAA;AAC9B,EAAA,MAAM,iBAAiB,MAAyB,CAAA,IAAA,CAAA,CAAA;AAEhD,EAAA,MAAM,mBAAmB,WAAY,CAAA,KAAA,CAAA;AACrC,EAAA,MAAM,eAAe,OAAQ,CAAA,KAAA,CAAA;AAE7B,EAAA,MAAM,CAAC,WAAa,EAAA,cAAA,CAAA,GAAkB,mBACpC,gBAAkB,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,gBAAA,CAAA,KAAA,EAClB,IACA,gBAAiB,CAAA,QAAA,CAAA,CAAA;AAGnB,EACE,IAAA,YAAA,CAAa,qBACb,OAAO,OAAA,KAAY,eACnB,CAAQ,CAAA,EAAA,GAAA,OAAA,CAAA,GAAA,KAAR,IAAa,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,QAAA,MAAa,aAC1B,EAAA;AAEA,IAAA,OAAA,CAAQ,IACN,CAAA,6NAAA,CAAA,CAAA;AAAA,GAAA;AAIJ,EAAM,MAAA,YAAA,GACJ,aAAa,YAAiB,KAAA,KAAA,IAC9B,MAAM,IAAK,CAAA,YAAA,CAAa,YAAgB,IAAA,EAAA,CAAA,CAAI,MAAS,GAAA,CAAA,CAAA;AAEvD,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,cAAD,EAAA,aAAA,CAAA,cAAA,CAAA,EAAA,EACM,UADN,CAAA,EAAA;AAAA,IAEE,UAAA,EAAY,CAAW,EAAA,GAAA,UAAA,CAAA,UAAA,KAAX,IAAyB,GAAA,EAAA,GAAA,IAAA;AAAA,IACrC,UAAY,EAAA,IAAA;AAAA,IAGZ,cAAA,EAAgB,QAAQ,UAAW,CAAA,OAAA,CAAA;AAAA,IAGnC,iBACE,UAAW,CAAA,eAAA,IAAoB,CAAC,YAAA,IAAgB,CAAC,UAAW,CAAA,KAAA;AAAA,GAAA,CAAA,sCAG7D,IAAD,EAAA;AAAA,IAAM,aAAc,EAAA,QAAA;AAAA,IAAS,MAAO,EAAA,MAAA;AAAA,GAAA,EACjC,aAAa,WAAa,EAAA;AAAA,IACzB,IAAM,EAAA,IAAA;AAAA,IACN,KAAA,EAAO,iBAAiB,KAAS,IAAA,WAAA;AAAA,IACjC,QAAA,EAAU,SAAU,CAAA,cAAA,EAAgB,gBAAiB,CAAA,QAAA,CAAA;AAAA,IACrD,KAAA,EAAO,iBAAiB,KAAS,IAAA,MAAA;AAAA,IACjC,YAAc,EAAA,gBAAA,CAAiB,YAAgB,IAAA,MAAA,CAAO,IAAK,CAAA,SAAA;AAAA,IAC3D,QAAU,EAAA,cAAA;AAAA,GAAA,CAAA,EAEX,aAAa,OAAS,EAAA;AAAA,IACrB,iBAAmB,EAAA,cAAA;AAAA,IACnB,aAAA,EAAe,aAAa,aAAiB,IAAA,UAAA;AAAA,IAC7C,OAAS,EAAA,CAAA,KAAA,EAAQ,MAAO,CAAA,IAAA,CAAK,4BAA6B,CAAA,KAAA,CAAA,MAAA,CAAA;AAAA,IAC1D,iBAAmB,EAAA,IAAA;AAAA,IACnB,MAAA,EAGE,QAAY,IAAA,YAAA,GACR,YAAa,CAAA,MAAA,GACb,CAAC,SACC,KAAA,SAAA,CAAU,WAAc,EAAA,CAAA,QAAA,CAAS,WAAY,CAAA,WAAA,EAAA,CAAA;AAAA,GAAA,CAAA,CAAA,CAAA,CAAA;AAAA;;;;"}
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} from '@danske/sapphire-react';\nimport { FilterDropdown, FilterDropdownProps } from '../..';\nimport { mergeRefs } from '@react-aria/utils';\nimport { useControlledState } from '@react-stately/utils';\n\nexport interface SearchableSelectFilterProps\n extends 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCO,SAAA,sBAAA,CACL,KACa,EAAA;AAnCf,EAAA,IAAA,EAAA,EAAA,EAAA,CAAA;AAoCE,EAA6D,MAAA,EAAA,GAAA,KAAA,EAArD,EAAa,WAAA,EAAA,OAAA,EAAS,IAAO,GAAA,IAAA,EAAA,GAAwB,IAAf,UAAe,GAAA,SAAA,CAAA,EAAA,EAAf,CAAtC,aAAA,EAAa,SAAS,EAAA,MAAA,CAAA,CAAA,CAAA;AAC9B,EAAA,MAAM,iBAAiB,MAAyB,CAAA,IAAA,CAAA,CAAA;AAEhD,EAAA,MAAM,mBAAmB,WAAY,CAAA,KAAA,CAAA;AACrC,EAAA,MAAM,eAAe,OAAQ,CAAA,KAAA,CAAA;AAE7B,EAAA,MAAM,CAAC,WAAa,EAAA,cAAA,CAAA,GAAkB,mBACpC,gBAAkB,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,gBAAA,CAAA,KAAA,EAClB,IACA,gBAAiB,CAAA,QAAA,CAAA,CAAA;AAGnB,EACE,IAAA,YAAA,CAAa,qBACb,OAAO,OAAA,KAAY,eACnB,CAAQ,CAAA,EAAA,GAAA,OAAA,CAAA,GAAA,KAAR,IAAa,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,QAAA,MAAa,aAC1B,EAAA;AAEA,IAAA,OAAA,CAAQ,IACN,CAAA,6NAAA,CAAA,CAAA;AAAA,GAAA;AAIJ,EAAM,MAAA,YAAA,GACJ,aAAa,YAAiB,KAAA,KAAA,IAC9B,MAAM,IAAK,CAAA,YAAA,CAAa,YAAgB,IAAA,EAAA,CAAA,CAAI,MAAS,GAAA,CAAA,CAAA;AAEvD,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,cAAD,EAAA,aAAA,CAAA,cAAA,CAAA,EAAA,EACM,UADN,CAAA,EAAA;AAAA,IAEE,UAAA,EAAY,CAAW,EAAA,GAAA,UAAA,CAAA,UAAA,KAAX,IAAyB,GAAA,EAAA,GAAA,IAAA;AAAA,IACrC,UAAY,EAAA,IAAA;AAAA,IAGZ,cAAA,EAAgB,QAAQ,UAAW,CAAA,OAAA,CAAA;AAAA,IAGnC,iBACE,UAAW,CAAA,eAAA,IAAoB,CAAC,YAAA,IAAgB,CAAC,UAAW,CAAA,KAAA;AAAA,GAAA,CAAA,sCAG7D,IAAD,EAAA;AAAA,IAAM,aAAc,EAAA,QAAA;AAAA,IAAS,MAAO,EAAA,MAAA;AAAA,GAAA,EACjC,aAAa,WAAa,EAAA;AAAA,IACzB,IAAM,EAAA,IAAA;AAAA,IACN,KAAA,EAAO,iBAAiB,KAAS,IAAA,WAAA;AAAA,IACjC,QAAA,EAAU,SAAU,CAAA,cAAA,EAAgB,gBAAiB,CAAA,QAAA,CAAA;AAAA,IACrD,KAAA,EAAO,iBAAiB,KAAS,IAAA,MAAA;AAAA,IACjC,YAAc,EAAA,gBAAA,CAAiB,YAAgB,IAAA,MAAA,CAAO,IAAK,CAAA,SAAA;AAAA,IAC3D,QAAU,EAAA,cAAA;AAAA,GAAA,CAAA,EAEX,aAAa,OAAS,EAAA;AAAA,IACrB,iBAAmB,EAAA,cAAA;AAAA,IACnB,aAAA,EAAe,aAAa,aAAiB,IAAA,UAAA;AAAA,IAC7C,OAAS,EAAA,CAAA,KAAA,EAAQ,MAAO,CAAA,IAAA,CAAK,4BAA6B,CAAA,KAAA,CAAA,MAAA,CAAA;AAAA,IAC1D,iBAAmB,EAAA,IAAA;AAAA,IACnB,MAAA,EAGE,QAAY,IAAA,YAAA,GACR,YAAa,CAAA,MAAA,GACb,CAAC,SACC,KAAA,SAAA,CAAU,WAAc,EAAA,CAAA,QAAA,CAAS,WAAY,CAAA,WAAA,EAAA,CAAA;AAAA,GAAA,CAAA,CAAA,CAAA,CAAA;AAAA;;;;"}
@@ -0,0 +1,57 @@
1
+ import React from 'react';
2
+ import clsx from 'clsx';
3
+ import styles from '@danske/sapphire-css/components/progressIndicator/progressIndicator.module.css';
4
+ import { useThemeCheck, useSapphireStyleProps } from '@danske/sapphire-react';
5
+ import { useProgressBar } from '@react-aria/progress';
6
+
7
+ var __defProp = Object.defineProperty;
8
+ var __defProps = Object.defineProperties;
9
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
10
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
11
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
12
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
13
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
14
+ var __spreadValues = (a, b) => {
15
+ for (var prop in b || (b = {}))
16
+ if (__hasOwnProp.call(b, prop))
17
+ __defNormalProp(a, prop, b[prop]);
18
+ if (__getOwnPropSymbols)
19
+ for (var prop of __getOwnPropSymbols(b)) {
20
+ if (__propIsEnum.call(b, prop))
21
+ __defNormalProp(a, prop, b[prop]);
22
+ }
23
+ return a;
24
+ };
25
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
26
+ const ProgressIndicator = (props) => {
27
+ const {
28
+ maxValue = 100,
29
+ value: realValue,
30
+ segments = 1,
31
+ "aria-valuetext": ariaValueText
32
+ } = props;
33
+ useThemeCheck();
34
+ const { styleProps } = useSapphireStyleProps(props);
35
+ const { progressBarProps } = useProgressBar(__spreadProps(__spreadValues({}, props), {
36
+ minValue: 0,
37
+ valueLabel: ariaValueText
38
+ }));
39
+ const minValue = 0;
40
+ const value = Math.min(Math.max(realValue, minValue), maxValue);
41
+ const widthPercentage = value / maxValue * 100;
42
+ return /* @__PURE__ */ React.createElement("div", {
43
+ className: clsx(styles["sapphire-progress"])
44
+ }, /* @__PURE__ */ React.createElement("div", __spreadProps(__spreadValues({}, progressBarProps), {
45
+ className: styles["sapphire-progress--indicator"],
46
+ style: __spreadProps(__spreadValues({}, styleProps), { width: `${widthPercentage}%` }),
47
+ "aria-label": "aria-label" in props ? props["aria-label"] : void 0,
48
+ "aria-labelledby": "aria-labelledby" in props ? props["aria-labelledby"] : void 0
49
+ })), segments > 1 && /* @__PURE__ */ React.createElement("div", {
50
+ className: styles["sapphire-progress--segments"]
51
+ }, Array.from({ length: segments }, (_, index) => /* @__PURE__ */ React.createElement("span", {
52
+ key: index
53
+ }))));
54
+ };
55
+
56
+ export { ProgressIndicator };
57
+ //# sourceMappingURL=ProgressIndicator.js.map
@@ -0,0 +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} from '@danske/sapphire-react';\nimport { useProgressBar } from '@react-aria/progress';\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 ({ '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 className={clsx(styles['sapphire-progress'])}>\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":";;;;;;;;;;;;;;;;;;;;;;;;;AAwCa,MAAA,iBAAA,GAAoB,CAC/B,KACgB,KAAA;AAChB,EAAM,MAAA;AAAA,IACJ,QAAW,GAAA,GAAA;AAAA,IACX,KAAO,EAAA,SAAA;AAAA,IACP,QAAW,GAAA,CAAA;AAAA,IACX,gBAAkB,EAAA,aAAA;AAAA,GAChB,GAAA,KAAA,CAAA;AAEJ,EAAA,aAAA,EAAA,CAAA;AACA,EAAM,MAAA,EAAE,eAAe,qBAAsB,CAAA,KAAA,CAAA,CAAA;AAC7C,EAAA,MAAM,EAAE,gBAAA,EAAA,GAAqB,cAAe,CAAA,aAAA,CAAA,cAAA,CAAA,EAAA,EACvC,KADuC,CAAA,EAAA;AAAA,IAE1C,QAAU,EAAA,CAAA;AAAA,IACV,UAAY,EAAA,aAAA;AAAA,GAAA,CAAA,CAAA,CAAA;AAGd,EAAA,MAAM,QAAW,GAAA,CAAA,CAAA;AAEjB,EAAA,MAAM,QAAQ,IAAK,CAAA,GAAA,CAAI,IAAK,CAAA,GAAA,CAAI,WAAW,QAAW,CAAA,EAAA,QAAA,CAAA,CAAA;AACtD,EAAM,MAAA,eAAA,GAAmB,QAAQ,QAAY,GAAA,GAAA,CAAA;AAE7C,EAAA,2CACG,KAAD,EAAA;AAAA,IAAK,SAAA,EAAW,KAAK,MAAO,CAAA,mBAAA,CAAA,CAAA;AAAA,GAC1B,kBAAA,KAAA,CAAA,aAAA,CAAC,KAAD,EAAA,aAAA,CAAA,cAAA,CAAA,EAAA,EACM,gBADN,CAAA,EAAA;AAAA,IAEE,WAAW,MAAO,CAAA,8BAAA,CAAA;AAAA,IAClB,KAAO,EAAA,aAAA,CAAA,cAAA,CAAA,EAAA,EAAK,UAAL,CAAA,EAAA,EAAiB,OAAO,CAAG,EAAA,eAAA,CAAA,CAAA,CAAA,EAAA,CAAA;AAAA,IAClC,YAAY,EAAA,YAAA,IAAgB,KAAQ,GAAA,KAAA,CAAM,YAAgB,CAAA,GAAA,KAAA,CAAA;AAAA,IAC1D,iBACE,EAAA,iBAAA,IAAqB,KAAQ,GAAA,KAAA,CAAM,iBAAqB,CAAA,GAAA,KAAA,CAAA;AAAA,GAG3D,CAAA,CAAA,EAAA,QAAA,GAAW,CACV,oBAAA,KAAA,CAAA,aAAA,CAAC,KAAD,EAAA;AAAA,IAAK,WAAW,MAAO,CAAA,6BAAA,CAAA;AAAA,GACpB,EAAA,KAAA,CAAM,KAAK,EAAE,MAAA,EAAQ,YAAY,CAAC,CAAA,EAAG,KACpC,qBAAA,KAAA,CAAA,aAAA,CAAC,MAAD,EAAA;AAAA,IAAM,GAAK,EAAA,KAAA;AAAA,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA;AAAA;;;;"}
@@ -5,9 +5,11 @@ export { FileDropzone } from './FileDropzone/src/FileDropzone.js';
5
5
  export { FileTrigger } from './FileDropzone/src/FileTrigger.js';
6
6
  export { Flag } from './Flag/src/Flag.js';
7
7
  export { NumberField } from './NumberField/src/NumberField.js';
8
+ export { ProgressIndicator } from './ProgressIndicator/src/ProgressIndicator.js';
8
9
  export { TagGroup } from './TagGroup/src/TagGroup.js';
9
10
  export { TagItem } from './TagGroup/src/TagItem.js';
10
11
  export { LabeledValue } from './LabeledValue/src/LabeledValue.js';
12
+ export { Alert } from './Alert/src/Alert.js';
11
13
  export { useLocale } from '@react-aria/i18n';
12
14
  export { AccordionContext } from './Accordion/src/AccordionContext.js';
13
15
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
package/build/index.d.ts CHANGED
@@ -276,6 +276,37 @@ interface NumberFieldProps extends SapphireNumberFieldProps, PressEvents, Sapphi
276
276
  }
277
277
  declare const NumberField: React__default.ForwardRefExoticComponent<NumberFieldProps & React__default.RefAttributes<NumberFieldRef>>;
278
278
 
279
+ declare type ProgressIndicatorProps = {
280
+ /**
281
+ * The maximum value for the progress bar. Will be used as:
282
+ * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-valuemax
283
+ *
284
+ * @default 100
285
+ */
286
+ maxValue?: number;
287
+ /**
288
+ * The current value of the progress bar. Will be used as:
289
+ * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-valuenow
290
+ */
291
+ value: number;
292
+ /**
293
+ * Defines how many segments the progress bar will have.
294
+ *
295
+ * @default 1
296
+ */
297
+ segments?: number;
298
+ /**
299
+ * Human-readable text alternative for the current value of the progress bar. Will be used as:
300
+ * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-valuetext
301
+ */
302
+ 'aria-valuetext'?: string;
303
+ } & SapphireStyleProps & ({
304
+ 'aria-labelledby': string;
305
+ } | {
306
+ 'aria-label': string;
307
+ });
308
+ declare const ProgressIndicator: (props: ProgressIndicatorProps) => JSX.Element;
309
+
279
310
  interface TagGroupProps<T> extends CollectionBase<T>, DOMProps, Pick<AriaLabelingProps, 'aria-label' | 'aria-labelledby' | 'aria-describedby' | 'aria-details'>, SapphireStyleProps {
280
311
  /**
281
312
  * A HelpButton element to place next to the label.
@@ -355,4 +386,20 @@ interface LabeledValueProps extends DOMProps, SapphireStyleProps {
355
386
  }
356
387
  declare function LabeledValue({ children, contextualHelp, label, labelPlacement, size, ...otherProps }: LabeledValueProps): React__default.JSX.Element;
357
388
 
358
- export { _Accordion as Accordion, AccordionContext, AccordionHeadingProps, AccordionItemProps, AccordionProps, FileDropzone, FileDropzoneProps, FileTrigger, FileTriggerProps, FilterDropdown, FilterDropdownProps, Flag, FlagProps, LabeledValue, NumberField, NumberFieldProps, NumberFieldRef, SearchableSelectFilter, SearchableSelectFilterProps, TagGroup, TagGroupProps, TagItem };
389
+ interface SapphireAlertProps extends SapphireStyleProps {
390
+ /**
391
+ * The content of the alert.
392
+ */
393
+ children?: ReactNode;
394
+ /**
395
+ * The title of the alert.
396
+ */
397
+ title?: ReactNode;
398
+ /**
399
+ * @default 'info'
400
+ */
401
+ variant?: 'info' | 'positive' | 'negative' | 'warning';
402
+ }
403
+ declare function Alert({ children, title, variant, ...props }: SapphireAlertProps): React__default.JSX.Element;
404
+
405
+ export { _Accordion as Accordion, AccordionContext, AccordionHeadingProps, AccordionItemProps, AccordionProps, Alert, FileDropzone, FileDropzoneProps, FileTrigger, FileTriggerProps, FilterDropdown, FilterDropdownProps, Flag, FlagProps, LabeledValue, NumberField, NumberFieldProps, NumberFieldRef, ProgressIndicator, ProgressIndicatorProps, SapphireAlertProps, SearchableSelectFilter, SearchableSelectFilterProps, TagGroup, TagGroupProps, TagItem };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danske/sapphire-react-lab",
3
- "version": "0.96.2",
3
+ "version": "0.97.0",
4
4
  "license": "SEE LICENSE IN LICENSE",
5
5
  "description": "Experimental React components of the Sapphire Design System from Danske Bank A/S",
6
6
  "exports": {
@@ -25,46 +25,47 @@
25
25
  },
26
26
  "peerDependencies": {
27
27
  "@danske/sapphire-icons": "^3.1.0",
28
- "@danske/sapphire-react": "^5.0.0",
28
+ "@danske/sapphire-react": "^5.3.0",
29
29
  "react": ">=16.8.0",
30
30
  "react-dom": ">=16.8.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@danske/sapphire-icons": "^3.1.0",
34
- "@danske/sapphire-react": "^5.1.0",
34
+ "@danske/sapphire-react": "^5.3.0",
35
35
  "@types/react-transition-group": "^4.4.5",
36
36
  "cross-env": "^7.0.3"
37
37
  },
38
38
  "dependencies": {
39
- "@danske/sapphire-css": "^40.2.0",
39
+ "@danske/sapphire-css": "^42.0.0",
40
40
  "@internationalized/date": "^3.6.0",
41
41
  "@internationalized/string": "^3.2.5",
42
- "@react-aria/accordion": "^3.0.0-alpha.37",
43
- "@react-aria/button": "^3.13.2",
44
- "@react-aria/combobox": "^3.12.4",
45
- "@react-aria/dialog": "^3.5.26",
46
- "@react-aria/dnd": "^3.10.0",
47
- "@react-aria/focus": "^3.20.4",
48
- "@react-aria/i18n": "^3.12.10",
49
- "@react-aria/interactions": "^3.25.2",
50
- "@react-aria/label": "^3.7.19",
51
- "@react-aria/numberfield": "^3.11.15",
52
- "@react-aria/overlays": "^3.27.2",
53
- "@react-aria/tag": "^3.6.1",
54
- "@react-aria/utils": "^3.29.1",
55
- "@react-aria/visually-hidden": "^3.8.24",
42
+ "@react-aria/accordion": "3.0.0-alpha.37",
43
+ "@react-aria/button": "^3.14.0",
44
+ "@react-aria/combobox": "^3.13.0",
45
+ "@react-aria/dialog": "^3.5.28",
46
+ "@react-aria/dnd": "^3.11.0",
47
+ "@react-aria/focus": "^3.21.0",
48
+ "@react-aria/i18n": "^3.12.11",
49
+ "@react-aria/interactions": "^3.25.4",
50
+ "@react-aria/label": "^3.7.20",
51
+ "@react-aria/numberfield": "^3.12.0",
52
+ "@react-aria/overlays": "^3.28.0",
53
+ "@react-aria/progress": "^3.4.24",
54
+ "@react-aria/tag": "^3.7.0",
55
+ "@react-aria/utils": "^3.30.0",
56
+ "@react-aria/visually-hidden": "^3.8.26",
56
57
  "@react-spectrum/utils": "^3.12.5",
57
- "@react-stately/collections": "^3.12.5",
58
- "@react-stately/combobox": "^3.10.6",
59
- "@react-stately/list": "^3.12.3",
60
- "@react-stately/numberfield": "^3.9.13",
61
- "@react-stately/toggle": "^3.8.5",
62
- "@react-stately/tree": "^3.9.0",
63
- "@react-stately/utils": "^3.10.7",
64
- "@react-types/dialog": "^3.5.18",
65
- "@react-types/shared": "^3.29.1",
58
+ "@react-stately/collections": "^3.12.6",
59
+ "@react-stately/combobox": "^3.11.0",
60
+ "@react-stately/list": "^3.12.4",
61
+ "@react-stately/numberfield": "^3.10.0",
62
+ "@react-stately/toggle": "^3.9.0",
63
+ "@react-stately/tree": "^3.9.1",
64
+ "@react-stately/utils": "^3.10.8",
65
+ "@react-types/dialog": "^3.5.20",
66
+ "@react-types/shared": "^3.31.0",
66
67
  "clsx": "^1.1.1",
67
68
  "react-transition-group": "^4.4.5"
68
69
  },
69
- "gitHead": "e1d288a48bcd633f5e7a6f89e50be28ff3faa43c"
70
+ "gitHead": "afb5a25463f39012c3599e6242c8d308786d11e1"
70
71
  }