@papernote/ui 1.7.2 → 1.7.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/components/Breadcrumbs.d.ts +3 -0
- package/dist/components/Breadcrumbs.d.ts.map +1 -1
- package/dist/components/Calendar.d.ts +3 -1
- package/dist/components/Calendar.d.ts.map +1 -1
- package/dist/components/FormWizard.d.ts.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.esm.js +48 -18
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +46 -16
- package/dist/index.js.map +1 -1
- package/dist/styles.css +0 -4
- package/package.json +1 -1
- package/src/components/Breadcrumbs.tsx +66 -22
- package/src/components/Calendar.tsx +21 -10
- package/src/components/FormWizard.tsx +1 -2
package/dist/index.js
CHANGED
|
@@ -4240,7 +4240,7 @@ function Stepper({ steps, activeStep, completedSteps = [], orientation = 'horizo
|
|
|
4240
4240
|
`, children: steps.map((step, index) => renderStep(step, index)) }));
|
|
4241
4241
|
}
|
|
4242
4242
|
|
|
4243
|
-
function Calendar({ value, onChange, events = [], onEventClick, rangeMode = false, rangeValue, onRangeChange, minDate, maxDate, disabledDates = [], showWeekNumbers = false, firstDayOfWeek = 0, className = '', }) {
|
|
4243
|
+
function Calendar({ value, onChange, onMonthChange, events = [], onEventClick, rangeMode = false, rangeValue, onRangeChange, minDate, maxDate, disabledDates = [], showWeekNumbers = false, firstDayOfWeek = 0, className = '', }) {
|
|
4244
4244
|
const [currentMonth, setCurrentMonth] = React.useState(value || new Date());
|
|
4245
4245
|
const [hoverDate, setHoverDate] = React.useState(null);
|
|
4246
4246
|
// Generate calendar grid for current month
|
|
@@ -4364,21 +4364,31 @@ function Calendar({ value, onChange, events = [], onEventClick, rangeMode = fals
|
|
|
4364
4364
|
};
|
|
4365
4365
|
// Navigate months
|
|
4366
4366
|
const previousMonth = () => {
|
|
4367
|
-
|
|
4367
|
+
const newMonth = new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1, 1);
|
|
4368
|
+
setCurrentMonth(newMonth);
|
|
4369
|
+
onMonthChange?.(newMonth);
|
|
4368
4370
|
};
|
|
4369
4371
|
const nextMonth = () => {
|
|
4370
|
-
|
|
4372
|
+
const newMonth = new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1, 1);
|
|
4373
|
+
setCurrentMonth(newMonth);
|
|
4374
|
+
onMonthChange?.(newMonth);
|
|
4371
4375
|
};
|
|
4372
4376
|
// Navigate years
|
|
4373
4377
|
const previousYear = () => {
|
|
4374
|
-
|
|
4378
|
+
const newMonth = new Date(currentMonth.getFullYear() - 1, currentMonth.getMonth(), 1);
|
|
4379
|
+
setCurrentMonth(newMonth);
|
|
4380
|
+
onMonthChange?.(newMonth);
|
|
4375
4381
|
};
|
|
4376
4382
|
const nextYear = () => {
|
|
4377
|
-
|
|
4383
|
+
const newMonth = new Date(currentMonth.getFullYear() + 1, currentMonth.getMonth(), 1);
|
|
4384
|
+
setCurrentMonth(newMonth);
|
|
4385
|
+
onMonthChange?.(newMonth);
|
|
4378
4386
|
};
|
|
4379
4387
|
// Go to today
|
|
4380
4388
|
const goToToday = () => {
|
|
4381
|
-
|
|
4389
|
+
const today = new Date();
|
|
4390
|
+
setCurrentMonth(today);
|
|
4391
|
+
onMonthChange?.(today);
|
|
4382
4392
|
};
|
|
4383
4393
|
// Day names
|
|
4384
4394
|
const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
@@ -4391,7 +4401,7 @@ function Calendar({ value, onChange, events = [], onEventClick, rangeMode = fals
|
|
|
4391
4401
|
error: 'bg-error-500',
|
|
4392
4402
|
accent: 'bg-accent-500',
|
|
4393
4403
|
};
|
|
4394
|
-
return (jsxRuntime.jsxs("div", { className: `bg-white rounded-lg border border-paper-200 shadow-sm ${className}`, children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 border-b border-paper-200", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.
|
|
4404
|
+
return (jsxRuntime.jsxs("div", { className: `bg-white rounded-lg border border-paper-200 shadow-sm ${className}`, children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 border-b border-paper-200", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("button", { onClick: previousYear, className: "p-1.5 hover:bg-paper-100 rounded transition-colors", "aria-label": "Previous year", children: jsxRuntime.jsx(lucideReact.ChevronsLeft, { className: "h-4 w-4 text-ink-600" }) }), jsxRuntime.jsx("button", { onClick: previousMonth, className: "p-1.5 hover:bg-paper-100 rounded transition-colors", "aria-label": "Previous month", children: jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-4 w-4 text-ink-600" }) })] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-ink-900", children: currentMonth.toLocaleDateString('en-US', { month: 'long', year: 'numeric' }) }), jsxRuntime.jsx("button", { onClick: goToToday, className: "px-3 py-1 text-sm font-medium text-accent-700 hover:bg-accent-50 rounded transition-colors", children: "Today" })] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("button", { onClick: nextMonth, className: "p-1.5 hover:bg-paper-100 rounded transition-colors", "aria-label": "Next month", children: jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4 text-ink-600" }) }), jsxRuntime.jsx("button", { onClick: nextYear, className: "p-1.5 hover:bg-paper-100 rounded transition-colors", "aria-label": "Next year", children: jsxRuntime.jsx(lucideReact.ChevronsRight, { className: "h-4 w-4 text-ink-600" }) })] })] }), jsxRuntime.jsx("div", { className: "p-4", children: jsxRuntime.jsxs("div", { className: "grid grid-cols-7 gap-1", children: [showWeekNumbers && jsxRuntime.jsx("div", { className: "h-8" }), adjustedDayNames.map((day) => (jsxRuntime.jsx("div", { className: "h-8 flex items-center justify-center text-xs font-semibold text-ink-600", children: day }, day))), Array.from({ length: 6 }).map((_, weekIndex) => (jsxRuntime.jsxs(React.Fragment, { children: [showWeekNumbers && (jsxRuntime.jsx("div", { className: "flex items-center justify-center text-xs text-ink-500 font-medium", children: getWeekNumber(calendarDays[weekIndex * 7]) })), calendarDays.slice(weekIndex * 7, weekIndex * 7 + 7).map((date, dayIndex) => {
|
|
4395
4405
|
const dateEvents = getEventsForDate(date);
|
|
4396
4406
|
const selected = isSelected(date);
|
|
4397
4407
|
const inRange = isInRange(date);
|
|
@@ -5378,7 +5388,6 @@ function FormWizard({ steps, onComplete, onStepChange, showStepNumbers = true, a
|
|
|
5378
5388
|
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
5379
5389
|
const isFirstStep = currentStep === 0;
|
|
5380
5390
|
const isLastStep = currentStep === steps.length - 1;
|
|
5381
|
-
const canGoNext = allowSkip || completedSteps.has(currentStep);
|
|
5382
5391
|
// Go to specific step
|
|
5383
5392
|
const goToStep = (stepIndex) => {
|
|
5384
5393
|
if (stepIndex < 0 || stepIndex >= steps.length)
|
|
@@ -5450,7 +5459,7 @@ function FormWizard({ steps, onComplete, onStepChange, showStepNumbers = true, a
|
|
|
5450
5459
|
? 'bg-accent-500'
|
|
5451
5460
|
: 'bg-paper-200'}
|
|
5452
5461
|
` }) }))] }, step.id));
|
|
5453
|
-
}) }) }), jsxRuntime.jsx("div", { className: "mb-8", children: steps.map((step, index) => (jsxRuntime.jsx("div", { hidden: index !== currentStep, children: step.content }, step.id))) }), jsxRuntime.jsxs("div", { className: "flex items-center justify-between pt-6 border-t border-paper-200", children: [jsxRuntime.jsx("button", { type: "button", onClick: prevStep, disabled: isFirstStep, className: "px-4 py-2 text-sm font-medium text-ink-700 bg-white border border-paper-300 rounded-lg hover:bg-paper-50 disabled:opacity-40 disabled:cursor-not-allowed transition-all", children: "Previous" }), jsxRuntime.jsxs("div", { className: "text-sm text-ink-600", children: ["Step ", currentStep + 1, " of ", steps.length] }), jsxRuntime.jsx("button", { type: "button", onClick: nextStep, disabled:
|
|
5462
|
+
}) }) }), jsxRuntime.jsx("div", { className: "mb-8", children: steps.map((step, index) => (jsxRuntime.jsx("div", { hidden: index !== currentStep, children: step.content }, step.id))) }), jsxRuntime.jsxs("div", { className: "flex items-center justify-between pt-6 border-t border-paper-200", children: [jsxRuntime.jsx("button", { type: "button", onClick: prevStep, disabled: isFirstStep, className: "px-4 py-2 text-sm font-medium text-ink-700 bg-white border border-paper-300 rounded-lg hover:bg-paper-50 disabled:opacity-40 disabled:cursor-not-allowed transition-all", children: "Previous" }), jsxRuntime.jsxs("div", { className: "text-sm text-ink-600", children: ["Step ", currentStep + 1, " of ", steps.length] }), jsxRuntime.jsx("button", { type: "button", onClick: nextStep, disabled: isSubmitting, className: "px-4 py-2 text-sm font-medium text-white bg-accent-500 rounded-lg hover:bg-accent-600 disabled:opacity-40 disabled:cursor-not-allowed transition-all", children: isSubmitting ? 'Submitting...' : isLastStep ? 'Complete' : 'Next' })] })] }));
|
|
5454
5463
|
}
|
|
5455
5464
|
|
|
5456
5465
|
function InfiniteScroll({ loadMore, hasMore, loading = false, children, threshold = 200, loader, scrollContainer, reverse = false, className = '', }) {
|
|
@@ -7283,6 +7292,9 @@ function Hide({ children, above, below, only, className = '' }) {
|
|
|
7283
7292
|
* Hook to detect breadcrumb navigation and trigger callbacks.
|
|
7284
7293
|
* Use this in host components to reset state when a breadcrumb is clicked.
|
|
7285
7294
|
*
|
|
7295
|
+
* Note: This hook requires React Router context. If used outside a Router,
|
|
7296
|
+
* it will be a no-op (the callback will never be called).
|
|
7297
|
+
*
|
|
7286
7298
|
* @param onReset - Callback fired when breadcrumb navigation is detected
|
|
7287
7299
|
*
|
|
7288
7300
|
* @example
|
|
@@ -7296,15 +7308,19 @@ function Hide({ children, above, below, only, className = '' }) {
|
|
|
7296
7308
|
* }
|
|
7297
7309
|
*/
|
|
7298
7310
|
function useBreadcrumbReset(onReset) {
|
|
7299
|
-
const
|
|
7311
|
+
const inRouter = reactRouterDom.useInRouterContext();
|
|
7300
7312
|
const lastResetRef = React.useRef(null);
|
|
7313
|
+
// Only use useLocation when inside Router context
|
|
7314
|
+
const location = inRouter ? reactRouterDom.useLocation() : null;
|
|
7301
7315
|
React.useEffect(() => {
|
|
7316
|
+
if (!location)
|
|
7317
|
+
return;
|
|
7302
7318
|
const state = location.state;
|
|
7303
7319
|
if (state?.breadcrumbReset && state.breadcrumbReset !== lastResetRef.current) {
|
|
7304
7320
|
lastResetRef.current = state.breadcrumbReset;
|
|
7305
7321
|
onReset();
|
|
7306
7322
|
}
|
|
7307
|
-
}, [location
|
|
7323
|
+
}, [location?.state, onReset, location]);
|
|
7308
7324
|
}
|
|
7309
7325
|
/**
|
|
7310
7326
|
* Breadcrumbs navigation component.
|
|
@@ -7339,8 +7355,10 @@ function useBreadcrumbReset(onReset) {
|
|
|
7339
7355
|
* }
|
|
7340
7356
|
*/
|
|
7341
7357
|
function Breadcrumbs({ items, showHome = true }) {
|
|
7342
|
-
const
|
|
7343
|
-
|
|
7358
|
+
const inRouter = reactRouterDom.useInRouterContext();
|
|
7359
|
+
// Only use router hooks when inside Router context
|
|
7360
|
+
const navigate = inRouter ? reactRouterDom.useNavigate() : null;
|
|
7361
|
+
const location = inRouter ? reactRouterDom.useLocation() : null;
|
|
7344
7362
|
/**
|
|
7345
7363
|
* Handle breadcrumb click with same-route detection.
|
|
7346
7364
|
* When clicking a breadcrumb that points to the current route,
|
|
@@ -7349,6 +7367,9 @@ function Breadcrumbs({ items, showHome = true }) {
|
|
|
7349
7367
|
const handleBreadcrumbClick = (e, href, onClick) => {
|
|
7350
7368
|
// Always call onClick if provided (for custom actions)
|
|
7351
7369
|
onClick?.();
|
|
7370
|
+
// If not in router context, let the browser handle navigation naturally
|
|
7371
|
+
if (!navigate || !location)
|
|
7372
|
+
return;
|
|
7352
7373
|
// Check if we're navigating to the same base path
|
|
7353
7374
|
const targetPath = href.split('?')[0].split('#')[0];
|
|
7354
7375
|
const currentPath = location.pathname;
|
|
@@ -7365,7 +7386,16 @@ function Breadcrumbs({ items, showHome = true }) {
|
|
|
7365
7386
|
}
|
|
7366
7387
|
// Different route - let the Link handle it normally
|
|
7367
7388
|
};
|
|
7368
|
-
|
|
7389
|
+
// Helper to render a link - uses Link when in router, <a> when not
|
|
7390
|
+
const renderLink = (href, children, className, onClick, ariaLabel) => {
|
|
7391
|
+
if (inRouter) {
|
|
7392
|
+
return (jsxRuntime.jsx(reactRouterDom.Link, { to: href, className: className, onClick: onClick, "aria-label": ariaLabel, children: children }));
|
|
7393
|
+
}
|
|
7394
|
+
return (jsxRuntime.jsx("a", { href: href, className: className, onClick: (e) => {
|
|
7395
|
+
onClick?.(e);
|
|
7396
|
+
}, "aria-label": ariaLabel, children: children }));
|
|
7397
|
+
};
|
|
7398
|
+
return (jsxRuntime.jsxs("nav", { "aria-label": "Breadcrumb", className: "flex items-center space-x-2 text-sm", children: [showHome && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [renderLink('/', jsxRuntime.jsx(lucideReact.Home, { className: "h-4 w-4" }), 'text-ink-500 hover:text-ink-900 transition-colors', (e) => handleBreadcrumbClick(e, '/'), 'Home'), items.length > 0 && jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4 text-ink-400" })] })), items.map((item, index) => {
|
|
7369
7399
|
const isLast = index === items.length - 1;
|
|
7370
7400
|
const isActive = isLast;
|
|
7371
7401
|
const content = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [item.icon && jsxRuntime.jsx("span", { className: "flex-shrink-0", children: item.icon }), jsxRuntime.jsx("span", { children: item.label })] }));
|
|
@@ -7374,9 +7404,9 @@ function Breadcrumbs({ items, showHome = true }) {
|
|
|
7374
7404
|
if (isActive) {
|
|
7375
7405
|
return (jsxRuntime.jsx("span", { className: "flex items-center gap-2 px-2 py-1 rounded-md bg-accent-50 text-accent-900 font-semibold transition-colors", "aria-current": "page", children: content }));
|
|
7376
7406
|
}
|
|
7377
|
-
// Has href - render as Link with same-route detection
|
|
7407
|
+
// Has href - render as Link (or <a> if no router) with same-route detection
|
|
7378
7408
|
if (item.href) {
|
|
7379
|
-
return (
|
|
7409
|
+
return renderLink(item.href, content, 'flex items-center gap-2 text-ink-500 hover:text-ink-900 hover:underline transition-colors', (e) => handleBreadcrumbClick(e, item.href, item.onClick));
|
|
7380
7410
|
}
|
|
7381
7411
|
// Only onClick (no href) - render as button
|
|
7382
7412
|
if (item.onClick) {
|