@a-type/ui 0.3.2 → 0.4.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/dist/cjs/components/datePicker/DatePicker.d.ts +19 -0
- package/dist/cjs/components/datePicker/DatePicker.js +97 -0
- package/dist/cjs/components/datePicker/DatePicker.js.map +1 -0
- package/dist/cjs/components/datePicker/DatePicker.stories.d.ts +16 -0
- package/dist/cjs/components/datePicker/DatePicker.stories.js +28 -0
- package/dist/cjs/components/datePicker/DatePicker.stories.js.map +1 -0
- package/dist/cjs/components/datePicker/index.d.ts +1 -0
- package/dist/cjs/components/datePicker/index.js +3 -0
- package/dist/cjs/components/datePicker/index.js.map +1 -0
- package/dist/esm/components/datePicker/DatePicker.d.ts +19 -0
- package/dist/esm/components/datePicker/DatePicker.js +89 -0
- package/dist/esm/components/datePicker/DatePicker.js.map +1 -0
- package/dist/esm/components/datePicker/DatePicker.stories.d.ts +16 -0
- package/dist/esm/components/datePicker/DatePicker.stories.js +25 -0
- package/dist/esm/components/datePicker/DatePicker.stories.js.map +1 -0
- package/dist/esm/components/datePicker/index.d.ts +1 -0
- package/dist/esm/components/datePicker/index.js +2 -0
- package/dist/esm/components/datePicker/index.js.map +1 -0
- package/package.json +4 -2
- package/src/components/actions/ActionBar.tsx +38 -0
- package/src/components/actions/ActionButton.tsx +59 -0
- package/src/components/actions/index.ts +2 -0
- package/src/components/actions.ts +1 -0
- package/src/components/avatar/Avatar.tsx +62 -0
- package/src/components/avatar/AvatarList.tsx +71 -0
- package/src/components/avatar/index.ts +2 -0
- package/src/components/avatar.ts +1 -0
- package/src/components/button/Button.stories.tsx +20 -0
- package/src/components/button/Button.tsx +66 -0
- package/src/components/button/ConfirmedButton.tsx +66 -0
- package/src/components/button/classes.tsx +56 -0
- package/src/components/button/index.ts +3 -0
- package/src/components/button.ts +1 -0
- package/src/components/camera/Camera.stories.tsx +40 -0
- package/src/components/camera/Camera.tsx +215 -0
- package/src/components/camera/index.ts +1 -0
- package/src/components/camera.ts +1 -0
- package/src/components/card/Card.stories.tsx +41 -0
- package/src/components/card/Card.tsx +68 -0
- package/src/components/card/index.ts +1 -0
- package/src/components/card.ts +1 -0
- package/src/components/checkbox/Checkbox.tsx +46 -0
- package/src/components/checkbox/index.ts +1 -0
- package/src/components/checkbox.ts +1 -0
- package/src/components/chip/Chip.tsx +29 -0
- package/src/components/chip/index.ts +1 -0
- package/src/components/chip.ts +1 -0
- package/src/components/collapsible/Collapsible.tsx +48 -0
- package/src/components/collapsible/index.ts +1 -0
- package/src/components/collapsible.ts +1 -0
- package/src/components/colorPicker/ColorPicker.tsx +82 -0
- package/src/components/colorPicker/index.ts +1 -0
- package/src/components/colorPicker.ts +1 -0
- package/src/components/contextMenu/contextMenu.tsx +43 -0
- package/src/components/contextMenu.ts +1 -0
- package/src/components/datePicker/DatePicker.stories.tsx +33 -0
- package/src/components/datePicker/DatePicker.tsx +258 -0
- package/src/components/datePicker/index.ts +0 -0
- package/src/components/dialog/Dialog.stories.tsx +38 -0
- package/src/components/dialog/Dialog.tsx +267 -0
- package/src/components/dialog/index.ts +1 -0
- package/src/components/dialog.ts +1 -0
- package/src/components/divider/Divider.tsx +26 -0
- package/src/components/divider/index.ts +1 -0
- package/src/components/divider.ts +1 -0
- package/src/components/dropdownMenu/DropdownMenu.stories.tsx +47 -0
- package/src/components/dropdownMenu/DropdownMenu.tsx +89 -0
- package/src/components/dropdownMenu/index.ts +1 -0
- package/src/components/dropdownMenu.ts +1 -0
- package/src/components/errorBoundary/ErrorBoundary.tsx +23 -0
- package/src/components/errorBoundary/index.ts +1 -0
- package/src/components/errorBoundary.ts +1 -0
- package/src/components/forms/Form.tsx +9 -0
- package/src/components/forms/FormikForm.tsx +41 -0
- package/src/components/forms/SubmitButton.tsx +15 -0
- package/src/components/forms/TextField.tsx +112 -0
- package/src/components/forms/index.tsx +4 -0
- package/src/components/forms.ts +1 -0
- package/src/components/icon/Icon.tsx +28 -0
- package/src/components/icon/generated/IconSpritesheet.tsx +442 -0
- package/src/components/icon/generated/iconNames.ts +44 -0
- package/src/components/icon/index.ts +3 -0
- package/src/components/icon.ts +1 -0
- package/src/components/imageUploader/ImageUploader.stories.tsx +39 -0
- package/src/components/imageUploader/ImageUploader.tsx +203 -0
- package/src/components/imageUploader/UploadIcon.tsx +23 -0
- package/src/components/imageUploader/index.ts +1 -0
- package/src/components/imageUploader.ts +1 -0
- package/src/components/infiniteLoadTrigger/InfiniteLoadTrigger.tsx +38 -0
- package/src/components/infiniteLoadTrigger.ts +1 -0
- package/src/components/input/Input.stories.tsx +17 -0
- package/src/components/input/Input.tsx +32 -0
- package/src/components/input/index.ts +1 -0
- package/src/components/input.ts +1 -0
- package/src/components/layouts/PageContent.tsx +51 -0
- package/src/components/layouts/PageFixedArea.tsx +17 -0
- package/src/components/layouts/PageNav.tsx +23 -0
- package/src/components/layouts/PageNowPlaying.tsx +24 -0
- package/src/components/layouts/PageRoot.tsx +29 -0
- package/src/components/layouts/PageSection.tsx +23 -0
- package/src/components/layouts/index.tsx +6 -0
- package/src/components/layouts.ts +1 -0
- package/src/components/liveUpdateTextField/LiveUpdateTextField.tsx +132 -0
- package/src/components/liveUpdateTextField/index.ts +1 -0
- package/src/components/liveUpdateTextField.ts +1 -0
- package/src/components/navBar/NavBar.tsx +59 -0
- package/src/components/navBar/index.ts +1 -0
- package/src/components/navBar.ts +1 -0
- package/src/components/note/Note.tsx +21 -0
- package/src/components/note/index.ts +1 -0
- package/src/components/note.ts +1 -0
- package/src/components/numberStepper/NumberStepper.stories.tsx +21 -0
- package/src/components/numberStepper/NumberStepper.tsx +74 -0
- package/src/components/numberStepper/index.ts +1 -0
- package/src/components/numberStepper.ts +1 -0
- package/src/components/particles/ParticleContext.tsx +11 -0
- package/src/components/particles/ParticleLayer.stories.tsx +46 -0
- package/src/components/particles/ParticleLayer.tsx +28 -0
- package/src/components/particles/index.ts +7 -0
- package/src/components/particles/particlesState.ts +502 -0
- package/src/components/particles.ts +1 -0
- package/src/components/peek/Peek.tsx +74 -0
- package/src/components/peek/index.ts +1 -0
- package/src/components/peek.ts +1 -0
- package/src/components/popover/Popover.tsx +84 -0
- package/src/components/popover/index.ts +1 -0
- package/src/components/popover.ts +1 -0
- package/src/components/relativeTime/RelativeTime.tsx +43 -0
- package/src/components/relativeTime/index.ts +1 -0
- package/src/components/relativeTime.ts +1 -0
- package/src/components/richEditor/EditorContent.tsx +4 -0
- package/src/components/richEditor/RichEditor.tsx +38 -0
- package/src/components/richEditor/index.ts +1 -0
- package/src/components/richEditor.ts +1 -0
- package/src/components/select/Select.tsx +247 -0
- package/src/components/select/index.ts +1 -0
- package/src/components/select.ts +1 -0
- package/src/components/skeletons/skeletons.tsx +27 -0
- package/src/components/skeletons.ts +1 -0
- package/src/components/spinner/Spinner.tsx +59 -0
- package/src/components/spinner/index.ts +1 -0
- package/src/components/spinner.ts +1 -0
- package/src/components/switch/Switch.tsx +23 -0
- package/src/components/switch/index.ts +1 -0
- package/src/components/switch.ts +1 -0
- package/src/components/tabs/tabs.tsx +18 -0
- package/src/components/tabs.ts +1 -0
- package/src/components/textArea/TextArea.stories.tsx +21 -0
- package/src/components/textArea/TextArea.tsx +58 -0
- package/src/components/textArea/index.ts +1 -0
- package/src/components/textArea.ts +1 -0
- package/src/components/toggleGroup/toggleGroup.tsx +11 -0
- package/src/components/toggleGroup.ts +1 -0
- package/src/components/tooltip/Tooltip.tsx +56 -0
- package/src/components/tooltip/index.ts +1 -0
- package/src/components/tooltip.ts +1 -0
- package/src/components/typography/index.ts +1 -0
- package/src/components/typography/typography.tsx +18 -0
- package/src/components/typography.ts +1 -0
- package/src/hooks/index.ts +7 -0
- package/src/hooks/useMergedRef.ts +14 -0
- package/src/hooks/useOnUnmount.ts +20 -0
- package/src/hooks/useSize.ts +164 -0
- package/src/hooks/useStableCallback.ts +11 -0
- package/src/hooks/useToggle.tsx +9 -0
- package/src/hooks/useVisualViewportOffset.ts +35 -0
- package/src/hooks/withClassName.tsx +21 -0
- package/src/hooks.ts +1 -0
- package/src/uno.preset.ts +767 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/// <reference types="react" resolution-mode="require"/>
|
|
2
|
+
export interface DatePickerProps {
|
|
3
|
+
value: Date | null;
|
|
4
|
+
onChange: (date: Date | null) => void;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function DatePicker({ value, onChange, className, ...rest }: DatePickerProps): JSX.Element;
|
|
8
|
+
export interface DateRangePickerProps {
|
|
9
|
+
value: {
|
|
10
|
+
start: Date | null;
|
|
11
|
+
end: Date | null;
|
|
12
|
+
};
|
|
13
|
+
onChange: (value: {
|
|
14
|
+
start: Date | null;
|
|
15
|
+
end: Date | null;
|
|
16
|
+
}) => void;
|
|
17
|
+
className?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function DateRangePicker({ value, onChange, className, }: DateRangePickerProps): JSX.Element;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.DateRangePicker = exports.DatePicker = void 0;
|
|
18
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
19
|
+
const calendar_blocks_1 = require("calendar-blocks");
|
|
20
|
+
const button_js_1 = require("../button.js");
|
|
21
|
+
const react_icons_1 = require("@radix-ui/react-icons");
|
|
22
|
+
const react_1 = require("react");
|
|
23
|
+
const hooks_js_1 = require("../../hooks.js");
|
|
24
|
+
const classnames_1 = __importDefault(require("classnames"));
|
|
25
|
+
function DatePicker(_a) {
|
|
26
|
+
var { value, onChange, className } = _a, rest = __rest(_a, ["value", "onChange", "className"]);
|
|
27
|
+
const [{ month, year }, setDisplay] = (0, react_1.useState)(() => ({
|
|
28
|
+
month: new Date().getMonth(),
|
|
29
|
+
year: new Date().getFullYear(),
|
|
30
|
+
}));
|
|
31
|
+
const monthLabel = new Date(year, month).toLocaleDateString('en-US', {
|
|
32
|
+
month: 'long',
|
|
33
|
+
year: 'numeric',
|
|
34
|
+
});
|
|
35
|
+
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: (0, classnames_1.default)('flex flex-col items-center justify-center w-[calc(var(--day-size,32px)*7)]', className) }, rest, { children: [(0, jsx_runtime_1.jsxs)(MonthRow, { children: [(0, jsx_runtime_1.jsx)(MonthButton, Object.assign({ size: "icon", color: "ghost", onClick: () => setDisplay((cur) => ({
|
|
36
|
+
month: cur.month - 1,
|
|
37
|
+
year: cur.year,
|
|
38
|
+
})) }, { children: (0, jsx_runtime_1.jsx)(react_icons_1.ArrowLeftIcon, {}) })), (0, jsx_runtime_1.jsx)(MonthLabel, { children: monthLabel }), (0, jsx_runtime_1.jsx)(MonthButton, Object.assign({ size: "icon", color: "ghost", onClick: () => setDisplay((cur) => ({
|
|
39
|
+
month: cur.month + 1,
|
|
40
|
+
year: cur.year,
|
|
41
|
+
})) }, { children: (0, jsx_runtime_1.jsx)(react_icons_1.ArrowRightIcon, {}) }))] }), (0, jsx_runtime_1.jsx)(calendar_blocks_1.Calendar, Object.assign({ displayMonth: month, displayYear: year, value: value, onChange: onChange, onDisplayChange: setDisplay }, { children: (0, jsx_runtime_1.jsxs)(CalendarGrid, { children: [(0, jsx_runtime_1.jsx)(DayLabels, {}), (0, jsx_runtime_1.jsx)(calendar_blocks_1.CalendarDays, { children: (value) => (0, jsx_runtime_1.jsx)(CalendarDay, { value: value }, value.key) })] }) }))] })));
|
|
42
|
+
}
|
|
43
|
+
exports.DatePicker = DatePicker;
|
|
44
|
+
function DateRangePicker({ value, onChange, className, }) {
|
|
45
|
+
const [{ month, year }, setDisplay] = (0, react_1.useState)(() => ({
|
|
46
|
+
month: new Date().getMonth(),
|
|
47
|
+
year: new Date().getFullYear(),
|
|
48
|
+
}));
|
|
49
|
+
const monthLabel = new Date(year, month).toLocaleDateString('en-US', {
|
|
50
|
+
month: 'long',
|
|
51
|
+
year: 'numeric',
|
|
52
|
+
});
|
|
53
|
+
const nextMonth = new Date(year, month + 1);
|
|
54
|
+
const nextMonthLabel = nextMonth.toLocaleDateString('en-US', {
|
|
55
|
+
month: 'long',
|
|
56
|
+
year: 'numeric',
|
|
57
|
+
});
|
|
58
|
+
const onDisplayChange = (0, react_1.useCallback)(({ month: newMonth, year: newYear }) => {
|
|
59
|
+
/**
|
|
60
|
+
* Important UX consideration:
|
|
61
|
+
*
|
|
62
|
+
* since we are displaying 2 months at once, we don't
|
|
63
|
+
* always want to change our view if the user's cursor
|
|
64
|
+
* date moves from one month to another. Specifically,
|
|
65
|
+
* if they move from the first visible month to the
|
|
66
|
+
* second visible month, we don't need to change the view,
|
|
67
|
+
* since they are still within the visible range.
|
|
68
|
+
* So, we write logic to ignore that case!
|
|
69
|
+
*/
|
|
70
|
+
if (newMonth === month + 1 && newYear === year) {
|
|
71
|
+
return; // ignore movement from the first to the second frame
|
|
72
|
+
}
|
|
73
|
+
setDisplay({
|
|
74
|
+
month: newMonth,
|
|
75
|
+
year: newYear,
|
|
76
|
+
});
|
|
77
|
+
}, [month, year]);
|
|
78
|
+
return ((0, jsx_runtime_1.jsx)(calendar_blocks_1.Calendar, Object.assign({ displayMonth: month, displayYear: year, rangeValue: value, onRangeChange: (range) => onChange(range), onDisplayChange: onDisplayChange, className: (0, classnames_1.default)('flex justify-center', className) }, { children: (0, jsx_runtime_1.jsxs)(RangeLayout, { children: [(0, jsx_runtime_1.jsx)(MonthButton, Object.assign({ size: "icon", color: "ghost", className: "[grid-area:prevMonth]", onClick: () => setDisplay((cur) => ({
|
|
79
|
+
month: cur.month - 1,
|
|
80
|
+
year: cur.year,
|
|
81
|
+
})) }, { children: (0, jsx_runtime_1.jsx)(react_icons_1.ArrowLeftIcon, {}) })), (0, jsx_runtime_1.jsx)(MonthLabel, Object.assign({ className: "[grid-area:leftMonth]" }, { children: monthLabel })), (0, jsx_runtime_1.jsx)(MonthLabel, Object.assign({ className: "[grid-area:rightMonth]" }, { children: nextMonthLabel })), (0, jsx_runtime_1.jsx)(MonthButton, Object.assign({ size: "icon", color: "ghost", className: "[grid-area:nextMonth]", onClick: () => setDisplay((cur) => ({
|
|
82
|
+
month: cur.month + 1,
|
|
83
|
+
year: cur.year,
|
|
84
|
+
})) }, { children: (0, jsx_runtime_1.jsx)(react_icons_1.ArrowRightIcon, {}) })), (0, jsx_runtime_1.jsxs)(CalendarGrid, Object.assign({ className: "[grid-area:leftGrid]" }, { children: [(0, jsx_runtime_1.jsx)(DayLabels, {}), (0, jsx_runtime_1.jsx)(calendar_blocks_1.CalendarDays, { children: (value) => (0, jsx_runtime_1.jsx)(CalendarDay, { value: value }, value.key) })] })), (0, jsx_runtime_1.jsxs)(CalendarGrid, Object.assign({ className: "[grid-area:rightGrid]" }, { children: [(0, jsx_runtime_1.jsx)(DayLabels, {}), (0, jsx_runtime_1.jsx)(calendar_blocks_1.CalendarDays, Object.assign({ monthOffset: 1 }, { children: (value) => (0, jsx_runtime_1.jsx)(CalendarDay, { value: value }, value.key) }))] }))] }) })));
|
|
85
|
+
}
|
|
86
|
+
exports.DateRangePicker = DateRangePicker;
|
|
87
|
+
const MonthRow = (0, hooks_js_1.withClassName)('div', 'flex flex-row justify-between items-center w-full');
|
|
88
|
+
const MonthLabel = (0, hooks_js_1.withClassName)('span', 'text-sm font-bold min-w-0 overflow-hidden text-center text-ellipsis', 'self-center');
|
|
89
|
+
const MonthButton = (0, hooks_js_1.withClassName)(button_js_1.Button, 'self-center');
|
|
90
|
+
const CalendarGrid = (0, hooks_js_1.withClassName)('div', 'grid grid-cols-[repeat(7,var(--day-size,32px))] [grid-auto-rows:var(--day-size,32px)]', 'height-[calc(var(--day-size,32px)*7)] rounded overflow-hidden p-2 bg-gray-1');
|
|
91
|
+
const CalendarDay = (0, hooks_js_1.withClassName)(calendar_blocks_1.CalendarDay, 'border border-solid border-transparent bg-white mr--1px mb--1px relative rounded', 'flex items-center justify-center transition-colors cursor-pointer', '[&[data-highlighted]]:(z-1 outline-accent)', '[&[data-selected]]:(bg-accent-light z-2)', '[&[data-in-range]]:(bg-accent-wash rounded-none z-1)', '[&[data-range-start]]:(bg-accent-light rounded-l rounded-r-none z-1)', '[&[data-range-end]]:(bg-accent-light rounded-r rounded-l-none z-1)', 'disabled:(opacity-50 cursor-default)',
|
|
92
|
+
// today dot
|
|
93
|
+
'[&[data-today]]:before:(content-[""] absolute left-[2px] top-[2px] w-[6px] h-[6px] rounded-full bg-primary)', '[&[data-top-edge]]:(border-top-gray-2)', '[&[data-bottom-edge]]:(border-bottom-gray-2)', '[&[data-first-column]]:(border-left-gray-2)', '[&[data-last-column]]:(border-right-gray-2)', '[&[data-day-first]]:(border-left-gray-2 rounded-tl)', '[&[data-day-last]]:(border-right-gray-2 rounded-br)', '[&[data-first-column][data-bottom-edge]]:rounded-bl', '[&[data-last-column][data-bottom-edge]]:rounded-br', '[&[data-first-column][data-top-edge]]:rounded-tl', '[&[data-last-column][data-top-edge]]:rounded-tr', '[&[data-different-month]]:[visibility:hidden]');
|
|
94
|
+
const DayLabel = (0, hooks_js_1.withClassName)('div', 'flex items-center justify-center text-sm text-gray-6');
|
|
95
|
+
const DayLabels = () => ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(DayLabel, { children: "S" }), (0, jsx_runtime_1.jsx)(DayLabel, { children: "M" }), (0, jsx_runtime_1.jsx)(DayLabel, { children: "T" }), (0, jsx_runtime_1.jsx)(DayLabel, { children: "W" }), (0, jsx_runtime_1.jsx)(DayLabel, { children: "T" }), (0, jsx_runtime_1.jsx)(DayLabel, { children: "F" }), (0, jsx_runtime_1.jsx)(DayLabel, { children: "S" })] }));
|
|
96
|
+
const RangeLayout = (0, hooks_js_1.withClassName)('div', 'grid [grid-template-areas:"prevMonth_leftMonth_rightMonth_nextMonth""leftGrid_leftGrid_rightGrid_rightGrid"]', '[grid-template-columns:auto_1fr_1fr_auto] [grid-template-rows:auto_1fr] gap-2');
|
|
97
|
+
//# sourceMappingURL=DatePicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatePicker.js","sourceRoot":"","sources":["../../../../src/components/datePicker/DatePicker.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { StoryObj } from '@storybook/react';
|
|
2
|
+
import { DatePicker } from './DatePicker.js';
|
|
3
|
+
declare const meta: {
|
|
4
|
+
title: string;
|
|
5
|
+
component: typeof DatePicker;
|
|
6
|
+
argTypes: {};
|
|
7
|
+
parameters: {
|
|
8
|
+
controls: {
|
|
9
|
+
expanded: boolean;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
export default meta;
|
|
14
|
+
type Story = StoryObj<typeof DatePicker>;
|
|
15
|
+
export declare const Default: Story;
|
|
16
|
+
export declare const Range: Story;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Range = exports.Default = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const DatePicker_js_1 = require("./DatePicker.js");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const meta = {
|
|
8
|
+
title: 'DatePicker',
|
|
9
|
+
component: DatePicker_js_1.DatePicker,
|
|
10
|
+
argTypes: {},
|
|
11
|
+
parameters: {
|
|
12
|
+
controls: { expanded: true },
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
exports.default = meta;
|
|
16
|
+
exports.Default = {
|
|
17
|
+
render() {
|
|
18
|
+
const [value, setValue] = (0, react_1.useState)(null);
|
|
19
|
+
return (0, jsx_runtime_1.jsx)(DatePicker_js_1.DatePicker, { value: value, onChange: setValue });
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
exports.Range = {
|
|
23
|
+
render() {
|
|
24
|
+
const [value, setValue] = (0, react_1.useState)({ start: null, end: null });
|
|
25
|
+
return (0, jsx_runtime_1.jsx)(DatePicker_js_1.DateRangePicker, { value: value, onChange: setValue });
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=DatePicker.stories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatePicker.stories.js","sourceRoot":"","sources":["../../../../src/components/datePicker/DatePicker.stories.tsx"],"names":[],"mappings":";;;;AACA,mDAA8D;AAC9D,iCAAiC;AAEjC,MAAM,IAAI,GAAG;IACZ,KAAK,EAAE,YAAY;IACnB,SAAS,EAAE,0BAAU;IACrB,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE;QACX,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;KAC5B;CACiC,CAAC;AAEpC,kBAAe,IAAI,CAAC;AAIP,QAAA,OAAO,GAAU;IAC7B,MAAM;QACL,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAA,gBAAQ,EAAc,IAAI,CAAC,CAAC;QACtD,OAAO,uBAAC,0BAAU,IAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAI,CAAC;IACzD,CAAC;CACD,CAAC;AAEW,QAAA,KAAK,GAAU;IAC3B,MAAM;QACL,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAA,gBAAQ,EAG/B,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/B,OAAO,uBAAC,+BAAe,IAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAI,CAAC;IAC9D,CAAC;CACD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/datePicker/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/// <reference types="react" resolution-mode="require"/>
|
|
2
|
+
export interface DatePickerProps {
|
|
3
|
+
value: Date | null;
|
|
4
|
+
onChange: (date: Date | null) => void;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function DatePicker({ value, onChange, className, ...rest }: DatePickerProps): JSX.Element;
|
|
8
|
+
export interface DateRangePickerProps {
|
|
9
|
+
value: {
|
|
10
|
+
start: Date | null;
|
|
11
|
+
end: Date | null;
|
|
12
|
+
};
|
|
13
|
+
onChange: (value: {
|
|
14
|
+
start: Date | null;
|
|
15
|
+
end: Date | null;
|
|
16
|
+
}) => void;
|
|
17
|
+
className?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function DateRangePicker({ value, onChange, className, }: DateRangePickerProps): JSX.Element;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
13
|
+
import { Calendar, CalendarDay as BaseCalendarDay, CalendarDays, } from 'calendar-blocks';
|
|
14
|
+
import { Button } from '../button.js';
|
|
15
|
+
import { ArrowLeftIcon, ArrowRightIcon } from '@radix-ui/react-icons';
|
|
16
|
+
import { useCallback, useState } from 'react';
|
|
17
|
+
import { withClassName } from '../../hooks.js';
|
|
18
|
+
import classNames from 'classnames';
|
|
19
|
+
export function DatePicker(_a) {
|
|
20
|
+
var { value, onChange, className } = _a, rest = __rest(_a, ["value", "onChange", "className"]);
|
|
21
|
+
const [{ month, year }, setDisplay] = useState(() => ({
|
|
22
|
+
month: new Date().getMonth(),
|
|
23
|
+
year: new Date().getFullYear(),
|
|
24
|
+
}));
|
|
25
|
+
const monthLabel = new Date(year, month).toLocaleDateString('en-US', {
|
|
26
|
+
month: 'long',
|
|
27
|
+
year: 'numeric',
|
|
28
|
+
});
|
|
29
|
+
return (_jsxs("div", Object.assign({ className: classNames('flex flex-col items-center justify-center w-[calc(var(--day-size,32px)*7)]', className) }, rest, { children: [_jsxs(MonthRow, { children: [_jsx(MonthButton, Object.assign({ size: "icon", color: "ghost", onClick: () => setDisplay((cur) => ({
|
|
30
|
+
month: cur.month - 1,
|
|
31
|
+
year: cur.year,
|
|
32
|
+
})) }, { children: _jsx(ArrowLeftIcon, {}) })), _jsx(MonthLabel, { children: monthLabel }), _jsx(MonthButton, Object.assign({ size: "icon", color: "ghost", onClick: () => setDisplay((cur) => ({
|
|
33
|
+
month: cur.month + 1,
|
|
34
|
+
year: cur.year,
|
|
35
|
+
})) }, { children: _jsx(ArrowRightIcon, {}) }))] }), _jsx(Calendar, Object.assign({ displayMonth: month, displayYear: year, value: value, onChange: onChange, onDisplayChange: setDisplay }, { children: _jsxs(CalendarGrid, { children: [_jsx(DayLabels, {}), _jsx(CalendarDays, { children: (value) => _jsx(CalendarDay, { value: value }, value.key) })] }) }))] })));
|
|
36
|
+
}
|
|
37
|
+
export function DateRangePicker({ value, onChange, className, }) {
|
|
38
|
+
const [{ month, year }, setDisplay] = useState(() => ({
|
|
39
|
+
month: new Date().getMonth(),
|
|
40
|
+
year: new Date().getFullYear(),
|
|
41
|
+
}));
|
|
42
|
+
const monthLabel = new Date(year, month).toLocaleDateString('en-US', {
|
|
43
|
+
month: 'long',
|
|
44
|
+
year: 'numeric',
|
|
45
|
+
});
|
|
46
|
+
const nextMonth = new Date(year, month + 1);
|
|
47
|
+
const nextMonthLabel = nextMonth.toLocaleDateString('en-US', {
|
|
48
|
+
month: 'long',
|
|
49
|
+
year: 'numeric',
|
|
50
|
+
});
|
|
51
|
+
const onDisplayChange = useCallback(({ month: newMonth, year: newYear }) => {
|
|
52
|
+
/**
|
|
53
|
+
* Important UX consideration:
|
|
54
|
+
*
|
|
55
|
+
* since we are displaying 2 months at once, we don't
|
|
56
|
+
* always want to change our view if the user's cursor
|
|
57
|
+
* date moves from one month to another. Specifically,
|
|
58
|
+
* if they move from the first visible month to the
|
|
59
|
+
* second visible month, we don't need to change the view,
|
|
60
|
+
* since they are still within the visible range.
|
|
61
|
+
* So, we write logic to ignore that case!
|
|
62
|
+
*/
|
|
63
|
+
if (newMonth === month + 1 && newYear === year) {
|
|
64
|
+
return; // ignore movement from the first to the second frame
|
|
65
|
+
}
|
|
66
|
+
setDisplay({
|
|
67
|
+
month: newMonth,
|
|
68
|
+
year: newYear,
|
|
69
|
+
});
|
|
70
|
+
}, [month, year]);
|
|
71
|
+
return (_jsx(Calendar, Object.assign({ displayMonth: month, displayYear: year, rangeValue: value, onRangeChange: (range) => onChange(range), onDisplayChange: onDisplayChange, className: classNames('flex justify-center', className) }, { children: _jsxs(RangeLayout, { children: [_jsx(MonthButton, Object.assign({ size: "icon", color: "ghost", className: "[grid-area:prevMonth]", onClick: () => setDisplay((cur) => ({
|
|
72
|
+
month: cur.month - 1,
|
|
73
|
+
year: cur.year,
|
|
74
|
+
})) }, { children: _jsx(ArrowLeftIcon, {}) })), _jsx(MonthLabel, Object.assign({ className: "[grid-area:leftMonth]" }, { children: monthLabel })), _jsx(MonthLabel, Object.assign({ className: "[grid-area:rightMonth]" }, { children: nextMonthLabel })), _jsx(MonthButton, Object.assign({ size: "icon", color: "ghost", className: "[grid-area:nextMonth]", onClick: () => setDisplay((cur) => ({
|
|
75
|
+
month: cur.month + 1,
|
|
76
|
+
year: cur.year,
|
|
77
|
+
})) }, { children: _jsx(ArrowRightIcon, {}) })), _jsxs(CalendarGrid, Object.assign({ className: "[grid-area:leftGrid]" }, { children: [_jsx(DayLabels, {}), _jsx(CalendarDays, { children: (value) => _jsx(CalendarDay, { value: value }, value.key) })] })), _jsxs(CalendarGrid, Object.assign({ className: "[grid-area:rightGrid]" }, { children: [_jsx(DayLabels, {}), _jsx(CalendarDays, Object.assign({ monthOffset: 1 }, { children: (value) => _jsx(CalendarDay, { value: value }, value.key) }))] }))] }) })));
|
|
78
|
+
}
|
|
79
|
+
const MonthRow = withClassName('div', 'flex flex-row justify-between items-center w-full');
|
|
80
|
+
const MonthLabel = withClassName('span', 'text-sm font-bold min-w-0 overflow-hidden text-center text-ellipsis', 'self-center');
|
|
81
|
+
const MonthButton = withClassName(Button, 'self-center');
|
|
82
|
+
const CalendarGrid = withClassName('div', 'grid grid-cols-[repeat(7,var(--day-size,32px))] [grid-auto-rows:var(--day-size,32px)]', 'height-[calc(var(--day-size,32px)*7)] rounded overflow-hidden p-2 bg-gray-1');
|
|
83
|
+
const CalendarDay = withClassName(BaseCalendarDay, 'border border-solid border-transparent bg-white mr--1px mb--1px relative rounded', 'flex items-center justify-center transition-colors cursor-pointer', '[&[data-highlighted]]:(z-1 outline-accent)', '[&[data-selected]]:(bg-accent-light z-2)', '[&[data-in-range]]:(bg-accent-wash rounded-none z-1)', '[&[data-range-start]]:(bg-accent-light rounded-l rounded-r-none z-1)', '[&[data-range-end]]:(bg-accent-light rounded-r rounded-l-none z-1)', 'disabled:(opacity-50 cursor-default)',
|
|
84
|
+
// today dot
|
|
85
|
+
'[&[data-today]]:before:(content-[""] absolute left-[2px] top-[2px] w-[6px] h-[6px] rounded-full bg-primary)', '[&[data-top-edge]]:(border-top-gray-2)', '[&[data-bottom-edge]]:(border-bottom-gray-2)', '[&[data-first-column]]:(border-left-gray-2)', '[&[data-last-column]]:(border-right-gray-2)', '[&[data-day-first]]:(border-left-gray-2 rounded-tl)', '[&[data-day-last]]:(border-right-gray-2 rounded-br)', '[&[data-first-column][data-bottom-edge]]:rounded-bl', '[&[data-last-column][data-bottom-edge]]:rounded-br', '[&[data-first-column][data-top-edge]]:rounded-tl', '[&[data-last-column][data-top-edge]]:rounded-tr', '[&[data-different-month]]:[visibility:hidden]');
|
|
86
|
+
const DayLabel = withClassName('div', 'flex items-center justify-center text-sm text-gray-6');
|
|
87
|
+
const DayLabels = () => (_jsxs(_Fragment, { children: [_jsx(DayLabel, { children: "S" }), _jsx(DayLabel, { children: "M" }), _jsx(DayLabel, { children: "T" }), _jsx(DayLabel, { children: "W" }), _jsx(DayLabel, { children: "T" }), _jsx(DayLabel, { children: "F" }), _jsx(DayLabel, { children: "S" })] }));
|
|
88
|
+
const RangeLayout = withClassName('div', 'grid [grid-template-areas:"prevMonth_leftMonth_rightMonth_nextMonth""leftGrid_leftGrid_rightGrid_rightGrid"]', '[grid-template-columns:auto_1fr_1fr_auto] [grid-template-rows:auto_1fr] gap-2');
|
|
89
|
+
//# sourceMappingURL=DatePicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatePicker.js","sourceRoot":"","sources":["../../../../src/components/datePicker/DatePicker.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { StoryObj } from '@storybook/react';
|
|
2
|
+
import { DatePicker } from './DatePicker.js';
|
|
3
|
+
declare const meta: {
|
|
4
|
+
title: string;
|
|
5
|
+
component: typeof DatePicker;
|
|
6
|
+
argTypes: {};
|
|
7
|
+
parameters: {
|
|
8
|
+
controls: {
|
|
9
|
+
expanded: boolean;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
export default meta;
|
|
14
|
+
type Story = StoryObj<typeof DatePicker>;
|
|
15
|
+
export declare const Default: Story;
|
|
16
|
+
export declare const Range: Story;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { DatePicker, DateRangePicker } from './DatePicker.js';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'DatePicker',
|
|
6
|
+
component: DatePicker,
|
|
7
|
+
argTypes: {},
|
|
8
|
+
parameters: {
|
|
9
|
+
controls: { expanded: true },
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
export default meta;
|
|
13
|
+
export const Default = {
|
|
14
|
+
render() {
|
|
15
|
+
const [value, setValue] = useState(null);
|
|
16
|
+
return _jsx(DatePicker, { value: value, onChange: setValue });
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
export const Range = {
|
|
20
|
+
render() {
|
|
21
|
+
const [value, setValue] = useState({ start: null, end: null });
|
|
22
|
+
return _jsx(DateRangePicker, { value: value, onChange: setValue });
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=DatePicker.stories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatePicker.stories.js","sourceRoot":"","sources":["../../../../src/components/datePicker/DatePicker.stories.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,MAAM,IAAI,GAAG;IACZ,KAAK,EAAE,YAAY;IACnB,SAAS,EAAE,UAAU;IACrB,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE;QACX,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;KAC5B;CACiC,CAAC;AAEpC,eAAe,IAAI,CAAC;AAIpB,MAAM,CAAC,MAAM,OAAO,GAAU;IAC7B,MAAM;QACL,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAc,IAAI,CAAC,CAAC;QACtD,OAAO,KAAC,UAAU,IAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAI,CAAC;IACzD,CAAC;CACD,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAU;IAC3B,MAAM;QACL,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAG/B,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/B,OAAO,KAAC,eAAe,IAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAI,CAAC;IAC9D,CAAC;CACD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/datePicker/index.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@a-type/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
|
-
"/dist"
|
|
6
|
+
"/dist",
|
|
7
|
+
"/src"
|
|
7
8
|
],
|
|
8
9
|
"exports": {
|
|
9
10
|
"./components/*": {
|
|
@@ -56,6 +57,7 @@
|
|
|
56
57
|
"@tiptap/starter-kit": "^2.0.3",
|
|
57
58
|
"@use-gesture/react": "^10.2.27",
|
|
58
59
|
"browser-image-resizer": "^2.4.1",
|
|
60
|
+
"calendar-blocks": "^0.3.0",
|
|
59
61
|
"classnames": "^2.3.2",
|
|
60
62
|
"color-interpolate": "^1.0.5",
|
|
61
63
|
"color-parse": "^2.0.0",
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ReactNode, Suspense } from 'react';
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
|
|
4
|
+
export interface ActionBarProps {
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
className?: string;
|
|
7
|
+
wrap?: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function ActionBar({
|
|
11
|
+
children,
|
|
12
|
+
className,
|
|
13
|
+
wrap,
|
|
14
|
+
...rest
|
|
15
|
+
}: ActionBarProps) {
|
|
16
|
+
return (
|
|
17
|
+
<Suspense fallback={null}>
|
|
18
|
+
<div
|
|
19
|
+
className={classNames(
|
|
20
|
+
'flex flex-row items-center justify-start w-full overflow-hidden relative h-[max-content] transition-[height] springy',
|
|
21
|
+
'[&:empty]:height-0',
|
|
22
|
+
'after:(content-[""] absolute right-0 top-0 bottom-0 w-50px z-1 bg-gradient-to-l from-wash to-transparent] pointer-events-none)',
|
|
23
|
+
className,
|
|
24
|
+
)}
|
|
25
|
+
{...rest}
|
|
26
|
+
>
|
|
27
|
+
<div
|
|
28
|
+
className={classNames(
|
|
29
|
+
'flex flex-row items-center justify-start w-full overflow-y-hidden overflow-x-auto pr-80px relative h-full [&::-webkit-scrollbar]:display-none',
|
|
30
|
+
wrap && 'flex-wrap',
|
|
31
|
+
)}
|
|
32
|
+
>
|
|
33
|
+
{children}
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</Suspense>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
import { forwardRef, ReactNode, useEffect, useRef, useState } from 'react';
|
|
5
|
+
import { Button, ButtonProps } from '../button/Button.js';
|
|
6
|
+
import { CollapsibleContent, CollapsibleRoot } from '../collapsible.js';
|
|
7
|
+
|
|
8
|
+
export interface ActionButtonProps extends ButtonProps {
|
|
9
|
+
icon?: ReactNode;
|
|
10
|
+
visible?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const ActionButton = forwardRef<HTMLButtonElement, ActionButtonProps>(
|
|
14
|
+
function ActionButton(
|
|
15
|
+
{ icon, children, className, visible = true, ...rest },
|
|
16
|
+
ref,
|
|
17
|
+
) {
|
|
18
|
+
// this rather convoluted logic is meant to do:
|
|
19
|
+
// - when button goes invisible, wait for collapse and then
|
|
20
|
+
// stop rendering
|
|
21
|
+
// - when button goes visible, render immediately and
|
|
22
|
+
// set collapsible open next frame.
|
|
23
|
+
const [render, setRender] = useState(visible);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (!visible) {
|
|
26
|
+
const timeout = setTimeout(() => {
|
|
27
|
+
setRender(visible);
|
|
28
|
+
}, 300);
|
|
29
|
+
return () => clearTimeout(timeout);
|
|
30
|
+
} else {
|
|
31
|
+
setRender(visible);
|
|
32
|
+
}
|
|
33
|
+
}, [visible]);
|
|
34
|
+
|
|
35
|
+
if (!render && !visible) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<CollapsibleRoot open={!visible ? false : render}>
|
|
41
|
+
<CollapsibleContent data-horizontal>
|
|
42
|
+
<Button
|
|
43
|
+
ref={ref}
|
|
44
|
+
size="small"
|
|
45
|
+
className={classNames(
|
|
46
|
+
'important:(border-gray7 font-normal whitespace-nowrap m-2 flex flex-row gap-2 items-center h-30px rounded-15px mx-1)',
|
|
47
|
+
'hover:bg-gray2',
|
|
48
|
+
className,
|
|
49
|
+
)}
|
|
50
|
+
{...rest}
|
|
51
|
+
>
|
|
52
|
+
{icon}
|
|
53
|
+
{children}
|
|
54
|
+
</Button>
|
|
55
|
+
</CollapsibleContent>
|
|
56
|
+
</CollapsibleRoot>
|
|
57
|
+
);
|
|
58
|
+
},
|
|
59
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './actions/index.js';
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import classNames from 'classnames';
|
|
2
|
+
import { CSSProperties } from 'react';
|
|
3
|
+
import { Icon } from '../icon.js';
|
|
4
|
+
|
|
5
|
+
export interface AvatarProps {
|
|
6
|
+
className?: string;
|
|
7
|
+
popIn?: boolean;
|
|
8
|
+
style?: CSSProperties;
|
|
9
|
+
imageSrc?: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function Avatar({
|
|
14
|
+
className,
|
|
15
|
+
popIn = true,
|
|
16
|
+
imageSrc,
|
|
17
|
+
name,
|
|
18
|
+
...rest
|
|
19
|
+
}: AvatarProps) {
|
|
20
|
+
const empty = !name && !imageSrc;
|
|
21
|
+
return (
|
|
22
|
+
<div
|
|
23
|
+
data-pop={popIn}
|
|
24
|
+
className={classNames(
|
|
25
|
+
'layer-components:(flex items-center justify-center rounded-full border-default p-2px overflow-hidden w-24px h-24px select-none relative bg-white flex-shrink-0)',
|
|
26
|
+
popIn &&
|
|
27
|
+
'layer-variants:(animate-pop-in-from-half animate-ease-springy animate-duration-200)',
|
|
28
|
+
empty && 'layer-components(border-dashed bg-gray2)',
|
|
29
|
+
className,
|
|
30
|
+
)}
|
|
31
|
+
{...rest}
|
|
32
|
+
>
|
|
33
|
+
{!empty && <AvatarContent name={name} imageSrc={imageSrc} />}
|
|
34
|
+
{empty && <Icon name="profile" />}
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function AvatarContent({
|
|
40
|
+
name,
|
|
41
|
+
imageSrc,
|
|
42
|
+
}: {
|
|
43
|
+
name?: string;
|
|
44
|
+
imageSrc?: string;
|
|
45
|
+
}) {
|
|
46
|
+
if (imageSrc) {
|
|
47
|
+
return (
|
|
48
|
+
<img
|
|
49
|
+
className="w-full h-full object-cover rounded-full"
|
|
50
|
+
referrerPolicy="no-referrer"
|
|
51
|
+
crossOrigin="anonymous"
|
|
52
|
+
src={imageSrc}
|
|
53
|
+
alt={`${name ?? 'user'}'s profile picture`}
|
|
54
|
+
/>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
return (
|
|
58
|
+
<div className="color-black items-center justify-center flex text-sm font-bold rounded-full">
|
|
59
|
+
{name?.charAt(0) || '?'}
|
|
60
|
+
</div>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { ReactNode, createContext, useContext } from 'react';
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import { Avatar, AvatarProps } from './Avatar.js';
|
|
4
|
+
|
|
5
|
+
const AvatarListContext = createContext<{ size: number }>({
|
|
6
|
+
size: 24,
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export function AvatarList({
|
|
10
|
+
children,
|
|
11
|
+
count,
|
|
12
|
+
size = 24,
|
|
13
|
+
}: {
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
count: number;
|
|
16
|
+
size?: number;
|
|
17
|
+
}) {
|
|
18
|
+
const width = count > 0 ? size + (count - 1) * ((size * 2) / 3) : 0;
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<AvatarListContext.Provider value={{ size }}>
|
|
22
|
+
<div
|
|
23
|
+
className="relative flex-basis-auto"
|
|
24
|
+
style={{ width, minWidth: width, height: size }}
|
|
25
|
+
>
|
|
26
|
+
{children}
|
|
27
|
+
</div>
|
|
28
|
+
</AvatarListContext.Provider>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function AvatarListItemRoot({
|
|
33
|
+
index,
|
|
34
|
+
children,
|
|
35
|
+
className,
|
|
36
|
+
}: {
|
|
37
|
+
index: number;
|
|
38
|
+
children: ReactNode;
|
|
39
|
+
className?: string;
|
|
40
|
+
}) {
|
|
41
|
+
const { size } = useContext(AvatarListContext);
|
|
42
|
+
return (
|
|
43
|
+
<div
|
|
44
|
+
className={classNames('absolute', className)}
|
|
45
|
+
style={{
|
|
46
|
+
left: index === 0 ? 0 : index * ((size * 2) / 3),
|
|
47
|
+
zIndex: index,
|
|
48
|
+
top: 0,
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
{children}
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function AvatarListItem({
|
|
57
|
+
index,
|
|
58
|
+
className,
|
|
59
|
+
...rest
|
|
60
|
+
}: {
|
|
61
|
+
index: number;
|
|
62
|
+
popIn?: boolean;
|
|
63
|
+
className?: string;
|
|
64
|
+
} & AvatarProps) {
|
|
65
|
+
const { size } = useContext(AvatarListContext);
|
|
66
|
+
return (
|
|
67
|
+
<AvatarListItemRoot index={index} className={className}>
|
|
68
|
+
<Avatar style={{ width: size, height: size }} {...rest} />
|
|
69
|
+
</AvatarListItemRoot>
|
|
70
|
+
);
|
|
71
|
+
}
|