@coopdigital/react 1.8.0 → 1.8.2
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.
- package/dist/components/DatePicker/DatePicker.js +14 -11
- package/dist/components/DatePicker/datepicker-utils.js +4 -5
- package/dist/components/Dialog/Dialog.js +1 -1
- package/dist/components/Field/Field.js +1 -1
- package/dist/components/Image/Image.js +2 -2
- package/dist/components/Textarea/Textarea.js +3 -2
- package/dist/components/ValidationSummary/ValidationSummary.js +1 -1
- package/dist/hooks/useSlots.js +1 -1
- package/dist/utils/index.js +1 -0
- package/package.json +3 -3
- package/src/components/Button/Button.tsx +1 -1
- package/src/components/Card/Card.tsx +1 -2
- package/src/components/DatePicker/DatePicker.tsx +21 -20
- package/src/components/DatePicker/datepicker-utils.ts +4 -4
- package/src/components/Dialog/Dialog.tsx +2 -2
- package/src/components/Field/Field.tsx +1 -1
- package/src/components/Image/Image.tsx +1 -1
- package/src/components/Pill/Pill.tsx +1 -1
- package/src/components/Signpost/Signpost.tsx +1 -1
- package/src/components/Tag/Tag.tsx +1 -1
- package/src/components/Textarea/Textarea.tsx +2 -2
- package/src/components/ValidationSummary/ValidationSummary.tsx +2 -2
- package/src/hooks/useSlots.ts +1 -1
- package/src/types/index.ts +1 -1
- package/src/types/react.d.ts +2 -1
- package/src/utils/index.ts +1 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
3
|
import clsx from 'clsx';
|
|
4
4
|
import { useMemo, useReducer, useCallback } from 'react';
|
|
5
5
|
import { DayPicker } from 'react-day-picker';
|
|
@@ -30,10 +30,8 @@ const defaultFormatters = {
|
|
|
30
30
|
formatWeekdayName: (d) => d.toLocaleDateString("default", { weekday: "short" }).slice(0, 2),
|
|
31
31
|
};
|
|
32
32
|
const Calendar = ({ captionLayout = "label", className, disabled, endMonth, formatters, showOutsideDays = true, startMonth, ...props }) => {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
...formatters,
|
|
36
|
-
}, navLayout: "around", showOutsideDays: showOutsideDays, startMonth: startMonth, weekStartsOn: 1, ...props }));
|
|
33
|
+
const combinedFormatters = useMemo(() => ({ ...defaultFormatters, ...formatters }), [formatters]);
|
|
34
|
+
return (jsx(DayPicker, { captionLayout: captionLayout, className: className, disabled: disabled, endMonth: endMonth, formatters: combinedFormatters, navLayout: "around", showOutsideDays: showOutsideDays, startMonth: startMonth, weekStartsOn: 1, ...props }));
|
|
37
35
|
};
|
|
38
36
|
const DatePicker = ({ className, closeOnSelect = true, dateFormat = "dd/MM/yyyy", disabled, disabledDates, endDate, error = false, id, initialDate = now, initialSelected = false, mode = "single", name, onChange, onSelect, ref, required = false, size, startDate, ...props }) => {
|
|
39
37
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
|
|
@@ -53,8 +51,10 @@ const DatePicker = ({ className, closeOnSelect = true, dateFormat = "dd/MM/yyyy"
|
|
|
53
51
|
}
|
|
54
52
|
const [state, setState] = useReducer((stale, fresh) => ({ ...stale, ...fresh }), { ...initialState, [mode]: initialValues.state, open: false, view: initialValues.view });
|
|
55
53
|
const dispatchChanges = useCallback((value) => {
|
|
56
|
-
typeof onChange === "function"
|
|
57
|
-
|
|
54
|
+
if (typeof onChange === "function")
|
|
55
|
+
onChange(value);
|
|
56
|
+
if (typeof onSelect === "function")
|
|
57
|
+
onSelect(value);
|
|
58
58
|
}, [onChange, onSelect]);
|
|
59
59
|
const updateValues = useCallback((selected) => {
|
|
60
60
|
var _a, _b, _c;
|
|
@@ -111,6 +111,9 @@ const DatePicker = ({ className, closeOnSelect = true, dateFormat = "dd/MM/yyyy"
|
|
|
111
111
|
id: id !== null && id !== void 0 ? id : field === null || field === void 0 ? void 0 : field.id,
|
|
112
112
|
name: name,
|
|
113
113
|
};
|
|
114
|
+
const computedSuffix = useMemo(() => {
|
|
115
|
+
return disabled ? (jsx("span", { className: "coop-datepicker-trigger", children: jsx(CalendarIcon, { width: 24 }) })) : (jsx(Popover.Trigger, { "aria-label": "Choose date", className: "coop-datepicker-trigger", children: jsx(CalendarIcon, { width: 24 }) }));
|
|
116
|
+
}, [disabled]);
|
|
114
117
|
const getPlaceholder = () => {
|
|
115
118
|
const lowerCaseDateFormat = dateFormat.toLowerCase();
|
|
116
119
|
switch (mode) {
|
|
@@ -124,19 +127,19 @@ const DatePicker = ({ className, closeOnSelect = true, dateFormat = "dd/MM/yyyy"
|
|
|
124
127
|
};
|
|
125
128
|
return (jsxs("div", { ...componentProps, children: [jsxs(Popover, { onOpenChange: setOpen, open: state.open, children: [jsx(Popover.Anchor, { className: "coop-datepicker-inner", children: jsx(TextInput, { autoComplete: "off", className: "coop-datepicker-input", disabled: disabled, id: valueProps.id + "_display",
|
|
126
129
|
//maxLength={dateFormat.length}
|
|
127
|
-
name: name + "_display", onChange: updateFromInput, placeholder: getPlaceholder(), ref: ref, required: required, size: size, suffix:
|
|
130
|
+
name: name + "_display", onChange: updateFromInput, placeholder: getPlaceholder(), ref: ref, required: required, size: size, suffix: computedSuffix, suffixInline: true, value: (_f = (_e = state === null || state === void 0 ? void 0 : state[mode]) === null || _e === void 0 ? void 0 : _e.input) !== null && _f !== void 0 ? _f : "" }) }), jsxs(Popover.Content, { "aria-label": "Date picker", className: "coop-datepicker-calendar bg-white", collisionPadding: 16, sideOffset: 4, children: [jsx(Calendar
|
|
128
131
|
// jsx-ally throws here because we set autoFocus, but this
|
|
129
132
|
// is not a standard element. Daypicker uses this value to
|
|
130
133
|
// focus the day rather than the nav when it renders.
|
|
131
|
-
//
|
|
134
|
+
// oxlint-disable-next-line jsx-a11y/no-autofocus
|
|
132
135
|
, {
|
|
133
136
|
// jsx-ally throws here because we set autoFocus, but this
|
|
134
137
|
// is not a standard element. Daypicker uses this value to
|
|
135
138
|
// focus the day rather than the nav when it renders.
|
|
136
|
-
//
|
|
139
|
+
// oxlint-disable-next-line jsx-a11y/no-autofocus
|
|
137
140
|
autoFocus: true, captionLayout: "dropdown",
|
|
138
141
|
//defaultMonth={defaultMonth}
|
|
139
|
-
disabled: disabledDates, endMonth: endDate, month: state.view, onMonthChange: setView, onSelect: updateValues, startMonth: startDate, ...calendarProps[mode] }), jsxs("div", { className: "coop-datepicker-actions", children: [jsxs(Button, { "aria-label": "Cancel", className: "bg-tint-grey", onClick: resetState, size: "sm", children: ["Clear ", jsx(CrossIcon, { stroke: "black", strokeWidth: 1 })] }), jsx(Popover.Close, { asChild: true, children: jsxs(Button, { "aria-label": "Accept", size: "sm", children: ["OK ", jsx(TickIcon, { stroke: "white", strokeWidth: 1 })] }) })] })] })] }), jsx("
|
|
142
|
+
disabled: disabledDates, endMonth: endDate, month: state.view, onMonthChange: setView, onSelect: updateValues, startMonth: startDate, ...calendarProps[mode] }), jsxs("div", { className: "coop-datepicker-actions", children: [jsxs(Button, { "aria-label": "Cancel", className: "bg-tint-grey", onClick: resetState, size: "sm", children: ["Clear ", jsx(CrossIcon, { stroke: "black", strokeWidth: 1 })] }), jsx(Popover.Close, { asChild: true, children: jsxs(Button, { "aria-label": "Accept", size: "sm", children: ["OK ", jsx(TickIcon, { stroke: "white", strokeWidth: 1 })] }) })] })] })] }), jsx("output", { "aria-live": "assertive", className: "sr-only coop-datepicker-status", children: (_g = state.message) !== null && _g !== void 0 ? _g : footerMessage[mode] }), mode === "single" && (jsx("input", { ...valueProps, value: (_l = (_j = (_h = state.single) === null || _h === void 0 ? void 0 : _h.field) !== null && _j !== void 0 ? _j : (_k = state.single) === null || _k === void 0 ? void 0 : _k.input) !== null && _l !== void 0 ? _l : "" })), mode === "multiple" && (jsx("input", { ...valueProps, value: (_q = (_o = (_m = state.multiple) === null || _m === void 0 ? void 0 : _m.field) !== null && _o !== void 0 ? _o : (_p = state.multiple) === null || _p === void 0 ? void 0 : _p.input) !== null && _q !== void 0 ? _q : "" })), mode === "range" && (jsxs(Fragment, { children: [jsx("input", { ...baseValueProps, id: `${valueProps.id}_start`, name: `${name}_start`, value: (_v = (_t = (_s = (_r = state.range) === null || _r === void 0 ? void 0 : _r.field) === null || _s === void 0 ? void 0 : _s.from) !== null && _t !== void 0 ? _t : (_u = state.range) === null || _u === void 0 ? void 0 : _u.input) !== null && _v !== void 0 ? _v : "" }), jsx("input", { ...baseValueProps, id: `${valueProps.id}_end`, name: `${name}_end`, value: (_0 = (_y = (_x = (_w = state.range) === null || _w === void 0 ? void 0 : _w.field) === null || _x === void 0 ? void 0 : _x.to) !== null && _y !== void 0 ? _y : (_z = state.range) === null || _z === void 0 ? void 0 : _z.input) !== null && _0 !== void 0 ? _0 : "" })] }))] }));
|
|
140
143
|
};
|
|
141
144
|
DatePicker.slot = {
|
|
142
145
|
field: true,
|
|
@@ -72,13 +72,12 @@ const initialState = {
|
|
|
72
72
|
validated: false,
|
|
73
73
|
};
|
|
74
74
|
function getSingleDate(date, df, now) {
|
|
75
|
-
var _a;
|
|
76
75
|
if (!date)
|
|
77
76
|
return initialState;
|
|
78
77
|
let parsed;
|
|
79
78
|
let input = "";
|
|
80
79
|
if (typeof date === "string") {
|
|
81
|
-
input =
|
|
80
|
+
input = date !== null && date !== void 0 ? date : "";
|
|
82
81
|
parsed = parse(date, df, now);
|
|
83
82
|
}
|
|
84
83
|
else if (isValidDate(date)) {
|
|
@@ -191,7 +190,7 @@ const getDateValues = (mode, selected, dateFormat, now) => {
|
|
|
191
190
|
return getRangeDate(selected, dateFormat, now);
|
|
192
191
|
};
|
|
193
192
|
const shouldSkipParsing = (value) => {
|
|
194
|
-
return typeof value !== "string" ? true :
|
|
193
|
+
return typeof value !== "string" ? true : value.length < 8 || value.split("/").length < 3;
|
|
195
194
|
};
|
|
196
195
|
const shouldClose = (mode, value, closeOnSelect) => {
|
|
197
196
|
var _a, _b;
|
|
@@ -204,10 +203,10 @@ const shouldClose = (mode, value, closeOnSelect) => {
|
|
|
204
203
|
else
|
|
205
204
|
return false;
|
|
206
205
|
};
|
|
207
|
-
/*
|
|
206
|
+
/* oxlint-disable eslint/no-unused-vars */
|
|
208
207
|
const isSingle = (m, d) => m === "single";
|
|
209
208
|
const isMultiple = (m, d) => m === "multiple";
|
|
210
209
|
const isRange = (m, d) => m === "range";
|
|
211
|
-
/*
|
|
210
|
+
/* oxlint-enable eslint/no-unused-vars */
|
|
212
211
|
|
|
213
212
|
export { getDateValues, getDefaultMonth, getEndDate, getISODateString, getInitialDate, getMultipleDate, getRangeDate, getRangeFromString, getSingleDate, getStartDate, isMultiple, isRange, isSingle, isValidDate, isValidRangeFrom, isValidRangeTo, shouldClose, shouldSkipParsing };
|
|
@@ -13,7 +13,7 @@ const useDialog = () => {
|
|
|
13
13
|
throw new Error("Dialog components must be used inside <Dialog>");
|
|
14
14
|
return ctx;
|
|
15
15
|
};
|
|
16
|
-
const Dialog = ({ children, className, closedBy = "any", label, mode = "dialog", onClose, onOpen, onToggle, open
|
|
16
|
+
const Dialog = ({ children, className, closedBy = "any", label, mode = "dialog", onClose, onOpen, onToggle, open, position, ref, role, ...props }) => {
|
|
17
17
|
const dialogRef = useRef(null);
|
|
18
18
|
useEffect(() => {
|
|
19
19
|
const dialog = dialogRef.current;
|
|
@@ -31,7 +31,7 @@ const Field = ({ boxed = false, children, className, error = false, hideErrorBar
|
|
|
31
31
|
var _a, _b, _c, _d;
|
|
32
32
|
if (child && typeof child === "object" && "type" in child) {
|
|
33
33
|
if (typeof (child === null || child === void 0 ? void 0 : child.type) === "function" && "slot" in child.type) {
|
|
34
|
-
const { slot } = child
|
|
34
|
+
const { slot } = child.type;
|
|
35
35
|
slots.Control = child;
|
|
36
36
|
if (slots.Control.props) {
|
|
37
37
|
controlProps.inline = (_a = slot.inline) !== null && _a !== void 0 ? _a : false;
|
|
@@ -11,8 +11,8 @@ const getContentfulParams = (src, width, height) => {
|
|
|
11
11
|
...(height ? [["h", height]] : []),
|
|
12
12
|
];
|
|
13
13
|
params.forEach(([k, v]) => {
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
if (!url.searchParams.has(k))
|
|
15
|
+
url.searchParams.set(k, v);
|
|
16
16
|
});
|
|
17
17
|
return {
|
|
18
18
|
height: (_a = url.searchParams.get("h")) !== null && _a !== void 0 ? _a : height,
|
|
@@ -9,7 +9,7 @@ const DEBOUNCE_DELAY = 750;
|
|
|
9
9
|
const charCountMessage = (remaining) => {
|
|
10
10
|
return `You have ${Math.abs(remaining).toLocaleString()} ${Math.abs(remaining) === 1 ? "character" : "characters"} ${remaining < 0 ? "too many" : "remaining"}`;
|
|
11
11
|
};
|
|
12
|
-
const Textarea = ({ "aria-placeholder": ariaPlaceholder, className, cols = 30, counter = false, cutoff = false, disabled = false, error = false, id, maxLength, name, onChange: userOnChange
|
|
12
|
+
const Textarea = ({ "aria-placeholder": ariaPlaceholder, className, cols = 30, counter = false, cutoff = false, disabled = false, error = false, id, maxLength, name, onChange: userOnChange, placeholder, ref, rows = 4, size, ...props }) => {
|
|
13
13
|
var _a;
|
|
14
14
|
const field = useField();
|
|
15
15
|
const componentProps = {
|
|
@@ -31,7 +31,8 @@ const Textarea = ({ "aria-placeholder": ariaPlaceholder, className, cols = 30, c
|
|
|
31
31
|
const showCounter = !disabled && counter && maxLength && remaining != null && debouncedRemaining != null;
|
|
32
32
|
const handleChange = (e) => {
|
|
33
33
|
userOnChange === null || userOnChange === void 0 ? void 0 : userOnChange(e);
|
|
34
|
-
|
|
34
|
+
if (maxLength && e.target)
|
|
35
|
+
setRemaining(maxLength - e.target.value.length);
|
|
35
36
|
};
|
|
36
37
|
// const formItemProps = { "aria-disabled": disabled ? true : undefined }
|
|
37
38
|
return (jsxs("div", { className: "coop-textarea-wrapper", children: [jsx("textarea", { ...componentProps, onChange: handleChange, ref: ref }), showCounter && (jsxs(Fragment, { children: [jsx("small", { "aria-hidden": "true", className: "coop-textarea-counter", ...(remaining < 0 && { "data-error": true }), children: charCountMessage(remaining) }), jsx("span", { "aria-live": "polite", className: "sr-only", children: charCountMessage(debouncedRemaining) })] }))] }));
|
|
@@ -17,7 +17,7 @@ const ValidationSummary = ({ autoScroll = true, children, className, forceMount
|
|
|
17
17
|
const slots = { ...useSlots(componentSlots, children) };
|
|
18
18
|
const errors = React.isValidElement(slots.ValidationSummaryErrors) &&
|
|
19
19
|
Object.keys((_a = slots.ValidationSummaryErrors.props.errors) !== null && _a !== void 0 ? _a : {});
|
|
20
|
-
const hasErrors =
|
|
20
|
+
const hasErrors = Object.keys(errors).length > 0;
|
|
21
21
|
const internalRef = useRef(null);
|
|
22
22
|
useEffect(() => {
|
|
23
23
|
var _a, _b;
|
package/dist/hooks/useSlots.js
CHANGED
|
@@ -3,7 +3,7 @@ import React from 'react';
|
|
|
3
3
|
function isKey(x, k) {
|
|
4
4
|
return k in x;
|
|
5
5
|
}
|
|
6
|
-
//
|
|
6
|
+
// oxlint-disable-next-line typecscript/no-explicit-any
|
|
7
7
|
function isLazy(type) {
|
|
8
8
|
return typeof type === "object" && type !== null && "_payload" in type && "_init" in type;
|
|
9
9
|
}
|
package/dist/utils/index.js
CHANGED
|
@@ -10,6 +10,7 @@ const bgClassToColor = (userClasses) => {
|
|
|
10
10
|
var _a, _b;
|
|
11
11
|
return (_b = (_a = /bg-([^\s]+)/.exec(userClasses)) === null || _a === void 0 ? void 0 : _a[1]) !== null && _b !== void 0 ? _b : null;
|
|
12
12
|
};
|
|
13
|
+
// oxlint-disable-next-line typescript/no-unnecessary-type-parameters
|
|
13
14
|
function getSlotProp(slot, prop) {
|
|
14
15
|
if (isValidElement(slot) && prop in slot.props) {
|
|
15
16
|
return slot.props[prop];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coopdigital/react",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.8.
|
|
4
|
+
"version": "1.8.2",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -100,11 +100,11 @@
|
|
|
100
100
|
"storybook": "$storybook"
|
|
101
101
|
},
|
|
102
102
|
"dependencies": {
|
|
103
|
-
"@coopdigital/styles": "^1.5.
|
|
103
|
+
"@coopdigital/styles": "^1.5.1",
|
|
104
104
|
"@radix-ui/react-popover": "^1.1.17",
|
|
105
105
|
"clsx": "^2.1.1",
|
|
106
106
|
"merge-refs": "^2.0.0",
|
|
107
107
|
"react-day-picker": "^10.0.1"
|
|
108
108
|
},
|
|
109
|
-
"gitHead": "
|
|
109
|
+
"gitHead": "bbd5f9f7c7ff206270e54690655c3087ad7add8c"
|
|
110
110
|
}
|
|
@@ -10,7 +10,7 @@ import { LoadingIcon } from "../icons"
|
|
|
10
10
|
|
|
11
11
|
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
12
12
|
/** **(Optional)** Specify a custom element to override default `a` or `button`. */
|
|
13
|
-
//
|
|
13
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
14
14
|
as?: React.FC<any> | ForwardRefExoticComponent<any> | string
|
|
15
15
|
/** **(Optional)** Main content inside the component. It can be any valid JSX or string. */
|
|
16
16
|
children?: React.ReactNode
|
|
@@ -17,10 +17,9 @@ export interface CardProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
17
17
|
className?: string
|
|
18
18
|
/** **(Optional)** Specify the URL that the Card will link to. */
|
|
19
19
|
href?: string
|
|
20
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
21
20
|
/** **(Optional)** Specify a custom element to use instead of `a`. */
|
|
21
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
22
22
|
hrefAs?: React.FC<any> | ForwardRefExoticComponent<any> | string
|
|
23
|
-
/* eslint-enable */
|
|
24
23
|
/** **(Optional)** Specify the position of the image in the Card. */
|
|
25
24
|
imagePosition?: "left" | "right"
|
|
26
25
|
/** **(Optional)** Specify the orientation of the Card. */
|
|
@@ -138,16 +138,15 @@ const Calendar = ({
|
|
|
138
138
|
startMonth,
|
|
139
139
|
...props
|
|
140
140
|
}: DayPickerProps) => {
|
|
141
|
+
const combinedFormatters = useMemo(() => ({ ...defaultFormatters, ...formatters }), [formatters])
|
|
142
|
+
|
|
141
143
|
return (
|
|
142
144
|
<DayPicker
|
|
143
145
|
captionLayout={captionLayout}
|
|
144
146
|
className={className}
|
|
145
147
|
disabled={disabled}
|
|
146
148
|
endMonth={endMonth}
|
|
147
|
-
formatters={
|
|
148
|
-
...defaultFormatters,
|
|
149
|
-
...formatters,
|
|
150
|
-
}}
|
|
149
|
+
formatters={combinedFormatters}
|
|
151
150
|
navLayout="around"
|
|
152
151
|
showOutsideDays={showOutsideDays}
|
|
153
152
|
startMonth={startMonth}
|
|
@@ -209,8 +208,8 @@ const DatePicker = ({
|
|
|
209
208
|
|
|
210
209
|
const dispatchChanges = useCallback(
|
|
211
210
|
(value: string | DateRangeStr | undefined) => {
|
|
212
|
-
typeof onChange === "function"
|
|
213
|
-
typeof onSelect === "function"
|
|
211
|
+
if (typeof onChange === "function") onChange(value)
|
|
212
|
+
if (typeof onSelect === "function") onSelect(value)
|
|
214
213
|
},
|
|
215
214
|
[onChange, onSelect]
|
|
216
215
|
)
|
|
@@ -284,6 +283,18 @@ const DatePicker = ({
|
|
|
284
283
|
name: name,
|
|
285
284
|
}
|
|
286
285
|
|
|
286
|
+
const computedSuffix = useMemo(() => {
|
|
287
|
+
return disabled ? (
|
|
288
|
+
<span className="coop-datepicker-trigger">
|
|
289
|
+
<CalendarIcon width={24} />
|
|
290
|
+
</span>
|
|
291
|
+
) : (
|
|
292
|
+
<Popover.Trigger aria-label="Choose date" className="coop-datepicker-trigger">
|
|
293
|
+
<CalendarIcon width={24} />
|
|
294
|
+
</Popover.Trigger>
|
|
295
|
+
)
|
|
296
|
+
}, [disabled])
|
|
297
|
+
|
|
287
298
|
const getPlaceholder = () => {
|
|
288
299
|
const lowerCaseDateFormat = dateFormat.toLowerCase()
|
|
289
300
|
switch (mode) {
|
|
@@ -312,17 +323,7 @@ const DatePicker = ({
|
|
|
312
323
|
ref={ref}
|
|
313
324
|
required={required}
|
|
314
325
|
size={size}
|
|
315
|
-
suffix={
|
|
316
|
-
disabled ? (
|
|
317
|
-
<span className="coop-datepicker-trigger">
|
|
318
|
-
<CalendarIcon width={24} />
|
|
319
|
-
</span>
|
|
320
|
-
) : (
|
|
321
|
-
<Popover.Trigger aria-label="Choose date" className="coop-datepicker-trigger">
|
|
322
|
-
<CalendarIcon width={24} />
|
|
323
|
-
</Popover.Trigger>
|
|
324
|
-
)
|
|
325
|
-
}
|
|
326
|
+
suffix={computedSuffix}
|
|
326
327
|
suffixInline={true}
|
|
327
328
|
value={state?.[mode]?.input ?? ""}
|
|
328
329
|
/>
|
|
@@ -337,7 +338,7 @@ const DatePicker = ({
|
|
|
337
338
|
// jsx-ally throws here because we set autoFocus, but this
|
|
338
339
|
// is not a standard element. Daypicker uses this value to
|
|
339
340
|
// focus the day rather than the nav when it renders.
|
|
340
|
-
//
|
|
341
|
+
// oxlint-disable-next-line jsx-a11y/no-autofocus
|
|
341
342
|
autoFocus
|
|
342
343
|
captionLayout="dropdown"
|
|
343
344
|
//defaultMonth={defaultMonth}
|
|
@@ -362,9 +363,9 @@ const DatePicker = ({
|
|
|
362
363
|
</Popover.Content>
|
|
363
364
|
</Popover>
|
|
364
365
|
|
|
365
|
-
<
|
|
366
|
+
<output aria-live="assertive" className="sr-only coop-datepicker-status">
|
|
366
367
|
{state.message ?? footerMessage[mode]}
|
|
367
|
-
</
|
|
368
|
+
</output>
|
|
368
369
|
|
|
369
370
|
{mode === "single" && (
|
|
370
371
|
<input {...valueProps} value={state.single?.field ?? state.single?.input ?? ""} />
|
|
@@ -131,7 +131,7 @@ export function getSingleDate(date: Date | DateBase, df: string, now: Date): RDa
|
|
|
131
131
|
let input = ""
|
|
132
132
|
|
|
133
133
|
if (typeof date === "string") {
|
|
134
|
-
input = date
|
|
134
|
+
input = date ?? ""
|
|
135
135
|
parsed = parse(date, df, now)
|
|
136
136
|
} else if (isValidDate(date)) {
|
|
137
137
|
input = format(date, df)
|
|
@@ -254,7 +254,7 @@ export const getDateValues = (mode: Mode, selected: DateType, dateFormat: string
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
export const shouldSkipParsing = (value: string): boolean => {
|
|
257
|
-
return typeof value !== "string" ? true :
|
|
257
|
+
return typeof value !== "string" ? true : value.length < 8 || value.split("/").length < 3
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
export const shouldClose = (mode: Mode, value: DateType, closeOnSelect?: boolean): boolean => {
|
|
@@ -264,8 +264,8 @@ export const shouldClose = (mode: Mode, value: DateType, closeOnSelect?: boolean
|
|
|
264
264
|
else return false
|
|
265
265
|
}
|
|
266
266
|
|
|
267
|
-
/*
|
|
267
|
+
/* oxlint-disable eslint/no-unused-vars */
|
|
268
268
|
export const isSingle = (m: Mode, d: DateType): d is Date & DateBase => m === "single"
|
|
269
269
|
export const isMultiple = (m: Mode, d: DateType): d is Date[] & DateBase => m === "multiple"
|
|
270
270
|
export const isRange = (m: Mode, d: DateType): d is DateRange & DateBase => m === "range"
|
|
271
|
-
/*
|
|
271
|
+
/* oxlint-enable eslint/no-unused-vars */
|
|
@@ -102,7 +102,7 @@ const Dialog = ({
|
|
|
102
102
|
onClose,
|
|
103
103
|
onOpen,
|
|
104
104
|
onToggle,
|
|
105
|
-
open
|
|
105
|
+
open,
|
|
106
106
|
position,
|
|
107
107
|
ref,
|
|
108
108
|
role,
|
|
@@ -190,7 +190,7 @@ const Dialog = ({
|
|
|
190
190
|
|
|
191
191
|
return (
|
|
192
192
|
<DialogContext.Provider value={{ ref: dialogRef }}>
|
|
193
|
-
{/*
|
|
193
|
+
{/*oxlint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions */}
|
|
194
194
|
<dialog
|
|
195
195
|
{...componentProps}
|
|
196
196
|
onCancel={handleCancel}
|
|
@@ -63,7 +63,7 @@ const Field = ({
|
|
|
63
63
|
|
|
64
64
|
if (child && typeof child === "object" && "type" in child) {
|
|
65
65
|
if (typeof child?.type === "function" && "slot" in child.type) {
|
|
66
|
-
const { slot } = child
|
|
66
|
+
const { slot } = child.type as { slot: SlotConfig }
|
|
67
67
|
|
|
68
68
|
slots.Control = child
|
|
69
69
|
|
|
@@ -9,7 +9,7 @@ import { hasUserBg } from "../../utils"
|
|
|
9
9
|
|
|
10
10
|
export interface PillProps extends HTMLAttributes<HTMLAnchorElement> {
|
|
11
11
|
/** **(Optional)** Specify a custom element to override default `a` or `span`. */
|
|
12
|
-
//
|
|
12
|
+
// oxlint-disable-next-line typecscript/no-explicit-any
|
|
13
13
|
as?: React.FC<any> | ForwardRefExoticComponent<any> | string
|
|
14
14
|
/** **(Optional)** Main content inside the component. It can be any valid JSX or string. */
|
|
15
15
|
children?: React.ReactNode
|
|
@@ -8,7 +8,7 @@ import { Image, ImageProps } from "../Image"
|
|
|
8
8
|
|
|
9
9
|
export interface SignpostProps extends HTMLAttributes<HTMLDivElement> {
|
|
10
10
|
/** **(Optional)** Specify a custom element to override default `a`. */
|
|
11
|
-
//
|
|
11
|
+
// oxlint-disable-next-line typecscript/no-explicit-any
|
|
12
12
|
as?: React.FC<any> | ForwardRefExoticComponent<any> | string
|
|
13
13
|
/** Main content inside the component. It can be any valid JSX or string. */
|
|
14
14
|
children: React.ReactNode
|
|
@@ -7,7 +7,7 @@ import { hasUserBg } from "../../../src/utils"
|
|
|
7
7
|
|
|
8
8
|
export interface TagProps extends HTMLAttributes<HTMLAnchorElement> {
|
|
9
9
|
/** **(Optional)** Specify a custom element to override default `a` or `span`. */
|
|
10
|
-
//
|
|
10
|
+
// oxlint-disable-next-line typecscript/no-explicit-any
|
|
11
11
|
as?: React.FC<any> | ForwardRefExoticComponent<any> | string
|
|
12
12
|
/** **(Optional)** Main content inside the component. It can be any valid JSX or string. */
|
|
13
13
|
children?: React.ReactNode
|
|
@@ -58,7 +58,7 @@ const Textarea = ({
|
|
|
58
58
|
id,
|
|
59
59
|
maxLength,
|
|
60
60
|
name,
|
|
61
|
-
onChange: userOnChange
|
|
61
|
+
onChange: userOnChange,
|
|
62
62
|
placeholder,
|
|
63
63
|
ref,
|
|
64
64
|
rows = 4,
|
|
@@ -89,7 +89,7 @@ const Textarea = ({
|
|
|
89
89
|
|
|
90
90
|
const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
|
|
91
91
|
userOnChange?.(e)
|
|
92
|
-
maxLength && e.target
|
|
92
|
+
if (maxLength && e.target) setRemaining(maxLength - e.target.value.length)
|
|
93
93
|
}
|
|
94
94
|
// const formItemProps = { "aria-disabled": disabled ? true : undefined }
|
|
95
95
|
return (
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client"
|
|
2
|
-
/*
|
|
2
|
+
/* oxlint-disable jsx-a11y/anchor-is-valid */
|
|
3
3
|
|
|
4
4
|
import type { HTMLAttributes, JSX, ReactNode, Ref } from "react"
|
|
5
5
|
|
|
@@ -84,7 +84,7 @@ const ValidationSummary = ({
|
|
|
84
84
|
React.isValidElement(slots.ValidationSummaryErrors) &&
|
|
85
85
|
Object.keys((slots.ValidationSummaryErrors.props as ValidationSummaryErrorsProps).errors ?? {})
|
|
86
86
|
|
|
87
|
-
const hasErrors =
|
|
87
|
+
const hasErrors = Object.keys(errors).length > 0
|
|
88
88
|
|
|
89
89
|
const internalRef = useRef<HTMLDivElement>(null)
|
|
90
90
|
|
package/src/hooks/useSlots.ts
CHANGED
|
@@ -8,7 +8,7 @@ export function isKey<T extends object>(x: T, k: PropertyKey): k is keyof T {
|
|
|
8
8
|
return k in x
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
//
|
|
11
|
+
// oxlint-disable-next-line typecscript/no-explicit-any
|
|
12
12
|
export function isLazy<T extends React.ComponentType<any>>(
|
|
13
13
|
type: unknown
|
|
14
14
|
): type is LazyComponent<T> {
|
package/src/types/index.ts
CHANGED
|
@@ -13,7 +13,7 @@ export interface LazyPayload<T> {
|
|
|
13
13
|
default: T
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
//
|
|
16
|
+
// oxlint-disable-next-line typecscript/no-explicit-any
|
|
17
17
|
export interface LazyComponent<T extends React.ComponentType<any>> {
|
|
18
18
|
_init: (payload: unknown) => T
|
|
19
19
|
_payload: Promise<LazyPayload<T>> | LazyPayload<T>
|
package/src/types/react.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
// oxlint-disable unicorn/require-module-specifiers
|
|
2
|
+
// oxlint-disable typescript/consistent-indexed-object-style
|
|
2
3
|
declare module "react" {
|
|
3
4
|
interface CSSProperties {
|
|
4
5
|
[key: `--${string}`]: string | number | undefined;
|
package/src/utils/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ export const bgClassToColor = (userClasses: string) => {
|
|
|
15
15
|
return /bg-([^\s]+)/.exec(userClasses)?.[1] ?? null
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
// oxlint-disable-next-line typescript/no-unnecessary-type-parameters
|
|
18
19
|
export function getSlotProp<R = unknown>(slot: React.ReactNode, prop: string): R | undefined {
|
|
19
20
|
if (isValidElement(slot) && prop in (slot.props as object)) {
|
|
20
21
|
return (slot.props as Record<string, unknown>)[prop] as R
|