@carefully-built/widgets 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +49 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +35 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LucideIcon } from "lucide-react";
|
|
2
|
-
import { ReactNode } from "react";
|
|
2
|
+
import { CSSProperties, ReactNode } from "react";
|
|
3
3
|
|
|
4
4
|
//#region src/widget-empty-state.d.ts
|
|
5
5
|
interface WidgetEmptyStateAction {
|
|
@@ -109,5 +109,52 @@ declare function PeriodSelect({
|
|
|
109
109
|
className
|
|
110
110
|
}: PeriodSelectProps): React.ReactElement;
|
|
111
111
|
//#endregion
|
|
112
|
-
|
|
112
|
+
//#region src/reveal.d.ts
|
|
113
|
+
interface RevealProps {
|
|
114
|
+
readonly children: ReactNode;
|
|
115
|
+
/** Position in the sequence: each step waits `step` ms more than the previous. */
|
|
116
|
+
readonly index?: number;
|
|
117
|
+
readonly step?: number;
|
|
118
|
+
/** Extra delay in ms before the sequence, e.g. for a block below another sequence. */
|
|
119
|
+
readonly offset?: number;
|
|
120
|
+
readonly duration?: number;
|
|
121
|
+
readonly className?: string;
|
|
122
|
+
readonly style?: CSSProperties;
|
|
123
|
+
readonly as?: 'div' | 'li' | 'section' | 'span';
|
|
124
|
+
/** Lets the wrapper take a themed slot (e.g. `widget`) instead of `reveal`. */
|
|
125
|
+
readonly 'data-slot'?: string;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Fades and lifts its content into place on mount, staggered by `index`, so a
|
|
129
|
+
* page of widgets appears one after the other instead of all at once.
|
|
130
|
+
*/
|
|
131
|
+
declare function Reveal({
|
|
132
|
+
children,
|
|
133
|
+
index,
|
|
134
|
+
step,
|
|
135
|
+
offset,
|
|
136
|
+
duration,
|
|
137
|
+
className,
|
|
138
|
+
style,
|
|
139
|
+
as: Tag,
|
|
140
|
+
'data-slot': slot
|
|
141
|
+
}: RevealProps): React.ReactElement;
|
|
142
|
+
interface GrowBarProps {
|
|
143
|
+
/** 0–100. */
|
|
144
|
+
readonly percent: number;
|
|
145
|
+
readonly color?: string;
|
|
146
|
+
readonly delay?: number;
|
|
147
|
+
readonly className?: string;
|
|
148
|
+
readonly trackClassName?: string;
|
|
149
|
+
}
|
|
150
|
+
/** A progress bar that grows from the left on mount. */
|
|
151
|
+
declare function GrowBar({
|
|
152
|
+
percent,
|
|
153
|
+
color,
|
|
154
|
+
delay,
|
|
155
|
+
className,
|
|
156
|
+
trackClassName
|
|
157
|
+
}: GrowBarProps): React.ReactElement;
|
|
158
|
+
//#endregion
|
|
159
|
+
export { DashboardWidget, type DashboardWidgetProps, EntityInfoWidget, type EntityInfoWidgetProps, GrowBar, type GrowBarProps, PERIOD_PRESETS, type PeriodPreset, type PeriodRange, PeriodSelect, Reveal, type RevealProps, WidgetEmptyState, type WidgetEmptyStateAction, type WidgetEmptyStateConfig, type WidgetEmptyStateProps, isPeriodPreset, resolvePeriodRange };
|
|
113
160
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/widget-empty-state.tsx","../src/dashboard-widget.tsx","../src/entity-info-widget.tsx","../src/period-select.tsx"],"sourcesContent":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/widget-empty-state.tsx","../src/dashboard-widget.tsx","../src/entity-info-widget.tsx","../src/period-select.tsx","../src/reveal.tsx"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -199,5 +199,39 @@ function PeriodSelect({ value, onChange, presets = PERIOD_PRESETS, className })
|
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
//#endregion
|
|
202
|
-
|
|
202
|
+
//#region src/reveal.tsx
|
|
203
|
+
/**
|
|
204
|
+
* Fades and lifts its content into place on mount, staggered by `index`, so a
|
|
205
|
+
* page of widgets appears one after the other instead of all at once.
|
|
206
|
+
*/
|
|
207
|
+
function Reveal({ children, index = 0, step = 80, offset = 0, duration = 700, className, style, as: Tag = "div", "data-slot": slot = "reveal" }) {
|
|
208
|
+
return /* @__PURE__ */ jsx(Tag, {
|
|
209
|
+
"data-slot": slot,
|
|
210
|
+
className: cn("animate-in fade-in-0 slide-in-from-bottom-3 fill-mode-both ease-out", className),
|
|
211
|
+
style: {
|
|
212
|
+
animationDuration: `${String(duration)}ms`,
|
|
213
|
+
animationDelay: `${String(offset + index * step)}ms`,
|
|
214
|
+
...style
|
|
215
|
+
},
|
|
216
|
+
children
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
/** A progress bar that grows from the left on mount. */
|
|
220
|
+
function GrowBar({ percent, color, delay = 0, className, trackClassName }) {
|
|
221
|
+
return /* @__PURE__ */ jsx("div", {
|
|
222
|
+
className: cn("bg-muted h-2 w-full overflow-hidden rounded-full", trackClassName),
|
|
223
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
224
|
+
"data-slot": "grow-bar",
|
|
225
|
+
className: cn("bg-primary h-full origin-left rounded-full", className),
|
|
226
|
+
style: {
|
|
227
|
+
width: `${String(Math.max(0, Math.min(100, percent)))}%`,
|
|
228
|
+
backgroundColor: color,
|
|
229
|
+
animation: `kit-grow-x 900ms cubic-bezier(0.2, 0.8, 0.2, 1) ${String(delay)}ms both`
|
|
230
|
+
}
|
|
231
|
+
})
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
//#endregion
|
|
236
|
+
export { DashboardWidget, EntityInfoWidget, GrowBar, PERIOD_PRESETS, PeriodSelect, Reveal, WidgetEmptyState, isPeriodPreset, resolvePeriodRange };
|
|
203
237
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/widget-empty-state.tsx","../src/entity-info-widget.tsx","../src/dashboard-widget.tsx","../src/period-select.tsx"],"sourcesContent":["\"use client\";\n\nimport type { LucideIcon } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\n\nimport { Button, cn } from \"@carefully-built/ui\";\n\nexport interface WidgetEmptyStateAction {\n readonly label: string;\n readonly href?: string;\n readonly onClick?: () => void;\n readonly target?: \"_blank\" | \"_self\" | \"_parent\" | \"_top\";\n readonly rel?: string;\n readonly icon?: ReactNode;\n readonly disabled?: boolean;\n}\n\nexport interface WidgetEmptyStateConfig {\n readonly title: string;\n readonly description: string;\n readonly icon?: LucideIcon;\n readonly minHeightClassName?: string;\n readonly className?: string;\n readonly action?: WidgetEmptyStateAction;\n}\n\nexport interface WidgetEmptyStateProps extends WidgetEmptyStateConfig {\n readonly icon: LucideIcon;\n}\n\nexport function WidgetEmptyState({\n icon: Icon,\n title,\n description,\n minHeightClassName,\n className,\n action,\n}: WidgetEmptyStateProps): React.ReactElement {\n return (\n <div\n data-empty-state=\"\"\n className={cn(\n \"flex h-full w-full items-center justify-center rounded-[16px] border border-dashed border-border/70 px-4 py-8 text-center\",\n minHeightClassName ?? \"min-h-[248px]\",\n className,\n )}\n >\n <div className=\"max-w-[280px] space-y-2\">\n <div className=\"text-muted-foreground flex justify-center\">\n <Icon className=\"size-5\" strokeWidth={1.75} />\n </div>\n <p className=\"text-foreground text-sm font-medium\">{title}</p>\n <p className=\"text-muted-foreground text-xs leading-5\">{description}</p>\n {action ? (\n action.href ? (\n <Button asChild variant=\"outline\" size=\"sm\" className=\"mt-4\">\n <a href={action.href} target={action.target ?? \"_self\"} rel={action.rel}>\n {action.icon ? <span className=\"inline-flex items-center\">{action.icon}</span> : null}\n {action.label}\n </a>\n </Button>\n ) : (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"mt-4\"\n onClick={action.onClick}\n disabled={action.disabled}\n >\n {action.icon ? <span className=\"inline-flex items-center\">{action.icon}</span> : null}\n {action.label}\n </Button>\n )\n ) : null}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport type { LucideIcon } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\n\nimport { cn } from \"@carefully-built/ui\";\n\nimport { WidgetEmptyState } from \"./widget-empty-state\";\nimport type { WidgetEmptyStateConfig } from \"./widget-empty-state\";\n\nexport interface EntityInfoWidgetProps {\n readonly icon: LucideIcon;\n readonly name: string;\n readonly children: ReactNode;\n readonly className?: string;\n readonly contentClassName?: string;\n readonly nameActions?: ReactNode;\n readonly headerActions?: ReactNode;\n readonly isEmpty?: boolean;\n readonly emptyState?: WidgetEmptyStateConfig;\n}\n\nexport function EntityInfoWidget({\n icon: Icon,\n name,\n children,\n className,\n contentClassName,\n nameActions,\n headerActions,\n isEmpty = false,\n emptyState,\n}: EntityInfoWidgetProps): React.ReactElement {\n return (\n <section\n data-slot=\"widget\"\n className={cn(\n \"border-border flex min-w-0 flex-col gap-3 rounded-[12px] border bg-background p-1.5\",\n className,\n )}\n >\n <div className=\"flex min-w-0 flex-wrap items-center justify-between gap-3 px-0.5 sm:flex-nowrap\">\n <div className=\"text-muted-foreground flex min-w-0 items-center gap-[3px] text-[13px]\">\n <Icon className=\"size-3.5 shrink-0\" strokeWidth={1.75} />\n <span className=\"truncate\">{name}</span>\n {nameActions ? <span className=\"ml-1 shrink-0\">{nameActions}</span> : null}\n </div>\n {headerActions ? (\n <div className=\"flex min-w-0 max-w-full items-center gap-2 sm:shrink-0\">\n {headerActions}\n </div>\n ) : null}\n </div>\n <div className={cn(\"min-w-0\", contentClassName)}>\n {isEmpty && emptyState ? (\n <WidgetEmptyState\n icon={emptyState.icon ?? Icon}\n title={emptyState.title}\n description={emptyState.description}\n minHeightClassName={emptyState.minHeightClassName}\n className={emptyState.className}\n action={emptyState.action}\n />\n ) : (\n children\n )}\n </div>\n </section>\n );\n}\n","\"use client\";\n\nimport type { LucideIcon } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\n\nimport { Skeleton, cn } from \"@carefully-built/ui\";\n\nimport { EntityInfoWidget } from \"./entity-info-widget\";\nimport type { WidgetEmptyStateConfig } from \"./widget-empty-state\";\n\nexport interface DashboardWidgetProps {\n readonly icon: LucideIcon;\n readonly title: string;\n readonly value?: ReactNode;\n readonly actions?: ReactNode;\n readonly children?: ReactNode;\n readonly className?: string;\n readonly contentClassName?: string;\n readonly isLoading?: boolean;\n readonly loadingFallback?: ReactNode;\n readonly isEmpty?: boolean;\n readonly emptyState?: WidgetEmptyStateConfig;\n}\n\nexport function DashboardWidget({\n icon,\n title,\n value,\n actions,\n children,\n className,\n contentClassName,\n isLoading = false,\n loadingFallback,\n isEmpty = false,\n emptyState,\n}: DashboardWidgetProps): React.ReactElement {\n const shouldRenderEmptyState = !isLoading && value === undefined && isEmpty;\n let defaultContentClassName = \"pt-1\";\n\n if (value !== undefined) {\n defaultContentClassName = \"px-0.5 pt-2 pb-0.5\";\n } else if (shouldRenderEmptyState) {\n defaultContentClassName = \"flex min-h-0 flex-1 pt-1\";\n }\n\n return (\n <EntityInfoWidget\n icon={icon}\n name={title}\n className={cn(\"h-full min-w-0 gap-0\", className)}\n contentClassName={cn(defaultContentClassName, contentClassName)}\n headerActions={actions}\n isEmpty={shouldRenderEmptyState}\n emptyState={value === undefined ? emptyState : undefined}\n >\n {value !== undefined ? (\n <div\n data-slot=\"widget-value\"\n className=\"text-foreground text-[24px] leading-none font-medium tracking-[-0.02em]\"\n aria-busy={isLoading || undefined}\n >\n {isLoading ? <Skeleton className=\"h-7 w-16\" /> : value}\n </div>\n ) : isLoading ? (\n (loadingFallback ?? <Skeleton className=\"h-[264px] w-full rounded-[10px]\" />)\n ) : (\n children\n )}\n </EntityInfoWidget>\n );\n}\n","'use client';\n\nimport { SearchableSelect, defineKitTexts, useKitTexts } from '@carefully-built/ui';\nimport { CalendarRange } from 'lucide-react';\n\nexport const PERIOD_PRESETS = ['today', '7d', '30d', '90d', 'month', 'year'] as const;\n\nexport type PeriodPreset = (typeof PERIOD_PRESETS)[number];\n\nexport interface PeriodRange {\n /** Inclusive start, epoch ms. */\n readonly from: number;\n /** Exclusive end, epoch ms. */\n readonly to: number;\n}\n\nconst periodTexts = defineKitTexts<Record<PeriodPreset, string> & { readonly ariaLabel: string }>({\n en: {\n today: 'Today',\n '7d': 'Last 7 days',\n '30d': 'Last 30 days',\n '90d': 'Last 90 days',\n month: 'This month',\n year: 'This year',\n ariaLabel: 'Period',\n },\n it: {\n today: 'Oggi',\n '7d': 'Ultimi 7 giorni',\n '30d': 'Ultimi 30 giorni',\n '90d': 'Ultimi 90 giorni',\n month: 'Questo mese',\n year: 'Quest’anno',\n ariaLabel: 'Periodo',\n },\n});\n\nexport function isPeriodPreset(value: string): value is PeriodPreset {\n return (PERIOD_PRESETS as readonly string[]).includes(value);\n}\n\n/** The time range a preset covers, in the browser's time zone, ending tomorrow at 00:00. */\nexport function resolvePeriodRange(preset: PeriodPreset, now = new Date()): PeriodRange {\n const start = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const to = start.getTime() + 24 * 60 * 60 * 1000;\n const daysBack = { today: 0, '7d': 6, '30d': 29, '90d': 89 } as const;\n\n if (preset === 'month') return { from: new Date(now.getFullYear(), now.getMonth(), 1).getTime(), to };\n if (preset === 'year') return { from: new Date(now.getFullYear(), 0, 1).getTime(), to };\n return { from: start.getTime() - daysBack[preset] * 24 * 60 * 60 * 1000, to };\n}\n\ninterface PeriodSelectProps {\n readonly value: PeriodPreset;\n readonly onChange: (value: PeriodPreset) => void;\n readonly presets?: readonly PeriodPreset[];\n readonly className?: string;\n}\n\n/** Dashboard period filter: the same presets, labels and ranges in every app. */\nexport function PeriodSelect({\n value,\n onChange,\n presets = PERIOD_PRESETS,\n className,\n}: PeriodSelectProps): React.ReactElement {\n const texts = useKitTexts(periodTexts);\n\n return (\n <SearchableSelect\n value={value}\n onValueChange={(next) => {\n if (isPeriodPreset(next)) onChange(next);\n }}\n options={presets.map((preset) => ({ value: preset, label: texts[preset] }))}\n ariaLabel={texts.ariaLabel}\n leadingIcon={CalendarRange}\n searchThreshold={99}\n size=\"sm\"\n className={className ?? 'min-w-40'}\n />\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/widget-empty-state.tsx","../src/entity-info-widget.tsx","../src/dashboard-widget.tsx","../src/period-select.tsx","../src/reveal.tsx"],"sourcesContent":["\"use client\";\n\nimport type { LucideIcon } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\n\nimport { Button, cn } from \"@carefully-built/ui\";\n\nexport interface WidgetEmptyStateAction {\n readonly label: string;\n readonly href?: string;\n readonly onClick?: () => void;\n readonly target?: \"_blank\" | \"_self\" | \"_parent\" | \"_top\";\n readonly rel?: string;\n readonly icon?: ReactNode;\n readonly disabled?: boolean;\n}\n\nexport interface WidgetEmptyStateConfig {\n readonly title: string;\n readonly description: string;\n readonly icon?: LucideIcon;\n readonly minHeightClassName?: string;\n readonly className?: string;\n readonly action?: WidgetEmptyStateAction;\n}\n\nexport interface WidgetEmptyStateProps extends WidgetEmptyStateConfig {\n readonly icon: LucideIcon;\n}\n\nexport function WidgetEmptyState({\n icon: Icon,\n title,\n description,\n minHeightClassName,\n className,\n action,\n}: WidgetEmptyStateProps): React.ReactElement {\n return (\n <div\n data-empty-state=\"\"\n className={cn(\n \"flex h-full w-full items-center justify-center rounded-[16px] border border-dashed border-border/70 px-4 py-8 text-center\",\n minHeightClassName ?? \"min-h-[248px]\",\n className,\n )}\n >\n <div className=\"max-w-[280px] space-y-2\">\n <div className=\"text-muted-foreground flex justify-center\">\n <Icon className=\"size-5\" strokeWidth={1.75} />\n </div>\n <p className=\"text-foreground text-sm font-medium\">{title}</p>\n <p className=\"text-muted-foreground text-xs leading-5\">{description}</p>\n {action ? (\n action.href ? (\n <Button asChild variant=\"outline\" size=\"sm\" className=\"mt-4\">\n <a href={action.href} target={action.target ?? \"_self\"} rel={action.rel}>\n {action.icon ? <span className=\"inline-flex items-center\">{action.icon}</span> : null}\n {action.label}\n </a>\n </Button>\n ) : (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"mt-4\"\n onClick={action.onClick}\n disabled={action.disabled}\n >\n {action.icon ? <span className=\"inline-flex items-center\">{action.icon}</span> : null}\n {action.label}\n </Button>\n )\n ) : null}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport type { LucideIcon } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\n\nimport { cn } from \"@carefully-built/ui\";\n\nimport { WidgetEmptyState } from \"./widget-empty-state\";\nimport type { WidgetEmptyStateConfig } from \"./widget-empty-state\";\n\nexport interface EntityInfoWidgetProps {\n readonly icon: LucideIcon;\n readonly name: string;\n readonly children: ReactNode;\n readonly className?: string;\n readonly contentClassName?: string;\n readonly nameActions?: ReactNode;\n readonly headerActions?: ReactNode;\n readonly isEmpty?: boolean;\n readonly emptyState?: WidgetEmptyStateConfig;\n}\n\nexport function EntityInfoWidget({\n icon: Icon,\n name,\n children,\n className,\n contentClassName,\n nameActions,\n headerActions,\n isEmpty = false,\n emptyState,\n}: EntityInfoWidgetProps): React.ReactElement {\n return (\n <section\n data-slot=\"widget\"\n className={cn(\n \"border-border flex min-w-0 flex-col gap-3 rounded-[12px] border bg-background p-1.5\",\n className,\n )}\n >\n <div className=\"flex min-w-0 flex-wrap items-center justify-between gap-3 px-0.5 sm:flex-nowrap\">\n <div className=\"text-muted-foreground flex min-w-0 items-center gap-[3px] text-[13px]\">\n <Icon className=\"size-3.5 shrink-0\" strokeWidth={1.75} />\n <span className=\"truncate\">{name}</span>\n {nameActions ? <span className=\"ml-1 shrink-0\">{nameActions}</span> : null}\n </div>\n {headerActions ? (\n <div className=\"flex min-w-0 max-w-full items-center gap-2 sm:shrink-0\">\n {headerActions}\n </div>\n ) : null}\n </div>\n <div className={cn(\"min-w-0\", contentClassName)}>\n {isEmpty && emptyState ? (\n <WidgetEmptyState\n icon={emptyState.icon ?? Icon}\n title={emptyState.title}\n description={emptyState.description}\n minHeightClassName={emptyState.minHeightClassName}\n className={emptyState.className}\n action={emptyState.action}\n />\n ) : (\n children\n )}\n </div>\n </section>\n );\n}\n","\"use client\";\n\nimport type { LucideIcon } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\n\nimport { Skeleton, cn } from \"@carefully-built/ui\";\n\nimport { EntityInfoWidget } from \"./entity-info-widget\";\nimport type { WidgetEmptyStateConfig } from \"./widget-empty-state\";\n\nexport interface DashboardWidgetProps {\n readonly icon: LucideIcon;\n readonly title: string;\n readonly value?: ReactNode;\n readonly actions?: ReactNode;\n readonly children?: ReactNode;\n readonly className?: string;\n readonly contentClassName?: string;\n readonly isLoading?: boolean;\n readonly loadingFallback?: ReactNode;\n readonly isEmpty?: boolean;\n readonly emptyState?: WidgetEmptyStateConfig;\n}\n\nexport function DashboardWidget({\n icon,\n title,\n value,\n actions,\n children,\n className,\n contentClassName,\n isLoading = false,\n loadingFallback,\n isEmpty = false,\n emptyState,\n}: DashboardWidgetProps): React.ReactElement {\n const shouldRenderEmptyState = !isLoading && value === undefined && isEmpty;\n let defaultContentClassName = \"pt-1\";\n\n if (value !== undefined) {\n defaultContentClassName = \"px-0.5 pt-2 pb-0.5\";\n } else if (shouldRenderEmptyState) {\n defaultContentClassName = \"flex min-h-0 flex-1 pt-1\";\n }\n\n return (\n <EntityInfoWidget\n icon={icon}\n name={title}\n className={cn(\"h-full min-w-0 gap-0\", className)}\n contentClassName={cn(defaultContentClassName, contentClassName)}\n headerActions={actions}\n isEmpty={shouldRenderEmptyState}\n emptyState={value === undefined ? emptyState : undefined}\n >\n {value !== undefined ? (\n <div\n data-slot=\"widget-value\"\n className=\"text-foreground text-[24px] leading-none font-medium tracking-[-0.02em]\"\n aria-busy={isLoading || undefined}\n >\n {isLoading ? <Skeleton className=\"h-7 w-16\" /> : value}\n </div>\n ) : isLoading ? (\n (loadingFallback ?? <Skeleton className=\"h-[264px] w-full rounded-[10px]\" />)\n ) : (\n children\n )}\n </EntityInfoWidget>\n );\n}\n","'use client';\n\nimport { SearchableSelect, defineKitTexts, useKitTexts } from '@carefully-built/ui';\nimport { CalendarRange } from 'lucide-react';\n\nexport const PERIOD_PRESETS = ['today', '7d', '30d', '90d', 'month', 'year'] as const;\n\nexport type PeriodPreset = (typeof PERIOD_PRESETS)[number];\n\nexport interface PeriodRange {\n /** Inclusive start, epoch ms. */\n readonly from: number;\n /** Exclusive end, epoch ms. */\n readonly to: number;\n}\n\nconst periodTexts = defineKitTexts<Record<PeriodPreset, string> & { readonly ariaLabel: string }>({\n en: {\n today: 'Today',\n '7d': 'Last 7 days',\n '30d': 'Last 30 days',\n '90d': 'Last 90 days',\n month: 'This month',\n year: 'This year',\n ariaLabel: 'Period',\n },\n it: {\n today: 'Oggi',\n '7d': 'Ultimi 7 giorni',\n '30d': 'Ultimi 30 giorni',\n '90d': 'Ultimi 90 giorni',\n month: 'Questo mese',\n year: 'Quest’anno',\n ariaLabel: 'Periodo',\n },\n});\n\nexport function isPeriodPreset(value: string): value is PeriodPreset {\n return (PERIOD_PRESETS as readonly string[]).includes(value);\n}\n\n/** The time range a preset covers, in the browser's time zone, ending tomorrow at 00:00. */\nexport function resolvePeriodRange(preset: PeriodPreset, now = new Date()): PeriodRange {\n const start = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const to = start.getTime() + 24 * 60 * 60 * 1000;\n const daysBack = { today: 0, '7d': 6, '30d': 29, '90d': 89 } as const;\n\n if (preset === 'month') return { from: new Date(now.getFullYear(), now.getMonth(), 1).getTime(), to };\n if (preset === 'year') return { from: new Date(now.getFullYear(), 0, 1).getTime(), to };\n return { from: start.getTime() - daysBack[preset] * 24 * 60 * 60 * 1000, to };\n}\n\ninterface PeriodSelectProps {\n readonly value: PeriodPreset;\n readonly onChange: (value: PeriodPreset) => void;\n readonly presets?: readonly PeriodPreset[];\n readonly className?: string;\n}\n\n/** Dashboard period filter: the same presets, labels and ranges in every app. */\nexport function PeriodSelect({\n value,\n onChange,\n presets = PERIOD_PRESETS,\n className,\n}: PeriodSelectProps): React.ReactElement {\n const texts = useKitTexts(periodTexts);\n\n return (\n <SearchableSelect\n value={value}\n onValueChange={(next) => {\n if (isPeriodPreset(next)) onChange(next);\n }}\n options={presets.map((preset) => ({ value: preset, label: texts[preset] }))}\n ariaLabel={texts.ariaLabel}\n leadingIcon={CalendarRange}\n searchThreshold={99}\n size=\"sm\"\n className={className ?? 'min-w-40'}\n />\n );\n}\n","'use client';\n\nimport { cn } from '@carefully-built/ui';\n\nimport type { CSSProperties, ReactNode } from 'react';\n\nexport interface RevealProps {\n readonly children: ReactNode;\n /** Position in the sequence: each step waits `step` ms more than the previous. */\n readonly index?: number;\n readonly step?: number;\n /** Extra delay in ms before the sequence, e.g. for a block below another sequence. */\n readonly offset?: number;\n readonly duration?: number;\n readonly className?: string;\n readonly style?: CSSProperties;\n readonly as?: 'div' | 'li' | 'section' | 'span';\n /** Lets the wrapper take a themed slot (e.g. `widget`) instead of `reveal`. */\n readonly 'data-slot'?: string;\n}\n\n/**\n * Fades and lifts its content into place on mount, staggered by `index`, so a\n * page of widgets appears one after the other instead of all at once.\n */\nexport function Reveal({\n children,\n index = 0,\n step = 80,\n offset = 0,\n duration = 700,\n className,\n style,\n as: Tag = 'div',\n 'data-slot': slot = 'reveal',\n}: RevealProps): React.ReactElement {\n return (\n <Tag\n data-slot={slot}\n className={cn('animate-in fade-in-0 slide-in-from-bottom-3 fill-mode-both ease-out', className)}\n style={{ animationDuration: `${String(duration)}ms`, animationDelay: `${String(offset + index * step)}ms`, ...style }}\n >\n {children}\n </Tag>\n );\n}\n\nexport interface GrowBarProps {\n /** 0–100. */\n readonly percent: number;\n readonly color?: string;\n readonly delay?: number;\n readonly className?: string;\n readonly trackClassName?: string;\n}\n\n/** A progress bar that grows from the left on mount. */\nexport function GrowBar({ percent, color, delay = 0, className, trackClassName }: GrowBarProps): React.ReactElement {\n return (\n <div className={cn('bg-muted h-2 w-full overflow-hidden rounded-full', trackClassName)}>\n <div\n data-slot=\"grow-bar\"\n className={cn('bg-primary h-full origin-left rounded-full', className)}\n style={{\n width: `${String(Math.max(0, Math.min(100, percent)))}%`,\n backgroundColor: color,\n animation: `kit-grow-x 900ms cubic-bezier(0.2, 0.8, 0.2, 1) ${String(delay)}ms both`,\n }}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|