@uxf/ui 11.20.0 → 11.21.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 (111) hide show
  1. package/_file-input-base/file-input-base.js +1 -1
  2. package/_input-with-popover/input-with-popover.d.ts +1 -4
  3. package/_input-with-popover/input-with-popover.js +13 -10
  4. package/alert-bubble/alert-bubble.d.ts +2 -2
  5. package/alert-bubble/alert-bubble.js +1 -1
  6. package/avatar-file-input/avatar-file-input.d.ts +1 -1
  7. package/avatar-file-input/avatar-file-input.js +2 -2
  8. package/calendar/calendar-day-cell.js +2 -2
  9. package/checkbox/checkbox.d.ts +1 -1
  10. package/checkbox-input/checkbox-input.d.ts +1 -1
  11. package/checkbox-input/checkbox-input.js +1 -1
  12. package/combobox/README.md +5 -4
  13. package/combobox/combobox.d.ts +40 -14
  14. package/combobox/combobox.js +64 -13
  15. package/combobox/combobox.stories.d.ts +2 -5
  16. package/combobox/index.d.ts +1 -1
  17. package/css/alert-bubble.css +8 -16
  18. package/css/avatar-file-input.css +13 -24
  19. package/css/avatar.css +1 -5
  20. package/css/badge.css +1 -5
  21. package/css/button-list.css +4 -18
  22. package/css/button.css +21 -89
  23. package/css/calendar.css +23 -41
  24. package/css/checkbox-button.css +54 -55
  25. package/css/checkbox-input.css +2 -4
  26. package/css/checkbox.css +47 -59
  27. package/css/chip.css +80 -140
  28. package/css/color-radio-group.css +2 -5
  29. package/css/color-radio.css +1 -5
  30. package/css/combobox.css +7 -0
  31. package/css/date-picker.css +2 -4
  32. package/css/dialog.css +2 -5
  33. package/css/dropdown.css +54 -40
  34. package/css/dropzone.css +4 -9
  35. package/css/file-input.css +5 -21
  36. package/css/input-with-popover.css +1 -5
  37. package/css/input.css +40 -55
  38. package/css/label.css +1 -5
  39. package/css/list-item.css +10 -13
  40. package/css/loader.css +4 -4
  41. package/css/message.css +2 -8
  42. package/css/multi-combobox.css +81 -56
  43. package/css/multi-select.css +98 -13
  44. package/css/pagination.css +5 -20
  45. package/css/radio-group.css +51 -92
  46. package/css/radio.css +49 -58
  47. package/css/select.css +11 -0
  48. package/css/tabs.css +12 -36
  49. package/css/text-link.css +3 -6
  50. package/css/textarea.css +16 -22
  51. package/css/toggle.css +20 -40
  52. package/dropdown/dropdown.js +1 -1
  53. package/dropzone/dropzone-input.js +2 -2
  54. package/file-input/file-input.js +2 -2
  55. package/flash-messages/flash-messages.js +2 -2
  56. package/icon/icon.d.ts +1 -0
  57. package/icon/icon.js +3 -3
  58. package/icon/index.d.ts +1 -0
  59. package/image-gallery/components/close-button.js +1 -1
  60. package/image-gallery/components/next-button.js +1 -1
  61. package/image-gallery/components/prev-button.js +1 -1
  62. package/input/README.md +1 -1
  63. package/input/index.d.ts +2 -0
  64. package/input/index.js +2 -0
  65. package/input/input-arrow-icon.d.ts +8 -0
  66. package/input/input-arrow-icon.js +16 -0
  67. package/input/input.d.ts +2 -1
  68. package/input/input.js +7 -7
  69. package/input/input.stories.d.ts +1 -0
  70. package/message/message.d.ts +1 -1
  71. package/multi-combobox/README.md +5 -2
  72. package/multi-combobox/multi-combobox.d.ts +2 -2
  73. package/multi-combobox/multi-combobox.js +118 -32
  74. package/multi-combobox/multi-combobox.stories.js +4 -6
  75. package/multi-combobox/types.d.ts +3 -1
  76. package/multi-select/README.md +5 -3
  77. package/multi-select/multi-select.d.ts +2 -2
  78. package/multi-select/multi-select.js +79 -23
  79. package/multi-select/multi-select.stories.js +1 -2
  80. package/multi-select/types.d.ts +3 -1
  81. package/package.json +4 -4
  82. package/radio/radio.d.ts +1 -1
  83. package/radio-group/radio-group.d.ts +2 -2
  84. package/radio-group/radio-group.js +1 -1
  85. package/raster-image/empty-image.d.ts +9 -0
  86. package/raster-image/empty-image.js +13 -0
  87. package/raster-image/img-sources.d.ts +1 -1
  88. package/raster-image/img-sources.js +6 -6
  89. package/raster-image/raster-image.d.ts +16 -12
  90. package/raster-image/raster-image.js +19 -21
  91. package/raster-image/raster-image.stories.d.ts +2 -1
  92. package/raster-image/responsive-img-sources.d.ts +15 -0
  93. package/raster-image/responsive-img-sources.js +20 -0
  94. package/select/README.md +5 -3
  95. package/select/select.d.ts +38 -13
  96. package/select/select.js +91 -13
  97. package/select/select.stories.js +3 -1
  98. package/text-input/text-input.js +2 -2
  99. package/textarea/textarea.js +2 -2
  100. package/toggle/toggle.d.ts +1 -1
  101. package/tooltip/tooltip.js +2 -2
  102. package/utils/files/get-file-icon.d.ts +1 -1
  103. package/_select-base/_select-base.d.ts +0 -58
  104. package/_select-base/_select-base.js +0 -107
  105. package/_select-base/index.d.ts +0 -2
  106. package/_select-base/index.js +0 -5
  107. package/css/select-base.css +0 -50
  108. package/multi-combobox/_multi-combobox-base.d.ts +0 -8
  109. package/multi-combobox/_multi-combobox-base.js +0 -141
  110. package/multi-select/_multi-select-base.d.ts +0 -8
  111. package/multi-select/_multi-select-base.js +0 -78
@@ -24,8 +24,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports._FileInputBase = void 0;
27
+ const validator_exceptions_1 = require("@uxf/ui//utils/validator/validator-exceptions");
27
28
  const react_1 = __importStar(require("react"));
28
- const validator_exceptions_1 = require("../utils/validator/validator-exceptions");
29
29
  exports._FileInputBase = (0, react_1.forwardRef)((props, ref) => {
30
30
  const onChange = async (e) => {
31
31
  var _a, _b;
@@ -1,6 +1,6 @@
1
1
  import { Placement, Strategy } from "@floating-ui/react";
2
+ import { InputProps } from "@uxf/ui/input";
2
3
  import React, { MutableRefObject, ReactElement, ReactNode } from "react";
3
- import { InputProps } from "../input";
4
4
  import { Clearable, FormControlProps } from "../types";
5
5
  export interface InputWithPopoverProps<ValueType = string> extends FormControlProps<ValueType>, Pick<InputProps, "size" | "variant">, Clearable {
6
6
  autoFocus?: boolean;
@@ -8,9 +8,6 @@ export interface InputWithPopoverProps<ValueType = string> extends FormControlPr
8
8
  children: (args: {
9
9
  close: (focusableElement?: HTMLElement | MutableRefObject<HTMLElement | null>) => void;
10
10
  }) => ReactElement;
11
- defaultValue?: string;
12
- error?: ReactNode;
13
- errorId?: string;
14
11
  form?: string;
15
12
  helperText?: ReactNode;
16
13
  hiddenLabel?: boolean;
@@ -26,13 +26,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports._InputWithPopover = void 0;
27
27
  const react_1 = require("@floating-ui/react");
28
28
  const react_2 = require("@headlessui/react");
29
+ const show_1 = require("@uxf/core-react/components/show");
29
30
  const use_input_focus_1 = require("@uxf/core-react/hooks/use-input-focus");
31
+ const compose_refs_1 = require("@uxf/core-react/utils/compose-refs");
30
32
  const classes_1 = require("@uxf/core/constants/classes");
31
- const composeRefs_1 = require("@uxf/core/utils/composeRefs");
32
33
  const cx_1 = require("@uxf/core/utils/cx");
34
+ const form_component_1 = require("@uxf/ui/form-component");
35
+ const input_1 = require("@uxf/ui/input");
33
36
  const react_3 = __importStar(require("react"));
34
- const form_component_1 = require("../form-component");
35
- const input_1 = require("../input");
36
37
  function useErrorProps(error, id, isInvalid) {
37
38
  const errorId = isInvalid ? `${id}--error-message` : undefined;
38
39
  return {
@@ -48,7 +49,7 @@ exports._InputWithPopover = (0, react_3.forwardRef)((props, ref) => {
48
49
  const id = (_a = props.id) !== null && _a !== void 0 ? _a : generatedId;
49
50
  const innerRef = (0, react_3.useRef)(null);
50
51
  const input = (0, use_input_focus_1.useInputFocus)(innerRef, props.onBlur, props.onFocus);
51
- const error = useErrorProps(props.error, id, props.isInvalid);
52
+ const error = useErrorProps(props.helperText, id, props.isInvalid);
52
53
  const rootClassName = (0, cx_1.cx)("uxf-input-with-popover", ((_b = props.isFocused) !== null && _b !== void 0 ? _b : input.focused) && classes_1.CLASSES.IS_FOCUSED, props.isDisabled && classes_1.CLASSES.IS_DISABLED, props.isInvalid && classes_1.CLASSES.IS_INVALID, props.isReadOnly && classes_1.CLASSES.IS_READONLY, props.isRequired && classes_1.CLASSES.IS_REQUIRED, props.className);
53
54
  const floatingPopover = (0, react_1.useFloating)({
54
55
  placement: (_c = props.popoverPlacement) !== null && _c !== void 0 ? _c : "bottom",
@@ -73,17 +74,19 @@ exports._InputWithPopover = (0, react_3.forwardRef)((props, ref) => {
73
74
  const showRemoveButton = !!(props.value && isInteractive && props.isClearable);
74
75
  return (react_3.default.createElement(form_component_1.FormComponent, { className: rootClassName, errorId: error.errorId, form: props.form, helperText: props.helperText, hiddenLabel: props.hiddenLabel, inputId: id, isRequired: props.isRequired, label: props.label, name: props.name },
75
76
  react_3.default.createElement(react_2.Popover, { as: react_3.Fragment }, (renderProps) => (react_3.default.createElement(react_3.default.Fragment, null,
76
- react_3.default.createElement(input_1.Input, { inputFocus: input, size: props.size, variant: props.variant, wrapperRef: floatingPopover.refs.setReference },
77
+ react_3.default.createElement(input_1.Input, { inputFocus: input, inputGroupRef: floatingPopover.refs.setReference, ref: (0, compose_refs_1.composeRefs)(innerRef, ref), size: props.size, variant: props.variant },
77
78
  props.leftAddon && react_3.default.createElement(input_1.Input.LeftAddon, null, props.leftAddon),
78
79
  props.leftElement && react_3.default.createElement(input_1.Input.LeftElement, null, props.leftElement),
79
- react_3.default.createElement(input_1.Input.Element, { "aria-describedby": error.ariaDescribedby, "aria-errormessage": error.ariaErrormessage, "aria-invalid": error.ariaInvalid, "aria-live": "polite", autoComplete: "off", autoFocus: props.autoFocus, form: props.form, id: id, isDisabled: props.isDisabled, isInvalid: props.isInvalid, isReadOnly: props.isReadOnly, isRequired: props.isRequired, name: props.name, onChange: props.onChange, placeholder: props.placeholder, ref: (0, composeRefs_1.composeRefs)(innerRef, ref), type: "text", value: props.value }),
80
+ react_3.default.createElement(input_1.Input.Element, { "aria-describedby": error.ariaDescribedby, "aria-errormessage": error.ariaErrormessage, "aria-invalid": error.ariaInvalid, "aria-live": "polite", autoComplete: "off", autoFocus: props.autoFocus, form: props.form, id: id, isDisabled: props.isDisabled, isInvalid: props.isInvalid, isReadOnly: props.isReadOnly, isRequired: props.isRequired, name: props.name, onChange: props.onChange, placeholder: props.placeholder, type: "text", value: props.value }),
80
81
  react_3.default.createElement(input_1.Input.RightElement, null,
81
- showRemoveButton && react_3.default.createElement(input_1.Input.RemoveButton, { onChange: () => props.onChange("") }),
82
+ react_3.default.createElement(show_1.Show, { when: showRemoveButton },
83
+ react_3.default.createElement(input_1.Input.RemoveButton, { onChange: () => props.onChange("") })),
82
84
  react_3.default.createElement(react_2.Popover.Button, { className: "uxf-input-with-popover__trigger-element" }, props.triggerElement),
83
85
  props.rightElement),
84
86
  props.rightAddon && react_3.default.createElement(input_1.Input.RightAddon, null, props.rightAddon)),
85
- isInteractive && renderProps.open && (react_3.default.createElement(react_1.FloatingPortal, null,
86
- react_3.default.createElement(react_2.Popover.Panel, { className: (0, cx_1.cx)("uxf-input-with-popover__panel", floatingPopover.placement === "bottom" &&
87
- "uxf-input-with-popover__panel--bottom", floatingPopover.placement === "top" && "uxf-input-with-popover__panel--top"), ref: floatingPopover.refs.setFloating, static: true, style: floatingPopover.floatingStyles }, props.children))))))));
87
+ react_3.default.createElement(show_1.Show, { when: isInteractive && renderProps.open },
88
+ react_3.default.createElement(react_1.FloatingPortal, null,
89
+ react_3.default.createElement(react_2.Popover.Panel, { className: (0, cx_1.cx)("uxf-input-with-popover__panel", floatingPopover.placement === "bottom" &&
90
+ "uxf-input-with-popover__panel--bottom", floatingPopover.placement === "top" && "uxf-input-with-popover__panel--top"), ref: floatingPopover.refs.setFloating, static: true, style: floatingPopover.floatingStyles }, props.children))))))));
88
91
  });
89
92
  exports._InputWithPopover.displayName = "UxfUiInputWithPopover";
@@ -1,6 +1,6 @@
1
+ import { AlertBubbleColor, AlertBubbleSize } from "@uxf/ui/alert-bubble/theme";
2
+ import { IconName } from "@uxf/ui/icon/types";
1
3
  import { FC } from "react";
2
- import { IconName } from "../icon/types";
3
- import { AlertBubbleColor, AlertBubbleSize } from "./theme";
4
4
  export interface AlertBubbleProps {
5
5
  className?: string;
6
6
  color?: AlertBubbleColor;
@@ -5,8 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.AlertBubble = void 0;
7
7
  const cx_1 = require("@uxf/core/utils/cx");
8
+ const icon_1 = require("@uxf/ui/icon");
8
9
  const react_1 = __importDefault(require("react"));
9
- const icon_1 = require("../icon");
10
10
  const ICON = {
11
11
  default: "triangle-exclamation",
12
12
  error: "xmark",
@@ -1,7 +1,7 @@
1
+ import { AvatarFileInputVariant } from "@uxf/ui/avatar-file-input/theme";
1
2
  import React, { MouseEventHandler, ReactNode } from "react";
2
3
  import { FileInputBaseProps } from "../_file-input-base";
3
4
  import { IconName } from "../icon/types";
4
- import { AvatarFileInputVariant } from "./theme";
5
5
  export interface AvatarFileInputProps extends FileInputBaseProps {
6
6
  customControls?: (args: {
7
7
  onSelectFile: MouseEventHandler;
@@ -25,8 +25,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.AvatarFileInput = void 0;
27
27
  const use_input_focus_1 = require("@uxf/core-react/hooks/use-input-focus");
28
+ const compose_refs_1 = require("@uxf/core-react/utils/compose-refs");
28
29
  const classes_1 = require("@uxf/core/constants/classes");
29
- const composeRefs_1 = require("@uxf/core/utils/composeRefs");
30
30
  const cx_1 = require("@uxf/core/utils/cx");
31
31
  const file_1 = require("@uxf/core/utils/file");
32
32
  const react_1 = __importStar(require("react"));
@@ -56,7 +56,7 @@ exports.AvatarFileInput = (0, react_1.forwardRef)((props, ref) => {
56
56
  return (react_1.default.createElement(form_component_1.FormComponent, { className: rootClassName, errorId: props.id, helperText: props.helperText, hiddenLabel: props.hiddenLabel, inputId: id, label: props.label, name: props.name },
57
57
  react_1.default.createElement("div", { className: "uxf-avatar-file-input__inner-wrapper" },
58
58
  react_1.default.createElement("div", { className: (0, cx_1.cx)("uxf-avatar-file-input__input", stateClassName), onClick: onSelectFile },
59
- react_1.default.createElement(_file_input_base_1._FileInputBase, { accept: (_c = props.accept) !== null && _c !== void 0 ? _c : "image/*", "aria-describedby": errorId, "aria-invalid": props.isInvalid, className: "uxf-avatar-file-input__input-element", form: props.form, id: id, isDisabled: props.isDisabled, isFocused: props.isFocused, isInvalid: props.isInvalid, isReadOnly: props.isReadOnly, isRequired: props.isRequired, maxFileSize: props.maxFileSize, name: props.name, onBlur: input.onBlur, onFocus: input.onFocus, onChange: props.onChange, onUploadError: props.onUploadError, onUploadFile: props.onUploadFile, ref: (0, composeRefs_1.composeRefs)(innerRef, ref), value: props.value }),
59
+ react_1.default.createElement(_file_input_base_1._FileInputBase, { accept: (_c = props.accept) !== null && _c !== void 0 ? _c : "image/*", "aria-describedby": errorId, "aria-invalid": props.isInvalid, className: "uxf-avatar-file-input__input-element", form: props.form, id: id, isDisabled: props.isDisabled, isFocused: props.isFocused, isInvalid: props.isInvalid, isReadOnly: props.isReadOnly, isRequired: props.isRequired, maxFileSize: props.maxFileSize, name: props.name, onBlur: input.onBlur, onFocus: input.onFocus, onChange: props.onChange, onUploadError: props.onUploadError, onUploadFile: props.onUploadFile, ref: (0, compose_refs_1.composeRefs)(innerRef, ref), value: props.value }),
60
60
  props.value ? (react_1.default.createElement(avatar_1.Avatar, { className: "uxf-avatar-file-input__input-avatar", src: (0, file_1.getFileUrl)(props.value) })) : (react_1.default.createElement("div", { className: "uxf-avatar-file-input__input-empty" },
61
61
  react_1.default.createElement(icon_1.Icon, { className: "uxf-avatar-file-input__input-empty-icon", name: (_d = props.icon) !== null && _d !== void 0 ? _d : "cloud" })))),
62
62
  react_1.default.createElement("div", { className: "uxf-avatar-file-input__controls" }, props.customControls ? (props.customControls({
@@ -25,8 +25,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.CalendarDayCell = void 0;
27
27
  const use_on_mount_1 = require("@uxf/core-react/hooks/use-on-mount");
28
+ const compose_refs_1 = require("@uxf/core-react/utils/compose-refs");
28
29
  const classes_1 = require("@uxf/core/constants/classes");
29
- const composeRefs_1 = require("@uxf/core/utils/composeRefs");
30
30
  const cx_1 = require("@uxf/core/utils/cx");
31
31
  const use_day_1 = require("@uxf/datepicker/hooks/use-day");
32
32
  const react_1 = __importStar(require("react"));
@@ -59,7 +59,7 @@ exports.CalendarDayCell = (0, react_1.memo)((props) => {
59
59
  if (!props.day.dayLabel) {
60
60
  return react_1.default.createElement("div", null);
61
61
  }
62
- return (react_1.default.createElement("button", { className: (0, cx_1.cx)("uxf-calendar__cell uxf-calendar__cell-day", isFirstDisabled && props.day.currentMonth && "is-disabled-start", isLastDisabled && props.day.currentMonth && "is-disabled-end", disabledDate && classes_1.CLASSES.IS_DISABLED, isToday && "uxf-calendar__cell--today", isSelected && "uxf-calendar__cell--selected", isInsideRange && "uxf-calendar__cell--inside-range", isWithinHoverRange && "uxf-calendar__cell--is-within-hover-range", isHovered && "uxf-calendar__cell--is-hovered", !props.day.currentMonth && "uxf-calendar__cell--not-current-month", (0, get_class_names_from_flags_1.getClassNamesFromFlags)(flags)), ref: disabledDate ? undefined : (0, composeRefs_1.composeRefs)(dayCellRef, innerRef), onClick: onClick, onKeyDown: onKeyDown, onMouseEnter: onMouseEnter, tabIndex: tabIndex, type: "button" },
62
+ return (react_1.default.createElement("button", { className: (0, cx_1.cx)("uxf-calendar__cell uxf-calendar__cell-day", isFirstDisabled && props.day.currentMonth && "is-disabled-start", isLastDisabled && props.day.currentMonth && "is-disabled-end", disabledDate && classes_1.CLASSES.IS_DISABLED, isToday && "uxf-calendar__cell--today", isSelected && "uxf-calendar__cell--selected", isInsideRange && "uxf-calendar__cell--inside-range", isWithinHoverRange && "uxf-calendar__cell--is-within-hover-range", isHovered && "uxf-calendar__cell--is-hovered", !props.day.currentMonth && "uxf-calendar__cell--not-current-month", (0, get_class_names_from_flags_1.getClassNamesFromFlags)(flags)), ref: disabledDate ? undefined : (0, compose_refs_1.composeRefs)(dayCellRef, innerRef), onClick: onClick, onKeyDown: onKeyDown, onMouseEnter: onMouseEnter, tabIndex: tabIndex, type: "button" },
63
63
  react_1.default.createElement("span", { className: "uxf-calendar__cell__inner" }, props.day.dayLabel)));
64
64
  });
65
65
  exports.CalendarDayCell.displayName = "UxfUiCalendarDayCell";
@@ -1,6 +1,6 @@
1
+ import { CheckboxSize } from "@uxf/ui/checkbox/theme";
1
2
  import React, { CSSProperties, ReactNode } from "react";
2
3
  import { FormControlProps } from "../types";
3
- import { CheckboxSize } from "./theme";
4
4
  export interface CheckboxProps extends FormControlProps<boolean | undefined> {
5
5
  className?: string;
6
6
  id?: string;
@@ -1,5 +1,5 @@
1
+ import { CheckboxSize } from "@uxf/ui/checkbox/theme";
1
2
  import React, { CSSProperties, ReactNode } from "react";
2
- import { CheckboxSize } from "../checkbox";
3
3
  import { FormControlProps } from "../types";
4
4
  export interface CheckboxInputProps extends FormControlProps<boolean | undefined> {
5
5
  className?: string;
@@ -25,8 +25,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.CheckboxInput = void 0;
27
27
  const react_1 = require("@headlessui/react");
28
+ const checkbox_1 = require("@uxf/ui/checkbox");
28
29
  const react_2 = __importStar(require("react"));
29
- const checkbox_1 = require("../checkbox");
30
30
  exports.CheckboxInput = (0, react_2.forwardRef)((props, ref) => {
31
31
  var _a, _b;
32
32
  const generatedId = (0, react_2.useId)();
@@ -3,10 +3,11 @@
3
3
  ## CSS dependencies
4
4
 
5
5
  ```css
6
+ @import url("@uxf/ui/icon/icon.css");
7
+ @import url("@uxf/ui/dropdown/dropdown.css");
6
8
  @import url("@uxf/ui/label/label.css");
7
9
  @import url("@uxf/ui/form-component/form-component.css");
8
- @import url("@uxf/ui/dropdown/dropdown.css");
9
- @import url("@uxf/ui/input/input.css");
10
- @import url("@uxf/ui/_select-base/select-base.css");
11
10
  @import url("@uxf/ui/input/input-basic.css");
12
- ```
11
+ @import url("@uxf/ui/input/input.css");
12
+ @import url("@uxf/ui/combobox/combobox.css");
13
+ ```
@@ -1,23 +1,49 @@
1
- import React, { ReactNode, Ref } from "react";
2
- import { SelectBaseProps, SelectBaseValueId } from "../_select-base";
3
- export type ComboboxValueId = SelectBaseValueId;
4
- export type ComboboxValue<ValueId = ComboboxValueId> = {
5
- id: ValueId;
1
+ import { Placement, Strategy } from "@floating-ui/react";
2
+ import { IconsSet } from "@uxf/ui/icon";
3
+ import { InputGroupSize, InputGroupVariant } from "@uxf/ui/input";
4
+ import { Clearable, FormControlProps } from "@uxf/ui/types";
5
+ import React, { CSSProperties, ReactNode, Ref } from "react";
6
+ export type ComboboxValueId = number | string;
7
+ export type ComboboxValue<Id = ComboboxValueId> = {
8
+ id: Id;
6
9
  label: string;
7
10
  };
8
- export interface ComboboxOption<ValueId = ComboboxValueId> extends ComboboxValue<ValueId> {
11
+ export interface ComboboxOption<Id = ComboboxValueId> extends ComboboxValue<Id> {
9
12
  disabled?: boolean;
10
13
  }
11
- type ComboboxTypeRef = HTMLDivElement;
12
- export interface ComboboxProps<ValueId = SelectBaseValueId, Option = ComboboxOption<ValueId>, Value = Option> extends Omit<SelectBaseProps<Value, Option>, "children" | "customInputElementDisplayName" | "emptyMessage"> {
13
- forwardRef?: Ref<ComboboxTypeRef> | undefined;
14
+ export type ComboboxTypeRef = HTMLInputElement;
15
+ export interface ComboboxProps<Id = ComboboxValueId, Option = ComboboxOption<Id>, Value = Option> extends FormControlProps<Value | null>, Clearable {
16
+ className?: string;
17
+ dropdownClassName?: string;
18
+ dropdownMatchesInputWidth?: boolean;
19
+ dropdownMaxHeight?: number;
20
+ dropdownPlacement?: Placement;
21
+ dropdownStrategy?: Strategy;
22
+ helperText?: ReactNode;
23
+ hiddenLabel?: boolean;
24
+ iconName?: keyof IconsSet;
25
+ id?: string;
26
+ inputArrow?: (open: boolean) => ReactNode;
27
+ keyExtractor?: (option: Option) => string | number;
28
+ label: ReactNode;
14
29
  loadOptions?: (query: string) => Promise<Option[]>;
15
30
  noQueryMessage?: string;
16
31
  notFoundMessage?: string;
32
+ options?: Option[];
33
+ placeholder?: string;
17
34
  renderOption?: (option: Option, isSelected: boolean) => ReactNode;
35
+ size?: InputGroupSize;
36
+ style?: CSSProperties;
37
+ variant?: InputGroupVariant;
38
+ leftAddon?: ReactNode;
39
+ leftElement?: ReactNode;
40
+ rightAddon?: ReactNode;
41
+ rightElement?: ReactNode;
42
+ inputGroupRef?: Ref<ComboboxTypeRef> | undefined;
43
+ inputRef?: Ref<HTMLInputElement> | undefined;
44
+ inputWrapperRef?: Ref<ComboboxTypeRef> | undefined;
45
+ }
46
+ export declare function Combobox<Id = ComboboxValueId, Option = ComboboxOption<Id>, Value = Option>(props: ComboboxProps<Id, Option, Value>): React.JSX.Element;
47
+ export declare namespace Combobox {
48
+ var displayName: string;
18
49
  }
19
- export declare const Combobox: {
20
- <ValueId = SelectBaseValueId, Option = ComboboxOption<ValueId>, Value = Option>(props: ComboboxProps<ValueId, Option, Value>): React.JSX.Element;
21
- displayName: string;
22
- };
23
- export {};
@@ -24,18 +24,43 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.Combobox = void 0;
27
- const react_1 = require("@headlessui/react");
27
+ const react_1 = require("@floating-ui/react");
28
+ const react_2 = require("@headlessui/react");
29
+ const show_1 = require("@uxf/core-react/components/show");
30
+ const use_input_focus_1 = require("@uxf/core-react/hooks/use-input-focus");
31
+ const use_on_unmount_1 = require("@uxf/core-react/hooks/use-on-unmount");
32
+ const compose_refs_1 = require("@uxf/core-react/utils/compose-refs");
33
+ const classes_1 = require("@uxf/core/constants/classes");
34
+ const cx_1 = require("@uxf/core/utils/cx");
35
+ const is_empty_1 = require("@uxf/core/utils/is-empty");
36
+ const is_not_nil_1 = require("@uxf/core/utils/is-not-nil");
28
37
  const slugify_1 = require("@uxf/core/utils/slugify");
29
38
  const use_async_loading_1 = require("@uxf/ui/hooks/use-async-loading");
30
- const react_2 = __importStar(require("react"));
31
- const _select_base_1 = require("../_select-base");
32
- const Combobox = (props) => {
33
- var _a, _b, _c, _d;
34
- const isAsync = !!props.loadOptions;
35
- const [query, setQuery] = (0, react_2.useState)("");
39
+ const use_dropdown_1 = require("@uxf/ui/hooks/use-dropdown");
40
+ const input_1 = require("@uxf/ui/input");
41
+ const label_1 = require("@uxf/ui/label");
42
+ const react_3 = __importStar(require("react"));
43
+ function Option(props) {
44
+ return (react_3.default.createElement(react_2.Combobox.Option, { className: (option) => (0, cx_1.cx)("uxf-dropdown__item uxf-combobox__dropdown-item", option.active && classes_1.CLASSES.IS_ACTIVE, option.disabled && classes_1.CLASSES.IS_DISABLED, option.selected && classes_1.CLASSES.IS_SELECTED), value: props.option }, (option) => { var _a, _b; return (_b = (_a = props.renderOption) === null || _a === void 0 ? void 0 : _a.call(props, props.option, option.selected)) !== null && _b !== void 0 ? _b : props.option.label; }));
45
+ }
46
+ Option.displayName = "UxfUiComboboxOption";
47
+ function Options(props) {
48
+ var _a, _b;
49
+ (0, use_on_unmount_1.useOnUnmount)(() => { var _a; return (_a = props.onUnmount) === null || _a === void 0 ? void 0 : _a.call(props); });
50
+ return (react_3.default.createElement(react_2.Combobox.Options, { className: (0, cx_1.cx)("uxf-dropdown uxf-combobox__dropdown", `uxf-dropdown--size-${(_a = props.size) !== null && _a !== void 0 ? _a : "default"}`, `uxf-dropdown--variant-${(_b = props.variant) !== null && _b !== void 0 ? _b : "default"}`, props.matchWidth ? "uxf-dropdown--match-width" : "uxf-dropdown--not-match-width", props.placement === "bottom" && "uxf-dropdown--bottom", props.placement === "top" && "uxf-dropdown--top", props.className), ref: props.forwardRef, static: true, style: props.style }, (0, is_empty_1.isEmpty)(props.options) ? (react_3.default.createElement("div", { className: "uxf-dropdown__empty-wrapper" }, props.emptyMessage)) : (props.options.map((option) => {
51
+ var _a, _b;
52
+ const optionKey = (_b = (_a = props.keyExtractor) === null || _a === void 0 ? void 0 : _a.call(props, option)) !== null && _b !== void 0 ? _b : option.id;
53
+ return react_3.default.createElement(Option, { key: optionKey, option: option, renderOption: props.renderOption });
54
+ }))));
55
+ }
56
+ Options.displayName = "UxfUiComboboxOptions";
57
+ function Combobox(props) {
58
+ var _a, _b, _c, _d, _e, _f, _g;
59
+ const isAsync = (0, is_not_nil_1.isNotNil)(props.loadOptions);
60
+ const [query, setQuery] = (0, react_3.useState)("");
36
61
  const options = (0, use_async_loading_1.useAsyncLoading)(query, (_a = props.options) !== null && _a !== void 0 ? _a : [], props.loadOptions);
37
- const filteredData = query === "" || isAsync ? options : options.filter((item) => (0, slugify_1.slugify)(item.label).includes((0, slugify_1.slugify)(query)));
38
- const emptyMessage = query.length === 0
62
+ const filteredData = (0, is_empty_1.isEmpty)(query) || isAsync ? options : options.filter((item) => (0, slugify_1.slugify)(item.label).includes((0, slugify_1.slugify)(query)));
63
+ const emptyMessage = (0, is_empty_1.isEmpty)(query)
39
64
  ? (_b = props.noQueryMessage) !== null && _b !== void 0 ? _b : "Pro zobrazení možností začněte psát"
40
65
  : (_c = props.notFoundMessage) !== null && _c !== void 0 ? _c : "Nic nenalezeno";
41
66
  const clearQuery = () => setQuery("");
@@ -43,8 +68,34 @@ const Combobox = (props) => {
43
68
  const onInputChange = (event) => setQuery(event.target.value);
44
69
  const displayValue = (item) => { var _a; return (_a = item === null || item === void 0 ? void 0 : item.label) !== null && _a !== void 0 ? _a : ""; };
45
70
  const selectedOption = (_d = props.value) !== null && _d !== void 0 ? _d : null;
46
- return (react_2.default.createElement(_select_base_1._SelectBase, { HUIComponent: react_1.Combobox, className: props.className, customInputElementDisplayName: react_1.Combobox.Input.displayName, dropdownClassName: props.dropdownClassName, dropdownMatchesInputWidth: props.dropdownMatchesInputWidth, dropdownPlacement: props.dropdownPlacement, dropdownStrategy: props.dropdownStrategy, emptyMessage: emptyMessage, forwardRef: props.forwardRef, helperText: props.helperText, hiddenLabel: props.hiddenLabel, iconName: props.iconName, id: props.id, isClearable: props.isClearable, isDisabled: props.isDisabled, isFocused: props.isFocused, isInvalid: props.isInvalid, isReadOnly: props.isReadOnly, isRequired: props.isRequired, keyExtractor: props.keyExtractor, label: props.label, leftAddon: props.leftAddon, leftElement: props.leftElement, name: props.name, onBlur: props.onBlur, onChange: onChange, onFocus: props.onFocus, onOptionsUnmount: clearQuery, options: filteredData, placeholder: props.placeholder, renderOption: props.renderOption, rightAddon: props.rightAddon, rightElement: props.rightElement, size: props.size, style: props.style, value: selectedOption, variant: props.variant },
47
- react_2.default.createElement(react_1.Combobox.Input, { autoComplete: "off", className: "uxf-input__element", displayValue: displayValue, onBlur: props.onBlur, onChange: onInputChange, placeholder: props.placeholder, type: "text" })));
48
- };
71
+ const generatedId = (0, react_3.useId)();
72
+ const id = (_e = props.id) !== null && _e !== void 0 ? _e : generatedId;
73
+ const innerRef = (0, react_3.useRef)(null);
74
+ const errorId = props.isInvalid ? `${id}--error-message` : undefined;
75
+ const input = (0, use_input_focus_1.useInputFocus)(innerRef, props.onBlur, props.onFocus);
76
+ const dropdown = (0, use_dropdown_1.useDropdown)((_f = props.dropdownPlacement) !== null && _f !== void 0 ? _f : "bottom", (_g = props.dropdownMatchesInputWidth) !== null && _g !== void 0 ? _g : true, props.dropdownMaxHeight, props.dropdownStrategy);
77
+ const stableRef = (0, react_3.useMemo)(() => (0, compose_refs_1.composeRefs)(innerRef, props.inputGroupRef, dropdown.refs.setReference), [dropdown.refs.setReference, props.inputGroupRef]);
78
+ return (react_3.default.createElement(react_2.Combobox, { as: "div", by: "id", className: (0, cx_1.cx)("uxf-form-component uxf-combobox", props.isInvalid && classes_1.CLASSES.IS_INVALID, props.isRequired && classes_1.CLASSES.IS_REQUIRED, props.isReadOnly && classes_1.CLASSES.IS_READONLY, props.isDisabled && classes_1.CLASSES.IS_DISABLED, props.className), "data-name": props.name, disabled: props.isDisabled || props.isReadOnly, onChange: onChange, style: props.style, value: selectedOption }, (renderProps) => (react_3.default.createElement(react_3.default.Fragment, null,
79
+ react_3.default.createElement("div", { className: "uxf-form-component__label" },
80
+ react_3.default.createElement(react_2.Combobox.Label, { as: label_1.Label, isHidden: props.hiddenLabel, onClick: props.isDisabled || props.isReadOnly ? undefined : input.focus }, props.label)),
81
+ react_3.default.createElement("div", { className: "uxf-form-component__input" },
82
+ react_3.default.createElement(react_2.Combobox.Button, { as: input_1.Input, "aria-invalid": props.isInvalid, "aria-describedby": errorId, className: (0, cx_1.cx)("uxf-combobox__button", dropdown.placement === "bottom" && `${classes_1.CLASSES.IS_OPEN}--bottom`, dropdown.placement === "top" && `${classes_1.CLASSES.IS_OPEN}--top`, renderProps.open && classes_1.CLASSES.IS_OPEN), customInputElementDisplayName: react_2.Combobox.Input.displayName, inputFocus: input, inputGroupRef: stableRef, inputWrapperRef: props.inputWrapperRef, isDisabled: props.isDisabled, isFocused: renderProps.open, isInvalid: props.isInvalid, isReadOnly: props.isReadOnly, ref: props.inputRef, size: props.size, variant: props.variant },
83
+ props.leftAddon && react_3.default.createElement(input_1.Input.LeftAddon, null, props.leftAddon),
84
+ props.leftElement && react_3.default.createElement(input_1.Input.LeftElement, null, props.leftElement),
85
+ react_3.default.createElement(react_2.Combobox.Input, { autoComplete: "off", className: "uxf-input__element", displayValue: displayValue, onBlur: props.onBlur, onChange: onInputChange, placeholder: props.placeholder, type: "text" }),
86
+ react_3.default.createElement(input_1.Input.RightElement, null,
87
+ react_3.default.createElement(show_1.Show, { when: Boolean(props.isClearable) &&
88
+ (0, is_not_nil_1.isNotNil)(selectedOption) &&
89
+ !props.isDisabled &&
90
+ !props.isReadOnly },
91
+ react_3.default.createElement(input_1.Input.RemoveButton, { onChange: onChange })),
92
+ props.inputArrow ? (react_3.default.createElement(react_2.Combobox.Button, null, props.inputArrow(renderProps.open))) : (react_3.default.createElement(input_1.Input.ArrowIcon, { iconName: props.iconName, isOpen: renderProps.open }))),
93
+ props.rightAddon && react_3.default.createElement(input_1.Input.RightAddon, null, props.rightAddon)),
94
+ react_3.default.createElement(show_1.Show, { when: renderProps.open },
95
+ react_3.default.createElement(react_1.FloatingPortal, null,
96
+ react_3.default.createElement(Options, { className: props.dropdownClassName, emptyMessage: emptyMessage, forwardRef: dropdown.refs.setFloating, keyExtractor: props.keyExtractor, matchWidth: props.dropdownMatchesInputWidth, onUnmount: clearQuery, options: filteredData, placement: dropdown.placement, renderOption: props.renderOption, size: props.size, style: dropdown.floatingStyles, variant: props.variant }))),
97
+ react_3.default.createElement(show_1.Show, { when: Boolean(props.helperText) },
98
+ react_3.default.createElement("div", { className: (0, cx_1.cx)("uxf-helper-text", props.isInvalid && classes_1.CLASSES.IS_INVALID), id: errorId }, props.helperText)))))));
99
+ }
49
100
  exports.Combobox = Combobox;
50
- exports.Combobox.displayName = "UxfUiCombobox";
101
+ Combobox.displayName = "UxfUiCombobox";
@@ -1,11 +1,8 @@
1
1
  import React from "react";
2
- import { ComboboxOption } from "./combobox";
2
+ import { Combobox } from "./index";
3
3
  declare const _default: {
4
4
  title: string;
5
- component: {
6
- <ValueId = import("./combobox").ComboboxValueId, Option = ComboboxOption<ValueId>, Value = Option>(props: import("./combobox").ComboboxProps<ValueId, Option, Value>): React.JSX.Element;
7
- displayName: string;
8
- };
5
+ component: typeof Combobox;
9
6
  };
10
7
  export default _default;
11
8
  export declare function Default(): React.JSX.Element;
@@ -1,2 +1,2 @@
1
1
  export { Combobox } from "./combobox";
2
- export type { ComboboxOption, ComboboxProps, ComboboxValue, ComboboxValueId } from "./combobox";
2
+ export type { ComboboxOption, ComboboxProps, ComboboxTypeRef, ComboboxValue, ComboboxValueId } from "./combobox";
@@ -21,10 +21,8 @@
21
21
  }
22
22
 
23
23
  &--color-default {
24
- :root .light & {
25
- --bg-color: theme("backgroundColor.primary.100");
26
- --icon-color: theme("colors.primary.600");
27
- }
24
+ --bg-color: theme("backgroundColor.primary.100");
25
+ --icon-color: theme("colors.primary.600");
28
26
 
29
27
  :root .dark & {
30
28
  --bg-color: theme("backgroundColor.primary.600");
@@ -33,10 +31,8 @@
33
31
  }
34
32
 
35
33
  &--color-warning {
36
- :root .light & {
37
- --bg-color: theme("backgroundColor.warning.100");
38
- --icon-color: theme("colors.warning.600");
39
- }
34
+ --bg-color: theme("backgroundColor.warning.100");
35
+ --icon-color: theme("colors.warning.600");
40
36
 
41
37
  :root .dark & {
42
38
  --bg-color: theme("backgroundColor.warning.600");
@@ -45,10 +41,8 @@
45
41
  }
46
42
 
47
43
  &--color-success {
48
- :root .light & {
49
- --bg-color: theme("backgroundColor.success.100");
50
- --icon-color: theme("colors.success.600");
51
- }
44
+ --bg-color: theme("backgroundColor.success.100");
45
+ --icon-color: theme("colors.success.600");
52
46
 
53
47
  :root .dark & {
54
48
  --bg-color: theme("backgroundColor.success.600");
@@ -57,10 +51,8 @@
57
51
  }
58
52
 
59
53
  &--color-error {
60
- :root .light & {
61
- --bg-color: theme("backgroundColor.error.100");
62
- --icon-color: theme("colors.error.600");
63
- }
54
+ --bg-color: theme("backgroundColor.error.100");
55
+ --icon-color: theme("colors.error.600");
64
56
 
65
57
  :root .dark & {
66
58
  --bg-color: theme("backgroundColor.error.600");
@@ -18,9 +18,7 @@
18
18
  width: theme("width.20");
19
19
 
20
20
  &:hover .uxf-avatar-file-input__input-empty {
21
- :root .light & {
22
- --bg-color: theme("colors.lightBorder/.25");
23
- }
21
+ --bg-color: theme("colors.lightBorder/.25");
24
22
 
25
23
  :root .dark & {
26
24
  --bg-color: theme("colors.darkBorder/.25");
@@ -28,11 +26,9 @@
28
26
  }
29
27
 
30
28
  &.is-invalid .uxf-avatar-file-input__input-empty {
31
- :root .light & {
32
- --bg-color: theme("colors.error.DEFAULT/.05");
33
- --border-color: var(--color);
34
- --color: theme("colors.error.DEFAULT");
35
- }
29
+ --bg-color: theme("colors.error.DEFAULT/.05");
30
+ --border-color: var(--color);
31
+ --color: theme("colors.error.DEFAULT");
36
32
 
37
33
  :root .dark & {
38
34
  --bg-color: theme("colors.error.DEFAULT/.05");
@@ -45,10 +41,8 @@
45
41
  pointer-events: none;
46
42
 
47
43
  .uxf-avatar-file-input__input-empty {
48
- :root .light & {
49
- --border-color: var(--color);
50
- --color: theme("colors.lightBorder");
51
- }
44
+ --border-color: var(--color);
45
+ --color: theme("colors.lightBorder");
52
46
 
53
47
  :root .dark & {
54
48
  --border-color: var(--color);
@@ -68,17 +62,15 @@
68
62
  &:focus-visible + .uxf-avatar-file-input__input-empty {
69
63
  border-width: theme("borderWidth.4");
70
64
 
71
- /* :root .light & {
72
- --bg-color: theme("colors.primary.DEFAULT/.05");
73
- --border-color: var(--color);
74
- --color: theme("colors.primary.DEFAULT");
75
- }
65
+ /* --bg-color: theme("colors.primary.DEFAULT/.05");
66
+ --border-color: var(--color);
67
+ --color: theme("colors.primary.DEFAULT");
76
68
 
77
69
  :root .dark & {
78
70
  --bg-color: theme("colors.primary.DEFAULT/.05");
79
71
  --border-color: var(--color);
80
72
  --color: theme("colors.primary.DEFAULT");
81
- */
73
+ } */
82
74
  }
83
75
  }
84
76
 
@@ -91,6 +83,8 @@
91
83
 
92
84
  &__input-empty {
93
85
  --bg-color: transparent;
86
+ --border-color: theme("colors.lightBorder");
87
+ --color: theme("colors.lightMedium");
94
88
 
95
89
  @apply transition-all duration-75;
96
90
 
@@ -103,14 +97,9 @@
103
97
  justify-content: center;
104
98
  width: 100%;
105
99
 
106
- :root .light & {
107
- --color: theme("colors.lightMedium");
108
- --border-color: theme("colors.lightBorder");
109
- }
110
-
111
100
  :root .dark & {
112
- --color: theme("colors.darkMedium");
113
101
  --border-color: theme("colors.darkBorder");
102
+ --color: theme("colors.darkMedium");
114
103
  }
115
104
  }
116
105
 
package/css/avatar.css CHANGED
@@ -1,14 +1,10 @@
1
1
  .uxf-avatar {
2
- @apply relative inline-flex size-10 items-center justify-center rounded-full;
2
+ @apply relative inline-flex size-10 items-center justify-center rounded-full bg-gray-200 text-gray-700;
3
3
 
4
4
  &__image {
5
5
  @apply rounded-inherit absolute left-0 top-0 block size-full object-cover;
6
6
  }
7
7
 
8
- :root .light & {
9
- @apply bg-gray-200 text-gray-700;
10
- }
11
-
12
8
  :root .dark & {
13
9
  @apply bg-gray-800 text-gray-200;
14
10
  }
package/css/badge.css CHANGED
@@ -1,5 +1,5 @@
1
1
  .uxf-badge {
2
- @apply inline-flex items-center justify-center font-bold;
2
+ @apply bg-primary inline-flex items-center justify-center font-bold text-white;
3
3
 
4
4
  &--size-small {
5
5
  @apply h-6 min-w-[24px] rounded-[12px] px-1.5 text-sm;
@@ -13,10 +13,6 @@
13
13
  @apply h-10 min-w-[40px] rounded-[20px] px-2 text-lg;
14
14
  }
15
15
 
16
- :root .light & {
17
- @apply bg-primary text-white;
18
- }
19
-
20
16
  :root .dark & {
21
17
  @apply bg-white text-gray-900;
22
18
  }
@@ -8,11 +8,7 @@
8
8
  }
9
9
 
10
10
  &__menu-items {
11
- @apply z-dropdown absolute right-0 mt-2 w-40 divide-y rounded-md shadow-lg ring-1 focus:outline-none;
12
-
13
- :root .light & {
14
- @apply divide-gray-100 bg-white ring-black/5;
15
- }
11
+ @apply z-dropdown absolute right-0 mt-2 w-40 divide-y divide-gray-100 rounded-md bg-white shadow-lg ring-1 ring-black/5 focus:outline-none;
16
12
 
17
13
  :root .dark & {
18
14
  @apply divide-gray-700 bg-gray-900 ring-white/10;
@@ -28,22 +24,14 @@
28
24
  }
29
25
 
30
26
  &__menu-button {
31
- @apply is-hoverable:hover:cursor-pointer flex space-x-3 px-3 py-2 text-sm;
32
-
33
- :root .light & {
34
- @apply text-black hover:text-gray-800;
35
- }
27
+ @apply is-hoverable:hover:cursor-pointer flex space-x-3 px-3 py-2 text-sm text-black hover:text-gray-800;
36
28
 
37
29
  :root .dark & {
38
30
  @apply text-white hover:text-gray-200;
39
31
  }
40
32
 
41
33
  &-icon {
42
- @apply w-3;
43
-
44
- :root .light & {
45
- @apply text-lightMedium;
46
- }
34
+ @apply text-lightMedium w-3;
47
35
 
48
36
  :root .dark & {
49
37
  @apply text-darkMedium;
@@ -51,9 +39,7 @@
51
39
  }
52
40
 
53
41
  &.is-disabled {
54
- :root .light & {
55
- @apply text-lightLow;
56
- }
42
+ @apply text-lightLow;
57
43
 
58
44
  :root .dark & {
59
45
  @apply text-darkLow;