@assure-one/design-system 0.16.0 → 0.17.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/dist/index.d.ts +40 -9
- package/dist/index.js +124 -42
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/tokens/index.d.ts +17 -4
- package/dist/tokens/index.js +16 -3
- package/dist/tokens/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -108,7 +108,7 @@ declare const Badge: React$1.ForwardRefExoticComponent<BadgeProps & React$1.RefA
|
|
|
108
108
|
|
|
109
109
|
/**
|
|
110
110
|
* Blockquote — semantic quote with optional attribution. Uses `font-display`
|
|
111
|
-
* (
|
|
111
|
+
* (Inter) at a comfortable reading scale; smart quotes are wrapped automatically.
|
|
112
112
|
*/
|
|
113
113
|
interface BlockquoteProps extends React.BlockquoteHTMLAttributes<HTMLQuoteElement> {
|
|
114
114
|
author?: string;
|
|
@@ -227,6 +227,8 @@ interface CheckboxProps extends Omit<React$1.ComponentPropsWithoutRef<typeof Che
|
|
|
227
227
|
defaultChecked?: boolean | "indeterminate";
|
|
228
228
|
/** Convenience: render with indeterminate state. Mirrors legacy prop. */
|
|
229
229
|
indeterminate?: boolean;
|
|
230
|
+
/** Box shape. Defaults to "square". */
|
|
231
|
+
shape?: "square" | "circle";
|
|
230
232
|
}
|
|
231
233
|
declare const Checkbox: React$1.ForwardRefExoticComponent<CheckboxProps & React$1.RefAttributes<HTMLButtonElement>>;
|
|
232
234
|
|
|
@@ -508,7 +510,7 @@ declare const DropdownMenuShortcut: {
|
|
|
508
510
|
};
|
|
509
511
|
|
|
510
512
|
/**
|
|
511
|
-
* EmptyState — display headline (
|
|
513
|
+
* EmptyState — display headline (Inter), fg-3 description, neutral icon halo on bg-2.
|
|
512
514
|
*
|
|
513
515
|
* Public API preserved: `icon`, `title`, `description`, `action`.
|
|
514
516
|
*/
|
|
@@ -847,7 +849,7 @@ declare const LoadingRows: React$1.ForwardRefExoticComponent<LoadingRowsProps &
|
|
|
847
849
|
|
|
848
850
|
/**
|
|
849
851
|
* Logo — Assure suite wordmark. Renders "Assure" in `fg` plus an optional
|
|
850
|
-
* product suffix in `pro-fg` (e.g., "Pro", "Tax"), set in
|
|
852
|
+
* product suffix in `pro-fg` (e.g., "Pro", "Tax"), set in Inter (font-display).
|
|
851
853
|
*
|
|
852
854
|
* The product suffix is configurable so the same component serves every
|
|
853
855
|
* Assure product. The default preserves the original "Assure Pro" output —
|
|
@@ -1161,15 +1163,23 @@ interface SearchSelectProps {
|
|
|
1161
1163
|
*/
|
|
1162
1164
|
onCreateNew?: () => void;
|
|
1163
1165
|
createNewLabel?: string;
|
|
1166
|
+
/**
|
|
1167
|
+
* How the collapsed single-value display renders the picked option's
|
|
1168
|
+
* `description`. "inline" (default) appends it as muted "· text" after the
|
|
1169
|
+
* label — the existing behaviour. "pill" renders it as a discrete rounded
|
|
1170
|
+
* badge after the label, so dense metadata (e.g. "1040 · 2025", "todo")
|
|
1171
|
+
* reads as a tag instead of running into the label. Single-mode only.
|
|
1172
|
+
*/
|
|
1173
|
+
descriptionVariant?: "inline" | "pill";
|
|
1164
1174
|
}
|
|
1165
|
-
declare function SearchSelect({ options, selected: selectedProp, onSelect: onSelectProp, onRemove: onRemoveProp, value, onValueChange, onCreate, placeholder, className, disabled, groupFilter, pinnedGroups, closeOnSelect: closeOnSelectProp, showGroupCounts, onCreateNew, createNewLabel, }: SearchSelectProps): react_jsx_runtime.JSX.Element;
|
|
1175
|
+
declare function SearchSelect({ options, selected: selectedProp, onSelect: onSelectProp, onRemove: onRemoveProp, value, onValueChange, onCreate, placeholder, className, disabled, groupFilter, pinnedGroups, closeOnSelect: closeOnSelectProp, showGroupCounts, onCreateNew, createNewLabel, descriptionVariant, }: SearchSelectProps): react_jsx_runtime.JSX.Element;
|
|
1166
1176
|
declare namespace SearchSelect {
|
|
1167
1177
|
var displayName: string;
|
|
1168
1178
|
}
|
|
1169
1179
|
|
|
1170
1180
|
/**
|
|
1171
1181
|
* SectionHeader — title + description block for marketing-style sections.
|
|
1172
|
-
* Uses
|
|
1182
|
+
* Uses Inter (`font-display`) with the spec's `-0.022em` letterspacing.
|
|
1173
1183
|
*/
|
|
1174
1184
|
interface SectionHeaderProps {
|
|
1175
1185
|
title: string;
|
|
@@ -1409,7 +1419,7 @@ declare const StarRating: React$1.ForwardRefExoticComponent<StarRatingProps & Re
|
|
|
1409
1419
|
|
|
1410
1420
|
/**
|
|
1411
1421
|
* Stat — paired numeric display + caption (the StatNum primitive).
|
|
1412
|
-
* Numerals are set in `font-display` (
|
|
1422
|
+
* Numerals are set in `font-display` (Inter) at a fluid clamp size with
|
|
1413
1423
|
* `font-variant-numeric: tabular-nums` for vertical alignment.
|
|
1414
1424
|
*/
|
|
1415
1425
|
interface StatProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
@@ -1680,6 +1690,16 @@ interface SidebarProps extends React$1.HTMLAttributes<HTMLElement> {
|
|
|
1680
1690
|
* `collapsible` alone is a no-op.
|
|
1681
1691
|
*/
|
|
1682
1692
|
collapsible?: boolean;
|
|
1693
|
+
/**
|
|
1694
|
+
* Visual treatment.
|
|
1695
|
+
* - `"classic"` (default) — full-height column flush to the left
|
|
1696
|
+
* edge with a right rule. The legacy look; unchanged.
|
|
1697
|
+
* - `"floating"` — a detached, rounded card inset from the viewport
|
|
1698
|
+
* with a soft shadow (modern SaaS pattern). Nav rows get larger
|
|
1699
|
+
* hit areas and a pill active state. Exposed as `data-variant` so
|
|
1700
|
+
* descendant atoms restyle via `group-data-[variant=floating]`.
|
|
1701
|
+
*/
|
|
1702
|
+
variant?: "classic" | "floating";
|
|
1683
1703
|
}
|
|
1684
1704
|
declare const Sidebar: React$1.ForwardRefExoticComponent<SidebarProps & React$1.RefAttributes<HTMLElement>>;
|
|
1685
1705
|
interface SidebarTriggerProps extends React$1.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
@@ -1946,7 +1966,7 @@ interface PageHeaderProps extends Omit<React.HTMLAttributes<HTMLElement>, "title
|
|
|
1946
1966
|
declare const PageHeader: React$1.ForwardRefExoticComponent<PageHeaderProps & React$1.RefAttributes<HTMLElement>>;
|
|
1947
1967
|
type PageHeaderSpecProps = React.HTMLAttributes<HTMLSpanElement>;
|
|
1948
1968
|
/**
|
|
1949
|
-
* PageHeaderSpec — small `.spec`-style span (
|
|
1969
|
+
* PageHeaderSpec — small `.spec`-style span (Inter w/ tnum/lnum/ss01).
|
|
1950
1970
|
* Used inside the `meta` slot for numeric facts ("4 due today",
|
|
1951
1971
|
* "EIN ·· 12-3456789").
|
|
1952
1972
|
*/
|
|
@@ -2162,7 +2182,7 @@ declare const DataTableCell: React$1.ForwardRefExoticComponent<DataTableCellProp
|
|
|
2162
2182
|
*/
|
|
2163
2183
|
declare const DataTableCellName: React$1.ForwardRefExoticComponent<DataTableCellProps & React$1.RefAttributes<HTMLTableCellElement>>;
|
|
2164
2184
|
/**
|
|
2165
|
-
* DataTableCellMono — currency / IDs / numerics.
|
|
2185
|
+
* DataTableCellMono — currency / IDs / numerics. Inter with
|
|
2166
2186
|
* tabular numerals and tight tracking.
|
|
2167
2187
|
*/
|
|
2168
2188
|
declare const DataTableCellMono: React$1.ForwardRefExoticComponent<DataTableCellProps & React$1.RefAttributes<HTMLTableCellElement>>;
|
|
@@ -2617,7 +2637,18 @@ interface UseStopwatchReturn {
|
|
|
2617
2637
|
reset: () => void;
|
|
2618
2638
|
}
|
|
2619
2639
|
declare function useStopwatch(): UseStopwatchReturn;
|
|
2620
|
-
|
|
2640
|
+
interface TimeLoggerProps extends React$1.HTMLAttributes<HTMLDivElement> {
|
|
2641
|
+
/**
|
|
2642
|
+
* Layout direction.
|
|
2643
|
+
* - `"vertical"` (default) — the stacked panel; rows separated by top
|
|
2644
|
+
* rules. For popovers and side panels.
|
|
2645
|
+
* - `"horizontal"` — a single compact bar; segments sit side by side,
|
|
2646
|
+
* separated by left rules. For an app top/bottom bar. Exposed as
|
|
2647
|
+
* `data-orientation` so segment atoms flip their divider via
|
|
2648
|
+
* `group-data-[orientation=horizontal]/timelogger`.
|
|
2649
|
+
*/
|
|
2650
|
+
orientation?: "vertical" | "horizontal";
|
|
2651
|
+
}
|
|
2621
2652
|
declare const TimeLogger: React$1.ForwardRefExoticComponent<TimeLoggerProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
2622
2653
|
interface TimeLoggerHeaderProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, "title"> {
|
|
2623
2654
|
title?: React$1.ReactNode;
|
package/dist/index.js
CHANGED
|
@@ -90,9 +90,9 @@ var colors = {
|
|
|
90
90
|
};
|
|
91
91
|
var typography = {
|
|
92
92
|
family: {
|
|
93
|
-
display: '"
|
|
93
|
+
display: '"Inter", -apple-system, system-ui, sans-serif',
|
|
94
94
|
body: '"Inter", -apple-system, system-ui, sans-serif',
|
|
95
|
-
mono: '"
|
|
95
|
+
mono: '"Inter", -apple-system, system-ui, sans-serif'
|
|
96
96
|
},
|
|
97
97
|
weight: {
|
|
98
98
|
regular: 400,
|
|
@@ -230,11 +230,24 @@ var systemTokens = {
|
|
|
230
230
|
dangerBg: "var(--color-danger-bg)",
|
|
231
231
|
dangerLine: "var(--color-danger-line)"
|
|
232
232
|
},
|
|
233
|
+
gradient: {
|
|
234
|
+
brand: "var(--gradient-brand)",
|
|
235
|
+
pro: "var(--gradient-pro)",
|
|
236
|
+
audit: "var(--gradient-audit)",
|
|
237
|
+
books: "var(--gradient-books)",
|
|
238
|
+
tax: "var(--gradient-tax)"
|
|
239
|
+
},
|
|
233
240
|
shadow: {
|
|
234
241
|
quiet: "var(--shadow-quiet)",
|
|
235
242
|
card: "var(--shadow-card)",
|
|
236
243
|
pop: "var(--shadow-pop)",
|
|
237
|
-
focusRing: "var(--shadow-focus-ring)"
|
|
244
|
+
focusRing: "var(--shadow-focus-ring)",
|
|
245
|
+
xs: "var(--shadow-xs)",
|
|
246
|
+
sm: "var(--shadow-sm)",
|
|
247
|
+
md: "var(--shadow-md)",
|
|
248
|
+
lg: "var(--shadow-lg)",
|
|
249
|
+
xl: "var(--shadow-xl)",
|
|
250
|
+
"2xl": "var(--shadow-2xl)"
|
|
238
251
|
},
|
|
239
252
|
radius: {
|
|
240
253
|
btn: "var(--radius-btn)",
|
|
@@ -2235,6 +2248,7 @@ var AccordionTrigger = React36.forwardRef(function AccordionTrigger2({ children,
|
|
|
2235
2248
|
"transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)] motion-reduce:transition-none",
|
|
2236
2249
|
"hover:text-fg-2",
|
|
2237
2250
|
"focus-visible:[box-shadow:var(--shadow-focus-ring)] focus-visible:outline-none",
|
|
2251
|
+
"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 data-[disabled]:hover:text-fg",
|
|
2238
2252
|
"[&[data-state=open]>svg]:rotate-180",
|
|
2239
2253
|
className
|
|
2240
2254
|
),
|
|
@@ -3013,7 +3027,16 @@ var CardAction = forwardRef(
|
|
|
3013
3027
|
}
|
|
3014
3028
|
);
|
|
3015
3029
|
CardAction.displayName = "CardAction";
|
|
3016
|
-
var Checkbox = React36.forwardRef(function Checkbox2({
|
|
3030
|
+
var Checkbox = React36.forwardRef(function Checkbox2({
|
|
3031
|
+
label,
|
|
3032
|
+
indeterminate,
|
|
3033
|
+
checked,
|
|
3034
|
+
defaultChecked,
|
|
3035
|
+
shape = "square",
|
|
3036
|
+
className,
|
|
3037
|
+
id: providedId,
|
|
3038
|
+
...props
|
|
3039
|
+
}, ref) {
|
|
3017
3040
|
const generatedId = React36.useId();
|
|
3018
3041
|
const id = providedId ?? generatedId;
|
|
3019
3042
|
const resolvedChecked = indeterminate ? "indeterminate" : checked;
|
|
@@ -3026,18 +3049,19 @@ var Checkbox = React36.forwardRef(function Checkbox2({ label, indeterminate, che
|
|
|
3026
3049
|
checked: resolvedChecked,
|
|
3027
3050
|
defaultChecked,
|
|
3028
3051
|
className: cn(
|
|
3029
|
-
"peer border-rule-strong bg-surface text-fg
|
|
3052
|
+
"peer border-rule-strong bg-surface text-pro-fg flex size-4 shrink-0 items-center justify-center border",
|
|
3053
|
+
shape === "circle" ? "rounded-full" : "rounded-[4px]",
|
|
3030
3054
|
"transition-[color,background-color,border-color,box-shadow] duration-[var(--duration-fast)]",
|
|
3031
3055
|
"hover:border-fg-4",
|
|
3032
3056
|
"focus-visible:border-accent focus-visible:[box-shadow:var(--shadow-focus-ring)] focus-visible:outline-none",
|
|
3033
|
-
"data-[state=checked]:border-pro-fg data-[state=checked]:bg-pro-
|
|
3034
|
-
"data-[state=indeterminate]:border-pro-fg data-[state=indeterminate]:bg-pro-
|
|
3057
|
+
"data-[state=checked]:border-pro-fg data-[state=checked]:bg-pro-bg",
|
|
3058
|
+
"data-[state=indeterminate]:border-pro-fg data-[state=indeterminate]:bg-pro-bg",
|
|
3035
3059
|
"disabled:bg-bg-disabled disabled:border-rule disabled:text-fg-disabled disabled:cursor-not-allowed",
|
|
3036
3060
|
"aria-[invalid=true]:border-danger-line",
|
|
3037
3061
|
className
|
|
3038
3062
|
),
|
|
3039
3063
|
...props,
|
|
3040
|
-
children: /* @__PURE__ */ jsx(CheckboxPrimitive.Indicator, { className: "flex items-center justify-center text-current", children: resolvedChecked === "indeterminate" ? /* @__PURE__ */ jsx(MinusIcon, { className: "size-3", strokeWidth: 3, "aria-hidden": "true" }) : /* @__PURE__ */ jsx(CheckIcon, { className: "size-3", strokeWidth: 3, "aria-hidden": "true" }) })
|
|
3064
|
+
children: /* @__PURE__ */ jsx(CheckboxPrimitive.Indicator, { className: "flex items-center justify-center text-current", children: resolvedChecked === "indeterminate" ? /* @__PURE__ */ jsx(MinusIcon, { className: "size-3", strokeWidth: 3, "aria-hidden": "true" }) : shape === "circle" ? /* @__PURE__ */ jsx("span", { className: "size-1.5 rounded-full bg-current", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(CheckIcon, { className: "size-3", strokeWidth: 3, "aria-hidden": "true" }) })
|
|
3041
3065
|
}
|
|
3042
3066
|
),
|
|
3043
3067
|
label && /* @__PURE__ */ jsx(
|
|
@@ -6062,7 +6086,8 @@ function SearchSelect({
|
|
|
6062
6086
|
closeOnSelect: closeOnSelectProp = false,
|
|
6063
6087
|
showGroupCounts = false,
|
|
6064
6088
|
onCreateNew,
|
|
6065
|
-
createNewLabel = "Create new"
|
|
6089
|
+
createNewLabel = "Create new",
|
|
6090
|
+
descriptionVariant = "inline"
|
|
6066
6091
|
}) {
|
|
6067
6092
|
const isSingleMode = value !== void 0 || onValueChange !== void 0;
|
|
6068
6093
|
const singleSelectedOption = React36.useMemo(
|
|
@@ -6219,10 +6244,10 @@ function SearchSelect({
|
|
|
6219
6244
|
"div",
|
|
6220
6245
|
{
|
|
6221
6246
|
className: cn(
|
|
6222
|
-
"rounded-input border-rule-strong bg-surface relative flex h-9 w-full items-center border",
|
|
6223
|
-
"transition-[color,background-color,border-color
|
|
6247
|
+
"rounded-input border-rule-strong bg-surface relative flex h-9 w-full items-center border outline-none",
|
|
6248
|
+
"transition-[color,background-color,border-color] duration-[var(--duration-fast)] ease-[var(--ease-out-quart)]",
|
|
6224
6249
|
"motion-reduce:transition-none",
|
|
6225
|
-
"focus-within:
|
|
6250
|
+
"focus-within:[outline:1px_solid_var(--color-pro-fg)] focus-within:[outline-offset:-1px]",
|
|
6226
6251
|
showValue && "hover:bg-bg-2 gap-2 pr-2 pl-3",
|
|
6227
6252
|
disabled && "bg-bg-disabled cursor-not-allowed"
|
|
6228
6253
|
),
|
|
@@ -6233,7 +6258,7 @@ function SearchSelect({
|
|
|
6233
6258
|
type: "button",
|
|
6234
6259
|
onClick: () => !disabled && setOpen(true),
|
|
6235
6260
|
disabled,
|
|
6236
|
-
className: "flex h-full flex-1 items-center gap-2 text-left outline-none disabled:cursor-not-allowed",
|
|
6261
|
+
className: "flex h-full min-w-0 flex-1 items-center gap-2 text-left outline-none disabled:cursor-not-allowed",
|
|
6237
6262
|
children: [
|
|
6238
6263
|
singleValue.icon && /* @__PURE__ */ jsx(
|
|
6239
6264
|
"span",
|
|
@@ -6246,7 +6271,15 @@ function SearchSelect({
|
|
|
6246
6271
|
children: singleValue.icon
|
|
6247
6272
|
}
|
|
6248
6273
|
),
|
|
6249
|
-
|
|
6274
|
+
descriptionVariant === "pill" && singleValue.description ? (
|
|
6275
|
+
// Pill variant: label truncates, description rides after it
|
|
6276
|
+
// as a discrete shrink-0 badge so dense metadata reads as a
|
|
6277
|
+
// tag instead of running into the label.
|
|
6278
|
+
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-1.5 text-[13px]", children: [
|
|
6279
|
+
/* @__PURE__ */ jsx("span", { className: "text-fg truncate", children: singleValue.label }),
|
|
6280
|
+
/* @__PURE__ */ jsx("span", { className: "rounded-pill border-rule bg-bg-2 text-fg-3 shrink-0 border px-1.5 py-0.5 text-[11px] leading-none", children: singleValue.description })
|
|
6281
|
+
] })
|
|
6282
|
+
) : /* @__PURE__ */ jsxs("span", { className: "text-fg min-w-0 flex-1 truncate text-[13px]", children: [
|
|
6250
6283
|
singleValue.label,
|
|
6251
6284
|
singleValue.description && /* @__PURE__ */ jsxs("span", { className: "text-fg-4", children: [
|
|
6252
6285
|
" \xB7 ",
|
|
@@ -7981,7 +8014,8 @@ function SidebarProvider({
|
|
|
7981
8014
|
SidebarProvider.displayName = "SidebarProvider";
|
|
7982
8015
|
var PEEK_ENTER_DELAY_MS = 100;
|
|
7983
8016
|
var PEEK_LEAVE_DELAY_MS = 200;
|
|
7984
|
-
var Sidebar = React36.forwardRef(function Sidebar2({ className, collapsible = false, onMouseEnter, onMouseLeave, style, ...props }, ref) {
|
|
8017
|
+
var Sidebar = React36.forwardRef(function Sidebar2({ className, collapsible = false, variant = "classic", onMouseEnter, onMouseLeave, style, ...props }, ref) {
|
|
8018
|
+
const isFloating = variant === "floating";
|
|
7985
8019
|
const ctx = React36.useContext(SidebarContext);
|
|
7986
8020
|
const state = collapsible && ctx ? ctx.state : "expanded";
|
|
7987
8021
|
const peekLockCount = collapsible && ctx ? ctx.peekLockCount : 0;
|
|
@@ -8044,12 +8078,19 @@ var Sidebar = React36.forwardRef(function Sidebar2({ className, collapsible = fa
|
|
|
8044
8078
|
"data-overlay": overlay ? "true" : void 0,
|
|
8045
8079
|
"data-labels": labelsHidden ? "hide" : "show",
|
|
8046
8080
|
"data-collapsible": collapsible ? "true" : void 0,
|
|
8081
|
+
"data-variant": variant,
|
|
8047
8082
|
onMouseEnter: handleEnter,
|
|
8048
8083
|
onMouseLeave: handleLeave,
|
|
8049
8084
|
style: { width: effectiveWidth, ...style },
|
|
8050
8085
|
className: cn(
|
|
8051
|
-
"group/sidebar scrollbar-thin flex
|
|
8052
|
-
|
|
8086
|
+
"group/sidebar scrollbar-thin flex shrink-0 flex-col overflow-y-auto px-3 pt-4 pb-4",
|
|
8087
|
+
// Classic: full-height column flush to the left edge with a right
|
|
8088
|
+
// rule. The legacy look.
|
|
8089
|
+
!isFloating && "h-dvh border-rule bg-bg-2 border-r",
|
|
8090
|
+
// Floating: a detached, rounded card inset from the viewport with a
|
|
8091
|
+
// soft shadow — the modern SaaS pattern. The clear figure/ground gap
|
|
8092
|
+
// (Aesthetic-Usability) reads as its own surface above the canvas.
|
|
8093
|
+
isFloating && "border-rule bg-surface shadow-card m-2.5 h-[calc(100dvh-1.25rem)] rounded-2xl border",
|
|
8053
8094
|
// 220ms feels right for a ~192px width sweep — slower than the
|
|
8054
8095
|
// 150ms `--duration-fast` (which reads as a snap on this size of
|
|
8055
8096
|
// movement) but well short of `--duration-slow` (which feels
|
|
@@ -8338,6 +8379,11 @@ var SidebarLink = React36.forwardRef(
|
|
|
8338
8379
|
// when the column widens during peek. The label simply collapses
|
|
8339
8380
|
// to width 0 via <SidebarLinkLabel>.
|
|
8340
8381
|
"[&_svg]:size-3.5 [&_svg]:shrink-0 [&_svg]:opacity-85",
|
|
8382
|
+
// Floating variant: softer corners + a taller hit area (Fitts's
|
|
8383
|
+
// law — a larger target is faster and lower-error to acquire), and
|
|
8384
|
+
// a full pill highlight for active instead of the left rail bar.
|
|
8385
|
+
"group-data-[variant=floating]/sidebar:gap-3 group-data-[variant=floating]/sidebar:rounded-lg group-data-[variant=floating]/sidebar:py-2",
|
|
8386
|
+
"group-data-[variant=floating]/sidebar:data-[active=true]:before:hidden",
|
|
8341
8387
|
className
|
|
8342
8388
|
),
|
|
8343
8389
|
...props,
|
|
@@ -8347,10 +8393,12 @@ var SidebarLink = React36.forwardRef(
|
|
|
8347
8393
|
"span",
|
|
8348
8394
|
{
|
|
8349
8395
|
className: cn(
|
|
8350
|
-
//
|
|
8351
|
-
//
|
|
8352
|
-
//
|
|
8353
|
-
"
|
|
8396
|
+
// Flex row so a trailing <SidebarLinkBadge> (ml-auto) aligns
|
|
8397
|
+
// to the right edge with a gap from the label, instead of
|
|
8398
|
+
// butting against it. A line-clamp box swallows the badge's
|
|
8399
|
+
// auto margin, which is why "Billing$48k" rendered glued.
|
|
8400
|
+
// Single-line label clips via overflow; badge stays put.
|
|
8401
|
+
"flex min-w-0 flex-1 items-center gap-1.5 overflow-hidden whitespace-nowrap",
|
|
8354
8402
|
"transition-[opacity,max-width] duration-[180ms] ease-[var(--ease-out-quart)] motion-reduce:transition-none",
|
|
8355
8403
|
"max-w-full opacity-100",
|
|
8356
8404
|
"group-data-[labels=hide]/sidebar:max-w-0 group-data-[labels=hide]/sidebar:opacity-0 group-data-[labels=hide]/sidebar:invisible"
|
|
@@ -8486,7 +8534,10 @@ var SidebarLinkGroup = React36.forwardRef(
|
|
|
8486
8534
|
"data-[active=true]:before:top-1/2 data-[active=true]:before:left-0",
|
|
8487
8535
|
"data-[active=true]:before:h-4 data-[active=true]:before:w-[2px] data-[active=true]:before:-translate-y-1/2",
|
|
8488
8536
|
"data-[active=true]:before:bg-pro-fg data-[active=true]:before:rounded-r-full",
|
|
8489
|
-
"[&_svg]:size-3.5 [&_svg]:shrink-0 [&_svg]:opacity-85"
|
|
8537
|
+
"[&_svg]:size-3.5 [&_svg]:shrink-0 [&_svg]:opacity-85",
|
|
8538
|
+
// Floating variant — match SidebarLink: taller hit area, pill active.
|
|
8539
|
+
"group-data-[variant=floating]/sidebar:gap-3 group-data-[variant=floating]/sidebar:rounded-lg group-data-[variant=floating]/sidebar:py-2",
|
|
8540
|
+
"group-data-[variant=floating]/sidebar:data-[active=true]:before:hidden"
|
|
8490
8541
|
);
|
|
8491
8542
|
const labelSpan = /* @__PURE__ */ jsx(
|
|
8492
8543
|
"span",
|
|
@@ -10161,30 +10212,43 @@ function useStopwatch() {
|
|
|
10161
10212
|
}, [setPhase]);
|
|
10162
10213
|
return { phase, elapsedMs, isRunning: phase === "running", start, pause, resume, stop, reset };
|
|
10163
10214
|
}
|
|
10164
|
-
var TimeLogger = forwardRef(function TimeLogger2({ className, children, ...props }, ref) {
|
|
10215
|
+
var TimeLogger = forwardRef(function TimeLogger2({ className, orientation = "vertical", children, ...props }, ref) {
|
|
10165
10216
|
return /* @__PURE__ */ jsx(
|
|
10166
10217
|
"div",
|
|
10167
10218
|
{
|
|
10168
10219
|
ref,
|
|
10169
|
-
|
|
10220
|
+
"data-orientation": orientation,
|
|
10221
|
+
className: cn(
|
|
10222
|
+
"group/timelogger bg-surface text-fg-2 flex w-full",
|
|
10223
|
+
orientation === "horizontal" ? "flex-row items-stretch" : "flex-col",
|
|
10224
|
+
className
|
|
10225
|
+
),
|
|
10170
10226
|
...props,
|
|
10171
10227
|
children
|
|
10172
10228
|
}
|
|
10173
10229
|
);
|
|
10174
10230
|
});
|
|
10175
10231
|
TimeLogger.displayName = "TimeLogger";
|
|
10232
|
+
var horizontalSegment = "group-data-[orientation=horizontal]/timelogger:border-t-0 group-data-[orientation=horizontal]/timelogger:border-l group-data-[orientation=horizontal]/timelogger:first:border-l-0";
|
|
10176
10233
|
var TimeLoggerHeader = forwardRef(
|
|
10177
10234
|
function TimeLoggerHeader2({ title = "Track Time", icon, loggedMinutes = 0, goalMinutes, className, ...props }, ref) {
|
|
10178
10235
|
const hasGoal = goalMinutes != null;
|
|
10179
10236
|
const pct = hasGoal && goalMinutes > 0 ? Math.min(100, loggedMinutes / goalMinutes * 100) : 0;
|
|
10180
10237
|
return /* @__PURE__ */ jsxs("div", { ref, className: cn("flex flex-col", className), ...props, children: [
|
|
10181
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [
|
|
10182
|
-
/* @__PURE__ */ jsxs("div", { className: "text-fg flex items-center gap-2 text-
|
|
10183
|
-
/* @__PURE__ */ jsx(
|
|
10238
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-3.5", children: [
|
|
10239
|
+
/* @__PURE__ */ jsxs("div", { className: "text-fg flex items-center gap-2.5 text-[17px] font-semibold", children: [
|
|
10240
|
+
/* @__PURE__ */ jsx(
|
|
10241
|
+
"span",
|
|
10242
|
+
{
|
|
10243
|
+
className: "bg-pro-bg text-pro-fg flex size-7 shrink-0 items-center justify-center rounded-lg [&_svg]:size-[17px]",
|
|
10244
|
+
"aria-hidden": "true",
|
|
10245
|
+
children: icon ?? /* @__PURE__ */ jsx(ClockIcon, {})
|
|
10246
|
+
}
|
|
10247
|
+
),
|
|
10184
10248
|
title
|
|
10185
10249
|
] }),
|
|
10186
10250
|
hasGoal && /* @__PURE__ */ jsxs("div", { className: "text-fg-3 font-mono text-[13px] tabular-nums", children: [
|
|
10187
|
-
/* @__PURE__ */ jsx("b", { className: "text-fg font-
|
|
10251
|
+
/* @__PURE__ */ jsx("b", { className: "text-fg font-semibold", children: formatDuration(loggedMinutes * 60) }),
|
|
10188
10252
|
" /",
|
|
10189
10253
|
" ",
|
|
10190
10254
|
formatDuration(goalMinutes * 60)
|
|
@@ -10193,7 +10257,7 @@ var TimeLoggerHeader = forwardRef(
|
|
|
10193
10257
|
hasGoal && /* @__PURE__ */ jsx(
|
|
10194
10258
|
"div",
|
|
10195
10259
|
{
|
|
10196
|
-
className: "bg-bg-3 relative h-
|
|
10260
|
+
className: "bg-bg-3 relative h-1 w-full",
|
|
10197
10261
|
role: "progressbar",
|
|
10198
10262
|
"aria-label": "Daily goal progress",
|
|
10199
10263
|
"aria-valuemin": 0,
|
|
@@ -10202,7 +10266,7 @@ var TimeLoggerHeader = forwardRef(
|
|
|
10202
10266
|
children: /* @__PURE__ */ jsx(
|
|
10203
10267
|
"div",
|
|
10204
10268
|
{
|
|
10205
|
-
className: "
|
|
10269
|
+
className: "h-full rounded-r-full bg-[image:var(--gradient-pro)] transition-[width] duration-[var(--duration-normal)] ease-[var(--ease-out-quart)] motion-reduce:transition-none",
|
|
10206
10270
|
style: { width: `${pct}%` }
|
|
10207
10271
|
}
|
|
10208
10272
|
)
|
|
@@ -10222,7 +10286,11 @@ var TimeLoggerContextRow = forwardRef(
|
|
|
10222
10286
|
"div",
|
|
10223
10287
|
{
|
|
10224
10288
|
ref,
|
|
10225
|
-
className: cn(
|
|
10289
|
+
className: cn(
|
|
10290
|
+
"border-rule-soft flex items-center gap-2.5 border-t px-4 py-3",
|
|
10291
|
+
horizontalSegment,
|
|
10292
|
+
className
|
|
10293
|
+
),
|
|
10226
10294
|
...props,
|
|
10227
10295
|
children: [
|
|
10228
10296
|
onClientSelect ? /* @__PURE__ */ jsxs(
|
|
@@ -10267,7 +10335,15 @@ var TimeLoggerTimer = forwardRef(
|
|
|
10267
10335
|
"div",
|
|
10268
10336
|
{
|
|
10269
10337
|
ref,
|
|
10270
|
-
className: cn(
|
|
10338
|
+
className: cn(
|
|
10339
|
+
"border-rule-soft flex items-center gap-2.5 border-t px-4 py-4",
|
|
10340
|
+
// In a horizontal bar this segment is usually the `flex-1` grower;
|
|
10341
|
+
// min-w-0 lets the clock shrink instead of pushing the trailing
|
|
10342
|
+
// segment off the edge.
|
|
10343
|
+
"group-data-[orientation=horizontal]/timelogger:min-w-0",
|
|
10344
|
+
horizontalSegment,
|
|
10345
|
+
className
|
|
10346
|
+
),
|
|
10271
10347
|
...props,
|
|
10272
10348
|
children: [
|
|
10273
10349
|
/* @__PURE__ */ jsx(
|
|
@@ -10275,7 +10351,7 @@ var TimeLoggerTimer = forwardRef(
|
|
|
10275
10351
|
{
|
|
10276
10352
|
className: cn(
|
|
10277
10353
|
"text-fg placeholder:text-fg-4 min-w-0 flex-1 border-0 bg-transparent outline-none",
|
|
10278
|
-
showClock ? "font-mono text-[
|
|
10354
|
+
showClock ? "font-mono text-[28px] font-semibold tracking-tight tabular-nums" : "text-[15px]"
|
|
10279
10355
|
),
|
|
10280
10356
|
value: showClock ? formatClock(elapsedMs) : value ?? "",
|
|
10281
10357
|
onChange: (event) => onValueChange?.(event.target.value),
|
|
@@ -10288,9 +10364,9 @@ var TimeLoggerTimer = forwardRef(
|
|
|
10288
10364
|
Button,
|
|
10289
10365
|
{
|
|
10290
10366
|
type: "button",
|
|
10291
|
-
variant: "
|
|
10367
|
+
variant: "ghost",
|
|
10292
10368
|
size: "icon",
|
|
10293
|
-
className: "rounded-full",
|
|
10369
|
+
className: "text-fg-3 hover:bg-bg-3 hover:text-fg size-10 rounded-full",
|
|
10294
10370
|
"aria-label": phase === "paused" ? "Resume timer" : "Pause timer",
|
|
10295
10371
|
disabled: phase === "idle" || phase === "stopped",
|
|
10296
10372
|
onClick: phase === "paused" ? onResume : onPause,
|
|
@@ -10303,7 +10379,7 @@ var TimeLoggerTimer = forwardRef(
|
|
|
10303
10379
|
type: "button",
|
|
10304
10380
|
variant: "destructive",
|
|
10305
10381
|
size: "icon",
|
|
10306
|
-
className: "rounded-full",
|
|
10382
|
+
className: "shadow-card hover:shadow-pop size-12 rounded-full transition-[transform,box-shadow] active:scale-95 motion-reduce:transition-none",
|
|
10307
10383
|
"aria-label": "Stop timer",
|
|
10308
10384
|
onClick: onStop,
|
|
10309
10385
|
children: /* @__PURE__ */ jsx(StopIcon, {})
|
|
@@ -10314,7 +10390,7 @@ var TimeLoggerTimer = forwardRef(
|
|
|
10314
10390
|
type: "button",
|
|
10315
10391
|
variant: "primary",
|
|
10316
10392
|
size: "icon",
|
|
10317
|
-
className: "rounded-full",
|
|
10393
|
+
className: "shadow-card hover:shadow-pop size-12 rounded-full bg-[image:var(--gradient-brand)] transition-[transform,box-shadow] active:scale-95 motion-reduce:transition-none",
|
|
10318
10394
|
"aria-label": "Start timer",
|
|
10319
10395
|
onClick: onStart,
|
|
10320
10396
|
children: /* @__PURE__ */ jsx(PlayIcon, {})
|
|
@@ -10345,7 +10421,9 @@ var TimeLoggerField = forwardRef(
|
|
|
10345
10421
|
trailing !== void 0 ? trailing : interactive ? /* @__PURE__ */ jsx(ChevronRightIcon, { className: "text-fg-4 size-4 shrink-0" }) : null
|
|
10346
10422
|
] });
|
|
10347
10423
|
const classes = cn(
|
|
10348
|
-
"border-rule-soft flex w-full items-center gap-3 border-t px-4 py-
|
|
10424
|
+
"border-rule-soft flex w-full items-center gap-3 border-t px-4 py-3 text-left",
|
|
10425
|
+
"group-data-[orientation=horizontal]/timelogger:w-auto",
|
|
10426
|
+
horizontalSegment,
|
|
10349
10427
|
interactive && "hover:bg-surface-2 focus-visible:bg-surface-2 cursor-pointer transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)] outline-none motion-reduce:transition-none",
|
|
10350
10428
|
className
|
|
10351
10429
|
);
|
|
@@ -10368,7 +10446,7 @@ var TimeLoggerField = forwardRef(
|
|
|
10368
10446
|
TimeLoggerField.displayName = "TimeLoggerField";
|
|
10369
10447
|
var TimeLoggerNotes = forwardRef(
|
|
10370
10448
|
function TimeLoggerNotes2({ value, onValueChange, icon, placeholder = "Add notes", className, ...props }, ref) {
|
|
10371
|
-
return /* @__PURE__ */ jsxs("div", { className: "border-rule-soft flex items-center gap-3 border-t px-4 py-
|
|
10449
|
+
return /* @__PURE__ */ jsxs("div", { className: "border-rule-soft flex items-center gap-3 border-t px-4 py-3", children: [
|
|
10372
10450
|
/* @__PURE__ */ jsx(
|
|
10373
10451
|
"span",
|
|
10374
10452
|
{
|
|
@@ -10486,7 +10564,8 @@ var TimeLoggerActions = forwardRef(
|
|
|
10486
10564
|
{
|
|
10487
10565
|
ref,
|
|
10488
10566
|
className: cn(
|
|
10489
|
-
"border-rule bg-surface-2 flex items-center gap-2 border-t px-4 py-
|
|
10567
|
+
"border-rule bg-surface-2 flex items-center gap-2 border-t px-4 py-3",
|
|
10568
|
+
horizontalSegment,
|
|
10490
10569
|
className
|
|
10491
10570
|
),
|
|
10492
10571
|
...props,
|
|
@@ -10514,7 +10593,10 @@ var TimeLoggerEntry = forwardRef(
|
|
|
10514
10593
|
"div",
|
|
10515
10594
|
{
|
|
10516
10595
|
ref,
|
|
10517
|
-
className: cn(
|
|
10596
|
+
className: cn(
|
|
10597
|
+
"border-rule-soft hover:bg-surface-2 flex items-center gap-3 border-t px-4 py-2.5 transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)] motion-reduce:transition-none",
|
|
10598
|
+
className
|
|
10599
|
+
),
|
|
10518
10600
|
...props,
|
|
10519
10601
|
children: [
|
|
10520
10602
|
/* @__PURE__ */ jsx(
|
|
@@ -10565,7 +10647,7 @@ var TimeLoggerFooter = forwardRef(
|
|
|
10565
10647
|
"div",
|
|
10566
10648
|
{
|
|
10567
10649
|
ref,
|
|
10568
|
-
className: cn("border-rule flex gap-2 border-t px-4 py-
|
|
10650
|
+
className: cn("border-rule flex gap-2 border-t px-4 py-3 [&>*]:flex-1", className),
|
|
10569
10651
|
...props,
|
|
10570
10652
|
children
|
|
10571
10653
|
}
|