@snacky/ui 0.10.0 → 0.11.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 +34 -0
- package/README.md +4 -3
- package/dist/index.cjs +134 -111
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +22 -2
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +24 -1
- package/dist/index.d.ts +24 -1
- package/dist/index.js +99 -77
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,40 @@ How `@snacky/ui` got to its current state. The README documents what the
|
|
|
4
4
|
package *is*; this documents how it got there, including the mistakes, so the
|
|
5
5
|
verification claims in the README can be taken at face value.
|
|
6
6
|
|
|
7
|
+
## PageIndicator, and a semantic role for indicator dots (0.11.0)
|
|
8
|
+
|
|
9
|
+
`PageIndicator` is the dot row under a carousel: 8x8 dots, a 28x8 pill for the
|
|
10
|
+
current page, `gap/cell` apart, so the row stays 8 tall whichever page is
|
|
11
|
+
showing. It reports position rather than changing it, so the dots are
|
|
12
|
+
`aria-hidden` with no click target and the row carries a single label ("Page 2
|
|
13
|
+
of 3" by default). Make the carousel itself operable and let this follow it.
|
|
14
|
+
|
|
15
|
+
The component is small; the reason it exists is the two tokens under it.
|
|
16
|
+
`--bg-indicator-active` and `--bg-indicator-inactive` are new semantic roles,
|
|
17
|
+
referencing `--color-amber-500` and `--color-neutral-200`. Adding a role rather
|
|
18
|
+
than reusing one needs a reason, and there were two. Figma drew the dots as raw
|
|
19
|
+
hex, one of them `#dadada`, a grey in no ramp at all. And `Stepper` was already
|
|
20
|
+
borrowing: its done dot painted `--icon-brand`, an icon token used as a shape
|
|
21
|
+
fill, and its pending dot `--bg-action-disabled`, which says a step the order
|
|
22
|
+
has not reached yet is a control you cannot use. Two components needing
|
|
23
|
+
"reached" versus "not yet", both saying something false, is what a missing role
|
|
24
|
+
looks like. Stepper now uses the pair, and its rendered colours are unchanged
|
|
25
|
+
(`#f8b732` and `#cccccc`, exactly as before).
|
|
26
|
+
|
|
27
|
+
Worth knowing if you theme the system: `--bg-indicator-inactive` and
|
|
28
|
+
`--bg-action-disabled` resolve to the same grey today but are free to diverge,
|
|
29
|
+
which is the point. Override the indicator one to restyle carousels and
|
|
30
|
+
progress dots without touching disabled controls.
|
|
31
|
+
|
|
32
|
+
compose-ui ships the same as `compose-v2.1.0`: `SnackyPageIndicator`, the
|
|
33
|
+
`SnackyColor.bgIndicatorActive`/`bgIndicatorInactive` pair, and the same Stepper
|
|
34
|
+
change. Both are additive, so neither release breaks anything.
|
|
35
|
+
|
|
36
|
+
Two README corrections came along: compose-ui still claimed
|
|
37
|
+
`SnackyPointBalanceBanner` paints the `primary-500` primitive, which stopped
|
|
38
|
+
being true when its binding was fixed against Figma in 0.10.0, and both READMEs
|
|
39
|
+
still counted 11 solid icons rather than 12.
|
|
40
|
+
|
|
7
41
|
## Brand ramp renamed to amber, components re-checked against Figma (0.10.0)
|
|
8
42
|
|
|
9
43
|
**Breaking: the brand primitive ramp is now `amber`.** It was the only
|
package/README.md
CHANGED
|
@@ -121,19 +121,20 @@ placeholder artwork rather than a real icon prop. Apply your own
|
|
|
121
121
|
|
|
122
122
|
## What's here
|
|
123
123
|
|
|
124
|
-
All
|
|
124
|
+
All 25 documented components, matching the real Figma-sourced spec values
|
|
125
125
|
(padding, colors, radius, states - all sourced directly from the design
|
|
126
126
|
tokens, not eyeballed):
|
|
127
127
|
|
|
128
128
|
Button, IconButton/UploadButton, Input family (TextField, SearchField,
|
|
129
129
|
OtpField, CopyField, ChatInput, AddressResult), Chips (ProductChip/FilterChip),
|
|
130
|
-
RadioOption, Checkbox, Toggle, NavBar, TabRow, Header,
|
|
130
|
+
RadioOption, Checkbox, Toggle, NavBar, TabRow, Header, PageIndicator, Banner
|
|
131
|
+
family, Badge family,
|
|
131
132
|
Callout, List (OrderListItem/NotificationListItem), Accordion, BottomSheet
|
|
132
133
|
(the shared Modal shell), Section (the shared content-block shell), Avatar,
|
|
133
134
|
Illustration, ProductImage, ProductCard.
|
|
134
135
|
|
|
135
136
|
Plus the icon set, as `SnackyIcons.outline.*` and `SnackyIcons.solid.*` (42
|
|
136
|
-
Outline,
|
|
137
|
+
Outline, 12 Solid). Two things to know: they are **filled** shapes rather than
|
|
137
138
|
stroked paths, so there is no `strokeWidth` to set, and the set is **not
|
|
138
139
|
uniform** - each icon is authored at 16, 20 or 24px and defaults to its own
|
|
139
140
|
natural size, so pass `width`/`height` if you need them to match.
|
package/dist/index.cjs
CHANGED
|
@@ -45,6 +45,7 @@ __export(index_exports, {
|
|
|
45
45
|
NotificationListItem: () => NotificationListItem,
|
|
46
46
|
OrderListItem: () => OrderListItem,
|
|
47
47
|
OtpField: () => OtpField,
|
|
48
|
+
PageIndicator: () => PageIndicator,
|
|
48
49
|
PointBalanceBanner: () => PointBalanceBanner,
|
|
49
50
|
ProductCard: () => ProductCard,
|
|
50
51
|
ProductChip: () => ProductChip,
|
|
@@ -837,43 +838,64 @@ function AlertBanner({ message, countdown, className }) {
|
|
|
837
838
|
] });
|
|
838
839
|
}
|
|
839
840
|
|
|
840
|
-
// src/components/
|
|
841
|
+
// src/components/PageIndicator/PageIndicator.tsx
|
|
841
842
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
843
|
+
function PageIndicator({ count, activeIndex, ariaLabel, className }) {
|
|
844
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
845
|
+
"div",
|
|
846
|
+
{
|
|
847
|
+
className: cx("snacky-page-indicator", className),
|
|
848
|
+
role: "status",
|
|
849
|
+
"aria-label": ariaLabel ?? `Page ${activeIndex + 1} of ${count}`,
|
|
850
|
+
children: Array.from({ length: count }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
851
|
+
"span",
|
|
852
|
+
{
|
|
853
|
+
"aria-hidden": "true",
|
|
854
|
+
className: cx("snacky-page-indicator__dot", i === activeIndex && "snacky-page-indicator__dot--active")
|
|
855
|
+
},
|
|
856
|
+
i
|
|
857
|
+
))
|
|
858
|
+
}
|
|
859
|
+
);
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
// src/components/Badge/Badge.tsx
|
|
863
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
842
864
|
function NotificationBadge({ count, max = 99, children, className }) {
|
|
843
|
-
if (count <= 0) return /* @__PURE__ */ (0,
|
|
844
|
-
return /* @__PURE__ */ (0,
|
|
865
|
+
if (count <= 0) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_jsx_runtime22.Fragment, { children });
|
|
866
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: cx("snacky-badge-wrap", className), children: [
|
|
845
867
|
children,
|
|
846
|
-
/* @__PURE__ */ (0,
|
|
868
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "snacky-badge-notification", children: count > max ? `${max}+` : count })
|
|
847
869
|
] });
|
|
848
870
|
}
|
|
849
871
|
function DiscountTag({ label, className }) {
|
|
850
|
-
return /* @__PURE__ */ (0,
|
|
872
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: cx("snacky-discount-tag", className), children: label });
|
|
851
873
|
}
|
|
852
874
|
function SoldOutBadge({ className }) {
|
|
853
|
-
return /* @__PURE__ */ (0,
|
|
875
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: cx("snacky-soldout-badge", className), children: "Sold Out" });
|
|
854
876
|
}
|
|
855
877
|
function InfoBadge({ label, icon: icon3, className }) {
|
|
856
|
-
return /* @__PURE__ */ (0,
|
|
857
|
-
icon3 && /* @__PURE__ */ (0,
|
|
878
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: cx("snacky-info-badge", className), children: [
|
|
879
|
+
icon3 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "snacky-info-badge__icon", children: icon3 }),
|
|
858
880
|
label
|
|
859
881
|
] });
|
|
860
882
|
}
|
|
861
883
|
var VariantBadge = InfoBadge;
|
|
862
884
|
|
|
863
885
|
// src/components/Callout/Callout.tsx
|
|
864
|
-
var
|
|
886
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
865
887
|
function Callout({ message, timestamp, variant, statusIcon, className }) {
|
|
866
|
-
return /* @__PURE__ */ (0,
|
|
867
|
-
/* @__PURE__ */ (0,
|
|
868
|
-
/* @__PURE__ */ (0,
|
|
888
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: cx("snacky-callout", `snacky-callout--${variant}`, className), children: [
|
|
889
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "snacky-callout__message", children: message }),
|
|
890
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: "snacky-callout__meta", children: [
|
|
869
891
|
timestamp,
|
|
870
|
-
statusIcon && variant !== "received" && /* @__PURE__ */ (0,
|
|
892
|
+
statusIcon && variant !== "received" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "snacky-callout__meta-icon", children: statusIcon })
|
|
871
893
|
] })
|
|
872
894
|
] });
|
|
873
895
|
}
|
|
874
896
|
|
|
875
897
|
// src/components/List/List.tsx
|
|
876
|
-
var
|
|
898
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
877
899
|
var STATUS_LABEL = {
|
|
878
900
|
waiting: "Waiting for Payment",
|
|
879
901
|
process: "Order Processing",
|
|
@@ -901,7 +923,7 @@ function OrderListItem({
|
|
|
901
923
|
}) {
|
|
902
924
|
const action = actionLabel ?? STATUS_ACTION[status];
|
|
903
925
|
const isCod = status === "processCod";
|
|
904
|
-
return /* @__PURE__ */ (0,
|
|
926
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
905
927
|
"div",
|
|
906
928
|
{
|
|
907
929
|
className: cx("snacky-order-item", className),
|
|
@@ -910,32 +932,32 @@ function OrderListItem({
|
|
|
910
932
|
onClick,
|
|
911
933
|
onKeyDown: onClick ? (e) => (e.key === "Enter" || e.key === " ") && onClick() : void 0,
|
|
912
934
|
children: [
|
|
913
|
-
/* @__PURE__ */ (0,
|
|
914
|
-
/* @__PURE__ */ (0,
|
|
915
|
-
/* @__PURE__ */ (0,
|
|
916
|
-
/* @__PURE__ */ (0,
|
|
935
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "snacky-order-item__top", children: [
|
|
936
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "snacky-order-item__thumb-box", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("img", { className: "snacky-order-item__thumb", src: productImage, alt: "" }) }),
|
|
937
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "snacky-order-item__info", children: [
|
|
938
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
917
939
|
"span",
|
|
918
940
|
{
|
|
919
941
|
className: cx("snacky-order-item__status", status === "cancelled" && "snacky-order-item__status--cancelled"),
|
|
920
942
|
children: STATUS_LABEL[status]
|
|
921
943
|
}
|
|
922
944
|
),
|
|
923
|
-
/* @__PURE__ */ (0,
|
|
945
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "snacky-order-item__name", children: productName })
|
|
924
946
|
] })
|
|
925
947
|
] }),
|
|
926
|
-
/* @__PURE__ */ (0,
|
|
927
|
-
/* @__PURE__ */ (0,
|
|
928
|
-
/* @__PURE__ */ (0,
|
|
948
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "snacky-order-item__details", children: [
|
|
949
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "snacky-order-item__count", children: itemsSummary }),
|
|
950
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { className: cx("snacky-order-item__total", isCod && "snacky-order-item__total--cod"), children: [
|
|
929
951
|
"Order Total: ",
|
|
930
|
-
/* @__PURE__ */ (0,
|
|
952
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("b", { children: total })
|
|
931
953
|
] }),
|
|
932
|
-
isCod && /* @__PURE__ */ (0,
|
|
954
|
+
isCod && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "snacky-order-item__cod", children: "COD" })
|
|
933
955
|
] }),
|
|
934
|
-
status === "waiting" && paymentDeadline && /* @__PURE__ */ (0,
|
|
956
|
+
status === "waiting" && paymentDeadline && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "snacky-order-item__deadline", children: [
|
|
935
957
|
"Pay before ",
|
|
936
958
|
paymentDeadline
|
|
937
959
|
] }),
|
|
938
|
-
action && /* @__PURE__ */ (0,
|
|
960
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "snacky-order-item__action-row", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
939
961
|
Button,
|
|
940
962
|
{
|
|
941
963
|
variant: "primary",
|
|
@@ -951,7 +973,7 @@ function OrderListItem({
|
|
|
951
973
|
);
|
|
952
974
|
}
|
|
953
975
|
function NotificationListItem({ title, message, unread = false, onClick, className }) {
|
|
954
|
-
return /* @__PURE__ */ (0,
|
|
976
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
955
977
|
"div",
|
|
956
978
|
{
|
|
957
979
|
className: cx("snacky-notif-item", unread && "snacky-notif-item--unread", className),
|
|
@@ -960,8 +982,8 @@ function NotificationListItem({ title, message, unread = false, onClick, classNa
|
|
|
960
982
|
onClick,
|
|
961
983
|
onKeyDown: onClick ? (e) => (e.key === "Enter" || e.key === " ") && onClick() : void 0,
|
|
962
984
|
children: [
|
|
963
|
-
/* @__PURE__ */ (0,
|
|
964
|
-
/* @__PURE__ */ (0,
|
|
985
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "snacky-notif-item__title", children: title }),
|
|
986
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "snacky-notif-item__message", children: message })
|
|
965
987
|
]
|
|
966
988
|
}
|
|
967
989
|
);
|
|
@@ -969,12 +991,12 @@ function NotificationListItem({ title, message, unread = false, onClick, classNa
|
|
|
969
991
|
|
|
970
992
|
// src/components/Accordion/Accordion.tsx
|
|
971
993
|
var import_react10 = require("react");
|
|
972
|
-
var
|
|
994
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
973
995
|
function Accordion({ title, leadingIcon, children, defaultOpen = false, className }) {
|
|
974
996
|
const [open, setOpen] = (0, import_react10.useState)(defaultOpen);
|
|
975
997
|
const panelId = (0, import_react10.useId)();
|
|
976
|
-
return /* @__PURE__ */ (0,
|
|
977
|
-
/* @__PURE__ */ (0,
|
|
998
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cx("snacky-accordion", !!leadingIcon && "snacky-accordion--icon", className), children: [
|
|
999
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
978
1000
|
"button",
|
|
979
1001
|
{
|
|
980
1002
|
type: "button",
|
|
@@ -983,27 +1005,27 @@ function Accordion({ title, leadingIcon, children, defaultOpen = false, classNam
|
|
|
983
1005
|
"aria-controls": panelId,
|
|
984
1006
|
onClick: () => setOpen((v) => !v),
|
|
985
1007
|
children: [
|
|
986
|
-
leadingIcon && /* @__PURE__ */ (0,
|
|
987
|
-
/* @__PURE__ */ (0,
|
|
988
|
-
/* @__PURE__ */ (0,
|
|
1008
|
+
leadingIcon && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "snacky-accordion__icon", children: leadingIcon }),
|
|
1009
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "snacky-accordion__title", children: title }),
|
|
1010
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
989
1011
|
"svg",
|
|
990
1012
|
{
|
|
991
1013
|
className: cx("snacky-accordion__chevron", open && "snacky-accordion__chevron--open"),
|
|
992
1014
|
viewBox: "0 0 20 20",
|
|
993
1015
|
fill: "none",
|
|
994
|
-
children: /* @__PURE__ */ (0,
|
|
1016
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("path", { d: "M5 7.5L10 12.5L15 7.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
995
1017
|
}
|
|
996
1018
|
)
|
|
997
1019
|
]
|
|
998
1020
|
}
|
|
999
1021
|
),
|
|
1000
|
-
open && /* @__PURE__ */ (0,
|
|
1022
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { id: panelId, className: "snacky-accordion__panel", children })
|
|
1001
1023
|
] });
|
|
1002
1024
|
}
|
|
1003
1025
|
|
|
1004
1026
|
// src/components/Modal/BottomSheet.tsx
|
|
1005
1027
|
var import_react11 = require("react");
|
|
1006
|
-
var
|
|
1028
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
1007
1029
|
function BottomSheet({ open, onDismiss, children, showHandle = false, className }) {
|
|
1008
1030
|
(0, import_react11.useEffect)(() => {
|
|
1009
1031
|
if (!open) return;
|
|
@@ -1014,7 +1036,7 @@ function BottomSheet({ open, onDismiss, children, showHandle = false, className
|
|
|
1014
1036
|
return () => window.removeEventListener("keydown", onKeyDown);
|
|
1015
1037
|
}, [open, onDismiss]);
|
|
1016
1038
|
if (!open) return null;
|
|
1017
|
-
return /* @__PURE__ */ (0,
|
|
1039
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "snacky-sheet-overlay", onClick: onDismiss, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
1018
1040
|
"div",
|
|
1019
1041
|
{
|
|
1020
1042
|
className: cx("snacky-sheet", className),
|
|
@@ -1022,7 +1044,7 @@ function BottomSheet({ open, onDismiss, children, showHandle = false, className
|
|
|
1022
1044
|
"aria-modal": "true",
|
|
1023
1045
|
onClick: (e) => e.stopPropagation(),
|
|
1024
1046
|
children: [
|
|
1025
|
-
showHandle && /* @__PURE__ */ (0,
|
|
1047
|
+
showHandle && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "snacky-sheet__handle" }),
|
|
1026
1048
|
children
|
|
1027
1049
|
]
|
|
1028
1050
|
}
|
|
@@ -1030,29 +1052,29 @@ function BottomSheet({ open, onDismiss, children, showHandle = false, className
|
|
|
1030
1052
|
}
|
|
1031
1053
|
|
|
1032
1054
|
// src/components/Section/Section.tsx
|
|
1033
|
-
var
|
|
1055
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
1034
1056
|
function Section({ title, onAction, children, className }) {
|
|
1035
|
-
return /* @__PURE__ */ (0,
|
|
1036
|
-
/* @__PURE__ */ (0,
|
|
1037
|
-
/* @__PURE__ */ (0,
|
|
1038
|
-
onAction && /* @__PURE__ */ (0,
|
|
1057
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("section", { className: cx("snacky-section", className), children: [
|
|
1058
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "snacky-section__header", children: [
|
|
1059
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h3", { className: "snacky-section__title", children: title }),
|
|
1060
|
+
onAction && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(IconButton, { size: "small", icon: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(angleSmallRight, {}), onClick: onAction, ariaLabel: `See more: ${title}` })
|
|
1039
1061
|
] }),
|
|
1040
1062
|
children
|
|
1041
1063
|
] });
|
|
1042
1064
|
}
|
|
1043
1065
|
|
|
1044
1066
|
// src/components/Stepper/Stepper.tsx
|
|
1045
|
-
var
|
|
1067
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1046
1068
|
function Stepper({ steps, className }) {
|
|
1047
|
-
return /* @__PURE__ */ (0,
|
|
1069
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("ol", { className: cx("snacky-stepper", className), children: steps.map((step, i) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
1048
1070
|
"li",
|
|
1049
1071
|
{
|
|
1050
1072
|
className: cx("snacky-stepper__step", i === steps.length - 1 && "snacky-stepper__step--last"),
|
|
1051
1073
|
children: [
|
|
1052
|
-
/* @__PURE__ */ (0,
|
|
1053
|
-
/* @__PURE__ */ (0,
|
|
1054
|
-
/* @__PURE__ */ (0,
|
|
1055
|
-
step.timestamp && /* @__PURE__ */ (0,
|
|
1074
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: cx("snacky-stepper__dot", `snacky-stepper__dot--${step.state}`), children: step.state === "cancelled" && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(close, { width: 12, height: 12 }) }),
|
|
1075
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "snacky-stepper__body", children: [
|
|
1076
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: cx("snacky-stepper__label", `snacky-stepper__label--${step.state}`), children: step.label }),
|
|
1077
|
+
step.timestamp && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "snacky-stepper__time", children: step.timestamp })
|
|
1056
1078
|
] })
|
|
1057
1079
|
]
|
|
1058
1080
|
},
|
|
@@ -1061,7 +1083,7 @@ function Stepper({ steps, className }) {
|
|
|
1061
1083
|
}
|
|
1062
1084
|
|
|
1063
1085
|
// src/components/Calendar/Calendar.tsx
|
|
1064
|
-
var
|
|
1086
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
1065
1087
|
var WEEKDAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
1066
1088
|
var MONTHS = [
|
|
1067
1089
|
"January",
|
|
@@ -1108,39 +1130,39 @@ function Calendar({
|
|
|
1108
1130
|
const [lo, hi] = range ? [range[0], range[1]].sort((a, b) => a.getTime() - b.getTime()) : [null, null];
|
|
1109
1131
|
const isEnd = (d) => single && sameDay(d, single) || lo && hi && (sameDay(d, lo) || sameDay(d, hi));
|
|
1110
1132
|
const isInRange = (d) => lo && hi && d > lo && d < hi;
|
|
1111
|
-
return /* @__PURE__ */ (0,
|
|
1112
|
-
/* @__PURE__ */ (0,
|
|
1113
|
-
/* @__PURE__ */ (0,
|
|
1133
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: cx("snacky-calendar", className), children: [
|
|
1134
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "snacky-calendar__header", children: [
|
|
1135
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
1114
1136
|
"button",
|
|
1115
1137
|
{
|
|
1116
1138
|
type: "button",
|
|
1117
1139
|
className: "snacky-calendar__nav",
|
|
1118
1140
|
onClick: onPrevMonth,
|
|
1119
1141
|
"aria-label": "Previous month",
|
|
1120
|
-
children: /* @__PURE__ */ (0,
|
|
1142
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(back, { width: 24, height: 24 })
|
|
1121
1143
|
}
|
|
1122
1144
|
),
|
|
1123
|
-
/* @__PURE__ */ (0,
|
|
1145
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "snacky-calendar__label", children: [
|
|
1124
1146
|
MONTHS[month.getMonth()],
|
|
1125
1147
|
" ",
|
|
1126
1148
|
month.getFullYear()
|
|
1127
1149
|
] }),
|
|
1128
|
-
/* @__PURE__ */ (0,
|
|
1150
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
1129
1151
|
"button",
|
|
1130
1152
|
{
|
|
1131
1153
|
type: "button",
|
|
1132
1154
|
className: "snacky-calendar__nav snacky-calendar__nav--next",
|
|
1133
1155
|
onClick: onNextMonth,
|
|
1134
1156
|
"aria-label": "Next month",
|
|
1135
|
-
children: /* @__PURE__ */ (0,
|
|
1157
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(back, { width: 24, height: 24 })
|
|
1136
1158
|
}
|
|
1137
1159
|
)
|
|
1138
1160
|
] }),
|
|
1139
|
-
/* @__PURE__ */ (0,
|
|
1140
|
-
WEEKDAYS.map((d) => /* @__PURE__ */ (0,
|
|
1161
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "snacky-calendar__grid", children: [
|
|
1162
|
+
WEEKDAYS.map((d) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "snacky-calendar__weekday", children: d }, d)),
|
|
1141
1163
|
days.map((d, i) => {
|
|
1142
1164
|
const outside = d.getMonth() !== month.getMonth();
|
|
1143
|
-
return /* @__PURE__ */ (0,
|
|
1165
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
1144
1166
|
"button",
|
|
1145
1167
|
{
|
|
1146
1168
|
type: "button",
|
|
@@ -1154,26 +1176,26 @@ function Calendar({
|
|
|
1154
1176
|
disabled: outside,
|
|
1155
1177
|
"aria-current": isEnd(d) ? "date" : void 0,
|
|
1156
1178
|
children: [
|
|
1157
|
-
/* @__PURE__ */ (0,
|
|
1158
|
-
marked.some((m) => sameDay(m, d)) && /* @__PURE__ */ (0,
|
|
1179
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "snacky-calendar__day-number", children: d.getDate() }),
|
|
1180
|
+
marked.some((m) => sameDay(m, d)) && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "snacky-calendar__marker" })
|
|
1159
1181
|
]
|
|
1160
1182
|
},
|
|
1161
1183
|
i
|
|
1162
1184
|
);
|
|
1163
1185
|
})
|
|
1164
1186
|
] }),
|
|
1165
|
-
onAction && /* @__PURE__ */ (0,
|
|
1187
|
+
onAction && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Button, { onClick: onAction, style: { width: "100%" }, children: actionLabel })
|
|
1166
1188
|
] });
|
|
1167
1189
|
}
|
|
1168
1190
|
|
|
1169
1191
|
// src/components/Avatar/Avatar.tsx
|
|
1170
|
-
var
|
|
1192
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1171
1193
|
function Avatar({ src, alt, size = "md", className }) {
|
|
1172
|
-
return /* @__PURE__ */ (0,
|
|
1194
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("img", { src, alt, className: cx("snacky-avatar", `snacky-avatar--${size}`, className) });
|
|
1173
1195
|
}
|
|
1174
1196
|
|
|
1175
1197
|
// src/components/Illustration/Illustration.tsx
|
|
1176
|
-
var
|
|
1198
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
1177
1199
|
var SIZE = {
|
|
1178
1200
|
empty: { width: 268, height: 200 },
|
|
1179
1201
|
createAccount: { width: 360, height: 240 },
|
|
@@ -1183,54 +1205,54 @@ var SIZE = {
|
|
|
1183
1205
|
};
|
|
1184
1206
|
function Illustration({ variant, src, alt, className }) {
|
|
1185
1207
|
const { width, height } = SIZE[variant];
|
|
1186
|
-
return /* @__PURE__ */ (0,
|
|
1208
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("img", { src, alt, width, height, className: cx("snacky-illustration", className) });
|
|
1187
1209
|
}
|
|
1188
1210
|
|
|
1189
1211
|
// src/components/ProductImage/ProductImage.tsx
|
|
1190
|
-
var
|
|
1212
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
1191
1213
|
function ProductImage({ src, alt, usage, sold = false, className }) {
|
|
1192
|
-
return /* @__PURE__ */ (0,
|
|
1193
|
-
/* @__PURE__ */ (0,
|
|
1194
|
-
sold && /* @__PURE__ */ (0,
|
|
1214
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: cx("snacky-product-image-wrap", `snacky-product-image-wrap--${usage}`, className), children: [
|
|
1215
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("img", { src, alt, className: cx("snacky-product-image", `snacky-product-image--${usage}`) }),
|
|
1216
|
+
sold && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "snacky-product-image-sold-overlay", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "snacky-product-image-sold-label", children: "Sold Out" }) })
|
|
1195
1217
|
] });
|
|
1196
1218
|
}
|
|
1197
1219
|
|
|
1198
1220
|
// src/components/ProductCard/ProductCard.tsx
|
|
1199
|
-
var
|
|
1221
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
1200
1222
|
function ProductCard(props) {
|
|
1201
1223
|
if (props.variant === "details") {
|
|
1202
1224
|
const { productName: productName2, imageUrl: imageUrl2, price: price2, rating: rating2, originalPrice: originalPrice2, discountLabel: discountLabel2, ratingCount, favorited, onFavoriteClick, onShareClick, onChatClick, sold, ratingIcon: ratingIcon2, favoriteIcon, shareIcon, chatIcon, onClick: onClick2, className: className2 } = props;
|
|
1203
|
-
return /* @__PURE__ */ (0,
|
|
1204
|
-
/* @__PURE__ */ (0,
|
|
1205
|
-
/* @__PURE__ */ (0,
|
|
1206
|
-
sold && /* @__PURE__ */ (0,
|
|
1225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: cx("snacky-product-card", "snacky-product-card--details", className2), children: [
|
|
1226
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "snacky-product-card__image-block", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "snacky-product-card__image-wrap", onClick: onClick2, children: [
|
|
1227
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("img", { className: "snacky-product-card__image", src: imageUrl2, alt: productName2 }),
|
|
1228
|
+
sold && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "snacky-product-card__sold-overlay", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(SoldOutBadge, {}) })
|
|
1207
1229
|
] }) }),
|
|
1208
|
-
/* @__PURE__ */ (0,
|
|
1209
|
-
/* @__PURE__ */ (0,
|
|
1210
|
-
/* @__PURE__ */ (0,
|
|
1211
|
-
/* @__PURE__ */ (0,
|
|
1212
|
-
originalPrice2 && /* @__PURE__ */ (0,
|
|
1213
|
-
discountLabel2 && /* @__PURE__ */ (0,
|
|
1230
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "snacky-product-card__details-body", children: [
|
|
1231
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: "snacky-product-card__name", children: productName2 }),
|
|
1232
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "snacky-product-card__price-row", children: [
|
|
1233
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "snacky-product-card__price", children: price2 }),
|
|
1234
|
+
originalPrice2 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "snacky-product-card__original-price", children: originalPrice2 }),
|
|
1235
|
+
discountLabel2 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(DiscountTag, { label: discountLabel2 })
|
|
1214
1236
|
] }),
|
|
1215
|
-
/* @__PURE__ */ (0,
|
|
1216
|
-
/* @__PURE__ */ (0,
|
|
1217
|
-
/* @__PURE__ */ (0,
|
|
1237
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "snacky-product-card__footer-row", children: [
|
|
1238
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "snacky-product-card__rating", children: [
|
|
1239
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "snacky-product-card__rating-icon", children: ratingIcon2 ?? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(star, { width: 16, height: 16 }) }),
|
|
1218
1240
|
rating2,
|
|
1219
1241
|
" (",
|
|
1220
1242
|
ratingCount,
|
|
1221
1243
|
")"
|
|
1222
1244
|
] }),
|
|
1223
|
-
/* @__PURE__ */ (0,
|
|
1224
|
-
/* @__PURE__ */ (0,
|
|
1225
|
-
/* @__PURE__ */ (0,
|
|
1226
|
-
/* @__PURE__ */ (0,
|
|
1245
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "snacky-product-card__actions snacky-product-card__actions--details", children: [
|
|
1246
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(IconButton, { variant: "secondary", icon: favoriteIcon ?? (favorited ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(heart2, { width: 20, height: 20 }) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(heart, { width: 20, height: 20 })), selected: favorited, onClick: onFavoriteClick, ariaLabel: "Favorite" }),
|
|
1247
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(IconButton, { variant: "secondary", icon: shareIcon ?? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(share, { width: 20, height: 20 }), onClick: onShareClick, ariaLabel: "Share" }),
|
|
1248
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(IconButton, { variant: "secondary", icon: chatIcon ?? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(chat, { width: 20, height: 20 }), onClick: onChatClick, ariaLabel: "Chat with seller" })
|
|
1227
1249
|
] })
|
|
1228
1250
|
] })
|
|
1229
1251
|
] })
|
|
1230
1252
|
] });
|
|
1231
1253
|
}
|
|
1232
1254
|
const { productName, imageUrl, price, rating, originalPrice, discountLabel, onAddToCart, cartIcon, ratingIcon, onClick, className } = props;
|
|
1233
|
-
return /* @__PURE__ */ (0,
|
|
1255
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
1234
1256
|
"div",
|
|
1235
1257
|
{
|
|
1236
1258
|
className: cx("snacky-product-card", "snacky-product-card--list", className),
|
|
@@ -1239,25 +1261,25 @@ function ProductCard(props) {
|
|
|
1239
1261
|
onClick,
|
|
1240
1262
|
onKeyDown: (e) => (e.key === "Enter" || e.key === " ") && onClick?.(),
|
|
1241
1263
|
children: [
|
|
1242
|
-
/* @__PURE__ */ (0,
|
|
1243
|
-
/* @__PURE__ */ (0,
|
|
1244
|
-
discountLabel && /* @__PURE__ */ (0,
|
|
1264
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "snacky-product-card__image-wrap", children: [
|
|
1265
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("img", { className: "snacky-product-card__image", src: imageUrl, alt: productName }),
|
|
1266
|
+
discountLabel && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "snacky-product-card__discount", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(DiscountTag, { label: discountLabel }) })
|
|
1245
1267
|
] }),
|
|
1246
|
-
/* @__PURE__ */ (0,
|
|
1247
|
-
/* @__PURE__ */ (0,
|
|
1248
|
-
/* @__PURE__ */ (0,
|
|
1249
|
-
originalPrice && /* @__PURE__ */ (0,
|
|
1268
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: "snacky-product-card__name", children: productName }),
|
|
1269
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "snacky-product-card__price-row", children: [
|
|
1270
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "snacky-product-card__price", children: price }),
|
|
1271
|
+
originalPrice && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "snacky-product-card__original-price", children: originalPrice })
|
|
1250
1272
|
] }),
|
|
1251
|
-
/* @__PURE__ */ (0,
|
|
1252
|
-
/* @__PURE__ */ (0,
|
|
1253
|
-
/* @__PURE__ */ (0,
|
|
1273
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "snacky-product-card__footer-row", children: [
|
|
1274
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "snacky-product-card__rating", children: [
|
|
1275
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "snacky-product-card__rating-icon", children: ratingIcon ?? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(star, { width: 16, height: 16 }) }),
|
|
1254
1276
|
rating
|
|
1255
1277
|
] }),
|
|
1256
|
-
/* @__PURE__ */ (0,
|
|
1278
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
1257
1279
|
IconButton,
|
|
1258
1280
|
{
|
|
1259
1281
|
variant: "primary",
|
|
1260
|
-
icon: cartIcon ?? /* @__PURE__ */ (0,
|
|
1282
|
+
icon: cartIcon ?? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(cartAdd, { width: 16, height: 16 }),
|
|
1261
1283
|
onClick: (e) => {
|
|
1262
1284
|
e.stopPropagation();
|
|
1263
1285
|
onAddToCart();
|
|
@@ -1272,17 +1294,17 @@ function ProductCard(props) {
|
|
|
1272
1294
|
}
|
|
1273
1295
|
|
|
1274
1296
|
// src/components/ImagePlaceholder/ImagePlaceholder.tsx
|
|
1275
|
-
var
|
|
1297
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
1276
1298
|
function ImagePlaceholder({ width, height, className }) {
|
|
1277
1299
|
const iconSize = Math.round(Math.min(width, height) * 0.32);
|
|
1278
|
-
return /* @__PURE__ */ (0,
|
|
1300
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
1279
1301
|
"div",
|
|
1280
1302
|
{
|
|
1281
1303
|
className: cx("snacky-image-placeholder", className),
|
|
1282
1304
|
style: { width, height },
|
|
1283
1305
|
role: "img",
|
|
1284
1306
|
"aria-label": "No image",
|
|
1285
|
-
children: /* @__PURE__ */ (0,
|
|
1307
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
1286
1308
|
"svg",
|
|
1287
1309
|
{
|
|
1288
1310
|
width: iconSize,
|
|
@@ -1294,9 +1316,9 @@ function ImagePlaceholder({ width, height, className }) {
|
|
|
1294
1316
|
strokeLinecap: "round",
|
|
1295
1317
|
strokeLinejoin: "round",
|
|
1296
1318
|
children: [
|
|
1297
|
-
/* @__PURE__ */ (0,
|
|
1298
|
-
/* @__PURE__ */ (0,
|
|
1299
|
-
/* @__PURE__ */ (0,
|
|
1319
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
|
|
1320
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("circle", { cx: "8.5", cy: "8.5", r: "1.5", fill: "currentColor", stroke: "none" }),
|
|
1321
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("polyline", { points: "21 15 16 10 5 21" })
|
|
1300
1322
|
]
|
|
1301
1323
|
}
|
|
1302
1324
|
)
|
|
@@ -1330,6 +1352,7 @@ function ImagePlaceholder({ width, height, className }) {
|
|
|
1330
1352
|
NotificationListItem,
|
|
1331
1353
|
OrderListItem,
|
|
1332
1354
|
OtpField,
|
|
1355
|
+
PageIndicator,
|
|
1333
1356
|
PointBalanceBanner,
|
|
1334
1357
|
ProductCard,
|
|
1335
1358
|
ProductChip,
|