diff --git a/index.d.ts b/index.d.ts index 452eb6b47..d60f83f9b 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,28 +1,36 @@ // This is just to make the auto-import work. // Next step is to add types for the props. export { + AccountIcon, + AddNoteIcon, AddSquareIcon, Alert, almostZero, AnnounceIcon, + AppIcon, ArchiveIcon, ArrowCcwIcon, + ArrowCwIcon, + ArrowDownIcon, ArrowRightIcon, ArrowTopRightIcon, + ArrowUpIcon, AtIcon, Avatar, Badge, BalloonIcon, BankCheckIcon, BarGraphIcon, - BaseChartOptions, + BaseInput, BellIcon, + BookIcon, BookmarkIcon, BoxIcon, Breadcrumb, Breakdown, BriefcaseIcon, Button, + ButtonCodeIcon, ButtonGroup, CakeIcon, CalendarDayIcon, @@ -35,6 +43,7 @@ export { CartIcon, CashIcon, Checkbox, + CheckboxIcon, CheckIcon, ChecklistIcon, ChevronDownIcon, @@ -42,18 +51,38 @@ export { ChevronRightIcon, ChevronUpIcon, ChipIcon, + CircleCheckIcon, + CircleCrossIcon, + CircleCrownIcon, + CircleDollarIcon, + CircleDotIcon, + CircleInfinityIcon, + CircleInfoIcon, + CircleKeyIcon, + CircleNotch, + CirclePauseIcon, + CirclePlusIcon, + CircleSubtractIcon, ClipboardIcon, ClockAltIcon, ClockIcon, + ClockManualIcon, CloseCircleIcon, CloseIcon, + CollapseIcon, + ComboBox, + CommentAltIcon, CommentIcon, + compactNumber, CompassIcon, CopyIcon, Counter, + CouponIcon, CrmIcon, + CrownIcon, Currency, DashboardIcon, + dateFromObjectId, DatePicker, DatePickerPopover, DecreaseIcon, @@ -61,76 +90,118 @@ export { DisabledIcon, DisputeIcon, Dot, + DotProgress, DotCircleIcon, + DoubleCheckIcon, DownArrowIcon, DownloadIcon, Drawer, + DropdownIcon, + DumbbellIcon, + DuplicateIcon, + DurationIcon, EditIcon, + EditNoteIcon, + EditNotesIcon, EllipsisIcon, + EmailCheckedIcon, EmailIcon, + EmailResendIcon, + EmailSendIcon, EmptyChecklistIcon, EquipmentIcon, ExportIcon, + EyeClosedIcon, EyeIcon, FaceNeutralIcon, FaceSadIcon, FaceSmileIcon, + FadeIn, + FilterIcon, + FilterIconOld, FlagIcon, flash, + FlexFee2Icon, + FlexFeeIcon, + FoodIcon, ForkIcon, + formatDate, + formatTime, FormGroup, FunnelIcon, + getChildByType, + getChildrenByType, + getInitials, getSymbol, GiftIcon, + GlobeIcon, HandIcon, + HandshakeIcon, HeaderToolbar, + HelpCenterIcon, HiddenIcon, - HiddenIcon, - HistogramOptions, - StoreCreditIcon, + HouseIcon, ImageIcon, + ImageUpload, InfinityIcon, - CircleInfoIcon, + InlineValuePopover, Input, InvoiceIcon, isOSX, isZeroDecimal, Key, KeyIcon, + KioskIcon, Label, + LabelIcon, LandscapeIcon, + LightIcon, LinkIcon, LockIcon, Login, Logo, + LogoutIcon, MagicIcon, + MedicalIcon, MegaphoneIcon, MenuIcon, + MinusIcon, MixedChecklistIcon, + MobileIcon, Modal, MoneyAddIcon, MoneyBackIcon, MoneyIcon, + MountainIcon, + MouseIcon, Number, numberFormat, + PassIcon, PauseIcon, PenIcon, Phone, PhoneIcon, - PieOptions, + PhotosIcon, PiggyBankIcon, PinIcon, PipeIcon, + PlayIcon, PlusIcon, + PolicyIcon, Popover, PopoverList, PrintIcon, ProductsIcon, + Provider, + QuestionIcon, QuestionnaireIcon, RangeSlider, ReceiptIcon, - RelativeDateRange, + ReceptionBellIcon, + ReceptionBellMoneyIcon, RefreshIcon, + RefundIcon, + RelativeDateRange, RosterIcon, RoundedSquareIcon, roundNumber, @@ -140,36 +211,61 @@ export { SearchIcon, Select, SendIcon, + SeniorIcon, + SeniorV2Icon, + SeniorV3Icon, ServiceIcon, SettingsIcon, ShapesIcon, ShareIcon, ShirtIcon, + ShoppingBagIcon, Sidebar, Skeleton, + SlideDown, Spinner, SplitPaymentIcon, SquareIcon, StackIcon, + StarFilledIcon, StarIcon, + StoreCreditIcon, + SubmitButton, Switch, Table, Tabs, Tag, + TaxIcon, Textarea, theme, + ThumbsDownIcon, + ThumbsUpIcon, TicketIcon, + ToggleButton, Tooltip, + TransferArrowIcon, TrashIcon, + TutorialsBadgeIcon, + TutorialsButtonIcon, + TutorialsSquareIcon, UnlinkIcon, + useId, + useIsClient, UserAddIcon, + UserChangedIcon, UserIcon, + UserSubtractIcon, + ValuePopoverText, VeteranIcon, + ViewNotesIcon, VoucherIcon, WaitlistIcon, + WarningDiamondIcon, WarningIcon, + WarningTriangleIcon, + WeightIcon, WifiIcon, WriteIcon, + XolaBotIcon, XrayIcon, - ImageUpload, } from "./build/ui-kit.umd"; diff --git a/package-lock.json b/package-lock.json index 29638f83a..b8307a6ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@xola/ui-kit", - "version": "2.1.20", + "version": "2.1.25", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@xola/ui-kit", - "version": "2.1.20", + "version": "2.1.25", "license": "MIT", "dependencies": { "@headlessui/react": "^1.4.0", diff --git a/package.json b/package.json index c2c7b6001..b10838b6c 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,12 @@ { "name": "@xola/ui-kit", - "version": "2.1.20", + "version": "2.1.25", "description": "Xola UI Kit", "license": "MIT", "files": [ "build", "index.css", + "index.d.ts", "tailwind.config.js", "postcss.config.js" ], @@ -14,18 +15,17 @@ "types": "index.d.ts", "scripts": { "prepare": "node scripts/prepare && vite build", - "start": "node scripts/prepare && start-storybook -p 6006 -s public", - "dev": "node scripts/prepare && start-storybook -p 6006 -s public --no-manager-cache", - "storybook": "node scripts/prepare && start-storybook -p 6006 -s public", - "build": "node scripts/prepare && vite build", - "watch": "npm run build -- --watch", + "start": "npm run storybook -s public --no-open", + "dev": "npm run storybook -s public --no-manager-cache --no-open", + "storybook": "npm run prepare && start-storybook -p 6006 -s public --no-open", + "build": "npm run prepare && vite build", "clean": "rm -rf node_modules/.vite", - "build:storybook": "node scripts/prepare && build-storybook -s public", - "lint": "xola-lint --ignore src/stories src", - "lint:fix": "xola-lint --ignore src/stories src --fix", - "lint:report": "xola-lint --ignore src/stories src --reporter=json src > eslint_report.json && echo 'ESLint report saved to eslint_report.json'", + "build:storybook": "npm run prepare && build-storybook -s public", + "lint": "xola-lint src --ignore src/stories", + "lint:fix": "xola-lint src --fix --ignore src/stories", + "lint:report": "xola-lint src --ignore src/stories --reporter=json src > eslint_report.json", "format": "prettier --write src", - "test": "xola-lint && jest", + "test": "jest", "chromatic": "chromatic --exit-zero-on-changes --build-script-name build:storybook" }, "dependencies": { diff --git a/src/components/DatePicker/DatePicker.css b/src/components/DatePicker/DatePicker.css index 54808a06c..1b6f3a626 100644 --- a/src/components/DatePicker/DatePicker.css +++ b/src/components/DatePicker/DatePicker.css @@ -127,7 +127,8 @@ } /* Change the dates within the date to have the full light blue to show that it's a part of the range */ -.date-range-picker .DayPicker-Day--selected:not(.DayPicker-Day--start):not(.DayPicker-Day--end):not(.DayPicker-Day--outside) { +.date-range-picker + .DayPicker-Day--selected:not(.DayPicker-Day--start):not(.DayPicker-Day--end):not(.DayPicker-Day--outside) { @apply rounded-none bg-blue-lighter text-black; } diff --git a/src/components/Dot.jsx b/src/components/Dot/Dot.jsx similarity index 60% rename from src/components/Dot.jsx rename to src/components/Dot/Dot.jsx index cc15107d9..a09c07294 100644 --- a/src/components/Dot.jsx +++ b/src/components/Dot/Dot.jsx @@ -11,10 +11,16 @@ const colors = { caution: "bg-caution", }; -export const Dot = ({ color = "primary", className, ...rest }) => { +const sizes = { + small: "h-1 w-1", + medium: "h-1.5 w-1.5", + large: "h-2 w-2", +}; + +export const Dot = ({ color = "primary", size = "medium", className, ...rest }) => { return ( ); diff --git a/src/components/Dot/DotProgress.jsx b/src/components/Dot/DotProgress.jsx new file mode 100644 index 000000000..a3cade55e --- /dev/null +++ b/src/components/Dot/DotProgress.jsx @@ -0,0 +1,25 @@ +import { range } from "lodash"; +import PropTypes from "prop-types"; +import React from "react"; +import { Dot } from "./Dot"; + +export const DotProgress = ({ current, total }) => { + if (total <= 1) { + return null; + } + + return ( +
+ {range(0, total).map((index) => { + const currentValue = current <= 0 ? 0 : current >= total ? current - 1 : current; + const color = index === currentValue ? "primary" : "secondary"; + return ; + })} +
+ ); +}; + +DotProgress.propTypes = { + total: PropTypes.number.isRequired, + current: PropTypes.number.isRequired, +}; diff --git a/src/components/Drawer.jsx b/src/components/Drawer.jsx index 0b7718886..08d30eadc 100644 --- a/src/components/Drawer.jsx +++ b/src/components/Drawer.jsx @@ -5,7 +5,23 @@ import React, { Fragment } from "react"; import { CloseIcon } from "../icons/CloseIcon"; import { Button } from "./Buttons/Button"; -export const Drawer = ({ isOpen = false, title, content, onClose, classNames = {}, position = "right" }) => { +const sizes = { + small: "w-72", + medium: "w-85", + large: "w-110", + xl: "w-200", + "2xl": "w-screen md:max-w-screen-md 2xl:max-w-screen-lg", // This was the old size +}; + +export const Drawer = ({ + isOpen = false, + title, + size = "medium", + content, + onClose, + classNames = {}, + position = "right", +}) => { return ( -
+
{position === "right" ? : null}
-
+
{/* eslint-disable-next-line react/jsx-max-depth */} {title}
diff --git a/src/components/Forms/BaseInput.jsx b/src/components/Forms/BaseInput.jsx index a751e0eff..50ab733f0 100644 --- a/src/components/Forms/BaseInput.jsx +++ b/src/components/Forms/BaseInput.jsx @@ -2,7 +2,7 @@ import clsx from "clsx"; import PropTypes from "prop-types"; import React from "react"; import { isEmpty, isString } from "lodash"; -import { Dot } from "../Dot"; +import { Dot } from "../Dot/Dot"; const sizes = { small: "px-3 py-1.5 text-sm leading-sm", // 30px @@ -24,8 +24,8 @@ export const BaseInput = ({ as: Tag, size = "medium", isError, className, isRequ "border border-transparent hover:border-black hover:bg-gray-lighter focus:text-black active:text-black disabled:bg-gray-lighter", sizes[size], isError - ? "border-danger focus:border-danger focus:ring-0 focus:ring-danger" - : "border-gray-light focus:border-primary focus:ring-0 focus:ring-primary", + ? "!focus:border-danger !border-danger focus:ring-0 focus:ring-danger" + : "!border-gray-light focus:border-primary focus:ring-0 focus:ring-primary", className, )} value={value} diff --git a/src/components/ImageUpload.jsx b/src/components/ImageUpload.jsx index 165f2cb9d..de9d1d31a 100644 --- a/src/components/ImageUpload.jsx +++ b/src/components/ImageUpload.jsx @@ -1,18 +1,20 @@ -import React, { useRef, useState } from "react"; -import PropTypes from "prop-types"; import clsx from "clsx"; -import { Button, ImageIcon, Logo, Spinner, TrashIcon } from ".."; +import PropTypes from "prop-types"; +import React, { useRef, useState } from "react"; +import { Button, ImageIcon, Logo, SubmitButton, TrashIcon } from ".."; export const ImageUpload = ({ src, size = "large", - onChange, - onDelete, - onError, isLoading = false, maxSize = 5, hasDelete = true, requirements = null, + caption = null, + csvAcceptFormats = "image/png,image/jpeg", + onChange, + onDelete, + onError, ...props }) => { const inputReference = useRef(); @@ -39,20 +41,28 @@ export const ImageUpload = ({ onDelete(); }; + const hasRequirements = typeof requirements === "string" ? requirements?.trim().length > 0 : !!requirements; + const hasCaption = caption ? caption.trim().length > 0 : false; + return ( -
+
{src ? ( ) : ( -
+
)}
-
+
{hasDelete ? ( <> - - {isLoading && } + + {hasCaption ? caption.trim() : "Upload New Photo"} + ) : ( - + + {hasCaption ? caption.trim() : src ? "Replace Photo" : "Upload New Photo"} + )}
- {requirements ?? ( + {hasRequirements ? ( + requirements + ) : (
Check that the image is in PNG or JPG format {maxSize ? ` and does not exceed ${maxSize}MB` : ""} @@ -101,11 +112,13 @@ export const ImageUpload = ({ ImageUpload.propTypes = { src: PropTypes.string, size: PropTypes.oneOf(["small", "medium", "large"]), - onChange: PropTypes.func.isRequired, - onDelete: PropTypes.func.isRequired, - onError: PropTypes.func.isRequired, isLoading: PropTypes.bool, maxSize: PropTypes.number, hasDelete: PropTypes.bool, - requirements: PropTypes.oneOf([PropTypes.string, PropTypes.node]), + caption: PropTypes.string, + requirements: PropTypes.oneOfType([PropTypes.node, PropTypes.string]), + csvAcceptFormats: PropTypes.string, + onChange: PropTypes.func.isRequired, + onDelete: PropTypes.func.isRequired, + onError: PropTypes.func.isRequired, }; diff --git a/src/components/Modal.jsx b/src/components/Modal.jsx index 4f8a3c88c..4e06c2f6b 100644 --- a/src/components/Modal.jsx +++ b/src/components/Modal.jsx @@ -5,14 +5,56 @@ import React, { Fragment } from "react"; import { CloseIcon } from "../icons/CloseIcon"; const sizes = { - small: "max-w-100", - medium: "max-w-125", - large: "max-w-150", - huge: "max-w-200", + small: "max-w-100", // 400px + medium: "max-w-125", // 500px + large: "max-w-150", // 600px + huge: "max-w-200", // 800px +}; + +const positions = { + center: "inline-block", + topLeft: "absolute m-4 top-0 left-0", + topRight: "absolute m-4 top-0 right-0", + bottomLeft: "absolute m-4 bottom-0 left-0", + bottomRight: "absolute m-4 bottom-0 right-0", +}; + +const animations = { + center: { + enterFrom: "translate-y-4 sm:translate-y-0 sm:scale-95", + enterTo: "translate-y-0 sm:scale-100", + leaveFrom: "translate-y-0 sm:scale-100", + leaveTo: "translate-y-4 sm:translate-y-0 sm:scale-95", + }, + topLeft: { + enterFrom: "scale-0 origin-top-left", + enterTo: "scale-100 origin-top-left", + leaveFrom: "scale-100 origin-top-left", + leaveTo: "scale-0 origin-top-left", + }, + topRight: { + enterFrom: "scale-0 origin-top-right", + enterTo: "scale-100 origin-top-right", + leaveFrom: "scale-100 origin-top-right", + leaveTo: "scale-0 origin-top-right", + }, + bottomLeft: { + enterFrom: "scale-0 origin-bottom-left", + enterTo: "scale-100 origin-bottom-left", + leaveFrom: "scale-100 origin-bottom-left", + leaveTo: "scale-0 origin-bottom-left", + }, + bottomRight: { + enterFrom: "scale-0 origin-bottom-right", + enterTo: "scale-100 origin-bottom-right", + leaveFrom: "scale-100 origin-bottom-right", + leaveTo: "scale-0 origin-bottom-right", + }, }; export const Modal = ({ size = "medium", + position = "center", isOpen = false, shouldCloseOnOutsideClick = false, onClose, @@ -42,24 +84,27 @@ export const Modal = ({ {/* This element is to trick the browser into centering the modal contents. */} - + {position === "center" && ( + + )}
{onClose ? ( @@ -81,6 +126,16 @@ export const Modal = ({ ); }; +Modal.propTypes = { + size: PropTypes.oneOf(Object.keys(sizes)), + position: PropTypes.oneOf(Object.keys(positions)), + isOpen: PropTypes.bool.isRequired, + shouldCloseOnOutsideClick: PropTypes.bool, + onClose: PropTypes.func.isRequired, + children: PropTypes.node.isRequired, + className: PropTypes.string, +}; + const Header = ({ children, description, className, ...rest }) => { return ( diff --git a/src/components/Popover/PopoverList.jsx b/src/components/Popover/PopoverList.jsx index a6fc1e284..97f636204 100644 --- a/src/components/Popover/PopoverList.jsx +++ b/src/components/Popover/PopoverList.jsx @@ -38,8 +38,8 @@ PopoverList.propTypes = { children: PropTypes.node.isRequired, }; -const Item = ({ name, isActive = false, position, total, children, className, onClickItem, ...rest }) => { - const onClick = (event) => onClickItem(event, name); +const Item = ({ name, isActive = false, id = null, position, total, children, className, onClickItem, ...rest }) => { + const onClick = (event) => onClickItem(event, name, id); return (
-
+
{label &&
{label}
} @@ -128,7 +128,7 @@ export const Login = ({