@wistia/ui 1.4.0 → 1.4.1-beta.be2d93c1.3d72713
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/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +115 -25
- package/dist/index.js.map +1 -1
- package/package.json +6 -8
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
/*
|
|
3
|
-
* @license @wistia/ui v1.4.
|
|
3
|
+
* @license @wistia/ui v1.4.1-beta.be2d93c1.3d72713
|
|
4
4
|
*
|
|
5
5
|
* Copyright (c) 2024-2026, Wistia, Inc. and its affiliates.
|
|
6
6
|
*
|
|
@@ -13,12 +13,6 @@ import { createGlobalStyle, css, keyframes, styled } from "styled-components";
|
|
|
13
13
|
import { isArray, isBoolean, isDate, isEmptyString, isFunction, isNil, isNonEmptyArray, isNonEmptyString, isNotNil, isNotUndefined, isNumber, isRecord, isString, isUndefined } from "@wistia/type-guards";
|
|
14
14
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
15
15
|
import { Toaster, toast } from "sonner";
|
|
16
|
-
import { isPast } from "date-fns/isPast";
|
|
17
|
-
import { isValid } from "date-fns/isValid";
|
|
18
|
-
import { parse } from "date-fns/parse";
|
|
19
|
-
import { startOfDay } from "date-fns/startOfDay";
|
|
20
|
-
import { startOfToday } from "date-fns/startOfToday";
|
|
21
|
-
import { startOfTomorrow } from "date-fns/startOfTomorrow";
|
|
22
16
|
import { getValueAndUnit } from "polished";
|
|
23
17
|
import { useFilePicker as useFilePicker$1, useImperativeFilePicker as useImperativeFilePicker$1 } from "use-file-picker";
|
|
24
18
|
import { FileAmountLimitValidator, FileSizeValidator, FileTypeValidator, ImageDimensionsValidator, PersistentFileAmountLimitValidator } from "use-file-picker/validators";
|
|
@@ -736,17 +730,69 @@ const MONTH_NAMES = [
|
|
|
736
730
|
"November",
|
|
737
731
|
"December"
|
|
738
732
|
];
|
|
739
|
-
const
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
733
|
+
const MONTH_ABBREVIATIONS = MONTH_NAMES.map((name) => name.slice(0, 3));
|
|
734
|
+
const startOfDay = (date) => {
|
|
735
|
+
const result = new Date(date);
|
|
736
|
+
result.setHours(0, 0, 0, 0);
|
|
737
|
+
return result;
|
|
738
|
+
};
|
|
739
|
+
const startOfToday = () => startOfDay(/* @__PURE__ */ new Date());
|
|
740
|
+
const startOfTomorrow = () => {
|
|
741
|
+
const tomorrow = startOfToday();
|
|
742
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
743
|
+
return tomorrow;
|
|
744
|
+
};
|
|
745
|
+
const monthIndexIn = (names, value) => names.findIndex((name) => name.toLowerCase() === value.toLowerCase());
|
|
746
|
+
const toNumberOrUndefined = (value) => value === void 0 ? void 0 : Number(value);
|
|
747
|
+
const DATE_PATTERNS = [
|
|
748
|
+
{
|
|
749
|
+
regex: new RegExp(`^(${MONTH_ABBREVIATIONS.join("|")}) (\\d{1,2})(?:, (\\d{1,4}))?$`, "i"),
|
|
750
|
+
toParts: ([, month, day, year]) => ({
|
|
751
|
+
monthIndex: monthIndexIn(MONTH_ABBREVIATIONS, month ?? ""),
|
|
752
|
+
day: Number(day),
|
|
753
|
+
year: toNumberOrUndefined(year)
|
|
754
|
+
})
|
|
755
|
+
},
|
|
756
|
+
{
|
|
757
|
+
regex: new RegExp(`^(${MONTH_NAMES.join("|")}) (\\d{1,2})(?:, (\\d{1,4}))?$`, "i"),
|
|
758
|
+
toParts: ([, month, day, year]) => ({
|
|
759
|
+
monthIndex: monthIndexIn(MONTH_NAMES, month ?? ""),
|
|
760
|
+
day: Number(day),
|
|
761
|
+
year: toNumberOrUndefined(year)
|
|
762
|
+
})
|
|
763
|
+
},
|
|
764
|
+
{
|
|
765
|
+
regex: /^(\d{1,2})\/(\d{1,2})(?:\/(\d{1,4}))?$/,
|
|
766
|
+
toParts: ([, month, day, year]) => ({
|
|
767
|
+
monthIndex: Number(month) - 1,
|
|
768
|
+
day: Number(day),
|
|
769
|
+
year: toNumberOrUndefined(year)
|
|
770
|
+
})
|
|
771
|
+
},
|
|
772
|
+
{
|
|
773
|
+
regex: /^(\d{1,2})-(\d{1,2})(?:-(\d{1,4}))?$/,
|
|
774
|
+
toParts: ([, month, day, year]) => ({
|
|
775
|
+
monthIndex: Number(month) - 1,
|
|
776
|
+
day: Number(day),
|
|
777
|
+
year: toNumberOrUndefined(year)
|
|
778
|
+
})
|
|
779
|
+
},
|
|
780
|
+
{
|
|
781
|
+
regex: /^(\d{1,4})-(\d{1,2})-(\d{1,2})$/,
|
|
782
|
+
toParts: ([, year, month, day]) => ({
|
|
783
|
+
monthIndex: Number(month) - 1,
|
|
784
|
+
day: Number(day),
|
|
785
|
+
year: Number(year)
|
|
786
|
+
})
|
|
787
|
+
}
|
|
749
788
|
];
|
|
789
|
+
const toValidDate = ({ monthIndex, day, year }, referenceDate) => {
|
|
790
|
+
if (year === 0) return null;
|
|
791
|
+
const resolvedYear = year ?? referenceDate.getFullYear();
|
|
792
|
+
const date = new Date(referenceDate.getFullYear(), 0, 1);
|
|
793
|
+
date.setFullYear(resolvedYear, monthIndex, day);
|
|
794
|
+
return date.getFullYear() === resolvedYear && date.getMonth() === monthIndex && date.getDate() === day ? date : null;
|
|
795
|
+
};
|
|
750
796
|
const parseDateString = (str) => {
|
|
751
797
|
const trimmed = str.trim();
|
|
752
798
|
if (!trimmed) return null;
|
|
@@ -757,14 +803,19 @@ const parseDateString = (str) => {
|
|
|
757
803
|
if (monthIndex !== -1) {
|
|
758
804
|
const today = startOfToday();
|
|
759
805
|
let date = new Date(today.getFullYear(), monthIndex, 1);
|
|
760
|
-
if (
|
|
761
|
-
return
|
|
806
|
+
if (date.getTime() < Date.now()) date = new Date(today.getFullYear() + 1, monthIndex, 1);
|
|
807
|
+
return date;
|
|
762
808
|
}
|
|
763
809
|
const referenceDate = /* @__PURE__ */ new Date();
|
|
764
|
-
|
|
765
|
-
|
|
810
|
+
for (const { regex, toParts } of DATE_PATTERNS) {
|
|
811
|
+
const match = trimmed.match(regex);
|
|
812
|
+
if (match) {
|
|
813
|
+
const parsed = toValidDate(toParts(match), referenceDate);
|
|
814
|
+
if (parsed !== null) return parsed;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
766
817
|
const native = new Date(trimmed);
|
|
767
|
-
if (
|
|
818
|
+
if (!Number.isNaN(native.getTime())) return startOfDay(native);
|
|
768
819
|
return null;
|
|
769
820
|
};
|
|
770
821
|
//#endregion
|
|
@@ -811,7 +862,7 @@ const getLocalDateParts = (date) => {
|
|
|
811
862
|
//#region src/helpers/dateTime/differenceInCalendarDays.ts
|
|
812
863
|
/**
|
|
813
864
|
* Returns the difference in calendar days between two dates in local time,
|
|
814
|
-
* ignoring the time of day.
|
|
865
|
+
* ignoring the time of day.
|
|
815
866
|
*
|
|
816
867
|
* @param {Date|number} dateLeft - The later date (or timestamp).
|
|
817
868
|
* @param {Date|number} dateRight - The earlier date (or timestamp).
|
|
@@ -1426,7 +1477,7 @@ const useFocusTrap = (active = true, options = {}) => {
|
|
|
1426
1477
|
setTimeout(() => {
|
|
1427
1478
|
if (node.ownerDocument) processNode(node);
|
|
1428
1479
|
if (!node.ownerDocument) console.warn("[useFocusTrap]: The focus trap is not part of the DOM yet, so it is unable to correctly set focus. Make sure to render the ref node.", node);
|
|
1429
|
-
});
|
|
1480
|
+
}, 0);
|
|
1430
1481
|
ref.current = node;
|
|
1431
1482
|
} else ref.current = null;
|
|
1432
1483
|
}, [
|
|
@@ -5347,6 +5398,9 @@ const IconComponent = ({ useInlineStyles = true, invertColor, colorScheme = "inh
|
|
|
5347
5398
|
});
|
|
5348
5399
|
};
|
|
5349
5400
|
IconComponent.displayName = "Icon_UI";
|
|
5401
|
+
/**
|
|
5402
|
+
* An `Icon` displays a visual symbol to represent an action, concept, or entity, rendering the SVG registered for its `type` at a fixed or responsive `size`.
|
|
5403
|
+
*/
|
|
5350
5404
|
const Icon = IconComponent;
|
|
5351
5405
|
//#endregion
|
|
5352
5406
|
//#region src/components/Link/Link.tsx
|
|
@@ -5928,6 +5982,9 @@ const StyledImage = styled.img`
|
|
|
5928
5982
|
object-fit: ${({ $objFit }) => $objFit};
|
|
5929
5983
|
object-position: ${({ $objPosition }) => $objPosition};
|
|
5930
5984
|
`;
|
|
5985
|
+
/**
|
|
5986
|
+
* An `Image` displays a photo or graphic inline, with controls for border radius, object fit, and how it fills its container. It lazy-loads by default via the native `loading` attribute.
|
|
5987
|
+
*/
|
|
5931
5988
|
const Image = ({ src, alt, borderRadius, fill: fillContainer = false, fit: objFit, loading = "lazy", position: objPosition, onLoad, onError, ...props }) => /* @__PURE__ */ jsx(StyledImage, {
|
|
5932
5989
|
$borderRadius: borderRadius,
|
|
5933
5990
|
$fillContainer: fillContainer,
|
|
@@ -7285,6 +7342,9 @@ const StyledHiddenCheckboxInput = styled.input`
|
|
|
7285
7342
|
${visuallyHiddenStyle}
|
|
7286
7343
|
position: relative;
|
|
7287
7344
|
`;
|
|
7345
|
+
/**
|
|
7346
|
+
* A `Checkbox` lets users select one or more options from a set, or toggle a single option on or off. It supports both standalone controlled usage and grouped usage via `CheckboxGroup`.
|
|
7347
|
+
*/
|
|
7288
7348
|
const Checkbox = ({ checked, disabled = false, id, label, description, name, onChange, size = "md", value, required = false, hideLabel = false, ref, ...props }) => {
|
|
7289
7349
|
const generatedId = useId();
|
|
7290
7350
|
const computedId = isNonEmptyString(id) ? id : `wistia-ui-checkbox-${generatedId}`;
|
|
@@ -8550,6 +8610,9 @@ const StyledSwitchThumb = styled.div`
|
|
|
8550
8610
|
const StyledHiddenSwitchInput = styled.input`
|
|
8551
8611
|
${visuallyHiddenStyle}
|
|
8552
8612
|
`;
|
|
8613
|
+
/**
|
|
8614
|
+
* A `Switch` allows users to toggle between two mutually exclusive states, such as on and off.
|
|
8615
|
+
*/
|
|
8553
8616
|
const Switch = ({ align = "left", checked, disabled = false, id, label, description, name, onChange, size = "md", value, required = false, hideLabel = false, ref, ...props }) => {
|
|
8554
8617
|
const generatedId = useId();
|
|
8555
8618
|
const computedId = isNonEmptyString(id) ? id : `wistia-ui-switch-${generatedId}`;
|
|
@@ -9766,6 +9829,9 @@ const defaultDisplayValues = (values, onRemove) => {
|
|
|
9766
9829
|
onClickRemoveLabel: `Remove ${selectedValue}`
|
|
9767
9830
|
}, selectedValue));
|
|
9768
9831
|
};
|
|
9832
|
+
/**
|
|
9833
|
+
* A `Combobox` is a searchable single- or multi-select input. Users can filter options by typing, and selected values in multi-select mode are displayed as removable `Tag` components.
|
|
9834
|
+
*/
|
|
9769
9835
|
const Combobox = ({ placeholder, value, onChange, searchValue, onSearchValueChange, displayValues = defaultDisplayValues, children, flipPopover = true, fullWidth = true }) => {
|
|
9770
9836
|
const [isOpen, setIsOpen] = useState(false);
|
|
9771
9837
|
const [isPending, startTransition] = useTransition();
|
|
@@ -9991,13 +10057,13 @@ const ContextMenuPopup = styled(Menu$1.Popup)`
|
|
|
9991
10057
|
${menuContentCss}
|
|
9992
10058
|
outline: none;
|
|
9993
10059
|
`;
|
|
10060
|
+
const NOOP$4 = () => null;
|
|
9994
10061
|
/**
|
|
9995
10062
|
* The ContextMenu is an extended implementation of the [Menu](/components/Menu) component that allows for right-click context menus.
|
|
9996
10063
|
* It can be used in two ways:
|
|
9997
10064
|
* 1. By providing a `triggerRef`, which will render the menu when the referenced element is right-clicked.
|
|
9998
10065
|
* 2. By providing a `position` prop, which will render the menu at the specified coordinates.
|
|
9999
10066
|
*/
|
|
10000
|
-
const NOOP$4 = () => null;
|
|
10001
10067
|
const ContextMenu = ({ position, triggerRef, children, side = "bottom", onRequestClose = NOOP$4, compact = false }) => {
|
|
10002
10068
|
const [isRightClicked, setIsRightClicked] = useState(false);
|
|
10003
10069
|
const [menuPosition, setMenuPosition] = useState(position ?? {
|
|
@@ -12506,6 +12572,9 @@ const GridComponent = ({ ref, children, columns = "auto", minChildWidth = "auto"
|
|
|
12506
12572
|
children
|
|
12507
12573
|
});
|
|
12508
12574
|
};
|
|
12575
|
+
/**
|
|
12576
|
+
* A `Grid` arranges its children in a CSS grid layout with configurable `columns`, `gap`, and responsive breakpoint support.
|
|
12577
|
+
*/
|
|
12509
12578
|
const Grid = makePolymorphic(GridComponent);
|
|
12510
12579
|
//#endregion
|
|
12511
12580
|
//#region src/components/PreviewCard/PreviewCard.tsx
|
|
@@ -13514,6 +13583,9 @@ const keyToString = (key) => {
|
|
|
13514
13583
|
default: return key.toUpperCase();
|
|
13515
13584
|
}
|
|
13516
13585
|
};
|
|
13586
|
+
/**
|
|
13587
|
+
* A `KeyboardShortcut` displays one or more keyboard keys with an optional label, rendering each key in a styled `kbd` element. Platform-specific keys like `Cmd`/`Meta` are rendered with the appropriate symbol for the detected operating system.
|
|
13588
|
+
*/
|
|
13517
13589
|
const KeyboardShortcut = ({ label, keyboardKeys, fullWidth = false, ...otherProps }) => /* @__PURE__ */ jsxs(StyledKeyboardShortcut, {
|
|
13518
13590
|
$fullWidth: fullWidth,
|
|
13519
13591
|
...otherProps,
|
|
@@ -13634,6 +13706,9 @@ const renderListFromArray = (listItems, variant, otherProps) => {
|
|
|
13634
13706
|
return /* @__PURE__ */ jsx(ListItem, { children: item }, key);
|
|
13635
13707
|
}), variant, otherProps);
|
|
13636
13708
|
};
|
|
13709
|
+
/**
|
|
13710
|
+
* A `List` groups related items in bulleted, ordered, or separator-based layouts, composed with `ListItem` children or a flat/nested `items` array.
|
|
13711
|
+
*/
|
|
13637
13712
|
const List = ({ children, items, variant, ...otherProps }) => {
|
|
13638
13713
|
const listVariant = variant ?? "bullets";
|
|
13639
13714
|
if (isNotNil(children)) {
|
|
@@ -14749,6 +14824,9 @@ const StyledRadioInput = styled.div`
|
|
|
14749
14824
|
const StyledHiddenRadioInput = styled.input`
|
|
14750
14825
|
${visuallyHiddenStyle}
|
|
14751
14826
|
`;
|
|
14827
|
+
/**
|
|
14828
|
+
* A `Radio` lets users select exactly one option from a visible set of choices.
|
|
14829
|
+
*/
|
|
14752
14830
|
const Radio = ({ checked, disabled = false, id, label, description, name, onChange, size = "md", value = "false", required = false, hideLabel = false, ref, ...props }) => {
|
|
14753
14831
|
const generatedId = useId();
|
|
14754
14832
|
const computedId = isNonEmptyString(id) ? id : `wistia-ui-radio-${generatedId}`;
|
|
@@ -15032,6 +15110,9 @@ const RadioCardDefaultLayout = ({ icon, label, description, showIndicator = true
|
|
|
15032
15110
|
RadioCardDefaultLayout.displayName = "RadioCardDefaultLayout_UI";
|
|
15033
15111
|
//#endregion
|
|
15034
15112
|
//#region src/components/RadioCard/RadioCard.tsx
|
|
15113
|
+
/**
|
|
15114
|
+
* A `RadioCard` lets users select exactly one option from a set of visually rich, card-based choices.
|
|
15115
|
+
*/
|
|
15035
15116
|
const RadioCard = ({ icon, label, description, showIndicator, isGated, children, ref, ...rootProps }) => {
|
|
15036
15117
|
return /* @__PURE__ */ jsx(RadioCardRoot, {
|
|
15037
15118
|
ref,
|
|
@@ -15652,6 +15733,9 @@ const StyledSidebar = styled.nav`
|
|
|
15652
15733
|
overflow: hidden;
|
|
15653
15734
|
border-right: 1px solid var(--wui-color-border);
|
|
15654
15735
|
`;
|
|
15736
|
+
/**
|
|
15737
|
+
* The `Sidebar` provides vertical navigation with a composable header, scrollable content area, and footer.
|
|
15738
|
+
*/
|
|
15655
15739
|
const Sidebar = ({ children, ref, ...props }) => {
|
|
15656
15740
|
return /* @__PURE__ */ jsx(StyledSidebar, {
|
|
15657
15741
|
ref,
|
|
@@ -15895,6 +15979,9 @@ const StyledSliderThumb = styled(Slider$1.Thumb)`
|
|
|
15895
15979
|
}
|
|
15896
15980
|
`;
|
|
15897
15981
|
const DEFAULT_INITIAL_VALUE = [0];
|
|
15982
|
+
/**
|
|
15983
|
+
* A `Slider` lets users select a value or range from a continuous scale via a draggable thumb.
|
|
15984
|
+
*/
|
|
15898
15985
|
const Slider = ({ "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, disabled = false, initialValue = DEFAULT_INITIAL_VALUE, max = 100, min = 0, onChange, onValueCommitted, step = 1, value, "data-testid": dataTestId = "ui-slider", ...otherProps }) => {
|
|
15899
15986
|
if (!(isNonEmptyString(ariaLabel) || isNonEmptyString(ariaLabelledby))) throw new Error("UI Slider: Sliders should have an accessible name. Add a label using the aria-label or aria-labelledby prop.");
|
|
15900
15987
|
const values = value ?? initialValue;
|
|
@@ -16122,6 +16209,9 @@ const useTabsValue = () => {
|
|
|
16122
16209
|
};
|
|
16123
16210
|
//#endregion
|
|
16124
16211
|
//#region src/components/Tabs/Tabs.tsx
|
|
16212
|
+
/**
|
|
16213
|
+
* The `Tabs` component lets users switch between panels of content. It is composed from the `TabsList`, `TabsTrigger`, and `TabsContent` subcomponents.
|
|
16214
|
+
*/
|
|
16125
16215
|
const Tabs = ({ children, value: valueProp, onValueChange: onValueChangeProp, defaultValue, ...props }) => {
|
|
16126
16216
|
const [internalValue, setInternalValue] = useState(valueProp ?? defaultValue);
|
|
16127
16217
|
const isControlled = isNotNil(valueProp);
|