@equinor/eds-core-react 2.3.0 → 2.3.1

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 (62) hide show
  1. package/README.md +3 -0
  2. package/build/index.css +1252 -0
  3. package/build/index.min.css +5 -0
  4. package/dist/eds-core-react.cjs +2 -2
  5. package/dist/esm/components/Autocomplete/SingleInput.js +2 -2
  6. package/dist/esm/components/EdsProvider/eds.context.js +3 -31
  7. package/dist/esm/components/next/Button/Button.js +53 -0
  8. package/dist/esm/components/next/Checkbox/Checkbox.js +85 -0
  9. package/dist/esm/components/next/Field/Field.Description.js +25 -0
  10. package/dist/esm/components/next/Field/Field.HelperMessage.js +45 -0
  11. package/dist/esm/components/next/Field/Field.Label.js +31 -0
  12. package/dist/esm/components/next/Field/Field.js +29 -0
  13. package/dist/esm/components/next/Field/useFieldIds.js +57 -0
  14. package/dist/esm/components/next/Icon/Icon.js +0 -1
  15. package/dist/esm/components/next/Input/Input.js +92 -0
  16. package/dist/esm/components/next/Radio/Radio.js +63 -0
  17. package/dist/esm/components/next/Switch/Switch.js +64 -0
  18. package/dist/esm/components/next/TextField/TextField.js +69 -0
  19. package/dist/esm/index.next.js +8 -1
  20. package/dist/index.next.cjs +825 -39
  21. package/dist/types/components/Autocomplete/Autocomplete.d.ts +2 -2
  22. package/dist/types/components/Autocomplete/AutocompleteContext.d.ts +2 -2
  23. package/dist/types/components/Autocomplete/useAutocomplete.d.ts +1 -1
  24. package/dist/types/components/Datepicker/DateRangePicker.d.ts +1 -1
  25. package/dist/types/components/SideBar/SideBarButton/index.d.ts +1 -1
  26. package/dist/types/components/next/Button/Button.d.ts +8 -0
  27. package/dist/types/components/next/Button/Button.figma.d.ts +1 -0
  28. package/dist/types/components/next/Button/Button.types.d.ts +80 -0
  29. package/dist/types/components/next/Button/index.d.ts +2 -0
  30. package/dist/types/components/next/Checkbox/Checkbox.d.ts +7 -0
  31. package/dist/types/components/next/Checkbox/Checkbox.figma.d.ts +1 -0
  32. package/dist/types/components/next/Checkbox/Checkbox.types.d.ts +15 -0
  33. package/dist/types/components/next/Checkbox/index.d.ts +2 -0
  34. package/dist/types/components/next/Field/Field.Description.d.ts +3 -0
  35. package/dist/types/components/next/Field/Field.HelperMessage.d.ts +19 -0
  36. package/dist/types/components/next/Field/Field.HelperMessage.types.d.ts +12 -0
  37. package/dist/types/components/next/Field/Field.Label.d.ts +4 -0
  38. package/dist/types/components/next/Field/Field.d.ts +15 -0
  39. package/dist/types/components/next/Field/Field.types.d.ts +25 -0
  40. package/dist/types/components/next/Field/index.d.ts +5 -0
  41. package/dist/types/components/next/Field/useFieldIds.d.ts +59 -0
  42. package/dist/types/components/next/Input/Input.d.ts +3 -0
  43. package/dist/types/components/next/Input/Input.types.d.ts +17 -0
  44. package/dist/types/components/next/Input/index.d.ts +2 -0
  45. package/dist/types/components/next/Placeholder/Placeholder.d.ts +4 -6
  46. package/dist/types/components/next/Placeholder/index.d.ts +0 -1
  47. package/dist/types/components/next/Radio/Radio.d.ts +3 -0
  48. package/dist/types/components/next/Radio/Radio.figma.d.ts +1 -0
  49. package/dist/types/components/next/Radio/Radio.types.d.ts +5 -0
  50. package/dist/types/components/next/Radio/index.d.ts +2 -0
  51. package/dist/types/components/next/Switch/Switch.d.ts +3 -0
  52. package/dist/types/components/next/Switch/Switch.types.d.ts +7 -0
  53. package/dist/types/components/next/Switch/index.d.ts +2 -0
  54. package/dist/types/components/next/TextField/TextField.d.ts +17 -0
  55. package/dist/types/components/next/TextField/TextField.types.d.ts +16 -0
  56. package/dist/types/components/next/TextField/index.d.ts +2 -0
  57. package/dist/types/components/next/index.d.ts +14 -2
  58. package/dist/types/index.next.d.ts +3 -0
  59. package/package.json +5 -9
  60. package/dist/esm/components/next/Icon/icon.css.js +0 -6
  61. package/dist/esm/components/next/Placeholder/Placeholder.js +0 -17
  62. package/dist/esm/node_modules/.pnpm/style-inject@0.3.0/node_modules/style-inject/dist/style-inject.es.js +0 -26
@@ -1,49 +1,128 @@
1
1
  'use strict';
2
2
 
3
- var jsxRuntime = require('react/jsx-runtime');
4
3
  var react = require('react');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var edsIcons = require('@equinor/eds-icons');
6
+ var reactDom = require('react-dom');
7
+ var styled = require('styled-components');
8
+ var edsUtils = require('@equinor/eds-utils');
9
+ var edsTokens = require('@equinor/eds-tokens');
10
+ var react$1 = require('@floating-ui/react');
11
+
12
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
+
14
+ var styled__default = /*#__PURE__*/_interopDefault(styled);
5
15
 
6
16
  /**
7
- * Placeholder component for testing the /next entry point.
8
- * This component should be removed once real EDS 2.0 components are added.
17
+ * TypographyNext component for flexible typography with baseline grid support.
18
+ *
19
+ * Provides full control over typography properties including family, size,
20
+ * lineHeight, baseline alignment, weight, and tracking.
21
+ *
22
+ * **Display behavior:** Elements render as `display: block` by default for
23
+ * text-box trimming and baseline grid alignment. Override with CSS if needed.
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * import { TypographyNext as Typography } from '@equinor/eds-core-react'
28
+ *
29
+ * <Typography
30
+ * family="ui"
31
+ * size="md"
32
+ * lineHeight="default"
33
+ * baseline="grid"
34
+ * weight="normal"
35
+ * tracking="normal"
36
+ * >
37
+ * Text content (renders as block-level by default)
38
+ * </Typography>
39
+ *
40
+ * <Typography
41
+ * as="h1"
42
+ * family="header"
43
+ * size="3xl"
44
+ * lineHeight="squished"
45
+ * baseline="grid"
46
+ * weight="bolder"
47
+ * tracking="tight"
48
+ * >
49
+ * Page heading
50
+ * </Typography>
51
+ * ```
9
52
  */
10
-
11
- const Placeholder = ({
12
- text = 'EDS 2.0 Placeholder'
13
- }) => {
14
- return /*#__PURE__*/jsxRuntime.jsx("div", {
15
- "data-testid": "eds-placeholder",
16
- children: text
53
+ const TypographyNext = /*#__PURE__*/react.forwardRef(({
54
+ as = 'span',
55
+ family,
56
+ size,
57
+ baseline,
58
+ lineHeight,
59
+ weight,
60
+ tracking,
61
+ debug,
62
+ ...rest
63
+ }, ref) => {
64
+ const Component = as;
65
+ return /*#__PURE__*/jsxRuntime.jsx(Component, {
66
+ ref: ref,
67
+ "data-font-family": family,
68
+ "data-font-size": size,
69
+ "data-baseline": baseline || undefined,
70
+ "data-line-height": lineHeight || undefined,
71
+ "data-font-weight": weight || undefined,
72
+ "data-tracking": tracking || undefined,
73
+ "data-debug": debug ? '' : undefined,
74
+ ...rest
17
75
  });
18
- };
19
-
20
- function styleInject(css, ref) {
21
- if (ref === void 0) ref = {};
22
- var insertAt = ref.insertAt;
23
- if (typeof document === 'undefined') {
24
- return;
25
- }
26
- var head = document.head || document.getElementsByTagName('head')[0];
27
- var style = document.createElement('style');
28
- style.type = 'text/css';
29
- if (insertAt === 'top') {
30
- if (head.firstChild) {
31
- head.insertBefore(style, head.firstChild);
32
- } else {
33
- head.appendChild(style);
34
- }
35
- } else {
36
- head.appendChild(style);
37
- }
38
- if (style.styleSheet) {
39
- style.styleSheet.cssText = css;
40
- } else {
41
- style.appendChild(document.createTextNode(css));
42
- }
43
- }
76
+ });
77
+ TypographyNext.displayName = 'TypographyNext';
44
78
 
45
- var css_248z = "/* Inline with text: uses token from parent's data-font-size, or 1.5em fallback */\n.icon {\n /*\n * Set font-size first to establish the icon's size context.\n * Then use 1em for width/height (relative to computed font-size).\n * This avoids compound scaling (1.5em × 1.5em = 2.25em would be wrong).\n */\n font-size: var(--eds-typography-icon-size, 1.5em);\n width: 1em;\n height: 1em;\n\n /* Negative margins for optical alignment with text baseline */\n margin-block: -0.25em;\n margin-inline: -0.1em;\n\n flex-shrink: 0;\n}\n\n/* Explicit size: fixed size from design tokens, no margins */\n.icon[data-icon-size] {\n --_explicit-size: var(--eds-sizing-icon-md); /* fallback */\n\n width: var(--_explicit-size);\n height: var(--_explicit-size);\n margin: 0;\n font-size: inherit;\n}\n\n.icon[data-icon-size='xs'] {\n --_explicit-size: var(--eds-sizing-icon-xs);\n}\n.icon[data-icon-size='sm'] {\n --_explicit-size: var(--eds-sizing-icon-sm);\n}\n.icon[data-icon-size='md'] {\n --_explicit-size: var(--eds-sizing-icon-md);\n}\n.icon[data-icon-size='lg'] {\n --_explicit-size: var(--eds-sizing-icon-lg);\n}\n.icon[data-icon-size='xl'] {\n --_explicit-size: var(--eds-sizing-icon-xl);\n}\n.icon[data-icon-size='2xl'] {\n --_explicit-size: var(--eds-sizing-icon-2xl);\n}\n.icon[data-icon-size='3xl'] {\n --_explicit-size: var(--eds-sizing-icon-3xl);\n}\n.icon[data-icon-size='4xl'] {\n --_explicit-size: var(--eds-sizing-icon-4xl);\n}\n.icon[data-icon-size='5xl'] {\n --_explicit-size: var(--eds-sizing-icon-5xl);\n}\n.icon[data-icon-size='6xl'] {\n --_explicit-size: var(--eds-sizing-icon-6xl);\n}\n";
46
- styleInject(css_248z);
79
+ const SIZE_MAPPING = {
80
+ small: 'sm',
81
+ default: 'md',
82
+ large: 'lg'
83
+ };
84
+ const sizeToTypography = SIZE_MAPPING;
85
+ const sizeToSelectableSpace = SIZE_MAPPING;
86
+ const Button = /*#__PURE__*/react.forwardRef(function Button({
87
+ variant = 'primary',
88
+ size = 'default',
89
+ tone = 'accent',
90
+ icon = false,
91
+ round = false,
92
+ children,
93
+ className,
94
+ disabled,
95
+ type = 'button',
96
+ ...rest
97
+ }, ref) {
98
+ const classes = ['eds-button', className].filter(Boolean).join(' ');
99
+ const typographySize = sizeToTypography[size];
100
+ const selectableSpace = sizeToSelectableSpace[size];
101
+ return /*#__PURE__*/jsxRuntime.jsx("button", {
102
+ ref: ref,
103
+ type: type,
104
+ className: classes,
105
+ disabled: disabled,
106
+ "data-variant": variant,
107
+ "data-selectable-space": selectableSpace,
108
+ "data-space-proportions": "squished",
109
+ "data-font-family": "ui",
110
+ "data-font-size": typographySize,
111
+ "data-line-height": "squished",
112
+ "data-color-appearance": disabled ? 'neutral' : tone,
113
+ "data-icon-only": icon || undefined,
114
+ "data-round": icon && round ? true : undefined,
115
+ ...rest,
116
+ children: /*#__PURE__*/jsxRuntime.jsx(TypographyNext, {
117
+ family: "ui",
118
+ size: typographySize,
119
+ baseline: "center",
120
+ lineHeight: "squished",
121
+ children: children
122
+ })
123
+ });
124
+ });
125
+ Button.displayName = 'Button';
47
126
 
48
127
  const Icon = /*#__PURE__*/react.forwardRef(function Icon({
49
128
  data,
@@ -97,5 +176,712 @@ const Icon = /*#__PURE__*/react.forwardRef(function Icon({
97
176
  });
98
177
  });
99
178
 
179
+ const FieldDescription = /*#__PURE__*/react.forwardRef(function FieldDescription({
180
+ children,
181
+ className,
182
+ ...rest
183
+ }, ref) {
184
+ return /*#__PURE__*/jsxRuntime.jsx(TypographyNext, {
185
+ ref: ref,
186
+ as: "p",
187
+ family: "ui",
188
+ size: "sm",
189
+ baseline: "center",
190
+ lineHeight: "default",
191
+ tracking: "normal",
192
+ className: ['eds-field__description', className].filter(Boolean).join(' '),
193
+ ...rest,
194
+ children: children
195
+ });
196
+ });
197
+ FieldDescription.displayName = 'Field.Description';
198
+
199
+ /**
200
+ * Field.HelperMessage provides contextual help or validation feedback for form fields.
201
+ *
202
+ * Use with `useFieldIds` hook to connect to form controls via `aria-describedby`.
203
+ *
204
+ * @example
205
+ * ```tsx
206
+ * const { inputId, helperMessageId, getDescribedBy } = useFieldIds()
207
+ *
208
+ * <Field>
209
+ * <Field.Label htmlFor={inputId}>Email</Field.Label>
210
+ * <input id={inputId} aria-describedby={getDescribedBy()} />
211
+ * <Field.HelperMessage id={helperMessageId}>We'll never share your email</Field.HelperMessage>
212
+ * </Field>
213
+ * ```
214
+ */
215
+ const HelperMessage = /*#__PURE__*/react.forwardRef(function HelperMessage({
216
+ children,
217
+ className,
218
+ role,
219
+ id,
220
+ ...rest
221
+ }, ref) {
222
+ return /*#__PURE__*/jsxRuntime.jsx(TypographyNext, {
223
+ ref: ref,
224
+ as: "p",
225
+ id: id,
226
+ family: "ui",
227
+ size: "sm",
228
+ baseline: "grid",
229
+ lineHeight: "default",
230
+ tracking: "normal",
231
+ role: role,
232
+ className: ['eds-field__helper-message', className].filter(Boolean).join(' '),
233
+ ...rest,
234
+ children: children
235
+ });
236
+ });
237
+ HelperMessage.displayName = 'Field.HelperMessage';
238
+
239
+ const FieldLabel = /*#__PURE__*/react.forwardRef(function FieldLabel({
240
+ children,
241
+ className,
242
+ indicator,
243
+ ...rest
244
+ }, ref) {
245
+ return /*#__PURE__*/jsxRuntime.jsxs(TypographyNext, {
246
+ ref: ref,
247
+ as: "label",
248
+ family: "ui",
249
+ size: "md",
250
+ baseline: "center",
251
+ lineHeight: "default",
252
+ weight: "normal",
253
+ tracking: "normal",
254
+ className: ['eds-field__label', className].filter(Boolean).join(' '),
255
+ ...rest,
256
+ children: [children, indicator && /*#__PURE__*/jsxRuntime.jsx("span", {
257
+ className: "eds-field__indicator",
258
+ "data-font-size": "sm",
259
+ children: indicator
260
+ })]
261
+ });
262
+ });
263
+ FieldLabel.displayName = 'Field.Label';
264
+
265
+ const FieldComponent = /*#__PURE__*/react.forwardRef(function Field({
266
+ disabled = false,
267
+ position,
268
+ className,
269
+ children,
270
+ ...rest
271
+ }, ref) {
272
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
273
+ ref: ref,
274
+ className: ['eds-field', className].filter(Boolean).join(' '),
275
+ "data-disabled": disabled || undefined,
276
+ "data-position": position,
277
+ ...rest,
278
+ children: children
279
+ });
280
+ });
281
+ FieldComponent.displayName = 'Field';
282
+ const Field = FieldComponent;
283
+ Field.Label = FieldLabel;
284
+ Field.Description = FieldDescription;
285
+ Field.HelperMessage = HelperMessage;
286
+
287
+ /**
288
+ * Hook for generating consistent, accessible IDs for form field elements.
289
+ *
290
+ * @param providedId - Optional custom ID. If not provided, a unique ID will be generated.
291
+ * @returns Object containing IDs for input, label, description, and helper message,
292
+ * plus a helper function to generate aria-describedby.
293
+ *
294
+ * @example
295
+ * ```tsx
296
+ * const ids = useFieldIds()
297
+ *
298
+ * <Field>
299
+ * <Field.Label htmlFor={ids.inputId}>Username</Field.Label>
300
+ * <Field.Description id={ids.descriptionId}>
301
+ * Choose a unique username
302
+ * </Field.Description>
303
+ * <input
304
+ * id={ids.inputId}
305
+ * aria-describedby={ids.getDescribedBy({
306
+ * hasDescription: true,
307
+ * hasHelperMessage: hasError,
308
+ * })}
309
+ * />
310
+ * {hasError && (
311
+ * <HelperMessage id={ids.helperMessageId}>
312
+ * Username is already taken
313
+ * </HelperMessage>
314
+ * )}
315
+ * </Field>
316
+ * ```
317
+ */
318
+ function useFieldIds(providedId) {
319
+ const generatedId = react.useId();
320
+ const baseId = providedId ?? generatedId;
321
+ return {
322
+ inputId: `${baseId}-input`,
323
+ labelId: `${baseId}-label`,
324
+ descriptionId: `${baseId}-description`,
325
+ helperMessageId: `${baseId}-helper-message`,
326
+ getDescribedBy: (options = {}) => {
327
+ const {
328
+ hasDescription = true,
329
+ hasHelperMessage = false
330
+ } = options;
331
+ const ids = [];
332
+
333
+ // Description first, then helper message
334
+ if (hasDescription) ids.push(`${baseId}-description`);
335
+ if (hasHelperMessage) ids.push(`${baseId}-helper-message`);
336
+ return ids.length > 0 ? ids.join(' ') : undefined;
337
+ }
338
+ };
339
+ }
340
+
341
+ /* eslint camelcase: "off" */
342
+ const classNames$1 = (...classes) => classes.filter(Boolean).join(' ');
343
+ const Checkbox = /*#__PURE__*/react.forwardRef(function Checkbox({
344
+ label,
345
+ disabled = false,
346
+ indeterminate = false,
347
+ indicator,
348
+ helperMessage,
349
+ id: providedId,
350
+ ...rest
351
+ }, ref) {
352
+ const internalRef = react.useRef(null);
353
+ const inputRef = ref || internalRef;
354
+ const generatedId = react.useId();
355
+ const inputId = providedId ?? generatedId;
356
+ const helperMessageId = `${inputId}-helper`;
357
+ react.useEffect(() => {
358
+ if (inputRef.current) {
359
+ inputRef.current.indeterminate = indeterminate;
360
+ }
361
+ }, [indeterminate, inputRef]);
362
+ const checkboxInput = /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
363
+ children: [/*#__PURE__*/jsxRuntime.jsx("input", {
364
+ type: "checkbox",
365
+ id: inputId,
366
+ "aria-checked": indeterminate ? 'mixed' : undefined,
367
+ "aria-describedby": helperMessage ? helperMessageId : undefined,
368
+ className: "eds-checkbox__input",
369
+ disabled: disabled,
370
+ ref: inputRef,
371
+ "data-indeterminate": indeterminate,
372
+ ...rest
373
+ }), /*#__PURE__*/jsxRuntime.jsxs("span", {
374
+ className: "eds-checkbox__icon-wrapper",
375
+ children: [/*#__PURE__*/jsxRuntime.jsx(Icon, {
376
+ data: edsIcons.checkbox,
377
+ size: "lg",
378
+ className: "eds-checkbox__icon eds-checkbox__icon--checked"
379
+ }), /*#__PURE__*/jsxRuntime.jsx(Icon, {
380
+ data: edsIcons.checkbox_outline,
381
+ size: "lg",
382
+ className: "eds-checkbox__icon eds-checkbox__icon--unchecked"
383
+ }), /*#__PURE__*/jsxRuntime.jsx(Icon, {
384
+ data: edsIcons.checkbox_indeterminate,
385
+ size: "lg",
386
+ className: "eds-checkbox__icon eds-checkbox__icon--indeterminate"
387
+ })]
388
+ })]
389
+ });
390
+
391
+ // Use Field for layout when label is provided
392
+ if (label) {
393
+ return /*#__PURE__*/jsxRuntime.jsxs(Field, {
394
+ position: "start",
395
+ disabled: disabled,
396
+ className: "eds-checkbox",
397
+ "data-color-appearance": disabled ? 'neutral' : 'accent',
398
+ "data-selectable-space": "md",
399
+ "data-space-proportions": "squished",
400
+ children: [checkboxInput, /*#__PURE__*/jsxRuntime.jsx(Field.Label, {
401
+ htmlFor: inputId,
402
+ indicator: indicator,
403
+ children: label
404
+ }), helperMessage && /*#__PURE__*/jsxRuntime.jsx(Field.HelperMessage, {
405
+ id: helperMessageId,
406
+ children: helperMessage
407
+ })]
408
+ });
409
+ }
410
+ return /*#__PURE__*/jsxRuntime.jsx("span", {
411
+ className: classNames$1('eds-checkbox', 'eds-checkbox--standalone'),
412
+ "data-color-appearance": disabled ? 'neutral' : 'accent',
413
+ "data-disabled": disabled || undefined,
414
+ children: checkboxInput
415
+ });
416
+ });
417
+ Checkbox.displayName = 'Checkbox';
418
+
419
+ /* eslint camelcase: "off" */
420
+ const classNames = (...classes) => classes.filter(Boolean).join(' ');
421
+ const Radio = /*#__PURE__*/react.forwardRef(function Radio({
422
+ label,
423
+ disabled = false,
424
+ id: providedId,
425
+ ...rest
426
+ }, ref) {
427
+ const generatedId = react.useId();
428
+ const inputId = providedId ?? generatedId;
429
+ const radioInput = /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
430
+ children: [/*#__PURE__*/jsxRuntime.jsx("input", {
431
+ type: "radio",
432
+ id: inputId,
433
+ className: "eds-radio__input",
434
+ disabled: disabled,
435
+ ref: ref,
436
+ ...rest
437
+ }), /*#__PURE__*/jsxRuntime.jsxs("span", {
438
+ className: "eds-radio__icon-wrapper",
439
+ children: [/*#__PURE__*/jsxRuntime.jsx(Icon, {
440
+ data: edsIcons.radio_button_selected,
441
+ size: "lg",
442
+ className: "eds-radio__icon eds-radio__icon--checked"
443
+ }), /*#__PURE__*/jsxRuntime.jsx(Icon, {
444
+ data: edsIcons.radio_button_unselected,
445
+ size: "lg",
446
+ className: "eds-radio__icon eds-radio__icon--unchecked"
447
+ })]
448
+ })]
449
+ });
450
+
451
+ // Use Field for layout when label is provided
452
+ if (label) {
453
+ return /*#__PURE__*/jsxRuntime.jsxs(Field, {
454
+ position: "start",
455
+ disabled: disabled,
456
+ className: "eds-radio",
457
+ "data-color-appearance": disabled ? 'neutral' : 'accent',
458
+ "data-selectable-space": "md",
459
+ "data-space-proportions": "squished",
460
+ children: [radioInput, /*#__PURE__*/jsxRuntime.jsx(Field.Label, {
461
+ htmlFor: inputId,
462
+ children: label
463
+ })]
464
+ });
465
+ }
466
+ return /*#__PURE__*/jsxRuntime.jsx("span", {
467
+ className: classNames('eds-radio', 'eds-radio--standalone'),
468
+ "data-color-appearance": disabled ? 'neutral' : 'accent',
469
+ "data-disabled": disabled || undefined,
470
+ children: radioInput
471
+ });
472
+ });
473
+ Radio.displayName = 'Radio';
474
+
475
+ const Switch = /*#__PURE__*/react.forwardRef(function Switch({
476
+ label,
477
+ disabled,
478
+ className,
479
+ id,
480
+ checked: controlledChecked,
481
+ defaultChecked,
482
+ onChange,
483
+ ...rest
484
+ }, ref) {
485
+ const generatedId = react.useId();
486
+ const inputId = id ?? generatedId;
487
+
488
+ // Track checked state for dynamic color appearance
489
+ const isControlled = controlledChecked !== undefined;
490
+ const [internalChecked, setInternalChecked] = react.useState(defaultChecked ?? false);
491
+ const isChecked = isControlled ? controlledChecked : internalChecked;
492
+ const handleChange = react.useCallback(event => {
493
+ if (!isControlled) {
494
+ setInternalChecked(event.target.checked);
495
+ }
496
+ onChange?.(event);
497
+ }, [isControlled, onChange]);
498
+ return /*#__PURE__*/jsxRuntime.jsxs(Field, {
499
+ position: "start",
500
+ disabled: disabled,
501
+ className: ['eds-switch', className].filter(Boolean).join(' '),
502
+ "data-font-size": "md",
503
+ "data-selectable-space": "md",
504
+ "data-space-proportions": "squished",
505
+ "data-color-appearance": disabled ? 'neutral' : 'accent',
506
+ children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
507
+ className: "eds-switch__control",
508
+ "data-color-appearance": !disabled && isChecked ? 'accent' : 'neutral',
509
+ children: [/*#__PURE__*/jsxRuntime.jsx("input", {
510
+ type: "checkbox",
511
+ role: "switch",
512
+ id: inputId,
513
+ className: "eds-switch__input",
514
+ disabled: disabled,
515
+ ref: ref,
516
+ checked: isControlled ? controlledChecked : undefined,
517
+ defaultChecked: !isControlled ? defaultChecked : undefined,
518
+ onChange: handleChange,
519
+ ...rest
520
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
521
+ className: "eds-switch__track",
522
+ children: /*#__PURE__*/jsxRuntime.jsx("span", {
523
+ className: "eds-switch__handle"
524
+ })
525
+ })]
526
+ }), /*#__PURE__*/jsxRuntime.jsx(Field.Label, {
527
+ htmlFor: inputId,
528
+ children: label
529
+ })]
530
+ });
531
+ });
532
+ Switch.displayName = 'Switch';
533
+
534
+ const Input = /*#__PURE__*/react.forwardRef(function Input({
535
+ invalid = false,
536
+ disabled,
537
+ readOnly,
538
+ type = 'text',
539
+ startText,
540
+ startAdornment,
541
+ endText,
542
+ endAdornment,
543
+ containerClassName,
544
+ className,
545
+ as: Component = 'input',
546
+ ...inputProps
547
+ }, ref) {
548
+ const tone = invalid && !disabled ? 'danger' : 'neutral';
549
+ const showErrorIcon = invalid && !disabled;
550
+ const hasStartAdornment = startText || startAdornment;
551
+ const hasEndAdornment = endText || endAdornment;
552
+ const containerClasses = ['eds-input-container', containerClassName].filter(Boolean).join(' ');
553
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
554
+ className: containerClasses,
555
+ "data-color-appearance": tone,
556
+ "data-font-size": "md",
557
+ "data-selectable-space": "sm",
558
+ "data-space-proportions": "squished",
559
+ "data-disabled": disabled || undefined,
560
+ "data-readonly": readOnly || undefined,
561
+ "data-invalid": invalid || undefined,
562
+ children: [showErrorIcon && /*#__PURE__*/jsxRuntime.jsx("span", {
563
+ className: "eds-error-icon",
564
+ "data-font-size": "xs",
565
+ "data-font-family": "ui",
566
+ "data-baseline": "center",
567
+ children: /*#__PURE__*/jsxRuntime.jsx(Icon, {
568
+ data: edsIcons.error_filled
569
+ })
570
+ }), hasStartAdornment && /*#__PURE__*/jsxRuntime.jsxs("div", {
571
+ className: "eds-adornment",
572
+ "data-font-size": "xs",
573
+ children: [startText && /*#__PURE__*/jsxRuntime.jsx("span", {
574
+ className: "eds-adornment__text",
575
+ "data-color-appearance": "neutral",
576
+ "data-font-family": "ui",
577
+ "data-font-size": "xs",
578
+ "data-baseline": "center",
579
+ children: startText
580
+ }), startAdornment && /*#__PURE__*/jsxRuntime.jsx("span", {
581
+ className: "eds-adornment__adornment",
582
+ "data-font-size": "xs",
583
+ "data-font-family": "ui",
584
+ "data-baseline": "center",
585
+ children: startAdornment
586
+ })]
587
+ }), /*#__PURE__*/jsxRuntime.jsx(Component, {
588
+ ref: ref,
589
+ type: type,
590
+ disabled: disabled,
591
+ readOnly: readOnly,
592
+ className: ['eds-input', className].filter(Boolean).join(' '),
593
+ "data-color-appearance": "neutral",
594
+ "data-font-family": "ui",
595
+ "data-font-size": "md",
596
+ "data-line-height": "default",
597
+ ...inputProps,
598
+ "aria-invalid": invalid || undefined
599
+ }), hasEndAdornment && /*#__PURE__*/jsxRuntime.jsxs("div", {
600
+ className: "eds-adornment",
601
+ "data-font-size": "xs",
602
+ children: [endText && /*#__PURE__*/jsxRuntime.jsx("span", {
603
+ className: "eds-adornment__text",
604
+ "data-color-appearance": "neutral",
605
+ "data-font-family": "ui",
606
+ "data-font-size": "xs",
607
+ "data-baseline": "center",
608
+ children: endText
609
+ }), endAdornment && /*#__PURE__*/jsxRuntime.jsx("span", {
610
+ className: "eds-adornment__adornment",
611
+ "data-font-size": "xs",
612
+ "data-font-family": "ui",
613
+ "data-baseline": "center",
614
+ children: endAdornment
615
+ })]
616
+ })]
617
+ });
618
+ });
619
+
620
+ const {
621
+ colors: {
622
+ text: {
623
+ static_icons__primary_white: {
624
+ rgba: white
625
+ }
626
+ },
627
+ ui: {
628
+ background__overlay: {
629
+ rgba: background
630
+ }
631
+ }
632
+ },
633
+ typography: {
634
+ ui
635
+ },
636
+ spacings: {
637
+ comfortable: {
638
+ x_large: spacingXlarge,
639
+ small: spacingSmall
640
+ }
641
+ },
642
+ shape: {
643
+ corners: {
644
+ borderRadius
645
+ }
646
+ }
647
+ } = edsTokens.tokens;
648
+ const tooltip = {
649
+ typography: {
650
+ ...ui.tooltip,
651
+ color: white
652
+ },
653
+ background,
654
+ border: {
655
+ type: 'border',
656
+ radius: borderRadius
657
+ },
658
+ entities: {
659
+ arrow: {
660
+ width: '6px',
661
+ height: spacingSmall}
662
+ },
663
+ spacings: {
664
+ left: spacingSmall,
665
+ right: spacingSmall,
666
+ top: spacingSmall,
667
+ bottom: spacingSmall
668
+ }
669
+ };
670
+
671
+ const initalState = {
672
+ /** Density for all components inside `EdsProvider` */
673
+ density: 'comfortable'
674
+ };
675
+ const EdsContext = /*#__PURE__*/react.createContext(initalState);
676
+ const useEds = () => react.useContext(EdsContext);
677
+
678
+ const StyledTooltip = styled__default.default('div').withConfig({
679
+ shouldForwardProp: () => true //workaround to avoid warning until popover gets added to react types
680
+ }).withConfig({
681
+ displayName: "Tooltip__StyledTooltip",
682
+ componentId: "sc-m2im2p-0"
683
+ })(["inset:unset;border:0;overflow:visible;", " ", " ", " background:", ";white-space:nowrap;&::before{content:'; Has tooltip: ';clip-path:inset(50%);height:1px;width:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;}&::backdrop{background-color:transparent;}"], edsUtils.typographyTemplate(tooltip.typography), edsUtils.spacingsTemplate(tooltip.spacings), edsUtils.bordersTemplate(tooltip.border), tooltip.background);
684
+ const ArrowWrapper = styled__default.default.div.withConfig({
685
+ displayName: "Tooltip__ArrowWrapper",
686
+ componentId: "sc-m2im2p-1"
687
+ })(["position:absolute;width:", ";height:", ";z-index:-1;"], tooltip.entities.arrow.width, tooltip.entities.arrow.height);
688
+ const TooltipArrow = styled__default.default.svg.withConfig({
689
+ displayName: "Tooltip__TooltipArrow",
690
+ componentId: "sc-m2im2p-2"
691
+ })(["width:", ";height:", ";position:absolute;fill:", ";"], tooltip.entities.arrow.width, tooltip.entities.arrow.height, tooltip.background);
692
+ const Tooltip = /*#__PURE__*/react.forwardRef(function Tooltip({
693
+ title,
694
+ placement = 'bottom',
695
+ children,
696
+ style,
697
+ enterDelay = 100,
698
+ disabled = false,
699
+ portalContainer,
700
+ ...rest
701
+ }, ref) {
702
+ const arrowRef = react.useRef(null);
703
+ const [open, setOpen] = react.useState(false);
704
+ const {
705
+ rootElement
706
+ } = useEds();
707
+ const shouldOpen = Boolean(title) && typeof document !== 'undefined';
708
+ const {
709
+ x,
710
+ y,
711
+ refs,
712
+ strategy,
713
+ context,
714
+ middlewareData: {
715
+ arrow: {
716
+ x: arrowX,
717
+ y: arrowY
718
+ } = {}
719
+ },
720
+ placement: finalPlacement,
721
+ elements
722
+ } = react$1.useFloating({
723
+ placement,
724
+ open,
725
+ onOpenChange: setOpen,
726
+ middleware: [react$1.offset(14), react$1.flip(), react$1.shift({
727
+ padding: 8
728
+ }), react$1.arrow({
729
+ element: arrowRef
730
+ })],
731
+ whileElementsMounted: react$1.autoUpdate
732
+ });
733
+ const mergedAnchorRef = react.useMemo(() => edsUtils.mergeRefs(refs.setReference), [refs.setReference]);
734
+ const tooltipRef = react.useMemo(() => edsUtils.mergeRefs(refs.setFloating, ref), [refs.setFloating, ref]);
735
+ const {
736
+ getReferenceProps,
737
+ getFloatingProps
738
+ } = react$1.useInteractions([react$1.useHover(context, {
739
+ delay: {
740
+ open: enterDelay
741
+ }
742
+ }), react$1.useFocus(context), react$1.useRole(context, {
743
+ role: 'tooltip'
744
+ }), react$1.useDismiss(context)]);
745
+ react.useEffect(() => {
746
+ const staticSide = {
747
+ top: 'bottom',
748
+ right: 'left',
749
+ bottom: 'top',
750
+ left: 'right'
751
+ }[finalPlacement.split('-')[0]];
752
+ let arrowTransform = 'none';
753
+ switch (staticSide) {
754
+ case 'right':
755
+ arrowTransform = 'rotateY(180deg)';
756
+ break;
757
+ case 'left':
758
+ arrowTransform = 'none';
759
+ break;
760
+ case 'top':
761
+ arrowTransform = 'rotate(90deg)';
762
+ break;
763
+ case 'bottom':
764
+ arrowTransform = 'rotate(-90deg)';
765
+ break;
766
+ }
767
+ if (arrowRef.current) {
768
+ Object.assign(arrowRef.current.style, {
769
+ left: arrowX != null ? `${arrowX}px` : '',
770
+ top: arrowY != null ? `${arrowY}px` : '',
771
+ right: '',
772
+ bottom: '',
773
+ [staticSide]: '-6px',
774
+ transform: arrowTransform
775
+ });
776
+ }
777
+ });
778
+ const updatedChildren = /*#__PURE__*/react.cloneElement(children,
779
+ // eslint-disable-line @typescript-eslint/no-explicit-any
780
+ {
781
+ ...getReferenceProps(children.props),
782
+ ref: edsUtils.mergeRefs(
783
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
784
+ children.props.ref, mergedAnchorRef)
785
+ });
786
+ react.useEffect(() => {
787
+ if (!elements.floating) return;
788
+ if (elements.floating.isConnected && shouldOpen && open) {
789
+ elements.floating.showPopover();
790
+ }
791
+ }, [open, shouldOpen, elements.floating]);
792
+ const TooltipEl = /*#__PURE__*/jsxRuntime.jsxs(StyledTooltip, {
793
+ popover: "manual",
794
+ ...rest,
795
+ ...getFloatingProps({
796
+ ref: tooltipRef,
797
+ className: `eds-tooltip ${rest.className ?? ''}`,
798
+ style: {
799
+ ...style,
800
+ position: strategy,
801
+ top: y || 0,
802
+ left: x || 0
803
+ }
804
+ }),
805
+ children: [title, /*#__PURE__*/jsxRuntime.jsx(ArrowWrapper, {
806
+ ref: arrowRef,
807
+ children: /*#__PURE__*/jsxRuntime.jsx(TooltipArrow, {
808
+ className: "arrowSvg",
809
+ children: /*#__PURE__*/jsxRuntime.jsx("path", {
810
+ d: "M0.504838 4.86885C-0.168399 4.48524 -0.168399 3.51476 0.504838 3.13115L6 8.59227e-08L6 8L0.504838 4.86885Z"
811
+ })
812
+ })
813
+ })]
814
+ });
815
+ return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
816
+ children: [updatedChildren, shouldOpen && open && !disabled && /*#__PURE__*/reactDom.createPortal(TooltipEl, portalContainer ?? rootElement ?? document.body)]
817
+ });
818
+ });
819
+
820
+ const TextField = /*#__PURE__*/react.forwardRef(function TextField({
821
+ label,
822
+ labelInfo,
823
+ indicator,
824
+ description,
825
+ helperMessage,
826
+ id: providedId,
827
+ invalid = false,
828
+ disabled = false,
829
+ ...inputProps
830
+ }, ref) {
831
+ const {
832
+ inputId,
833
+ descriptionId,
834
+ helperMessageId,
835
+ getDescribedBy
836
+ } = useFieldIds(providedId);
837
+ return /*#__PURE__*/jsxRuntime.jsxs(Field, {
838
+ disabled: disabled,
839
+ children: [label && /*#__PURE__*/jsxRuntime.jsxs("div", {
840
+ className: "eds-text-field__header",
841
+ children: [/*#__PURE__*/jsxRuntime.jsx(Field.Label, {
842
+ htmlFor: inputId,
843
+ indicator: indicator,
844
+ children: label
845
+ }), labelInfo && /*#__PURE__*/jsxRuntime.jsx(Tooltip, {
846
+ title: labelInfo,
847
+ placement: "top",
848
+ children: /*#__PURE__*/jsxRuntime.jsx("button", {
849
+ type: "button",
850
+ className: "eds-text-field__info",
851
+ "aria-label": "More information",
852
+ children: /*#__PURE__*/jsxRuntime.jsx(Icon, {
853
+ data: edsIcons.info_circle,
854
+ size: "xs"
855
+ })
856
+ })
857
+ })]
858
+ }), description && /*#__PURE__*/jsxRuntime.jsx(Field.Description, {
859
+ id: descriptionId,
860
+ children: description
861
+ }), /*#__PURE__*/jsxRuntime.jsx(Input, {
862
+ ref: ref,
863
+ id: inputId,
864
+ disabled: disabled,
865
+ invalid: invalid,
866
+ "aria-describedby": getDescribedBy({
867
+ hasDescription: !!description,
868
+ hasHelperMessage: !!helperMessage
869
+ }),
870
+ ...inputProps
871
+ }), helperMessage && /*#__PURE__*/jsxRuntime.jsx(Field.HelperMessage, {
872
+ id: helperMessageId,
873
+ role: invalid ? 'alert' : undefined,
874
+ children: helperMessage
875
+ })]
876
+ });
877
+ });
878
+
879
+ exports.Button = Button;
880
+ exports.Checkbox = Checkbox;
881
+ exports.Field = Field;
100
882
  exports.Icon = Icon;
101
- exports.Placeholder = Placeholder;
883
+ exports.Input = Input;
884
+ exports.Radio = Radio;
885
+ exports.Switch = Switch;
886
+ exports.TextField = TextField;
887
+ exports.useFieldIds = useFieldIds;