@crystallize/design-system 1.18.0 → 1.19.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/dist/index.css +91 -0
- package/dist/index.d.ts +18 -1
- package/dist/index.js +83 -3
- package/dist/index.mjs +84 -6
- package/package.json +3 -2
- package/src/index.ts +1 -0
- package/src/toast/index.ts +2 -0
- package/src/toast/toast.css +51 -0
- package/src/toast/toast.stories.tsx +110 -0
- package/src/toast/toast.tsx +72 -0
package/CHANGELOG.md
CHANGED
package/dist/index.css
CHANGED
|
@@ -3640,6 +3640,97 @@ button {
|
|
|
3640
3640
|
outline: 2px solid rgb(60, 132, 244);
|
|
3641
3641
|
}
|
|
3642
3642
|
|
|
3643
|
+
/* src/toast/toast.css */
|
|
3644
|
+
.c-toast {
|
|
3645
|
+
position: relative;
|
|
3646
|
+
display: flex;
|
|
3647
|
+
gap: 0.5rem;
|
|
3648
|
+
border-radius: 0.375rem;
|
|
3649
|
+
--tw-bg-opacity: 1;
|
|
3650
|
+
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
|
3651
|
+
padding-left: 0.75rem;
|
|
3652
|
+
padding-right: 1.5rem;
|
|
3653
|
+
--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
3654
|
+
--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
|
|
3655
|
+
box-shadow:
|
|
3656
|
+
var(--tw-ring-offset-shadow, 0 0 #0000),
|
|
3657
|
+
var(--tw-ring-shadow, 0 0 #0000),
|
|
3658
|
+
var(--tw-shadow);
|
|
3659
|
+
}
|
|
3660
|
+
.c-toast:hover .c-toast-close {
|
|
3661
|
+
display: block;
|
|
3662
|
+
}
|
|
3663
|
+
.c-toast.c-toast-with-message {
|
|
3664
|
+
padding-top: 0.75rem;
|
|
3665
|
+
padding-bottom: 0.75rem;
|
|
3666
|
+
}
|
|
3667
|
+
.c-toast.c-toast-with-message .c-toast-title {
|
|
3668
|
+
font-weight: 700;
|
|
3669
|
+
}
|
|
3670
|
+
.c-toast.c-toast-title-only {
|
|
3671
|
+
align-items: center;
|
|
3672
|
+
padding-top: 0.5rem;
|
|
3673
|
+
padding-bottom: 0.5rem;
|
|
3674
|
+
}
|
|
3675
|
+
.c-toast.c-toast-title-only .c-toast-title {
|
|
3676
|
+
font-weight: 500;
|
|
3677
|
+
}
|
|
3678
|
+
.c-toast-success {
|
|
3679
|
+
border-width: 1px;
|
|
3680
|
+
border-style: solid;
|
|
3681
|
+
--tw-border-opacity: 1;
|
|
3682
|
+
border-color: rgb(var(--c-color-cyan-300-600) / var(--tw-border-opacity));
|
|
3683
|
+
--tw-bg-opacity: 1;
|
|
3684
|
+
background-color: rgb(var(--c-color-cyan-100-800) / var(--tw-bg-opacity));
|
|
3685
|
+
--tw-text-opacity: 1;
|
|
3686
|
+
color: rgb(var(--c-color-green-600-300) / var(--tw-text-opacity));
|
|
3687
|
+
}
|
|
3688
|
+
.c-toast-error {
|
|
3689
|
+
border-width: 1px;
|
|
3690
|
+
border-style: solid;
|
|
3691
|
+
--tw-border-opacity: 1;
|
|
3692
|
+
border-color: rgb(var(--c-color-pink-200-700) / var(--tw-border-opacity));
|
|
3693
|
+
--tw-bg-opacity: 1;
|
|
3694
|
+
background-color: rgb(var(--c-color-pink-100-800) / var(--tw-bg-opacity));
|
|
3695
|
+
--tw-text-opacity: 1;
|
|
3696
|
+
color: rgb(var(--c-color-pink-700-200) / var(--tw-text-opacity));
|
|
3697
|
+
}
|
|
3698
|
+
.c-toast-warning {
|
|
3699
|
+
border-width: 1px;
|
|
3700
|
+
border-style: solid;
|
|
3701
|
+
--tw-border-opacity: 1;
|
|
3702
|
+
border-color: rgb(var(--c-color-orange-200-700) / var(--tw-border-opacity));
|
|
3703
|
+
--tw-bg-opacity: 1;
|
|
3704
|
+
background-color: rgb(var(--c-color-orange-100-800) / var(--tw-bg-opacity));
|
|
3705
|
+
--tw-text-opacity: 1;
|
|
3706
|
+
color: rgb(var(--c-color-green-600-300) / var(--tw-text-opacity));
|
|
3707
|
+
}
|
|
3708
|
+
.c-toast-info {
|
|
3709
|
+
border-width: 1px;
|
|
3710
|
+
border-style: solid;
|
|
3711
|
+
--tw-border-opacity: 1;
|
|
3712
|
+
border-color: rgb(var(--c-color-purple-200-700) / var(--tw-border-opacity));
|
|
3713
|
+
--tw-bg-opacity: 1;
|
|
3714
|
+
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
|
3715
|
+
--tw-text-opacity: 1;
|
|
3716
|
+
color: rgb(var(--c-color-green-600-300) / var(--tw-text-opacity));
|
|
3717
|
+
}
|
|
3718
|
+
.c-toast-title {
|
|
3719
|
+
font-size: 0.875rem;
|
|
3720
|
+
line-height: 1.25rem;
|
|
3721
|
+
}
|
|
3722
|
+
.c-toast-message {
|
|
3723
|
+
font-size: 13px;
|
|
3724
|
+
font-weight: 500;
|
|
3725
|
+
line-height: 1rem;
|
|
3726
|
+
}
|
|
3727
|
+
.c-toast-close {
|
|
3728
|
+
position: absolute;
|
|
3729
|
+
right: 0.25rem;
|
|
3730
|
+
top: 0.25rem;
|
|
3731
|
+
display: none;
|
|
3732
|
+
}
|
|
3733
|
+
|
|
3643
3734
|
/* src/switch/switch.css */
|
|
3644
3735
|
.c-switch-root {
|
|
3645
3736
|
position: relative;
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
|
|
|
11
11
|
import * as ProgressPrimitives from '@radix-ui/react-progress';
|
|
12
12
|
import * as _radix_ui_react_select from '@radix-ui/react-select';
|
|
13
13
|
import * as SliderPrimitive from '@radix-ui/react-slider';
|
|
14
|
+
export { Toaster } from 'sonner';
|
|
14
15
|
import * as RadixTooltip from '@radix-ui/react-tooltip';
|
|
15
16
|
import * as RadixSwitch from '@radix-ui/react-switch';
|
|
16
17
|
|
|
@@ -433,6 +434,22 @@ declare function RichTextEditor({ initialData, language, labelTranslations, ...r
|
|
|
433
434
|
initialData?: CrystallizeRichText | null;
|
|
434
435
|
}): JSX.Element;
|
|
435
436
|
|
|
437
|
+
declare const toastStyles: (props?: ({
|
|
438
|
+
type?: "info" | "error" | "warning" | "success" | null | undefined;
|
|
439
|
+
} & class_variance_authority_dist_types.ClassProp) | undefined) => string;
|
|
440
|
+
type ToastType = 'info' | 'error' | 'success' | 'warning';
|
|
441
|
+
type ToastStylesProps = VariantProps<typeof toastStyles>;
|
|
442
|
+
type ToastProps = Omit<React.ComponentProps<'div'>, 'title'> & Omit<ToastStylesProps, 'type'> & {
|
|
443
|
+
title: React.ReactNode;
|
|
444
|
+
type?: ToastType;
|
|
445
|
+
message?: React.ReactNode;
|
|
446
|
+
timeout?: number;
|
|
447
|
+
};
|
|
448
|
+
declare const toast: {
|
|
449
|
+
({ title, message, type, timeout }: ToastProps): string;
|
|
450
|
+
dismiss: (id?: string | number | undefined) => string | number;
|
|
451
|
+
};
|
|
452
|
+
|
|
436
453
|
type TooltipProps = Partial<Pick<RadixTooltip.TooltipContentProps, 'side'>> & {
|
|
437
454
|
children: ReactNode;
|
|
438
455
|
content: ReactNode;
|
|
@@ -575,4 +592,4 @@ declare const tokens: {
|
|
|
575
592
|
card: string;
|
|
576
593
|
};
|
|
577
594
|
|
|
578
|
-
export { ActionMenu, Avatar, Button, ButtonProps, Card, Checkbox, CheckboxProps, CheckboxRef, Container, CrystallizeRichText, CrystallizeRichTextActionMenuItem, Dialog, DropdownMenu, DropdownMenuRootProps, Icon, IconButton, IconButtonProps, InlineRadio, Input, InputWithLabel, Label, Progress, Radio, RichTextEditor, Select, Slider, Spinner, StackIcon, Switch, Tag, Tooltip, buttonTokens, cardToken, destroyAll, showConfirm, showDialog, showError, showInfo, showWarning, tokens };
|
|
595
|
+
export { ActionMenu, Avatar, Button, ButtonProps, Card, Checkbox, CheckboxProps, CheckboxRef, Container, CrystallizeRichText, CrystallizeRichTextActionMenuItem, Dialog, DropdownMenu, DropdownMenuRootProps, Icon, IconButton, IconButtonProps, InlineRadio, Input, InputWithLabel, Label, Progress, Radio, RichTextEditor, Select, Slider, Spinner, StackIcon, Switch, Tag, ToastProps, Tooltip, buttonTokens, cardToken, destroyAll, showConfirm, showDialog, showError, showInfo, showWarning, toast, tokens };
|
package/dist/index.js
CHANGED
|
@@ -28875,6 +28875,7 @@ __export(src_exports, {
|
|
|
28875
28875
|
StackIcon: () => StackIcon,
|
|
28876
28876
|
Switch: () => Switch2,
|
|
28877
28877
|
Tag: () => Tag,
|
|
28878
|
+
Toaster: () => import_sonner2.Toaster,
|
|
28878
28879
|
Tooltip: () => Tooltip,
|
|
28879
28880
|
buttonTokens: () => buttonTokens,
|
|
28880
28881
|
cardToken: () => cardToken,
|
|
@@ -28884,6 +28885,7 @@ __export(src_exports, {
|
|
|
28884
28885
|
showError: () => showError,
|
|
28885
28886
|
showInfo: () => showInfo,
|
|
28886
28887
|
showWarning: () => showWarning,
|
|
28888
|
+
toast: () => toast,
|
|
28887
28889
|
tokens: () => tokens
|
|
28888
28890
|
});
|
|
28889
28891
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -38069,14 +38071,90 @@ function RichTextEditorWithoutContext({
|
|
|
38069
38071
|
});
|
|
38070
38072
|
}
|
|
38071
38073
|
|
|
38074
|
+
// src/toast/index.ts
|
|
38075
|
+
var import_sonner2 = require("sonner");
|
|
38076
|
+
|
|
38077
|
+
// src/toast/toast.tsx
|
|
38078
|
+
var import_class_variance_authority19 = require("class-variance-authority");
|
|
38079
|
+
var import_sonner = require("sonner");
|
|
38080
|
+
var import_jsx_runtime138 = require("react/jsx-runtime");
|
|
38081
|
+
var toastStyles = (0, import_class_variance_authority19.cva)("c-toast", {
|
|
38082
|
+
variants: {
|
|
38083
|
+
type: {
|
|
38084
|
+
info: "c-toast-info",
|
|
38085
|
+
error: "c-toast-error",
|
|
38086
|
+
success: "c-toast-success",
|
|
38087
|
+
warning: "c-toast-warning"
|
|
38088
|
+
}
|
|
38089
|
+
},
|
|
38090
|
+
defaultVariants: {
|
|
38091
|
+
type: "success"
|
|
38092
|
+
}
|
|
38093
|
+
});
|
|
38094
|
+
var iconMap = {
|
|
38095
|
+
info: Icon.Info,
|
|
38096
|
+
error: Icon.Error,
|
|
38097
|
+
success: Icon.CheckWithCircle,
|
|
38098
|
+
warning: Icon.Warning
|
|
38099
|
+
};
|
|
38100
|
+
var toast = ({ title, message, type = "success", timeout = 6e3 }) => {
|
|
38101
|
+
const ToastIcon = iconMap[type];
|
|
38102
|
+
const withMessage = !!message;
|
|
38103
|
+
const toastId = Date.now().toString();
|
|
38104
|
+
import_sonner.toast.custom(
|
|
38105
|
+
(id) => /* @__PURE__ */ (0, import_jsx_runtime138.jsxs)("div", {
|
|
38106
|
+
"data-testid": "toast-content",
|
|
38107
|
+
className: (0, import_class_variance_authority19.cx)(toastStyles({ type }), withMessage ? "c-toast-with-message" : "c-toast-title-only"),
|
|
38108
|
+
children: [
|
|
38109
|
+
/* @__PURE__ */ (0, import_jsx_runtime138.jsx)("div", {
|
|
38110
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(ToastIcon, {
|
|
38111
|
+
width: 26,
|
|
38112
|
+
height: 26
|
|
38113
|
+
})
|
|
38114
|
+
}),
|
|
38115
|
+
/* @__PURE__ */ (0, import_jsx_runtime138.jsxs)("div", {
|
|
38116
|
+
children: [
|
|
38117
|
+
/* @__PURE__ */ (0, import_jsx_runtime138.jsx)("div", {
|
|
38118
|
+
className: "c-toast-title",
|
|
38119
|
+
children: title
|
|
38120
|
+
}),
|
|
38121
|
+
!!message && /* @__PURE__ */ (0, import_jsx_runtime138.jsx)("div", {
|
|
38122
|
+
className: "c-toast-message",
|
|
38123
|
+
children: message
|
|
38124
|
+
})
|
|
38125
|
+
]
|
|
38126
|
+
}),
|
|
38127
|
+
/* @__PURE__ */ (0, import_jsx_runtime138.jsx)("div", {
|
|
38128
|
+
className: "c-toast-close",
|
|
38129
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(IconButton, {
|
|
38130
|
+
onClick: () => import_sonner.toast.dismiss(id),
|
|
38131
|
+
size: "xs",
|
|
38132
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(Icon.Cancel, {
|
|
38133
|
+
width: 12,
|
|
38134
|
+
height: 12
|
|
38135
|
+
})
|
|
38136
|
+
})
|
|
38137
|
+
})
|
|
38138
|
+
]
|
|
38139
|
+
}),
|
|
38140
|
+
{
|
|
38141
|
+
id: toastId,
|
|
38142
|
+
duration: timeout,
|
|
38143
|
+
style: { width: "100%" }
|
|
38144
|
+
}
|
|
38145
|
+
);
|
|
38146
|
+
return toastId;
|
|
38147
|
+
};
|
|
38148
|
+
toast.dismiss = import_sonner.toast.dismiss;
|
|
38149
|
+
|
|
38072
38150
|
// src/switch/switch.tsx
|
|
38073
38151
|
var RadixSwitch = __toESM(require("@radix-ui/react-switch"));
|
|
38074
|
-
var
|
|
38152
|
+
var import_jsx_runtime139 = require("react/jsx-runtime");
|
|
38075
38153
|
function Switch2(props) {
|
|
38076
|
-
return /* @__PURE__ */ (0,
|
|
38154
|
+
return /* @__PURE__ */ (0, import_jsx_runtime139.jsx)(RadixSwitch.Root, {
|
|
38077
38155
|
...props,
|
|
38078
38156
|
className: "c-switch-root",
|
|
38079
|
-
children: /* @__PURE__ */ (0,
|
|
38157
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime139.jsx)(RadixSwitch.Thumb, {
|
|
38080
38158
|
className: "c-switch-thumb"
|
|
38081
38159
|
})
|
|
38082
38160
|
});
|
|
@@ -38111,6 +38189,7 @@ var tokens = {
|
|
|
38111
38189
|
StackIcon,
|
|
38112
38190
|
Switch,
|
|
38113
38191
|
Tag,
|
|
38192
|
+
Toaster,
|
|
38114
38193
|
Tooltip,
|
|
38115
38194
|
buttonTokens,
|
|
38116
38195
|
cardToken,
|
|
@@ -38120,5 +38199,6 @@ var tokens = {
|
|
|
38120
38199
|
showError,
|
|
38121
38200
|
showInfo,
|
|
38122
38201
|
showWarning,
|
|
38202
|
+
toast,
|
|
38123
38203
|
tokens
|
|
38124
38204
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1443,7 +1443,7 @@ Dashboard.displayName = "DashboardIcon";
|
|
|
1443
1443
|
// src/iconography/date.tsx
|
|
1444
1444
|
import { forwardRef as forwardRef27 } from "react";
|
|
1445
1445
|
import { jsx as jsx34, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1446
|
-
var
|
|
1446
|
+
var Date2 = forwardRef27((delegated, ref) => {
|
|
1447
1447
|
return /* @__PURE__ */ jsxs25("svg", {
|
|
1448
1448
|
ref,
|
|
1449
1449
|
width: "22",
|
|
@@ -1555,7 +1555,7 @@ var Date = forwardRef27((delegated, ref) => {
|
|
|
1555
1555
|
]
|
|
1556
1556
|
});
|
|
1557
1557
|
});
|
|
1558
|
-
|
|
1558
|
+
Date2.displayName = "Date";
|
|
1559
1559
|
|
|
1560
1560
|
// src/iconography/document.tsx
|
|
1561
1561
|
import { forwardRef as forwardRef28 } from "react";
|
|
@@ -5298,7 +5298,7 @@ var Icon = {
|
|
|
5298
5298
|
Location,
|
|
5299
5299
|
Video,
|
|
5300
5300
|
GridRelation,
|
|
5301
|
-
Date,
|
|
5301
|
+
Date: Date2,
|
|
5302
5302
|
Relation,
|
|
5303
5303
|
Numeric,
|
|
5304
5304
|
FileUpload,
|
|
@@ -9263,14 +9263,90 @@ function RichTextEditorWithoutContext({
|
|
|
9263
9263
|
});
|
|
9264
9264
|
}
|
|
9265
9265
|
|
|
9266
|
+
// src/toast/index.ts
|
|
9267
|
+
import { Toaster } from "sonner";
|
|
9268
|
+
|
|
9269
|
+
// src/toast/toast.tsx
|
|
9270
|
+
import { cva as cva12, cx as cx11 } from "class-variance-authority";
|
|
9271
|
+
import { toast as sonnerToast } from "sonner";
|
|
9272
|
+
import { jsx as jsx138, jsxs as jsxs114 } from "react/jsx-runtime";
|
|
9273
|
+
var toastStyles = cva12("c-toast", {
|
|
9274
|
+
variants: {
|
|
9275
|
+
type: {
|
|
9276
|
+
info: "c-toast-info",
|
|
9277
|
+
error: "c-toast-error",
|
|
9278
|
+
success: "c-toast-success",
|
|
9279
|
+
warning: "c-toast-warning"
|
|
9280
|
+
}
|
|
9281
|
+
},
|
|
9282
|
+
defaultVariants: {
|
|
9283
|
+
type: "success"
|
|
9284
|
+
}
|
|
9285
|
+
});
|
|
9286
|
+
var iconMap = {
|
|
9287
|
+
info: Icon.Info,
|
|
9288
|
+
error: Icon.Error,
|
|
9289
|
+
success: Icon.CheckWithCircle,
|
|
9290
|
+
warning: Icon.Warning
|
|
9291
|
+
};
|
|
9292
|
+
var toast = ({ title, message, type = "success", timeout = 6e3 }) => {
|
|
9293
|
+
const ToastIcon = iconMap[type];
|
|
9294
|
+
const withMessage = !!message;
|
|
9295
|
+
const toastId = Date.now().toString();
|
|
9296
|
+
sonnerToast.custom(
|
|
9297
|
+
(id) => /* @__PURE__ */ jsxs114("div", {
|
|
9298
|
+
"data-testid": "toast-content",
|
|
9299
|
+
className: cx11(toastStyles({ type }), withMessage ? "c-toast-with-message" : "c-toast-title-only"),
|
|
9300
|
+
children: [
|
|
9301
|
+
/* @__PURE__ */ jsx138("div", {
|
|
9302
|
+
children: /* @__PURE__ */ jsx138(ToastIcon, {
|
|
9303
|
+
width: 26,
|
|
9304
|
+
height: 26
|
|
9305
|
+
})
|
|
9306
|
+
}),
|
|
9307
|
+
/* @__PURE__ */ jsxs114("div", {
|
|
9308
|
+
children: [
|
|
9309
|
+
/* @__PURE__ */ jsx138("div", {
|
|
9310
|
+
className: "c-toast-title",
|
|
9311
|
+
children: title
|
|
9312
|
+
}),
|
|
9313
|
+
!!message && /* @__PURE__ */ jsx138("div", {
|
|
9314
|
+
className: "c-toast-message",
|
|
9315
|
+
children: message
|
|
9316
|
+
})
|
|
9317
|
+
]
|
|
9318
|
+
}),
|
|
9319
|
+
/* @__PURE__ */ jsx138("div", {
|
|
9320
|
+
className: "c-toast-close",
|
|
9321
|
+
children: /* @__PURE__ */ jsx138(IconButton, {
|
|
9322
|
+
onClick: () => sonnerToast.dismiss(id),
|
|
9323
|
+
size: "xs",
|
|
9324
|
+
children: /* @__PURE__ */ jsx138(Icon.Cancel, {
|
|
9325
|
+
width: 12,
|
|
9326
|
+
height: 12
|
|
9327
|
+
})
|
|
9328
|
+
})
|
|
9329
|
+
})
|
|
9330
|
+
]
|
|
9331
|
+
}),
|
|
9332
|
+
{
|
|
9333
|
+
id: toastId,
|
|
9334
|
+
duration: timeout,
|
|
9335
|
+
style: { width: "100%" }
|
|
9336
|
+
}
|
|
9337
|
+
);
|
|
9338
|
+
return toastId;
|
|
9339
|
+
};
|
|
9340
|
+
toast.dismiss = sonnerToast.dismiss;
|
|
9341
|
+
|
|
9266
9342
|
// src/switch/switch.tsx
|
|
9267
9343
|
import * as RadixSwitch from "@radix-ui/react-switch";
|
|
9268
|
-
import { jsx as
|
|
9344
|
+
import { jsx as jsx139 } from "react/jsx-runtime";
|
|
9269
9345
|
function Switch2(props) {
|
|
9270
|
-
return /* @__PURE__ */
|
|
9346
|
+
return /* @__PURE__ */ jsx139(RadixSwitch.Root, {
|
|
9271
9347
|
...props,
|
|
9272
9348
|
className: "c-switch-root",
|
|
9273
|
-
children: /* @__PURE__ */
|
|
9349
|
+
children: /* @__PURE__ */ jsx139(RadixSwitch.Thumb, {
|
|
9274
9350
|
className: "c-switch-thumb"
|
|
9275
9351
|
})
|
|
9276
9352
|
});
|
|
@@ -9304,6 +9380,7 @@ export {
|
|
|
9304
9380
|
StackIcon,
|
|
9305
9381
|
Switch2 as Switch,
|
|
9306
9382
|
Tag,
|
|
9383
|
+
Toaster,
|
|
9307
9384
|
Tooltip,
|
|
9308
9385
|
buttonTokens,
|
|
9309
9386
|
cardToken,
|
|
@@ -9313,5 +9390,6 @@ export {
|
|
|
9313
9390
|
showError,
|
|
9314
9391
|
showInfo,
|
|
9315
9392
|
showWarning,
|
|
9393
|
+
toast,
|
|
9316
9394
|
tokens
|
|
9317
9395
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crystallize/design-system",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.19.0",
|
|
4
4
|
"types": "./dist/index.d.ts",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -45,10 +45,11 @@
|
|
|
45
45
|
"@radix-ui/react-radio-group": "1.1.0",
|
|
46
46
|
"@radix-ui/react-select": "1.1.2",
|
|
47
47
|
"@radix-ui/react-slider": "^1.1.0",
|
|
48
|
-
"@radix-ui/react-tooltip": "1.0.0",
|
|
49
48
|
"@radix-ui/react-switch": "^1.0.2",
|
|
49
|
+
"@radix-ui/react-tooltip": "1.0.0",
|
|
50
50
|
"class-variance-authority": "^0.4.0",
|
|
51
51
|
"lexical": "0.10.0",
|
|
52
|
+
"sonner": "^0.6.2",
|
|
52
53
|
"use-debounce": "8.0.4"
|
|
53
54
|
},
|
|
54
55
|
"peerDependencies": {
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
.c-toast {
|
|
2
|
+
@apply relative flex gap-2 rounded-md bg-white pl-3 pr-6 shadow-sm;
|
|
3
|
+
|
|
4
|
+
&:hover .c-toast-close {
|
|
5
|
+
@apply block;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
&.c-toast-with-message {
|
|
9
|
+
@apply py-3;
|
|
10
|
+
|
|
11
|
+
& .c-toast-title {
|
|
12
|
+
@apply font-bold;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
&.c-toast-title-only {
|
|
17
|
+
@apply items-center py-2;
|
|
18
|
+
|
|
19
|
+
& .c-toast-title {
|
|
20
|
+
@apply font-medium;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.c-toast-success {
|
|
26
|
+
@apply border border-solid border-cyan-300-600 bg-cyan-100-800 text-green-600-300;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.c-toast-error {
|
|
30
|
+
@apply border border-solid border-pink-200-700 bg-pink-100-800 text-pink-700-200;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.c-toast-warning {
|
|
34
|
+
@apply border border-solid border-orange-200-700 bg-orange-100-800 text-green-600-300;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.c-toast-info {
|
|
38
|
+
@apply border border-solid border-purple-200-700 bg-white text-green-600-300;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.c-toast-title {
|
|
42
|
+
@apply text-sm;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.c-toast-message {
|
|
46
|
+
@apply text-[13px] font-medium leading-4;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.c-toast-close {
|
|
50
|
+
@apply absolute right-1 top-1 hidden;
|
|
51
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
|
|
3
|
+
import { toast, Toaster } from '.';
|
|
4
|
+
import { Button } from '../button';
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof toast> = {
|
|
7
|
+
title: 'Components/Toast',
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default meta;
|
|
11
|
+
type Story = StoryObj<typeof toast>;
|
|
12
|
+
|
|
13
|
+
export const SimpleToast: Story = {
|
|
14
|
+
name: 'Simple Toast',
|
|
15
|
+
render: () => (
|
|
16
|
+
<>
|
|
17
|
+
<Toaster />
|
|
18
|
+
<div className="flex w-1/2 gap-2">
|
|
19
|
+
<Button onClick={() => toast({ title: 'You did something good' })}>Success toast</Button>
|
|
20
|
+
<Button onClick={() => toast({ title: 'You have been warned buddy', type: 'warning' })}>Warning toast</Button>
|
|
21
|
+
<Button onClick={() => toast({ title: 'There was a oopsie daisy ', type: 'error' })}>Error toast</Button>
|
|
22
|
+
<Button onClick={() => toast({ title: 'Let me inform you about something ', type: 'info' })}>
|
|
23
|
+
Info toast
|
|
24
|
+
</Button>
|
|
25
|
+
</div>
|
|
26
|
+
</>
|
|
27
|
+
),
|
|
28
|
+
};
|
|
29
|
+
export const WarningToast: Story = {
|
|
30
|
+
name: 'Toast with message ',
|
|
31
|
+
render: () => (
|
|
32
|
+
<>
|
|
33
|
+
<Toaster />
|
|
34
|
+
<div
|
|
35
|
+
className="flex w-full
|
|
36
|
+
gap-4"
|
|
37
|
+
>
|
|
38
|
+
<Button
|
|
39
|
+
onClick={() =>
|
|
40
|
+
toast({
|
|
41
|
+
title: 'You did alot of good',
|
|
42
|
+
message: 'So let me tell you are story about the bread and the toast',
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
>
|
|
46
|
+
Success message
|
|
47
|
+
</Button>
|
|
48
|
+
|
|
49
|
+
<Button
|
|
50
|
+
onClick={() =>
|
|
51
|
+
toast({
|
|
52
|
+
title: 'You have been warned with a explanation',
|
|
53
|
+
type: 'warning',
|
|
54
|
+
message: 'Here i could explain in detail why i am warning you.',
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
>
|
|
58
|
+
Warning message
|
|
59
|
+
</Button>
|
|
60
|
+
<Button
|
|
61
|
+
onClick={() =>
|
|
62
|
+
toast({
|
|
63
|
+
title: 'There was an oopsie daisy',
|
|
64
|
+
type: 'error',
|
|
65
|
+
message: 'And it happend because you clicked the button above',
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
>
|
|
69
|
+
Error message
|
|
70
|
+
</Button>
|
|
71
|
+
<Button
|
|
72
|
+
onClick={() =>
|
|
73
|
+
toast({
|
|
74
|
+
title: 'This is that something',
|
|
75
|
+
type: 'info',
|
|
76
|
+
message: 'And this is something with more details',
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
>
|
|
80
|
+
Info message
|
|
81
|
+
</Button>
|
|
82
|
+
</div>
|
|
83
|
+
</>
|
|
84
|
+
),
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const TimeoutToast: Story = {
|
|
88
|
+
name: 'Timeout toast',
|
|
89
|
+
render: () => (
|
|
90
|
+
<>
|
|
91
|
+
<Toaster />
|
|
92
|
+
<div className="flex w-full gap-4">
|
|
93
|
+
<Button onClick={() => toast({ title: 'Can you read this? ', timeout: 500, type: 'info' })}>Quick toast</Button>
|
|
94
|
+
|
|
95
|
+
<Button
|
|
96
|
+
onClick={() =>
|
|
97
|
+
toast({
|
|
98
|
+
title: 'A slow message',
|
|
99
|
+
message: 'With with 20s duration, you can cross it out if you hover it ',
|
|
100
|
+
timeout: 20000,
|
|
101
|
+
type: 'info',
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
>
|
|
105
|
+
A slow toast
|
|
106
|
+
</Button>
|
|
107
|
+
</div>
|
|
108
|
+
</>
|
|
109
|
+
),
|
|
110
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { cva, cx, VariantProps } from 'class-variance-authority';
|
|
2
|
+
import { toast as sonnerToast } from 'sonner';
|
|
3
|
+
|
|
4
|
+
import { IconButton } from '../icon-button';
|
|
5
|
+
import { Icon } from '../iconography';
|
|
6
|
+
import './toast.css';
|
|
7
|
+
|
|
8
|
+
const toastStyles = cva('c-toast', {
|
|
9
|
+
variants: {
|
|
10
|
+
type: {
|
|
11
|
+
info: 'c-toast-info',
|
|
12
|
+
error: 'c-toast-error',
|
|
13
|
+
success: 'c-toast-success',
|
|
14
|
+
warning: 'c-toast-warning',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
defaultVariants: {
|
|
18
|
+
type: 'success',
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
type ToastType = 'info' | 'error' | 'success' | 'warning';
|
|
23
|
+
type ToastStylesProps = VariantProps<typeof toastStyles>;
|
|
24
|
+
export type ToastProps = Omit<React.ComponentProps<'div'>, 'title'> &
|
|
25
|
+
Omit<ToastStylesProps, 'type'> & {
|
|
26
|
+
title: React.ReactNode;
|
|
27
|
+
type?: ToastType;
|
|
28
|
+
message?: React.ReactNode;
|
|
29
|
+
timeout?: number;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const iconMap = {
|
|
33
|
+
info: Icon.Info,
|
|
34
|
+
error: Icon.Error,
|
|
35
|
+
success: Icon.CheckWithCircle,
|
|
36
|
+
warning: Icon.Warning,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const toast = ({ title, message, type = 'success', timeout = 6000 }: ToastProps) => {
|
|
40
|
+
const ToastIcon = iconMap[type];
|
|
41
|
+
const withMessage = !!message;
|
|
42
|
+
const toastId = Date.now().toString();
|
|
43
|
+
|
|
44
|
+
sonnerToast.custom(
|
|
45
|
+
id => (
|
|
46
|
+
<div
|
|
47
|
+
data-testid="toast-content"
|
|
48
|
+
className={cx(toastStyles({ type }), withMessage ? 'c-toast-with-message' : 'c-toast-title-only')}
|
|
49
|
+
>
|
|
50
|
+
<div>{<ToastIcon width={26} height={26} />}</div>
|
|
51
|
+
<div>
|
|
52
|
+
<div className="c-toast-title">{title}</div>
|
|
53
|
+
{!!message && <div className="c-toast-message">{message}</div>}
|
|
54
|
+
</div>
|
|
55
|
+
<div className="c-toast-close">
|
|
56
|
+
<IconButton onClick={() => sonnerToast.dismiss(id)} size="xs">
|
|
57
|
+
<Icon.Cancel width={12} height={12} />
|
|
58
|
+
</IconButton>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
),
|
|
62
|
+
{
|
|
63
|
+
id: toastId,
|
|
64
|
+
duration: timeout,
|
|
65
|
+
style: { width: '100%' },
|
|
66
|
+
},
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
return toastId;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
toast.dismiss = sonnerToast.dismiss;
|