@leavepulse/ui 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +61 -0
- package/dist/component-names.d.ts +1 -0
- package/dist/components/LayoutCanvas.vue.d.ts +28 -0
- package/dist/components/LayoutNode.vue.d.ts +40 -0
- package/dist/components/LpAlert.vue.d.ts +44 -0
- package/dist/components/LpAppShell.vue.d.ts +83 -0
- package/dist/components/LpAutocomplete.vue.d.ts +50 -0
- package/dist/components/LpAvatar.vue.d.ts +20 -0
- package/dist/components/LpBadge.vue.d.ts +47 -0
- package/dist/components/LpBreadcrumbs.vue.d.ts +14 -0
- package/dist/components/LpButton.vue.d.ts +113 -0
- package/dist/components/LpCalendar.vue.d.ts +20 -0
- package/dist/components/LpCard.vue.d.ts +29 -0
- package/dist/components/LpCheckbox.vue.d.ts +28 -0
- package/dist/components/LpCodeBlock.vue.d.ts +39 -0
- package/dist/components/LpCommandPalette.vue.d.ts +42 -0
- package/dist/components/LpConfirmDialog.vue.d.ts +32 -0
- package/dist/components/LpContextMenu.vue.d.ts +30 -0
- package/dist/components/LpDatePicker.vue.d.ts +25 -0
- package/dist/components/LpDisclosure.vue.d.ts +37 -0
- package/dist/components/LpDivider.vue.d.ts +17 -0
- package/dist/components/LpDrawer.vue.d.ts +88 -0
- package/dist/components/LpDropdownMenu.vue.d.ts +23 -0
- package/dist/components/LpEmptyState.vue.d.ts +18 -0
- package/dist/components/LpFormField.vue.d.ts +21 -0
- package/dist/components/LpIcon.vue.d.ts +8 -0
- package/dist/components/LpInfraNode.vue.d.ts +21 -0
- package/dist/components/LpInput.vue.d.ts +68 -0
- package/dist/components/LpLaneNode.vue.d.ts +24 -0
- package/dist/components/LpLink.vue.d.ts +27 -0
- package/dist/components/LpLogViewer.vue.d.ts +92 -0
- package/dist/components/LpModal.vue.d.ts +43 -0
- package/dist/components/LpNotificationBell.vue.d.ts +51 -0
- package/dist/components/LpNumberField.vue.d.ts +14 -0
- package/dist/components/LpOtpInput.vue.d.ts +27 -0
- package/dist/components/LpPagination.vue.d.ts +25 -0
- package/dist/components/LpPasswordInput.vue.d.ts +28 -0
- package/dist/components/LpPhoneInput.vue.d.ts +37 -0
- package/dist/components/LpPopover.vue.d.ts +34 -0
- package/dist/components/LpProgress.vue.d.ts +12 -0
- package/dist/components/LpRadio.vue.d.ts +18 -0
- package/dist/components/LpRadioGroup.vue.d.ts +26 -0
- package/dist/components/LpScrollArea.vue.d.ts +24 -0
- package/dist/components/LpSegmented.vue.d.ts +24 -0
- package/dist/components/LpSelect.vue.d.ts +45 -0
- package/dist/components/LpServiceNode.vue.d.ts +14 -0
- package/dist/components/LpSidebar.vue.d.ts +85 -0
- package/dist/components/LpSidebarNav.vue.d.ts +34 -0
- package/dist/components/LpSkeleton.vue.d.ts +6 -0
- package/dist/components/LpSlider.vue.d.ts +23 -0
- package/dist/components/LpStat.vue.d.ts +22 -0
- package/dist/components/LpStepper.vue.d.ts +10 -0
- package/dist/components/LpSwitch.vue.d.ts +11 -0
- package/dist/components/LpTable.vue.d.ts +63 -0
- package/dist/components/LpTableOfContents.vue.d.ts +19 -0
- package/dist/components/LpTabs.vue.d.ts +45 -0
- package/dist/components/LpTextarea.vue.d.ts +17 -0
- package/dist/components/LpThemeSwitcher.vue.d.ts +40 -0
- package/dist/components/LpToaster.vue.d.ts +3 -0
- package/dist/components/LpTooltip.vue.d.ts +19 -0
- package/dist/components/LpTopologyCanvas.vue.d.ts +154 -0
- package/dist/components/LpUptimeBar.vue.d.ts +30 -0
- package/dist/components/codeHighlight.d.ts +8 -0
- package/dist/components/countries-data.d.ts +2 -0
- package/dist/components/countries.d.ts +20 -0
- package/dist/components/dropdown.d.ts +29 -0
- package/dist/components/sidebar.d.ts +18 -0
- package/dist/composables/useInputFilter.d.ts +14 -0
- package/dist/composables/usePillTransition.d.ts +9 -0
- package/dist/composables/useToast.d.ts +39 -0
- package/dist/countries-data-9rgqJWHo.js +203 -0
- package/dist/icons.d.ts +1 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +100 -0
- package/dist/index.js +17600 -0
- package/dist/layout/registry.d.ts +26 -0
- package/dist/layout/tree.d.ts +75 -0
- package/dist/layout/useLayout.d.ts +39 -0
- package/dist/theme/config.d.ts +16 -0
- package/dist/theme/define.d.ts +12 -0
- package/dist/theme/presets.d.ts +20 -0
- package/dist/theme/tokens.d.ts +72 -0
- package/dist/theme/useTheme.d.ts +36 -0
- package/package.json +93 -0
- package/src/canvas.css +67 -0
- package/src/component-names.ts +65 -0
- package/src/components/LayoutCanvas.vue +76 -0
- package/src/components/LayoutNode.vue +248 -0
- package/src/components/LpAlert.vue +59 -0
- package/src/components/LpAppShell.vue +210 -0
- package/src/components/LpAutocomplete.vue +244 -0
- package/src/components/LpAvatar.vue +67 -0
- package/src/components/LpBadge.vue +32 -0
- package/src/components/LpBreadcrumbs.vue +35 -0
- package/src/components/LpButton.vue +111 -0
- package/src/components/LpCalendar.vue +134 -0
- package/src/components/LpCard.vue +71 -0
- package/src/components/LpCheckbox.vue +44 -0
- package/src/components/LpCodeBlock.vue +298 -0
- package/src/components/LpCommandPalette.vue +323 -0
- package/src/components/LpConfirmDialog.vue +49 -0
- package/src/components/LpContextMenu.vue +111 -0
- package/src/components/LpDatePicker.vue +117 -0
- package/src/components/LpDisclosure.vue +92 -0
- package/src/components/LpDivider.vue +20 -0
- package/src/components/LpDrawer.vue +402 -0
- package/src/components/LpDropdownMenu.vue +54 -0
- package/src/components/LpEmptyState.vue +21 -0
- package/src/components/LpFormField.vue +31 -0
- package/src/components/LpIcon.vue +49 -0
- package/src/components/LpInfraNode.vue +108 -0
- package/src/components/LpInput.vue +147 -0
- package/src/components/LpLaneNode.vue +48 -0
- package/src/components/LpLink.vue +48 -0
- package/src/components/LpLogViewer.vue +569 -0
- package/src/components/LpModal.vue +123 -0
- package/src/components/LpNotificationBell.vue +238 -0
- package/src/components/LpNumberField.vue +56 -0
- package/src/components/LpOtpInput.vue +81 -0
- package/src/components/LpPagination.vue +165 -0
- package/src/components/LpPasswordInput.vue +50 -0
- package/src/components/LpPhoneInput.vue +241 -0
- package/src/components/LpPopover.vue +42 -0
- package/src/components/LpProgress.vue +30 -0
- package/src/components/LpRadio.vue +28 -0
- package/src/components/LpRadioGroup.vue +43 -0
- package/src/components/LpScrollArea.vue +82 -0
- package/src/components/LpSegmented.vue +83 -0
- package/src/components/LpSelect.vue +0 -0
- package/src/components/LpServiceNode.vue +57 -0
- package/src/components/LpSidebar.vue +200 -0
- package/src/components/LpSidebarNav.vue +118 -0
- package/src/components/LpSkeleton.vue +16 -0
- package/src/components/LpSlider.vue +53 -0
- package/src/components/LpStat.vue +90 -0
- package/src/components/LpStepper.vue +46 -0
- package/src/components/LpSwitch.vue +19 -0
- package/src/components/LpTable.vue +252 -0
- package/src/components/LpTableOfContents.vue +183 -0
- package/src/components/LpTabs.vue +120 -0
- package/src/components/LpTextarea.vue +39 -0
- package/src/components/LpThemeSwitcher.vue +168 -0
- package/src/components/LpToaster.vue +216 -0
- package/src/components/LpTooltip.vue +30 -0
- package/src/components/LpTopologyCanvas.vue +370 -0
- package/src/components/LpUptimeBar.vue +126 -0
- package/src/components/codeHighlight.ts +137 -0
- package/src/components/countries-data.ts +207 -0
- package/src/components/countries.ts +67 -0
- package/src/components/dropdown.ts +64 -0
- package/src/components/sidebar.ts +26 -0
- package/src/composables/useInputFilter.ts +89 -0
- package/src/composables/usePillTransition.ts +19 -0
- package/src/composables/useToast.ts +92 -0
- package/src/icons.ts +11 -0
- package/src/index.css +21 -0
- package/src/index.ts +146 -0
- package/src/layout/registry.ts +44 -0
- package/src/layout/tree.ts +288 -0
- package/src/layout/useLayout.ts +134 -0
- package/src/nuxt.ts +22 -0
- package/src/theme/config.ts +48 -0
- package/src/theme/define.ts +50 -0
- package/src/theme/presets.ts +279 -0
- package/src/theme/tokens.ts +151 -0
- package/src/theme/useTheme.ts +288 -0
- package/src/tokens/scrollbar.css +138 -0
- package/src/tokens/tokens.css +333 -0
- package/src/tokens/utilities.css +23 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import type { Country } from "./countries"
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Country dial-code data — split out from countries.ts so it can be code-split
|
|
5
|
+
* into its own chunk and loaded lazily by LpPhoneInput (see loadCountries).
|
|
6
|
+
* E.164 calling codes, sorted by name. Not a substitute for full phone parsing.
|
|
7
|
+
*/
|
|
8
|
+
export const COUNTRIES: Country[] = [
|
|
9
|
+
{ iso2: "AF", name: "Afghanistan", dial: "93" },
|
|
10
|
+
{ iso2: "AL", name: "Albania", dial: "355" },
|
|
11
|
+
{ iso2: "DZ", name: "Algeria", dial: "213" },
|
|
12
|
+
{ iso2: "AD", name: "Andorra", dial: "376" },
|
|
13
|
+
{ iso2: "AO", name: "Angola", dial: "244" },
|
|
14
|
+
{ iso2: "AG", name: "Antigua and Barbuda", dial: "1268" },
|
|
15
|
+
{ iso2: "AR", name: "Argentina", dial: "54" },
|
|
16
|
+
{ iso2: "AM", name: "Armenia", dial: "374" },
|
|
17
|
+
{ iso2: "AU", name: "Australia", dial: "61" },
|
|
18
|
+
{ iso2: "AT", name: "Austria", dial: "43" },
|
|
19
|
+
{ iso2: "AZ", name: "Azerbaijan", dial: "994" },
|
|
20
|
+
{ iso2: "BS", name: "Bahamas", dial: "1242" },
|
|
21
|
+
{ iso2: "BH", name: "Bahrain", dial: "973" },
|
|
22
|
+
{ iso2: "BD", name: "Bangladesh", dial: "880" },
|
|
23
|
+
{ iso2: "BB", name: "Barbados", dial: "1246" },
|
|
24
|
+
{ iso2: "BY", name: "Belarus", dial: "375" },
|
|
25
|
+
{ iso2: "BE", name: "Belgium", dial: "32" },
|
|
26
|
+
{ iso2: "BZ", name: "Belize", dial: "501" },
|
|
27
|
+
{ iso2: "BJ", name: "Benin", dial: "229" },
|
|
28
|
+
{ iso2: "BT", name: "Bhutan", dial: "975" },
|
|
29
|
+
{ iso2: "BO", name: "Bolivia", dial: "591" },
|
|
30
|
+
{ iso2: "BA", name: "Bosnia and Herzegovina", dial: "387" },
|
|
31
|
+
{ iso2: "BW", name: "Botswana", dial: "267" },
|
|
32
|
+
{ iso2: "BR", name: "Brazil", dial: "55" },
|
|
33
|
+
{ iso2: "BN", name: "Brunei", dial: "673" },
|
|
34
|
+
{ iso2: "BG", name: "Bulgaria", dial: "359" },
|
|
35
|
+
{ iso2: "BF", name: "Burkina Faso", dial: "226" },
|
|
36
|
+
{ iso2: "BI", name: "Burundi", dial: "257" },
|
|
37
|
+
{ iso2: "KH", name: "Cambodia", dial: "855" },
|
|
38
|
+
{ iso2: "CM", name: "Cameroon", dial: "237" },
|
|
39
|
+
{ iso2: "CA", name: "Canada", dial: "1" },
|
|
40
|
+
{ iso2: "CV", name: "Cape Verde", dial: "238" },
|
|
41
|
+
{ iso2: "CF", name: "Central African Republic", dial: "236" },
|
|
42
|
+
{ iso2: "TD", name: "Chad", dial: "235" },
|
|
43
|
+
{ iso2: "CL", name: "Chile", dial: "56" },
|
|
44
|
+
{ iso2: "CN", name: "China", dial: "86" },
|
|
45
|
+
{ iso2: "CO", name: "Colombia", dial: "57" },
|
|
46
|
+
{ iso2: "KM", name: "Comoros", dial: "269" },
|
|
47
|
+
{ iso2: "CG", name: "Congo", dial: "242" },
|
|
48
|
+
{ iso2: "CD", name: "Congo (DRC)", dial: "243" },
|
|
49
|
+
{ iso2: "CR", name: "Costa Rica", dial: "506" },
|
|
50
|
+
{ iso2: "CI", name: "Côte d’Ivoire", dial: "225" },
|
|
51
|
+
{ iso2: "HR", name: "Croatia", dial: "385" },
|
|
52
|
+
{ iso2: "CU", name: "Cuba", dial: "53" },
|
|
53
|
+
{ iso2: "CY", name: "Cyprus", dial: "357" },
|
|
54
|
+
{ iso2: "CZ", name: "Czechia", dial: "420" },
|
|
55
|
+
{ iso2: "DK", name: "Denmark", dial: "45" },
|
|
56
|
+
{ iso2: "DJ", name: "Djibouti", dial: "253" },
|
|
57
|
+
{ iso2: "DM", name: "Dominica", dial: "1767" },
|
|
58
|
+
{ iso2: "DO", name: "Dominican Republic", dial: "1809" },
|
|
59
|
+
{ iso2: "EC", name: "Ecuador", dial: "593" },
|
|
60
|
+
{ iso2: "EG", name: "Egypt", dial: "20" },
|
|
61
|
+
{ iso2: "SV", name: "El Salvador", dial: "503" },
|
|
62
|
+
{ iso2: "GQ", name: "Equatorial Guinea", dial: "240" },
|
|
63
|
+
{ iso2: "ER", name: "Eritrea", dial: "291" },
|
|
64
|
+
{ iso2: "EE", name: "Estonia", dial: "372" },
|
|
65
|
+
{ iso2: "SZ", name: "Eswatini", dial: "268" },
|
|
66
|
+
{ iso2: "ET", name: "Ethiopia", dial: "251" },
|
|
67
|
+
{ iso2: "FJ", name: "Fiji", dial: "679" },
|
|
68
|
+
{ iso2: "FI", name: "Finland", dial: "358" },
|
|
69
|
+
{ iso2: "FR", name: "France", dial: "33" },
|
|
70
|
+
{ iso2: "GA", name: "Gabon", dial: "241" },
|
|
71
|
+
{ iso2: "GM", name: "Gambia", dial: "220" },
|
|
72
|
+
{ iso2: "GE", name: "Georgia", dial: "995" },
|
|
73
|
+
{ iso2: "DE", name: "Germany", dial: "49" },
|
|
74
|
+
{ iso2: "GH", name: "Ghana", dial: "233" },
|
|
75
|
+
{ iso2: "GR", name: "Greece", dial: "30" },
|
|
76
|
+
{ iso2: "GD", name: "Grenada", dial: "1473" },
|
|
77
|
+
{ iso2: "GT", name: "Guatemala", dial: "502" },
|
|
78
|
+
{ iso2: "GN", name: "Guinea", dial: "224" },
|
|
79
|
+
{ iso2: "GW", name: "Guinea-Bissau", dial: "245" },
|
|
80
|
+
{ iso2: "GY", name: "Guyana", dial: "592" },
|
|
81
|
+
{ iso2: "HT", name: "Haiti", dial: "509" },
|
|
82
|
+
{ iso2: "HN", name: "Honduras", dial: "504" },
|
|
83
|
+
{ iso2: "HK", name: "Hong Kong", dial: "852" },
|
|
84
|
+
{ iso2: "HU", name: "Hungary", dial: "36" },
|
|
85
|
+
{ iso2: "IS", name: "Iceland", dial: "354" },
|
|
86
|
+
{ iso2: "IN", name: "India", dial: "91" },
|
|
87
|
+
{ iso2: "ID", name: "Indonesia", dial: "62" },
|
|
88
|
+
{ iso2: "IR", name: "Iran", dial: "98" },
|
|
89
|
+
{ iso2: "IQ", name: "Iraq", dial: "964" },
|
|
90
|
+
{ iso2: "IE", name: "Ireland", dial: "353" },
|
|
91
|
+
{ iso2: "IL", name: "Israel", dial: "972" },
|
|
92
|
+
{ iso2: "IT", name: "Italy", dial: "39" },
|
|
93
|
+
{ iso2: "JM", name: "Jamaica", dial: "1876" },
|
|
94
|
+
{ iso2: "JP", name: "Japan", dial: "81" },
|
|
95
|
+
{ iso2: "JO", name: "Jordan", dial: "962" },
|
|
96
|
+
{ iso2: "KZ", name: "Kazakhstan", dial: "7" },
|
|
97
|
+
{ iso2: "KE", name: "Kenya", dial: "254" },
|
|
98
|
+
{ iso2: "KI", name: "Kiribati", dial: "686" },
|
|
99
|
+
{ iso2: "KW", name: "Kuwait", dial: "965" },
|
|
100
|
+
{ iso2: "KG", name: "Kyrgyzstan", dial: "996" },
|
|
101
|
+
{ iso2: "LA", name: "Laos", dial: "856" },
|
|
102
|
+
{ iso2: "LV", name: "Latvia", dial: "371" },
|
|
103
|
+
{ iso2: "LB", name: "Lebanon", dial: "961" },
|
|
104
|
+
{ iso2: "LS", name: "Lesotho", dial: "266" },
|
|
105
|
+
{ iso2: "LR", name: "Liberia", dial: "231" },
|
|
106
|
+
{ iso2: "LY", name: "Libya", dial: "218" },
|
|
107
|
+
{ iso2: "LI", name: "Liechtenstein", dial: "423" },
|
|
108
|
+
{ iso2: "LT", name: "Lithuania", dial: "370" },
|
|
109
|
+
{ iso2: "LU", name: "Luxembourg", dial: "352" },
|
|
110
|
+
{ iso2: "MO", name: "Macau", dial: "853" },
|
|
111
|
+
{ iso2: "MG", name: "Madagascar", dial: "261" },
|
|
112
|
+
{ iso2: "MW", name: "Malawi", dial: "265" },
|
|
113
|
+
{ iso2: "MY", name: "Malaysia", dial: "60" },
|
|
114
|
+
{ iso2: "MV", name: "Maldives", dial: "960" },
|
|
115
|
+
{ iso2: "ML", name: "Mali", dial: "223" },
|
|
116
|
+
{ iso2: "MT", name: "Malta", dial: "356" },
|
|
117
|
+
{ iso2: "MH", name: "Marshall Islands", dial: "692" },
|
|
118
|
+
{ iso2: "MR", name: "Mauritania", dial: "222" },
|
|
119
|
+
{ iso2: "MU", name: "Mauritius", dial: "230" },
|
|
120
|
+
{ iso2: "MX", name: "Mexico", dial: "52" },
|
|
121
|
+
{ iso2: "FM", name: "Micronesia", dial: "691" },
|
|
122
|
+
{ iso2: "MD", name: "Moldova", dial: "373" },
|
|
123
|
+
{ iso2: "MC", name: "Monaco", dial: "377" },
|
|
124
|
+
{ iso2: "MN", name: "Mongolia", dial: "976" },
|
|
125
|
+
{ iso2: "ME", name: "Montenegro", dial: "382" },
|
|
126
|
+
{ iso2: "MA", name: "Morocco", dial: "212" },
|
|
127
|
+
{ iso2: "MZ", name: "Mozambique", dial: "258" },
|
|
128
|
+
{ iso2: "MM", name: "Myanmar", dial: "95" },
|
|
129
|
+
{ iso2: "NA", name: "Namibia", dial: "264" },
|
|
130
|
+
{ iso2: "NR", name: "Nauru", dial: "674" },
|
|
131
|
+
{ iso2: "NP", name: "Nepal", dial: "977" },
|
|
132
|
+
{ iso2: "NL", name: "Netherlands", dial: "31" },
|
|
133
|
+
{ iso2: "NZ", name: "New Zealand", dial: "64" },
|
|
134
|
+
{ iso2: "NI", name: "Nicaragua", dial: "505" },
|
|
135
|
+
{ iso2: "NE", name: "Niger", dial: "227" },
|
|
136
|
+
{ iso2: "NG", name: "Nigeria", dial: "234" },
|
|
137
|
+
{ iso2: "KP", name: "North Korea", dial: "850" },
|
|
138
|
+
{ iso2: "MK", name: "North Macedonia", dial: "389" },
|
|
139
|
+
{ iso2: "NO", name: "Norway", dial: "47" },
|
|
140
|
+
{ iso2: "OM", name: "Oman", dial: "968" },
|
|
141
|
+
{ iso2: "PK", name: "Pakistan", dial: "92" },
|
|
142
|
+
{ iso2: "PW", name: "Palau", dial: "680" },
|
|
143
|
+
{ iso2: "PS", name: "Palestine", dial: "970" },
|
|
144
|
+
{ iso2: "PA", name: "Panama", dial: "507" },
|
|
145
|
+
{ iso2: "PG", name: "Papua New Guinea", dial: "675" },
|
|
146
|
+
{ iso2: "PY", name: "Paraguay", dial: "595" },
|
|
147
|
+
{ iso2: "PE", name: "Peru", dial: "51" },
|
|
148
|
+
{ iso2: "PH", name: "Philippines", dial: "63" },
|
|
149
|
+
{ iso2: "PL", name: "Poland", dial: "48" },
|
|
150
|
+
{ iso2: "PT", name: "Portugal", dial: "351" },
|
|
151
|
+
{ iso2: "QA", name: "Qatar", dial: "974" },
|
|
152
|
+
{ iso2: "RO", name: "Romania", dial: "40" },
|
|
153
|
+
{ iso2: "RU", name: "Russia", dial: "7" },
|
|
154
|
+
{ iso2: "RW", name: "Rwanda", dial: "250" },
|
|
155
|
+
{ iso2: "KN", name: "Saint Kitts and Nevis", dial: "1869" },
|
|
156
|
+
{ iso2: "LC", name: "Saint Lucia", dial: "1758" },
|
|
157
|
+
{ iso2: "VC", name: "Saint Vincent and the Grenadines", dial: "1784" },
|
|
158
|
+
{ iso2: "WS", name: "Samoa", dial: "685" },
|
|
159
|
+
{ iso2: "SM", name: "San Marino", dial: "378" },
|
|
160
|
+
{ iso2: "ST", name: "São Tomé and Príncipe", dial: "239" },
|
|
161
|
+
{ iso2: "SA", name: "Saudi Arabia", dial: "966" },
|
|
162
|
+
{ iso2: "SN", name: "Senegal", dial: "221" },
|
|
163
|
+
{ iso2: "RS", name: "Serbia", dial: "381" },
|
|
164
|
+
{ iso2: "SC", name: "Seychelles", dial: "248" },
|
|
165
|
+
{ iso2: "SL", name: "Sierra Leone", dial: "232" },
|
|
166
|
+
{ iso2: "SG", name: "Singapore", dial: "65" },
|
|
167
|
+
{ iso2: "SK", name: "Slovakia", dial: "421" },
|
|
168
|
+
{ iso2: "SI", name: "Slovenia", dial: "386" },
|
|
169
|
+
{ iso2: "SB", name: "Solomon Islands", dial: "677" },
|
|
170
|
+
{ iso2: "SO", name: "Somalia", dial: "252" },
|
|
171
|
+
{ iso2: "ZA", name: "South Africa", dial: "27" },
|
|
172
|
+
{ iso2: "KR", name: "South Korea", dial: "82" },
|
|
173
|
+
{ iso2: "SS", name: "South Sudan", dial: "211" },
|
|
174
|
+
{ iso2: "ES", name: "Spain", dial: "34" },
|
|
175
|
+
{ iso2: "LK", name: "Sri Lanka", dial: "94" },
|
|
176
|
+
{ iso2: "SD", name: "Sudan", dial: "249" },
|
|
177
|
+
{ iso2: "SR", name: "Suriname", dial: "597" },
|
|
178
|
+
{ iso2: "SE", name: "Sweden", dial: "46" },
|
|
179
|
+
{ iso2: "CH", name: "Switzerland", dial: "41" },
|
|
180
|
+
{ iso2: "SY", name: "Syria", dial: "963" },
|
|
181
|
+
{ iso2: "TW", name: "Taiwan", dial: "886" },
|
|
182
|
+
{ iso2: "TJ", name: "Tajikistan", dial: "992" },
|
|
183
|
+
{ iso2: "TZ", name: "Tanzania", dial: "255" },
|
|
184
|
+
{ iso2: "TH", name: "Thailand", dial: "66" },
|
|
185
|
+
{ iso2: "TL", name: "Timor-Leste", dial: "670" },
|
|
186
|
+
{ iso2: "TG", name: "Togo", dial: "228" },
|
|
187
|
+
{ iso2: "TO", name: "Tonga", dial: "676" },
|
|
188
|
+
{ iso2: "TT", name: "Trinidad and Tobago", dial: "1868" },
|
|
189
|
+
{ iso2: "TN", name: "Tunisia", dial: "216" },
|
|
190
|
+
{ iso2: "TR", name: "Turkey", dial: "90" },
|
|
191
|
+
{ iso2: "TM", name: "Turkmenistan", dial: "993" },
|
|
192
|
+
{ iso2: "TV", name: "Tuvalu", dial: "688" },
|
|
193
|
+
{ iso2: "UG", name: "Uganda", dial: "256" },
|
|
194
|
+
{ iso2: "UA", name: "Ukraine", dial: "380" },
|
|
195
|
+
{ iso2: "AE", name: "United Arab Emirates", dial: "971" },
|
|
196
|
+
{ iso2: "GB", name: "United Kingdom", dial: "44" },
|
|
197
|
+
{ iso2: "US", name: "United States", dial: "1" },
|
|
198
|
+
{ iso2: "UY", name: "Uruguay", dial: "598" },
|
|
199
|
+
{ iso2: "UZ", name: "Uzbekistan", dial: "998" },
|
|
200
|
+
{ iso2: "VU", name: "Vanuatu", dial: "678" },
|
|
201
|
+
{ iso2: "VA", name: "Vatican City", dial: "39" },
|
|
202
|
+
{ iso2: "VE", name: "Venezuela", dial: "58" },
|
|
203
|
+
{ iso2: "VN", name: "Vietnam", dial: "84" },
|
|
204
|
+
{ iso2: "YE", name: "Yemen", dial: "967" },
|
|
205
|
+
{ iso2: "ZM", name: "Zambia", dial: "260" },
|
|
206
|
+
{ iso2: "ZW", name: "Zimbabwe", dial: "263" },
|
|
207
|
+
]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Lightweight country helpers for LpPhoneInput. The heavy dial-code TABLE lives
|
|
3
|
+
* in ./countries-data.ts and is loaded lazily via loadCountries() so it lands in
|
|
4
|
+
* its own chunk — apps that never render a phone field don't pay for it. Only the
|
|
5
|
+
* type + tiny pure helpers stay here (importing these does not pull the data).
|
|
6
|
+
*/
|
|
7
|
+
export interface Country {
|
|
8
|
+
/** ISO 3166-1 alpha-2, uppercase (e.g. "US"). Drives the flag. */
|
|
9
|
+
iso2: string
|
|
10
|
+
name: string
|
|
11
|
+
/** Calling code without "+", e.g. "1", "44", "380". */
|
|
12
|
+
dial: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Turn an ISO2 code into its flag emoji (two regional-indicator symbols). */
|
|
16
|
+
export function flagEmoji(iso2: string): string {
|
|
17
|
+
if (!/^[A-Za-z]{2}$/.test(iso2)) return ""
|
|
18
|
+
const base = 0x1f1e6 - 0x41 // regional indicator 'A' minus ASCII 'A'
|
|
19
|
+
return String.fromCodePoint(
|
|
20
|
+
...iso2.toUpperCase().split("").map((c) => base + c.charCodeAt(0)),
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let cache: Country[] | undefined
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Load the country table (code-split chunk). Cached after first call, so repeat
|
|
28
|
+
* calls are synchronous-ish (resolved promise) with no re-import cost.
|
|
29
|
+
*/
|
|
30
|
+
export async function loadCountries(): Promise<Country[]> {
|
|
31
|
+
if (cache) return cache
|
|
32
|
+
const mod = await import("./countries-data")
|
|
33
|
+
cache = mod.COUNTRIES
|
|
34
|
+
return cache
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Several countries share a dial code (notably NANP "+1" → US, CA, …). Without
|
|
38
|
+
// area-code parsing we can't disambiguate, so we pick a sensible primary per
|
|
39
|
+
// shared code. Anything not listed falls back to the first list match.
|
|
40
|
+
const PRIMARY_BY_DIAL: Record<string, string> = {
|
|
41
|
+
"1": "US",
|
|
42
|
+
"7": "RU",
|
|
43
|
+
"39": "IT",
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Best-effort: pick the country whose dial code prefixes the given E.164-ish
|
|
48
|
+
* value (longest match wins, so "1868" beats "1"). For shared codes the primary
|
|
49
|
+
* country is preferred. Pass the list (from loadCountries). Undefined if none.
|
|
50
|
+
*/
|
|
51
|
+
export function matchCountryByValue(
|
|
52
|
+
value: string,
|
|
53
|
+
list: Country[],
|
|
54
|
+
): Country | undefined {
|
|
55
|
+
const digits = value.replace(/[^\d]/g, "")
|
|
56
|
+
if (!digits) return undefined
|
|
57
|
+
let best: Country | undefined
|
|
58
|
+
for (const c of list) {
|
|
59
|
+
if (!digits.startsWith(c.dial)) continue
|
|
60
|
+
if (!best || c.dial.length > best.dial.length) {
|
|
61
|
+
best = c
|
|
62
|
+
} else if (c.dial.length === best.dial.length && PRIMARY_BY_DIAL[c.dial] === c.iso2) {
|
|
63
|
+
best = c // same length, but this one is the designated primary
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return best
|
|
67
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Shared class strings for floating panels (the dropdown/popover surface) and
|
|
3
|
+
* their option rows. These were copy-pasted across LpSelect, LpAutocomplete,
|
|
4
|
+
* LpPhoneInput, LpPopover and LpDropdownMenu — one source of truth means a tweak
|
|
5
|
+
* to the look or the side-aware enter/exit animation lands everywhere at once.
|
|
6
|
+
*
|
|
7
|
+
* The panel is built on different reka primitives per component (Combobox /
|
|
8
|
+
* Popover / DropdownMenu content), so we share CLASSES, not a wrapper component.
|
|
9
|
+
* Callers still own per-use bits: width, padding, overflow, and which primitive.
|
|
10
|
+
*
|
|
11
|
+
* IMPORTANT: a panel that hosts an option cascade must include `group` (it's in
|
|
12
|
+
* POPOVER_PANEL) so each OPTION_ITEM can read the panel's data-side and cascade
|
|
13
|
+
* the right way when the list flips above the trigger.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/** Enter/exit animation for state-open panels (Select, Popover, Dropdown, …). */
|
|
17
|
+
export const POPOVER_ANIM =
|
|
18
|
+
"data-[state=open]:animate-[popover-in_140ms_var(--ease-emphasized)] " +
|
|
19
|
+
"data-[state=closed]:animate-[popover-out_120ms_ease] " +
|
|
20
|
+
"data-[side=top]:data-[state=open]:animate-[popover-in-up_140ms_var(--ease-emphasized)] " +
|
|
21
|
+
"data-[side=top]:data-[state=closed]:animate-[popover-out-up_120ms_ease]"
|
|
22
|
+
|
|
23
|
+
/** Tooltip variant: faster, and reka uses `delayed-open` instead of `open`. */
|
|
24
|
+
export const TOOLTIP_ANIM =
|
|
25
|
+
"data-[state=delayed-open]:animate-[popover-in_120ms_var(--ease-emphasized)] " +
|
|
26
|
+
"data-[state=closed]:animate-[popover-out_100ms_ease] " +
|
|
27
|
+
"data-[side=top]:data-[state=delayed-open]:animate-[popover-in-up_120ms_var(--ease-emphasized)] " +
|
|
28
|
+
"data-[side=top]:data-[state=closed]:animate-[popover-out-up_100ms_ease]"
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The bare floating surface (border, raised overlay fill, blur, shadow) without
|
|
32
|
+
* any animation — pair with POPOVER_ANIM or TOOLTIP_ANIM. `group` lets option
|
|
33
|
+
* rows read the panel's data-side for the cascade direction.
|
|
34
|
+
*/
|
|
35
|
+
export const PANEL_SURFACE =
|
|
36
|
+
"group rounded-control border border-line bg-surface-overlay shadow-panel backdrop-blur"
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Surface + the state-open animation. Add width/padding/overflow and the z-layer
|
|
40
|
+
* at the call-site (z-layer omitted so tooltips can use z-(--z-tooltip) while the
|
|
41
|
+
* rest use z-(--z-popover)).
|
|
42
|
+
*/
|
|
43
|
+
export const POPOVER_PANEL = PANEL_SURFACE + " " + POPOVER_ANIM
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A selectable option row: layout, highlight state, and the staggered cascade.
|
|
47
|
+
* Cascades downward by default and upward when the panel is flipped above the
|
|
48
|
+
* trigger (group-data-[side=top]). Pair with an inline animationDelay for the
|
|
49
|
+
* stagger. `flex` + gap are included; add justify/extra layout if needed.
|
|
50
|
+
*/
|
|
51
|
+
export const OPTION_ITEM =
|
|
52
|
+
"flex cursor-pointer items-center gap-2 rounded-md px-2.5 py-1.5 text-sm text-ink outline-none " +
|
|
53
|
+
"animate-[option-in_180ms_var(--ease-emphasized)_both] " +
|
|
54
|
+
"group-data-[side=top]:animate-[option-in-up_180ms_var(--ease-emphasized)_both] " +
|
|
55
|
+
"data-[highlighted]:bg-brand-soft data-[highlighted]:text-brand"
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Micro-animation for a close / clear "✕" icon: a quarter-turn on hover and a
|
|
59
|
+
* dip on press. Put on the <LpIcon>, with `group` on its button. Shared by
|
|
60
|
+
* Modal, Drawer, Toaster and the Autocomplete clear button.
|
|
61
|
+
*/
|
|
62
|
+
export const CLOSE_ICON =
|
|
63
|
+
"transition-transform duration-medium ease-[var(--ease-emphasized)] " +
|
|
64
|
+
"group-hover:rotate-90 group-active:scale-90 motion-reduce:group-hover:rotate-0"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Shared sidebar types. Lives in its own module so LpSidebar and its internal
|
|
3
|
+
* LpSidebarNav body can both import them without a component-to-component cycle.
|
|
4
|
+
* Re-exported from LpSidebar.vue for back-compat with existing import sites.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ContextMenuItemDef } from "./LpContextMenu.vue"
|
|
8
|
+
|
|
9
|
+
export interface SidebarItem {
|
|
10
|
+
id: string
|
|
11
|
+
label: string
|
|
12
|
+
icon?: string
|
|
13
|
+
/** Render as a link instead of a button. */
|
|
14
|
+
href?: string
|
|
15
|
+
/** Count chip on the right (number or short string). */
|
|
16
|
+
badge?: number | string
|
|
17
|
+
disabled?: boolean
|
|
18
|
+
/** Right-click menu for this item (e.g. "Open in new tab", "Pin"). */
|
|
19
|
+
menu?: ContextMenuItemDef[]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface SidebarSection {
|
|
23
|
+
/** Optional heading above the group. */
|
|
24
|
+
title?: string
|
|
25
|
+
items: SidebarItem[]
|
|
26
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { computed, type MaybeRefOrGetter, toValue } from "vue"
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Cursor- and IME-safe input filtering + pattern validation for native <input>.
|
|
5
|
+
*
|
|
6
|
+
* Two orthogonal jobs:
|
|
7
|
+
*
|
|
8
|
+
* restrict — a character class (RegExp matching ONE allowed char, e.g. /[0-9]/)
|
|
9
|
+
* that hard-blocks disallowed input. We cancel the offending `beforeinput`
|
|
10
|
+
* instead of rewriting `value` after the fact: rewriting moves the caret to
|
|
11
|
+
* the end and aborts IME composition. By vetoing the event the browser never
|
|
12
|
+
* applies the bad edit, so the caret and any in-flight composition stay put.
|
|
13
|
+
*
|
|
14
|
+
* pattern — a RegExp the WHOLE value must match to be considered valid. This
|
|
15
|
+
* never blocks typing; it only drives the invalid state (border + aria), so
|
|
16
|
+
* partially-typed values aren't punished mid-entry — the caller decides when
|
|
17
|
+
* to surface it.
|
|
18
|
+
*
|
|
19
|
+
* A bare string pattern is treated as a full-string match (anchored), mirroring
|
|
20
|
+
* the native HTML `pattern` attribute.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
export interface UseInputFilterOptions {
|
|
24
|
+
/** One-char RegExp of allowed characters. Disallowed input is blocked. */
|
|
25
|
+
restrict?: MaybeRefOrGetter<RegExp | undefined>
|
|
26
|
+
/** RegExp/string the full value must match to be valid. Validation only. */
|
|
27
|
+
pattern?: MaybeRefOrGetter<RegExp | string | undefined>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function toAnchored(p: RegExp | string): RegExp {
|
|
31
|
+
if (p instanceof RegExp) {
|
|
32
|
+
// Re-anchor so `pattern` validates the whole string, like HTML's attribute.
|
|
33
|
+
const src = p.source.replace(/^\^/, "").replace(/\$$/, "")
|
|
34
|
+
return new RegExp(`^(?:${src})$`, p.flags.replace(/[gy]/g, ""))
|
|
35
|
+
}
|
|
36
|
+
return new RegExp(`^(?:${p})$`)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Does a string contain only restrict-allowed characters? */
|
|
40
|
+
function allAllowed(text: string, charRe: RegExp): boolean {
|
|
41
|
+
// Strip g/y so lastIndex can't leak state across .test() calls, then reuse
|
|
42
|
+
// the one instance per char (tested by code point, so surrogate pairs hold).
|
|
43
|
+
const re = new RegExp(charRe.source, charRe.flags.replace(/[gy]/g, ""))
|
|
44
|
+
for (const ch of text) {
|
|
45
|
+
if (!re.test(ch)) return false
|
|
46
|
+
}
|
|
47
|
+
return true
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function useInputFilter(options: UseInputFilterOptions = {}) {
|
|
51
|
+
const restrict = computed(() => toValue(options.restrict))
|
|
52
|
+
const patternRe = computed(() => {
|
|
53
|
+
const p = toValue(options.pattern)
|
|
54
|
+
return p === undefined ? undefined : toAnchored(p)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
/** True when a non-empty value fails `pattern`. Empty is treated as valid. */
|
|
58
|
+
function isInvalid(value: string | undefined): boolean {
|
|
59
|
+
const re = patternRe.value
|
|
60
|
+
if (!re || !value) return false
|
|
61
|
+
return !re.test(value)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Attach to the input's `beforeinput`. Vetoes edits that would introduce a
|
|
66
|
+
* disallowed character. No-op while composing (IME) or when no restrict set.
|
|
67
|
+
*/
|
|
68
|
+
function onBeforeInput(event: InputEvent): void {
|
|
69
|
+
const re = restrict.value
|
|
70
|
+
if (!re || event.isComposing) return
|
|
71
|
+
// Deletions / formatting carry no data to validate; let them through.
|
|
72
|
+
const data = event.data
|
|
73
|
+
if (data == null) return
|
|
74
|
+
if (!allAllowed(data, re)) event.preventDefault()
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Attach to `paste`. Veto the paste if any pasted char is disallowed, rather
|
|
79
|
+
* than silently dropping part of it — partial pastes confuse more than help.
|
|
80
|
+
*/
|
|
81
|
+
function onPaste(event: ClipboardEvent): void {
|
|
82
|
+
const re = restrict.value
|
|
83
|
+
if (!re) return
|
|
84
|
+
const text = event.clipboardData?.getData("text") ?? ""
|
|
85
|
+
if (text && !allAllowed(text, re)) event.preventDefault()
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return { isInvalid, onBeforeInput, onPaste, patternRe, restrict }
|
|
89
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useReducedMotion } from "motion-v"
|
|
2
|
+
import { computed, type ComputedRef } from "vue"
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* Shared motion-v transition for the sliding "pill" indicator used by LpTabs,
|
|
6
|
+
* LpSegmented and LpPagination (a shared layoutId element that flies under the
|
|
7
|
+
* active item). One spring keeps the feel identical across them; it collapses to
|
|
8
|
+
* an instant move when the OS prefers reduced motion.
|
|
9
|
+
*/
|
|
10
|
+
export type PillTransition =
|
|
11
|
+
| { duration: number }
|
|
12
|
+
| { type: "spring"; stiffness: number; damping: number }
|
|
13
|
+
|
|
14
|
+
export function usePillTransition(): ComputedRef<PillTransition> {
|
|
15
|
+
const reduceMotion = useReducedMotion()
|
|
16
|
+
return computed<PillTransition>(() =>
|
|
17
|
+
reduceMotion.value ? { duration: 0 } : { type: "spring", stiffness: 520, damping: 40 },
|
|
18
|
+
)
|
|
19
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { reactive } from "vue"
|
|
2
|
+
|
|
3
|
+
export type ToastVariant = "info" | "success" | "warning" | "error"
|
|
4
|
+
|
|
5
|
+
export interface ToastAction {
|
|
6
|
+
label: string
|
|
7
|
+
onClick: () => void | Promise<void>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ToastItem {
|
|
11
|
+
id: number
|
|
12
|
+
title?: string
|
|
13
|
+
message: string
|
|
14
|
+
variant: ToastVariant
|
|
15
|
+
duration: number
|
|
16
|
+
/** Epoch ms when this toast auto-dismisses, or null if it never does. */
|
|
17
|
+
dismissAt: number | null
|
|
18
|
+
actions?: ToastAction[]
|
|
19
|
+
/** Whole-toast click handler (UAProject-style clickable toast). */
|
|
20
|
+
onClick?: () => void | Promise<void>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ToastOptions {
|
|
24
|
+
title?: string
|
|
25
|
+
duration?: number
|
|
26
|
+
actions?: ToastAction[]
|
|
27
|
+
onClick?: () => void | Promise<void>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const DEFAULT_DURATION = 4500
|
|
31
|
+
const MAX_ACTIVE = 4
|
|
32
|
+
|
|
33
|
+
// Pin the queue to a global symbol so the singleton survives module
|
|
34
|
+
// duplication (a barrel import and a deep import can otherwise resolve to two
|
|
35
|
+
// module instances, each with its own state — the toasts-never-show footgun).
|
|
36
|
+
const STATE_KEY = Symbol.for("@leavepulse/ui:toast-queue")
|
|
37
|
+
type GlobalWithQueue = typeof globalThis & {
|
|
38
|
+
[STATE_KEY]?: { queue: ToastItem[]; nextId: number }
|
|
39
|
+
}
|
|
40
|
+
const g = globalThis as GlobalWithQueue
|
|
41
|
+
const state = (g[STATE_KEY] ??= { queue: reactive<ToastItem[]>([]), nextId: 0 })
|
|
42
|
+
const queue = state.queue
|
|
43
|
+
|
|
44
|
+
function push(
|
|
45
|
+
variant: ToastVariant,
|
|
46
|
+
message: string,
|
|
47
|
+
options: ToastOptions = {},
|
|
48
|
+
): number {
|
|
49
|
+
const id = state.nextId++
|
|
50
|
+
const duration = options.duration ?? DEFAULT_DURATION
|
|
51
|
+
const item: ToastItem = {
|
|
52
|
+
id,
|
|
53
|
+
title: options.title,
|
|
54
|
+
message,
|
|
55
|
+
variant,
|
|
56
|
+
duration,
|
|
57
|
+
dismissAt: duration > 0 ? Date.now() + duration : null,
|
|
58
|
+
actions: options.actions,
|
|
59
|
+
onClick: options.onClick,
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Cap the active count: drop the oldest beyond the limit.
|
|
63
|
+
const overflow = queue.length - (MAX_ACTIVE - 1)
|
|
64
|
+
if (overflow > 0) queue.splice(0, overflow)
|
|
65
|
+
queue.push(item)
|
|
66
|
+
|
|
67
|
+
return id
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function dismiss(id: number): void {
|
|
71
|
+
const i = queue.findIndex((t) => t.id === id)
|
|
72
|
+
if (i !== -1) queue.splice(i, 1)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function clear(): void {
|
|
76
|
+
queue.splice(0, queue.length)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function useToast() {
|
|
80
|
+
return {
|
|
81
|
+
queue,
|
|
82
|
+
toast: (message: string, o?: ToastOptions) => push("info", message, o),
|
|
83
|
+
info: (message: string, o?: ToastOptions) => push("info", message, o),
|
|
84
|
+
success: (message: string, o?: ToastOptions) => push("success", message, o),
|
|
85
|
+
warning: (message: string, o?: ToastOptions) => push("warning", message, o),
|
|
86
|
+
error: (message: string, o?: ToastOptions) => push("error", message, o),
|
|
87
|
+
/** Low-level push for bridges (e.g. @leavepulse/ui-sdk apiError). */
|
|
88
|
+
push,
|
|
89
|
+
dismiss,
|
|
90
|
+
clear,
|
|
91
|
+
}
|
|
92
|
+
}
|
package/src/icons.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { addCollection } from "@iconify/vue"
|
|
2
|
+
import lucide from "@iconify-json/lucide/icons.json"
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* Register the lucide collection offline so <LpIcon name="lucide:*"> resolves
|
|
6
|
+
* without hitting the iconify API (required for Tauri / air-gapped use).
|
|
7
|
+
*
|
|
8
|
+
* This pulls the whole lucide set. If bundle size matters in an app, replace
|
|
9
|
+
* this with a curated subset via addIcon() — the LpIcon API is unchanged.
|
|
10
|
+
*/
|
|
11
|
+
addCollection(lucide as Parameters<typeof addCollection>[0])
|
package/src/index.css
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Public CSS entry for @leavepulse/ui — what `@import "@leavepulse/ui"`
|
|
3
|
+
* resolves to (see the "." export's "style" field and "./css").
|
|
4
|
+
*
|
|
5
|
+
* Mirrors how @nuxt/ui ships styles: the consumer owns Tailwind, the kit owns
|
|
6
|
+
* its tokens + a @source over its own components. So this file deliberately
|
|
7
|
+
* does NOT `@import "tailwindcss"` — the consuming app does that once, then
|
|
8
|
+
* imports this. The @source makes the consumer's Tailwind build emit the
|
|
9
|
+
* utilities our components use (node_modules isn't scanned by default).
|
|
10
|
+
*
|
|
11
|
+
* Consumer usage:
|
|
12
|
+
* @import "tailwindcss";
|
|
13
|
+
* @import "@leavepulse/ui";
|
|
14
|
+
*/
|
|
15
|
+
@import "./tokens/tokens.css";
|
|
16
|
+
@import "./tokens/utilities.css";
|
|
17
|
+
|
|
18
|
+
@source "./components";
|
|
19
|
+
@source "./composables";
|
|
20
|
+
@source "./layout";
|
|
21
|
+
@source "./theme";
|