@nubitio/ui 0.5.19 → 0.5.22

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.cjs CHANGED
@@ -1010,6 +1010,78 @@ const Badge = ({ variant = "primary", size = "md", outlined = false, pill = true
1010
1010
  });
1011
1011
  };
1012
1012
  //#endregion
1013
+ //#region packages/ui/FeatureGate.tsx
1014
+ function FeatureGate({ featureKey, children, enabled = false, behavior = "lock", planBadge = "Pro", upgradeMessage, upgradeUrl = "/settings", lockTooltip = "Esta función no está disponible en tu plan actual." }) {
1015
+ if (enabled) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1016
+ className: "feature-gate",
1017
+ children
1018
+ });
1019
+ if (behavior === "upgrade") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UpgradeGate, {
1020
+ planBadge,
1021
+ upgradeMessage,
1022
+ upgradeUrl,
1023
+ children
1024
+ });
1025
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1026
+ className: "feature-gate--locked",
1027
+ title: lockTooltip,
1028
+ "aria-label": lockTooltip,
1029
+ role: "presentation",
1030
+ children
1031
+ });
1032
+ }
1033
+ function UpgradeGate({ planBadge, upgradeMessage, upgradeUrl, children }) {
1034
+ const [open, setOpen] = (0, react.useState)(false);
1035
+ const message = upgradeMessage ?? `Esta función requiere el plan ${planBadge}. Actualiza tu plan para desbloquearla.`;
1036
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1037
+ className: "feature-gate--upgrade",
1038
+ onBlur: (e) => {
1039
+ if (!e.currentTarget.contains(e.relatedTarget)) setOpen(false);
1040
+ },
1041
+ children: [
1042
+ children,
1043
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1044
+ role: "button",
1045
+ tabIndex: 0,
1046
+ className: "feature-gate__badge",
1047
+ "aria-expanded": open,
1048
+ onClick: (e) => {
1049
+ e.stopPropagation();
1050
+ setOpen((prev) => !prev);
1051
+ },
1052
+ onKeyDown: (e) => {
1053
+ if (e.key === "Enter" || e.key === " ") {
1054
+ e.preventDefault();
1055
+ setOpen((prev) => !prev);
1056
+ }
1057
+ },
1058
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Badge, {
1059
+ variant: "primary",
1060
+ size: "sm",
1061
+ pill: true,
1062
+ children: planBadge
1063
+ })
1064
+ }),
1065
+ open && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1066
+ className: "feature-gate__prompt",
1067
+ role: "dialog",
1068
+ children: [
1069
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconButton, {
1070
+ icon: "ph ph-x",
1071
+ label: "Cerrar",
1072
+ onClick: () => setOpen(false)
1073
+ }),
1074
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: message }),
1075
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
1076
+ href: upgradeUrl,
1077
+ children: "Ver planes"
1078
+ })
1079
+ ]
1080
+ })
1081
+ ]
1082
+ });
1083
+ }
1084
+ //#endregion
1013
1085
  //#region packages/ui/Skeleton.tsx
1014
1086
  const fmtSize = (v) => v === void 0 ? void 0 : typeof v === "number" ? `${v}px` : v;
1015
1087
  const Skeleton = ({ variant = "rect", width, height, lines = 1, className }) => {
@@ -2611,6 +2683,7 @@ exports.Drawer = Drawer;
2611
2683
  exports.EN_UI_STRINGS = EN_UI_STRINGS;
2612
2684
  exports.ES_UI_STRINGS = ES_UI_STRINGS;
2613
2685
  exports.EmptyState = EmptyState;
2686
+ exports.FeatureGate = FeatureGate;
2614
2687
  exports.FileDropzone = FileDropzone;
2615
2688
  exports.FormField = FormField;
2616
2689
  exports.IconButton = IconButton;
package/dist/index.d.cts CHANGED
@@ -368,6 +368,28 @@ declare const SettingsPanel: ({
368
368
  onClose: _onClose
369
369
  }: SettingsPanelProps) => React$1.JSX.Element;
370
370
  //#endregion
371
+ //#region packages/ui/FeatureGate.d.ts
372
+ interface FeatureGateProps {
373
+ featureKey: string;
374
+ children: React$1.ReactNode;
375
+ enabled?: boolean;
376
+ behavior?: 'lock' | 'upgrade';
377
+ planBadge?: string;
378
+ upgradeMessage?: string;
379
+ upgradeUrl?: string;
380
+ lockTooltip?: string;
381
+ }
382
+ declare function FeatureGate({
383
+ featureKey,
384
+ children,
385
+ enabled,
386
+ behavior,
387
+ planBadge,
388
+ upgradeMessage,
389
+ upgradeUrl,
390
+ lockTooltip
391
+ }: FeatureGateProps): React$1.JSX.Element;
392
+ //#endregion
371
393
  //#region packages/ui/Badge.d.ts
372
394
  type BadgeVariant = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'light' | 'dark';
373
395
  type BadgeSize = 'sm' | 'md';
@@ -879,4 +901,4 @@ interface UiStringsProviderProps {
879
901
  declare const UiStringsProvider: React$1.FC<UiStringsProviderProps>;
880
902
  declare const useUiStrings: () => UiStrings;
881
903
  //#endregion
882
- export { ACCENT_PRESETS, type AccentPreset, AppDialog, type AppDialogProps, AppDropdown, type AppDropdownOption, type AppDropdownProps, type AppDropdownVariant, AppToolbar, type AppToolbarProps, Avatar, type AvatarProps, type AvatarShape, type AvatarSize, Badge, type BadgeProps, type BadgeSize, type BadgeVariant, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Card, type CardProps, Chip, type ChipProps, CollapsibleSection, type CollapsibleSectionProps, ConfirmDialog, type ConfirmDialogProps, ContextMenu, type ContextMenuItem, type ContextMenuProps, DatePicker, type DatePickerProps, DateRangePicker, type DateRangePickerProps, type Density, DensityContext, type DensityContextValue, DensityProvider, Drawer, type DrawerProps, type DrawerSide, EN_UI_STRINGS, ES_UI_STRINGS, EmptyState, type EmptyStateProps, FileDropzone, type FileDropzoneLabels, type FileDropzoneProps, type FileDropzoneValue, FormField, type FormFieldProps, IconButton, type IconButtonProps, Popover, type PopoverAlign, type PopoverProps, SelectField, type SelectFieldProps, SettingsPanel, type SettingsPanelProps, Skeleton, type SkeletonProps, StatCard, type StatCardProps, TextAreaField, type TextAreaFieldProps, TextField, type TextFieldProps, type Theme, ThemeContext, type ThemeContextValue, type ThemeMode, ThemeProvider, type ThemeProviderProps, ThemeSwitcher, type ThemeSwitcherProps, Timeline, TimelineItem, type TimelineItemProps, type TimelineItemStatus, type TimelineItemTone, type TimelineOrientation, type TimelineProps, type TimelineVariant, Toggle, type ToggleProps, type UiStrings, UiStringsProvider, type UiStringsProviderProps, type UseFloatingPanelOptions, type UseFloatingPanelResult, getAvatarHue, getAvatarInitials, useAccentColor, useDensity, useFloatingPanel, useTheme, useUiStrings };
904
+ export { ACCENT_PRESETS, type AccentPreset, AppDialog, type AppDialogProps, AppDropdown, type AppDropdownOption, type AppDropdownProps, type AppDropdownVariant, AppToolbar, type AppToolbarProps, Avatar, type AvatarProps, type AvatarShape, type AvatarSize, Badge, type BadgeProps, type BadgeSize, type BadgeVariant, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Card, type CardProps, Chip, type ChipProps, CollapsibleSection, type CollapsibleSectionProps, ConfirmDialog, type ConfirmDialogProps, ContextMenu, type ContextMenuItem, type ContextMenuProps, DatePicker, type DatePickerProps, DateRangePicker, type DateRangePickerProps, type Density, DensityContext, type DensityContextValue, DensityProvider, Drawer, type DrawerProps, type DrawerSide, EN_UI_STRINGS, ES_UI_STRINGS, EmptyState, type EmptyStateProps, FeatureGate, type FeatureGateProps, FileDropzone, type FileDropzoneLabels, type FileDropzoneProps, type FileDropzoneValue, FormField, type FormFieldProps, IconButton, type IconButtonProps, Popover, type PopoverAlign, type PopoverProps, SelectField, type SelectFieldProps, SettingsPanel, type SettingsPanelProps, Skeleton, type SkeletonProps, StatCard, type StatCardProps, TextAreaField, type TextAreaFieldProps, TextField, type TextFieldProps, type Theme, ThemeContext, type ThemeContextValue, type ThemeMode, ThemeProvider, type ThemeProviderProps, ThemeSwitcher, type ThemeSwitcherProps, Timeline, TimelineItem, type TimelineItemProps, type TimelineItemStatus, type TimelineItemTone, type TimelineOrientation, type TimelineProps, type TimelineVariant, Toggle, type ToggleProps, type UiStrings, UiStringsProvider, type UiStringsProviderProps, type UseFloatingPanelOptions, type UseFloatingPanelResult, getAvatarHue, getAvatarInitials, useAccentColor, useDensity, useFloatingPanel, useTheme, useUiStrings };
package/dist/index.d.mts CHANGED
@@ -368,6 +368,28 @@ declare const SettingsPanel: ({
368
368
  onClose: _onClose
369
369
  }: SettingsPanelProps) => React$1.JSX.Element;
370
370
  //#endregion
371
+ //#region packages/ui/FeatureGate.d.ts
372
+ interface FeatureGateProps {
373
+ featureKey: string;
374
+ children: React$1.ReactNode;
375
+ enabled?: boolean;
376
+ behavior?: 'lock' | 'upgrade';
377
+ planBadge?: string;
378
+ upgradeMessage?: string;
379
+ upgradeUrl?: string;
380
+ lockTooltip?: string;
381
+ }
382
+ declare function FeatureGate({
383
+ featureKey,
384
+ children,
385
+ enabled,
386
+ behavior,
387
+ planBadge,
388
+ upgradeMessage,
389
+ upgradeUrl,
390
+ lockTooltip
391
+ }: FeatureGateProps): React$1.JSX.Element;
392
+ //#endregion
371
393
  //#region packages/ui/Badge.d.ts
372
394
  type BadgeVariant = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'light' | 'dark';
373
395
  type BadgeSize = 'sm' | 'md';
@@ -879,4 +901,4 @@ interface UiStringsProviderProps {
879
901
  declare const UiStringsProvider: React$1.FC<UiStringsProviderProps>;
880
902
  declare const useUiStrings: () => UiStrings;
881
903
  //#endregion
882
- export { ACCENT_PRESETS, type AccentPreset, AppDialog, type AppDialogProps, AppDropdown, type AppDropdownOption, type AppDropdownProps, type AppDropdownVariant, AppToolbar, type AppToolbarProps, Avatar, type AvatarProps, type AvatarShape, type AvatarSize, Badge, type BadgeProps, type BadgeSize, type BadgeVariant, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Card, type CardProps, Chip, type ChipProps, CollapsibleSection, type CollapsibleSectionProps, ConfirmDialog, type ConfirmDialogProps, ContextMenu, type ContextMenuItem, type ContextMenuProps, DatePicker, type DatePickerProps, DateRangePicker, type DateRangePickerProps, type Density, DensityContext, type DensityContextValue, DensityProvider, Drawer, type DrawerProps, type DrawerSide, EN_UI_STRINGS, ES_UI_STRINGS, EmptyState, type EmptyStateProps, FileDropzone, type FileDropzoneLabels, type FileDropzoneProps, type FileDropzoneValue, FormField, type FormFieldProps, IconButton, type IconButtonProps, Popover, type PopoverAlign, type PopoverProps, SelectField, type SelectFieldProps, SettingsPanel, type SettingsPanelProps, Skeleton, type SkeletonProps, StatCard, type StatCardProps, TextAreaField, type TextAreaFieldProps, TextField, type TextFieldProps, type Theme, ThemeContext, type ThemeContextValue, type ThemeMode, ThemeProvider, type ThemeProviderProps, ThemeSwitcher, type ThemeSwitcherProps, Timeline, TimelineItem, type TimelineItemProps, type TimelineItemStatus, type TimelineItemTone, type TimelineOrientation, type TimelineProps, type TimelineVariant, Toggle, type ToggleProps, type UiStrings, UiStringsProvider, type UiStringsProviderProps, type UseFloatingPanelOptions, type UseFloatingPanelResult, getAvatarHue, getAvatarInitials, useAccentColor, useDensity, useFloatingPanel, useTheme, useUiStrings };
904
+ export { ACCENT_PRESETS, type AccentPreset, AppDialog, type AppDialogProps, AppDropdown, type AppDropdownOption, type AppDropdownProps, type AppDropdownVariant, AppToolbar, type AppToolbarProps, Avatar, type AvatarProps, type AvatarShape, type AvatarSize, Badge, type BadgeProps, type BadgeSize, type BadgeVariant, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Card, type CardProps, Chip, type ChipProps, CollapsibleSection, type CollapsibleSectionProps, ConfirmDialog, type ConfirmDialogProps, ContextMenu, type ContextMenuItem, type ContextMenuProps, DatePicker, type DatePickerProps, DateRangePicker, type DateRangePickerProps, type Density, DensityContext, type DensityContextValue, DensityProvider, Drawer, type DrawerProps, type DrawerSide, EN_UI_STRINGS, ES_UI_STRINGS, EmptyState, type EmptyStateProps, FeatureGate, type FeatureGateProps, FileDropzone, type FileDropzoneLabels, type FileDropzoneProps, type FileDropzoneValue, FormField, type FormFieldProps, IconButton, type IconButtonProps, Popover, type PopoverAlign, type PopoverProps, SelectField, type SelectFieldProps, SettingsPanel, type SettingsPanelProps, Skeleton, type SkeletonProps, StatCard, type StatCardProps, TextAreaField, type TextAreaFieldProps, TextField, type TextFieldProps, type Theme, ThemeContext, type ThemeContextValue, type ThemeMode, ThemeProvider, type ThemeProviderProps, ThemeSwitcher, type ThemeSwitcherProps, Timeline, TimelineItem, type TimelineItemProps, type TimelineItemStatus, type TimelineItemTone, type TimelineOrientation, type TimelineProps, type TimelineVariant, Toggle, type ToggleProps, type UiStrings, UiStringsProvider, type UiStringsProviderProps, type UseFloatingPanelOptions, type UseFloatingPanelResult, getAvatarHue, getAvatarInitials, useAccentColor, useDensity, useFloatingPanel, useTheme, useUiStrings };
package/dist/index.mjs CHANGED
@@ -986,6 +986,78 @@ const Badge = ({ variant = "primary", size = "md", outlined = false, pill = true
986
986
  });
987
987
  };
988
988
  //#endregion
989
+ //#region packages/ui/FeatureGate.tsx
990
+ function FeatureGate({ featureKey, children, enabled = false, behavior = "lock", planBadge = "Pro", upgradeMessage, upgradeUrl = "/settings", lockTooltip = "Esta función no está disponible en tu plan actual." }) {
991
+ if (enabled) return /* @__PURE__ */ jsx("div", {
992
+ className: "feature-gate",
993
+ children
994
+ });
995
+ if (behavior === "upgrade") return /* @__PURE__ */ jsx(UpgradeGate, {
996
+ planBadge,
997
+ upgradeMessage,
998
+ upgradeUrl,
999
+ children
1000
+ });
1001
+ return /* @__PURE__ */ jsx("div", {
1002
+ className: "feature-gate--locked",
1003
+ title: lockTooltip,
1004
+ "aria-label": lockTooltip,
1005
+ role: "presentation",
1006
+ children
1007
+ });
1008
+ }
1009
+ function UpgradeGate({ planBadge, upgradeMessage, upgradeUrl, children }) {
1010
+ const [open, setOpen] = useState(false);
1011
+ const message = upgradeMessage ?? `Esta función requiere el plan ${planBadge}. Actualiza tu plan para desbloquearla.`;
1012
+ return /* @__PURE__ */ jsxs("div", {
1013
+ className: "feature-gate--upgrade",
1014
+ onBlur: (e) => {
1015
+ if (!e.currentTarget.contains(e.relatedTarget)) setOpen(false);
1016
+ },
1017
+ children: [
1018
+ children,
1019
+ /* @__PURE__ */ jsx("span", {
1020
+ role: "button",
1021
+ tabIndex: 0,
1022
+ className: "feature-gate__badge",
1023
+ "aria-expanded": open,
1024
+ onClick: (e) => {
1025
+ e.stopPropagation();
1026
+ setOpen((prev) => !prev);
1027
+ },
1028
+ onKeyDown: (e) => {
1029
+ if (e.key === "Enter" || e.key === " ") {
1030
+ e.preventDefault();
1031
+ setOpen((prev) => !prev);
1032
+ }
1033
+ },
1034
+ children: /* @__PURE__ */ jsx(Badge, {
1035
+ variant: "primary",
1036
+ size: "sm",
1037
+ pill: true,
1038
+ children: planBadge
1039
+ })
1040
+ }),
1041
+ open && /* @__PURE__ */ jsxs("div", {
1042
+ className: "feature-gate__prompt",
1043
+ role: "dialog",
1044
+ children: [
1045
+ /* @__PURE__ */ jsx(IconButton, {
1046
+ icon: "ph ph-x",
1047
+ label: "Cerrar",
1048
+ onClick: () => setOpen(false)
1049
+ }),
1050
+ /* @__PURE__ */ jsx("p", { children: message }),
1051
+ /* @__PURE__ */ jsx("a", {
1052
+ href: upgradeUrl,
1053
+ children: "Ver planes"
1054
+ })
1055
+ ]
1056
+ })
1057
+ ]
1058
+ });
1059
+ }
1060
+ //#endregion
989
1061
  //#region packages/ui/Skeleton.tsx
990
1062
  const fmtSize = (v) => v === void 0 ? void 0 : typeof v === "number" ? `${v}px` : v;
991
1063
  const Skeleton = ({ variant = "rect", width, height, lines = 1, className }) => {
@@ -2567,4 +2639,4 @@ function Timeline({ variant = "stepper", orientation = "vertical", title, descri
2567
2639
  });
2568
2640
  }
2569
2641
  //#endregion
2570
- export { ACCENT_PRESETS, AppDialog, AppDropdown, AppToolbar, Avatar, Badge, Button, Card, Chip, CollapsibleSection, ConfirmDialog, ContextMenu, DatePicker, DateRangePicker, DensityContext, DensityProvider, Drawer, EN_UI_STRINGS, ES_UI_STRINGS, EmptyState, FileDropzone, FormField, IconButton, Popover, SelectField, SettingsPanel, Skeleton, StatCard, TextAreaField, TextField, ThemeContext, ThemeProvider, ThemeSwitcher, Timeline, TimelineItem, Toggle, UiStringsProvider, getAvatarHue, getAvatarInitials, useAccentColor, useDensity, useFloatingPanel, useTheme, useUiStrings };
2642
+ export { ACCENT_PRESETS, AppDialog, AppDropdown, AppToolbar, Avatar, Badge, Button, Card, Chip, CollapsibleSection, ConfirmDialog, ContextMenu, DatePicker, DateRangePicker, DensityContext, DensityProvider, Drawer, EN_UI_STRINGS, ES_UI_STRINGS, EmptyState, FeatureGate, FileDropzone, FormField, IconButton, Popover, SelectField, SettingsPanel, Skeleton, StatCard, TextAreaField, TextField, ThemeContext, ThemeProvider, ThemeSwitcher, Timeline, TimelineItem, Toggle, UiStringsProvider, getAvatarHue, getAvatarInitials, useAccentColor, useDensity, useFloatingPanel, useTheme, useUiStrings };
package/dist/style.css CHANGED
@@ -1401,6 +1401,36 @@ html[data-density=compact] .nb-badge--sm {
1401
1401
  min-height: 14px;
1402
1402
  padding: 0 var(--space-1);
1403
1403
  }
1404
+ .feature-gate--locked {
1405
+ opacity: 0.55;
1406
+ pointer-events: none;
1407
+ filter: grayscale(0.2);
1408
+ }
1409
+
1410
+ .feature-gate--upgrade {
1411
+ position: relative;
1412
+ display: inline-flex;
1413
+ align-items: flex-start;
1414
+ gap: 0.5rem;
1415
+ }
1416
+
1417
+ .feature-gate__badge {
1418
+ cursor: pointer;
1419
+ }
1420
+
1421
+ .feature-gate__prompt {
1422
+ position: absolute;
1423
+ top: 100%;
1424
+ right: 0;
1425
+ z-index: 20;
1426
+ margin-top: 0.5rem;
1427
+ min-width: 220px;
1428
+ padding: 0.75rem;
1429
+ border-radius: 0.5rem;
1430
+ background: var(--surface-elevated, #fff);
1431
+ border: 1px solid var(--border-subtle, #e5e7eb);
1432
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
1433
+ }
1404
1434
  @keyframes nb-skeleton-shimmer {
1405
1435
  0% {
1406
1436
  background-position: 200% 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nubitio/ui",
3
- "version": "0.5.19",
3
+ "version": "0.5.22",
4
4
  "type": "module",
5
5
  "description": "Visual primitives and theme system for the Nubit admin stack (dialogs, cards, toolbar, light/dark theme).",
6
6
  "license": "MIT",