@open-mercato/ui 0.6.1-develop.3256.1.fe3dec2464 → 0.6.1-develop.3260.1.dc719cac84

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.
Files changed (137) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/backend/CrudForm.js +46 -129
  3. package/dist/backend/CrudForm.js.map +3 -3
  4. package/dist/backend/DataTable.js +10 -3
  5. package/dist/backend/DataTable.js.map +2 -2
  6. package/dist/backend/EmptyState.js +1 -47
  7. package/dist/backend/EmptyState.js.map +2 -2
  8. package/dist/backend/FilterOverlay.js +31 -26
  9. package/dist/backend/FilterOverlay.js.map +2 -2
  10. package/dist/backend/FlashMessages.js +23 -25
  11. package/dist/backend/FlashMessages.js.map +2 -2
  12. package/dist/backend/JsonBuilder.js +4 -2
  13. package/dist/backend/JsonBuilder.js.map +2 -2
  14. package/dist/backend/LogList.js +49 -0
  15. package/dist/backend/LogList.js.map +7 -0
  16. package/dist/backend/crud/CollapsibleGroup.js +13 -3
  17. package/dist/backend/crud/CollapsibleGroup.js.map +2 -2
  18. package/dist/backend/detail/InlineEditors.js +80 -32
  19. package/dist/backend/detail/InlineEditors.js.map +2 -2
  20. package/dist/backend/inputs/ComboboxInput.js +60 -6
  21. package/dist/backend/inputs/ComboboxInput.js.map +2 -2
  22. package/dist/backend/inputs/DatePicker.js +6 -142
  23. package/dist/backend/inputs/DatePicker.js.map +2 -2
  24. package/dist/backend/inputs/DateTimePicker.js +6 -182
  25. package/dist/backend/inputs/DateTimePicker.js.map +2 -2
  26. package/dist/backend/inputs/TagsInput.js +16 -19
  27. package/dist/backend/inputs/TagsInput.js.map +2 -2
  28. package/dist/backend/inputs/TimeInput.js +1 -1
  29. package/dist/backend/inputs/TimeInput.js.map +2 -2
  30. package/dist/backend/inputs/TimePicker.js +83 -72
  31. package/dist/backend/inputs/TimePicker.js.map +2 -2
  32. package/dist/backend/utils/customFieldForms.js +2 -2
  33. package/dist/backend/utils/customFieldForms.js.map +1 -1
  34. package/dist/portal/components/PortalEmptyState.js +13 -9
  35. package/dist/portal/components/PortalEmptyState.js.map +2 -2
  36. package/dist/primitives/accordion.js +137 -0
  37. package/dist/primitives/accordion.js.map +7 -0
  38. package/dist/primitives/alert.js +180 -12
  39. package/dist/primitives/alert.js.map +2 -2
  40. package/dist/primitives/calendar.js +122 -32
  41. package/dist/primitives/calendar.js.map +2 -2
  42. package/dist/primitives/compact-select.js +47 -0
  43. package/dist/primitives/compact-select.js.map +7 -0
  44. package/dist/primitives/counter-input.js +174 -0
  45. package/dist/primitives/counter-input.js.map +7 -0
  46. package/dist/primitives/date-picker-helpers.js +79 -0
  47. package/dist/primitives/date-picker-helpers.js.map +7 -0
  48. package/dist/primitives/date-picker.js +216 -0
  49. package/dist/primitives/date-picker.js.map +7 -0
  50. package/dist/primitives/date-range-picker.js +239 -0
  51. package/dist/primitives/date-range-picker.js.map +7 -0
  52. package/dist/primitives/digit-input.js +157 -0
  53. package/dist/primitives/digit-input.js.map +7 -0
  54. package/dist/primitives/empty-state.js +93 -0
  55. package/dist/primitives/empty-state.js.map +7 -0
  56. package/dist/primitives/inline-input.js +29 -0
  57. package/dist/primitives/inline-input.js.map +7 -0
  58. package/dist/primitives/inline-select.js +41 -0
  59. package/dist/primitives/inline-select.js.map +7 -0
  60. package/dist/primitives/notification-stack.js +116 -0
  61. package/dist/primitives/notification-stack.js.map +7 -0
  62. package/dist/primitives/notification.js +62 -0
  63. package/dist/primitives/notification.js.map +7 -0
  64. package/dist/primitives/rich-editor.js +1230 -0
  65. package/dist/primitives/rich-editor.js.map +7 -0
  66. package/dist/primitives/select.js +1 -0
  67. package/dist/primitives/select.js.map +2 -2
  68. package/dist/primitives/skeleton.js +55 -0
  69. package/dist/primitives/skeleton.js.map +7 -0
  70. package/dist/primitives/tag-input.js +186 -0
  71. package/dist/primitives/tag-input.js.map +7 -0
  72. package/dist/primitives/tag.js +66 -13
  73. package/dist/primitives/tag.js.map +2 -2
  74. package/dist/primitives/time-picker.js +793 -0
  75. package/dist/primitives/time-picker.js.map +7 -0
  76. package/package.json +4 -3
  77. package/src/backend/CrudForm.tsx +61 -113
  78. package/src/backend/DataTable.tsx +17 -5
  79. package/src/backend/EmptyState.tsx +13 -63
  80. package/src/backend/FilterOverlay.tsx +38 -22
  81. package/src/backend/FlashMessages.tsx +23 -24
  82. package/src/backend/JsonBuilder.tsx +4 -2
  83. package/src/backend/LogList.tsx +109 -0
  84. package/src/backend/__tests__/CrudForm.datetime.test.tsx +12 -7
  85. package/src/backend/__tests__/FilterOverlay.dateRange.test.tsx +89 -0
  86. package/src/backend/__tests__/LogList.test.tsx +163 -0
  87. package/src/backend/crud/CollapsibleGroup.tsx +17 -3
  88. package/src/backend/detail/InlineEditors.tsx +78 -25
  89. package/src/backend/detail/__tests__/InlineEditors.test.tsx +81 -1
  90. package/src/backend/inputs/ComboboxInput.tsx +81 -9
  91. package/src/backend/inputs/DatePicker.tsx +28 -155
  92. package/src/backend/inputs/DateTimePicker.tsx +25 -193
  93. package/src/backend/inputs/TagsInput.tsx +10 -13
  94. package/src/backend/inputs/TimeInput.tsx +2 -1
  95. package/src/backend/inputs/TimePicker.tsx +99 -70
  96. package/src/backend/inputs/__tests__/ComboboxInput.test.tsx +133 -0
  97. package/src/backend/inputs/__tests__/TimePicker.test.tsx +2 -2
  98. package/src/backend/utils/__tests__/richTextSanitizer.test.ts +5 -2
  99. package/src/backend/utils/customFieldForms.ts +2 -2
  100. package/src/portal/components/PortalEmptyState.tsx +27 -22
  101. package/src/primitives/__tests__/accordion.test.tsx +197 -0
  102. package/src/primitives/__tests__/alert.test.tsx +204 -0
  103. package/src/primitives/__tests__/compact-select.test.tsx +98 -0
  104. package/src/primitives/__tests__/counter-input.test.tsx +165 -0
  105. package/src/primitives/__tests__/date-picker.test.tsx +221 -0
  106. package/src/primitives/__tests__/date-range-picker.test.tsx +173 -0
  107. package/src/primitives/__tests__/digit-input.test.tsx +168 -0
  108. package/src/primitives/__tests__/empty-state.test.tsx +154 -0
  109. package/src/primitives/__tests__/inline-input.test.tsx +100 -0
  110. package/src/primitives/__tests__/inline-select.test.tsx +103 -0
  111. package/src/primitives/__tests__/notification-stack.test.tsx +174 -0
  112. package/src/primitives/__tests__/notification.test.tsx +119 -0
  113. package/src/primitives/__tests__/rich-editor.test.tsx +411 -0
  114. package/src/primitives/__tests__/skeleton.test.tsx +76 -0
  115. package/src/primitives/__tests__/tag-input.test.tsx +198 -0
  116. package/src/primitives/__tests__/tag.test.tsx +123 -0
  117. package/src/primitives/__tests__/time-picker.test.tsx +392 -0
  118. package/src/primitives/accordion.tsx +225 -0
  119. package/src/primitives/alert.tsx +234 -24
  120. package/src/primitives/calendar.tsx +146 -38
  121. package/src/primitives/compact-select.tsx +59 -0
  122. package/src/primitives/counter-input.tsx +211 -0
  123. package/src/primitives/date-picker-helpers.ts +96 -0
  124. package/src/primitives/date-picker.tsx +290 -0
  125. package/src/primitives/date-range-picker.tsx +281 -0
  126. package/src/primitives/digit-input.tsx +208 -0
  127. package/src/primitives/empty-state.tsx +140 -0
  128. package/src/primitives/inline-input.tsx +55 -0
  129. package/src/primitives/inline-select.tsx +74 -0
  130. package/src/primitives/notification-stack.tsx +185 -0
  131. package/src/primitives/notification.tsx +136 -0
  132. package/src/primitives/rich-editor.tsx +1578 -0
  133. package/src/primitives/select.tsx +1 -0
  134. package/src/primitives/skeleton.tsx +70 -0
  135. package/src/primitives/tag-input.tsx +223 -0
  136. package/src/primitives/tag.tsx +69 -10
  137. package/src/primitives/time-picker.tsx +1059 -0
@@ -0,0 +1,137 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import * as AccordionPrimitive from "@radix-ui/react-accordion";
5
+ import { ChevronDown, Minus, Plus } from "lucide-react";
6
+ import { cva } from "class-variance-authority";
7
+ import { cn } from "@open-mercato/shared/lib/utils";
8
+ const accordionItemVariants = cva(
9
+ // `--accordion-indent` defaults to the container padding (14px). The
10
+ // `has-[…trigger-left-icon]` Tailwind v4 variant promotes it to 44px
11
+ // (icon 20 + gap 10 + container padding 14) whenever an `AccordionTrigger`
12
+ // declares a `leftIcon`, so `AccordionContent` aligns with the title text
13
+ // — matches Figma 210:4064 (Active state) without React state or hydration
14
+ // flash.
15
+ "overflow-hidden rounded-[10px] transition-colors [--accordion-indent:14px] has-[[data-slot=accordion-trigger-left-icon]]:[--accordion-indent:44px]",
16
+ {
17
+ variants: {
18
+ variant: {
19
+ // Figma 210:4021 (Default), 210:4048 (Hover), 210:4064 (Active):
20
+ // closed = white card + soft border + x-small shadow,
21
+ // hover (closed) = weak-50 bg, no border, no shadow,
22
+ // open = weak-50 bg, no border, no shadow.
23
+ card: "border border-border bg-card shadow-xs data-[state=open]:border-transparent data-[state=open]:bg-muted data-[state=open]:shadow-none data-[state=closed]:hover:border-transparent data-[state=closed]:hover:bg-muted data-[state=closed]:hover:shadow-none",
24
+ // For embedded use cases (e.g. FAQ block on a coloured surface or
25
+ // borderless nav-style list where the surrounding container owns
26
+ // the visual chrome).
27
+ borderless: "border-transparent bg-transparent shadow-none"
28
+ }
29
+ },
30
+ defaultVariants: { variant: "card" }
31
+ }
32
+ );
33
+ const Accordion = AccordionPrimitive.Root;
34
+ const AccordionItem = React.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx(
35
+ AccordionPrimitive.Item,
36
+ {
37
+ ref,
38
+ "data-slot": "accordion-item",
39
+ className: cn(accordionItemVariants({ variant }), className),
40
+ ...props
41
+ }
42
+ ));
43
+ AccordionItem.displayName = "AccordionItem";
44
+ const AccordionHeader = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
45
+ AccordionPrimitive.Header,
46
+ {
47
+ ref,
48
+ "data-slot": "accordion-header",
49
+ className: cn("flex", className),
50
+ ...props
51
+ }
52
+ ));
53
+ AccordionHeader.displayName = "AccordionHeader";
54
+ const AccordionTrigger = React.forwardRef(
55
+ ({
56
+ className,
57
+ leftIcon,
58
+ triggerIcon = "plus-minus",
59
+ iconPosition = "end",
60
+ indicator,
61
+ headerClassName,
62
+ children,
63
+ ...props
64
+ }, ref) => {
65
+ const indicatorNode = indicator !== void 0 ? indicator : triggerIcon === "chevron" ? /* @__PURE__ */ jsx(ChevronDown, { className: "size-5 transition-transform duration-200 group-data-[state=open]/accordion-trigger:rotate-180", "aria-hidden": "true" }) : triggerIcon === "plus-minus" ? /* @__PURE__ */ jsxs(Fragment, { children: [
66
+ /* @__PURE__ */ jsx(Plus, { className: "size-5 group-data-[state=open]/accordion-trigger:hidden", "aria-hidden": "true" }),
67
+ /* @__PURE__ */ jsx(Minus, { className: "hidden size-5 group-data-[state=open]/accordion-trigger:block", "aria-hidden": "true" })
68
+ ] }) : null;
69
+ const renderLeftIcon = Boolean(leftIcon) && iconPosition === "end";
70
+ return /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: cn("flex", headerClassName), "data-slot": "accordion-header", children: /* @__PURE__ */ jsxs(
71
+ AccordionPrimitive.Trigger,
72
+ {
73
+ ref,
74
+ "data-slot": "accordion-trigger",
75
+ className: cn(
76
+ "group/accordion-trigger flex w-full items-start gap-2.5 p-3.5 text-left text-sm font-medium leading-5 tracking-tight text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50",
77
+ className
78
+ ),
79
+ ...props,
80
+ children: [
81
+ iconPosition === "start" && indicatorNode ? /* @__PURE__ */ jsx(
82
+ "span",
83
+ {
84
+ className: "inline-flex size-5 shrink-0 items-center justify-center text-foreground",
85
+ "data-slot": "accordion-trigger-indicator",
86
+ "aria-hidden": "true",
87
+ children: indicatorNode
88
+ }
89
+ ) : null,
90
+ renderLeftIcon ? /* @__PURE__ */ jsx(
91
+ "span",
92
+ {
93
+ className: "inline-flex size-5 shrink-0 items-center justify-center text-muted-foreground [&>svg]:size-5",
94
+ "data-slot": "accordion-trigger-left-icon",
95
+ "aria-hidden": "true",
96
+ children: leftIcon
97
+ }
98
+ ) : null,
99
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 self-center", "data-slot": "accordion-trigger-label", children }),
100
+ iconPosition === "end" && indicatorNode ? /* @__PURE__ */ jsx(
101
+ "span",
102
+ {
103
+ className: "inline-flex size-5 shrink-0 items-center justify-center text-foreground",
104
+ "data-slot": "accordion-trigger-indicator",
105
+ "aria-hidden": "true",
106
+ children: indicatorNode
107
+ }
108
+ ) : null
109
+ ]
110
+ }
111
+ ) });
112
+ }
113
+ );
114
+ AccordionTrigger.displayName = "AccordionTrigger";
115
+ const AccordionContent = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
116
+ AccordionPrimitive.Content,
117
+ {
118
+ ref,
119
+ "data-slot": "accordion-content",
120
+ className: cn(
121
+ "overflow-hidden text-sm leading-5 text-muted-foreground data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",
122
+ className
123
+ ),
124
+ ...props,
125
+ children: /* @__PURE__ */ jsx("div", { className: "pb-3.5 pt-0 pl-[var(--accordion-indent)] pr-[var(--accordion-indent)]", children })
126
+ }
127
+ ));
128
+ AccordionContent.displayName = "AccordionContent";
129
+ export {
130
+ Accordion,
131
+ AccordionContent,
132
+ AccordionHeader,
133
+ AccordionItem,
134
+ AccordionTrigger,
135
+ accordionItemVariants
136
+ };
137
+ //# sourceMappingURL=accordion.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/primitives/accordion.tsx"],
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport * as AccordionPrimitive from '@radix-ui/react-accordion'\nimport { ChevronDown, Minus, Plus } from 'lucide-react'\nimport { cva, type VariantProps } from 'class-variance-authority'\n\nimport { cn } from '@open-mercato/shared/lib/utils'\n\nexport type AccordionTriggerIcon = 'plus-minus' | 'chevron' | 'none'\nexport type AccordionIconPosition = 'end' | 'start'\n\nconst accordionItemVariants = cva(\n // `--accordion-indent` defaults to the container padding (14px). The\n // `has-[\u2026trigger-left-icon]` Tailwind v4 variant promotes it to 44px\n // (icon 20 + gap 10 + container padding 14) whenever an `AccordionTrigger`\n // declares a `leftIcon`, so `AccordionContent` aligns with the title text\n // \u2014 matches Figma 210:4064 (Active state) without React state or hydration\n // flash.\n 'overflow-hidden rounded-[10px] transition-colors [--accordion-indent:14px] has-[[data-slot=accordion-trigger-left-icon]]:[--accordion-indent:44px]',\n {\n variants: {\n variant: {\n // Figma 210:4021 (Default), 210:4048 (Hover), 210:4064 (Active):\n // closed = white card + soft border + x-small shadow,\n // hover (closed) = weak-50 bg, no border, no shadow,\n // open = weak-50 bg, no border, no shadow.\n card:\n 'border border-border bg-card shadow-xs ' +\n 'data-[state=open]:border-transparent data-[state=open]:bg-muted data-[state=open]:shadow-none ' +\n 'data-[state=closed]:hover:border-transparent data-[state=closed]:hover:bg-muted data-[state=closed]:hover:shadow-none',\n // For embedded use cases (e.g. FAQ block on a coloured surface or\n // borderless nav-style list where the surrounding container owns\n // the visual chrome).\n borderless: 'border-transparent bg-transparent shadow-none',\n },\n },\n defaultVariants: { variant: 'card' },\n },\n)\n\nconst Accordion = AccordionPrimitive.Root\n\ntype AccordionItemProps = React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item> &\n VariantProps<typeof accordionItemVariants>\n\nconst AccordionItem = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Item>,\n AccordionItemProps\n>(({ className, variant, ...props }, ref) => (\n <AccordionPrimitive.Item\n ref={ref}\n data-slot=\"accordion-item\"\n className={cn(accordionItemVariants({ variant }), className)}\n {...props}\n />\n))\nAccordionItem.displayName = 'AccordionItem'\n\nconst AccordionHeader = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Header>,\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Header>\n>(({ className, ...props }, ref) => (\n <AccordionPrimitive.Header\n ref={ref}\n data-slot=\"accordion-header\"\n className={cn('flex', className)}\n {...props}\n />\n))\nAccordionHeader.displayName = 'AccordionHeader'\n\ntype AccordionTriggerProps = React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger> & {\n /**\n * Leading icon (Figma 210:4017 `question-line` slot). Renders as a\n * 20\u00D720 decorative glyph before the label. Pass any Lucide icon or\n * custom element; omit to skip the slot.\n *\n * When present and `iconPosition=\"end\"`, the parent `AccordionItem`\n * auto-promotes `AccordionContent`'s horizontal padding to 44px so the\n * description aligns with the title text.\n */\n leftIcon?: React.ReactNode\n /**\n * Trailing indicator style. Figma reference uses `'plus-minus'`\n * (add-line / subtract-line) \u2014 the default. `'chevron'` swaps in a\n * rotating ChevronDown for shadcn-style consumers. `'none'` disables\n * the indicator entirely (useful when `indicator` carries the visual).\n */\n triggerIcon?: AccordionTriggerIcon\n /**\n * Where the open/close indicator sits. `'end'` (default) puts it on\n * the trailing edge per Figma `Flip Icon = Off`; `'start'` mirrors the\n * Figma `Flip Icon = On` variant. With `'start'`, `leftIcon` is\n * intentionally suppressed because the indicator already occupies the\n * leading slot \u2014 pass any decorative glyph as the indicator itself.\n */\n iconPosition?: AccordionIconPosition\n /**\n * Custom indicator override. When provided, replaces the\n * `triggerIcon` plus/chevron node entirely \u2014 useful for status\n * badges, step numbers, or progress dots.\n */\n indicator?: React.ReactNode\n /**\n * Extra className applied to the internal `AccordionPrimitive.Header`\n * (`<h3>`) wrapper. Use this when the trigger row needs to share its\n * line with sibling action buttons (e.g. a kebab menu next to the\n * Accordion list of settings rows) \u2014 the header can then take\n * `flex-1` while the sibling stays its natural size.\n */\n headerClassName?: string\n}\n\nconst AccordionTrigger = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Trigger>,\n AccordionTriggerProps\n>(\n (\n {\n className,\n leftIcon,\n triggerIcon = 'plus-minus',\n iconPosition = 'end',\n indicator,\n headerClassName,\n children,\n ...props\n },\n ref,\n ) => {\n const indicatorNode =\n indicator !== undefined\n ? indicator\n : triggerIcon === 'chevron'\n ? <ChevronDown className=\"size-5 transition-transform duration-200 group-data-[state=open]/accordion-trigger:rotate-180\" aria-hidden=\"true\" />\n : triggerIcon === 'plus-minus'\n ? (\n <>\n <Plus className=\"size-5 group-data-[state=open]/accordion-trigger:hidden\" aria-hidden=\"true\" />\n <Minus className=\"hidden size-5 group-data-[state=open]/accordion-trigger:block\" aria-hidden=\"true\" />\n </>\n )\n : null\n\n const renderLeftIcon = Boolean(leftIcon) && iconPosition === 'end'\n\n return (\n <AccordionPrimitive.Header className={cn('flex', headerClassName)} data-slot=\"accordion-header\">\n <AccordionPrimitive.Trigger\n ref={ref}\n data-slot=\"accordion-trigger\"\n className={cn(\n 'group/accordion-trigger flex w-full items-start gap-2.5 p-3.5 text-left text-sm font-medium leading-5 tracking-tight text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50',\n className,\n )}\n {...props}\n >\n {iconPosition === 'start' && indicatorNode ? (\n <span\n className=\"inline-flex size-5 shrink-0 items-center justify-center text-foreground\"\n data-slot=\"accordion-trigger-indicator\"\n aria-hidden=\"true\"\n >\n {indicatorNode}\n </span>\n ) : null}\n {renderLeftIcon ? (\n <span\n className=\"inline-flex size-5 shrink-0 items-center justify-center text-muted-foreground [&>svg]:size-5\"\n data-slot=\"accordion-trigger-left-icon\"\n aria-hidden=\"true\"\n >\n {leftIcon}\n </span>\n ) : null}\n <span className=\"min-w-0 flex-1 self-center\" data-slot=\"accordion-trigger-label\">\n {children}\n </span>\n {iconPosition === 'end' && indicatorNode ? (\n <span\n className=\"inline-flex size-5 shrink-0 items-center justify-center text-foreground\"\n data-slot=\"accordion-trigger-indicator\"\n aria-hidden=\"true\"\n >\n {indicatorNode}\n </span>\n ) : null}\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n )\n },\n)\nAccordionTrigger.displayName = 'AccordionTrigger'\n\ntype AccordionContentProps = React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>\n\nconst AccordionContent = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Content>,\n AccordionContentProps\n>(({ className, children, ...props }, ref) => (\n <AccordionPrimitive.Content\n ref={ref}\n data-slot=\"accordion-content\"\n className={cn(\n 'overflow-hidden text-sm leading-5 text-muted-foreground data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down',\n className,\n )}\n {...props}\n >\n <div className=\"pb-3.5 pt-0 pl-[var(--accordion-indent)] pr-[var(--accordion-indent)]\">\n {children}\n </div>\n </AccordionPrimitive.Content>\n))\nAccordionContent.displayName = 'AccordionContent'\n\nexport {\n Accordion,\n AccordionItem,\n AccordionHeader,\n AccordionTrigger,\n AccordionContent,\n accordionItemVariants,\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -1,38 +1,206 @@
1
- import { jsx } from "react/jsx-runtime";
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
2
3
  import * as React from "react";
4
+ import { AlertCircle, CheckCircle2, Info, Rocket, X, AlertTriangle } from "lucide-react";
3
5
  import { cva } from "class-variance-authority";
4
6
  import { cn } from "@open-mercato/shared/lib/utils";
7
+ const legacyVariantToStatus = {
8
+ default: "information",
9
+ destructive: "error",
10
+ success: "success",
11
+ warning: "warning",
12
+ info: "information"
13
+ };
5
14
  const alertVariants = cva(
6
- "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg~*]:pl-8",
15
+ "relative flex w-full gap-2 transition-colors",
7
16
  {
8
17
  variants: {
9
- variant: {
10
- default: "border-border bg-background text-foreground [&>svg]:text-foreground",
11
- destructive: "border-status-error-border bg-status-error-bg text-status-error-text [&>svg]:text-status-error-icon",
12
- success: "border-status-success-border bg-status-success-bg text-status-success-text [&>svg]:text-status-success-icon",
13
- warning: "border-status-warning-border bg-status-warning-bg text-status-warning-text [&>svg]:text-status-warning-icon",
14
- info: "border-status-info-border bg-status-info-bg text-status-info-text [&>svg]:text-status-info-icon"
18
+ status: {
19
+ error: "",
20
+ warning: "",
21
+ success: "",
22
+ information: "",
23
+ feature: ""
24
+ },
25
+ style: {
26
+ filled: "",
27
+ light: "",
28
+ lighter: "",
29
+ stroke: ""
30
+ },
31
+ size: {
32
+ // Figma X-Small: px-[8px] py-[6px], radius-8, Paragraph/X Small (12/16)
33
+ xs: "min-h-8 items-center rounded-lg px-2 py-1.5 text-xs leading-4 tracking-tight",
34
+ // Figma Small: px-[10px] py-[8px], radius-8, Paragraph/Small (14/20)
35
+ sm: "min-h-9 items-center rounded-lg px-2.5 py-2 text-sm leading-5 tracking-tight",
36
+ // Figma Large: px-[12px] py-[10px], radius-12, Paragraph/Small (14/20) multi-line
37
+ default: "items-start rounded-xl px-3 py-2.5 text-sm leading-5 tracking-tight"
15
38
  }
16
39
  },
40
+ compoundVariants: [
41
+ // === filled (Figma: bg = state/{x}/base, text = static-white) ===
42
+ { status: "error", style: "filled", className: "border border-transparent bg-status-error-icon text-white" },
43
+ { status: "warning", style: "filled", className: "border border-transparent bg-status-warning-icon text-white" },
44
+ { status: "success", style: "filled", className: "border border-transparent bg-status-success-icon text-white" },
45
+ { status: "information", style: "filled", className: "border border-transparent bg-status-info-icon text-white" },
46
+ { status: "feature", style: "filled", className: "border border-transparent bg-status-neutral-icon text-white" },
47
+ // === light (Figma: bg = state/{x}/light, text = text/strong-950 = #171717 black) ===
48
+ { status: "error", style: "light", className: "border border-transparent bg-status-error-border text-foreground" },
49
+ { status: "warning", style: "light", className: "border border-transparent bg-status-warning-border text-foreground" },
50
+ { status: "success", style: "light", className: "border border-transparent bg-status-success-border text-foreground" },
51
+ { status: "information", style: "light", className: "border border-transparent bg-status-info-border text-foreground" },
52
+ { status: "feature", style: "light", className: "border border-transparent bg-status-neutral-border text-foreground" },
53
+ // === lighter (Figma: bg = state/{x}/lighter, text = text/strong-950 = #171717 black) ===
54
+ { status: "error", style: "lighter", className: "border border-transparent bg-status-error-bg text-foreground" },
55
+ { status: "warning", style: "lighter", className: "border border-transparent bg-status-warning-bg text-foreground" },
56
+ { status: "success", style: "lighter", className: "border border-transparent bg-status-success-bg text-foreground" },
57
+ { status: "information", style: "lighter", className: "border border-transparent bg-status-info-bg text-foreground" },
58
+ { status: "feature", style: "lighter", className: "border border-transparent bg-status-neutral-bg text-foreground" },
59
+ // === stroke (Figma: bg = white, border = stroke/soft-200, text = strong-950, shadow = regular-shadow/medium) ===
60
+ { style: "stroke", className: "border border-border bg-background text-foreground shadow-lg" }
61
+ ],
17
62
  defaultVariants: {
18
- variant: "default"
63
+ status: "information",
64
+ style: "light",
65
+ size: "sm"
19
66
  }
20
67
  }
21
68
  );
22
- const Alert = React.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, role: "alert", className: cn(alertVariants({ variant }), className), ...props }));
69
+ const alertDismissVariants = cva(
70
+ "shrink-0 rounded-md p-0.5 transition-opacity focus:outline-none focus-visible:ring-2 focus-visible:ring-ring/40",
71
+ {
72
+ variants: {
73
+ style: {
74
+ filled: "text-white opacity-90 hover:opacity-100",
75
+ light: "text-foreground opacity-40 hover:opacity-100",
76
+ lighter: "text-foreground opacity-40 hover:opacity-100",
77
+ stroke: "text-foreground opacity-40 hover:opacity-100"
78
+ }
79
+ },
80
+ defaultVariants: { style: "light" }
81
+ }
82
+ );
83
+ const alertIconBadgeVariants = cva(
84
+ "inline-flex shrink-0 items-center justify-center rounded-full text-white",
85
+ {
86
+ variants: {
87
+ status: {
88
+ error: "bg-status-error-icon",
89
+ warning: "bg-status-warning-icon",
90
+ success: "bg-status-success-icon",
91
+ information: "bg-status-info-icon",
92
+ feature: "bg-status-neutral-icon"
93
+ },
94
+ size: {
95
+ xs: "size-4 [&>svg]:size-2.5",
96
+ sm: "size-5 [&>svg]:size-3",
97
+ default: "size-6 [&>svg]:size-3.5"
98
+ }
99
+ },
100
+ defaultVariants: { status: "information", size: "sm" }
101
+ }
102
+ );
103
+ const defaultStatusIcons = {
104
+ error: AlertCircle,
105
+ warning: AlertTriangle,
106
+ success: CheckCircle2,
107
+ information: Info,
108
+ feature: Rocket
109
+ };
110
+ const Alert = React.forwardRef(
111
+ ({
112
+ className,
113
+ status,
114
+ style,
115
+ size,
116
+ showIcon = true,
117
+ icon,
118
+ dismissible = false,
119
+ onDismiss,
120
+ dismissAriaLabel = "Dismiss",
121
+ action,
122
+ variant,
123
+ children,
124
+ ...props
125
+ }, ref) => {
126
+ const resolvedStatus = status ?? (variant ? legacyVariantToStatus[variant] : "information");
127
+ const resolvedStyle = style ?? "light";
128
+ const resolvedSize = size ?? "sm";
129
+ const IconComponent = defaultStatusIcons[resolvedStatus];
130
+ const rawIcon = icon ?? /* @__PURE__ */ jsx(IconComponent, { "aria-hidden": "true" });
131
+ let iconSlot = null;
132
+ if (showIcon) {
133
+ if (resolvedStyle === "filled") {
134
+ iconSlot = /* @__PURE__ */ jsx(
135
+ "span",
136
+ {
137
+ className: cn(
138
+ "inline-flex shrink-0 items-center justify-center",
139
+ resolvedSize === "default" ? "[&>svg]:size-5" : "[&>svg]:size-4"
140
+ ),
141
+ "data-slot": "alert-icon",
142
+ children: rawIcon
143
+ }
144
+ );
145
+ } else {
146
+ iconSlot = /* @__PURE__ */ jsx(
147
+ "span",
148
+ {
149
+ className: alertIconBadgeVariants({ status: resolvedStatus, size: resolvedSize }),
150
+ "data-slot": "alert-icon-badge",
151
+ "data-status": resolvedStatus,
152
+ children: rawIcon
153
+ }
154
+ );
155
+ }
156
+ }
157
+ return /* @__PURE__ */ jsxs(
158
+ "div",
159
+ {
160
+ ref,
161
+ role: "alert",
162
+ className: cn(
163
+ alertVariants({ status: resolvedStatus, style: resolvedStyle, size: resolvedSize }),
164
+ className
165
+ ),
166
+ "data-slot": "alert",
167
+ "data-status": resolvedStatus,
168
+ "data-style": resolvedStyle,
169
+ ...props,
170
+ children: [
171
+ iconSlot,
172
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children }),
173
+ action ? /* @__PURE__ */ jsx("div", { className: "shrink-0", children: action }) : null,
174
+ dismissible ? /* @__PURE__ */ jsx(
175
+ "button",
176
+ {
177
+ type: "button",
178
+ onClick: onDismiss,
179
+ "aria-label": dismissAriaLabel,
180
+ className: alertDismissVariants({ style: resolvedStyle }),
181
+ "data-slot": "alert-dismiss",
182
+ children: /* @__PURE__ */ jsx(X, { "aria-hidden": "true", className: "size-4" })
183
+ }
184
+ ) : null
185
+ ]
186
+ }
187
+ );
188
+ }
189
+ );
23
190
  Alert.displayName = "Alert";
24
191
  const AlertTitle = React.forwardRef(
25
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx("h5", { ref, className: cn("mb-1 text-sm font-semibold leading-tight", className), ...props })
192
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("h5", { ref, className: cn("mb-1 text-sm font-medium leading-5", className), ...props })
26
193
  );
27
194
  AlertTitle.displayName = "AlertTitle";
28
195
  const AlertDescription = React.forwardRef(
29
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx("p", { ref, className: cn("text-sm leading-relaxed", className), ...props })
196
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("p", { ref, className: cn("text-sm leading-5", className), ...props })
30
197
  );
31
198
  AlertDescription.displayName = "AlertDescription";
32
199
  export {
33
200
  Alert,
34
201
  AlertDescription,
35
202
  AlertTitle,
203
+ alertIconBadgeVariants,
36
204
  alertVariants
37
205
  };
38
206
  //# sourceMappingURL=alert.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/primitives/alert.tsx"],
4
- "sourcesContent": ["import * as React from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\n\nimport { cn } from '@open-mercato/shared/lib/utils'\n\nconst alertVariants = cva(\n \"relative w-full rounded-lg border px-4 py-3 text-sm [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg~*]:pl-8\",\n {\n variants: {\n variant: {\n default: 'border-border bg-background text-foreground [&>svg]:text-foreground',\n destructive:\n 'border-status-error-border bg-status-error-bg text-status-error-text [&>svg]:text-status-error-icon',\n success:\n 'border-status-success-border bg-status-success-bg text-status-success-text [&>svg]:text-status-success-icon',\n warning:\n 'border-status-warning-border bg-status-warning-bg text-status-warning-text [&>svg]:text-status-warning-icon',\n info:\n 'border-status-info-border bg-status-info-bg text-status-info-text [&>svg]:text-status-info-icon',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n }\n)\n\ntype AlertProps = React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>\n\nconst Alert = React.forwardRef<HTMLDivElement, AlertProps>(({ className, variant, ...props }, ref) => (\n <div ref={ref} role=\"alert\" className={cn(alertVariants({ variant }), className)} {...props} />\n))\n\nAlert.displayName = 'Alert'\n\nconst AlertTitle = React.forwardRef<HTMLHeadingElement, React.HTMLAttributes<HTMLHeadingElement>>(\n ({ className, ...props }, ref) => (\n <h5 ref={ref} className={cn('mb-1 text-sm font-semibold leading-tight', className)} {...props} />\n )\n)\n\nAlertTitle.displayName = 'AlertTitle'\n\nconst AlertDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(\n ({ className, ...props }, ref) => (\n <p ref={ref} className={cn('text-sm leading-relaxed', className)} {...props} />\n )\n)\n\nAlertDescription.displayName = 'AlertDescription'\n\nexport { Alert, AlertDescription, AlertTitle, alertVariants }\n"],
5
- "mappings": "AA8BE;AA9BF,YAAY,WAAW;AACvB,SAAS,WAA8B;AAEvC,SAAS,UAAU;AAEnB,MAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAAS;AAAA,QACT,aACE;AAAA,QACF,SACE;AAAA,QACF,SACE;AAAA,QACF,MACE;AAAA,MACJ;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAIA,MAAM,QAAQ,MAAM,WAAuC,CAAC,EAAE,WAAW,SAAS,GAAG,MAAM,GAAG,QAC5F,oBAAC,SAAI,KAAU,MAAK,SAAQ,WAAW,GAAG,cAAc,EAAE,QAAQ,CAAC,GAAG,SAAS,GAAI,GAAG,OAAO,CAC9F;AAED,MAAM,cAAc;AAEpB,MAAM,aAAa,MAAM;AAAA,EACvB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QACxB,oBAAC,QAAG,KAAU,WAAW,GAAG,4CAA4C,SAAS,GAAI,GAAG,OAAO;AAEnG;AAEA,WAAW,cAAc;AAEzB,MAAM,mBAAmB,MAAM;AAAA,EAC7B,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QACxB,oBAAC,OAAE,KAAU,WAAW,GAAG,2BAA2B,SAAS,GAAI,GAAG,OAAO;AAEjF;AAEA,iBAAiB,cAAc;",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { AlertCircle, CheckCircle2, Info, Rocket, X, AlertTriangle } from 'lucide-react'\nimport { cva, type VariantProps } from 'class-variance-authority'\n\nimport { cn } from '@open-mercato/shared/lib/utils'\n\nexport type AlertStatus = 'error' | 'warning' | 'success' | 'information' | 'feature'\nexport type AlertStyle = 'filled' | 'light' | 'lighter' | 'stroke'\nexport type AlertSize = 'xs' | 'sm' | 'default'\n\n/**\n * Legacy `variant` values from the pre-Figma-`169:2358` API. Kept for BC \u2014\n * mapped to `status` inside the Alert component so existing call sites do\n * not need migration. The Figma `light` look (`#fecaca` saturated tint\n * for error \u2192 `state/{x}/light` token family) is heavier than the\n * pre-Figma look; legacy call sites that want the softer pre-Figma\n * appearance should switch explicitly to `style=\"lighter\"`.\n */\ntype LegacyVariant = 'default' | 'destructive' | 'success' | 'warning' | 'info'\n\nconst legacyVariantToStatus: Record<LegacyVariant, AlertStatus> = {\n default: 'information',\n destructive: 'error',\n success: 'success',\n warning: 'warning',\n info: 'information',\n}\n\nconst alertVariants = cva(\n 'relative flex w-full gap-2 transition-colors',\n {\n variants: {\n status: {\n error: '',\n warning: '',\n success: '',\n information: '',\n feature: '',\n },\n style: {\n filled: '',\n light: '',\n lighter: '',\n stroke: '',\n },\n size: {\n // Figma X-Small: px-[8px] py-[6px], radius-8, Paragraph/X Small (12/16)\n xs: 'min-h-8 items-center rounded-lg px-2 py-1.5 text-xs leading-4 tracking-tight',\n // Figma Small: px-[10px] py-[8px], radius-8, Paragraph/Small (14/20)\n sm: 'min-h-9 items-center rounded-lg px-2.5 py-2 text-sm leading-5 tracking-tight',\n // Figma Large: px-[12px] py-[10px], radius-12, Paragraph/Small (14/20) multi-line\n default: 'items-start rounded-xl px-3 py-2.5 text-sm leading-5 tracking-tight',\n },\n },\n compoundVariants: [\n // === filled (Figma: bg = state/{x}/base, text = static-white) ===\n { status: 'error', style: 'filled', className: 'border border-transparent bg-status-error-icon text-white' },\n { status: 'warning', style: 'filled', className: 'border border-transparent bg-status-warning-icon text-white' },\n { status: 'success', style: 'filled', className: 'border border-transparent bg-status-success-icon text-white' },\n { status: 'information', style: 'filled', className: 'border border-transparent bg-status-info-icon text-white' },\n { status: 'feature', style: 'filled', className: 'border border-transparent bg-status-neutral-icon text-white' },\n // === light (Figma: bg = state/{x}/light, text = text/strong-950 = #171717 black) ===\n { status: 'error', style: 'light', className: 'border border-transparent bg-status-error-border text-foreground' },\n { status: 'warning', style: 'light', className: 'border border-transparent bg-status-warning-border text-foreground' },\n { status: 'success', style: 'light', className: 'border border-transparent bg-status-success-border text-foreground' },\n { status: 'information', style: 'light', className: 'border border-transparent bg-status-info-border text-foreground' },\n { status: 'feature', style: 'light', className: 'border border-transparent bg-status-neutral-border text-foreground' },\n // === lighter (Figma: bg = state/{x}/lighter, text = text/strong-950 = #171717 black) ===\n { status: 'error', style: 'lighter', className: 'border border-transparent bg-status-error-bg text-foreground' },\n { status: 'warning', style: 'lighter', className: 'border border-transparent bg-status-warning-bg text-foreground' },\n { status: 'success', style: 'lighter', className: 'border border-transparent bg-status-success-bg text-foreground' },\n { status: 'information', style: 'lighter', className: 'border border-transparent bg-status-info-bg text-foreground' },\n { status: 'feature', style: 'lighter', className: 'border border-transparent bg-status-neutral-bg text-foreground' },\n // === stroke (Figma: bg = white, border = stroke/soft-200, text = strong-950, shadow = regular-shadow/medium) ===\n { style: 'stroke', className: 'border border-border bg-background text-foreground shadow-lg' },\n ],\n defaultVariants: {\n status: 'information',\n style: 'light',\n size: 'sm',\n },\n },\n)\n\n// Dismiss button (X) color per Figma: text/strong-950 (#171717 black) at\n// `opacity-40` for light/lighter/stroke \u2014 matches the Figma `close-line`\n// icon which is the dark icon-strong-950 fill rendered at 40% alpha\n// (visually \u2248 #5c5c5c gray). White at full opacity for filled so it\n// stays legible over the saturated bg.\nconst alertDismissVariants = cva(\n 'shrink-0 rounded-md p-0.5 transition-opacity focus:outline-none focus-visible:ring-2 focus-visible:ring-ring/40',\n {\n variants: {\n style: {\n filled: 'text-white opacity-90 hover:opacity-100',\n light: 'text-foreground opacity-40 hover:opacity-100',\n lighter: 'text-foreground opacity-40 hover:opacity-100',\n stroke: 'text-foreground opacity-40 hover:opacity-100',\n },\n },\n defaultVariants: { style: 'light' },\n },\n)\n\nconst alertIconBadgeVariants = cva(\n 'inline-flex shrink-0 items-center justify-center rounded-full text-white',\n {\n variants: {\n status: {\n error: 'bg-status-error-icon',\n warning: 'bg-status-warning-icon',\n success: 'bg-status-success-icon',\n information: 'bg-status-info-icon',\n feature: 'bg-status-neutral-icon',\n },\n size: {\n xs: 'size-4 [&>svg]:size-2.5',\n sm: 'size-5 [&>svg]:size-3',\n default: 'size-6 [&>svg]:size-3.5',\n },\n },\n defaultVariants: { status: 'information', size: 'sm' },\n },\n)\n\nconst defaultStatusIcons: Record<AlertStatus, React.ComponentType<{ className?: string; 'aria-hidden'?: 'true' }>> = {\n error: AlertCircle,\n warning: AlertTriangle,\n success: CheckCircle2,\n information: Info,\n feature: Rocket,\n}\n\nexport type AlertProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'role'> &\n Omit<VariantProps<typeof alertVariants>, 'status' | 'style' | 'size'> & {\n status?: AlertStatus\n style?: AlertStyle\n size?: AlertSize\n /** Show the leading icon. Default `true`. */\n showIcon?: boolean\n /** Override the default per-status Lucide icon. */\n icon?: React.ReactNode\n /** Render a trailing close (X) button. Pair with `onDismiss`. */\n dismissible?: boolean\n onDismiss?: () => void\n dismissAriaLabel?: string\n /** Inline action slot (link buttons) rendered to the right of the body. */\n action?: React.ReactNode\n /**\n * @deprecated Use `status` + `style` instead. Kept for BC. Maps the\n * legacy single-prop variants onto `status` and picks up the new\n * `light` + `sm` defaults.\n */\n variant?: LegacyVariant\n }\n\nconst Alert = React.forwardRef<HTMLDivElement, AlertProps>(\n (\n {\n className,\n status,\n style,\n size,\n showIcon = true,\n icon,\n dismissible = false,\n onDismiss,\n dismissAriaLabel = 'Dismiss',\n action,\n variant,\n children,\n ...props\n },\n ref,\n ) => {\n const resolvedStatus: AlertStatus = status ?? (variant ? legacyVariantToStatus[variant] : 'information')\n const resolvedStyle: AlertStyle = style ?? 'light'\n const resolvedSize: AlertSize = size ?? 'sm'\n const IconComponent = defaultStatusIcons[resolvedStatus]\n const rawIcon = icon ?? <IconComponent aria-hidden=\"true\" />\n\n let iconSlot: React.ReactNode = null\n if (showIcon) {\n if (resolvedStyle === 'filled') {\n // Filled: plain icon over saturated bg \u2014 no badge wrap, inherit text-white.\n iconSlot = (\n <span\n className={cn(\n 'inline-flex shrink-0 items-center justify-center',\n resolvedSize === 'default' ? '[&>svg]:size-5' : '[&>svg]:size-4',\n )}\n data-slot=\"alert-icon\"\n >\n {rawIcon}\n </span>\n )\n } else {\n // light / lighter / stroke: badge wrap with status color bg + white icon.\n iconSlot = (\n <span\n className={alertIconBadgeVariants({ status: resolvedStatus, size: resolvedSize })}\n data-slot=\"alert-icon-badge\"\n data-status={resolvedStatus}\n >\n {rawIcon}\n </span>\n )\n }\n }\n\n return (\n <div\n ref={ref}\n role=\"alert\"\n className={cn(\n alertVariants({ status: resolvedStatus, style: resolvedStyle, size: resolvedSize }),\n className,\n )}\n data-slot=\"alert\"\n data-status={resolvedStatus}\n data-style={resolvedStyle}\n {...props}\n >\n {iconSlot}\n <div className=\"min-w-0 flex-1\">{children}</div>\n {action ? <div className=\"shrink-0\">{action}</div> : null}\n {dismissible ? (\n <button\n type=\"button\"\n onClick={onDismiss}\n aria-label={dismissAriaLabel}\n className={alertDismissVariants({ style: resolvedStyle })}\n data-slot=\"alert-dismiss\"\n >\n <X aria-hidden=\"true\" className=\"size-4\" />\n </button>\n ) : null}\n </div>\n )\n },\n)\nAlert.displayName = 'Alert'\n\n// Figma \"Label/Small\": Inter Medium 14 / 20.\nconst AlertTitle = React.forwardRef<HTMLHeadingElement, React.HTMLAttributes<HTMLHeadingElement>>(\n ({ className, ...props }, ref) => (\n <h5 ref={ref} className={cn('mb-1 text-sm font-medium leading-5', className)} {...props} />\n ),\n)\nAlertTitle.displayName = 'AlertTitle'\n\n// Figma \"Paragraph/Small\": Inter Regular 14 / 20.\nconst AlertDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(\n ({ className, ...props }, ref) => (\n <p ref={ref} className={cn('text-sm leading-5', className)} {...props} />\n ),\n)\nAlertDescription.displayName = 'AlertDescription'\n\nexport { Alert, AlertDescription, AlertTitle, alertVariants, alertIconBadgeVariants }\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,56 +1,146 @@
1
1
  "use client";
2
- import { jsx } from "react/jsx-runtime";
3
- import { DayPicker } from "react-day-picker";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { DayPicker, useDayPicker } from "react-day-picker";
4
5
  import { ChevronLeft, ChevronRight } from "lucide-react";
6
+ import { format } from "date-fns";
5
7
  import { cn } from "@open-mercato/shared/lib/utils";
6
- function Calendar({ className, classNames, showOutsideDays = true, ...props }) {
8
+ function MonthNavButton({
9
+ direction,
10
+ locale
11
+ }) {
12
+ const dayPicker = useDayPicker();
13
+ const target = direction === "prev" ? dayPicker.previousMonth : dayPicker.nextMonth;
14
+ const Icon = direction === "prev" ? ChevronLeft : ChevronRight;
15
+ const targetLabel = format(target ?? /* @__PURE__ */ new Date(), "MMMM yyyy", locale ? { locale } : void 0);
16
+ const ariaLabel = `Go to ${direction === "prev" ? "previous" : "next"} month: ${targetLabel}`;
17
+ return /* @__PURE__ */ jsx(
18
+ "button",
19
+ {
20
+ type: "button",
21
+ disabled: !target,
22
+ "aria-label": ariaLabel,
23
+ onClick: () => {
24
+ if (target && dayPicker.goToMonth) dayPicker.goToMonth(target);
25
+ },
26
+ className: cn(
27
+ "h-9 w-9 inline-flex items-center justify-center rounded-md shrink-0",
28
+ "border border-border bg-background text-muted-foreground transition-colors",
29
+ "hover:bg-accent hover:text-accent-foreground hover:border-input",
30
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
31
+ "disabled:opacity-30 disabled:pointer-events-none disabled:hover:bg-background"
32
+ ),
33
+ children: /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4", "aria-hidden": "true" })
34
+ }
35
+ );
36
+ }
37
+ function buildMonthCaption(locale, totalMonths) {
38
+ return function MonthCaption({
39
+ calendarMonth,
40
+ displayIndex
41
+ }) {
42
+ const label = format(calendarMonth.date, "MMMM yyyy", locale ? { locale } : void 0);
43
+ const index = typeof displayIndex === "number" ? displayIndex : 0;
44
+ const showPrev = index === 0;
45
+ const showNext = index === totalMonths - 1;
46
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 mb-3", children: [
47
+ showPrev ? /* @__PURE__ */ jsx(MonthNavButton, { direction: "prev", locale }) : /* @__PURE__ */ jsx("div", { className: "h-9 w-9 shrink-0", "aria-hidden": "true" }),
48
+ /* @__PURE__ */ jsx(
49
+ "div",
50
+ {
51
+ className: "flex-1 flex items-center justify-center h-9 rounded-md bg-muted px-3 text-sm font-medium",
52
+ "aria-live": "polite",
53
+ children: label
54
+ }
55
+ ),
56
+ showNext ? /* @__PURE__ */ jsx(MonthNavButton, { direction: "next", locale }) : /* @__PURE__ */ jsx("div", { className: "h-9 w-9 shrink-0", "aria-hidden": "true" })
57
+ ] });
58
+ };
59
+ }
60
+ function Calendar({
61
+ className,
62
+ classNames,
63
+ showOutsideDays = true,
64
+ fixedWeeks = true,
65
+ locale,
66
+ components,
67
+ numberOfMonths = 1,
68
+ pagedNavigation = true,
69
+ ...props
70
+ }) {
71
+ const monthCaption = React.useMemo(
72
+ () => buildMonthCaption(locale, numberOfMonths),
73
+ [locale, numberOfMonths]
74
+ );
7
75
  return /* @__PURE__ */ jsx(
8
76
  DayPicker,
9
77
  {
10
78
  showOutsideDays,
79
+ fixedWeeks,
80
+ pagedNavigation,
81
+ locale,
82
+ numberOfMonths,
11
83
  className: cn("p-3", className),
12
84
  classNames: {
13
85
  months: "flex flex-col sm:flex-row gap-4",
14
- month: "space-y-4",
15
- month_caption: "flex justify-center pt-1 relative items-center",
16
- caption_label: "text-sm font-medium",
17
- nav: "flex items-center gap-1",
18
- button_previous: cn(
19
- "absolute left-1 h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
20
- "inline-flex items-center justify-center rounded-md text-sm font-medium",
21
- "ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2",
22
- "focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
23
- "hover:bg-accent hover:text-accent-foreground border-0"
24
- ),
25
- button_next: cn(
26
- "absolute right-1 h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
27
- "inline-flex items-center justify-center rounded-md text-sm font-medium",
28
- "ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2",
29
- "focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
30
- "hover:bg-accent hover:text-accent-foreground border-0"
31
- ),
32
- month_grid: "w-full border-collapse space-y-1",
86
+ month: "space-y-2",
87
+ month_caption: "",
88
+ caption_label: "sr-only",
89
+ nav: "sr-only",
90
+ month_grid: "w-full border-collapse",
33
91
  weekdays: "flex",
34
92
  weekday: "text-muted-foreground rounded-md w-9 font-normal text-xs",
35
- weeks: "w-full border-collapse space-y-1",
36
- week: "flex w-full mt-2",
37
- day: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
93
+ weeks: "w-full border-collapse",
94
+ week: "flex w-full mt-1",
95
+ day: "h-9 w-9 text-center text-sm p-0 relative focus-within:relative focus-within:z-20",
38
96
  day_button: cn(
39
97
  "h-9 w-9 p-0 font-normal aria-selected:opacity-100",
40
98
  "inline-flex items-center justify-center rounded-md text-sm",
41
- "ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2",
42
- "focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none",
43
- "hover:bg-accent hover:text-accent-foreground"
99
+ "transition-colors focus:outline-none focus-visible:outline-none disabled:pointer-events-none",
100
+ // Focus indicator is a soft accent fill instead of a ring overlay — keyboard
101
+ // users get a visible cue, but mouse-click focus does not leave a stuck ring
102
+ // on top of the selected cell.
103
+ "hover:bg-accent hover:text-accent-foreground",
104
+ "focus-visible:bg-accent focus-visible:text-accent-foreground"
105
+ ),
106
+ // React-day-picker v9 applies `classNames.selected` / `range_*` to the day
107
+ // CELL (`<td>`) wrapper, not to the inner `<button>`. To keep the parent
108
+ // fill visible through interaction, we (a) paint the cell with the desired
109
+ // bg/text, and (b) force the inner button to render transparent — so the
110
+ // button's own hover/focus-visible bg overrides cannot cover the cell fill.
111
+ selected: cn(
112
+ "!bg-primary !text-primary-foreground rounded-md",
113
+ "[&_button]:!bg-transparent [&_button]:!text-primary-foreground",
114
+ "[&_button:hover]:!bg-transparent [&_button:hover]:!text-primary-foreground",
115
+ "[&_button:focus-visible]:!bg-transparent [&_button:focus-visible]:!text-primary-foreground"
116
+ ),
117
+ range_start: cn(
118
+ "!bg-primary !text-primary-foreground rounded-l-md !rounded-r-none",
119
+ "[&_button]:!bg-transparent [&_button]:!text-primary-foreground",
120
+ "[&_button:hover]:!bg-transparent [&_button:hover]:!text-primary-foreground",
121
+ "[&_button:focus-visible]:!bg-transparent [&_button:focus-visible]:!text-primary-foreground"
122
+ ),
123
+ range_end: cn(
124
+ "!bg-primary !text-primary-foreground rounded-r-md !rounded-l-none",
125
+ "[&_button]:!bg-transparent [&_button]:!text-primary-foreground",
126
+ "[&_button:hover]:!bg-transparent [&_button:hover]:!text-primary-foreground",
127
+ "[&_button:focus-visible]:!bg-transparent [&_button:focus-visible]:!text-primary-foreground"
128
+ ),
129
+ range_middle: cn(
130
+ "!bg-accent !text-accent-foreground !rounded-none",
131
+ "[&_button]:!bg-transparent [&_button]:!text-accent-foreground",
132
+ "[&_button:hover]:!bg-transparent [&_button:hover]:!text-accent-foreground",
133
+ "[&_button:focus-visible]:!bg-transparent [&_button:focus-visible]:!text-accent-foreground"
44
134
  ),
45
- selected: "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground rounded-md",
46
- today: "bg-accent text-accent-foreground rounded-md",
47
- outside: "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
135
+ today: "font-semibold text-primary rounded-md",
136
+ outside: "day-outside text-muted-foreground opacity-40 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
48
137
  disabled: "text-muted-foreground opacity-50",
49
138
  hidden: "invisible",
50
139
  ...classNames
51
140
  },
52
141
  components: {
53
- Chevron: ({ orientation }) => orientation === "left" ? /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
142
+ MonthCaption: monthCaption,
143
+ ...components
54
144
  },
55
145
  ...props
56
146
  }