@adamjanicki/ui 1.0.6 → 1.0.8

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.
@@ -8,7 +8,7 @@ type Props = {
8
8
  /**
9
9
  * The content to display in the alert.
10
10
  */
11
- children: string;
11
+ children: React.ReactNode | React.ReactNode[];
12
12
  /**
13
13
  * [Optional] Additional class names to apply to the alert.
14
14
  */
@@ -9,7 +9,7 @@ type Props = {
9
9
  * The content to display in the badge.
10
10
  * Should be short.
11
11
  */
12
- children: React.ReactNode;
12
+ children: React.ReactNode | React.ReactNode[];
13
13
  /**
14
14
  * [Optional] Additional class names to apply to the badge.
15
15
  */
@@ -8,7 +8,7 @@ type Props = {
8
8
  /**
9
9
  * The content to display in the banner.
10
10
  */
11
- children: React.ReactNode;
11
+ children: React.ReactNode | React.ReactNode[];
12
12
  /**
13
13
  * [Optional] Additional class names to apply to the banner.
14
14
  */
@@ -0,0 +1,26 @@
1
+ import React from "react";
2
+ type Props = {
3
+ /**
4
+ * Whether the layer is open or not
5
+ */
6
+ open: boolean;
7
+ /**
8
+ * Callback that fires when the user clicks outside the layer
9
+ */
10
+ onClose: () => void;
11
+ /**
12
+ * The child of the layer.
13
+ * IMPORTANT: the child must be able to accept a ref
14
+ */
15
+ children: React.ReactElement;
16
+ /**
17
+ * [Optional] Additional class name
18
+ */
19
+ backdropClassName?: string;
20
+ /**
21
+ * [Optional] Additional styles
22
+ */
23
+ backdropStyle?: React.CSSProperties;
24
+ };
25
+ declare const Modal: ({ open, onClose, children, backdropStyle, backdropClassName, }: Props) => JSX.Element | null;
26
+ export default Modal;
@@ -0,0 +1,35 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React, { useEffect } from "react";
3
+ import { useFocusTrap, useScrollLock } from "../../hooks";
4
+ import { classNames } from "../../utils/util";
5
+ var Modal = function (_a) {
6
+ var open = _a.open, onClose = _a.onClose, children = _a.children, _b = _a.backdropStyle, backdropStyle = _b === void 0 ? {} : _b, backdropClassName = _a.backdropClassName;
7
+ var _c = useScrollLock(), lock = _c.lock, unlock = _c.unlock;
8
+ var focusRef = useFocusTrap(open);
9
+ useEffect(function () {
10
+ var handleEscape = function (event) {
11
+ if (event.key === "Escape") {
12
+ onClose();
13
+ }
14
+ };
15
+ document.addEventListener("keydown", handleEscape);
16
+ return function () {
17
+ document.removeEventListener("keydown", handleEscape);
18
+ };
19
+ }, [onClose]);
20
+ useEffect(function () {
21
+ if (open)
22
+ lock();
23
+ else
24
+ unlock();
25
+ }, [open, lock, unlock]);
26
+ return open ? (_jsx("div", { className: classNames("ajui-layer-backdrop", backdropClassName), style: backdropStyle, onClick: onClose, children: React.cloneElement(children, {
27
+ ref: focusRef,
28
+ onClick: function (e) {
29
+ var _a, _b;
30
+ e.stopPropagation();
31
+ (_b = (_a = children.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a, e);
32
+ },
33
+ }) })) : null;
34
+ };
35
+ export default Modal;
@@ -0,0 +1,2 @@
1
+ import Layer from "./Layer";
2
+ export default Layer;
@@ -0,0 +1,2 @@
1
+ import Layer from "./Layer";
2
+ export default Layer;
@@ -3,7 +3,7 @@ type Props = {
3
3
  /**
4
4
  * Whether the modal is open or not
5
5
  */
6
- isOpen: boolean;
6
+ open: boolean;
7
7
  /**
8
8
  * Callback that fires when the user clicks the close button or outside the modal
9
9
  */
@@ -21,5 +21,5 @@ type Props = {
21
21
  */
22
22
  style?: React.CSSProperties;
23
23
  };
24
- declare const Modal: ({ isOpen, onClose, children, className, style, }: Props) => JSX.Element | null;
24
+ declare const Modal: ({ open, onClose, children, className, style, }: Props) => JSX.Element | null;
25
25
  export default Modal;
@@ -1,36 +1,12 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useEffect } from "react";
3
- import { useFocusTrap, useScrollLock } from "../../hooks";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
2
  import { IconButton } from "../Button";
5
3
  import { classNames } from "../../utils/util";
4
+ import Layer from "../Layer";
6
5
  var Modal = function (_a) {
7
- var isOpen = _a.isOpen, onClose = _a.onClose, children = _a.children, className = _a.className, style = _a.style;
8
- var _b = useScrollLock(), lock = _b.lock, unlock = _b.unlock;
9
- var focusRef = useFocusTrap(isOpen);
10
- useEffect(function () {
11
- var handleEscape = function (event) {
12
- if (event.key === "Escape") {
13
- onClose();
14
- }
15
- };
16
- document.addEventListener("keydown", handleEscape);
17
- return function () {
18
- document.removeEventListener("keydown", handleEscape);
19
- };
20
- }, [onClose]);
21
- useEffect(function () {
22
- if (isOpen) {
23
- lock();
24
- }
25
- else {
26
- unlock();
27
- }
28
- }, [isOpen, lock, unlock]);
29
- if (!isOpen)
30
- return null;
31
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: "ajui-modal-backdrop", onClick: onClose }), _jsxs("div", { className: classNames("ajui-modal", className), role: "dialog", "aria-modal": "true", ref: focusRef, style: style, children: [_jsx("div", { style: {
32
- display: "flex",
33
- justifyContent: "flex-end",
34
- }, children: _jsx(IconButton, { name: "close", icon: "\u00D7", onClick: onClose, className: "ajui-modal-close" }) }), children, " "] })] }));
6
+ var open = _a.open, onClose = _a.onClose, children = _a.children, className = _a.className, style = _a.style;
7
+ return (_jsx(Layer, { onClose: onClose, open: open, children: _jsxs("div", { className: classNames("ajui-modal", className), role: "dialog", "aria-modal": "true", style: style, children: [_jsx("div", { style: {
8
+ display: "flex",
9
+ justifyContent: "flex-end",
10
+ }, children: _jsx(IconButton, { name: "close", icon: "\u00D7", onClick: onClose, className: "ajui-modal-close" }) }), children] }) }));
35
11
  };
36
12
  export default Modal;
@@ -11,14 +11,14 @@ type Props = React.DetailedHTMLProps<React.SelectHTMLAttributes<HTMLSelectElemen
11
11
  * @param option the option to get the value of
12
12
  * @returns the value of the option
13
13
  */
14
- getOptionValue: (option: string) => string;
14
+ getOptionValue?: (option: string) => string;
15
15
  /**
16
16
  * Mapper function to get the label of the option
17
17
  *
18
18
  * @param option the option to get the label of
19
19
  * @returns the label of the option
20
20
  */
21
- getOptionLabel: (option: string) => string;
21
+ getOptionLabel?: (option: string) => string;
22
22
  /**
23
23
  * [Optional] The corner style of the select element.
24
24
  * @default "rounded"
@@ -23,8 +23,9 @@ var __rest = (this && this.__rest) || function (s, e) {
23
23
  import { jsx as _jsx } from "react/jsx-runtime";
24
24
  import { forwardRef } from "react";
25
25
  import { classNames } from "../../utils/util";
26
+ var identity = function (x) { return x; };
26
27
  var Select = function (_a, ref) {
27
- var className = _a.className, options = _a.options, getOptionValue = _a.getOptionValue, getOptionLabel = _a.getOptionLabel, _b = _a.corners, corners = _b === void 0 ? "rounded" : _b, props = __rest(_a, ["className", "options", "getOptionValue", "getOptionLabel", "corners"]);
28
+ var className = _a.className, options = _a.options, _b = _a.getOptionValue, getOptionValue = _b === void 0 ? identity : _b, _c = _a.getOptionLabel, getOptionLabel = _c === void 0 ? identity : _c, _d = _a.corners, corners = _d === void 0 ? "rounded" : _d, props = __rest(_a, ["className", "options", "getOptionValue", "getOptionLabel", "corners"]);
28
29
  return (_jsx("select", __assign({}, props, { ref: ref, className: classNames("ajui-select-base corners--".concat(corners), className), children: options.map(function (option, index) { return (_jsx("option", { value: getOptionValue(option), children: getOptionLabel(option) }, index)); }) })));
29
30
  };
30
31
  export default forwardRef(Select);
package/index.d.ts CHANGED
@@ -10,4 +10,5 @@ export { default as Banner } from "./components/Banner";
10
10
  export { default as Select } from "./components/Select";
11
11
  export { default as ClickOutside } from "./components/ClickOutside";
12
12
  export { default as Modal } from "./components/Modal";
13
+ export { default as Layer } from "./components/Layer";
13
14
  export * from "./hooks";
package/index.js CHANGED
@@ -11,5 +11,6 @@ export { default as Banner } from "./components/Banner";
11
11
  export { default as Select } from "./components/Select";
12
12
  export { default as ClickOutside } from "./components/ClickOutside";
13
13
  export { default as Modal } from "./components/Modal";
14
+ export { default as Layer } from "./components/Layer";
14
15
  // Hooks
15
16
  export * from "./hooks";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adamjanicki/ui",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Basic UI components and hooks for React in TypeScript",
5
5
  "main": "./index.js",
6
6
  "types": "./index.d.ts",
package/style.css CHANGED
@@ -3,14 +3,16 @@
3
3
  /* General colors */
4
4
  --ajui-light-gray: #eee;
5
5
  --ajui-moon-gray: #ccc;
6
+ --ajui-dark-gray: #555;
6
7
  --ajui-darkest-gray: #333;
8
+ --ajui-obsidian: #121212;
7
9
  --ajui-focus-ring-color: #b2dbfa;
8
- --ajui-default-color: black;
10
+ --ajui-default-color: #111;
9
11
  --ajui-default-background: white;
10
12
  --ajui-default-border: var(--ajui-moon-gray);
11
13
  /* General values */
12
- --ajui-disabled-opacity: 0.4;
13
- --ajui-default-transition: 0.2s ease-in-out;
14
+ --ajui-disabled-opacity: 0.5;
15
+ --ajui-default-transition: 0.25s ease-in-out;
14
16
  --ajui-default-opacity-dim: 0.75;
15
17
  /* Corners */
16
18
  --ajui-sharp-radius: 0;
@@ -18,18 +20,18 @@
18
20
  --ajui-pill-radius: 9999px;
19
21
  --ajui-circle-radius: 50%;
20
22
  /* Buttons */
21
- --ajui-button-primary-background: var(--ajui-default-color);
22
- --ajui-button-primary-color: var(--ajui-default-background);
23
- --ajui-button-secondary-background: var(--ajui-default-background);
24
- --ajui-button-secondary-color: var(--ajui-default-color);
25
- --ajui-button-secondary-border: var(--ajui-default-border);
23
+ --ajui-button-primary-background: black;
24
+ --ajui-button-primary-color: white;
25
+ --ajui-button-secondary-background: white;
26
+ --ajui-button-secondary-color: #111;
27
+ --ajui-button-secondary-border: var(--ajui-moon-gray);
26
28
  --ajui-button-transparent-background: transparent;
27
29
  --ajui-button-secondary-border-hover: var(--ajui-darkest-gray);
28
30
  /* Input */
29
31
  --ajui-input-selection-color: var(--ajui-focus-ring-color);
30
32
  --ajui-input-border: var(--ajui-default-border);
31
33
  /* Select */
32
- --ajui-select-border: var(--ajui-default-border);
34
+ --ajui-select-border: var(--ajui-moon-gray);
33
35
  /* Content types */
34
36
  --ajui-success-background: #dff2e1;
35
37
  --ajui-success-color: #1b5e20;
@@ -51,13 +53,61 @@
51
53
  --ajui-static-color: #424242;
52
54
  --ajui-static-border: #bdbdbd;
53
55
  /* Modal */
54
- --ajui-modal-backdrop-background: rgba(0, 0, 0, 0.5);
56
+ --ajui-layer-backdrop-background: rgba(0, 0, 0, 0.25);
55
57
  /* Link */
56
58
  --ajui-link-color: #0070ff;
57
59
  }
58
60
 
61
+ [data-theme="dark"] {
62
+ /* General colors */
63
+ --ajui-focus-ring-color: #6699cc;
64
+ --ajui-default-color: white;
65
+ --ajui-default-background: var(--ajui-obsidian);
66
+ --ajui-default-border: var(--ajui-dark-gray);
67
+ /* Buttons */
68
+ --ajui-button-primary-background: white;
69
+ --ajui-button-primary-color: var(--ajui-obsidian);
70
+ --ajui-button-secondary-background: var(--ajui-obsidian);
71
+ --ajui-button-secondary-color: white;
72
+ --ajui-button-secondary-border: var(--ajui-dark-gray);
73
+ --ajui-button-transparent-background: transparent;
74
+ --ajui-button-secondary-border-hover: var(--ajui-moon-gray);
75
+ /* Input */
76
+ --ajui-input-selection-color: var(--ajui-focus-ring-color);
77
+ --ajui-input-border: var(--ajui-dark-gray);
78
+ /* Select */
79
+ --ajui-select-border: var(--ajui-dark-gray);
80
+ /* Content types */
81
+ --ajui-success-background: #2a5733;
82
+ --ajui-success-color: #d9efd8;
83
+ --ajui-success-border: #439e4a;
84
+
85
+ --ajui-warning-background: #736230;
86
+ --ajui-warning-color: #fff6d1;
87
+ --ajui-warning-border: #927a3b;
88
+
89
+ --ajui-error-background: #663232;
90
+ --ajui-error-color: #f9dadc;
91
+ --ajui-error-border: #8d2a2a;
92
+
93
+ --ajui-info-background: #335f72;
94
+ --ajui-info-color: #d4f1f5;
95
+ --ajui-info-border: #1d8ea4;
96
+
97
+ --ajui-static-background: #333333;
98
+ --ajui-static-color: #e5e5e5;
99
+ --ajui-static-border: #595959;
100
+ /* Modal */
101
+ --ajui-layer-backdrop-background: rgba(0, 0, 0, 0.4);
102
+ /* Link */
103
+ --ajui-link-color: #ffa500;
104
+ }
105
+
59
106
  a:not([disabled]):is(:focus-visible),
60
- button:not([disabled]):is(:focus-visible),
107
+ button:not([disabled]):is(:focus-visible) {
108
+ outline: 3px solid var(--ajui-link-color);
109
+ outline-offset: 0;
110
+ }
61
111
  .ajui-input-default:focus-within,
62
112
  .ajui-select-base:focus-within {
63
113
  outline: 3px solid var(--ajui-focus-ring-color);
@@ -108,7 +158,7 @@ button:not([disabled]):is(:focus-visible),
108
158
 
109
159
  /* Alert */
110
160
  .ajui-alert {
111
- padding: 0.75rem;
161
+ padding: 1rem;
112
162
  border-style: solid;
113
163
  border-width: 1px;
114
164
  font-weight: 400;
@@ -116,7 +166,7 @@ button:not([disabled]):is(:focus-visible),
116
166
 
117
167
  /* Badge */
118
168
  .ajui-badge {
119
- padding: 1px 5px;
169
+ padding: 0.125rem 0.375rem;
120
170
  border-style: solid;
121
171
  border-width: 1px;
122
172
  font-weight: 600;
@@ -151,7 +201,7 @@ a {
151
201
  }
152
202
 
153
203
  .ajui-button-default {
154
- padding: 0.5rem 0.75rem;
204
+ padding: 0.5rem 1rem;
155
205
  }
156
206
 
157
207
  .ajui-icon-button {
@@ -170,6 +220,7 @@ a {
170
220
  .ajui-button--primary {
171
221
  background-color: var(--ajui-button-primary-background);
172
222
  color: var(--ajui-button-primary-color);
223
+ fill: var(--ajui-button-primary-color);
173
224
  transition: opacity var(--ajui-default-transition);
174
225
  }
175
226
 
@@ -189,14 +240,14 @@ a {
189
240
  }
190
241
 
191
242
  @media (hover: hover) {
192
- .ajui-button--primary:not([disabled]):hover,
193
- .ajui-icon-button:not([disabled]):hover,
194
- .ajui-link-default:hover {
243
+ .ajui-button--primary:not([disabled]):is(:hover, :focus-visible),
244
+ .ajui-icon-button:not([disabled]):is(:hover, :focus-visible),
245
+ .ajui-link-default:is(:hover, :focus-visible) {
195
246
  opacity: var(--ajui-default-opacity-dim);
196
247
  }
197
248
 
198
- .ajui-button--transparent:not([disabled]):hover,
199
- .ajui-button--secondary:not([disabled]):hover {
249
+ .ajui-button--transparent:not([disabled]):is(:hover, :focus-visible),
250
+ .ajui-button--secondary:not([disabled]):is(:hover, :focus-visible) {
200
251
  box-shadow: inset 0 0 0 1px var(--ajui-button-secondary-border-hover);
201
252
  }
202
253
  }
@@ -206,6 +257,7 @@ a {
206
257
  outline: 0px solid transparent;
207
258
  border: none;
208
259
  background-color: inherit;
260
+ color: inherit;
209
261
  padding: 0.75rem 0.5rem;
210
262
  font-size: 1rem;
211
263
  font-weight: 400;
@@ -234,6 +286,7 @@ a {
234
286
 
235
287
  /* Select */
236
288
  .ajui-select-base {
289
+ color: inherit;
237
290
  outline: 0px solid transparent;
238
291
  border: none;
239
292
  background-color: inherit;
@@ -251,27 +304,25 @@ a {
251
304
  }
252
305
 
253
306
  /* Modal */
254
- .ajui-modal-backdrop {
307
+ .ajui-layer-backdrop {
255
308
  position: fixed;
256
309
  top: 0;
257
310
  left: 0;
258
311
  width: 100vw;
259
312
  height: 100vh;
260
- background: var(--ajui-modal-backdrop-background);
261
313
  z-index: 10000;
314
+ background: var(--ajui-layer-backdrop-background);
315
+ display: flex;
316
+ justify-content: center;
317
+ align-items: center;
262
318
  }
263
319
 
264
320
  .ajui-modal {
265
- position: fixed;
266
- top: 50%;
267
- left: 50%;
268
- transform: translate(-50%, -50%);
269
321
  background: var(--ajui-default-background);
270
- z-index: 10001;
271
322
  box-shadow: inset 0 0 0 1px var(--ajui-default-border);
272
323
  border-radius: var(--ajui-rounded-radius);
273
- min-width: 50vw;
274
- max-width: 90vw;
324
+ min-width: 50%;
325
+ max-width: 90%;
275
326
  }
276
327
 
277
328
  .ajui-modal-close {