mn-angular-lib 1.0.119 → 1.0.121
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.
|
@@ -229,6 +229,9 @@ const mnButtonVariants = tv({
|
|
|
229
229
|
outline: 'bg-transparent border',
|
|
230
230
|
text: 'bg-transparent',
|
|
231
231
|
textUnderline: 'bg-transparent underline underline-offset-2',
|
|
232
|
+
// Transparent button that only reveals a subtle surface on hover — the idiomatic
|
|
233
|
+
// icon-button look. Colors resolved via compoundVariants.
|
|
234
|
+
ghost: 'bg-transparent',
|
|
232
235
|
},
|
|
233
236
|
// Intentionally empty; resolved via compoundVariants
|
|
234
237
|
color: {
|
|
@@ -251,6 +254,14 @@ const mnButtonVariants = tv({
|
|
|
251
254
|
three_xl: 'rounded-3xl',
|
|
252
255
|
four_xl: 'rounded-4xl',
|
|
253
256
|
},
|
|
257
|
+
// Icon-button shape. `circle`/`square` drop the text padding and make the button a
|
|
258
|
+
// fixed square sized off `size` (see compoundVariants), overriding `borderRadius`.
|
|
259
|
+
// `default` leaves a normal text button untouched.
|
|
260
|
+
shape: {
|
|
261
|
+
default: '',
|
|
262
|
+
circle: 'p-0 shrink-0 rounded-full',
|
|
263
|
+
square: 'p-0 shrink-0 rounded-md',
|
|
264
|
+
},
|
|
254
265
|
disabled: {
|
|
255
266
|
true: 'opacity-50 pointer-events-none',
|
|
256
267
|
},
|
|
@@ -332,12 +343,36 @@ const mnButtonVariants = tv({
|
|
|
332
343
|
{ variant: 'textUnderline', color: 'success', hover: true, class: 'hover:bg-success/10' },
|
|
333
344
|
{ variant: 'textUnderline', color: 'accent', hover: true, class: 'hover:bg-accent/10' },
|
|
334
345
|
{ variant: 'textUnderline', color: 'gray', hover: true, class: 'hover:bg-base-content/10' },
|
|
346
|
+
// Ghost — base (transparent, colored text/icon)
|
|
347
|
+
{ variant: 'ghost', color: 'primary', class: 'text-primary' },
|
|
348
|
+
{ variant: 'ghost', color: 'secondary', class: 'text-neutral' },
|
|
349
|
+
{ variant: 'ghost', color: 'danger', class: 'text-error' },
|
|
350
|
+
{ variant: 'ghost', color: 'warning', class: 'text-warning' },
|
|
351
|
+
{ variant: 'ghost', color: 'success', class: 'text-success' },
|
|
352
|
+
{ variant: 'ghost', color: 'accent', class: 'text-accent' },
|
|
353
|
+
{ variant: 'ghost', color: 'gray', class: 'text-base-content' },
|
|
354
|
+
// Ghost — hover (reveal a subtle surface in the button's own hue)
|
|
355
|
+
{ variant: 'ghost', color: 'primary', hover: true, class: 'hover:bg-primary/10' },
|
|
356
|
+
{ variant: 'ghost', color: 'secondary', hover: true, class: 'hover:bg-neutral/10' },
|
|
357
|
+
{ variant: 'ghost', color: 'danger', hover: true, class: 'hover:bg-error/10' },
|
|
358
|
+
{ variant: 'ghost', color: 'warning', hover: true, class: 'hover:bg-warning/10' },
|
|
359
|
+
{ variant: 'ghost', color: 'success', hover: true, class: 'hover:bg-success/10' },
|
|
360
|
+
{ variant: 'ghost', color: 'accent', hover: true, class: 'hover:bg-accent/10' },
|
|
361
|
+
{ variant: 'ghost', color: 'gray', hover: true, class: 'hover:bg-base-content/10' },
|
|
362
|
+
// Icon-button square sizing — applies to both circle and square shapes, sized off `size`.
|
|
363
|
+
{ shape: 'circle', size: 'sm', class: 'h-8 w-8' },
|
|
364
|
+
{ shape: 'circle', size: 'md', class: 'h-10 w-10' },
|
|
365
|
+
{ shape: 'circle', size: 'lg', class: 'h-12 w-12' },
|
|
366
|
+
{ shape: 'square', size: 'sm', class: 'h-8 w-8' },
|
|
367
|
+
{ shape: 'square', size: 'md', class: 'h-10 w-10' },
|
|
368
|
+
{ shape: 'square', size: 'lg', class: 'h-12 w-12' },
|
|
335
369
|
],
|
|
336
370
|
defaultVariants: {
|
|
337
371
|
size: 'md',
|
|
338
372
|
variant: 'fill',
|
|
339
373
|
color: 'primary',
|
|
340
374
|
borderRadius: 'lg',
|
|
375
|
+
shape: 'default',
|
|
341
376
|
disabled: false,
|
|
342
377
|
loading: false,
|
|
343
378
|
wrap: false,
|
|
@@ -355,6 +390,7 @@ class MnButton {
|
|
|
355
390
|
variant: this.data.variant,
|
|
356
391
|
color: this.data.color,
|
|
357
392
|
borderRadius: this.data.borderRadius,
|
|
393
|
+
shape: this.data.shape,
|
|
358
394
|
disabled: this.data.disabled,
|
|
359
395
|
loading: this.data.loading,
|
|
360
396
|
wrap: this.data.wrap,
|
|
@@ -9210,7 +9246,6 @@ class CalendarViewComponent {
|
|
|
9210
9246
|
focusDay = new Date();
|
|
9211
9247
|
viewOptions = [];
|
|
9212
9248
|
isMobileView = false;
|
|
9213
|
-
isTabletView = false;
|
|
9214
9249
|
/** BehaviorSubject so late-subscribing child views receive the last emitted events. */
|
|
9215
9250
|
internalEventsChanged = new BehaviorSubject([]);
|
|
9216
9251
|
/** Subject for broadcasting focus-day changes to child views. */
|
|
@@ -9367,7 +9402,6 @@ class CalendarViewComponent {
|
|
|
9367
9402
|
// view takes over earlier — and consumers can tune where via `mobileBreakpoint`.
|
|
9368
9403
|
const breakpoint = this.config.mobileBreakpoint;
|
|
9369
9404
|
this.isMobileView = width < breakpoint;
|
|
9370
|
-
this.isTabletView = width >= breakpoint && width < 1024;
|
|
9371
9405
|
if (this.isMobileView && !wasMobile) {
|
|
9372
9406
|
this.currentView = CalendarView.DAY;
|
|
9373
9407
|
}
|
|
@@ -9400,7 +9434,7 @@ class CalendarViewComponent {
|
|
|
9400
9434
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CalendarViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9401
9435
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: CalendarViewComponent, isStandalone: true, selector: "mn-calendar-view", inputs: { showButton: "showButton", buttonTitle: "buttonTitle", buttons: "buttons", CalendarEventComponent: "CalendarEventComponent", NewCalendarItemsEvent: "NewCalendarItemsEvent" }, outputs: { RequestNewCalendarItemsEvent: "RequestNewCalendarItemsEvent", CalendarItemClickedEvent: "CalendarItemClickedEvent", ButtonClickedEvent: "ButtonClickedEvent" }, host: { listeners: { "window:resize": "onResize()" } }, providers: [
|
|
9402
9436
|
provideMnCalendarConfig(DEFAULT_CALENDAR_CONFIG),
|
|
9403
|
-
], ngImport: i0, template: "<div class=\"w-full h-full flex flex-col\" role=\"application\" aria-label=\"Calendar\">\n\n <!-- Toolbar
|
|
9437
|
+
], ngImport: i0, template: "<div class=\"w-full h-full flex flex-col\" role=\"application\" aria-label=\"Calendar\">\n\n <!-- Toolbar has one layout below the desktop (`lg`) width and one at it. Below\n `lg`: a controls row (Today anchored left, the right-hand cluster anchored\n right) with the \u2039 date \u203A nav centred on its own row beneath \u2014 the same\n shape from phone through tablet, so nothing wraps into a lopsided diagonal.\n At `lg`, where the upcoming-events sidebar also appears, the nav folds up\n inline after Today and the whole toolbar becomes a single row. The one JS\n breakpoint (`mobileBreakpoint`) governs the phone controls \u2014 icon-only\n picker, hidden view-switcher, forced day view \u2014 not the toolbar's shape. -->\n <div class=\"flex flex-wrap items-center gap-x-3 gap-y-2 py-3\">\n\n <button (click)=\"goToToday()\"\n [data]=\"{ variant: 'outline', size: 'md', color: 'primary' }\"\n class=\"shrink-0\"\n mnButton\n type=\"button\">\n {{ config.todayLabel }}\n </button>\n\n <!-- Stepping through time. The arrows sit either side of the date they move,\n so the control and the thing it controls read as one unit. Below `lg` it\n sits centred on its own row (basis-full, ordered last) \u2014 a period header\n above the grid, tight rather than flinging the arrows to the row's edges.\n At `lg` it folds inline right after Today, taking a stable min-width so\n the arrows don't jitter as the label's length changes. -->\n <div class=\"flex basis-full order-last justify-center items-center gap-1\n lg:basis-auto lg:order-none lg:justify-start\">\n <button (click)=\"navigate(-1)\"\n [attr.aria-label]=\"config.previousLabel\"\n [data]=\"{ variant: 'text', size: 'md', color: 'gray' }\"\n class=\"shrink-0\"\n mnButton\n type=\"button\">\n <svg [size]=\"18\" lucideChevronLeft></svg>\n </button>\n\n <h2 aria-live=\"polite\"\n class=\"text-center text-base font-semibold whitespace-nowrap px-1 lg:min-w-56\">\n {{ periodLabel }}\n </h2>\n\n <button (click)=\"navigate(1)\"\n [attr.aria-label]=\"config.nextLabel\"\n [data]=\"{ variant: 'text', size: 'md', color: 'gray' }\"\n class=\"shrink-0\"\n mnButton\n type=\"button\">\n <svg [size]=\"18\" lucideChevronRight></svg>\n </button>\n </div>\n\n <!-- Right-hand controls travel together as one cluster with `ml-auto`, so they\n hold to the right of the row on every width \u2014 and when space runs short the\n whole group wraps to a new line as a unit rather than stranding a lone\n button. On desktop the cluster lands above the upcoming-events sidebar,\n using that otherwise-empty space. -->\n <div class=\"ml-auto flex items-center gap-2\">\n <!-- On mobile the picker collapses to its icon-only variant. -->\n <mn-lib-datetime (ngModelChange)=\"onPickDate($event)\"\n [ngModel]=\"focusDayString\"\n [props]=\"{ id: panelId + '-date', mode: 'date', placeholder: config.pickDateLabel, size: 'md', borderRadius: 'lg', hover: true, iconOnly: isMobileView }\"\n class=\"block\"></mn-lib-datetime>\n\n <!-- View switcher (month / week / day) \u2014 hidden on mobile, which is forced to day view. -->\n @if (!isMobileView) {\n <div aria-label=\"Calendar view\" class=\"flex border border-base-300 rounded-md overflow-hidden\" role=\"tablist\">\n @for (view of viewOptions; track view.value) {\n <button\n (click)=\"switchView(view.value)\"\n [attr.aria-controls]=\"panelId\"\n [attr.aria-selected]=\"currentView === view.value\"\n [data]=\"{ size: 'md', variant: currentView === view.value ? 'fill' : 'text', color: 'primary' }\"\n mnButton\n role=\"tab\"\n type=\"button\">\n {{ view.label }}\n </button>\n }\n </div>\n }\n\n <!-- Action buttons (custom buttons + optional showButton CTA). -->\n @if (buttons.length || showButton) {\n @for (btn of buttons; track btn.label) {\n <button (click)=\"btn.onClick()\" [data]=\"btn.buttonData || {}\" mnButton type=\"button\">\n {{ btn.label }}\n </button>\n }\n @if (showButton) {\n <button (click)=\"ButtonClickedEvent.emit()\" [data]=\"{}\" mnButton type=\"button\">\n {{ buttonTitle }}\n </button>\n }\n }\n </div>\n\n </div>\n\n <div class=\"grid grid-cols-1 lg:grid-cols-[1fr_220px] gap-3 flex-1 min-h-0\">\n <div [id]=\"panelId\" class=\"min-w-0 min-h-0 overflow-hidden overflow-y-auto\" role=\"tabpanel\">\n @if (currentView === CalendarView.MONTH) {\n <mn-calendar-month\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n (dayClicked)=\"onMonthDayClick($event)\">\n </mn-calendar-month>\n }\n @if (currentView === CalendarView.WEEK) {\n <mn-calendar-week\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n [calendarEventComponent]=\"CalendarEventComponent\"\n (eventClicked)=\"onEventClick($event)\">\n </mn-calendar-week>\n }\n @if (currentView === CalendarView.DAY) {\n <mn-calendar-day\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n [calendarEventComponent]=\"CalendarEventComponent\"\n (eventClicked)=\"onEventClick($event)\">\n </mn-calendar-day>\n }\n </div>\n <div class=\"hidden lg:block border-l border-base-300 overflow-auto\">\n <mn-upcoming-events\n [eventsChanged]=\"internalEventsChanged\"\n [config]=\"config\"\n (eventClicked)=\"onEventClick($event)\">\n </mn-upcoming-events>\n </div>\n </div>\n\n</div>\n", styles: [":host{display:flex;flex-direction:column;width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CalendarMonthComponent, selector: "mn-calendar-month", inputs: ["focusDay", "eventsChanged", "focusDayChanged", "config"], outputs: ["dayClicked"] }, { kind: "component", type: CalendarWeekComponent, selector: "mn-calendar-week", inputs: ["focusDay", "eventsChanged", "focusDayChanged", "config", "calendarEventComponent"], outputs: ["eventClicked"] }, { kind: "component", type: CalendarDayComponent, selector: "mn-calendar-day", inputs: ["focusDay", "eventsChanged", "focusDayChanged", "config", "calendarEventComponent"], outputs: ["eventClicked"] }, { kind: "component", type: UpcomingEventsComponent, selector: "mn-upcoming-events", inputs: ["eventsChanged", "config"], outputs: ["eventClicked"] }, { kind: "component", type: MnButton, selector: "button[mnButton], a[mnButton]", inputs: ["data"] }, { kind: "component", type: MnDatetime, selector: "mn-lib-datetime", inputs: ["props"] }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }] });
|
|
9404
9438
|
}
|
|
9405
9439
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CalendarViewComponent, decorators: [{
|
|
9406
9440
|
type: Component,
|
|
@@ -9417,7 +9451,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
9417
9451
|
LucideChevronRight
|
|
9418
9452
|
], providers: [
|
|
9419
9453
|
provideMnCalendarConfig(DEFAULT_CALENDAR_CONFIG),
|
|
9420
|
-
], template: "<div class=\"w-full h-full flex flex-col\" role=\"application\" aria-label=\"Calendar\">\n\n <!-- Toolbar
|
|
9454
|
+
], template: "<div class=\"w-full h-full flex flex-col\" role=\"application\" aria-label=\"Calendar\">\n\n <!-- Toolbar has one layout below the desktop (`lg`) width and one at it. Below\n `lg`: a controls row (Today anchored left, the right-hand cluster anchored\n right) with the \u2039 date \u203A nav centred on its own row beneath \u2014 the same\n shape from phone through tablet, so nothing wraps into a lopsided diagonal.\n At `lg`, where the upcoming-events sidebar also appears, the nav folds up\n inline after Today and the whole toolbar becomes a single row. The one JS\n breakpoint (`mobileBreakpoint`) governs the phone controls \u2014 icon-only\n picker, hidden view-switcher, forced day view \u2014 not the toolbar's shape. -->\n <div class=\"flex flex-wrap items-center gap-x-3 gap-y-2 py-3\">\n\n <button (click)=\"goToToday()\"\n [data]=\"{ variant: 'outline', size: 'md', color: 'primary' }\"\n class=\"shrink-0\"\n mnButton\n type=\"button\">\n {{ config.todayLabel }}\n </button>\n\n <!-- Stepping through time. The arrows sit either side of the date they move,\n so the control and the thing it controls read as one unit. Below `lg` it\n sits centred on its own row (basis-full, ordered last) \u2014 a period header\n above the grid, tight rather than flinging the arrows to the row's edges.\n At `lg` it folds inline right after Today, taking a stable min-width so\n the arrows don't jitter as the label's length changes. -->\n <div class=\"flex basis-full order-last justify-center items-center gap-1\n lg:basis-auto lg:order-none lg:justify-start\">\n <button (click)=\"navigate(-1)\"\n [attr.aria-label]=\"config.previousLabel\"\n [data]=\"{ variant: 'text', size: 'md', color: 'gray' }\"\n class=\"shrink-0\"\n mnButton\n type=\"button\">\n <svg [size]=\"18\" lucideChevronLeft></svg>\n </button>\n\n <h2 aria-live=\"polite\"\n class=\"text-center text-base font-semibold whitespace-nowrap px-1 lg:min-w-56\">\n {{ periodLabel }}\n </h2>\n\n <button (click)=\"navigate(1)\"\n [attr.aria-label]=\"config.nextLabel\"\n [data]=\"{ variant: 'text', size: 'md', color: 'gray' }\"\n class=\"shrink-0\"\n mnButton\n type=\"button\">\n <svg [size]=\"18\" lucideChevronRight></svg>\n </button>\n </div>\n\n <!-- Right-hand controls travel together as one cluster with `ml-auto`, so they\n hold to the right of the row on every width \u2014 and when space runs short the\n whole group wraps to a new line as a unit rather than stranding a lone\n button. On desktop the cluster lands above the upcoming-events sidebar,\n using that otherwise-empty space. -->\n <div class=\"ml-auto flex items-center gap-2\">\n <!-- On mobile the picker collapses to its icon-only variant. -->\n <mn-lib-datetime (ngModelChange)=\"onPickDate($event)\"\n [ngModel]=\"focusDayString\"\n [props]=\"{ id: panelId + '-date', mode: 'date', placeholder: config.pickDateLabel, size: 'md', borderRadius: 'lg', hover: true, iconOnly: isMobileView }\"\n class=\"block\"></mn-lib-datetime>\n\n <!-- View switcher (month / week / day) \u2014 hidden on mobile, which is forced to day view. -->\n @if (!isMobileView) {\n <div aria-label=\"Calendar view\" class=\"flex border border-base-300 rounded-md overflow-hidden\" role=\"tablist\">\n @for (view of viewOptions; track view.value) {\n <button\n (click)=\"switchView(view.value)\"\n [attr.aria-controls]=\"panelId\"\n [attr.aria-selected]=\"currentView === view.value\"\n [data]=\"{ size: 'md', variant: currentView === view.value ? 'fill' : 'text', color: 'primary' }\"\n mnButton\n role=\"tab\"\n type=\"button\">\n {{ view.label }}\n </button>\n }\n </div>\n }\n\n <!-- Action buttons (custom buttons + optional showButton CTA). -->\n @if (buttons.length || showButton) {\n @for (btn of buttons; track btn.label) {\n <button (click)=\"btn.onClick()\" [data]=\"btn.buttonData || {}\" mnButton type=\"button\">\n {{ btn.label }}\n </button>\n }\n @if (showButton) {\n <button (click)=\"ButtonClickedEvent.emit()\" [data]=\"{}\" mnButton type=\"button\">\n {{ buttonTitle }}\n </button>\n }\n }\n </div>\n\n </div>\n\n <div class=\"grid grid-cols-1 lg:grid-cols-[1fr_220px] gap-3 flex-1 min-h-0\">\n <div [id]=\"panelId\" class=\"min-w-0 min-h-0 overflow-hidden overflow-y-auto\" role=\"tabpanel\">\n @if (currentView === CalendarView.MONTH) {\n <mn-calendar-month\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n (dayClicked)=\"onMonthDayClick($event)\">\n </mn-calendar-month>\n }\n @if (currentView === CalendarView.WEEK) {\n <mn-calendar-week\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n [calendarEventComponent]=\"CalendarEventComponent\"\n (eventClicked)=\"onEventClick($event)\">\n </mn-calendar-week>\n }\n @if (currentView === CalendarView.DAY) {\n <mn-calendar-day\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n [calendarEventComponent]=\"CalendarEventComponent\"\n (eventClicked)=\"onEventClick($event)\">\n </mn-calendar-day>\n }\n </div>\n <div class=\"hidden lg:block border-l border-base-300 overflow-auto\">\n <mn-upcoming-events\n [eventsChanged]=\"internalEventsChanged\"\n [config]=\"config\"\n (eventClicked)=\"onEventClick($event)\">\n </mn-upcoming-events>\n </div>\n </div>\n\n</div>\n", styles: [":host{display:flex;flex-direction:column;width:100%;height:100%}\n"] }]
|
|
9421
9455
|
}], ctorParameters: () => [], propDecorators: { showButton: [{
|
|
9422
9456
|
type: Input
|
|
9423
9457
|
}], buttonTitle: [{
|