@ziyarago/ui 0.2.0 → 0.4.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.
Files changed (120) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +24 -2
  3. package/dist/llms-full.txt +101 -9
  4. package/dist/llms.txt +2 -2
  5. package/dist/manifest.json +412 -20
  6. package/dist/style.css +73 -4
  7. package/docs/INTEGRATION.md +153 -0
  8. package/docs/MIGRATION.md +453 -0
  9. package/package.json +88 -8
  10. package/src/compat/index.js +468 -0
  11. package/src/compat/map.js +282 -0
  12. package/src/compat/resolver.js +22 -0
  13. package/src/compat/vite.js +29 -0
  14. package/src/core/bools.js +4 -0
  15. package/src/core/components.js +40 -31
  16. package/src/core/components2.js +52 -47
  17. package/src/core/components3.js +8 -7
  18. package/src/core/components4.js +25 -24
  19. package/src/core/components6.js +30 -20
  20. package/src/core/components7.js +10 -9
  21. package/src/core/index.js +2 -0
  22. package/src/i18n/components/ActionCard.js +5 -0
  23. package/src/i18n/components/Actionsheet.js +5 -0
  24. package/src/i18n/components/Alert.js +5 -0
  25. package/src/i18n/components/Breadcrumbs.js +5 -0
  26. package/src/i18n/components/Calendar.js +5 -0
  27. package/src/i18n/components/CallCard.js +5 -0
  28. package/src/i18n/components/CallRow.js +5 -0
  29. package/src/i18n/components/Carousel.js +5 -0
  30. package/src/i18n/components/ChartCard.js +5 -0
  31. package/src/i18n/components/ChatAi.js +5 -0
  32. package/src/i18n/components/Chip.js +5 -0
  33. package/src/i18n/components/ChipInput.js +5 -0
  34. package/src/i18n/components/CodeInput.js +5 -0
  35. package/src/i18n/components/Combobox.js +5 -0
  36. package/src/i18n/components/CommandPalette.js +5 -0
  37. package/src/i18n/components/ConfirmDialog.js +5 -0
  38. package/src/i18n/components/ContactPanel.js +5 -0
  39. package/src/i18n/components/CopyButton.js +5 -0
  40. package/src/i18n/components/DataGroup.js +5 -0
  41. package/src/i18n/components/DataState.js +5 -0
  42. package/src/i18n/components/DataTable.js +5 -0
  43. package/src/i18n/components/DatePicker.js +5 -0
  44. package/src/i18n/components/DealCard.js +5 -0
  45. package/src/i18n/components/Drawer.js +5 -0
  46. package/src/i18n/components/ErrorPage.js +5 -0
  47. package/src/i18n/components/FileUpload.js +5 -0
  48. package/src/i18n/components/FullscreenDialog.js +5 -0
  49. package/src/i18n/components/Gallery.js +5 -0
  50. package/src/i18n/components/GuestCard.js +5 -0
  51. package/src/i18n/components/ImageUpload.js +5 -0
  52. package/src/i18n/components/ImageViewer.js +5 -0
  53. package/src/i18n/components/IncomingCall.js +5 -0
  54. package/src/i18n/components/InlineEdit.js +5 -0
  55. package/src/i18n/components/IntegrationCard.js +5 -0
  56. package/src/i18n/components/LoginForm.js +5 -0
  57. package/src/i18n/components/Map.js +5 -0
  58. package/src/i18n/components/Modal.js +5 -0
  59. package/src/i18n/components/MultiSelect.js +5 -0
  60. package/src/i18n/components/NotificationBell.js +5 -0
  61. package/src/i18n/components/NumberInput.js +5 -0
  62. package/src/i18n/components/Pagination.js +5 -0
  63. package/src/i18n/components/PasswordInput.js +5 -0
  64. package/src/i18n/components/Popconfirm.js +5 -0
  65. package/src/i18n/components/PricingCard.js +5 -0
  66. package/src/i18n/components/RamadanTracker.js +5 -0
  67. package/src/i18n/components/RangeCalendar.js +5 -0
  68. package/src/i18n/components/RangeSlider.js +5 -0
  69. package/src/i18n/components/Rating.js +5 -0
  70. package/src/i18n/components/RichEditor.js +5 -0
  71. package/src/i18n/components/Screensaver.js +5 -0
  72. package/src/i18n/components/SearchInput.js +5 -0
  73. package/src/i18n/components/SideNav.js +5 -0
  74. package/src/i18n/components/Snackbar.js +5 -0
  75. package/src/i18n/components/Sortable.js +5 -0
  76. package/src/i18n/components/Spinner.js +5 -0
  77. package/src/i18n/components/StatusPage.js +5 -0
  78. package/src/i18n/components/StepDialog.js +5 -0
  79. package/src/i18n/components/StepForm.js +5 -0
  80. package/src/i18n/components/TabTiles.js +5 -0
  81. package/src/i18n/components/Tag.js +5 -0
  82. package/src/i18n/components/TopNav.js +5 -0
  83. package/src/i18n/components/Tour.js +5 -0
  84. package/src/i18n/components/TourCard.js +5 -0
  85. package/src/i18n/components/TourPopover.js +5 -0
  86. package/src/i18n/components/TreeSelect.js +5 -0
  87. package/src/i18n/components/Validation.js +5 -0
  88. package/src/i18n/components/index.js +135 -0
  89. package/src/i18n/index.js +50 -0
  90. package/src/meta/actions.js +10 -3
  91. package/src/meta/data.js +8 -3
  92. package/src/meta/feedback.js +2 -1
  93. package/src/meta/forms.js +44 -4
  94. package/src/meta/media.js +7 -2
  95. package/src/meta/navigation.js +3 -0
  96. package/src/meta/overlay.js +8 -2
  97. package/src/nuxt/module.mjs +2 -2
  98. package/src/nuxt/plugin.mjs +6 -5
  99. package/src/react/index.js +202 -8
  100. package/src/resolver.js +33 -0
  101. package/src/styles/components.css +7 -0
  102. package/src/styles/components6.css +2 -0
  103. package/src/styles/effects.css +6 -4
  104. package/src/styles/extras.css +55 -0
  105. package/src/styles/index.css +1 -0
  106. package/src/theme.js +16 -4
  107. package/src/vue/global.js +2 -0
  108. package/src/vue/index.js +13 -5
  109. package/types/compat-resolver.d.ts +12 -0
  110. package/types/compat-vite.d.ts +11 -0
  111. package/types/compat.d.ts +176 -0
  112. package/types/i18n.d.ts +14 -0
  113. package/types/meta.d.ts +4 -0
  114. package/types/nuxt.d.ts +1 -1
  115. package/types/react.d.ts +6282 -186
  116. package/types/resolver.d.ts +14 -0
  117. package/types/shared.d.ts +7 -7
  118. package/types/theme.d.ts +20 -1
  119. package/types/vue-global.d.ts +193 -0
  120. package/types/vue.d.ts +6178 -186
@@ -1,12 +1,14 @@
1
+ 'use client';
1
2
  // React 18+ adapter. Usage: import { UiButton, UiAppShell } from '@ziyarago/ui/react'
2
- import React, { useState, createElement, cloneElement, isValidElement } from 'react';
3
+ import React, { useState, useRef, useEffect, useLayoutEffect, useSyncExternalStore, createElement, cloneElement, isValidElement } from 'react';
3
4
  import { createPortal } from 'react-dom';
4
- import { components } from '../core/index.js';
5
+ import { components, subscribeUiLocale, getUiVersion } from '../core/index.js';
5
6
 
6
7
  const C = {};
7
- const EV = { keydown: 'KeyDown', keyup: 'KeyUp', dragenter: 'DragEnter', dragover: 'DragOver', dragleave: 'DragLeave', pointerdown: 'PointerDown', pointerup: 'PointerUp', pointermove: 'PointerMove', mousedown: 'MouseDown', mouseup: 'MouseUp', mouseenter: 'MouseEnter', mouseleave: 'MouseLeave' };
8
+ const useIsoLayoutEffect = typeof document === 'undefined' ? useEffect : useLayoutEffect;
9
+ const EV = { keydown: 'KeyDown', keyup: 'KeyUp', dragenter: 'DragEnter', dragover: 'DragOver', dragleave: 'DragLeave', pointerdown: 'PointerDown', pointerup: 'PointerUp', pointermove: 'PointerMove', mousedown: 'MouseDown', mouseup: 'MouseUp', mouseenter: 'MouseEnter', mouseleave: 'MouseLeave', mousemove: 'MouseMove', mouseover: 'MouseOver', mouseout: 'MouseOut', dragstart: 'DragStart', dragend: 'DragEnd', dblclick: 'DoubleClick', contextmenu: 'ContextMenu', pointerenter: 'PointerEnter', pointerleave: 'PointerLeave', pointercancel: 'PointerCancel', touchstart: 'TouchStart', touchend: 'TouchEnd', touchmove: 'TouchMove', focusin: 'FocusIn', focusout: 'FocusOut' };
8
10
  const hh = (t, p, ...k) => {
9
- if (p && typeof t === 'string') { const q = {}; for (const key in p) { const m = /^on([a-z]+)$/.exec(key); q[m && EV[m[1]] ? 'on' + EV[m[1]] : key] = p[key]; } p = q; }
11
+ if (p && typeof t === 'string') { const q = {}; for (const key in p) { const m = /^on([A-Za-z]+)$/.exec(key), n = m && EV[m[1].toLowerCase()]; q[n ? 'on' + n : key] = p[key]; } p = q; }
10
12
  if (p && 'class' in p) { const { class: cls, ...rest } = p; p = { ...rest, className: cls }; }
11
13
  if (p) { const q = {}; for (const key in p) q[/^(aria|data)-/.test(key) || !key.includes('-') ? key : key.replace(/-(\w)/g, (_, c) => c.toUpperCase())] = p[key]; p = q; }
12
14
  if (p && typeof p.innerHTML === 'string') { const { innerHTML, ...rest } = p; p = { ...rest, dangerouslySetInnerHTML: { __html: innerHTML }, suppressContentEditableWarning: true }; }
@@ -14,18 +16,210 @@ const hh = (t, p, ...k) => {
14
16
  };
15
17
  const wrap = (name, def) => {
16
18
  const Comp = ({ children, ...props }) => {
19
+ useSyncExternalStore(subscribeUiLocale, getUiVersion, () => 0);
17
20
  const [state, setState] = useState({ ...(def.state || {}) });
18
21
  const set = o => setState(s => ({ ...s, ...o }));
22
+ // Portals must not render on the server pass or during hydration (React throws a hydration mismatch): the first render returns null
23
+ // and, only if portal() was asked for, a layout effect re-renders once mounted.
24
+ const mounted = useRef(false), wantPortal = useRef(false), [, bump] = useState(0);
25
+ useIsoLayoutEffect(() => { mounted.current = true; if (wantPortal.current) bump(n => n + 1); }, []);
19
26
  const slots = {}; for (const k of [...(def.slots || []), 'actions', 'footer']) if (props[k] !== undefined) slots[k] = props[k];
20
27
  if (props.onChange === undefined && props.onValueChange) props.onChange = props.onValueChange;
21
- const out = def.render({ C, h: hh, props, children: React.Children.toArray(children), slots, state, set, portal: (kids, to) => typeof document === 'undefined' ? null : createPortal(kids, (typeof to === 'string' ? document.querySelector(to) : to) || document.body) });
22
- return props.size && isValidElement(out) && typeof out.type === 'string' ? cloneElement(out, { 'data-size': props.size }) : out;
28
+ const out = def.render({ C, h: hh, props, children: React.Children.toArray(children), slots, state, set, portal: (kids, to) => { if (!mounted.current) { wantPortal.current = true; return null; } return createPortal(kids, (typeof to === 'string' ? document.querySelector(to) : to) || document.body); } });
29
+ if (!isValidElement(out) || typeof out.type !== 'string') return out;
30
+ const root = {}; for (const k in props) if (/^(aria|data)-|^id$/.test(k)) root[k] = props[k];
31
+ if (props.size) root['data-size'] = props.size;
32
+ if (props.className) root.className = [out.props.className, props.className].filter(Boolean).join(' ');
33
+ if (props.style && typeof props.style === 'object') root.style = { ...out.props.style, ...props.style };
34
+ return Object.keys(root).length ? cloneElement(out, root) : out;
23
35
  };
24
36
  Comp.displayName = 'Ui' + name;
25
37
  return Comp;
26
38
  };
27
39
  for (const [name, def] of Object.entries(components)) C[name] = wrap(name, def);
28
40
 
29
- export const { Button: UiButton, IconButton: UiIconButton, Badge: UiBadge, Avatar: UiAvatar, Switch: UiSwitch, Checkbox: UiCheckbox, SegmentedControl: UiSegmentedControl, Tabs: UiTabs, FilterChips: UiFilterChips, TextField: UiTextField, Select: UiSelect, CodeInput: UiCodeInput, Stepper: UiStepper, Card: UiCard, Modal: UiModal, Drawer: UiDrawer, Toast: UiToast, Breadcrumbs: UiBreadcrumbs, Pagination: UiPagination, Progress: UiProgress, Ring: UiRing, KpiTile: UiKpiTile, DataTable: UiDataTable, KanbanColumn: UiKanbanColumn, KanbanCard: UiKanbanCard, Timeline: UiTimeline, TopNav: UiTopNav, SideNav: UiSideNav, AppShell: UiAppShell, PageHeader: UiPageHeader, AuthLayout: UiAuthLayout, LeadCard: UiLeadCard, HotelCard: UiHotelCard, TourCard: UiTourCard, PrayerTimes: UiPrayerTimes, RamadanTracker: UiRamadanTracker, CallRow: UiCallRow, Alert: UiAlert, Banner: UiBanner, Accordion: UiAccordion, Skeleton: UiSkeleton, Spinner: UiSpinner, Divider: UiDivider, EmptyState: UiEmptyState, ErrorPage: UiErrorPage, DataState: UiDataState, LoadingOverlay: UiLoadingOverlay, ConfirmDialog: UiConfirmDialog, Popconfirm: UiPopconfirm, Carousel: UiCarousel, Gallery: UiGallery, Code: UiCode, PricingCard: UiPricingCard, IntegrationCard: UiIntegrationCard, IncomingCall: UiIncomingCall, CallCard: UiCallCard, Dropdown: UiDropdown, Menu: UiMenu, Tooltip: UiTooltip, HoverCard: UiHoverCard, Popover: UiPopover, CopyButton: UiCopyButton, CommandBar: UiCommandBar, CommandPalette: UiCommandPalette, NotificationBell: UiNotificationBell, ToggleGroup: UiToggleGroup, Fab: UiFab, Textarea: UiTextarea, NumberInput: UiNumberInput, PasswordInput: UiPasswordInput, SearchInput: UiSearchInput, RadioGroup: UiRadioGroup, Slider: UiSlider, Rating: UiRating, ChipInput: UiChipInput, InlineEdit: UiInlineEdit, ColorPicker: UiColorPicker, FileUpload: UiFileUpload, Combobox: UiCombobox, MultiSelect: UiMultiSelect, GroupedSelect: UiGroupedSelect, PhoneInput: UiPhoneInput, Calendar: UiCalendar, DatePicker: UiDatePicker, TimePicker: UiTimePicker, FormField: UiFormField, LoginForm: UiLoginForm, StepForm: UiStepForm, Tag: UiTag, Kbd: UiKbd, StatsCard: UiStatsCard, KpiInline: UiKpiInline, MiniChart: UiMiniChart, Descriptions: UiDescriptions, LazyImage: UiLazyImage, SystemStatus: UiSystemStatus, TreeView: UiTreeView, CalendarView: UiCalendarView, SubNav: UiSubNav, ActionRail: UiActionRail, SplitLayout: UiSplitLayout, SettingsSection: UiSettingsSection, ScrollArea: UiScrollArea, DealCard: UiDealCard, PipelineBoard: UiPipelineBoard, ContactPanel: UiContactPanel, SalesFunnel: UiSalesFunnel, BookingCard: UiBookingCard, GuestCard: UiGuestCard, RoomGrid: UiRoomGrid, RoomCalendar: UiRoomCalendar, OccupancyChart: UiOccupancyChart, Chip: UiChip, IconTile: UiIconTile, StatusIcon: UiStatusIcon, UserCell: UiUserCell, StatRow: UiStatRow, CountryRow: UiCountryRow, StatLine: UiStatLine, StatStrip: UiStatStrip, VersusBar: UiVersusBar, SegBar: UiSegBar, HeroBanner: UiHeroBanner, TabTiles: UiTabTiles, PillTabs: UiPillTabs, PillSelect: UiPillSelect, ChartCard: UiChartCard, ActionCard: UiActionCard, Snackbar: UiSnackbar, TourPopover: UiTourPopover, ProfileHeader: UiProfileHeader, AuthSplit: UiAuthSplit, StatusPage: UiStatusPage, ValidatedField: UiValidatedField, Footer: UiFooter, DataGroup: UiDataGroup, OptionCard: UiOptionCard, OptionCards: UiOptionCards, RichEditor: UiRichEditor, RangeSlider: UiRangeSlider, RangeCalendar: UiRangeCalendar, StepDialog: UiStepDialog, FullscreenDialog: UiFullscreenDialog, PageDashboard: UiPageDashboard, PagePatterns: UiPagePatterns, PageCrm: UiPageCrm, PageBookings: UiPageBookings, PageCatalog: UiPageCatalog, PageDetail: UiPageDetail, PageSettings: UiPageSettings, PageUserList: UiPageUserList, PageProfile: UiPageProfile, PageForm: UiPageForm, PageOrder: UiPageOrder, PageAccount: UiPageAccount, PagePricing: UiPagePricing, PageFaq: UiPageFaq, PageAuth: UiPageAuth, PageStatus: UiPageStatus, TreeSelect: UiTreeSelect, ContextMenu: UiContextMenu, Sortable: UiSortable, Map: UiMap, ImageUpload: UiImageUpload, Screensaver: UiScreensaver, Tour: UiTour, Heading: UiHeading, Text: UiText, Box: UiBox, Center: UiCenter, HStack: UiHStack, VStack: UiVStack, Grid: UiGrid, Link: UiLink, Pressable: UiPressable, Icon: UiIcon, Portal: UiPortal, LiquidGlass: UiLiquidGlass, BottomSheet: UiBottomSheet, Actionsheet: UiActionsheet, ImageViewer: UiImageViewer, ChatAi: UiChatAi } = C;
30
- export { fmt, setIconBase, rules } from '../core/index.js';
41
+ // Explicit named exports (not destructuring): Next.js reads the export names of a 'use client' module statically.
42
+ export const UiButton = C.Button;
43
+ export const UiIconButton = C.IconButton;
44
+ export const UiBadge = C.Badge;
45
+ export const UiAvatar = C.Avatar;
46
+ export const UiSwitch = C.Switch;
47
+ export const UiCheckbox = C.Checkbox;
48
+ export const UiSegmentedControl = C.SegmentedControl;
49
+ export const UiTabs = C.Tabs;
50
+ export const UiFilterChips = C.FilterChips;
51
+ export const UiTextField = C.TextField;
52
+ export const UiSelect = C.Select;
53
+ export const UiCodeInput = C.CodeInput;
54
+ export const UiStepper = C.Stepper;
55
+ export const UiCard = C.Card;
56
+ export const UiModal = C.Modal;
57
+ export const UiDrawer = C.Drawer;
58
+ export const UiToast = C.Toast;
59
+ export const UiBreadcrumbs = C.Breadcrumbs;
60
+ export const UiPagination = C.Pagination;
61
+ export const UiProgress = C.Progress;
62
+ export const UiRing = C.Ring;
63
+ export const UiKpiTile = C.KpiTile;
64
+ export const UiDataTable = C.DataTable;
65
+ export const UiKanbanColumn = C.KanbanColumn;
66
+ export const UiKanbanCard = C.KanbanCard;
67
+ export const UiTimeline = C.Timeline;
68
+ export const UiTopNav = C.TopNav;
69
+ export const UiSideNav = C.SideNav;
70
+ export const UiAppShell = C.AppShell;
71
+ export const UiPageHeader = C.PageHeader;
72
+ export const UiAuthLayout = C.AuthLayout;
73
+ export const UiLeadCard = C.LeadCard;
74
+ export const UiHotelCard = C.HotelCard;
75
+ export const UiTourCard = C.TourCard;
76
+ export const UiPrayerTimes = C.PrayerTimes;
77
+ export const UiRamadanTracker = C.RamadanTracker;
78
+ export const UiCallRow = C.CallRow;
79
+ export const UiAlert = C.Alert;
80
+ export const UiBanner = C.Banner;
81
+ export const UiAccordion = C.Accordion;
82
+ export const UiSkeleton = C.Skeleton;
83
+ export const UiSpinner = C.Spinner;
84
+ export const UiDivider = C.Divider;
85
+ export const UiEmptyState = C.EmptyState;
86
+ export const UiErrorPage = C.ErrorPage;
87
+ export const UiDataState = C.DataState;
88
+ export const UiLoadingOverlay = C.LoadingOverlay;
89
+ export const UiConfirmDialog = C.ConfirmDialog;
90
+ export const UiPopconfirm = C.Popconfirm;
91
+ export const UiCarousel = C.Carousel;
92
+ export const UiGallery = C.Gallery;
93
+ export const UiCode = C.Code;
94
+ export const UiPricingCard = C.PricingCard;
95
+ export const UiIntegrationCard = C.IntegrationCard;
96
+ export const UiIncomingCall = C.IncomingCall;
97
+ export const UiCallCard = C.CallCard;
98
+ export const UiDropdown = C.Dropdown;
99
+ export const UiMenu = C.Menu;
100
+ export const UiTooltip = C.Tooltip;
101
+ export const UiHoverCard = C.HoverCard;
102
+ export const UiPopover = C.Popover;
103
+ export const UiCopyButton = C.CopyButton;
104
+ export const UiCommandBar = C.CommandBar;
105
+ export const UiCommandPalette = C.CommandPalette;
106
+ export const UiNotificationBell = C.NotificationBell;
107
+ export const UiToggleGroup = C.ToggleGroup;
108
+ export const UiFab = C.Fab;
109
+ export const UiTextarea = C.Textarea;
110
+ export const UiNumberInput = C.NumberInput;
111
+ export const UiPasswordInput = C.PasswordInput;
112
+ export const UiSearchInput = C.SearchInput;
113
+ export const UiRadioGroup = C.RadioGroup;
114
+ export const UiSlider = C.Slider;
115
+ export const UiRating = C.Rating;
116
+ export const UiChipInput = C.ChipInput;
117
+ export const UiInlineEdit = C.InlineEdit;
118
+ export const UiColorPicker = C.ColorPicker;
119
+ export const UiFileUpload = C.FileUpload;
120
+ export const UiCombobox = C.Combobox;
121
+ export const UiMultiSelect = C.MultiSelect;
122
+ export const UiGroupedSelect = C.GroupedSelect;
123
+ export const UiPhoneInput = C.PhoneInput;
124
+ export const UiCalendar = C.Calendar;
125
+ export const UiDatePicker = C.DatePicker;
126
+ export const UiTimePicker = C.TimePicker;
127
+ export const UiFormField = C.FormField;
128
+ export const UiLoginForm = C.LoginForm;
129
+ export const UiStepForm = C.StepForm;
130
+ export const UiTag = C.Tag;
131
+ export const UiKbd = C.Kbd;
132
+ export const UiStatsCard = C.StatsCard;
133
+ export const UiKpiInline = C.KpiInline;
134
+ export const UiMiniChart = C.MiniChart;
135
+ export const UiDescriptions = C.Descriptions;
136
+ export const UiLazyImage = C.LazyImage;
137
+ export const UiSystemStatus = C.SystemStatus;
138
+ export const UiTreeView = C.TreeView;
139
+ export const UiCalendarView = C.CalendarView;
140
+ export const UiSubNav = C.SubNav;
141
+ export const UiActionRail = C.ActionRail;
142
+ export const UiSplitLayout = C.SplitLayout;
143
+ export const UiSettingsSection = C.SettingsSection;
144
+ export const UiScrollArea = C.ScrollArea;
145
+ export const UiDealCard = C.DealCard;
146
+ export const UiPipelineBoard = C.PipelineBoard;
147
+ export const UiContactPanel = C.ContactPanel;
148
+ export const UiSalesFunnel = C.SalesFunnel;
149
+ export const UiBookingCard = C.BookingCard;
150
+ export const UiGuestCard = C.GuestCard;
151
+ export const UiRoomGrid = C.RoomGrid;
152
+ export const UiRoomCalendar = C.RoomCalendar;
153
+ export const UiOccupancyChart = C.OccupancyChart;
154
+ export const UiChip = C.Chip;
155
+ export const UiIconTile = C.IconTile;
156
+ export const UiStatusIcon = C.StatusIcon;
157
+ export const UiUserCell = C.UserCell;
158
+ export const UiStatRow = C.StatRow;
159
+ export const UiCountryRow = C.CountryRow;
160
+ export const UiStatLine = C.StatLine;
161
+ export const UiStatStrip = C.StatStrip;
162
+ export const UiVersusBar = C.VersusBar;
163
+ export const UiSegBar = C.SegBar;
164
+ export const UiHeroBanner = C.HeroBanner;
165
+ export const UiTabTiles = C.TabTiles;
166
+ export const UiPillTabs = C.PillTabs;
167
+ export const UiPillSelect = C.PillSelect;
168
+ export const UiChartCard = C.ChartCard;
169
+ export const UiActionCard = C.ActionCard;
170
+ export const UiSnackbar = C.Snackbar;
171
+ export const UiTourPopover = C.TourPopover;
172
+ export const UiProfileHeader = C.ProfileHeader;
173
+ export const UiAuthSplit = C.AuthSplit;
174
+ export const UiStatusPage = C.StatusPage;
175
+ export const UiValidatedField = C.ValidatedField;
176
+ export const UiFooter = C.Footer;
177
+ export const UiDataGroup = C.DataGroup;
178
+ export const UiOptionCard = C.OptionCard;
179
+ export const UiOptionCards = C.OptionCards;
180
+ export const UiRichEditor = C.RichEditor;
181
+ export const UiRangeSlider = C.RangeSlider;
182
+ export const UiRangeCalendar = C.RangeCalendar;
183
+ export const UiStepDialog = C.StepDialog;
184
+ export const UiFullscreenDialog = C.FullscreenDialog;
185
+ export const UiPageDashboard = C.PageDashboard;
186
+ export const UiPagePatterns = C.PagePatterns;
187
+ export const UiPageCrm = C.PageCrm;
188
+ export const UiPageBookings = C.PageBookings;
189
+ export const UiPageCatalog = C.PageCatalog;
190
+ export const UiPageDetail = C.PageDetail;
191
+ export const UiPageSettings = C.PageSettings;
192
+ export const UiPageUserList = C.PageUserList;
193
+ export const UiPageProfile = C.PageProfile;
194
+ export const UiPageForm = C.PageForm;
195
+ export const UiPageOrder = C.PageOrder;
196
+ export const UiPageAccount = C.PageAccount;
197
+ export const UiPagePricing = C.PagePricing;
198
+ export const UiPageFaq = C.PageFaq;
199
+ export const UiPageAuth = C.PageAuth;
200
+ export const UiPageStatus = C.PageStatus;
201
+ export const UiTreeSelect = C.TreeSelect;
202
+ export const UiContextMenu = C.ContextMenu;
203
+ export const UiSortable = C.Sortable;
204
+ export const UiMap = C.Map;
205
+ export const UiImageUpload = C.ImageUpload;
206
+ export const UiScreensaver = C.Screensaver;
207
+ export const UiTour = C.Tour;
208
+ export const UiHeading = C.Heading;
209
+ export const UiText = C.Text;
210
+ export const UiBox = C.Box;
211
+ export const UiCenter = C.Center;
212
+ export const UiHStack = C.HStack;
213
+ export const UiVStack = C.VStack;
214
+ export const UiGrid = C.Grid;
215
+ export const UiLink = C.Link;
216
+ export const UiPressable = C.Pressable;
217
+ export const UiIcon = C.Icon;
218
+ export const UiPortal = C.Portal;
219
+ export const UiLiquidGlass = C.LiquidGlass;
220
+ export const UiBottomSheet = C.BottomSheet;
221
+ export const UiActionsheet = C.Actionsheet;
222
+ export const UiImageViewer = C.ImageViewer;
223
+ export const UiChatAi = C.ChatAi;
224
+ export { fmt, setIconBase, rules, LOCALES, setUiLocale, getUiLocale, setUiMessages, isRtlLocale } from '../core/index.js';
31
225
  export { useUiTheme } from '../theme.js';
@@ -0,0 +1,33 @@
1
+ // Auto-import resolver for unplugin-vue-components (Vite, Webpack, Rollup, Rspack).
2
+ // import Components from 'unplugin-vue-components/vite'
3
+ // import { ZiyaragoUiResolver } from '@ziyarago/ui/resolver'
4
+ // Components({ resolvers: [ZiyaragoUiResolver()] })
5
+ // Zero dependencies: it only maps <UiButton> to { name: 'UiButton', from: '@ziyarago/ui/vue' }.
6
+ import { components } from './core/index.js';
7
+
8
+ const NAMES = new Set(Object.keys(components));
9
+
10
+ /**
11
+ * @param {{ prefix?: string, css?: boolean | string, exclude?: string[], from?: string }} [options]
12
+ * prefix component prefix, default 'Ui' (must match the registered names, which are always Ui*)
13
+ * css true: import '@ziyarago/ui/style.css' as a side effect together with the first resolved component (once per module that uses one);
14
+ * a string: import that path instead (for example your own entry that imports the css inside a Tailwind @layer). Default false.
15
+ * exclude component names (without prefix) that must not be auto-imported, e.g. ['Button'] if you keep your own UiButton.
16
+ * from module the components are imported from, default '@ziyarago/ui/vue'
17
+ */
18
+ export function ZiyaragoUiResolver(options = {}) {
19
+ const { prefix = 'Ui', css = false, exclude = [], from = '@ziyarago/ui/vue' } = options;
20
+ const skip = new Set(exclude.map(n => n.replace(/^Ui/, '')));
21
+ const sideEffects = css ? (css === true ? '@ziyarago/ui/style.css' : css) : undefined;
22
+ return {
23
+ type: 'component',
24
+ resolve(name) {
25
+ if (!name.startsWith(prefix)) return;
26
+ const bare = name.slice(prefix.length);
27
+ if (!NAMES.has(bare) || skip.has(bare)) return;
28
+ return { name: 'Ui' + bare, from, ...(sideEffects ? { sideEffects } : {}) };
29
+ },
30
+ };
31
+ }
32
+
33
+ export default ZiyaragoUiResolver;
@@ -1,6 +1,13 @@
1
1
  /* @ziyarago/ui · components. Every class is zg-*; no global resets except .zg-root */
2
2
  .zg-root{font-family:var(--zg-font);color:var(--zg-text-1);background:var(--zg-bg);-webkit-font-smoothing:antialiased}
3
3
  .zg-root *,.zg-root *::before,.zg-root *::after{box-sizing:border-box}
4
+ /* Host-CSS robustness. Zero specificity (:where), so any zg-* rule, utility class or app rule wins. Makes a component look the same with or without
5
+ Tailwind preflight / a CSS reset: form controls inherit font and color, no UA padding, border-box, normal line-height, svg without a baseline gap. */
6
+ :where(.zg-root,[class*="zg-"]){line-height:normal}
7
+ :where([class*="zg-"]),:where([class*="zg-"])::before,:where([class*="zg-"])::after,:where(.zg-root,[class*="zg-"]) :where(*,*::before,*::after){box-sizing:border-box}
8
+ :where(.zg-root,[class*="zg-"]) :where(button,input,select,textarea),:where(button,input,select,textarea):where([class*="zg-"]){font:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0;background-color:transparent}
9
+ :where(.zg-root,[class*="zg-"]) a:where(:not([class])){text-decoration:underline}
10
+ :where(.zg-root,[class*="zg-"]) svg,svg:where([class*="zg-"]){vertical-align:middle}
4
11
  .zg-glass{background:var(--zg-s1);backdrop-filter:blur(24px) saturate(1.5);-webkit-backdrop-filter:blur(24px) saturate(1.5);box-shadow:var(--zg-rim),var(--zg-shadow-1)}
5
12
  .zg-icon:not([style*="--zg-icon"]){visibility:hidden}
6
13
  .zg-icon{display:inline-block;flex:none;width:1em;height:1em;background:currentColor;-webkit-mask:var(--zg-icon) center/contain no-repeat;mask:var(--zg-icon) center/contain no-repeat}
@@ -11,6 +11,8 @@
11
11
  .zg-saver__c{position:relative;display:flex;flex-direction:column;align-items:center;gap:12px;text-align:center}.zg-saver__m{width:72px;height:72px;background:center/contain no-repeat;opacity:.9}
12
12
  .zg-tourov{position:fixed;inset:0;z-index:250}.zg-tourov__full{position:absolute;inset:0;background:oklch(0.1 0 0 / .7)}.zg-tourov__cut{position:absolute;border-radius:14px;box-shadow:0 0 0 9999px oklch(0.1 0 0 / .7),0 0 0 2px var(--zg-brand);pointer-events:none}
13
13
  .zg-rte__c blockquote{margin:8px 0;padding:4px 14px;border-inline-start:3px solid var(--zg-brand);color:var(--zg-text-2)}.zg-rte__c pre{margin:8px 0;padding:12px 14px;border-radius:12px;background:oklch(0.17 0.006 240);color:oklch(0.9 0.01 240);font:500 13px var(--zg-font-mono);overflow:auto;direction:ltr;text-align:left}
14
+ /* Rich text defaults that a CSS reset (Tailwind preflight) would remove; :where keeps them overridable. */
15
+ :where(.zg-rte__c) :where(p){margin:0 0 .6em}:where(.zg-rte__c) :where(ul,ol){margin:.5em 0;padding-inline-start:1.5em}:where(.zg-rte__c) ul{list-style:disc}:where(.zg-rte__c) ol{list-style:decimal}:where(.zg-rte__c) :where(h1,h2,h3){font-weight:700;margin:.8em 0 .4em}:where(.zg-rte__c) h1{font-size:1.5em}:where(.zg-rte__c) h2{font-size:1.25em}:where(.zg-rte__c) h3{font-size:1.1em}:where(.zg-rte__c) a{color:var(--zg-brand-text);text-decoration:underline}
14
16
  /* focus + disabled audit */
15
17
  .zg-btn:focus-visible,.zg-ibtn:focus-visible,.zg-chip:focus-visible,.zg-chip2 button:focus-visible,.zg-tt__i:focus-visible,.zg-pt button:focus-visible,.zg-navitem:focus-visible,.zg-menu__i:focus-visible,.zg-check:focus-visible,.zg-switch:focus-visible,.zg-cal__d:focus-visible,.zg-acc__h:focus-visible,.zg-tree__n:focus-visible,.zg-room:focus-visible,.zg-pin:focus-visible,.zg-sort__i:focus-visible,.zg-inline:focus-visible{outline:3px solid var(--zg-brand-soft);outline-offset:2px}
16
18
  .zg-btn:disabled,.zg-ibtn:disabled,.zg-chip:disabled,[aria-disabled="true"]{opacity:.45;cursor:not-allowed;pointer-events:none}.zg-tt__i:hover,.zg-chip:hover:not([aria-pressed="true"]){background:var(--zg-s2)}.zg-room:hover,.zg-hotel:hover,.zg-lead:hover{box-shadow:var(--zg-rim),var(--zg-shadow-1)}.zg-table tbody tr:hover{background:var(--zg-s1)}
@@ -10,8 +10,8 @@
10
10
  [data-fx="lite"] .zg-glass{background:var(--zg-pop)}
11
11
 
12
12
  /* ── page backgrounds ── set data-bg on <html> (useUiTheme().setBackground) or on any element with class zg-bg ── */
13
- :root{--zg-bgL:.62;--zg-bgC:.16;--zg-bgA:26%}
14
- [data-theme="light"]{--zg-bgL:.8;--zg-bgC:.11;--zg-bgA:34%}
13
+ :root{--zg-bgL:.62;--zg-bgC:.2;--zg-bgA:42%}
14
+ [data-theme="light"]{--zg-bgL:.8;--zg-bgC:.14;--zg-bgA:50%}
15
15
  [data-bg="aurora"]{--zg-bg-image:radial-gradient(60% 50% at 12% 8%,color-mix(in oklch,var(--zg-brand) var(--zg-bgA),transparent),transparent 70%),radial-gradient(50% 45% at 88% 18%,color-mix(in oklch,oklch(var(--zg-bgL) var(--zg-bgC) 250) var(--zg-bgA),transparent),transparent 70%),radial-gradient(65% 55% at 50% 105%,color-mix(in oklch,oklch(var(--zg-bgL) var(--zg-bgC) 320) var(--zg-bgA),transparent),transparent 70%)}
16
16
  [data-bg="sunset"]{--zg-bg-image:radial-gradient(70% 55% at 10% 0%,color-mix(in oklch,oklch(var(--zg-bgL) var(--zg-bgC) 55) var(--zg-bgA),transparent),transparent 70%),radial-gradient(60% 50% at 95% 25%,color-mix(in oklch,oklch(var(--zg-bgL) var(--zg-bgC) 15) var(--zg-bgA),transparent),transparent 70%),radial-gradient(70% 60% at 40% 110%,color-mix(in oklch,oklch(var(--zg-bgL) var(--zg-bgC) 340) var(--zg-bgA),transparent),transparent 70%)}
17
17
  [data-bg="ocean"]{--zg-bg-image:radial-gradient(70% 55% at 85% 0%,color-mix(in oklch,oklch(var(--zg-bgL) var(--zg-bgC) 230) var(--zg-bgA),transparent),transparent 70%),radial-gradient(60% 55% at 5% 40%,color-mix(in oklch,oklch(var(--zg-bgL) var(--zg-bgC) 200) var(--zg-bgA),transparent),transparent 70%),radial-gradient(70% 55% at 60% 110%,color-mix(in oklch,oklch(var(--zg-bgL) var(--zg-bgC) 265) var(--zg-bgA),transparent),transparent 70%)}
@@ -21,8 +21,10 @@
21
21
  html[data-bg]:not([data-bg="none"]),.zg-bg:not([data-bg="none"]){background-color:var(--zg-bg);background-image:var(--zg-bg-image);background-attachment:fixed}
22
22
  .zg-bg:not([data-bg="none"]){background-attachment:scroll}
23
23
  html[data-bg]:not([data-bg="none"]) .zg-root{background:transparent}
24
- html[data-fx="full"][data-motion="on"][data-bg]:not([data-bg="none"]){background-size:140% 140%;animation:zg-bg-drift 48s ease-in-out infinite alternate}
25
- @keyframes zg-bg-drift{from{background-position:0% 0%}to{background-position:100% 100%}}
24
+ html[data-motion="on"][data-bg]:not([data-bg="none"]){background-image:none}
25
+ html[data-motion="on"][data-bg]:not([data-bg="none"])::before{content:"";position:fixed;inset:-25%;z-index:-1;pointer-events:none;background-image:var(--zg-bg-image);background-repeat:no-repeat;animation:zg-bg-float 18s ease-in-out infinite alternate,zg-bg-hue 40s linear infinite;will-change:transform,filter}
26
+ @keyframes zg-bg-hue{from{filter:hue-rotate(0deg) saturate(1.15)}to{filter:hue-rotate(360deg) saturate(1.15)}}
27
+ @keyframes zg-bg-float{0%{transform:translate3d(-3%,-2%,0) scale(1) rotate(0deg)}50%{transform:translate3d(4%,3%,0) scale(1.18) rotate(3deg)}100%{transform:translate3d(-2%,5%,0) scale(1.08) rotate(-3deg)}}
26
28
 
27
29
  /* ── gradient cards ── <UiCard variant="gradient" tone="sky" intensity="soft|vivid"> ── */
28
30
  .zg-card--grad{--t:var(--zg-brand);--tv:var(--zg-brand);--on:var(--zg-on-brand)}
@@ -0,0 +1,55 @@
1
+ /* Additions for parity with older UI kits (icon-only buttons, avatar status, card slots, tooltip placement, ...). Plain classes, no size selectors. */
2
+ .zg-req{color:var(--zg-red)}
3
+ .zg-btn--sq{width:var(--h);padding:0}
4
+ .zg-ta--fixed{resize:none}.zg-ta--auto{field-sizing:content}.zg-ta__count{align-self:flex-end}
5
+ .zg-select__trigger--error{box-shadow:var(--zg-rim),inset 0 0 0 1.5px var(--zg-red)}
6
+ .zg-check--error .zg-check__box{box-shadow:inset 0 0 0 1.5px var(--zg-red)}
7
+ .zg-check[aria-checked="mixed"] .zg-check__box{background:var(--zg-brand);box-shadow:none}
8
+ .zg-seg--block{display:flex;width:100%}.zg-seg--block button{flex:1}
9
+ .zg-seg button{display:inline-flex;align-items:center;justify-content:center;gap:6px}.zg-seg button[disabled]{opacity:.45;cursor:not-allowed}
10
+ .zg-alert__act{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}
11
+ .zg-badge--sq{border-radius:8px}.zg-badge--inverse{background:var(--zg-inv-bg);color:var(--zg-inv-fg)}
12
+ .zg-avatar--sq{border-radius:30%}
13
+ .zg-avatar--ring{box-shadow:var(--zg-rim),0 0 0 2px var(--zg-bg)}
14
+ .zg-avatar--st{position:relative;overflow:visible}.zg-avatar--st img{border-radius:inherit}
15
+ .zg-avatar__st{position:absolute;inset-inline-end:0;bottom:0;width:max(8px,calc(var(--s)*.26));height:max(8px,calc(var(--s)*.26));border-radius:50%;background:var(--zg-text-3);box-shadow:0 0 0 2px var(--zg-bg)}
16
+ .zg-avatar__st--online{background:var(--zg-green)}.zg-avatar__st--away{background:var(--zg-amber)}.zg-avatar__st--busy{background:var(--zg-red)}
17
+ .zg-avatar--sky{background:var(--zg-sky);color:var(--zg-bg)}.zg-avatar--success{background:var(--zg-green);color:var(--zg-bg)}.zg-avatar--warning{background:var(--zg-amber);color:var(--zg-bg)}.zg-avatar--danger{background:var(--zg-red);color:var(--zg-bg)}.zg-avatar--neutral{background:var(--zg-s3);color:var(--zg-text-1)}
18
+ .zg-card.zg-card--outline{background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;box-shadow:inset 0 0 0 1px var(--zg-stroke)}
19
+ .zg-card.zg-card--flush{padding:0}
20
+ .zg-card--click{cursor:pointer;transition:transform .2s var(--zg-ease)}.zg-card--click:hover{transform:translateY(-2px)}.zg-card--click:focus-visible{outline:2px solid var(--zg-brand);outline-offset:2px}
21
+ .zg-card__foot{display:flex;align-items:center;gap:8px;padding-top:14px;box-shadow:0 -1px 0 var(--zg-stroke)}
22
+ .zg-modal__sub{font-size:13px;font-weight:500;color:var(--zg-text-3);margin-top:2px}
23
+ .zg-crumbs__sep{color:var(--zg-text-3)}
24
+ .zg-tr--click{cursor:pointer}
25
+ .zg-tip--bottom::after{bottom:auto;top:calc(100% + 8px);transform:translateX(-50%) translateY(-4px)}
26
+ .zg-tip--bottom:hover::after,.zg-tip--bottom:focus-visible::after{transform:translateX(-50%) translateY(0)}
27
+ .zg-tip--left::after,.zg-tip--right::after{bottom:auto;top:50%;inset-inline-start:auto}
28
+ .zg-tip--left::after{left:auto;right:calc(100% + 8px);transform:translateY(-50%) translateX(4px)}
29
+ .zg-tip--right::after{right:auto;left:calc(100% + 8px);transform:translateY(-50%) translateX(-4px)}
30
+ .zg-tip--left:hover::after,.zg-tip--left:focus-visible::after,.zg-tip--right:hover::after,.zg-tip--right:focus-visible::after{transform:translateY(-50%) translateX(0)}
31
+ .zg-rg{display:flex;flex-direction:column;gap:10px}.zg-rg--row{flex-direction:row;flex-wrap:wrap;gap:10px 22px}
32
+ /* compat layer (@ziyarago/ui/compat): compound components that have no counterpart in the new kit */
33
+ .zg-dd-trig{display:inline-block}.zg-dd__panel{position:fixed;z-index:var(--zg-z-pop,60);animation:zg-pop-in .16s var(--zg-ease) both}
34
+ .zg-menu__lbl{padding:10px 12px 4px;font:700 11px var(--zg-font);letter-spacing:.1em;text-transform:uppercase;color:var(--zg-text-3)}
35
+ .zg-avgroup{display:flex}.zg-avgroup>*+*{margin-inline-start:-8px}.zg-avgroup--tight>*+*{margin-inline-start:-12px}.zg-avgroup--loose>*+*{margin-inline-start:-4px}
36
+ .zg-avgroup>.zg-avatar{box-shadow:var(--zg-rim),0 0 0 2px var(--zg-bg)}.zg-avgroup--rev{flex-direction:row-reverse;justify-content:flex-end}
37
+ .zg-toasts{position:fixed;z-index:calc(var(--zg-z-modal,200) + 20);display:flex;flex-direction:column;gap:10px;padding:16px;max-width:100vw;pointer-events:none}
38
+ .zg-toasts--top-right{top:0;right:0;align-items:flex-end}.zg-toasts--top-left{top:0;left:0;align-items:flex-start}.zg-toasts--top-center{top:0;left:50%;transform:translateX(-50%);align-items:center}
39
+ .zg-toasts--bottom-right{bottom:0;right:0;align-items:flex-end;flex-direction:column-reverse}.zg-toasts--bottom-left{bottom:0;left:0;align-items:flex-start;flex-direction:column-reverse}.zg-toasts--bottom-center{bottom:0;left:50%;transform:translateX(-50%);align-items:center;flex-direction:column-reverse}
40
+ .zg-toasts__i{position:relative;pointer-events:auto}.zg-toasts__x{position:absolute;top:6px;inset-inline-end:6px}.zg-toasts__act{margin-top:6px}
41
+ .zg-sidenav--compat{position:fixed;inset-block:0;inset-inline-start:0;z-index:60;width:min(288px,80vw);height:100vh;transform:translateX(-100%);transition:transform .3s var(--zg-ease),width .3s var(--zg-ease);background-color:var(--sidebar-bg,oklch(0.108 0.022 50));color:var(--zg-text-2)}
42
+ [dir="rtl"] .zg-sidenav--compat{transform:translateX(100%)}.zg-sidenav--compat.is-open{transform:none}
43
+ .zg-sidenav__nav{flex:1;min-height:0;display:flex;flex-direction:column;gap:18px;overflow-y:auto;overflow-x:hidden;padding:8px 0}.zg-sidenav__sec{display:flex;flex-direction:column;gap:2px}
44
+ .zg-sidenav__foot{padding-top:12px;box-shadow:0 -1px 0 var(--zg-stroke)}
45
+ .zg-sidenav-scrim{position:fixed;inset:0;z-index:55;background:oklch(0.12 0.005 40 / .45);backdrop-filter:blur(4px)}
46
+ @media (min-width:1024px){.zg-sidenav--compat{position:sticky;top:12px;margin:12px 0 12px 12px;height:calc(100vh - 24px);width:var(--w);transform:none;border-radius:24px;flex:none}[dir="rtl"] .zg-sidenav--compat{margin:12px 12px 12px 0}.zg-sidenav-scrim{display:none}}
47
+ .zg-sidenav--collapsed .zg-sidenav__group{display:none}
48
+ .zg-topnav--compat{padding-inline:clamp(16px,3vw,32px);min-height:64px}.zg-topnav--compat.zg-topnav--md{min-height:56px}.zg-topnav__mid{flex:1;min-width:0;display:flex;justify-content:center}
49
+ .zg-topnav--compat .zg-topnav__brand{gap:12px}
50
+ .zg-subnav--compat .zg-navitem{text-decoration:none;width:100%}.zg-subnav--compat .zg-sidenav__group{display:flex;align-items:center;gap:8px}
51
+ @media (min-width:1024px){.zg-subnav--compat{position:sticky;top:16px;align-self:flex-start}}
52
+ .zg-check,.zg-switch{text-align:start}
53
+ .zg-sidenav__close{position:absolute;top:12px;inset-inline-end:12px}@media (min-width:1024px){.zg-sidenav__close{display:none}}
54
+ .zg-cal__d:disabled{opacity:.35;cursor:not-allowed;background:none}
55
+ .zg-tipbox{position:fixed;z-index:calc(var(--zg-z-modal,200) + 40);max-width:min(320px,90vw);padding:6px 10px;border-radius:10px;font:600 12px var(--zg-font);background:var(--zg-inv-bg);color:var(--zg-inv-fg);box-shadow:var(--zg-shadow-1);pointer-events:none}.zg-tipbox--glass{background:var(--zg-pop);color:var(--zg-text-1);box-shadow:var(--zg-rim),var(--zg-shadow-1)}
@@ -18,4 +18,5 @@
18
18
  @import './sizes/navigation.css';
19
19
  @import './sizes/media.css';
20
20
  @import './sizes/domain.css';
21
+ @import './extras.css';
21
22
  @import './effects.css';
package/src/theme.js CHANGED
@@ -1,10 +1,16 @@
1
+ import { setUiLocale, isRtlLocale, LOCALES } from './i18n/index.js';
1
2
  // Framework-free theme controller: palette, theme, direction, motion, effects, background → attributes on <html>. Persists to localStorage.
2
3
  const KEY = 'zg-ui';
3
4
  export const PALETTES = ['gold', 'tamam'];
4
5
  export const BACKGROUNDS = ['none', 'aurora', 'sunset', 'ocean', 'emerald', 'rose', 'mesh'];
5
- const DEFAULTS = { theme: 'dark', palette: 'gold', dir: 'ltr', motion: 'auto', effects: 'auto', bg: 'none' };
6
+ const DEFAULTS = { theme: 'dark', palette: 'gold', dir: 'ltr', motion: 'auto', effects: 'auto', bg: 'none', locale: 'en' };
6
7
  const read = () => { try { return JSON.parse(localStorage.getItem(KEY) || '{}'); } catch { return {}; } };
7
8
  let cur = typeof localStorage === 'undefined' ? { ...DEFAULTS } : { ...DEFAULTS, ...read() };
9
+
10
+ /** Set the app defaults (used when the visitor has no saved choice). Call before the first useUiTheme(). */
11
+ export function configureTheme(defaults = {}) {
12
+ cur = typeof localStorage === 'undefined' ? { ...DEFAULTS, ...defaults } : { ...DEFAULTS, ...defaults, ...read() };
13
+ }
8
14
  const subs = new Set();
9
15
 
10
16
  export const capable = () => {
@@ -22,14 +28,17 @@ export const resolve = (s = cur) => ({
22
28
  const apply = () => {
23
29
  if (typeof document === 'undefined') return;
24
30
  const r = document.documentElement, v = resolve();
25
- r.dataset.theme = cur.theme; r.dataset.palette = cur.palette; r.dir = cur.dir;
31
+ r.dataset.theme = cur.theme; r.dataset.palette = cur.palette; r.dir = cur.dir; r.lang = cur.locale;
26
32
  r.dataset.motion = v.motion; r.dataset.fx = v.effects; r.dataset.bg = cur.bg;
27
33
  try { localStorage.setItem(KEY, JSON.stringify(cur)); } catch {}
28
34
  subs.forEach(f => f({ ...cur }));
29
35
  };
30
36
 
31
37
  /** Inline script for <head>: applies the saved settings before first paint (no flash). */
32
- export const themeInitScript = `try{var s=JSON.parse(localStorage.getItem('${KEY}')||'{}'),r=document.documentElement,d=r.dataset;if(s.theme)d.theme=s.theme;if(s.palette)d.palette=s.palette;if(s.dir)r.dir=s.dir;if(s.bg)d.bg=s.bg;var m=s.motion||'auto',f=s.effects||'auto';d.motion=m==='auto'?(matchMedia('(prefers-reduced-motion: reduce)').matches?'off':'on'):m;d.fx=f==='auto'?((CSS.supports('backdrop-filter','blur(1px)')&&(navigator.deviceMemory||8)>=4&&(navigator.hardwareConcurrency||8)>=4)?'full':'lite'):f}catch(e){}`;
38
+ export const themeInitScript = `try{var s=JSON.parse(localStorage.getItem('${KEY}')||'{}'),r=document.documentElement,d=r.dataset;if(s.theme)d.theme=s.theme;if(s.palette)d.palette=s.palette;if(s.dir)r.dir=s.dir;if(s.locale)r.lang=s.locale;if(s.bg)d.bg=s.bg;var m=s.motion||'auto',f=s.effects||'auto';d.motion=m==='auto'?(matchMedia('(prefers-reduced-motion: reduce)').matches?'off':'on'):m;d.fx=f==='auto'?((CSS.supports('backdrop-filter','blur(1px)')&&(navigator.deviceMemory||8)>=4&&(navigator.hardwareConcurrency||8)>=4)?'full':'lite'):f}catch(e){}`;
39
+
40
+ /** Apply the saved language to the built-in strings. Call AFTER the first render/hydration (the Nuxt module does it on app:mounted). */
41
+ export function applySavedLocale() { if (cur.locale && cur.locale !== 'en') setUiLocale(cur.locale); }
33
42
 
34
43
  export function useUiTheme() {
35
44
  if (typeof document !== 'undefined') apply();
@@ -40,7 +49,10 @@ export function useUiTheme() {
40
49
  get resolved() { return resolve(); },
41
50
  palettes: PALETTES, backgrounds: BACKGROUNDS,
42
51
  setTheme: t => set({ theme: t }), toggleTheme: () => set({ theme: cur.theme === 'dark' ? 'light' : 'dark' }),
43
- setPalette: p => set({ palette: p }), setDir: d => set({ dir: d }), setLocale: l => set({ dir: l === 'ar' ? 'rtl' : 'ltr' }),
52
+ setPalette: p => set({ palette: p }), setDir: d => set({ dir: d }),
53
+ /** Language of the built-in component strings. Also sets dir (rtl for Arabic) and <html lang>. */
54
+ get locale() { return cur.locale; }, locales: LOCALES,
55
+ setLocale: l => { setUiLocale(l); set({ locale: String(l).toLowerCase().split(/[-_]/)[0], dir: isRtlLocale(l) ? 'rtl' : 'ltr' }); },
44
56
  /** 'auto' follows prefers-reduced-motion, 'on' enables animations, 'off' disables them */
45
57
  setMotion: m => set({ motion: m }),
46
58
  /** 'auto' picks by browser capability, 'full' = blur, glow and animated backgrounds, 'lite' = flat and fast */
@@ -0,0 +1,2 @@
1
+ // Types-only entry: import '@ziyarago/ui/vue/global' to register Ui* in GlobalComponents. See types/vue-global.d.ts.
2
+ export {};
package/src/vue/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // Vue 3 adapter. Usage: import { UiButton, UiAppShell } from '@ziyarago/ui/vue'
2
- import { h, ref, reactive, defineComponent, Teleport, cloneVNode, isVNode } from 'vue';
3
- import { components } from '../core/index.js';
2
+ import { h, ref, reactive, defineComponent, onMounted, onBeforeUnmount, Teleport, cloneVNode, isVNode } from 'vue';
3
+ import { components, subscribeUiLocale } from '../core/index.js';
4
+ import { BOOL_PROPS } from '../core/bools.js';
4
5
 
5
6
  const C = {};
6
7
  const vh = (t, p, ...k) => { const kids = k.flat(); if (p && typeof t === 'string') for (const key of Object.keys(p)) if (/^on[A-Z]/.test(key) && !key.startsWith('onVnode')) { const nk = 'on' + key[2] + key.slice(3).toLowerCase(); if (nk !== key) { p[nk] = p[key]; delete p[key]; } } return typeof t === 'string' || !kids.length ? h(t, p, kids.length ? kids : undefined) : h(t, p, { default: () => kids }); };
@@ -9,14 +10,20 @@ const wrap = (name, def) => defineComponent({
9
10
  setup(_, { attrs, slots, emit }) {
10
11
  const state = reactive({ ...(def.state || {}) });
11
12
  const set = o => Object.assign(state, o);
13
+ // Teleports are client-only: during SSR and hydration portal() renders nothing (a teleport to <body> cannot hydrate), then appears once mounted.
14
+ const mounted = ref(false), localeTick = ref(0); let offLocale; onMounted(() => { mounted.value = true; offLocale = subscribeUiLocale(() => { localeTick.value++; }); }); onBeforeUnmount(() => offLocale && offLocale());
12
15
  return () => {
13
- const props = { ...attrs, onChange: v => { emit('update:modelValue', v); emit('change', v); } };
16
+ void localeTick.value;
17
+ const props = {}, root = {};
18
+ for (const k in attrs) { if (/^(aria|data)-|^(class|style|id)$/.test(k)) root[k] = attrs[k]; const pk = k.includes('-') && !/^(aria|data)-/.test(k) ? k.replace(/-([a-z])/g, (_, c) => c.toUpperCase()) : k; props[pk] = attrs[k] === '' && BOOL_PROPS.has(pk) ? true : attrs[k]; }
19
+ props.onChange = v => { emit('update:modelValue', v); emit('change', v); };
14
20
  if (attrs.modelValue === undefined) delete props.modelValue;
15
21
  const named = {}; for (const k of Object.keys(slots)) if (k !== 'default') named[k] = slots[k]();
16
22
  const children = slots.default ? slots.default() : [];
17
- const out = def.render({ C, h: vh, props, children, slots: named, state, set, portal: (kids, to) => h(Teleport, { to: to || 'body' }, kids) });
23
+ const out = def.render({ C, h: vh, props, children, slots: named, state, set, portal: (kids, to) => mounted.value ? h(Teleport, { to: to || 'body' }, kids) : null });
18
24
  const sz = attrs.size;
19
- return sz && isVNode(out) && typeof out.type === 'string' ? cloneVNode(out, { 'data-size': sz }) : out;
25
+ if (sz) root['data-size'] = sz;
26
+ return isVNode(out) && typeof out.type === 'string' && Object.keys(root).length ? cloneVNode(out, root) : out;
20
27
  };
21
28
  },
22
29
  });
@@ -27,3 +34,4 @@ export const install = app => { for (const [n, c] of Object.entries(C)) app.comp
27
34
  export { fmt, setIconBase, rules } from '../core/index.js';
28
35
  export { useUiTheme } from '../theme.js';
29
36
  export default { install };
37
+ export { LOCALES, setUiLocale, getUiLocale, setUiMessages, isRtlLocale } from '../core/index.js';
@@ -0,0 +1,12 @@
1
+ export interface ZiyaragoCompatResolverOptions {
2
+ /** Module the compat components come from. Default '@ziyarago/ui/compat'. */
3
+ from?: string;
4
+ /** Full component names (with the Ui prefix) to leave to other resolvers or local files, for example ['UiTable']. */
5
+ exclude?: string[];
6
+ /** true: also import '@ziyarago/ui/style.css'; a string: import that module instead. Default false. */
7
+ css?: boolean | string;
8
+ }
9
+ export interface ZiyaragoCompatResolverResult { name: string; from: string; sideEffects?: string }
10
+ export interface ZiyaragoCompatResolver { type: 'component'; resolve(name: string): ZiyaragoCompatResolverResult | undefined }
11
+ export function ZiyaragoCompatResolver(options?: ZiyaragoCompatResolverOptions): ZiyaragoCompatResolver;
12
+ export default ZiyaragoCompatResolver;
@@ -0,0 +1,11 @@
1
+ import type { Plugin } from 'vite';
2
+ export interface ZiyaragoCompatViteOptions {
3
+ /** Module the redirected imports resolve to. Default '@ziyarago/ui/compat'. */
4
+ from?: string;
5
+ /** Matches the local ui directory in an import path; group 1 is the folder, group 2 the optional file. */
6
+ ui?: RegExp;
7
+ /** Import paths that stay local. Default [/MultilangInput/]. */
8
+ exclude?: RegExp[];
9
+ }
10
+ export function ziyaragoCompat(options?: ZiyaragoCompatViteOptions): Plugin;
11
+ export default ziyaragoCompat;