@ndla/primitives 0.0.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 (97) hide show
  1. package/LICENSE +674 -0
  2. package/dist/panda.buildinfo.json +426 -0
  3. package/dist/styles.css +1738 -0
  4. package/es/Accordion.js +103 -0
  5. package/es/ArticleLists.js +106 -0
  6. package/es/Badge.js +55 -0
  7. package/es/BlockQuote.js +49 -0
  8. package/es/Button.js +211 -0
  9. package/es/Checkbox.js +118 -0
  10. package/es/Dialog.js +329 -0
  11. package/es/ExpandableBox.js +55 -0
  12. package/es/FieldErrorMessage.js +44 -0
  13. package/es/FieldHelper.js +37 -0
  14. package/es/FormControl.js +163 -0
  15. package/es/FramedContent.js +54 -0
  16. package/es/Icon.js +71 -0
  17. package/es/Input.js +159 -0
  18. package/es/Label.js +104 -0
  19. package/es/Menu.js +171 -0
  20. package/es/MessageBox.js +57 -0
  21. package/es/NdlaLogo.js +284 -0
  22. package/es/Pagination.js +37 -0
  23. package/es/Popover.js +78 -0
  24. package/es/RadioGroup.js +136 -0
  25. package/es/Skeleton.js +31 -0
  26. package/es/Slider.js +102 -0
  27. package/es/Spinner.js +54 -0
  28. package/es/Switch.js +130 -0
  29. package/es/Table.js +75 -0
  30. package/es/Text.js +54 -0
  31. package/es/Toast.js +82 -0
  32. package/es/Tooltip.js +59 -0
  33. package/es/createStyleContext.js +62 -0
  34. package/es/index.js +19 -0
  35. package/lib/Accordion.d.ts +17 -0
  36. package/lib/Accordion.js +109 -0
  37. package/lib/ArticleLists.d.ts +20 -0
  38. package/lib/ArticleLists.js +115 -0
  39. package/lib/Badge.d.ts +33 -0
  40. package/lib/Badge.js +62 -0
  41. package/lib/BlockQuote.d.ts +28 -0
  42. package/lib/BlockQuote.js +56 -0
  43. package/lib/Button.d.ts +131 -0
  44. package/lib/Button.js +217 -0
  45. package/lib/Checkbox.d.ts +15 -0
  46. package/lib/Checkbox.js +125 -0
  47. package/lib/Dialog.d.ts +107 -0
  48. package/lib/Dialog.js +338 -0
  49. package/lib/ExpandableBox.d.ts +12 -0
  50. package/lib/ExpandableBox.js +63 -0
  51. package/lib/FieldErrorMessage.d.ts +11 -0
  52. package/lib/FieldErrorMessage.js +50 -0
  53. package/lib/FieldHelper.d.ts +11 -0
  54. package/lib/FieldHelper.js +43 -0
  55. package/lib/FormControl.d.ts +65 -0
  56. package/lib/FormControl.js +173 -0
  57. package/lib/FramedContent.d.ts +32 -0
  58. package/lib/FramedContent.js +61 -0
  59. package/lib/Icon.d.ts +37 -0
  60. package/lib/Icon.js +78 -0
  61. package/lib/Input.d.ts +20 -0
  62. package/lib/Input.js +165 -0
  63. package/lib/Label.d.ts +16 -0
  64. package/lib/Label.js +110 -0
  65. package/lib/Menu.d.ts +25 -0
  66. package/lib/Menu.js +179 -0
  67. package/lib/MessageBox.d.ts +33 -0
  68. package/lib/MessageBox.js +64 -0
  69. package/lib/NdlaLogo.d.ts +15 -0
  70. package/lib/NdlaLogo.js +293 -0
  71. package/lib/Pagination.d.ts +14 -0
  72. package/lib/Pagination.js +43 -0
  73. package/lib/Popover.d.ts +22 -0
  74. package/lib/Popover.js +87 -0
  75. package/lib/RadioGroup.d.ts +19 -0
  76. package/lib/RadioGroup.js +143 -0
  77. package/lib/Skeleton.d.ts +11 -0
  78. package/lib/Skeleton.js +38 -0
  79. package/lib/Slider.d.ts +17 -0
  80. package/lib/Slider.js +109 -0
  81. package/lib/Spinner.d.ts +26 -0
  82. package/lib/Spinner.js +61 -0
  83. package/lib/Switch.d.ts +21 -0
  84. package/lib/Switch.js +137 -0
  85. package/lib/Table.d.ts +10 -0
  86. package/lib/Table.js +82 -0
  87. package/lib/Text.d.ts +24 -0
  88. package/lib/Text.js +62 -0
  89. package/lib/Toast.d.ts +18 -0
  90. package/lib/Toast.js +90 -0
  91. package/lib/Tooltip.d.ts +16 -0
  92. package/lib/Tooltip.js +65 -0
  93. package/lib/createStyleContext.d.ts +27 -0
  94. package/lib/createStyleContext.js +69 -0
  95. package/lib/index.d.ts +28 -0
  96. package/lib/index.js +130 -0
  97. package/package.json +48 -0
package/es/Dialog.js ADDED
@@ -0,0 +1,329 @@
1
+ /**
2
+ * Copyright (c) 2024-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import { forwardRef } from "react";
10
+ import { Dialog } from "@ark-ui/react";
11
+ import { sva } from "@ndla/styled-system/css";
12
+ import { styled } from "@ndla/styled-system/jsx";
13
+ import { createStyleContext } from "./createStyleContext";
14
+ import { Heading, Text } from "./Text";
15
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
16
+ const dialogRecipe = sva({
17
+ // We only use a subset of the dialog components, so we roll our own slots instead of relying on @ark/anatomy.
18
+ slots: ["positioner", "backdrop", "content"],
19
+ className: "dialog",
20
+ base: {
21
+ backdrop: {
22
+ position: "fixed",
23
+ height: "100vh",
24
+ width: "100vw",
25
+ zIndex: "overlay",
26
+ left: "0",
27
+ top: "0",
28
+ // TODO: Consider if this should be a token. It's probably consistent enough between dark and light mode to be a token.
29
+ background: "rgba(1, 1, 1, 0.3)",
30
+ _open: {
31
+ animation: "backdrop-in"
32
+ },
33
+ _closed: {
34
+ animation: "backdrop-out"
35
+ }
36
+ },
37
+ positioner: {
38
+ position: "fixed",
39
+ display: "flex",
40
+ alignItems: "center",
41
+ justifyContent: "center",
42
+ overflow: "hidden",
43
+ left: "0",
44
+ top: "0",
45
+ width: "100vw",
46
+ height: "100dvh",
47
+ zIndex: "modal"
48
+ },
49
+ content: {
50
+ "--margin": "token(sizes.medium)",
51
+ position: "relative",
52
+ background: "surface.default",
53
+ boxShadow: "xlarge",
54
+ height: "min-content",
55
+ maxWidth: "95%",
56
+ maxHeight: "95%",
57
+ margin: "auto",
58
+ overflowY: "auto",
59
+ borderRadius: {
60
+ base: "sharp",
61
+ tablet: "small"
62
+ },
63
+ paddingBlockStart: "env(safe-area-inset-top)",
64
+ paddingBlockEnd: "env(safe-area-inset-bottom)",
65
+ paddingInlineStart: "env(safe-area-inset-left)",
66
+ paddingInlineEnd: "env(safe-area-inset-right)",
67
+ tabletDown: {
68
+ "--margin": "0px",
69
+ minWidth: "100%",
70
+ minHeight: "100%"
71
+ }
72
+ }
73
+ },
74
+ defaultVariants: {
75
+ size: "medium",
76
+ position: "center"
77
+ },
78
+ compoundVariants: [{
79
+ variant: "drawer",
80
+ position: "left",
81
+ css: {
82
+ content: {
83
+ minHeight: "100%",
84
+ maxHeight: "100%",
85
+ width: "var(--size)",
86
+ _open: {
87
+ animation: "drawer-in-left"
88
+ },
89
+ _closed: {
90
+ animation: "drawer-out-left"
91
+ }
92
+ }
93
+ }
94
+ }, {
95
+ variant: "drawer",
96
+ position: "right",
97
+ css: {
98
+ content: {
99
+ minHeight: "100%",
100
+ maxHeight: "100%",
101
+ width: "var(--size)",
102
+ _open: {
103
+ animation: "drawer-in-right"
104
+ },
105
+ _closed: {
106
+ animation: "drawer-out-right"
107
+ }
108
+ }
109
+ }
110
+ }, {
111
+ variant: "drawer",
112
+ position: "top",
113
+ css: {
114
+ content: {
115
+ minWidth: "100%",
116
+ maxWidth: "100%",
117
+ height: "var(--size)",
118
+ _open: {
119
+ animation: "drawer-in-top"
120
+ },
121
+ _closed: {
122
+ animation: "drawer-out-top"
123
+ }
124
+ }
125
+ }
126
+ }, {
127
+ variant: "drawer",
128
+ position: "bottom",
129
+ css: {
130
+ content: {
131
+ minWidth: "100%",
132
+ maxWidth: "100%",
133
+ height: "var(--size)",
134
+ _open: {
135
+ animation: "drawer-in-bottom"
136
+ },
137
+ _closed: {
138
+ animation: "drawer-out-bottom"
139
+ }
140
+ }
141
+ }
142
+ }, {
143
+ variant: "drawer",
144
+ size: "xsmall",
145
+ css: {
146
+ content: {
147
+ "--size": "sizes.surface.3xsmall"
148
+ }
149
+ }
150
+ }, {
151
+ variant: "drawer",
152
+ size: "small",
153
+ css: {
154
+ content: {
155
+ "--size": "sizes.surface.xsmall"
156
+ }
157
+ }
158
+ }, {
159
+ variant: "drawer",
160
+ size: "medium",
161
+ css: {
162
+ content: {
163
+ "--size": "sizes.surface.medium"
164
+ }
165
+ }
166
+ }, {
167
+ variant: "drawer",
168
+ size: "large",
169
+ css: {
170
+ content: {
171
+ "--size": "sizes.surface.xlarge"
172
+ }
173
+ }
174
+ }],
175
+ variants: {
176
+ variant: {
177
+ drawer: {
178
+ content: {
179
+ "--margin": "0px",
180
+ borderRadius: {
181
+ base: "sharp",
182
+ tablet: "sharp"
183
+ }
184
+ }
185
+ },
186
+ dialog: {
187
+ content: {
188
+ width: "var(--size)",
189
+ _open: {
190
+ animation: "dialog-in"
191
+ },
192
+ _closed: {
193
+ animation: "dialog-out"
194
+ }
195
+ }
196
+ }
197
+ },
198
+ position: {
199
+ left: {
200
+ content: {
201
+ marginInlineStart: "min(var(--margin), 5%)"
202
+ }
203
+ },
204
+ center: {},
205
+ right: {
206
+ content: {
207
+ marginInlineEnd: "var(--margin)"
208
+ }
209
+ },
210
+ bottom: {
211
+ content: {
212
+ marginBlockEnd: "var(--margin)"
213
+ }
214
+ },
215
+ top: {
216
+ content: {
217
+ marginBlockStart: "var(--margin)"
218
+ }
219
+ }
220
+ },
221
+ size: {
222
+ full: {
223
+ content: {
224
+ "--margin": "0px",
225
+ minHeight: "100%",
226
+ minWidth: "100%",
227
+ borderRadius: "sharp"
228
+ }
229
+ },
230
+ xsmall: {
231
+ content: {
232
+ "--size": "sizes.surface.xsmall"
233
+ }
234
+ },
235
+ small: {
236
+ content: {
237
+ "--size": "sizes.surface.medium"
238
+ }
239
+ },
240
+ medium: {
241
+ content: {
242
+ "--size": "sizes.surface.xlarge"
243
+ }
244
+ },
245
+ large: {
246
+ content: {
247
+ "--size": "sizes.surface.4xlarge"
248
+ }
249
+ }
250
+ }
251
+ }
252
+ });
253
+ const {
254
+ withRootProvider,
255
+ withContext
256
+ } = createStyleContext(dialogRecipe);
257
+ export const InternalDialogRoot = withRootProvider(Dialog.Root);
258
+ export const DialogRoot = _ref => {
259
+ let {
260
+ lazyMount = true,
261
+ unmountOnExit = true,
262
+ ...props
263
+ } = _ref;
264
+ return /*#__PURE__*/_jsx(InternalDialogRoot, {
265
+ lazyMount: lazyMount,
266
+ unmountOnExit: unmountOnExit,
267
+ ...props
268
+ });
269
+ };
270
+ export const DialogBackdrop = withContext(Dialog.Backdrop, "backdrop");
271
+ export const DialogStandaloneContent = withContext(Dialog.Content, "content");
272
+ export const DialogPositioner = withContext(Dialog.Positioner, "positioner");
273
+ export const DialogContent = /*#__PURE__*/forwardRef((props, ref) => /*#__PURE__*/_jsxs(_Fragment, {
274
+ children: [/*#__PURE__*/_jsx(DialogBackdrop, {}), /*#__PURE__*/_jsx(DialogPositioner, {
275
+ children: /*#__PURE__*/_jsx(DialogStandaloneContent, {
276
+ ref: ref,
277
+ ...props
278
+ })
279
+ })]
280
+ }));
281
+ export const DialogDescription = _ref2 => {
282
+ let {
283
+ textStyle = "body.large",
284
+ ...rest
285
+ } = _ref2;
286
+ return /*#__PURE__*/_jsx(Dialog.Description, {
287
+ asChild: true,
288
+ children: /*#__PURE__*/_jsx(Text, {
289
+ as: "p",
290
+ textStyle: textStyle,
291
+ ...rest
292
+ })
293
+ });
294
+ };
295
+ export const DialogTitle = _ref3 => {
296
+ let {
297
+ textStyle = "title.medium",
298
+ ...rest
299
+ } = _ref3;
300
+ return /*#__PURE__*/_jsx(Dialog.Title, {
301
+ asChild: true,
302
+ children: /*#__PURE__*/_jsx(Heading, {
303
+ as: "h1",
304
+ textStyle: textStyle,
305
+ ...rest
306
+ })
307
+ });
308
+ };
309
+ export const DialogTrigger = Dialog.Trigger;
310
+ export const DialogCloseTrigger = Dialog.CloseTrigger;
311
+ export const DialogHeader = styled("div", {
312
+ base: {
313
+ display: "flex",
314
+ paddingInline: "medium",
315
+ paddingBlockStart: "medium",
316
+ justifyContent: "space-between",
317
+ gap: "xsmall"
318
+ }
319
+ });
320
+ export const DialogBody = styled("div", {
321
+ base: {
322
+ display: "flex",
323
+ flexDirection: "column",
324
+ gap: "xsmall",
325
+ paddingInline: "medium",
326
+ paddingBlockStart: "small",
327
+ paddingBlockEnd: "medium"
328
+ }
329
+ });
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Copyright (c) 2024-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import { styled } from "@ndla/styled-system/jsx";
10
+ import { jsx as _jsx } from "react/jsx-runtime";
11
+ const StyledExpandableBox = styled("details", {
12
+ base: {
13
+ transitionDuration: "fast",
14
+ width: "100%",
15
+ position: "relative",
16
+ border: "1px solid",
17
+ borderRadius: "xsmall",
18
+ borderColor: "stroke.subtle",
19
+ padding: "medium",
20
+ _open: {
21
+ padding: "medium",
22
+ "& summary": {
23
+ marginBlockEnd: "-xxsmall"
24
+ }
25
+ }
26
+ }
27
+ });
28
+ export const ExpandableBox = props => /*#__PURE__*/_jsx(StyledExpandableBox, {
29
+ ...props
30
+ });
31
+ const StyledExpandableBoxSummary = styled("summary", {
32
+ base: {
33
+ cursor: "pointer",
34
+ margin: "-medium",
35
+ padding: "medium",
36
+ textStyle: "label.large!",
37
+ _hover: {
38
+ color: "text.action"
39
+ },
40
+ "& > *": {
41
+ display: "inline!",
42
+ textStyle: "label.large!"
43
+ }
44
+ }
45
+ });
46
+ export const ExpandableBoxSummary = _ref => {
47
+ let {
48
+ children,
49
+ ...rest
50
+ } = _ref;
51
+ return /*#__PURE__*/_jsx(StyledExpandableBoxSummary, {
52
+ ...rest,
53
+ children: children
54
+ });
55
+ };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Copyright (c) 2024-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import { forwardRef } from "react";
10
+ import { css, cx } from "@ndla/styled-system/css";
11
+ import { styled } from "@ndla/styled-system/jsx";
12
+ import { useFormControlContext } from "./FormControl";
13
+ import { jsx as _jsx } from "react/jsx-runtime";
14
+ const StyledErrorMessage = styled("div", {
15
+ base: {
16
+ color: "text.error",
17
+ whiteSpace: "pre-line"
18
+ }
19
+ });
20
+ export const FieldErrorMessage = /*#__PURE__*/forwardRef((_ref, ref) => {
21
+ var _field$getErrorMessag;
22
+ let {
23
+ textStyle = "label.small",
24
+ fontWeight,
25
+ color,
26
+ srOnly,
27
+ className,
28
+ ...props
29
+ } = _ref;
30
+ const field = useFormControlContext();
31
+ if (field && !field.isInvalid) return null;
32
+ return /*#__PURE__*/_jsx(StyledErrorMessage, {
33
+ ...((_field$getErrorMessag = field === null || field === void 0 ? void 0 : field.getErrorMessageProps(props, ref)) !== null && _field$getErrorMessag !== void 0 ? _field$getErrorMessag : {
34
+ ref,
35
+ ...props
36
+ }),
37
+ className: cx(css({
38
+ textStyle,
39
+ fontWeight,
40
+ color,
41
+ srOnly: srOnly
42
+ }), className)
43
+ });
44
+ });
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Copyright (c) 2024-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import { forwardRef } from "react";
10
+ import { css, cx } from "@ndla/styled-system/css";
11
+ import { styled } from "@ndla/styled-system/jsx";
12
+ import { useFormControlContext } from "./FormControl";
13
+ import { jsx as _jsx } from "react/jsx-runtime";
14
+ export const FieldHelper = /*#__PURE__*/forwardRef((_ref, ref) => {
15
+ var _field$getHelpTextPro;
16
+ let {
17
+ textStyle = "label.small",
18
+ fontWeight,
19
+ color,
20
+ srOnly,
21
+ className,
22
+ ...props
23
+ } = _ref;
24
+ const field = useFormControlContext();
25
+ return /*#__PURE__*/_jsx(styled.div, {
26
+ ...((_field$getHelpTextPro = field === null || field === void 0 ? void 0 : field.getHelpTextProps(props, ref)) !== null && _field$getHelpTextPro !== void 0 ? _field$getHelpTextPro : {
27
+ ref,
28
+ ...props
29
+ }),
30
+ className: cx(css({
31
+ textStyle,
32
+ fontWeight,
33
+ color,
34
+ srOnly
35
+ }), className)
36
+ });
37
+ });
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Copyright (c) 2024-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import { createContext, useCallback, useContext, useState } from "react";
10
+ import { styled } from "@ndla/styled-system/jsx";
11
+ import { composeRefs } from "@ndla/util";
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ const StyledFormControl = styled("div", {
14
+ base: {
15
+ display: "flex",
16
+ flexDirection: "column",
17
+ gap: "3xsmall"
18
+ }
19
+ });
20
+ const useFormControlProvider = _ref => {
21
+ let {
22
+ id: idProp,
23
+ isRequired,
24
+ isDisabled,
25
+ isInvalid
26
+ } = _ref;
27
+ const id = "field-".concat(idProp);
28
+ const labelId = "".concat(id, "-label");
29
+ const errorTextId = "".concat(id, "-error-message");
30
+ const helpTextId = "".concat(id, "-helper");
31
+ const [hasErrorText, setHasErrorText] = useState(false);
32
+ const [hasHelpText, setHasHelpText] = useState(false);
33
+ const getHelpTextProps = useCallback(function () {
34
+ let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
35
+ let forwardedRef = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
36
+ return {
37
+ id: helpTextId,
38
+ ...props,
39
+ ref: composeRefs(forwardedRef, node => {
40
+ if (!node) return;
41
+ setHasHelpText(true);
42
+ })
43
+ };
44
+ }, [helpTextId]);
45
+ const getLabelProps = useCallback(function () {
46
+ let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
47
+ let forwardedRef = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
48
+ return {
49
+ ...props,
50
+ ref: forwardedRef,
51
+ "data-disabled": props !== null && props !== void 0 && props["data-disabled"] ? props["data-disabled"] : isDisabled,
52
+ "data-invalid": props !== null && props !== void 0 && props["data-invalid"] ? props["data-invalid"] : isInvalid,
53
+ id: props.id !== undefined ? props.id : labelId,
54
+ htmlFor: props.htmlFor !== undefined ? props.htmlFor : id
55
+ };
56
+ }, [id, isDisabled, isInvalid, labelId]);
57
+ const getErrorMessageProps = useCallback(function () {
58
+ let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
59
+ let forwardedRef = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
60
+ return {
61
+ id: errorTextId,
62
+ ...props,
63
+ ref: composeRefs(forwardedRef, node => {
64
+ if (!node) return;
65
+ setHasErrorText(true);
66
+ }),
67
+ "aria-live": "polite"
68
+ };
69
+ }, [errorTextId]);
70
+ return {
71
+ isRequired: !!isRequired,
72
+ isDisabled: !!isDisabled,
73
+ isInvalid: !!isInvalid,
74
+ hasErrorText,
75
+ setHasErrorText,
76
+ hasHelpText,
77
+ setHasHelpText,
78
+ id,
79
+ labelId,
80
+ errorTextId,
81
+ helpTextId,
82
+ getHelpTextProps,
83
+ getErrorMessageProps,
84
+ getLabelProps
85
+ };
86
+ };
87
+ const FormControlContext = /*#__PURE__*/createContext(undefined);
88
+
89
+ /**
90
+ * Form control component inspired by chakra-ui. Allows for easy composition of form fields.
91
+ */
92
+ export const FormControl = _ref2 => {
93
+ let {
94
+ children,
95
+ id,
96
+ isDisabled,
97
+ isInvalid,
98
+ isRequired,
99
+ ...rest
100
+ } = _ref2;
101
+ const context = useFormControlProvider({
102
+ id,
103
+ isDisabled,
104
+ isInvalid,
105
+ isRequired
106
+ });
107
+ return /*#__PURE__*/_jsx(FormControlContext.Provider, {
108
+ value: context,
109
+ children: /*#__PURE__*/_jsx(StyledFormControl, {
110
+ ...rest,
111
+ children: children
112
+ })
113
+ });
114
+ };
115
+ export const useFormControlContext = () => {
116
+ const context = useContext(FormControlContext);
117
+ return context;
118
+ };
119
+ export const useFormControlProps = _ref3 => {
120
+ let {
121
+ id,
122
+ disabled,
123
+ required,
124
+ isDisabled,
125
+ isInvalid,
126
+ isRequired,
127
+ ...rest
128
+ } = _ref3;
129
+ const field = useFormControlContext();
130
+ const labelIds = [];
131
+ if (field !== null && field !== void 0 && field.hasErrorText && field !== null && field !== void 0 && field.isInvalid) {
132
+ labelIds.push(field.errorTextId);
133
+ }
134
+ if (rest["aria-describedby"]) {
135
+ labelIds.push(rest["aria-describedby"]);
136
+ }
137
+ if (field !== null && field !== void 0 && field.hasHelpText) {
138
+ labelIds.push(field.helpTextId);
139
+ }
140
+ return {
141
+ ...rest,
142
+ "aria-describedby": labelIds.join(" ") || undefined,
143
+ id: id !== null && id !== void 0 ? id : field === null || field === void 0 ? void 0 : field.id,
144
+ isDisabled: disabled !== null && disabled !== void 0 ? disabled : field === null || field === void 0 ? void 0 : field.isDisabled,
145
+ isRequired: required !== null && required !== void 0 ? required : field === null || field === void 0 ? void 0 : field.isRequired,
146
+ isInvalid: isInvalid !== null && isInvalid !== void 0 ? isInvalid : field === null || field === void 0 ? void 0 : field.isInvalid
147
+ };
148
+ };
149
+ export const useFormControl = props => {
150
+ const {
151
+ isDisabled,
152
+ isInvalid,
153
+ isRequired,
154
+ ...rest
155
+ } = useFormControlProps(props);
156
+ return {
157
+ ...rest,
158
+ disabled: isDisabled,
159
+ required: isRequired,
160
+ "aria-invalid": isInvalid ? true : undefined,
161
+ "aria-required": isRequired ? true : undefined
162
+ };
163
+ };
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Copyright (c) 2024-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import { cva, cx } from "@ndla/styled-system/css";
10
+ import { styled } from "@ndla/styled-system/jsx";
11
+ import { jsx as _jsx } from "react/jsx-runtime";
12
+ const framedContentRecipe = cva({
13
+ base: {
14
+ padding: "medium",
15
+ border: "1px solid",
16
+ borderRadius: "small",
17
+ boxShadow: "4px 4px 0px 0px var(--shadow-color)"
18
+ },
19
+ variants: {
20
+ colorTheme: {
21
+ neutral: {
22
+ backgroundColor: "surface.default",
23
+ borderColor: "stroke.subtle",
24
+ boxShadowColor: "stroke.subtle"
25
+ },
26
+ brand1: {
27
+ backgroundColor: "surface.brand.1.subtle",
28
+ borderColor: "surface.brand.1.strong",
29
+ boxShadowColor: "surface.brand.1.strong"
30
+ },
31
+ brand2: {
32
+ backgroundColor: "surface.brand.2.subtle",
33
+ borderColor: "surface.brand.2.strong",
34
+ boxShadowColor: "surface.brand.2.strong"
35
+ }
36
+ }
37
+ },
38
+ defaultVariants: {
39
+ colorTheme: "neutral"
40
+ }
41
+ });
42
+ export const FramedContent = _ref => {
43
+ let {
44
+ className,
45
+ colorTheme,
46
+ ...rest
47
+ } = _ref;
48
+ return /*#__PURE__*/_jsx(styled.div, {
49
+ className: cx(framedContentRecipe({
50
+ colorTheme
51
+ }), className),
52
+ ...rest
53
+ });
54
+ };