@rimelight/ui 0.0.2 → 0.0.4

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 (105) hide show
  1. package/package.json +6 -3
  2. package/src/components/carousel/carousel-script.ts +188 -188
  3. package/src/components/carousel/index.ts +1 -1
  4. package/src/components/input-otp/InputOtpTypes.ts +6 -6
  5. package/src/components/radio-group/RadioGroupTypes.ts +6 -6
  6. package/src/components/select/SelectTypes.ts +13 -13
  7. package/src/components/switch/SwitchTypes.ts +6 -6
  8. package/src/components/toast/index.ts +1 -1
  9. package/src/components/toast/toast-manager.ts +234 -234
  10. package/src/components/toggle/ToggleTypes.ts +14 -14
  11. package/src/config/cookies.ts +5 -5
  12. package/src/config/index.ts +3 -3
  13. package/src/config/links.ts +4 -4
  14. package/src/config/site.config.ts +27 -45
  15. package/src/domain/cms/index.ts +1 -1
  16. package/src/domain/cms/types.ts +20 -20
  17. package/src/domain/i18n/constants.ts +21 -21
  18. package/src/domain/i18n/cookie-storage.ts +13 -13
  19. package/src/domain/i18n/country-to-locale-map.ts +67 -67
  20. package/src/domain/i18n/fetcher.ts +278 -268
  21. package/src/domain/i18n/flags.ts +16 -16
  22. package/src/domain/i18n/format.ts +90 -90
  23. package/src/domain/i18n/index.ts +10 -10
  24. package/src/domain/i18n/middleware/i18n.ts +161 -160
  25. package/src/domain/i18n/resolve-locale.ts +55 -55
  26. package/src/domain/i18n/schema.ts +29 -29
  27. package/src/domain/index.ts +4 -4
  28. package/src/domain/seo/constants.ts +6 -20
  29. package/src/domain/seo/index.ts +3 -3
  30. package/src/domain/seo/services/index.ts +3 -3
  31. package/src/domain/seo/services/llms.ts +56 -53
  32. package/src/domain/seo/services/robots.ts +12 -12
  33. package/src/domain/seo/services/sitemap.ts +56 -56
  34. package/src/domain/seo/utils.ts +36 -37
  35. package/src/domain/theme/constants.ts +6 -6
  36. package/src/domain/theme/index.ts +2 -2
  37. package/src/domain/theme/schema.ts +10 -10
  38. package/src/env.d.ts +49 -49
  39. package/src/integrations/index.ts +1 -0
  40. package/src/integrations/sri.ts +92 -0
  41. package/src/lib/component-preview.ts +73 -73
  42. package/src/lib/index.ts +6 -6
  43. package/src/lib/remark/remark-modified-time.ts +13 -13
  44. package/src/lib/showcase-preview-elements.ts +408 -408
  45. package/src/lib/showcase-renderer.ts +218 -218
  46. package/src/lib/showcase-utils.ts +189 -189
  47. package/src/lib/turnstile.ts +35 -35
  48. package/src/lib/utils/starwind/positioning.ts +318 -318
  49. package/src/locales/de/blog.json +9 -9
  50. package/src/locales/de/common.json +19 -19
  51. package/src/locales/de/errors.json +6 -6
  52. package/src/locales/de/home.json +20 -20
  53. package/src/locales/de/messages.json +8 -8
  54. package/src/locales/de/nav.json +13 -13
  55. package/src/locales/de/projects.json +9 -9
  56. package/src/locales/de/services.json +43 -43
  57. package/src/locales/en/blog.json +9 -9
  58. package/src/locales/en/chat.json +29 -29
  59. package/src/locales/en/common.json +19 -19
  60. package/src/locales/en/cookie_notice.json +11 -11
  61. package/src/locales/en/editor.json +24 -24
  62. package/src/locales/en/errors.json +6 -6
  63. package/src/locales/en/home.json +20 -20
  64. package/src/locales/en/messages.json +8 -8
  65. package/src/locales/en/nav.json +13 -13
  66. package/src/locales/en/projects.json +9 -9
  67. package/src/locales/en/services.json +43 -43
  68. package/src/locales/es/blog.json +9 -9
  69. package/src/locales/es/common.json +19 -19
  70. package/src/locales/es/errors.json +6 -6
  71. package/src/locales/es/home.json +20 -20
  72. package/src/locales/es/messages.json +8 -8
  73. package/src/locales/es/nav.json +13 -13
  74. package/src/locales/es/projects.json +9 -9
  75. package/src/locales/es/services.json +43 -43
  76. package/src/locales/ja/blog.json +9 -9
  77. package/src/locales/ja/common.json +19 -19
  78. package/src/locales/ja/errors.json +6 -6
  79. package/src/locales/ja/home.json +20 -20
  80. package/src/locales/ja/messages.json +8 -8
  81. package/src/locales/ja/nav.json +13 -13
  82. package/src/locales/ja/projects.json +9 -9
  83. package/src/locales/ja/services.json +43 -43
  84. package/src/locales/pt/blog.json +9 -9
  85. package/src/locales/pt/chat.json +29 -29
  86. package/src/locales/pt/common.json +19 -19
  87. package/src/locales/pt/cookie_notice.json +11 -11
  88. package/src/locales/pt/editor.json +24 -24
  89. package/src/locales/pt/errors.json +6 -6
  90. package/src/locales/pt/home.json +20 -20
  91. package/src/locales/pt/messages.json +8 -8
  92. package/src/locales/pt/nav.json +13 -13
  93. package/src/locales/pt/projects.json +9 -9
  94. package/src/locales/pt/services.json +43 -43
  95. package/src/middleware/index.ts +2 -0
  96. package/src/middleware/security.ts +15 -0
  97. package/src/middleware/sri.ts +78 -0
  98. package/src/utils/index.ts +2 -2
  99. package/src/utils/server/cookies.ts +98 -98
  100. package/src/utils/server/index.ts +1 -1
  101. package/src/utils/shared/deep-merge.ts +36 -36
  102. package/src/utils/shared/embed.ts +105 -105
  103. package/src/utils/shared/index.ts +3 -3
  104. package/src/utils/shared/parse-boolean.ts +14 -14
  105. package/worker-configuration.d.ts +0 -14791
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rimelight/ui",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Rimelight UI Library.",
5
5
  "license": "MIT",
6
6
  "author": "Daniel Marchi",
@@ -22,6 +22,10 @@
22
22
  "./lib/*": "./src/lib/*",
23
23
  "./utils": "./src/utils/index.ts",
24
24
  "./utils/*": "./src/utils/*",
25
+ "./integrations": "./src/integrations/index.ts",
26
+ "./integrations/*": "./src/integrations/*",
27
+ "./middleware": "./src/middleware/index.ts",
28
+ "./middleware/*": "./src/middleware/*",
25
29
  "./*": "./src/*"
26
30
  },
27
31
  "publishConfig": {
@@ -36,8 +40,7 @@
36
40
  "@types/node": "25.5.2",
37
41
  "astro": "6.1.4",
38
42
  "typescript": "6.0.2",
39
- "vite-plus": "0.1.15",
40
- "wrangler": "4.80.0"
43
+ "vite-plus": "0.1.15"
41
44
  },
42
45
  "peerDependencies": {
43
46
  "astro": ">=6.0.0"
@@ -1,188 +1,188 @@
1
- import EmblaCarousel, {
2
- type EmblaCarouselType,
3
- type EmblaOptionsType,
4
- type EmblaPluginType
5
- } from "embla-carousel"
6
-
7
- export type CarouselApi = EmblaCarouselType
8
-
9
- export interface CarouselOptions {
10
- opts?: EmblaOptionsType
11
- plugins?: EmblaPluginType[]
12
- setApi?: (api: CarouselApi) => void
13
- }
14
-
15
- export interface CarouselManager {
16
- api: CarouselApi
17
- scrollPrev: () => void
18
- scrollNext: () => void
19
- canScrollPrev: () => boolean
20
- canScrollNext: () => boolean
21
- destroy: () => void
22
- }
23
-
24
- export function initCarousel(
25
- carouselElement: HTMLElement,
26
- options: CarouselOptions = {}
27
- ): CarouselManager | null {
28
- // don't re-initialize if already initialized
29
- if (carouselElement.dataset.initialized === "true") return null
30
- carouselElement.dataset.initialized = "true"
31
-
32
- if (!carouselElement) {
33
- console.warn("Carousel element not found")
34
- return null
35
- }
36
-
37
- // Find content element - Embla expects the viewport element, not the container
38
- const viewportElement = carouselElement.querySelector('[data-slot="carousel-content"]')
39
-
40
- if (!(viewportElement instanceof HTMLElement)) {
41
- console.warn("Carousel content element not found")
42
- return null
43
- }
44
-
45
- // Get configuration from data attributes
46
- const axisData = carouselElement.dataset.axis
47
- const axis: EmblaOptionsType["axis"] = axisData === "y" ? "y" : "x"
48
-
49
- // Safely parse data options
50
- let dataOpts = {}
51
- try {
52
- const optsString = carouselElement.dataset.opts
53
- if (optsString && optsString !== "undefined" && optsString !== "null") {
54
- dataOpts = JSON.parse(optsString)
55
- }
56
- } catch (e) {
57
- console.warn("Failed to parse carousel opts:", e)
58
- dataOpts = {}
59
- }
60
-
61
- // Ensure dataOpts is a valid object
62
- if (!dataOpts || typeof dataOpts !== "object") {
63
- dataOpts = {}
64
- }
65
-
66
- // Merge options - ensure we always have a valid object
67
- const emblaOptions: EmblaOptionsType = {
68
- axis,
69
- ...dataOpts,
70
- ...options.opts
71
- }
72
-
73
- // Handle plugins - EmblaCarousel expects undefined when no plugins, not empty array
74
- const plugins = options.plugins && options.plugins.length > 0 ? options.plugins : undefined
75
-
76
- // console.log("ID:", carouselElement.id);
77
- // console.log("Plugins:", plugins);
78
- // console.log("Options:", emblaOptions);
79
-
80
- // Find navigation buttons
81
- const prevButton = carouselElement.querySelector(".starwind-carousel-previous")
82
- const nextButton = carouselElement.querySelector(".starwind-carousel-next")
83
-
84
- const prevButtonEl = prevButton instanceof HTMLButtonElement ? prevButton : null
85
- const nextButtonEl = nextButton instanceof HTMLButtonElement ? nextButton : null
86
-
87
- // Initialize Embla
88
- let emblaApi: EmblaCarouselType
89
- if (plugins) {
90
- emblaApi = EmblaCarousel(viewportElement, emblaOptions, plugins)
91
- } else {
92
- emblaApi = EmblaCarousel(viewportElement, emblaOptions)
93
- }
94
-
95
- // Update button states
96
- const updateButtons = () => {
97
- const canScrollPrev = emblaApi.canScrollPrev()
98
- const canScrollNext = emblaApi.canScrollNext()
99
-
100
- if (prevButtonEl) {
101
- prevButtonEl.disabled = !canScrollPrev
102
- prevButtonEl.setAttribute("aria-disabled", (!canScrollPrev).toString())
103
- }
104
-
105
- if (nextButtonEl) {
106
- nextButtonEl.disabled = !canScrollNext
107
- nextButtonEl.setAttribute("aria-disabled", (!canScrollNext).toString())
108
- }
109
- }
110
-
111
- // Event handlers for cleanup
112
- const prevClickHandler = () => emblaApi.scrollPrev()
113
- const nextClickHandler = () => emblaApi.scrollNext()
114
- const keydownHandler = (event: KeyboardEvent) => {
115
- if (axis === "y") {
116
- // Vertical axis: ArrowUp = previous, ArrowDown = next
117
- if (event.key === "ArrowUp") {
118
- event.preventDefault()
119
- emblaApi.scrollPrev()
120
- } else if (event.key === "ArrowDown") {
121
- event.preventDefault()
122
- emblaApi.scrollNext()
123
- }
124
- } else {
125
- // Horizontal axis (default): ArrowLeft = previous, ArrowRight = next
126
- if (event.key === "ArrowLeft") {
127
- event.preventDefault()
128
- emblaApi.scrollPrev()
129
- } else if (event.key === "ArrowRight") {
130
- event.preventDefault()
131
- emblaApi.scrollNext()
132
- }
133
- }
134
- }
135
-
136
- // Setup event listeners
137
- const setupEventListeners = () => {
138
- // Navigation button listeners
139
- prevButtonEl?.addEventListener("click", prevClickHandler)
140
- nextButtonEl?.addEventListener("click", nextClickHandler)
141
-
142
- // Keyboard navigation
143
- carouselElement.addEventListener("keydown", keydownHandler)
144
- }
145
-
146
- // Setup user API callback
147
- const setupUserCallbacks = () => {
148
- if (options.setApi) {
149
- options.setApi(emblaApi)
150
- }
151
- }
152
-
153
- // Initialize everything
154
- updateButtons()
155
- setupEventListeners()
156
- setupUserCallbacks()
157
-
158
- // Setup internal event listeners
159
- emblaApi.on("select", updateButtons)
160
- emblaApi.on("init", () => {
161
- updateButtons()
162
- })
163
- emblaApi.on("reInit", () => {
164
- updateButtons()
165
- })
166
-
167
- // Return manager interface
168
- return {
169
- api: emblaApi,
170
- scrollPrev: () => emblaApi.scrollPrev(),
171
- scrollNext: () => emblaApi.scrollNext(),
172
- canScrollPrev: () => emblaApi.canScrollPrev(),
173
- canScrollNext: () => emblaApi.canScrollNext(),
174
- destroy: () => {
175
- // Remove event listeners to prevent memory leaks
176
- if (prevButtonEl) {
177
- prevButtonEl.removeEventListener("click", prevClickHandler)
178
- }
179
- if (nextButtonEl) {
180
- nextButtonEl.removeEventListener("click", nextClickHandler)
181
- }
182
- carouselElement.removeEventListener("keydown", keydownHandler)
183
-
184
- // Destroy the Embla instance
185
- emblaApi.destroy()
186
- }
187
- }
188
- }
1
+ import EmblaCarousel, {
2
+ type EmblaCarouselType,
3
+ type EmblaOptionsType,
4
+ type EmblaPluginType
5
+ } from "embla-carousel"
6
+
7
+ export type CarouselApi = EmblaCarouselType
8
+
9
+ export interface CarouselOptions {
10
+ opts?: EmblaOptionsType
11
+ plugins?: EmblaPluginType[]
12
+ setApi?: (api: CarouselApi) => void
13
+ }
14
+
15
+ export interface CarouselManager {
16
+ api: CarouselApi
17
+ scrollPrev: () => void
18
+ scrollNext: () => void
19
+ canScrollPrev: () => boolean
20
+ canScrollNext: () => boolean
21
+ destroy: () => void
22
+ }
23
+
24
+ export function initCarousel(
25
+ carouselElement: HTMLElement,
26
+ options: CarouselOptions = {}
27
+ ): CarouselManager | null {
28
+ // don't re-initialize if already initialized
29
+ if (carouselElement.dataset.initialized === "true") return null
30
+ carouselElement.dataset.initialized = "true"
31
+
32
+ if (!carouselElement) {
33
+ console.warn("Carousel element not found")
34
+ return null
35
+ }
36
+
37
+ // Find content element - Embla expects the viewport element, not the container
38
+ const viewportElement = carouselElement.querySelector('[data-slot="carousel-content"]')
39
+
40
+ if (!(viewportElement instanceof HTMLElement)) {
41
+ console.warn("Carousel content element not found")
42
+ return null
43
+ }
44
+
45
+ // Get configuration from data attributes
46
+ const axisData = carouselElement.dataset.axis
47
+ const axis: EmblaOptionsType["axis"] = axisData === "y" ? "y" : "x"
48
+
49
+ // Safely parse data options
50
+ let dataOpts = {}
51
+ try {
52
+ const optsString = carouselElement.dataset.opts
53
+ if (optsString && optsString !== "undefined" && optsString !== "null") {
54
+ dataOpts = JSON.parse(optsString)
55
+ }
56
+ } catch (e) {
57
+ console.warn("Failed to parse carousel opts:", e)
58
+ dataOpts = {}
59
+ }
60
+
61
+ // Ensure dataOpts is a valid object
62
+ if (!dataOpts || typeof dataOpts !== "object") {
63
+ dataOpts = {}
64
+ }
65
+
66
+ // Merge options - ensure we always have a valid object
67
+ const emblaOptions: EmblaOptionsType = {
68
+ axis,
69
+ ...dataOpts,
70
+ ...options.opts
71
+ }
72
+
73
+ // Handle plugins - EmblaCarousel expects undefined when no plugins, not empty array
74
+ const plugins = options.plugins && options.plugins.length > 0 ? options.plugins : undefined
75
+
76
+ // console.log("ID:", carouselElement.id);
77
+ // console.log("Plugins:", plugins);
78
+ // console.log("Options:", emblaOptions);
79
+
80
+ // Find navigation buttons
81
+ const prevButton = carouselElement.querySelector(".starwind-carousel-previous")
82
+ const nextButton = carouselElement.querySelector(".starwind-carousel-next")
83
+
84
+ const prevButtonEl = prevButton instanceof HTMLButtonElement ? prevButton : null
85
+ const nextButtonEl = nextButton instanceof HTMLButtonElement ? nextButton : null
86
+
87
+ // Initialize Embla
88
+ let emblaApi: EmblaCarouselType
89
+ if (plugins) {
90
+ emblaApi = EmblaCarousel(viewportElement, emblaOptions, plugins)
91
+ } else {
92
+ emblaApi = EmblaCarousel(viewportElement, emblaOptions)
93
+ }
94
+
95
+ // Update button states
96
+ const updateButtons = () => {
97
+ const canScrollPrev = emblaApi.canScrollPrev()
98
+ const canScrollNext = emblaApi.canScrollNext()
99
+
100
+ if (prevButtonEl) {
101
+ prevButtonEl.disabled = !canScrollPrev
102
+ prevButtonEl.setAttribute("aria-disabled", (!canScrollPrev).toString())
103
+ }
104
+
105
+ if (nextButtonEl) {
106
+ nextButtonEl.disabled = !canScrollNext
107
+ nextButtonEl.setAttribute("aria-disabled", (!canScrollNext).toString())
108
+ }
109
+ }
110
+
111
+ // Event handlers for cleanup
112
+ const prevClickHandler = () => emblaApi.scrollPrev()
113
+ const nextClickHandler = () => emblaApi.scrollNext()
114
+ const keydownHandler = (event: KeyboardEvent) => {
115
+ if (axis === "y") {
116
+ // Vertical axis: ArrowUp = previous, ArrowDown = next
117
+ if (event.key === "ArrowUp") {
118
+ event.preventDefault()
119
+ emblaApi.scrollPrev()
120
+ } else if (event.key === "ArrowDown") {
121
+ event.preventDefault()
122
+ emblaApi.scrollNext()
123
+ }
124
+ } else {
125
+ // Horizontal axis (default): ArrowLeft = previous, ArrowRight = next
126
+ if (event.key === "ArrowLeft") {
127
+ event.preventDefault()
128
+ emblaApi.scrollPrev()
129
+ } else if (event.key === "ArrowRight") {
130
+ event.preventDefault()
131
+ emblaApi.scrollNext()
132
+ }
133
+ }
134
+ }
135
+
136
+ // Setup event listeners
137
+ const setupEventListeners = () => {
138
+ // Navigation button listeners
139
+ prevButtonEl?.addEventListener("click", prevClickHandler)
140
+ nextButtonEl?.addEventListener("click", nextClickHandler)
141
+
142
+ // Keyboard navigation
143
+ carouselElement.addEventListener("keydown", keydownHandler)
144
+ }
145
+
146
+ // Setup user API callback
147
+ const setupUserCallbacks = () => {
148
+ if (options.setApi) {
149
+ options.setApi(emblaApi)
150
+ }
151
+ }
152
+
153
+ // Initialize everything
154
+ updateButtons()
155
+ setupEventListeners()
156
+ setupUserCallbacks()
157
+
158
+ // Setup internal event listeners
159
+ emblaApi.on("select", updateButtons)
160
+ emblaApi.on("init", () => {
161
+ updateButtons()
162
+ })
163
+ emblaApi.on("reInit", () => {
164
+ updateButtons()
165
+ })
166
+
167
+ // Return manager interface
168
+ return {
169
+ api: emblaApi,
170
+ scrollPrev: () => emblaApi.scrollPrev(),
171
+ scrollNext: () => emblaApi.scrollNext(),
172
+ canScrollPrev: () => emblaApi.canScrollPrev(),
173
+ canScrollNext: () => emblaApi.canScrollNext(),
174
+ destroy: () => {
175
+ // Remove event listeners to prevent memory leaks
176
+ if (prevButtonEl) {
177
+ prevButtonEl.removeEventListener("click", prevClickHandler)
178
+ }
179
+ if (nextButtonEl) {
180
+ nextButtonEl.removeEventListener("click", nextClickHandler)
181
+ }
182
+ carouselElement.removeEventListener("keydown", keydownHandler)
183
+
184
+ // Destroy the Embla instance
185
+ emblaApi.destroy()
186
+ }
187
+ }
188
+ }
@@ -1 +1 @@
1
- export * from "./carousel-script"
1
+ export * from "./carousel-script"
@@ -1,6 +1,6 @@
1
- export interface InputOtpChangeEvent extends CustomEvent {
2
- detail: {
3
- value: string
4
- inputOtpId?: string
5
- }
6
- }
1
+ export interface InputOtpChangeEvent extends CustomEvent {
2
+ detail: {
3
+ value: string
4
+ inputOtpId?: string
5
+ }
6
+ }
@@ -1,6 +1,6 @@
1
- export interface RadioGroupChangeEvent extends CustomEvent {
2
- detail: {
3
- value: string
4
- radioGroupId?: string
5
- }
6
- }
1
+ export interface RadioGroupChangeEvent extends CustomEvent {
2
+ detail: {
3
+ value: string
4
+ radioGroupId?: string
5
+ }
6
+ }
@@ -1,13 +1,13 @@
1
- export interface SelectChangeEvent extends CustomEvent {
2
- detail: {
3
- value: string
4
- selectId: string
5
- label: string
6
- }
7
- }
8
-
9
- export interface SelectEvent extends CustomEvent {
10
- detail:
11
- | { value: string; selectId: string; selectName?: string }
12
- | { value: string; selectId?: string; selectName: string }
13
- }
1
+ export interface SelectChangeEvent extends CustomEvent {
2
+ detail: {
3
+ value: string
4
+ selectId: string
5
+ label: string
6
+ }
7
+ }
8
+
9
+ export interface SelectEvent extends CustomEvent {
10
+ detail:
11
+ | { value: string; selectId: string; selectName?: string }
12
+ | { value: string; selectId?: string; selectName: string }
13
+ }
@@ -1,6 +1,6 @@
1
- export interface SwitchChangeEvent extends CustomEvent {
2
- detail: {
3
- checked: boolean
4
- switchId: string
5
- }
6
- }
1
+ export interface SwitchChangeEvent extends CustomEvent {
2
+ detail: {
3
+ checked: boolean
4
+ switchId: string
5
+ }
6
+ }
@@ -1 +1 @@
1
- export * from "./toast-manager"
1
+ export * from "./toast-manager"