lapikit 0.3.7 → 0.3.8

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 (42) hide show
  1. package/dist/entry-bundler.d.ts +1 -3
  2. package/dist/entry-bundler.js +2 -104
  3. package/dist/labs/compiler/components.d.ts +2 -0
  4. package/dist/labs/compiler/components.js +2 -0
  5. package/dist/labs/compiler/index.d.ts +1 -0
  6. package/dist/labs/compiler/index.js +1 -0
  7. package/dist/labs/compiler/mapped-code.d.ts +27 -0
  8. package/dist/labs/compiler/mapped-code.js +103 -0
  9. package/dist/labs/compiler/plugins.d.ts +7 -0
  10. package/dist/labs/compiler/plugins.js +7 -0
  11. package/dist/labs/compiler/preprocess/decode-sourcemap.d.ts +2 -0
  12. package/dist/labs/compiler/preprocess/decode-sourcemap.js +106 -0
  13. package/dist/labs/compiler/preprocess/finding.d.ts +1 -0
  14. package/dist/labs/compiler/preprocess/finding.js +49 -0
  15. package/dist/labs/compiler/preprocess/index.d.ts +1 -0
  16. package/dist/labs/compiler/preprocess/index.js +1 -0
  17. package/dist/labs/compiler/preprocess/lili.d.ts +9 -0
  18. package/dist/labs/compiler/preprocess/lili.js +82 -0
  19. package/dist/labs/compiler/preprocess/source-import.d.ts +7 -0
  20. package/dist/labs/compiler/preprocess/source-import.js +9 -0
  21. package/dist/labs/compiler/types/dom.d.ts +2 -0
  22. package/dist/labs/compiler/types/dom.js +1 -0
  23. package/dist/labs/compiler/types/index.d.ts +2 -0
  24. package/dist/labs/compiler/types/index.js +1 -0
  25. package/dist/labs/compiler/types/options.d.ts +12 -0
  26. package/dist/labs/compiler/types/options.js +1 -0
  27. package/dist/labs/components/index.d.ts +1 -1
  28. package/dist/labs/components/index.js +1 -1
  29. package/dist/labs/components/sheet/sheet.svelte +49 -0
  30. package/dist/labs/components/sheet/sheet.svelte.d.ts +7 -0
  31. package/dist/labs/utils/components.d.ts +18 -0
  32. package/dist/labs/utils/components.js +92 -0
  33. package/dist/labs/utils/index.d.ts +1 -1
  34. package/dist/labs/utils/index.js +1 -1
  35. package/dist/labs/utils/types/index.d.ts +13 -0
  36. package/dist/labs/utils/types/index.js +1 -0
  37. package/package.json +1 -1
  38. package/dist/labs/components/btn/btn.svelte +0 -44
  39. package/dist/labs/components/btn/btn.svelte.d.ts +0 -7
  40. package/dist/labs/components/btn/btn.svelte.js +0 -71
  41. package/dist/labs/utils/props.d.ts +0 -15
  42. package/dist/labs/utils/props.js +0 -60
@@ -1,6 +1,4 @@
1
- type LapikitPreprocessOptions = {
2
- plugins?: string[];
3
- };
1
+ import type { LapikitPreprocessOptions } from './labs/compiler/types/options.js';
4
2
  declare function lapikitPreprocess(options?: LapikitPreprocessOptions): {
5
3
  markup({ content }: {
6
4
  content: string;
@@ -1,107 +1,5 @@
1
- const components = ['btn'];
2
- function componentName(shortName) {
3
- return 'Kit' + shortName.charAt(0).toUpperCase() + shortName.slice(1);
4
- }
5
- // plugins lapikit
6
- const lapikitPlugins = {
7
- repl: {
8
- components: ['repl'],
9
- ref: '@lapikit/repl'
10
- }
11
- };
1
+ import { liliCore } from './labs/compiler/preprocess/index.js';
12
2
  function lapikitPreprocess(options) {
13
- return {
14
- markup({ content }) {
15
- const allComponents = [...components];
16
- const componentToRef = new Map();
17
- components.forEach((comp) => {
18
- componentToRef.set(comp, 'lapikit/labs/components');
19
- });
20
- // plugins
21
- if (options?.plugins) {
22
- options.plugins.forEach((pluginKey) => {
23
- const plugin = lapikitPlugins[pluginKey];
24
- if (plugin) {
25
- plugin.components.forEach((comp) => {
26
- if (!allComponents.includes(comp)) {
27
- allComponents.push(comp);
28
- }
29
- componentToRef.set(comp, plugin.ref);
30
- });
31
- }
32
- });
33
- }
34
- const hasComponent = allComponents.some((comp) => content.includes(`<kit:${comp}`));
35
- if (!hasComponent)
36
- return;
37
- let processedContent = content;
38
- const importedComponents = new Map();
39
- let hasChanges = true;
40
- while (hasChanges) {
41
- hasChanges = false;
42
- for (const shortName of allComponents) {
43
- const componentNameStr = componentName(shortName);
44
- const attrPattern = `(?:[^>"']|"[^"]*"|'[^']*')*?`;
45
- const selfClosingRegex = new RegExp(`<kit:${shortName}(${attrPattern})\\s*/>`, 'g');
46
- const pairRegex = new RegExp(`<kit:${shortName}(${attrPattern})>([\\s\\S]*?)<\\/kit:${shortName}\\s*>`, 'g');
47
- let newContent = processedContent.replace(selfClosingRegex, (fullMatch, attrs) => {
48
- hasChanges = true;
49
- const ref = componentToRef.get(shortName) || 'lapikit/labs/components';
50
- importedComponents.set(componentNameStr, ref);
51
- return `<${componentNameStr}${attrs} />`;
52
- });
53
- newContent = newContent.replace(pairRegex, (fullMatch, attrs, children) => {
54
- hasChanges = true;
55
- const ref = componentToRef.get(shortName) || 'lapikit/labs/components';
56
- importedComponents.set(componentNameStr, ref);
57
- return `<${componentNameStr}${attrs}>${children}</${componentNameStr}>`;
58
- });
59
- if (newContent !== processedContent) {
60
- processedContent = newContent;
61
- }
62
- }
63
- }
64
- if (processedContent === content)
65
- return;
66
- if (importedComponents.size > 0) {
67
- const importsByRef = new Map();
68
- importedComponents.forEach((ref, component) => {
69
- if (!importsByRef.has(ref)) {
70
- importsByRef.set(ref, []);
71
- }
72
- importsByRef.get(ref).push(component);
73
- });
74
- const importLines = Array.from(importsByRef.entries())
75
- .map(([ref, components]) => {
76
- const imports = components.join(', ');
77
- return `\n\timport { ${imports} } from '${ref}';`;
78
- })
79
- .join('');
80
- const scriptRegex = /<script(?![^>]*\bmodule\b)([^>]*)>/;
81
- const scriptMatch = processedContent.match(scriptRegex);
82
- if (scriptMatch && scriptMatch.index !== undefined) {
83
- const insertPos = scriptMatch.index + scriptMatch[0].length;
84
- processedContent =
85
- processedContent.slice(0, insertPos) + importLines + processedContent.slice(insertPos);
86
- }
87
- else {
88
- const moduleScriptMatch = processedContent.match(/<script[^>]*\bmodule\b[^>]*>/);
89
- if (moduleScriptMatch && moduleScriptMatch.index !== undefined) {
90
- const moduleScriptEnd = processedContent.indexOf('</script>', moduleScriptMatch.index) + '</script>'.length;
91
- processedContent =
92
- processedContent.slice(0, moduleScriptEnd) +
93
- `\n\n<script>${importLines}\n</script>` +
94
- processedContent.slice(moduleScriptEnd);
95
- }
96
- else {
97
- processedContent = `<script>${importLines}\n</script>\n\n` + processedContent;
98
- }
99
- }
100
- }
101
- return {
102
- code: processedContent
103
- };
104
- }
105
- };
3
+ return liliCore(options);
106
4
  }
107
5
  export { lapikitPreprocess };
@@ -0,0 +1,2 @@
1
+ declare const lapikitComponents: readonly string[];
2
+ export default lapikitComponents;
@@ -0,0 +1,2 @@
1
+ const lapikitComponents = ['sheet'];
2
+ export default lapikitComponents;
@@ -0,0 +1 @@
1
+ export * from './preprocess/index.js';
@@ -0,0 +1 @@
1
+ export * from './preprocess/index.js';
@@ -0,0 +1,27 @@
1
+ import type { SClassProp, SStyleProp } from './types/index.js';
2
+ import type { PropValue } from '../utils/types/index.js';
3
+ /**
4
+ * Computes a string of class names based on the provided sClass and classDirectiveProps.
5
+ * @param sClass - The s-class property which can be a string, array, or object.
6
+ * @param classDirectiveProps - An object containing s-class_xxx directives.
7
+ * @returns A string of class names.
8
+ */
9
+ export declare function computeSClasses(sClass: SClassProp, classDirectiveProps: Record<string, unknown>): string;
10
+ /**
11
+ * Computes a string of style declarations based on the provided sStyle and styleDirectiveProps.
12
+ * @param sStyle - The s-style property which is an object of style key-value pairs.
13
+ * @param styleDirectiveProps - An object containing s-style_xxx directives.
14
+ * @returns A string of style declarations.
15
+ */
16
+ export declare function computeSStyles(sStyle: SStyleProp, styleDirectiveProps: Record<string, unknown>): string;
17
+ /**
18
+ * Makes component props by separating s-class and s-style directives from other props.
19
+ * Optimized to use a single pass instead of three separate iterations.
20
+ * @param props The original props object containing all props.
21
+ * @returns An object containing separated classProps, styleProps, and restProps.
22
+ */
23
+ export declare function makeComponentProps(props: Record<string, unknown>): {
24
+ classProps: Record<string, PropValue>;
25
+ styleProps: Record<string, PropValue>;
26
+ restProps: Record<string, unknown>;
27
+ };
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Computes a string of class names based on the provided sClass and classDirectiveProps.
3
+ * @param sClass - The s-class property which can be a string, array, or object.
4
+ * @param classDirectiveProps - An object containing s-class_xxx directives.
5
+ * @returns A string of class names.
6
+ */
7
+ export function computeSClasses(sClass, classDirectiveProps) {
8
+ const classes = [];
9
+ // s-class string
10
+ if (typeof sClass === 'string' && sClass) {
11
+ classes.push(sClass);
12
+ }
13
+ // s-class array
14
+ if (Array.isArray(sClass)) {
15
+ for (const value of sClass) {
16
+ if (typeof value === 'string' && value) {
17
+ classes.push(value);
18
+ }
19
+ }
20
+ }
21
+ // s-class object
22
+ if (sClass && typeof sClass === 'object' && !Array.isArray(sClass)) {
23
+ const entries = Object.entries(sClass);
24
+ if (entries.length > 0) {
25
+ for (const [key, value] of entries) {
26
+ if (value === true) {
27
+ classes.push(key);
28
+ }
29
+ else if (typeof value === 'string' && value) {
30
+ classes.push(value);
31
+ }
32
+ }
33
+ }
34
+ }
35
+ // s-class_xxx
36
+ const classEntries = Object.entries(classDirectiveProps);
37
+ if (classEntries.length > 0) {
38
+ for (const [key, value] of classEntries) {
39
+ // Use slice instead of replace for better performance (8 = 's-class_'.length)
40
+ const base = key.slice(8);
41
+ if (value === true) {
42
+ classes.push(base);
43
+ }
44
+ else if (typeof value === 'string' && value) {
45
+ classes.push(`${base}${value}`);
46
+ }
47
+ }
48
+ }
49
+ return classes.join(' ');
50
+ }
51
+ /**
52
+ * Computes a string of style declarations based on the provided sStyle and styleDirectiveProps.
53
+ * @param sStyle - The s-style property which is an object of style key-value pairs.
54
+ * @param styleDirectiveProps - An object containing s-style_xxx directives.
55
+ * @returns A string of style declarations.
56
+ */
57
+ export function computeSStyles(sStyle, styleDirectiveProps) {
58
+ const styles = [];
59
+ if (sStyle && typeof sStyle === 'object') {
60
+ const entries = Object.entries(sStyle);
61
+ if (entries.length > 0) {
62
+ for (const [key, value] of entries) {
63
+ if (value) {
64
+ styles.push(`${key}: ${value}`);
65
+ }
66
+ }
67
+ }
68
+ }
69
+ const styleEntries = Object.entries(styleDirectiveProps);
70
+ if (styleEntries.length > 0) {
71
+ for (const [key, value] of styleEntries) {
72
+ // Use slice instead of replace for better performance (8 = 's-style_'.length)
73
+ const base = key.slice(8);
74
+ if (value) {
75
+ styles.push(`${base}: ${value}`);
76
+ }
77
+ }
78
+ }
79
+ return styles.join('; ');
80
+ }
81
+ /**
82
+ * Makes component props by separating s-class and s-style directives from other props.
83
+ * Optimized to use a single pass instead of three separate iterations.
84
+ * @param props The original props object containing all props.
85
+ * @returns An object containing separated classProps, styleProps, and restProps.
86
+ */
87
+ export function makeComponentProps(props) {
88
+ const classProps = {};
89
+ const styleProps = {};
90
+ const restProps = {};
91
+ for (const [key, value] of Object.entries(props)) {
92
+ if (key.startsWith('s-class_')) {
93
+ classProps[key] = value;
94
+ }
95
+ else if (key.startsWith('s-style_')) {
96
+ styleProps[key] = value;
97
+ }
98
+ else if (!key.startsWith('s-class') && !key.startsWith('s-style')) {
99
+ restProps[key] = value;
100
+ }
101
+ }
102
+ return { classProps, styleProps, restProps };
103
+ }
@@ -0,0 +1,7 @@
1
+ declare const lapikitPlugins: {
2
+ readonly repl: {
3
+ readonly components: readonly ["repl"];
4
+ readonly ref: "@lapikit/repl";
5
+ };
6
+ };
7
+ export default lapikitPlugins;
@@ -0,0 +1,7 @@
1
+ const lapikitPlugins = {
2
+ repl: {
3
+ components: ['repl'],
4
+ ref: '@lapikit/repl'
5
+ }
6
+ };
7
+ export default lapikitPlugins;
@@ -0,0 +1,2 @@
1
+ import type { ComponentInfo, KitComponentScan } from '../types/index.js';
2
+ export declare const decodeSourceMap: (content: string, componentInfo: Map<string, ComponentInfo>) => KitComponentScan;
@@ -0,0 +1,106 @@
1
+ import { findTagEnd } from './finding.js';
2
+ export const decodeSourceMap = (content, componentInfo) => {
3
+ const importedComponents = new Map();
4
+ const parts = [];
5
+ let changed = false;
6
+ let index = 0;
7
+ const length = content.length;
8
+ while (index < length) {
9
+ const nextLt = content.indexOf('<', index);
10
+ if (nextLt === -1) {
11
+ parts.push(content.slice(index));
12
+ break;
13
+ }
14
+ if (nextLt > index) {
15
+ parts.push(content.slice(index, nextLt));
16
+ }
17
+ const ch = content[nextLt + 1];
18
+ const isClosing = ch === '/';
19
+ if (content.startsWith('<script', nextLt) || content.startsWith('<style', nextLt)) {
20
+ const tagName = content.startsWith('<script', nextLt) ? 'script' : 'style';
21
+ const nameEnd = nextLt + tagName.length + 1;
22
+ const afterName = content[nameEnd];
23
+ if (afterName && !/[\s>/]/.test(afterName)) {
24
+ parts.push('<');
25
+ index = nextLt + 1;
26
+ continue;
27
+ }
28
+ const openEnd = findTagEnd(content, nameEnd);
29
+ if (openEnd === -1) {
30
+ parts.push(content.slice(nextLt));
31
+ break;
32
+ }
33
+ const closeTag = `</${tagName}>`;
34
+ const closeStart = content.indexOf(closeTag, openEnd + 1);
35
+ if (closeStart === -1) {
36
+ parts.push(content.slice(nextLt));
37
+ break;
38
+ }
39
+ const closeEnd = closeStart + closeTag.length;
40
+ parts.push(content.slice(nextLt, closeEnd));
41
+ index = closeEnd;
42
+ continue;
43
+ }
44
+ const isKitTag = (!isClosing && content.startsWith('<kit:', nextLt)) ||
45
+ (isClosing && content.startsWith('</kit:', nextLt));
46
+ if (!isKitTag) {
47
+ parts.push('<');
48
+ index = nextLt + 1;
49
+ continue;
50
+ }
51
+ const prefixLength = isClosing ? 6 : 5;
52
+ const nameStart = nextLt + prefixLength;
53
+ let nameEnd = nameStart;
54
+ while (nameEnd < length) {
55
+ const c = content[nameEnd];
56
+ if (c === '>' || c === '/' || c === ' ' || c === '\n' || c === '\t' || c === '\r') {
57
+ break;
58
+ }
59
+ nameEnd++;
60
+ }
61
+ const shortName = content.slice(nameStart, nameEnd);
62
+ if (!shortName) {
63
+ parts.push('<');
64
+ index = nextLt + 1;
65
+ continue;
66
+ }
67
+ const info = componentInfo.get(shortName);
68
+ const isKnown = info !== undefined;
69
+ if (isClosing) {
70
+ const tagEnd = content.indexOf('>', nameEnd);
71
+ if (tagEnd === -1) {
72
+ parts.push(content.slice(nextLt));
73
+ break;
74
+ }
75
+ if (isKnown) {
76
+ importedComponents.set(info.name, info.ref);
77
+ parts.push(`</${info.name}>`);
78
+ changed = true;
79
+ }
80
+ else {
81
+ parts.push(content.slice(nextLt, tagEnd + 1));
82
+ }
83
+ index = tagEnd + 1;
84
+ continue;
85
+ }
86
+ const tagEnd = findTagEnd(content, nameEnd);
87
+ if (tagEnd === -1) {
88
+ parts.push(content.slice(nextLt));
89
+ break;
90
+ }
91
+ if (isKnown) {
92
+ importedComponents.set(info.name, info.ref);
93
+ parts.push(`<${info.name}${content.slice(nameEnd, tagEnd + 1)}`);
94
+ changed = true;
95
+ }
96
+ else {
97
+ parts.push(content.slice(nextLt, tagEnd + 1));
98
+ }
99
+ index = tagEnd + 1;
100
+ }
101
+ return {
102
+ code: changed ? parts.join('') : content,
103
+ changed,
104
+ importedComponents
105
+ };
106
+ };
@@ -0,0 +1 @@
1
+ export declare const findTagEnd: (content: string, start: number) => number;
@@ -0,0 +1,49 @@
1
+ export const findTagEnd = (content, start) => {
2
+ let inSingle = false;
3
+ let inDouble = false;
4
+ let inTemplate = false;
5
+ let braceDepth = 0;
6
+ for (let i = start; i < content.length; i++) {
7
+ const ch = content[i];
8
+ const prev = i > 0 ? content[i - 1] : '';
9
+ if (inSingle) {
10
+ if (ch === "'" && prev !== '\\')
11
+ inSingle = false;
12
+ continue;
13
+ }
14
+ if (inDouble) {
15
+ if (ch === '"' && prev !== '\\')
16
+ inDouble = false;
17
+ continue;
18
+ }
19
+ if (inTemplate) {
20
+ if (ch === '`' && prev !== '\\')
21
+ inTemplate = false;
22
+ continue;
23
+ }
24
+ if (ch === "'") {
25
+ inSingle = true;
26
+ continue;
27
+ }
28
+ if (ch === '"') {
29
+ inDouble = true;
30
+ continue;
31
+ }
32
+ if (ch === '`') {
33
+ inTemplate = true;
34
+ continue;
35
+ }
36
+ if (ch === '{') {
37
+ braceDepth++;
38
+ continue;
39
+ }
40
+ if (ch === '}' && braceDepth > 0) {
41
+ braceDepth--;
42
+ continue;
43
+ }
44
+ if (braceDepth === 0 && ch === '>') {
45
+ return i;
46
+ }
47
+ }
48
+ return -1;
49
+ };
@@ -0,0 +1 @@
1
+ export * from './lili.js';
@@ -0,0 +1 @@
1
+ export * from './lili.js';
@@ -0,0 +1,9 @@
1
+ import type { LapikitPreprocessOptions } from '../types/index.js';
2
+ export declare function liliCore(options?: LapikitPreprocessOptions): {
3
+ markup({ content }: {
4
+ content: string;
5
+ filename?: string;
6
+ }): {
7
+ code: string;
8
+ } | undefined;
9
+ };
@@ -0,0 +1,82 @@
1
+ import { componentName, lapikitImportsRef } from './source-import.js';
2
+ import { decodeSourceMap } from './decode-sourcemap.js';
3
+ // imports components and plugins
4
+ import lapikitComponents from '../components.js';
5
+ import lapikitPlugins from '../plugins.js';
6
+ export function liliCore(options) {
7
+ return {
8
+ markup({ content }) {
9
+ const allComponents = [...lapikitComponents];
10
+ const componentToRef = new Map();
11
+ lapikitComponents.forEach((comp) => {
12
+ componentToRef.set(comp, lapikitImportsRef);
13
+ });
14
+ // plugins
15
+ if (options?.plugins) {
16
+ options.plugins.forEach((pluginKey) => {
17
+ const plugin = lapikitPlugins[pluginKey];
18
+ if (plugin) {
19
+ plugin.components.forEach((comp) => {
20
+ if (!allComponents.includes(comp)) {
21
+ allComponents.push(comp);
22
+ }
23
+ componentToRef.set(comp, plugin.ref);
24
+ });
25
+ }
26
+ });
27
+ }
28
+ if (!content.includes('<kit:'))
29
+ return;
30
+ const componentInfo = new Map();
31
+ for (const shortName of allComponents) {
32
+ componentInfo.set(shortName, {
33
+ name: componentName(shortName),
34
+ ref: componentToRef.get(shortName) || lapikitImportsRef
35
+ });
36
+ }
37
+ const scanResult = decodeSourceMap(content, componentInfo);
38
+ if (!scanResult.changed)
39
+ return;
40
+ let processedContent = scanResult.code;
41
+ const importedComponents = scanResult.importedComponents;
42
+ if (importedComponents.size > 0) {
43
+ const importsByRef = new Map();
44
+ importedComponents.forEach((ref, component) => {
45
+ if (!importsByRef.has(ref)) {
46
+ importsByRef.set(ref, []);
47
+ }
48
+ importsByRef.get(ref).push(component);
49
+ });
50
+ const importLines = Array.from(importsByRef.entries())
51
+ .map(([ref, components]) => {
52
+ const imports = components.join(', ');
53
+ return `\n\timport { ${imports} } from '${ref}';`;
54
+ })
55
+ .join('');
56
+ const scriptRegex = /<script(?![^>]*\bmodule\b)([^>]*)>/;
57
+ const scriptMatch = processedContent.match(scriptRegex);
58
+ if (scriptMatch && scriptMatch.index !== undefined) {
59
+ const insertPos = scriptMatch.index + scriptMatch[0].length;
60
+ processedContent =
61
+ processedContent.slice(0, insertPos) + importLines + processedContent.slice(insertPos);
62
+ }
63
+ else {
64
+ const moduleScriptMatch = processedContent.match(/<script[^>]*\bmodule\b[^>]*>/);
65
+ if (moduleScriptMatch && moduleScriptMatch.index !== undefined) {
66
+ const moduleScriptEnd = processedContent.indexOf('</script>', moduleScriptMatch.index) + '</script>'.length;
67
+ processedContent =
68
+ processedContent.slice(0, moduleScriptEnd) +
69
+ `\n\n<script>${importLines}\n</script>` +
70
+ processedContent.slice(moduleScriptEnd);
71
+ }
72
+ else {
73
+ processedContent = `<script>${importLines}\n</script>\n\n` + processedContent;
74
+ }
75
+ }
76
+ }
77
+ return {
78
+ code: processedContent
79
+ };
80
+ }
81
+ };
82
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * componentName generates the component name used in imports
3
+ * @param shortName The short name of the component
4
+ * @returns The component name with "Kit" prefix and the first letter capitalized
5
+ */
6
+ export declare function componentName(shortName: string): string;
7
+ export declare const lapikitImportsRef = "lapikit/labs/components";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * componentName generates the component name used in imports
3
+ * @param shortName The short name of the component
4
+ * @returns The component name with "Kit" prefix and the first letter capitalized
5
+ */
6
+ export function componentName(shortName) {
7
+ return 'Kit' + shortName.charAt(0).toUpperCase() + shortName.slice(1);
8
+ }
9
+ export const lapikitImportsRef = 'lapikit/labs/components';
@@ -0,0 +1,2 @@
1
+ export type SClassProp = string | string[] | Record<string, boolean | string> | undefined;
2
+ export type SStyleProp = Record<string, boolean | string> | undefined;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export type * from './dom.js';
2
+ export * from './options.js';
@@ -0,0 +1 @@
1
+ export * from './options.js';
@@ -0,0 +1,12 @@
1
+ export type LapikitPreprocessOptions = {
2
+ plugins?: string[];
3
+ };
4
+ export type KitComponentScan = {
5
+ code: string;
6
+ changed: boolean;
7
+ importedComponents: Map<string, string>;
8
+ };
9
+ export type ComponentInfo = {
10
+ name: string;
11
+ ref: string;
12
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1 +1 @@
1
- export { default as KitBtn } from './btn/btn.svelte';
1
+ export { default as KitSheet } from './sheet/sheet.svelte';
@@ -1,2 +1,2 @@
1
1
  // components
2
- export { default as KitBtn } from './btn/btn.svelte';
2
+ export { default as KitSheet } from './sheet/sheet.svelte';
@@ -0,0 +1,49 @@
1
+ <script lang="ts">
2
+ /**
3
+ * Sheet component
4
+ * @description A simple sheet component for experimentation for developers Lapikit. Please don't use it in production.
5
+ */
6
+
7
+ import { useClassName, useStyles } from '../../utils/index.js';
8
+ import { makeComponentProps } from '../../compiler/mapped-code.js';
9
+
10
+ let {
11
+ class: className,
12
+ style: styleAttr,
13
+ children,
14
+ 's-class': sClass,
15
+ 's-style': sStyle,
16
+ ...rest
17
+ } = $props();
18
+
19
+ let { classProps, styleProps, restProps } = $derived(
20
+ makeComponentProps(rest as Record<string, unknown>)
21
+ );
22
+
23
+ let componentClass = $derived(
24
+ useClassName({
25
+ baseClass: 'kit-sheet',
26
+ className,
27
+ sClass,
28
+ classProps
29
+ })
30
+ );
31
+
32
+ let componentStyle = $derived(
33
+ useStyles({
34
+ styleAttr,
35
+ sStyle,
36
+ styleProps
37
+ })
38
+ );
39
+ </script>
40
+
41
+ <div class={componentClass} style={componentStyle} {...restProps}>
42
+ {@render children()}
43
+ </div>
44
+
45
+ <style>
46
+ .kit-sheet {
47
+ border: 1px solid rgb(0, 0, 0);
48
+ }
49
+ </style>
@@ -0,0 +1,7 @@
1
+ declare const Sheet: import("svelte").Component<{
2
+ class: any;
3
+ style: any;
4
+ children: any;
5
+ } & Record<string, any>, {}, "">;
6
+ type Sheet = ReturnType<typeof Sheet>;
7
+ export default Sheet;
@@ -0,0 +1,18 @@
1
+ import type { useClassNameProps, useStylesProps } from './types/index.js';
2
+ /**
3
+ * useClassName - Utility to compute class names for a component.
4
+ * @param baseClass - The base class name for the component.
5
+ * @param className - Additional class names as a string.
6
+ * @param sClass - The s-class property which can be a string, array, or object.
7
+ * @param classProps - An object containing s-class_xxx directives.
8
+ * @returns A computed class string.
9
+ */
10
+ export declare function useClassName({ baseClass, className, sClass, classProps }?: useClassNameProps): string;
11
+ /**
12
+ * useStyles - Utility to compute style declarations for a component (optimized pure function).
13
+ * @param styleAttr - Inline style attribute as a string.
14
+ * @param sStyle - The s-style property which is an object of style key-value pairs.
15
+ * @param styleProps - An object containing s-style_xxx directives.
16
+ * @returns A computed style string.
17
+ */
18
+ export declare function useStyles({ styleAttr, sStyle, styleProps }?: useStylesProps): string;
@@ -0,0 +1,92 @@
1
+ /**
2
+ * useClassName - Utility to compute class names for a component.
3
+ * @param baseClass - The base class name for the component.
4
+ * @param className - Additional class names as a string.
5
+ * @param sClass - The s-class property which can be a string, array, or object.
6
+ * @param classProps - An object containing s-class_xxx directives.
7
+ * @returns A computed class string.
8
+ */
9
+ export function useClassName({ baseClass = '', className, sClass, classProps } = {}) {
10
+ const classes = [];
11
+ if (baseClass) {
12
+ classes.push(baseClass);
13
+ }
14
+ if (typeof sClass === 'string' && sClass) {
15
+ classes.push(sClass);
16
+ }
17
+ if (Array.isArray(sClass)) {
18
+ for (const value of sClass) {
19
+ if (typeof value === 'string' && value) {
20
+ classes.push(value);
21
+ }
22
+ }
23
+ }
24
+ if (sClass && typeof sClass === 'object' && !Array.isArray(sClass)) {
25
+ const entries = Object.entries(sClass);
26
+ if (entries.length > 0) {
27
+ for (const [key, value] of entries) {
28
+ if (value === true) {
29
+ classes.push(key);
30
+ }
31
+ else if (typeof value === 'string' && value) {
32
+ classes.push(value);
33
+ }
34
+ }
35
+ }
36
+ }
37
+ if (classProps) {
38
+ const entries = Object.entries(classProps);
39
+ if (entries.length > 0) {
40
+ for (const [key, value] of entries) {
41
+ // Use slice instead of replace for better performance (8 = 's-class_'.length)
42
+ const base = key.slice(8);
43
+ if (value === true) {
44
+ classes.push(base);
45
+ }
46
+ else if (typeof value === 'string' && value) {
47
+ classes.push(`${base}${value}`);
48
+ }
49
+ }
50
+ }
51
+ }
52
+ if (className) {
53
+ classes.push(className);
54
+ }
55
+ return classes.filter(Boolean).join(' ');
56
+ }
57
+ /**
58
+ * useStyles - Utility to compute style declarations for a component (optimized pure function).
59
+ * @param styleAttr - Inline style attribute as a string.
60
+ * @param sStyle - The s-style property which is an object of style key-value pairs.
61
+ * @param styleProps - An object containing s-style_xxx directives.
62
+ * @returns A computed style string.
63
+ */
64
+ export function useStyles({ styleAttr, sStyle, styleProps } = {}) {
65
+ const styles = [];
66
+ if (sStyle && typeof sStyle === 'object') {
67
+ const entries = Object.entries(sStyle);
68
+ if (entries.length > 0) {
69
+ for (const [key, value] of entries) {
70
+ if (value) {
71
+ styles.push(`${key}: ${value}`);
72
+ }
73
+ }
74
+ }
75
+ }
76
+ if (styleProps) {
77
+ const entries = Object.entries(styleProps);
78
+ if (entries.length > 0) {
79
+ for (const [key, value] of entries) {
80
+ // Use slice instead of replace for better performance (8 = 's-style_'.length)
81
+ const base = key.slice(8);
82
+ if (value) {
83
+ styles.push(`${base}: ${value}`);
84
+ }
85
+ }
86
+ }
87
+ }
88
+ if (styleAttr) {
89
+ styles.push(styleAttr);
90
+ }
91
+ return styles.filter(Boolean).join('; ');
92
+ }
@@ -1 +1 @@
1
- export * from './props.js';
1
+ export * from './components.js';
@@ -1 +1 @@
1
- export * from './props.js';
1
+ export * from './components.js';
@@ -0,0 +1,13 @@
1
+ import type { SClassProp, SStyleProp } from '../../compiler/types/index.js';
2
+ export type PropValue = string | boolean | number | null | undefined;
3
+ export interface useClassNameProps {
4
+ baseClass?: string;
5
+ className?: string;
6
+ sClass?: SClassProp;
7
+ classProps?: Record<string, PropValue>;
8
+ }
9
+ export interface useStylesProps {
10
+ styleAttr?: string;
11
+ sStyle?: SStyleProp;
12
+ styleProps?: Record<string, PropValue>;
13
+ }
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lapikit",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -1,44 +0,0 @@
1
- <script lang="ts">
2
- import { useClassName, useStyles } from './btn.svelte.js';
3
- import { splitSyntheticProps } from '../../utils/index.js';
4
-
5
- let {
6
- class: className,
7
- style: styleAttr,
8
- children,
9
- 's-class': sClass,
10
- 's-style': sStyle,
11
- ...rest
12
- } = $props();
13
-
14
- let { classDirectiveProps, styleDirectiveProps, regularProps } = $derived(
15
- splitSyntheticProps(rest as Record<string, unknown>)
16
- );
17
-
18
- let finalClass = $derived(
19
- useClassName({
20
- baseClass: 'kit-button',
21
- className,
22
- sClass,
23
- classDirectiveProps
24
- }).value
25
- );
26
-
27
- let finalStyle = $derived(
28
- useStyles({
29
- styleAttr,
30
- sStyle,
31
- styleDirectiveProps
32
- }).value
33
- );
34
- </script>
35
-
36
- <button class={finalClass} style={finalStyle} {...regularProps}>
37
- {@render children()}
38
- </button>
39
-
40
- <style>
41
- .kit-btn {
42
- border: 1px solid rgb(0, 0, 0);
43
- }
44
- </style>
@@ -1,7 +0,0 @@
1
- declare const Btn: import("svelte").Component<{
2
- class: any;
3
- style: any;
4
- children: any;
5
- } & Record<string, any>, {}, "">;
6
- type Btn = ReturnType<typeof Btn>;
7
- export default Btn;
@@ -1,71 +0,0 @@
1
- export function useClassName({ baseClass = '', className, sClass, classDirectiveProps } = {}) {
2
- return {
3
- get value() {
4
- const classes = [];
5
- if (baseClass) {
6
- classes.push(baseClass);
7
- }
8
- if (typeof sClass === 'string' && sClass) {
9
- classes.push(sClass);
10
- }
11
- if (Array.isArray(sClass)) {
12
- for (const value of sClass) {
13
- if (typeof value === 'string' && value) {
14
- classes.push(value);
15
- }
16
- }
17
- }
18
- if (sClass && typeof sClass === 'object' && !Array.isArray(sClass)) {
19
- Object.entries(sClass).forEach(([key, value]) => {
20
- if (value === true) {
21
- classes.push(key);
22
- }
23
- else if (typeof value === 'string' && value) {
24
- classes.push(value);
25
- }
26
- });
27
- }
28
- if (classDirectiveProps) {
29
- Object.entries(classDirectiveProps).forEach(([key, value]) => {
30
- const base = key.replace('s-class_', '');
31
- if (value === true) {
32
- classes.push(base);
33
- }
34
- else if (typeof value === 'string' && value) {
35
- classes.push(`${base}${value}`);
36
- }
37
- });
38
- }
39
- if (className) {
40
- classes.push(className);
41
- }
42
- return classes.filter(Boolean).join(' ');
43
- }
44
- };
45
- }
46
- export function useStyles({ styleAttr, sStyle, styleDirectiveProps } = {}) {
47
- return {
48
- get value() {
49
- const styles = [];
50
- if (sStyle && typeof sStyle === 'object') {
51
- Object.entries(sStyle).forEach(([key, value]) => {
52
- if (value) {
53
- styles.push(`${key}: ${value}`);
54
- }
55
- });
56
- }
57
- if (styleDirectiveProps) {
58
- Object.entries(styleDirectiveProps).forEach(([key, value]) => {
59
- const base = key.replace('s-style_', '');
60
- if (value) {
61
- styles.push(`${base}: ${value}`);
62
- }
63
- });
64
- }
65
- if (styleAttr) {
66
- styles.push(styleAttr);
67
- }
68
- return styles.filter(Boolean).join('; ');
69
- }
70
- };
71
- }
@@ -1,15 +0,0 @@
1
- export type SClassProp = string | string[] | Record<string, boolean | string> | undefined;
2
- export type SStyleProp = Record<string, boolean | string> | undefined;
3
- export declare function splitSyntheticProps(allProps: Record<string, unknown>): {
4
- classDirectiveProps: {
5
- [k: string]: unknown;
6
- };
7
- styleDirectiveProps: {
8
- [k: string]: unknown;
9
- };
10
- regularProps: {
11
- [k: string]: unknown;
12
- };
13
- };
14
- export declare function computeSClasses(sClass: SClassProp, classDirectiveProps: Record<string, unknown>): string;
15
- export declare function computeSStyles(sStyle: SStyleProp, styleDirectiveProps: Record<string, unknown>): string;
@@ -1,60 +0,0 @@
1
- export function splitSyntheticProps(allProps) {
2
- const classDirectiveProps = Object.fromEntries(Object.entries(allProps).filter(([key]) => key.startsWith('s-class_')));
3
- const styleDirectiveProps = Object.fromEntries(Object.entries(allProps).filter(([key]) => key.startsWith('s-style_')));
4
- const regularProps = Object.fromEntries(Object.entries(allProps).filter(([key]) => !key.startsWith('s-class') && !key.startsWith('s-style')));
5
- return { classDirectiveProps, styleDirectiveProps, regularProps };
6
- }
7
- export function computeSClasses(sClass, classDirectiveProps) {
8
- const classes = [];
9
- // s-class string
10
- if (typeof sClass === 'string' && sClass) {
11
- classes.push(sClass);
12
- }
13
- // s-class array
14
- if (Array.isArray(sClass)) {
15
- for (const value of sClass) {
16
- if (typeof value === 'string' && value) {
17
- classes.push(value);
18
- }
19
- }
20
- }
21
- // s-class object
22
- if (sClass && typeof sClass === 'object' && !Array.isArray(sClass)) {
23
- Object.entries(sClass).forEach(([key, value]) => {
24
- if (value === true) {
25
- classes.push(key);
26
- }
27
- else if (typeof value === 'string' && value) {
28
- classes.push(value);
29
- }
30
- });
31
- }
32
- // s-class_xxx
33
- Object.entries(classDirectiveProps).forEach(([key, value]) => {
34
- const base = key.replace('s-class_', '');
35
- if (value === true) {
36
- classes.push(base);
37
- }
38
- else if (typeof value === 'string' && value) {
39
- classes.push(`${base}${value}`);
40
- }
41
- });
42
- return classes.join(' ');
43
- }
44
- export function computeSStyles(sStyle, styleDirectiveProps) {
45
- const styles = [];
46
- if (sStyle && typeof sStyle === 'object') {
47
- Object.entries(sStyle).forEach(([key, value]) => {
48
- if (value) {
49
- styles.push(`${key}: ${value}`);
50
- }
51
- });
52
- }
53
- Object.entries(styleDirectiveProps).forEach(([key, value]) => {
54
- const base = key.replace('s-style_', '');
55
- if (value) {
56
- styles.push(`${base}: ${value}`);
57
- }
58
- });
59
- return styles.join('; ');
60
- }