imba-localization 0.2.8 → 0.3.1

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/README.md CHANGED
@@ -11,7 +11,7 @@ A lightweight Imba module for loading and handling JSON-based localization files
11
11
  - 🧠 **Intuitive access** - Proxy-based access to translation strings
12
12
  - 📡 **Event handling** - Support for `onready`, `onchange`, and `onerror` events
13
13
  - 🚀 **Simple integration** - Easy to use in any Imba-based web application
14
- - 🧩 **`<LocalizationSelector>`** - Plug and play component for switching languages
14
+ - 🧩 **`<language-selector>`** - Plug and play tag component for switching languages
15
15
 
16
16
  ## 📘 Notes
17
17
 
@@ -54,10 +54,10 @@ Add this to your HTML head to load the localization file simultaneously with you
54
54
 
55
55
  ```imba
56
56
  # app.imba
57
- import { LocalizationState } from 'imba-localization'
57
+ import { Localization } from 'imba-localization'
58
58
 
59
59
  # Create an instance with the JSON URL and optional default language
60
- const loc = new LocalizationState("path/to/lang.json", "en")
60
+ const loc = new Localization("path/to/lang.json", "en")
61
61
 
62
62
  # Set up event handlers
63
63
  loc.onready = do
@@ -69,7 +69,7 @@ loc.onready = do
69
69
  console.log loc['user']['profile'] # Accessing nested properties
70
70
 
71
71
  loc.onerror = do(error, details)
72
- # The LocalizationState object can return following types of errors:
72
+ # The Localization object can return following types of errors:
73
73
  # 'no_localization_file' - if there were a problem when downloading JSON file
74
74
  # 'no_default_localization' - if there is no localization in the file for the default language
75
75
  # 'no_localization_key' - if there is no requiered (from the interface) key in the file
@@ -123,7 +123,7 @@ Your localization file should follow this format:
123
123
  ### Constructor
124
124
 
125
125
  ```imba
126
- new LocalizationState(url, default = 'en')
126
+ new Localization(url, default = 'en')
127
127
  ```
128
128
 
129
129
  - `url`: Path to your JSON localization file
@@ -148,13 +148,15 @@ new LocalizationState(url, default = 'en')
148
148
  A customizable dropdown component that allows users to select from available in the JSON localization file languages.
149
149
 
150
150
  ```imba
151
- import { LocalizationState, LocalizationSelector } from 'imba-localization'
152
- const loc = new LocalizationState("path/to/lang.json", "en")
151
+ import { Localization } from 'imba-localization'
152
+ const loc = new Localization("path/to/lang.json", "en")
153
153
 
154
- # In your UI component
154
+ # after importing Localization object
155
+ # <language-selector> tag will be available
156
+ # in any of you project your UI component
155
157
  tag AppHeader
156
158
  <self>
157
- <LocalizationSelector state=loc> # state attribute is mandatory
159
+ <language-selector state=loc> # state attribute is mandatory
158
160
  ```
159
161
 
160
162
  To make this component work as intended, your JSON file will need some adjustments. For each supported language you will need to define the display name for the language and also the country code for the flag to show (for example `en` language is used in `gb` and `us` countries):
@@ -189,8 +191,11 @@ css
189
191
  .main-arrow
190
192
  w:16px h:16px ml:auto
191
193
  fill:light-dark(#000000,#FFFFFF)
192
- scale-y:-1
193
- ead:$ease
194
+ transition: transform $ease ease
195
+ .main-arrow-passive
196
+ scale-y:-1
197
+ .main-arrow-active
198
+ scale-y:1
194
199
  .menu
195
200
  t:100% l:50% x:-50% mt:2px rd:8px rd:8px py:5px zi:999
196
201
  fw:500 fs:13px
@@ -206,14 +211,19 @@ css
206
211
  .menu-item-text
207
212
  fs:13px
208
213
  ```
209
- LanguageSelector can be easily customized through CSS and Imba tag (class) inheritance. Here how the above classes can be adjusted via the inheritance:
214
+ `<language-selector>` can be easily customized through CSS and Imba tag (class) inheritance. Here how the above classes can be adjusted via the inheritance, or through CSS selectors:
210
215
 
211
216
  ```imba
212
- import { LocalizationState, LocalizationSelector } from 'imba-localization'
213
- const loc = new LocalizationState("path/to/lang.json", "en")
217
+
218
+ import { Localization } from 'imba-localization'
219
+ const loc = new Localization("path/to/lang.json", "en")
220
+
221
+ # --------------------
222
+ # Inheritance
223
+ # --------------------
214
224
 
215
225
  # Create an inheritent class
216
- tag Languages < LocalizationSelector
226
+ tag custom-languages < language-selector
217
227
  css
218
228
  $ease: 1s
219
229
  .menu-item rd:2px
@@ -222,7 +232,34 @@ tag Languages < LocalizationSelector
222
232
  # Using the adjusted component
223
233
  tag MyApp
224
234
  <self>
225
- <Languages state=loc>
235
+ <custom-languages state=loc>
236
+
237
+
238
+ # --------------------
239
+ # CSS selectors
240
+ # --------------------
241
+
242
+ global css
243
+ language-selector
244
+ @not(#_) # is needed for higher precedence
245
+ .main
246
+ bgc: #992033
247
+ bd: 1px solid #992033
248
+ .main-active
249
+ bgc: blue2
250
+ bd: 1px solid #992033
251
+ .menu
252
+ bgc: #992033
253
+ bd: 1px solid #992033
254
+ .menu-item
255
+ bgc@hover: orange4
256
+ c@hover: black
257
+
258
+ # Using component that will be restyled
259
+ tag MyApp
260
+ <self>
261
+ <language-selector state=loc>
262
+
226
263
  ```
227
264
 
228
265
  #### Flag collections
@@ -230,7 +267,7 @@ tag MyApp
230
267
  You can redefine the collection of flag icons through the `icons` attribute:
231
268
 
232
269
  ```imba
233
- <LocalizationSelector icons='https://flagicons.lipis.dev/flags/4x3/##.svg'>
270
+ <language-selector icons='https://flagicons.lipis.dev/flags/4x3/##.svg'>
234
271
  ```
235
272
  There are many flag collections out there:
236
273
  - https://kapowaz.github.io/square-flags/flags/##.svg (default one)
@@ -247,13 +284,12 @@ You can use any other collection you prefer, just change the actual country code
247
284
  You can use any arrow icon you prefer (or remove it though CSS) by passing a tag of the image to the LanguageSelector `arrow` attribute:
248
285
 
249
286
  ```imba
250
- tag SomeIcon
251
- <self>
252
- <svg viewBox="..." xmlns="http://www.w3.org/2000/svg">
253
- <path d="...">
287
+ const arrow =
288
+ <svg viewBox="..." xmlns="http://www.w3.org/2000/svg">
289
+ <path d="...">
254
290
 
255
291
 
256
- <LocalizationSelector arrow=SomeIcon>
292
+ <language-selector arrow=arrow>
257
293
  ```
258
294
 
259
295
  ### ArrowIcon
@@ -261,10 +297,10 @@ tag SomeIcon
261
297
  The default arrow icon used in the LocalizationSelector component is available as a separate icon (in case for some reason you don't want to use [imba-phosphor-icons](https://www.npmjs.com/package/imba-phosphor-icons) package by Sindre).
262
298
 
263
299
  ```imba
264
- import {ArrowIcon} from 'imba-localization'
300
+ import {svg-arrow-down} from 'imba-localization'
265
301
 
266
302
  tag App
267
303
  <self>
268
- <ArrowIcon>
304
+ <{svg-arrow-down}>
269
305
  css w:20px h:20px stroke:red
270
306
  ```
package/localization.imba CHANGED
@@ -49,4 +49,54 @@ export class Localization
49
49
  name = name and languages[name] ? name : active
50
50
  if window.localStorage.getItem('imba-localization') != name
51
51
  window.localStorage.setItem('imba-localization', name)
52
- onchange(name) if onchange isa Function
52
+ onchange(name) if onchange isa Function
53
+
54
+ export const svg-arrow-down =
55
+ <svg viewBox="0 0 256 256">
56
+ <path d="M213.66,165.66a8,8,0,0,1-11.32,0L128,91.31,53.66,165.66a8,8,0,0,1-11.32-11.32l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,213.66,165.66Z">
57
+
58
+ tag language-selector
59
+ state
60
+ icons = "https://kapowaz.github.io/square-flags/flags/##.svg"
61
+ #dropdown = false
62
+ arrow = svg-arrow-down
63
+
64
+ def onselect key
65
+ #dropdown = false
66
+ state.active = key
67
+
68
+ css
69
+ $ease: 0.5s
70
+ .main rd:8px px:15px py:8px cursor:pointer bgc:light-dark(#000000/10, #FFFFFF/20) fw:500 fs:13px ead:$ease
71
+ .main-active bgc:light-dark(#000000/20, #FFFFFF/30)
72
+ .main-flag mr:10px rd:50% w:20px h:20px
73
+ .main-name mr:10px
74
+ .main-arrow w:16px h:16px fill:light-dark(#000000,#FFFFFF) ml:auto transition: transform $ease ease
75
+ .main-arrow-passive scale-y:-1
76
+ .main-arrow-active scale-y:1
77
+ .menu t:100% l:50% x:-50% zi:999 backdrop-filter:blur(20px) mt:2px rd:8px rd:8px py:5px bgc:light-dark(#000000/5, #FFFFFF/10) fw:500 fs:13px ead:$ease
78
+ .menu-item d:hflex ai:center px:10px py:5px rd:8px cursor:pointer bg@hover:light-dark(#000000/10, #FFFFFF/20) m:5px
79
+ .menu-item-icon h:20px w:20px mr:10px rd:50%
80
+ .menu-item-text fs:13px
81
+
82
+ def icon country
83
+ return icons.replace('##',country)
84
+
85
+ def mouseleave e
86
+ const rect = self.getBoundingClientRect!
87
+ const menu = $menu.getBoundingClientRect!
88
+ const inside = e.clientY >= menu.bottom || e.clientY <= rect.top || (e.clientX <= rect.left and e.clientY <= rect.bottom) || (e.clientX <= menu.left and e.clientY >= menu.top) || (e.clientX >= rect.right and e.clientY <= rect.bottom) || (e.clientX >= menu.right and e.clientY >= menu.top)
89
+ #dropdown = !inside
90
+
91
+ <self [pos:rel] @mouseenter=(#dropdown = true) @mouseleave=mouseleave>
92
+ <div.main [pos:rel d:hcc] .main-active=#dropdown>
93
+ <img.main-flag src=icon(state[state.active].$.flag)>
94
+ <div.main-name> state.$.name
95
+ <{arrow}.main-arrow .main-arrow-passive=!#dropdown .main-arrow-active=#dropdown>
96
+
97
+ if #dropdown
98
+ <div$menu.menu [pos:abs w:100% > max-content o@off:0] ease>
99
+ for own key, value of state.languages
100
+ <div.menu-item @click=onselect(key) [d:none]=(key == state.active)>
101
+ <img.menu-item-icon src=icon(value.$.flag)>
102
+ <span.menu-item-text> value.$.name
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "imba-localization",
3
- "version": "0.2.8",
3
+ "version": "0.3.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/HeapVoid/imba-localization.git"
@@ -13,15 +13,6 @@
13
13
  "license": "MIT",
14
14
  "type": "module",
15
15
  "files": [
16
- "localization.imba",
17
- "components.imba"
18
- ],
19
- "exports": {
20
- ".": {
21
- "import": "./localization.imba"
22
- },
23
- "./components": {
24
- "import": "./components.imba"
25
- }
26
- }
16
+ "localization.imba"
17
+ ]
27
18
  }
package/components.imba DELETED
@@ -1,51 +0,0 @@
1
- const arrow-down =
2
- <svg viewBox="0 0 256 256">
3
- <path d="M213.66,165.66a8,8,0,0,1-11.32,0L128,91.31,53.66,165.66a8,8,0,0,1-11.32-11.32l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,213.66,165.66Z">
4
-
5
- tag icon-arrow-down
6
- <self>
7
- <{arrow-down}>
8
-
9
- tag language-selector
10
- state
11
- icons = "https://kapowaz.github.io/square-flags/flags/##.svg"
12
- #dropdown = false
13
- icon-arrow = arrow-down
14
-
15
- def onselect key
16
- #dropdown = false
17
- state.active = key
18
-
19
- css
20
- $ease: 0.5s
21
- .main rd:8px px:15px py:8px cursor:pointer bgc:light-dark(#000000/10, #FFFFFF/20) fw:500 fs:13px ead:$ease
22
- .main-active bgc:light-dark(#000000/20, #FFFFFF/30)
23
- .main-flag mr:10px rd:50% w:20px h:20px
24
- .main-name mr:10px
25
- .main-arrow w:16px h:16px fill:light-dark(#000000,#FFFFFF) ml:auto scale-y:-1 ead:$ease
26
- .menu t:100% l:50% x:-50% zi:999 backdrop-filter:blur(20px) mt:2px rd:8px rd:8px py:5px bgc:light-dark(#000000/5, #FFFFFF/10) fw:500 fs:13px ead:$ease
27
- .menu-item d:hflex ai:center px:10px py:5px rd:8px cursor:pointer bg@hover:light-dark(#000000/10, #FFFFFF/20) m:5px
28
- .menu-item-icon h:20px w:20px mr:10px rd:50%
29
- .menu-item-text fs:13px
30
-
31
- def icon country
32
- return icons.replace('##',country)
33
-
34
- def mouseleave e
35
- const rect = self.getBoundingClientRect!
36
- const menu = $menu.getBoundingClientRect!
37
- const inside = e.clientY >= menu.bottom || e.clientY <= rect.top || (e.clientX <= rect.left and e.clientY <= rect.bottom) || (e.clientX <= menu.left and e.clientY >= menu.top) || (e.clientX >= rect.right and e.clientY <= rect.bottom) || (e.clientX >= menu.right and e.clientY >= menu.top)
38
- #dropdown = !inside
39
-
40
- <self [pos:rel] @mouseenter=(#dropdown = true) @mouseleave=mouseleave>
41
- <div.main [pos:rel d:hcc] .main-active=#dropdown>
42
- <img.main-flag src=icon(state[state.active].$.flag)>
43
- <div.main-name> state.$.name
44
- <{icon-arrow}.main-arrow [scale-y:1]=#dropdown>
45
-
46
- if #dropdown
47
- <div$menu.menu [pos:abs w:100% > max-content o@off:0] ease>
48
- for own key, value of state.languages
49
- <div.menu-item @click=onselect(key) [d:none]=(key == state.active)>
50
- <img.menu-item-icon src=icon(value.$.flag)>
51
- <span.menu-item-text> value.$.name