@digdir/designsystemet-react 1.0.0-next.48 → 1.0.0-next.50

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.
Files changed (119) hide show
  1. package/dist/cjs/components/Badge/Badge.js +2 -2
  2. package/dist/cjs/components/Button/Button.js +1 -1
  3. package/dist/cjs/components/Card/Card.js +2 -2
  4. package/dist/cjs/components/Combobox/Combobox.js +0 -2
  5. package/dist/cjs/components/Details/Details.js +2 -2
  6. package/dist/cjs/components/Dialog/Dialog.js +74 -0
  7. package/dist/cjs/components/Dialog/DialogBlock.js +30 -0
  8. package/dist/cjs/components/Dialog/DialogTrigger.js +27 -0
  9. package/dist/cjs/components/Dialog/DialogTriggerContext.js +28 -0
  10. package/dist/cjs/components/Dialog/index.js +34 -0
  11. package/dist/cjs/components/Popover/Popover.js +2 -2
  12. package/dist/cjs/components/Suggestion/Suggestion.js +2 -3
  13. package/dist/cjs/components/Suggestion/SuggestionEmpty.js +4 -4
  14. package/dist/cjs/index.js +10 -10
  15. package/dist/cjs/{components/Pagination → utilities/hooks/usePagination}/usePagination.js +10 -1
  16. package/dist/esm/components/Badge/Badge.js +2 -2
  17. package/dist/esm/components/Button/Button.js +2 -2
  18. package/dist/esm/components/Card/Card.js +2 -2
  19. package/dist/esm/components/Chip/Chips.js +1 -1
  20. package/dist/esm/components/Chip/index.js +1 -1
  21. package/dist/esm/components/Combobox/Combobox.js +1 -3
  22. package/dist/esm/components/Combobox/ComboboxIdContext.js +1 -1
  23. package/dist/esm/components/Combobox/useFloatingCombobox.js +1 -1
  24. package/dist/esm/components/Details/Details.js +2 -2
  25. package/dist/esm/components/Dialog/Dialog.js +72 -0
  26. package/dist/esm/components/Dialog/DialogBlock.js +28 -0
  27. package/dist/esm/components/{Modal/ModalTrigger.js → Dialog/DialogTrigger.js} +9 -9
  28. package/dist/esm/components/Dialog/DialogTriggerContext.js +25 -0
  29. package/dist/esm/components/Dialog/index.js +29 -0
  30. package/dist/esm/components/ErrorSummary/ErrorSummary.js +1 -1
  31. package/dist/esm/components/Field/index.js +1 -1
  32. package/dist/esm/components/List/index.js +1 -1
  33. package/dist/esm/components/Popover/Popover.js +2 -2
  34. package/dist/esm/components/Suggestion/Suggestion.js +3 -4
  35. package/dist/esm/components/Suggestion/SuggestionEmpty.js +4 -4
  36. package/dist/esm/components/Tabs/Tabs.js +1 -1
  37. package/dist/esm/components/ToggleGroup/ToggleGroup.js +1 -1
  38. package/dist/esm/index.js +5 -5
  39. package/dist/esm/utilities/RovingFocus/RovingFocusRoot.js +1 -1
  40. package/dist/esm/{components/Pagination → utilities/hooks/usePagination}/usePagination.js +10 -1
  41. package/dist/types/colors.d.ts +12 -2
  42. package/dist/types/colors.d.ts.map +1 -1
  43. package/dist/types/components/Badge/Badge.d.ts +13 -1
  44. package/dist/types/components/Badge/Badge.d.ts.map +1 -1
  45. package/dist/types/components/Badge/index.d.ts +2 -1
  46. package/dist/types/components/Badge/index.d.ts.map +1 -1
  47. package/dist/types/components/Button/Button.d.ts +10 -6
  48. package/dist/types/components/Button/Button.d.ts.map +1 -1
  49. package/dist/types/components/Card/Card.d.ts +9 -7
  50. package/dist/types/components/Card/Card.d.ts.map +1 -1
  51. package/dist/types/components/Card/index.d.ts +2 -2
  52. package/dist/types/components/Details/Details.d.ts +4 -4
  53. package/dist/types/components/Details/Details.d.ts.map +1 -1
  54. package/dist/types/components/{Modal/Modal.d.ts → Dialog/Dialog.d.ts} +17 -17
  55. package/dist/types/components/Dialog/Dialog.d.ts.map +1 -0
  56. package/dist/types/components/{Modal/ModalBlock.d.ts → Dialog/DialogBlock.d.ts} +12 -12
  57. package/dist/types/components/Dialog/DialogBlock.d.ts.map +1 -0
  58. package/dist/types/components/Dialog/DialogTrigger.d.ts +22 -0
  59. package/dist/types/components/Dialog/DialogTrigger.d.ts.map +1 -0
  60. package/dist/types/components/Dialog/DialogTriggerContext.d.ts +21 -0
  61. package/dist/types/components/Dialog/DialogTriggerContext.d.ts.map +1 -0
  62. package/dist/types/components/Dialog/index.d.ts +43 -0
  63. package/dist/types/components/Dialog/index.d.ts.map +1 -0
  64. package/dist/types/components/Dropdown/DropdownHeading.d.ts +1 -1
  65. package/dist/types/components/Dropdown/index.d.ts +1 -1
  66. package/dist/types/components/ErrorSummary/ErrorSummaryHeading.d.ts +1 -1
  67. package/dist/types/components/ErrorSummary/index.d.ts +1 -1
  68. package/dist/types/components/Fieldset/FieldsetDescription.d.ts +1 -1
  69. package/dist/types/components/Fieldset/index.d.ts +1 -1
  70. package/dist/types/components/Heading/Heading.d.ts +2 -2
  71. package/dist/types/components/Heading/Heading.d.ts.map +1 -1
  72. package/dist/types/components/Pagination/index.d.ts +0 -2
  73. package/dist/types/components/Pagination/index.d.ts.map +1 -1
  74. package/dist/types/components/Paragraph/Paragraph.d.ts +2 -2
  75. package/dist/types/components/Paragraph/Paragraph.d.ts.map +1 -1
  76. package/dist/types/components/Popover/Popover.d.ts +13 -1
  77. package/dist/types/components/Popover/Popover.d.ts.map +1 -1
  78. package/dist/types/components/Popover/index.d.ts +2 -1
  79. package/dist/types/components/Popover/index.d.ts.map +1 -1
  80. package/dist/types/components/Search/SearchButton.d.ts +2 -2
  81. package/dist/types/components/Search/index.d.ts +2 -2
  82. package/dist/types/components/Spinner/Spinner.d.ts +1 -1
  83. package/dist/types/components/Spinner/Spinner.d.ts.map +1 -1
  84. package/dist/types/components/Suggestion/Suggestion.d.ts.map +1 -1
  85. package/dist/types/components/Suggestion/SuggestionEmpty.d.ts +3 -16
  86. package/dist/types/components/Suggestion/SuggestionEmpty.d.ts.map +1 -1
  87. package/dist/types/components/Suggestion/index.d.ts +1 -3
  88. package/dist/types/components/Suggestion/index.d.ts.map +1 -1
  89. package/dist/types/components/index.d.ts +1 -1
  90. package/dist/types/components/index.d.ts.map +1 -1
  91. package/dist/types/types.d.ts +2 -2
  92. package/dist/types/types.d.ts.map +1 -1
  93. package/dist/types/utilities/hooks/index.d.ts +2 -0
  94. package/dist/types/utilities/hooks/index.d.ts.map +1 -1
  95. package/dist/types/utilities/hooks/useCheckboxGroup/useCheckboxGroup.d.ts +2 -1
  96. package/dist/types/utilities/hooks/useCheckboxGroup/useCheckboxGroup.d.ts.map +1 -1
  97. package/dist/types/{components/Pagination → utilities/hooks/usePagination}/usePagination.d.ts +19 -11
  98. package/dist/types/utilities/hooks/usePagination/usePagination.d.ts.map +1 -0
  99. package/dist/types/utilities/hooks/useRadioGroup/useRadioGroup.d.ts +1 -1
  100. package/dist/types/utilities/hooks/useRadioGroup/useRadioGroup.d.ts.map +1 -1
  101. package/package.json +7 -5
  102. package/dist/cjs/components/Modal/Modal.js +0 -74
  103. package/dist/cjs/components/Modal/ModalBlock.js +0 -30
  104. package/dist/cjs/components/Modal/ModalTrigger.js +0 -27
  105. package/dist/cjs/components/Modal/ModalTriggerContext.js +0 -28
  106. package/dist/cjs/components/Modal/index.js +0 -34
  107. package/dist/esm/components/Modal/Modal.js +0 -72
  108. package/dist/esm/components/Modal/ModalBlock.js +0 -28
  109. package/dist/esm/components/Modal/ModalTriggerContext.js +0 -25
  110. package/dist/esm/components/Modal/index.js +0 -29
  111. package/dist/types/components/Modal/Modal.d.ts.map +0 -1
  112. package/dist/types/components/Modal/ModalBlock.d.ts.map +0 -1
  113. package/dist/types/components/Modal/ModalTrigger.d.ts +0 -22
  114. package/dist/types/components/Modal/ModalTrigger.d.ts.map +0 -1
  115. package/dist/types/components/Modal/ModalTriggerContext.d.ts +0 -21
  116. package/dist/types/components/Modal/ModalTriggerContext.d.ts.map +0 -1
  117. package/dist/types/components/Modal/index.d.ts +0 -43
  118. package/dist/types/components/Modal/index.d.ts.map +0 -1
  119. package/dist/types/components/Pagination/usePagination.d.ts.map +0 -1
@@ -16,8 +16,8 @@ var react = require('react');
16
16
  * <Icon />
17
17
  * </Badge>
18
18
  */
19
- const Badge = react.forwardRef(function Badge({ className, count, maxCount, ...rest }, ref) {
20
- return (jsxRuntime.jsx("span", { className: cl('ds-badge', className), "data-count": count && maxCount && count > maxCount ? `${maxCount}+` : count, ref: ref, ...rest }));
19
+ const Badge = react.forwardRef(function Badge({ className, count, maxCount, 'data-variant': variant = 'base', ...rest }, ref) {
20
+ return (jsxRuntime.jsx("span", { className: cl('ds-badge', className), "data-count": count && maxCount && count > maxCount ? `${maxCount}+` : count, "data-variant": variant, ref: ref, ...rest }));
21
21
  });
22
22
 
23
23
  exports.Badge = Badge;
@@ -18,7 +18,7 @@ const Button = react.forwardRef(function Button({ asChild, className, children,
18
18
  // Fallbacks to undefined to prevent rendering attribute="false"
19
19
  return (jsxRuntime.jsxs(Component, { "aria-busy": Boolean(loading) || undefined, className: cl('ds-button', className), "data-icon": icon || undefined, "data-variant": variant, ref: ref,
20
20
  /* don't set type when we use `asChild` */
21
- type: asChild ? undefined : 'button', ...rest, children: [loading === true ? (jsxRuntime.jsx(Spinner.Spinner, { "aria-hidden": 'true', "data-size": 'sm' })) : (loading // Allow custom loading spinner
21
+ type: asChild ? undefined : 'button', ...rest, children: [loading === true ? (jsxRuntime.jsx(Spinner.Spinner, { "aria-hidden": 'true' })) : (loading // Allow custom loading spinner
22
22
  ), jsxRuntime.jsx(reactSlot.Slottable, { children: children })] }));
23
23
  });
24
24
 
@@ -17,7 +17,7 @@ var react = require('react');
17
17
  * <Card.Block>Footer</Card.Block>
18
18
  * </Card>
19
19
  */
20
- const Card = react.forwardRef(function Card({ asChild = false, 'data-color': color = 'neutral', className, ...rest }, ref) {
20
+ const Card = react.forwardRef(function Card({ asChild = false, 'data-variant': variant = 'default', className, ...rest }, ref) {
21
21
  const Component = asChild ? reactSlot.Slot : 'div';
22
22
  const cardRef = react.useRef(null);
23
23
  const mergedRefs = react$1.useMergeRefs([cardRef, ref]);
@@ -37,7 +37,7 @@ const Card = react.forwardRef(function Card({ asChild = false, 'data-color': col
37
37
  card?.addEventListener('click', handleClick);
38
38
  return () => card?.removeEventListener('click', handleClick);
39
39
  }, []);
40
- return (jsxRuntime.jsx(Component, { className: cl(`ds-card`, className), "data-color": color, ref: mergedRefs, ...rest }));
40
+ return (jsxRuntime.jsx(Component, { className: cl(`ds-card`, className), "data-variant": variant, ref: mergedRefs, ...rest }));
41
41
  });
42
42
 
43
43
  exports.Card = Card;
@@ -47,7 +47,6 @@ const ComboboxComponent = react.forwardRef(({ value, initialValue = [], onValueC
47
47
  });
48
48
  const formFieldProps = useFormField.useFormField({
49
49
  disabled,
50
- readOnly,
51
50
  error,
52
51
  errorId,
53
52
  size,
@@ -133,7 +132,6 @@ const ComboboxComponent = react.forwardRef(({ value, initialValue = [], onValueC
133
132
  open,
134
133
  interactiveChildren,
135
134
  setOpen,
136
- setInputValue,
137
135
  handleSelectOption: debouncedHandleSelectOption,
138
136
  });
139
137
  const rowVirtualizer = reactVirtual.useVirtualizer({
@@ -16,7 +16,7 @@ require('@u-elements/u-details');
16
16
  * <Details.Content>Content</Details.Content>
17
17
  * </Details>
18
18
  */
19
- const Details = react.forwardRef(function Details({ className, open, defaultOpen = false, onToggle, ...rest }, ref) {
19
+ const Details = react.forwardRef(function Details({ className, open, defaultOpen = false, 'data-variant': variant = 'default', onToggle, ...rest }, ref) {
20
20
  const detailsRef = react.useRef(null);
21
21
  const initialOpen = react.useRef(defaultOpen); // Allow rendering defaultOpen on server, but only render once on client
22
22
  const mergedRefs = react$1.useMergeRefs([detailsRef, ref]);
@@ -37,7 +37,7 @@ const Details = react.forwardRef(function Details({ className, open, defaultOpen
37
37
  details?.addEventListener('toggle', handleToggle, true);
38
38
  return () => details?.removeEventListener('toggle', handleToggle, true);
39
39
  }, []);
40
- return (jsxRuntime.jsx("u-details", { class: cl('ds-details', className), open: (open ?? initialOpen.current) || undefined, ref: mergedRefs, ...rest }));
40
+ return (jsxRuntime.jsx("u-details", { class: cl('ds-details', className), open: (open ?? initialOpen.current) || undefined, "data-variant": variant, ref: mergedRefs, ...rest }));
41
41
  });
42
42
 
43
43
  exports.Details = Details;
@@ -0,0 +1,74 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var react$1 = require('@floating-ui/react');
6
+ var reactSlot = require('@radix-ui/react-slot');
7
+ var cl = require('clsx/lite');
8
+ var react = require('react');
9
+ var DialogTriggerContext = require('./DialogTriggerContext.js');
10
+ var Button = require('../Button/Button.js');
11
+
12
+ /**
13
+ * Dialog component, used to display a dialog dialog.
14
+ *
15
+ * @example with TriggerContext
16
+ * <Dialog.TriggerContext>
17
+ * <Dialog.Trigger>Open Dialog</Dialog.Trigger>
18
+ * <Dialog>
19
+ * <Dialog.Block>
20
+ * Content
21
+ * </Dialog.Block>
22
+ * </Dialog>
23
+ * </Dialog.TriggerContext>
24
+ *
25
+ * @example without TriggerContext
26
+ * const dialogRef = useRef<HTMLDialogElement>(null);
27
+ *
28
+ * ...
29
+ *
30
+ * <Button onClick={() => dialogRef.current?.showDialog()}>Open Dialog</Button>
31
+ * <Dialog ref={dialogRef}>
32
+ * Content
33
+ * </Dialog>
34
+ */
35
+ const Dialog = react.forwardRef(function Dialog({ asChild, children, className, closeButton = 'Lukk dialogvindu', onClose, open, backdropClose = false, ...rest }, ref) {
36
+ const contextRef = react.useContext(DialogTriggerContext.Context);
37
+ const dialogRef = react.useRef(null); // This local ref is used to make sure the dialog works without a DialogTriggerContext
38
+ const Component = asChild ? reactSlot.Slot : 'dialog';
39
+ const mergedRefs = react$1.useMergeRefs([contextRef, ref, dialogRef]);
40
+ react.useEffect(() => dialogRef.current?.[open ? 'showModal' : 'close'](), [open]); // Toggle open based on prop
41
+ react.useEffect(() => {
42
+ const dialog = dialogRef.current;
43
+ const handleBackdropClick = ({ clientY: y, clientX: x, target, }) => {
44
+ if (window.getSelection()?.toString())
45
+ return; // Fix bug where if you select text spanning two divs it thinks you clicked outside
46
+ if (dialog && target === dialog && backdropClose) {
47
+ const { top, left, right, bottom } = dialog.getBoundingClientRect();
48
+ const isInDialog = top <= y && y <= bottom && left <= x && x <= right;
49
+ if (!isInDialog)
50
+ dialog?.close(); // Both <dialog> and ::backdrop is considered same event.target
51
+ }
52
+ };
53
+ const handleAutoFocus = () => {
54
+ const autofocus = dialog?.querySelector('[autofocus]');
55
+ if (document.activeElement !== autofocus)
56
+ autofocus?.focus();
57
+ };
58
+ dialog?.addEventListener('animationend', handleAutoFocus);
59
+ dialog?.addEventListener('click', handleBackdropClick);
60
+ return () => {
61
+ dialog?.removeEventListener('animationend', handleAutoFocus);
62
+ dialog?.removeEventListener('click', handleBackdropClick);
63
+ };
64
+ }, [backdropClose]);
65
+ /* handle closing */
66
+ react.useEffect(() => {
67
+ const handleClose = (event) => onClose?.(event);
68
+ dialogRef.current?.addEventListener('close', handleClose);
69
+ return () => dialogRef.current?.removeEventListener('close', handleClose);
70
+ }, [onClose]);
71
+ return (jsxRuntime.jsxs(Component, { className: cl('ds-dialog', className), ref: mergedRefs, ...rest, children: [closeButton !== false && (jsxRuntime.jsx("form", { method: 'dialog', children: jsxRuntime.jsx(Button.Button, { "aria-label": closeButton, autoFocus: true, "data-color": 'neutral', icon: true, name: 'close', type: 'submit', variant: 'tertiary' }) })), children] }));
72
+ });
73
+
74
+ exports.Dialog = Dialog;
@@ -0,0 +1,30 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var reactSlot = require('@radix-ui/react-slot');
6
+ var cl = require('clsx/lite');
7
+ var react = require('react');
8
+
9
+ /**
10
+ * DialogBlock component, used to separate content in a Dialog.
11
+ *
12
+ * @example
13
+ * <Dialog>
14
+ * <Dialog.Block>
15
+ * Header
16
+ * </Dialog.Block>
17
+ * <Dialog.Block>
18
+ * Content
19
+ * </Dialog.Block>
20
+ * <Dialog.Block>
21
+ * Footer
22
+ * </Dialog.Block>
23
+ * </Dialog>
24
+ */
25
+ const DialogBlock = react.forwardRef(function DialogBlock({ asChild, className, ...rest }, ref) {
26
+ const Component = asChild ? reactSlot.Slot : 'div';
27
+ return (jsxRuntime.jsx(Component, { className: cl('ds-dialog__block', className), ref: ref, ...rest }));
28
+ });
29
+
30
+ exports.DialogBlock = DialogBlock;
@@ -0,0 +1,27 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var reactSlot = require('@radix-ui/react-slot');
6
+ var react = require('react');
7
+ var Button = require('../Button/Button.js');
8
+ var DialogTriggerContext = require('./DialogTriggerContext.js');
9
+
10
+ /**
11
+ * DialogTrigger component, used within a Dialog.TriggerContext to open a dialog.
12
+ *
13
+ * @example
14
+ * <Dialog.TriggerContext>
15
+ * <Dialog.Trigger>Open Dialog</Dialog.Trigger>
16
+ * <Dialog>
17
+ * Content
18
+ * </Dialog>
19
+ * </Dialog.TriggerContext>
20
+ */
21
+ const DialogTrigger = react.forwardRef(function DialogTrigger({ asChild, ...rest }, ref) {
22
+ const contextRef = react.useContext(DialogTriggerContext.Context);
23
+ const Component = asChild ? reactSlot.Slot : Button.Button;
24
+ return (jsxRuntime.jsx(Component, { "aria-haspopup": 'dialog', onClick: () => contextRef?.current?.showModal(), ref: ref, ...rest }));
25
+ });
26
+
27
+ exports.DialogTrigger = DialogTrigger;
@@ -0,0 +1,28 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var react = require('react');
6
+
7
+ const Context = react.createContext({
8
+ current: null,
9
+ });
10
+ /**
11
+ * DialogTriggerContext component, used to provide a context for a dialog trigger.
12
+ *
13
+ * @example
14
+ * <Dialog.TriggerContext>
15
+ * <Dialog.Trigger>Open Dialog</Dialog.Trigger>
16
+ * <Dialog>
17
+ * Content
18
+ * </Dialog>
19
+ * </Dialog.TriggerContext>
20
+ */
21
+ const DialogTriggerContext = ({ children, }) => {
22
+ const contextRef = react.useRef(null);
23
+ return jsxRuntime.jsx(Context.Provider, { value: contextRef, children: children });
24
+ };
25
+ DialogTriggerContext.displayName = 'DialogTriggerContext';
26
+
27
+ exports.Context = Context;
28
+ exports.DialogTriggerContext = DialogTriggerContext;
@@ -0,0 +1,34 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var Dialog$1 = require('./Dialog.js');
5
+ var DialogBlock = require('./DialogBlock.js');
6
+ var DialogTrigger = require('./DialogTrigger.js');
7
+ var DialogTriggerContext = require('./DialogTriggerContext.js');
8
+
9
+ /**
10
+ * Dialog component, used to display a Dialog dialog.
11
+ *
12
+ * @example
13
+ * <Dialog.TriggerContext>
14
+ * <Dialog.Trigger>Open Dialog</Dialog.Trigger>
15
+ * <Dialog>
16
+ * <Dialog.Block>
17
+ * Content
18
+ * </Dialog.Block>
19
+ * </Dialog>
20
+ * </Dialog.TriggerContext>
21
+ */
22
+ const Dialog = Object.assign(Dialog$1.Dialog, {
23
+ Block: DialogBlock.DialogBlock,
24
+ TriggerContext: DialogTriggerContext.DialogTriggerContext,
25
+ Trigger: DialogTrigger.DialogTrigger,
26
+ });
27
+ Dialog.Block.displayName = 'Dialog.Block';
28
+ Dialog.TriggerContext.displayName = 'Dialog.TriggerContext';
29
+ Dialog.Trigger.displayName = 'Dialog.Trigger';
30
+
31
+ exports.DialogBlock = DialogBlock.DialogBlock;
32
+ exports.DialogTrigger = DialogTrigger.DialogTrigger;
33
+ exports.DialogTriggerContext = DialogTriggerContext.DialogTriggerContext;
34
+ exports.Dialog = Dialog;
@@ -26,7 +26,7 @@ var PopoverTriggerContext = require('./PopoverTriggerContext.js');
26
26
  * Content
27
27
  * </Popover>
28
28
  */
29
- const Popover = react.forwardRef(function Popover({ id, className, onClose, onOpen, open, placement = 'top', autoPlacement = true, asChild = false, ...rest }, ref) {
29
+ const Popover = react.forwardRef(function Popover({ id, className, onClose, onOpen, open, 'data-variant': variant = 'default', placement = 'top', autoPlacement = true, asChild = false, ...rest }, ref) {
30
30
  const Component = asChild ? reactSlot.Slot : 'div';
31
31
  const popoverRef = react.useRef(null);
32
32
  const mergedRefs = react$1.useMergeRefs([popoverRef, ref]);
@@ -97,7 +97,7 @@ const Popover = react.forwardRef(function Popover({ id, className, onClose, onOp
97
97
  }, [id]);
98
98
  return (jsxRuntime.jsx(Component, { className: cl('ds-popover', className), id: id || popoverId,
99
99
  // @ts-ignore @types/react-dom does not understand popover yet
100
- popover: 'manual', ref: mergedRefs, ...rest }));
100
+ popover: 'manual', "data-variant": variant, ref: mergedRefs, ...rest }));
101
101
  });
102
102
  const arrowPseudoElement = {
103
103
  name: 'ArrowPseudoElement',
@@ -34,9 +34,8 @@ const Suggestion = react.forwardRef(function Suggestion({ className, filter = tr
34
34
  // Handle custom filter
35
35
  if (filter !== false) {
36
36
  let index = 0;
37
- for (const option of list.children) {
38
- // Skip <datalist> children that are not <option>
39
- if ('value' in option)
37
+ for (const option of list.getElementsByTagName('u-option')) {
38
+ if (!option.hasAttribute('data-empty'))
40
39
  option.disabled = !filter({
41
40
  index: index++, // Increment index for each <option>
42
41
  input,
@@ -2,7 +2,6 @@
2
2
  'use strict';
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
- var reactSlot = require('@radix-ui/react-slot');
6
5
  var react = require('react');
7
6
 
8
7
  /**
@@ -15,9 +14,10 @@ var react = require('react');
15
14
  * <Suggestion.Empty>Tomt</Suggestion.Empty>
16
15
  * </Suggestion.List>
17
16
  */
18
- const SuggestionEmpty = react.forwardRef(function SuggestionEmpty({ asChild, ...rest }, ref) {
19
- const Component = asChild ? reactSlot.Slot : 'div';
20
- return (jsxRuntime.jsx(Component, { "aria-disabled": 'true', ref: ref, role: 'option', tabIndex: 0, ...rest }));
17
+ const SuggestionEmpty = react.forwardRef(function SuggestionEmpty(rest, ref) {
18
+ return (
19
+ // biome-ignore lint/a11y/noInteractiveElementToNoninteractiveRole: Empty option shoult not be interactive
20
+ jsxRuntime.jsx("u-option", { "data-empty": true, role: 'none', ref: ref, ...rest }));
21
21
  });
22
22
 
23
23
  exports.SuggestionEmpty = SuggestionEmpty;
package/dist/cjs/index.js CHANGED
@@ -29,7 +29,6 @@ var Alert = require('./components/Alert/Alert.js');
29
29
  var Tag = require('./components/Tag/Tag.js');
30
30
  var index$5 = require('./components/Chip/index.js');
31
31
  var Chips = require('./components/Chip/Chips.js');
32
- var usePagination = require('./components/Pagination/usePagination.js');
33
32
  var index$6 = require('./components/Pagination/index.js');
34
33
  var PaginationList = require('./components/Pagination/PaginationList.js');
35
34
  var PaginationItem = require('./components/Pagination/PaginationItem.js');
@@ -59,10 +58,10 @@ var index$b = require('./components/Popover/index.js');
59
58
  var PopoverTriggerContext = require('./components/Popover/PopoverTriggerContext.js');
60
59
  var PopoverTrigger = require('./components/Popover/PopoverTrigger.js');
61
60
  var Divider = require('./components/Divider/Divider.js');
62
- var index$c = require('./components/Modal/index.js');
63
- var ModalBlock = require('./components/Modal/ModalBlock.js');
64
- var ModalTriggerContext = require('./components/Modal/ModalTriggerContext.js');
65
- var ModalTrigger = require('./components/Modal/ModalTrigger.js');
61
+ var index$c = require('./components/Dialog/index.js');
62
+ var DialogBlock = require('./components/Dialog/DialogBlock.js');
63
+ var DialogTriggerContext = require('./components/Dialog/DialogTriggerContext.js');
64
+ var DialogTrigger = require('./components/Dialog/DialogTrigger.js');
66
65
  var index$d = require('./components/Dropdown/index.js');
67
66
  var DropdownTriggerContext = require('./components/Dropdown/DropdownTriggerContext.js');
68
67
  var DropdownList = require('./components/Dropdown/DropdownList.js');
@@ -104,6 +103,7 @@ var useIsomorphicLayoutEffect = require('./utilities/hooks/useIsomorphicLayoutEf
104
103
  var useMediaQuery = require('./utilities/hooks/useMediaQuery/useMediaQuery.js');
105
104
  var useRadioGroup = require('./utilities/hooks/useRadioGroup/useRadioGroup.js');
106
105
  var useSynchronizedAnimation = require('./utilities/hooks/useSynchronizedAnimation/useSynchronizedAnimation.js');
106
+ var usePagination = require('./utilities/hooks/usePagination/usePagination.js');
107
107
  var RovingFocusRoot = require('./utilities/RovingFocus/RovingFocusRoot.js');
108
108
  var useRovingFocus = require('./utilities/RovingFocus/useRovingFocus.js');
109
109
  var RovingFocusItem = require('./utilities/RovingFocus/RovingFocusItem.js');
@@ -142,7 +142,6 @@ exports.ChipButton = Chips.ChipButton;
142
142
  exports.ChipCheckbox = Chips.ChipCheckbox;
143
143
  exports.ChipRadio = Chips.ChipRadio;
144
144
  exports.ChipRemovable = Chips.ChipRemovable;
145
- exports.usePagination = usePagination.usePagination;
146
145
  exports.Pagination = index$6.Pagination;
147
146
  exports.PaginationList = PaginationList.PaginationList;
148
147
  exports.PaginationItem = PaginationItem.PaginationItem;
@@ -173,10 +172,10 @@ exports.Popover = index$b.Popover;
173
172
  exports.PopoverTriggerContext = PopoverTriggerContext.PopoverTriggerContext;
174
173
  exports.PopoverTrigger = PopoverTrigger.PopoverTrigger;
175
174
  exports.Divider = Divider.Divider;
176
- exports.Modal = index$c.Modal;
177
- exports.ModalBlock = ModalBlock.ModalBlock;
178
- exports.ModalTriggerContext = ModalTriggerContext.ModalTriggerContext;
179
- exports.ModalTrigger = ModalTrigger.ModalTrigger;
175
+ exports.Dialog = index$c.Dialog;
176
+ exports.DialogBlock = DialogBlock.DialogBlock;
177
+ exports.DialogTriggerContext = DialogTriggerContext.DialogTriggerContext;
178
+ exports.DialogTrigger = DialogTrigger.DialogTrigger;
180
179
  exports.Dropdown = index$d.Dropdown;
181
180
  exports.DropdownTriggerContext = DropdownTriggerContext.DropdownTriggerContext;
182
181
  exports.DropdownList = DropdownList.DropdownList;
@@ -218,6 +217,7 @@ exports.useIsomorphicLayoutEffect = useIsomorphicLayoutEffect.useIsomorphicLayou
218
217
  exports.useMediaQuery = useMediaQuery.useMediaQuery;
219
218
  exports.useRadioGroup = useRadioGroup.useRadioGroup;
220
219
  exports.useSynchronizedAnimation = useSynchronizedAnimation.useSynchronizedAnimation;
220
+ exports.usePagination = usePagination.usePagination;
221
221
  exports.RovingFocusRoot = RovingFocusRoot.RovingFocusRoot;
222
222
  exports.useRovingFocus = useRovingFocus.useRovingFocus;
223
223
  exports.RovingFocusItem = RovingFocusItem.RovingFocusItem;
@@ -43,7 +43,7 @@ const getSteps = (now, max, show) => {
43
43
  * </Pagination.Item>
44
44
  * </Pagination>
45
45
  **/
46
- const usePagination = ({ currentPage = 1, setCurrentPage, onChange, totalPages, showPages = 7, }) => react.useMemo(() => {
46
+ const usePagination = ({ currentPage = 1, setCurrentPage, onChange, totalPages = 1, showPages = 7, }) => react.useMemo(() => {
47
47
  const hasNext = currentPage < totalPages;
48
48
  const hasPrev = currentPage !== 1;
49
49
  const handleClick = (page) => (event) => {
@@ -56,8 +56,17 @@ const usePagination = ({ currentPage = 1, setCurrentPage, onChange, totalPages,
56
56
  return {
57
57
  /** Number of steps */
58
58
  pages: getSteps(currentPage, totalPages, showPages).map((page, index) => ({
59
+ /**
60
+ * Page number or "ellipsis" for the ellipsis item
61
+ */
59
62
  page: page || 'ellipsis',
63
+ /**
64
+ * Unique key for the item
65
+ */
60
66
  itemKey: page ? `page-${page}` : `ellipsis-${index}`, // React key utility
67
+ /**
68
+ * Properties to spread on Pagination.Button
69
+ */
61
70
  buttonProps: (page
62
71
  ? {
63
72
  'aria-current': page === currentPage ? 'page' : undefined,
@@ -14,8 +14,8 @@ import { forwardRef } from 'react';
14
14
  * <Icon />
15
15
  * </Badge>
16
16
  */
17
- const Badge = forwardRef(function Badge({ className, count, maxCount, ...rest }, ref) {
18
- return (jsx("span", { className: cl('ds-badge', className), "data-count": count && maxCount && count > maxCount ? `${maxCount}+` : count, ref: ref, ...rest }));
17
+ const Badge = forwardRef(function Badge({ className, count, maxCount, 'data-variant': variant = 'base', ...rest }, ref) {
18
+ return (jsx("span", { className: cl('ds-badge', className), "data-count": count && maxCount && count > maxCount ? `${maxCount}+` : count, "data-variant": variant, ref: ref, ...rest }));
19
19
  });
20
20
 
21
21
  export { Badge };
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
- import { Slottable, Slot } from '@radix-ui/react-slot';
3
+ import { Slot, Slottable } from '@radix-ui/react-slot';
4
4
  import cl from 'clsx/lite';
5
5
  import { forwardRef } from 'react';
6
6
  import { Spinner } from '../Spinner/Spinner.js';
@@ -16,7 +16,7 @@ const Button = forwardRef(function Button({ asChild, className, children, icon =
16
16
  // Fallbacks to undefined to prevent rendering attribute="false"
17
17
  return (jsxs(Component, { "aria-busy": Boolean(loading) || undefined, className: cl('ds-button', className), "data-icon": icon || undefined, "data-variant": variant, ref: ref,
18
18
  /* don't set type when we use `asChild` */
19
- type: asChild ? undefined : 'button', ...rest, children: [loading === true ? (jsx(Spinner, { "aria-hidden": 'true', "data-size": 'sm' })) : (loading // Allow custom loading spinner
19
+ type: asChild ? undefined : 'button', ...rest, children: [loading === true ? (jsx(Spinner, { "aria-hidden": 'true' })) : (loading // Allow custom loading spinner
20
20
  ), jsx(Slottable, { children: children })] }));
21
21
  });
22
22
 
@@ -15,7 +15,7 @@ import { forwardRef, useRef, useEffect } from 'react';
15
15
  * <Card.Block>Footer</Card.Block>
16
16
  * </Card>
17
17
  */
18
- const Card = forwardRef(function Card({ asChild = false, 'data-color': color = 'neutral', className, ...rest }, ref) {
18
+ const Card = forwardRef(function Card({ asChild = false, 'data-variant': variant = 'default', className, ...rest }, ref) {
19
19
  const Component = asChild ? Slot : 'div';
20
20
  const cardRef = useRef(null);
21
21
  const mergedRefs = useMergeRefs([cardRef, ref]);
@@ -35,7 +35,7 @@ const Card = forwardRef(function Card({ asChild = false, 'data-color': color = '
35
35
  card?.addEventListener('click', handleClick);
36
36
  return () => card?.removeEventListener('click', handleClick);
37
37
  }, []);
38
- return (jsx(Component, { className: cl(`ds-card`, className), "data-color": color, ref: mergedRefs, ...rest }));
38
+ return (jsx(Component, { className: cl(`ds-card`, className), "data-variant": variant, ref: mergedRefs, ...rest }));
39
39
  });
40
40
 
41
41
  export { Card };
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
- import { Slottable, Slot } from '@radix-ui/react-slot';
3
+ import { Slot, Slottable } from '@radix-ui/react-slot';
4
4
  import cl from 'clsx/lite';
5
5
  import { forwardRef } from 'react';
6
6
  import { Input } from '../Input/Input.js';
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { ChipButton, ChipCheckbox, ChipRadio, ChipRemovable } from './Chips.js';
2
+ import { ChipRemovable, ChipRadio, ChipCheckbox, ChipButton } from './Chips.js';
3
3
 
4
4
  const Chip = {
5
5
  Button: ChipButton,
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import { FloatingPortal, FloatingFocusManager } from '@floating-ui/react';
4
4
  import { useVirtualizer } from '@tanstack/react-virtual';
5
5
  import cl from 'clsx/lite';
@@ -45,7 +45,6 @@ const ComboboxComponent = forwardRef(({ value, initialValue = [], onValueChange,
45
45
  });
46
46
  const formFieldProps = useFormField({
47
47
  disabled,
48
- readOnly,
49
48
  error,
50
49
  errorId,
51
50
  size,
@@ -131,7 +130,6 @@ const ComboboxComponent = forwardRef(({ value, initialValue = [], onValueChange,
131
130
  open,
132
131
  interactiveChildren,
133
132
  setOpen,
134
- setInputValue,
135
133
  handleSelectOption: debouncedHandleSelectOption,
136
134
  });
137
135
  const rowVirtualizer = useVirtualizer({
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsx } from 'react/jsx-runtime';
3
- import { createContext, useReducer, useContext } from 'react';
3
+ import { useReducer, createContext, useContext } from 'react';
4
4
 
5
5
  const ComboboxIdContext = createContext({
6
6
  activeIndex: 0,
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { useFloating, autoUpdate, flip, size, offset, useRole, useDismiss, useListNavigation, useInteractions } from '@floating-ui/react';
2
+ import { useFloating, flip, size, offset, autoUpdate, useRole, useDismiss, useListNavigation, useInteractions } from '@floating-ui/react';
3
3
  import { useState } from 'react';
4
4
  import { flushSync } from 'react-dom';
5
5
  import { useComboboxId, useComboboxIdDispatch } from './ComboboxIdContext.js';
@@ -14,7 +14,7 @@ import '@u-elements/u-details';
14
14
  * <Details.Content>Content</Details.Content>
15
15
  * </Details>
16
16
  */
17
- const Details = forwardRef(function Details({ className, open, defaultOpen = false, onToggle, ...rest }, ref) {
17
+ const Details = forwardRef(function Details({ className, open, defaultOpen = false, 'data-variant': variant = 'default', onToggle, ...rest }, ref) {
18
18
  const detailsRef = useRef(null);
19
19
  const initialOpen = useRef(defaultOpen); // Allow rendering defaultOpen on server, but only render once on client
20
20
  const mergedRefs = useMergeRefs([detailsRef, ref]);
@@ -35,7 +35,7 @@ const Details = forwardRef(function Details({ className, open, defaultOpen = fal
35
35
  details?.addEventListener('toggle', handleToggle, true);
36
36
  return () => details?.removeEventListener('toggle', handleToggle, true);
37
37
  }, []);
38
- return (jsx("u-details", { class: cl('ds-details', className), open: (open ?? initialOpen.current) || undefined, ref: mergedRefs, ...rest }));
38
+ return (jsx("u-details", { class: cl('ds-details', className), open: (open ?? initialOpen.current) || undefined, "data-variant": variant, ref: mergedRefs, ...rest }));
39
39
  });
40
40
 
41
41
  export { Details };
@@ -0,0 +1,72 @@
1
+ 'use client';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { useMergeRefs } from '@floating-ui/react';
4
+ import { Slot } from '@radix-ui/react-slot';
5
+ import cl from 'clsx/lite';
6
+ import { forwardRef, useContext, useRef, useEffect } from 'react';
7
+ import { Context } from './DialogTriggerContext.js';
8
+ import { Button } from '../Button/Button.js';
9
+
10
+ /**
11
+ * Dialog component, used to display a dialog dialog.
12
+ *
13
+ * @example with TriggerContext
14
+ * <Dialog.TriggerContext>
15
+ * <Dialog.Trigger>Open Dialog</Dialog.Trigger>
16
+ * <Dialog>
17
+ * <Dialog.Block>
18
+ * Content
19
+ * </Dialog.Block>
20
+ * </Dialog>
21
+ * </Dialog.TriggerContext>
22
+ *
23
+ * @example without TriggerContext
24
+ * const dialogRef = useRef<HTMLDialogElement>(null);
25
+ *
26
+ * ...
27
+ *
28
+ * <Button onClick={() => dialogRef.current?.showDialog()}>Open Dialog</Button>
29
+ * <Dialog ref={dialogRef}>
30
+ * Content
31
+ * </Dialog>
32
+ */
33
+ const Dialog = forwardRef(function Dialog({ asChild, children, className, closeButton = 'Lukk dialogvindu', onClose, open, backdropClose = false, ...rest }, ref) {
34
+ const contextRef = useContext(Context);
35
+ const dialogRef = useRef(null); // This local ref is used to make sure the dialog works without a DialogTriggerContext
36
+ const Component = asChild ? Slot : 'dialog';
37
+ const mergedRefs = useMergeRefs([contextRef, ref, dialogRef]);
38
+ useEffect(() => dialogRef.current?.[open ? 'showModal' : 'close'](), [open]); // Toggle open based on prop
39
+ useEffect(() => {
40
+ const dialog = dialogRef.current;
41
+ const handleBackdropClick = ({ clientY: y, clientX: x, target, }) => {
42
+ if (window.getSelection()?.toString())
43
+ return; // Fix bug where if you select text spanning two divs it thinks you clicked outside
44
+ if (dialog && target === dialog && backdropClose) {
45
+ const { top, left, right, bottom } = dialog.getBoundingClientRect();
46
+ const isInDialog = top <= y && y <= bottom && left <= x && x <= right;
47
+ if (!isInDialog)
48
+ dialog?.close(); // Both <dialog> and ::backdrop is considered same event.target
49
+ }
50
+ };
51
+ const handleAutoFocus = () => {
52
+ const autofocus = dialog?.querySelector('[autofocus]');
53
+ if (document.activeElement !== autofocus)
54
+ autofocus?.focus();
55
+ };
56
+ dialog?.addEventListener('animationend', handleAutoFocus);
57
+ dialog?.addEventListener('click', handleBackdropClick);
58
+ return () => {
59
+ dialog?.removeEventListener('animationend', handleAutoFocus);
60
+ dialog?.removeEventListener('click', handleBackdropClick);
61
+ };
62
+ }, [backdropClose]);
63
+ /* handle closing */
64
+ useEffect(() => {
65
+ const handleClose = (event) => onClose?.(event);
66
+ dialogRef.current?.addEventListener('close', handleClose);
67
+ return () => dialogRef.current?.removeEventListener('close', handleClose);
68
+ }, [onClose]);
69
+ return (jsxs(Component, { className: cl('ds-dialog', className), ref: mergedRefs, ...rest, children: [closeButton !== false && (jsx("form", { method: 'dialog', children: jsx(Button, { "aria-label": closeButton, autoFocus: true, "data-color": 'neutral', icon: true, name: 'close', type: 'submit', variant: 'tertiary' }) })), children] }));
70
+ });
71
+
72
+ export { Dialog };