@fibery/ui-kit 1.40.4 → 1.41.0
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/CHANGELOG.md +6 -0
- package/eslint.config.mjs +16 -0
- package/package.json +8 -7
- package/src/a11y-color.test.ts +5 -24
- package/src/actions-menu/actions-menu-item.tsx +6 -9
- package/src/actions-menu/context-actions-menu.tsx +8 -3
- package/src/ai/model.tsx +0 -1
- package/src/ai/temperature.tsx +0 -1
- package/src/animated-height-container.tsx +3 -3
- package/src/antd/index.tsx +3 -0
- package/src/antd/input.tsx +0 -1
- package/src/antd/styles.ts +9 -9
- package/src/app-icon-with-fallback.tsx +5 -5
- package/src/app-icon-wrapper.tsx +2 -3
- package/src/app-icon.tsx +3 -3
- package/src/avatar.tsx +3 -3
- package/src/button/base-button.tsx +0 -1
- package/src/button/make-button-colors.ts +2 -2
- package/src/checkbox.tsx +1 -1
- package/src/collapsible-section.tsx +11 -1
- package/src/color-utils.test.ts +15 -25
- package/src/color-utils.ts +43 -8
- package/src/command-menu/index.tsx +1 -0
- package/src/context-menu/index.tsx +5 -5
- package/src/date-picker/contexts.ts +2 -2
- package/src/date-picker/date-range-picker.tsx +3 -4
- package/src/date-picker/single-date-picker.tsx +147 -119
- package/src/date-picker/types.ts +4 -3
- package/src/day-select/iso-week-day-select.tsx +2 -2
- package/src/day-select/week-day-select.tsx +2 -2
- package/src/delayed.tsx +0 -1
- package/src/design-system/alpha.test.ts +59 -0
- package/src/design-system/alpha.ts +41 -0
- package/src/design-system/animation.ts +10 -0
- package/src/design-system/colors-css.test.ts +39 -0
- package/src/design-system/colors-css.ts +25 -0
- package/src/design-system/colors-js.test.ts +232 -0
- package/src/design-system/colors-js.ts +107 -0
- package/src/design-system/colors.test.ts +74 -0
- package/src/{design-system.colors.ts → design-system/colors.ts} +133 -134
- package/src/design-system/date.ts +3 -0
- package/src/design-system/layout.ts +106 -0
- package/src/design-system/theme.test.ts +94 -0
- package/src/design-system/theme.ts +93 -0
- package/src/design-system/typography.ts +179 -0
- package/src/design-system/vars.test.ts +1679 -0
- package/src/design-system/vars.ts +52 -0
- package/src/design-system.test.ts +46 -303
- package/src/design-system.ts +25 -545
- package/src/dropdown-menu/index.tsx +5 -5
- package/src/emoji-picker/icon-emoji-picker.tsx +1 -1
- package/src/fibermoji-placeholder.tsx +3 -3
- package/src/field-container.tsx +11 -2
- package/src/file-item/file-icon.tsx +3 -3
- package/src/file-item-2.tsx +4 -10
- package/src/file-item.tsx +0 -1
- package/src/icons/ast/ChatBubble.ts +8 -0
- package/src/icons/ast/ChatFloat.ts +8 -0
- package/src/icons/ast/ChatSidebar.ts +8 -0
- package/src/icons/ast/FileOther.ts +8 -0
- package/src/icons/ast/NoBorder.ts +8 -0
- package/src/icons/ast/NoFill.ts +8 -0
- package/src/icons/ast/index.tsx +6 -0
- package/src/icons/react/ChatBubble.tsx +13 -0
- package/src/icons/react/ChatFloat.tsx +13 -0
- package/src/icons/react/ChatSidebar.tsx +13 -0
- package/src/icons/react/FileOther.tsx +13 -0
- package/src/icons/react/NoBorder.tsx +13 -0
- package/src/icons/react/NoFill.tsx +13 -0
- package/src/icons/react/index.tsx +6 -0
- package/src/icons/svg/chat-bubble.svg +4 -0
- package/src/icons/svg/chat-float.svg +4 -0
- package/src/icons/svg/chat-sidebar.svg +4 -0
- package/src/icons/svg/file-other.svg +3 -0
- package/src/icons/svg/no-border.svg +17 -0
- package/src/icons/svg/no-fill.svg +4 -0
- package/src/images-gallery/images-gallery.tsx +8 -6
- package/src/images-gallery/slide-buttons.tsx +2 -2
- package/src/is-iOS.ts +0 -1
- package/src/is-in-popup.ts +2 -1
- package/src/lists/actions-menu-row-surface.tsx +4 -4
- package/src/loading-sausage.tsx +2 -2
- package/src/media-query-utils.ts +1 -2
- package/src/mobile-keyboard-aware-popup.tsx +2 -2
- package/src/modal-menu/modal-menu-content.tsx +2 -2
- package/src/number-input/decimal.js +9 -7
- package/src/number-input/{number-inline-input-with-autosize.tsx → number-input-inline-with-autosize.tsx} +20 -41
- package/src/number-input/number-input-inline.tsx +118 -0
- package/src/number-input/{index.test.js → number-input.test.tsx} +38 -43
- package/src/number-input/number-input.tsx +63 -121
- package/src/number-input/types.ts +19 -0
- package/src/number-input/utils.ts +61 -0
- package/src/online-users.tsx +2 -2
- package/src/palette-generator.test.ts +24 -281
- package/src/palette-generator.ts +39 -45
- package/src/palettes/_.ts +72 -0
- package/src/palettes/slate-arch.colors-snapshot.test.ts +1689 -0
- package/src/palettes/slate-arch.ts +188 -0
- package/src/palettes/slate-user.colors-snapshot.test.ts +1689 -0
- package/src/palettes/slate-user.ts +187 -0
- package/src/palettes/warm-arch.colors-snapshot.test.ts +1689 -0
- package/src/palettes/warm-arch.ts +222 -0
- package/src/palettes/warm-user.colors-snapshot.test.ts +1689 -0
- package/src/palettes/warm-user.ts +222 -0
- package/src/popover/get-element-ref.ts +28 -0
- package/src/popover/index.tsx +232 -333
- package/src/popover/{mobile-popup-context.tsx → mobile-popover-context.tsx} +7 -7
- package/src/popover/mobile-popover.tsx +169 -0
- package/src/popover/modifiers.tsx +2 -2
- package/src/popover/popup-stack-context.tsx +8 -9
- package/src/root-theme-provider.test.tsx +114 -19
- package/src/scale-generator.ts +31 -22
- package/src/select/components/menu-list-virtualized.tsx +5 -3
- package/src/select/index.tsx +6 -5
- package/src/select/select.tsx +36 -38
- package/src/select/util.ts +1 -1
- package/src/static-palettes.ts +221 -11
- package/src/thematic-controls.tsx +6 -6
- package/src/thematic-scales.tsx +15 -15
- package/src/thematic-state.ts +57 -20
- package/src/thematic.tsx +36 -32
- package/src/theme-provider.test.tsx +31 -19
- package/src/theme-provider.tsx +41 -38
- package/src/theme-settings.ts +66 -11
- package/src/theme-styles.ts +53 -8
- package/src/toast/toast.tsx +1 -2
- package/src/toggle.tsx +2 -2
- package/src/tooltip.tsx +4 -3
- package/src/type-badge.tsx +4 -11
- package/src/unit/styles.ts +0 -23
- package/src/use-is-phone.tsx +7 -2
- package/src/use-on-screen-keyboard-data.tsx +2 -2
- package/src/with-data.tsx +4 -3
- package/src/workflow-progress-icon.tsx +2 -2
- package/.eslintignore +0 -3
- package/.eslintrc +0 -14
- package/src/__mocks__/createInlineTheme.js +0 -3
- package/src/__snapshots__/design-system.test.ts.snap +0 -7265
- package/src/create-inline-theme.ts +0 -67
- package/src/number-input/index.js +0 -191
- package/src/palette.ts +0 -253
package/src/color-utils.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {Coords, PlainColorObject} from "colorjs.io/fn";
|
|
2
2
|
import {
|
|
3
3
|
ColorSpace,
|
|
4
4
|
contrastWCAG21,
|
|
@@ -25,13 +25,22 @@ ColorSpace.register(LCH);
|
|
|
25
25
|
ColorSpace.register(OKLCH);
|
|
26
26
|
ColorSpace.register(P3);
|
|
27
27
|
|
|
28
|
-
type Color = PlainColorObject
|
|
28
|
+
type Color = PlainColorObject;
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
// FIXME consolidate as common util
|
|
31
|
+
const isFlagPresent = (flag: string) => globalThis.window && new RegExp(`[?&]${flag}\\b`).test(window.location.search);
|
|
32
|
+
|
|
33
|
+
const defaultColorSpace = isFlagPresent("oklch") ? OKLCH : sRGB;
|
|
34
|
+
|
|
35
|
+
function colorSafe(
|
|
36
|
+
color: string,
|
|
37
|
+
fallback = "hsl(220, 62%, 56%)" /* formerly brandColor.blue, currently accent[9] */,
|
|
38
|
+
space: ColorSpace = defaultColorSpace
|
|
39
|
+
): Color {
|
|
31
40
|
try {
|
|
32
|
-
return
|
|
41
|
+
return to(color, space);
|
|
33
42
|
} catch {
|
|
34
|
-
return
|
|
43
|
+
return to(fallback, space);
|
|
35
44
|
}
|
|
36
45
|
}
|
|
37
46
|
|
|
@@ -51,8 +60,12 @@ function serializesRGB(color: Color): string {
|
|
|
51
60
|
|
|
52
61
|
type ColorTransform = (color: PlainColorObject) => PlainColorObject | void;
|
|
53
62
|
|
|
54
|
-
export function produceColor(
|
|
55
|
-
|
|
63
|
+
export function produceColor(
|
|
64
|
+
color: string,
|
|
65
|
+
transforms: ColorTransform | ColorTransform[],
|
|
66
|
+
space: ColorSpace = defaultColorSpace
|
|
67
|
+
): string {
|
|
68
|
+
let c = colorSafe(color);
|
|
56
69
|
for (const transform of Array.isArray(transforms) ? transforms : [transforms]) {
|
|
57
70
|
const result = transform(c);
|
|
58
71
|
if (result !== undefined) {
|
|
@@ -61,7 +74,7 @@ export function produceColor(color: string, transforms: ColorTransform | ColorTr
|
|
|
61
74
|
}
|
|
62
75
|
// TODO make sRGB default space and apply colorjs.io outputs CSS Level 4 format (rgb(100% 0% 0%))
|
|
63
76
|
// instead of compatible format (rgb(255,0,0))
|
|
64
|
-
if (space ===
|
|
77
|
+
if (space === sRGB) {
|
|
65
78
|
return serializesRGB(c);
|
|
66
79
|
}
|
|
67
80
|
return serialize(to(c, space));
|
|
@@ -161,6 +174,10 @@ export function toOKLCH(color: string) {
|
|
|
161
174
|
return produceColor(color, [], OKLCH);
|
|
162
175
|
}
|
|
163
176
|
|
|
177
|
+
export function toRGB(color: string) {
|
|
178
|
+
return produceColor(color, [], sRGB);
|
|
179
|
+
}
|
|
180
|
+
|
|
164
181
|
export function getHsl(color: string): [number, number, number] {
|
|
165
182
|
const c = to(colorSafe(color), HSL);
|
|
166
183
|
return [c.coords[0] || 0, (c.coords[1] || 0) / 100, (c.coords[2] || 0) / 100];
|
|
@@ -177,4 +194,22 @@ export function toCss(color: string): string {
|
|
|
177
194
|
return produceColor(color, []);
|
|
178
195
|
}
|
|
179
196
|
|
|
197
|
+
/**
|
|
198
|
+
* @deprecated use toCss instead
|
|
199
|
+
*/
|
|
200
|
+
export function toHex(color: string): string {
|
|
201
|
+
const c = toGamut(to(colorSafe(color), sRGB), {space: sRGB});
|
|
202
|
+
const r = Math.round(clamp01(c.coords[0]) * 255);
|
|
203
|
+
const g = Math.round(clamp01(c.coords[1]) * 255);
|
|
204
|
+
const b = Math.round(clamp01(c.coords[2]) * 255);
|
|
205
|
+
const a = c.alpha ?? 1;
|
|
206
|
+
const hex = "#" + [r, g, b].map((v) => v.toString(16).padStart(2, "0")).join("");
|
|
207
|
+
return a < 1
|
|
208
|
+
? hex +
|
|
209
|
+
Math.round(a * 255)
|
|
210
|
+
.toString(16)
|
|
211
|
+
.padStart(2, "0")
|
|
212
|
+
: hex;
|
|
213
|
+
}
|
|
214
|
+
|
|
180
215
|
export {ColorSpace, mix, OKLCH, parse, set, sRGB, to, HSL, Lab, LCH};
|
|
@@ -4,7 +4,7 @@ import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
|
|
|
4
4
|
import {forwardRef} from "react";
|
|
5
5
|
import {border, layout, space, textStyles, themeVars} from "../design-system";
|
|
6
6
|
import {mobileRootSelector} from "../mobile-styles";
|
|
7
|
-
import {
|
|
7
|
+
import {RadixPortalThemeProvider} from "../theme-provider";
|
|
8
8
|
|
|
9
9
|
export const Root = (contextMenuProps: ContextMenuPrimitive.ContextMenuProps) => (
|
|
10
10
|
<ContextMenuPrimitive.Root dir="ltr" {...contextMenuProps} />
|
|
@@ -95,14 +95,14 @@ export type ContentProps = ContextMenuPrimitive.ContextMenuContentProps;
|
|
|
95
95
|
export const Content = forwardRef<HTMLDivElement, ContentProps>(function ContextMenuContent({className, ...rest}, ref) {
|
|
96
96
|
return (
|
|
97
97
|
<ContextMenuPrimitive.Portal>
|
|
98
|
-
<
|
|
98
|
+
<RadixPortalThemeProvider>
|
|
99
99
|
<ContextMenuPrimitive.Content
|
|
100
100
|
ref={ref}
|
|
101
101
|
className={cx(dropdownMenuContentStyles, className)}
|
|
102
102
|
collisionPadding={space.s12 + space.s8}
|
|
103
103
|
{...rest}
|
|
104
104
|
/>
|
|
105
|
-
</
|
|
105
|
+
</RadixPortalThemeProvider>
|
|
106
106
|
</ContextMenuPrimitive.Portal>
|
|
107
107
|
);
|
|
108
108
|
});
|
|
@@ -135,9 +135,9 @@ export const SubContent = forwardRef<HTMLDivElement, ContextMenuPrimitive.Contex
|
|
|
135
135
|
function DropdownMenuSubContent({className, ...rest}, ref) {
|
|
136
136
|
return (
|
|
137
137
|
<ContextMenuPrimitive.Portal>
|
|
138
|
-
<
|
|
138
|
+
<RadixPortalThemeProvider>
|
|
139
139
|
<ContextMenuPrimitive.SubContent ref={ref} className={cx(dropdownMenuContentStyles, className)} {...rest} />
|
|
140
|
-
</
|
|
140
|
+
</RadixPortalThemeProvider>
|
|
141
141
|
</ContextMenuPrimitive.Portal>
|
|
142
142
|
);
|
|
143
143
|
}
|
|
@@ -7,7 +7,7 @@ import {css} from "@linaria/core";
|
|
|
7
7
|
import "react-day-picker/dist/style.css";
|
|
8
8
|
import {stopPropagation} from "@fibery/react/src/stop-propagation";
|
|
9
9
|
import {forwardRef, useCallback, useRef} from "react";
|
|
10
|
-
import
|
|
10
|
+
import omit from "lodash/omit";
|
|
11
11
|
import moment from "moment";
|
|
12
12
|
import {FakeDateInputWrapper} from "./fake-date-input";
|
|
13
13
|
import {formatDateRangeInputValue} from "./utils";
|
|
@@ -27,7 +27,6 @@ export const DateRangePicker = forwardRef<
|
|
|
27
27
|
bypassedRef,
|
|
28
28
|
value,
|
|
29
29
|
disabled = false,
|
|
30
|
-
renderInPortal = true,
|
|
31
30
|
onChange,
|
|
32
31
|
showTime = false,
|
|
33
32
|
dateFormat,
|
|
@@ -107,14 +106,14 @@ export const DateRangePicker = forwardRef<
|
|
|
107
106
|
popupContainerClassName={css`
|
|
108
107
|
z-index: 10001;
|
|
109
108
|
`}
|
|
110
|
-
renderInPortal={
|
|
109
|
+
renderInPortal={true}
|
|
111
110
|
preventOverflowOptions={{
|
|
112
111
|
altAxis: true,
|
|
113
112
|
}}
|
|
114
113
|
>
|
|
115
114
|
<DateRangePickerPopupContent
|
|
116
115
|
ref={ref}
|
|
117
|
-
{...
|
|
116
|
+
{...omit(props, ["onChange", "value"])}
|
|
118
117
|
onChange={onDatesChange}
|
|
119
118
|
value={dateValue}
|
|
120
119
|
onKeyDown={onDatePickerKeyDown}
|
|
@@ -1,17 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ControlledDatePickerProps,
|
|
3
|
+
RelativeDateValue,
|
|
4
|
+
SingleDatePickerPopoverContentProps,
|
|
5
|
+
SingleDatePickerProps,
|
|
6
|
+
} from "./types";
|
|
2
7
|
import {FakeDateInputWrapper} from "./fake-date-input";
|
|
3
8
|
import {space, themeVars} from "../design-system";
|
|
4
9
|
import {withPopupControl} from "./with-popup-control";
|
|
5
|
-
import {css} from "@linaria/core";
|
|
10
|
+
import {css, cx} from "@linaria/core";
|
|
6
11
|
import "react-day-picker/dist/style.css";
|
|
7
12
|
import {SingleDatePickerPopupContent} from "./single-date-picker-popup-content";
|
|
8
13
|
import {stopPropagation} from "@fibery/react/src/stop-propagation";
|
|
9
14
|
import {forwardRef, useCallback, useRef, useState} from "react";
|
|
10
15
|
import moment, {Moment} from "moment";
|
|
11
|
-
import
|
|
16
|
+
import omit from "lodash/omit";
|
|
12
17
|
import {EmptyValue} from "../empty-value";
|
|
13
18
|
import {formatDateInputValue} from "./utils";
|
|
14
|
-
import {
|
|
19
|
+
import {Popover} from "../popover";
|
|
15
20
|
import {focusable} from "tabbable";
|
|
16
21
|
import {TabNavLink, TabNavList, TabNavRoot} from "../tab-nav/tab-nav";
|
|
17
22
|
import {RelativeDatePicker} from "./relative-date-picker";
|
|
@@ -69,43 +74,18 @@ interface ControlledSingleDatePickerWithForwardRefType extends React.FC<Uncontro
|
|
|
69
74
|
>;
|
|
70
75
|
}
|
|
71
76
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
type DatePickerRef = {
|
|
78
|
+
setValue: (value: string) => void;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const SingleDatePickerPopoverContent = forwardRef<
|
|
82
|
+
DatePickerRef,
|
|
83
|
+
{className?: string} & SingleDatePickerPopoverContentProps<boolean>
|
|
77
84
|
>((props, ref) => {
|
|
78
|
-
const {
|
|
79
|
-
title,
|
|
80
|
-
open,
|
|
81
|
-
onOpen,
|
|
82
|
-
onClose,
|
|
83
|
-
children,
|
|
84
|
-
bypassedRef,
|
|
85
|
-
value,
|
|
86
|
-
disabled = false,
|
|
87
|
-
placeholder,
|
|
88
|
-
renderInPortal = true,
|
|
89
|
-
onChange,
|
|
90
|
-
showTime = false,
|
|
91
|
-
dateFormat,
|
|
92
|
-
dateTimeFormat,
|
|
93
|
-
onKeyDown,
|
|
94
|
-
allowRelativeDate = false,
|
|
95
|
-
relativeDateToExactDate,
|
|
96
|
-
} = props;
|
|
85
|
+
const {className, value, onChange, onKeyDown, allowRelativeDate = false, relativeDateToExactDate} = props;
|
|
97
86
|
|
|
98
87
|
const isRelativeValue = allowRelativeDate ? isRelativeDatePlaceholder(value) : false;
|
|
99
88
|
|
|
100
|
-
const dateValueFormatted = isRelativeValue
|
|
101
|
-
? formatRelativeDate(value as RelativeDateValue)
|
|
102
|
-
: value
|
|
103
|
-
? formatDateInputValue((value as Moment).toDate(), {
|
|
104
|
-
showTime,
|
|
105
|
-
dateFormat,
|
|
106
|
-
dateTimeFormat,
|
|
107
|
-
})
|
|
108
|
-
: null;
|
|
109
89
|
const onDateChange = useCallback(
|
|
110
90
|
(value: Date | null) => {
|
|
111
91
|
// @ts-expect-error fix types
|
|
@@ -124,12 +104,6 @@ export const SingleDatePicker: SingleDatePickerWithForwardRefType = forwardRef<
|
|
|
124
104
|
|
|
125
105
|
const fakeWrapperRef = useRef<HTMLDivElement>(null);
|
|
126
106
|
|
|
127
|
-
const pickerValue = children || (
|
|
128
|
-
<FakeDateInputWrapper disabled={disabled} isPickerOpen={open}>
|
|
129
|
-
{!dateValueFormatted ? <EmptyValue>{placeholder}</EmptyValue> : <>{dateValueFormatted}</>}
|
|
130
|
-
</FakeDateInputWrapper>
|
|
131
|
-
);
|
|
132
|
-
|
|
133
107
|
const onDatePickerKeyDown = useCallback(
|
|
134
108
|
(e: React.KeyboardEvent<HTMLInputElement>) => {
|
|
135
109
|
if (e.key === "Tab" || e.key === "Enter") {
|
|
@@ -151,93 +125,147 @@ export const SingleDatePicker: SingleDatePickerWithForwardRefType = forwardRef<
|
|
|
151
125
|
allowRelativeDate && (isRelativeValue || value === null) ? "relative" : "exact"
|
|
152
126
|
);
|
|
153
127
|
|
|
128
|
+
return (
|
|
129
|
+
<div
|
|
130
|
+
className={cx(
|
|
131
|
+
css`
|
|
132
|
+
display: flex;
|
|
133
|
+
flex-direction: column;
|
|
134
|
+
`,
|
|
135
|
+
allowRelativeDate &&
|
|
136
|
+
css`
|
|
137
|
+
min-width: 320px;
|
|
138
|
+
`,
|
|
139
|
+
className
|
|
140
|
+
)}
|
|
141
|
+
>
|
|
142
|
+
{allowRelativeDate ? (
|
|
143
|
+
<div
|
|
144
|
+
className={css`
|
|
145
|
+
border-bottom: ${themeVars.separators.opacity5};
|
|
146
|
+
`}
|
|
147
|
+
>
|
|
148
|
+
<TabNavRoot>
|
|
149
|
+
<TabNavList
|
|
150
|
+
className={css`
|
|
151
|
+
padding-left: ${space.s12}px;
|
|
152
|
+
padding-right: ${space.s12}px;
|
|
153
|
+
padding-top: ${space.s6}px;
|
|
154
|
+
display: flex;
|
|
155
|
+
width: 100%;
|
|
156
|
+
justify-content: space-evenly;
|
|
157
|
+
`}
|
|
158
|
+
>
|
|
159
|
+
<TabNavLink
|
|
160
|
+
className={tabNavLinkClassName}
|
|
161
|
+
itemClassName={tabItemClassName}
|
|
162
|
+
active={activeButton === "relative"}
|
|
163
|
+
onSelect={() => setActiveButton("relative")}
|
|
164
|
+
>
|
|
165
|
+
Relative
|
|
166
|
+
</TabNavLink>
|
|
167
|
+
<TabNavLink
|
|
168
|
+
className={tabNavLinkClassName}
|
|
169
|
+
itemClassName={tabItemClassName}
|
|
170
|
+
active={activeButton === "exact"}
|
|
171
|
+
onSelect={() => setActiveButton("exact")}
|
|
172
|
+
>
|
|
173
|
+
Exact
|
|
174
|
+
</TabNavLink>
|
|
175
|
+
</TabNavList>
|
|
176
|
+
</TabNavRoot>
|
|
177
|
+
</div>
|
|
178
|
+
) : null}
|
|
179
|
+
<div>
|
|
180
|
+
{!allowRelativeDate || activeButton === "exact" ? (
|
|
181
|
+
<SingleDatePickerPopupContent
|
|
182
|
+
ref={ref}
|
|
183
|
+
{...omit(props, ["onChange", "value"])}
|
|
184
|
+
onChange={onDateChange}
|
|
185
|
+
value={!isRelativeValue && value ? (value as Moment).toDate() : null}
|
|
186
|
+
onKeyDown={onDatePickerKeyDown}
|
|
187
|
+
/>
|
|
188
|
+
) : (
|
|
189
|
+
<RelativeDatePicker
|
|
190
|
+
value={isRelativeValue ? (value as RelativeDateValue) : null}
|
|
191
|
+
onChange={onRelativeDateChange}
|
|
192
|
+
relativeDateToExactDate={relativeDateToExactDate}
|
|
193
|
+
/>
|
|
194
|
+
)}
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
export const SingleDatePicker: SingleDatePickerWithForwardRefType = forwardRef<
|
|
201
|
+
DatePickerRef,
|
|
202
|
+
SingleDatePickerProps<boolean>
|
|
203
|
+
>((props, ref) => {
|
|
204
|
+
const {
|
|
205
|
+
title,
|
|
206
|
+
open,
|
|
207
|
+
onOpen,
|
|
208
|
+
onClose,
|
|
209
|
+
children,
|
|
210
|
+
bypassedRef,
|
|
211
|
+
value,
|
|
212
|
+
disabled = false,
|
|
213
|
+
placeholder,
|
|
214
|
+
showTime = false,
|
|
215
|
+
dateFormat,
|
|
216
|
+
dateTimeFormat,
|
|
217
|
+
allowRelativeDate = false,
|
|
218
|
+
} = props;
|
|
219
|
+
|
|
220
|
+
const isRelativeValue = allowRelativeDate ? isRelativeDatePlaceholder(value) : false;
|
|
221
|
+
|
|
222
|
+
const dateValueFormatted = isRelativeValue
|
|
223
|
+
? formatRelativeDate(value as RelativeDateValue)
|
|
224
|
+
: value
|
|
225
|
+
? formatDateInputValue((value as Moment).toDate(), {
|
|
226
|
+
showTime,
|
|
227
|
+
dateFormat,
|
|
228
|
+
dateTimeFormat,
|
|
229
|
+
})
|
|
230
|
+
: null;
|
|
231
|
+
|
|
232
|
+
const fakeWrapperRef = useRef<HTMLDivElement>(null);
|
|
233
|
+
|
|
234
|
+
const pickerValue = children || (
|
|
235
|
+
<FakeDateInputWrapper disabled={disabled} isPickerOpen={open}>
|
|
236
|
+
{!dateValueFormatted ? <EmptyValue>{placeholder}</EmptyValue> : <>{dateValueFormatted}</>}
|
|
237
|
+
</FakeDateInputWrapper>
|
|
238
|
+
);
|
|
239
|
+
|
|
154
240
|
if (disabled) {
|
|
155
241
|
return pickerValue;
|
|
156
242
|
}
|
|
157
243
|
|
|
158
244
|
return (
|
|
159
245
|
<div ref={bypassedRef}>
|
|
160
|
-
<
|
|
161
|
-
|
|
162
|
-
offset={[0, space.s6]}
|
|
163
|
-
trigger={
|
|
246
|
+
<Popover.Root open={open} onOpen={onOpen} onClose={onClose}>
|
|
247
|
+
<Popover.Trigger>
|
|
164
248
|
<div ref={fakeWrapperRef} onClick={stopPropagation}>
|
|
165
249
|
{pickerValue}
|
|
166
250
|
</div>
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
renderInPortal={renderInPortal}
|
|
177
|
-
preventOverflowOptions={{
|
|
178
|
-
altAxis: true,
|
|
179
|
-
}}
|
|
180
|
-
>
|
|
181
|
-
{allowRelativeDate ? (
|
|
182
|
-
<div
|
|
183
|
-
className={css`
|
|
184
|
-
border-bottom: ${themeVars.separators.opacity5};
|
|
251
|
+
</Popover.Trigger>
|
|
252
|
+
<Popover.Portal>
|
|
253
|
+
<Popover.Content
|
|
254
|
+
title={title}
|
|
255
|
+
offset={[0, space.s6]}
|
|
256
|
+
placement="bottom-start"
|
|
257
|
+
supportMobile
|
|
258
|
+
popupContainerClassName={css`
|
|
259
|
+
z-index: 10001;
|
|
185
260
|
`}
|
|
261
|
+
preventOverflowOptions={{
|
|
262
|
+
altAxis: true,
|
|
263
|
+
}}
|
|
186
264
|
>
|
|
187
|
-
<
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
padding-right: ${space.s12}px;
|
|
192
|
-
padding-top: ${space.s6}px;
|
|
193
|
-
display: flex;
|
|
194
|
-
width: 100%;
|
|
195
|
-
justify-content: space-evenly;
|
|
196
|
-
`}
|
|
197
|
-
>
|
|
198
|
-
<TabNavLink
|
|
199
|
-
className={tabNavLinkClassName}
|
|
200
|
-
itemClassName={tabItemClassName}
|
|
201
|
-
active={activeButton === "relative"}
|
|
202
|
-
onSelect={() => setActiveButton("relative")}
|
|
203
|
-
>
|
|
204
|
-
Relative
|
|
205
|
-
</TabNavLink>
|
|
206
|
-
<TabNavLink
|
|
207
|
-
className={tabNavLinkClassName}
|
|
208
|
-
itemClassName={tabItemClassName}
|
|
209
|
-
active={activeButton === "exact"}
|
|
210
|
-
onSelect={() => setActiveButton("exact")}
|
|
211
|
-
>
|
|
212
|
-
Exact
|
|
213
|
-
</TabNavLink>
|
|
214
|
-
</TabNavList>
|
|
215
|
-
</TabNavRoot>
|
|
216
|
-
</div>
|
|
217
|
-
) : null}
|
|
218
|
-
<div
|
|
219
|
-
style={allowRelativeDate ? {minWidth: 320} : undefined}
|
|
220
|
-
className={css`
|
|
221
|
-
width: 100%;
|
|
222
|
-
`}
|
|
223
|
-
>
|
|
224
|
-
{!allowRelativeDate || activeButton === "exact" ? (
|
|
225
|
-
<SingleDatePickerPopupContent
|
|
226
|
-
ref={ref}
|
|
227
|
-
{..._.omit(props, ["onChange", "value"])}
|
|
228
|
-
onChange={onDateChange}
|
|
229
|
-
value={!isRelativeValue && value ? (value as Moment).toDate() : null}
|
|
230
|
-
onKeyDown={onDatePickerKeyDown}
|
|
231
|
-
/>
|
|
232
|
-
) : (
|
|
233
|
-
<RelativeDatePicker
|
|
234
|
-
value={isRelativeValue ? (value as RelativeDateValue) : null}
|
|
235
|
-
onChange={onRelativeDateChange}
|
|
236
|
-
relativeDateToExactDate={relativeDateToExactDate}
|
|
237
|
-
/>
|
|
238
|
-
)}
|
|
239
|
-
</div>
|
|
240
|
-
</PopoverOld>
|
|
265
|
+
<SingleDatePickerPopoverContent ref={ref} {...props} />
|
|
266
|
+
</Popover.Content>
|
|
267
|
+
</Popover.Portal>
|
|
268
|
+
</Popover.Root>
|
|
241
269
|
</div>
|
|
242
270
|
);
|
|
243
271
|
});
|
package/src/date-picker/types.ts
CHANGED
|
@@ -27,7 +27,6 @@ export type DatePickerCommonProps = {
|
|
|
27
27
|
allowClear?: boolean;
|
|
28
28
|
bypassedRef?: React.Ref<$TSFixMe>;
|
|
29
29
|
disabled?: boolean;
|
|
30
|
-
renderInPortal?: boolean;
|
|
31
30
|
onKeyDown?: React.KeyboardEventHandler<$TSFixMe>;
|
|
32
31
|
placeholder: string;
|
|
33
32
|
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | undefined;
|
|
@@ -49,10 +48,12 @@ export type NativeDateRangePickerProps = {
|
|
|
49
48
|
|
|
50
49
|
export type ControlledDatePickerProps = {open: boolean; onOpen: () => void; onClose: () => void};
|
|
51
50
|
|
|
52
|
-
export type
|
|
53
|
-
ControlledDatePickerProps &
|
|
51
|
+
export type SingleDatePickerPopoverContentProps<IsRelativeDate extends boolean = false> = DatePickerCommonProps &
|
|
54
52
|
MomentSingleDateProps<IsRelativeDate> & {
|
|
55
53
|
allowRelativeDate?: IsRelativeDate;
|
|
56
54
|
} & (IsRelativeDate extends true
|
|
57
55
|
? {relativeDateToExactDate?: (value: RelativeDateValue) => string} // Required if IsRelativeDate is true
|
|
58
56
|
: {relativeDateToExactDate?: never}); // Undefined if IsRelativeDate is false;
|
|
57
|
+
|
|
58
|
+
export type SingleDatePickerProps<IsRelativeDate extends boolean = false> = ControlledDatePickerProps &
|
|
59
|
+
SingleDatePickerPopoverContentProps<IsRelativeDate>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import range from "lodash/range";
|
|
2
2
|
import {DaySelect, Props} from "./day-select";
|
|
3
3
|
import moment from "moment";
|
|
4
4
|
|
|
5
|
-
const isoWeekDays =
|
|
5
|
+
const isoWeekDays = range(1, 8).map((day) => {
|
|
6
6
|
return {
|
|
7
7
|
key: String(day),
|
|
8
8
|
title: moment().isoWeekday(day).format("dd").charAt(0),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import memoize from "lodash/memoize";
|
|
2
2
|
import {DaySelect, Props} from "./day-select";
|
|
3
3
|
|
|
4
4
|
export enum Days {
|
|
@@ -21,7 +21,7 @@ const WeekDayMap = {
|
|
|
21
21
|
SU: Days.SU,
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
export const getDays =
|
|
24
|
+
export const getDays = memoize((firstDay) => {
|
|
25
25
|
const entries = Object.entries(WeekDayMap);
|
|
26
26
|
const firstDayIndex = entries.findIndex((entry) => entry[1] === firstDay);
|
|
27
27
|
const partA = entries.slice(firstDayIndex);
|
package/src/delayed.tsx
CHANGED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import {getOpacities, transparent} from "./alpha";
|
|
2
|
+
|
|
3
|
+
describe("getOpacities", () => {
|
|
4
|
+
test("color maps to alphas", () => {
|
|
5
|
+
expect(getOpacities("#f00")).toMatchInlineSnapshot(`
|
|
6
|
+
{
|
|
7
|
+
"opacity0": "rgba(255,0,0,0)",
|
|
8
|
+
"opacity10": "rgba(255,0,0,0.1)",
|
|
9
|
+
"opacity100": "rgb(255,0,0)",
|
|
10
|
+
"opacity15": "rgba(255,0,0,0.15)",
|
|
11
|
+
"opacity20": "rgba(255,0,0,0.2)",
|
|
12
|
+
"opacity25": "rgba(255,0,0,0.25)",
|
|
13
|
+
"opacity30": "rgba(255,0,0,0.3)",
|
|
14
|
+
"opacity35": "rgba(255,0,0,0.35)",
|
|
15
|
+
"opacity40": "rgba(255,0,0,0.4)",
|
|
16
|
+
"opacity45": "rgba(255,0,0,0.45)",
|
|
17
|
+
"opacity5": "rgba(255,0,0,0.05)",
|
|
18
|
+
"opacity50": "rgba(255,0,0,0.5)",
|
|
19
|
+
"opacity55": "rgba(255,0,0,0.55)",
|
|
20
|
+
"opacity60": "rgba(255,0,0,0.6)",
|
|
21
|
+
"opacity65": "rgba(255,0,0,0.65)",
|
|
22
|
+
"opacity70": "rgba(255,0,0,0.7)",
|
|
23
|
+
"opacity75": "rgba(255,0,0,0.75)",
|
|
24
|
+
"opacity80": "rgba(255,0,0,0.8)",
|
|
25
|
+
"opacity85": "rgba(255,0,0,0.85)",
|
|
26
|
+
"opacity90": "rgba(255,0,0,0.9)",
|
|
27
|
+
"opacity95": "rgba(255,0,0,0.95)",
|
|
28
|
+
}
|
|
29
|
+
`);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("transparent is identity map", () => {
|
|
33
|
+
expect(getOpacities(transparent)).toMatchInlineSnapshot(`
|
|
34
|
+
{
|
|
35
|
+
"opacity0": "rgba(255, 255, 255, 0)",
|
|
36
|
+
"opacity10": "rgba(255, 255, 255, 0)",
|
|
37
|
+
"opacity100": "rgba(255, 255, 255, 0)",
|
|
38
|
+
"opacity15": "rgba(255, 255, 255, 0)",
|
|
39
|
+
"opacity20": "rgba(255, 255, 255, 0)",
|
|
40
|
+
"opacity25": "rgba(255, 255, 255, 0)",
|
|
41
|
+
"opacity30": "rgba(255, 255, 255, 0)",
|
|
42
|
+
"opacity35": "rgba(255, 255, 255, 0)",
|
|
43
|
+
"opacity40": "rgba(255, 255, 255, 0)",
|
|
44
|
+
"opacity45": "rgba(255, 255, 255, 0)",
|
|
45
|
+
"opacity5": "rgba(255, 255, 255, 0)",
|
|
46
|
+
"opacity50": "rgba(255, 255, 255, 0)",
|
|
47
|
+
"opacity55": "rgba(255, 255, 255, 0)",
|
|
48
|
+
"opacity60": "rgba(255, 255, 255, 0)",
|
|
49
|
+
"opacity65": "rgba(255, 255, 255, 0)",
|
|
50
|
+
"opacity70": "rgba(255, 255, 255, 0)",
|
|
51
|
+
"opacity75": "rgba(255, 255, 255, 0)",
|
|
52
|
+
"opacity80": "rgba(255, 255, 255, 0)",
|
|
53
|
+
"opacity85": "rgba(255, 255, 255, 0)",
|
|
54
|
+
"opacity90": "rgba(255, 255, 255, 0)",
|
|
55
|
+
"opacity95": "rgba(255, 255, 255, 0)",
|
|
56
|
+
}
|
|
57
|
+
`);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {produceColor, setAlpha} from "../color-utils";
|
|
2
|
+
import mapValues from "lodash/mapValues";
|
|
3
|
+
import memoize from "lodash/memoize";
|
|
4
|
+
export const transparent = "rgba(255, 255, 255, 0)";
|
|
5
|
+
|
|
6
|
+
export const opacity = {
|
|
7
|
+
opacity100: 1,
|
|
8
|
+
opacity95: 0.95,
|
|
9
|
+
opacity90: 0.9,
|
|
10
|
+
opacity85: 0.85,
|
|
11
|
+
opacity80: 0.8,
|
|
12
|
+
opacity75: 0.75,
|
|
13
|
+
opacity70: 0.7,
|
|
14
|
+
opacity65: 0.65,
|
|
15
|
+
opacity60: 0.6,
|
|
16
|
+
opacity55: 0.55,
|
|
17
|
+
opacity50: 0.5,
|
|
18
|
+
opacity45: 0.45,
|
|
19
|
+
opacity40: 0.4,
|
|
20
|
+
opacity35: 0.35,
|
|
21
|
+
opacity30: 0.3,
|
|
22
|
+
opacity25: 0.25,
|
|
23
|
+
opacity20: 0.2,
|
|
24
|
+
opacity15: 0.15,
|
|
25
|
+
opacity10: 0.1,
|
|
26
|
+
opacity5: 0.05,
|
|
27
|
+
opacity0: 0,
|
|
28
|
+
} as const;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated I would think thrice on semantic value of this wrapper before one more usage
|
|
32
|
+
* maybe you will come up with something better
|
|
33
|
+
*/
|
|
34
|
+
export const getOpacities = memoize((color: string) =>
|
|
35
|
+
mapValues(opacity, (opacityValue) => {
|
|
36
|
+
if (color === transparent) {
|
|
37
|
+
return transparent;
|
|
38
|
+
}
|
|
39
|
+
return produceColor(color, (c) => setAlpha(c, opacityValue));
|
|
40
|
+
})
|
|
41
|
+
);
|