luxen-ui 0.18.2 → 0.19.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 (77) hide show
  1. package/README.md +1 -0
  2. package/cdn/color-scheme.d.ts +76 -0
  3. package/cdn/color-scheme.d.ts.map +1 -0
  4. package/cdn/color-scheme.js +2 -0
  5. package/cdn/color-scheme.js.map +1 -0
  6. package/cdn/config.d.ts +23 -0
  7. package/cdn/config.d.ts.map +1 -1
  8. package/cdn/custom-elements.json +142 -2
  9. package/cdn/elements/color-scheme-icon/color-scheme-icon.d.ts +55 -0
  10. package/cdn/elements/color-scheme-icon/color-scheme-icon.d.ts.map +1 -0
  11. package/cdn/elements/color-scheme-icon/color-scheme-icon.js +44 -0
  12. package/cdn/elements/color-scheme-icon/color-scheme-icon.js.map +1 -0
  13. package/cdn/elements/color-scheme-icon/index.d.ts +2 -0
  14. package/cdn/elements/color-scheme-icon/index.d.ts.map +1 -0
  15. package/cdn/elements/color-scheme-icon/index.js +2 -0
  16. package/cdn/elements/color-scheme-icon/index.js.map +1 -0
  17. package/cdn/elements/dropdown-item/dropdown-item.d.ts +9 -1
  18. package/cdn/elements/dropdown-item/dropdown-item.d.ts.map +1 -1
  19. package/cdn/elements/dropdown-item/dropdown-item.js +32 -23
  20. package/cdn/elements/dropdown-item/dropdown-item.js.map +1 -1
  21. package/cdn/elements/segmented-control/segmented-control.d.ts +2 -0
  22. package/cdn/elements/segmented-control/segmented-control.d.ts.map +1 -1
  23. package/cdn/elements/segmented-control/segmented-control.js +1 -1
  24. package/cdn/elements/segmented-control/segmented-control.js.map +1 -1
  25. package/cdn/elements/tabs/tabs.d.ts +28 -1
  26. package/cdn/elements/tabs/tabs.d.ts.map +1 -1
  27. package/cdn/elements/tabs/tabs.js +1 -1
  28. package/cdn/elements/tabs/tabs.js.map +1 -1
  29. package/cdn/index.d.ts +2 -0
  30. package/cdn/index.d.ts.map +1 -1
  31. package/cdn/index.js +1 -1
  32. package/cdn/registry.d.ts +1 -1
  33. package/cdn/registry.d.ts.map +1 -1
  34. package/cdn/registry.js.map +1 -1
  35. package/cdn/standalone.css +23 -4
  36. package/cdn/standalone.js.map +1 -1
  37. package/cdn/styles/elements/tabs/enclosed.css +9 -1
  38. package/cdn/styles/elements/tabs/line.css +14 -3
  39. package/dist/color-scheme.d.ts +76 -0
  40. package/dist/color-scheme.d.ts.map +1 -0
  41. package/dist/color-scheme.js +203 -0
  42. package/dist/config.d.ts +23 -0
  43. package/dist/config.d.ts.map +1 -1
  44. package/dist/css/elements/tabs/enclosed.css +9 -1
  45. package/dist/css/elements/tabs/line.css +14 -3
  46. package/dist/custom-elements.json +142 -2
  47. package/dist/elements/color-scheme-icon/color-scheme-icon.css +98 -0
  48. package/dist/elements/color-scheme-icon/color-scheme-icon.d.ts +55 -0
  49. package/dist/elements/color-scheme-icon/color-scheme-icon.d.ts.map +1 -0
  50. package/dist/elements/color-scheme-icon/color-scheme-icon.js +138 -0
  51. package/dist/elements/color-scheme-icon/index.d.ts +2 -0
  52. package/dist/elements/color-scheme-icon/index.d.ts.map +1 -0
  53. package/dist/elements/color-scheme-icon/index.js +4 -0
  54. package/dist/elements/dropdown-item/dropdown-item.d.ts +9 -1
  55. package/dist/elements/dropdown-item/dropdown-item.d.ts.map +1 -1
  56. package/dist/elements/dropdown-item/dropdown-item.js +49 -26
  57. package/dist/elements/segmented-control/segmented-control.d.ts +2 -0
  58. package/dist/elements/segmented-control/segmented-control.d.ts.map +1 -1
  59. package/dist/elements/segmented-control/segmented-control.js +11 -1
  60. package/dist/elements/tabs/tabs.d.ts +28 -1
  61. package/dist/elements/tabs/tabs.d.ts.map +1 -1
  62. package/dist/elements/tabs/tabs.js +121 -26
  63. package/dist/index.d.ts +2 -0
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +1 -0
  66. package/dist/metadata/color-scheme-icon.json +66 -0
  67. package/dist/metadata/dropdown-item.json +9 -1
  68. package/dist/metadata/index.json +82 -3
  69. package/dist/metadata/tabs.json +6 -1
  70. package/dist/registry.d.ts +1 -1
  71. package/dist/registry.d.ts.map +1 -1
  72. package/dist/templates/elements/color-scheme-icon.md +279 -0
  73. package/dist/templates/elements/dropdown.md +54 -1
  74. package/dist/templates/elements/tabs.md +40 -7
  75. package/elements.json +8 -0
  76. package/package.json +5 -1
  77. package/vite-plugin.ts +71 -8
package/vite-plugin.ts CHANGED
@@ -83,11 +83,30 @@ export interface LuxenOptions {
83
83
  * commit it and edit freely.
84
84
  */
85
85
  emitTypes?: string | EmitTypesOptions;
86
+ /**
87
+ * Build-time defaults for the `luxen-ui/color-scheme` store, so a project
88
+ * never has to call `colorScheme.configure()` from its entry point.
89
+ */
90
+ colorScheme?: ColorSchemeOptions;
91
+ }
92
+
93
+ /** Build-time defaults for `luxen-ui/color-scheme`. */
94
+ export interface ColorSchemeOptions {
95
+ /**
96
+ * `localStorage` key holding the light/dark override. Default
97
+ * `'luxen-color-scheme'`; `''` disables persistence. The before-first-paint
98
+ * snippet in your `<head>` must read the same key — it runs before any module
99
+ * and cannot be rewritten by the build.
100
+ */
101
+ storageKey?: string;
102
+ /** Have the store write `color-scheme` on `<html>` itself. Default `false`. */
103
+ apply?: 'root' | false;
86
104
  }
87
105
 
88
106
  export default function luxen(options: LuxenOptions = {}): Plugin {
89
107
  let elementPrefix = 'l';
90
108
  let cssPrefix = 'l';
109
+ let colorSchemeCfg: ColorSchemeOptions = {};
91
110
 
92
111
  return {
93
112
  name: 'luxen',
@@ -99,6 +118,7 @@ export default function luxen(options: LuxenOptions = {}): Plugin {
99
118
  const fileCfg = await loadLuxenConfig();
100
119
  elementPrefix = options.elementPrefix ?? fileCfg?.elementPrefix ?? 'l';
101
120
  cssPrefix = options.cssPrefix ?? fileCfg?.cssPrefix ?? 'l';
121
+ colorSchemeCfg = { ...fileCfg?.colorScheme, ...options.colorScheme };
102
122
  const emitTypes = options.emitTypes ?? fileCfg?.emitTypes;
103
123
 
104
124
  if (emitTypes) {
@@ -127,20 +147,63 @@ export default function luxen(options: LuxenOptions = {}): Plugin {
127
147
  * switching), but ordinary consumers don't need to call it.
128
148
  */
129
149
  transform(code, id) {
130
- if (elementPrefix === 'l' && cssPrefix === 'l') return null;
131
- if (!isLuxenRegistry(id)) return null;
132
- let out = code;
133
- if (elementPrefix !== 'l') {
134
- out = out.replace(/_elementPrefix = 'l';/g, `_elementPrefix = '${elementPrefix}';`);
150
+ if (isLuxenRegistry(id)) {
151
+ if (elementPrefix === 'l' && cssPrefix === 'l') return null;
152
+ let out = code;
153
+ if (elementPrefix !== 'l') {
154
+ out = out.replace(/_elementPrefix = 'l';/g, `_elementPrefix = '${elementPrefix}';`);
155
+ }
156
+ if (cssPrefix !== 'l') {
157
+ out = out.replace(/_cssPrefix = 'l';/g, `_cssPrefix = '${cssPrefix}';`);
158
+ }
159
+ return out === code ? null : { code: out, map: null };
135
160
  }
136
- if (cssPrefix !== 'l') {
137
- out = out.replace(/_cssPrefix = 'l';/g, `_cssPrefix = '${cssPrefix}';`);
161
+
162
+ // Same trick for the color-scheme store: rewrite the two literal
163
+ // initialisers in `color-scheme.js` so a project's `luxen.config.mjs`
164
+ // defaults are baked in. `configure()` remains the runtime path.
165
+ if (isLuxenColorScheme(id)) {
166
+ const { storageKey, apply } = colorSchemeCfg;
167
+ if (storageKey === undefined && apply === undefined) return null;
168
+ let out = code;
169
+ if (storageKey !== undefined) {
170
+ out = bakeInitialiser(out, '_storageKey', "'luxen-color-scheme'", storageKey);
171
+ }
172
+ if (apply !== undefined) out = bakeInitialiser(out, '_apply', 'false', apply);
173
+ return out === code ? null : { code: out, map: null };
138
174
  }
139
- return out === code ? null : { code: out, map: null };
175
+
176
+ return null;
140
177
  },
141
178
  };
142
179
  }
143
180
 
181
+ /**
182
+ * Rewrite `let <name>[: Type] = <literal>;` to hold `value`.
183
+ *
184
+ * The optional type annotation is what makes this a helper rather than a plain
185
+ * `String.replace`: the module resolves to the compiled `let _apply = false;` in
186
+ * `dist`, but to `let _apply: ColorSchemeApply = false;` when a project points at
187
+ * the TypeScript source — which `isLuxenColorScheme` accepts. A pattern that only
188
+ * matched the compiled shape would drop half a project's configuration there,
189
+ * silently and with no build error.
190
+ */
191
+ function bakeInitialiser(code: string, name: string, literal: string, value: unknown): string {
192
+ const pattern = new RegExp(
193
+ `${name}(\\s*:\\s*[\\w.<>|'" ]+?)? = ${literal.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')};`,
194
+ 'g',
195
+ );
196
+ return code.replace(
197
+ pattern,
198
+ (_match, annotation) => `${name}${annotation ?? ''} = ${JSON.stringify(value)};`,
199
+ );
200
+ }
201
+
202
+ function isLuxenColorScheme(id: string): boolean {
203
+ const path = id.replace(/\\/g, '/').split('?')[0] ?? '';
204
+ return /\/luxen-ui\/(?:dist|src\/html)\/color-scheme\.(?:js|ts)$/.test(path);
205
+ }
206
+
144
207
  function isLuxenRegistry(id: string): boolean {
145
208
  // Normalise for Windows + strip Vite query params (`?import`, `?used`, …)
146
209
  const path = id.replace(/\\/g, '/').split('?')[0] ?? '';