@knapsack/rendering-utils 4.69.11--canary.4820.6c04f2a.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/.eslintignore ADDED
@@ -0,0 +1 @@
1
+ dist
package/.eslintrc.cjs ADDED
@@ -0,0 +1,9 @@
1
+ module.exports = {
2
+ extends: [
3
+ '@knapsack/eslint-config-starter',
4
+ '@knapsack/eslint-config-starter/esm',
5
+ ],
6
+ parserOptions: { tsconfigRootDir: __dirname },
7
+ ignorePatterns: [],
8
+ rules: {},
9
+ };
@@ -0,0 +1,11 @@
1
+ import { dirname } from 'path';
2
+ import { fileURLToPath } from 'url';
3
+
4
+ import defaultConfig from '../../.lintstagedrc.mjs';
5
+
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+
8
+ export default {
9
+ '*.{ts,tsx,js,jsx,cjs,mjs}': `cd ${__dirname} && ./node_modules/.bin/eslint`,
10
+ ...defaultConfig,
11
+ };
@@ -0,0 +1,4 @@
1
+
2
+ > @knapsack/rendering-utils@4.69.10 build /home/runner/work/app-monorepo/app-monorepo/libs/rendering-utils
3
+ > tsc
4
+
@@ -0,0 +1,4 @@
1
+
2
+ > @knapsack/rendering-utils@4.69.10 lint /home/runner/work/app-monorepo/app-monorepo/libs/rendering-utils
3
+ > eslint ./
4
+
@@ -0,0 +1,4 @@
1
+ export * from './rendering.js';
2
+ export * from './slot-layout-options-utils.js';
3
+ export * from './theming.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gCAAgC,CAAC;AAC/C,cAAc,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from './rendering.js';
2
+ export * from './slot-layout-options-utils.js';
3
+ export * from './theming.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gCAAgC,CAAC;AAC/C,cAAc,cAAc,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { KsAppClientData, KsAppClientDataNoMeta, RenderDataDemo, ContentStateForRendering } from '@knapsack/types';
2
+ export declare function getContentStateFromAppClientData({ patterns, demosById, }: {
3
+ patterns: KsAppClientDataNoMeta['patternsState']['patterns'];
4
+ demosById: KsAppClientDataNoMeta['db']['demos']['byId'];
5
+ }): ContentStateForRendering;
6
+ /**
7
+ * What we're going to here is look at all the slots data and grab
8
+ * the ACTUAL demo data we have locally here instead of just sending up the
9
+ * demoId - b/c that could be wrong on the server due to changes that were made
10
+ * in the UI to that demo that is in a slot for the demo we're currently rendering.
11
+ * A good example is if the Button was changed and we are now rendering a Card
12
+ * that uses the Button.
13
+ */
14
+ export declare function inlineDemoData({ demosById, demo, collectionsParentKey, }: {
15
+ demosById: KsAppClientData['db']['demos']['byId'];
16
+ demo: Extract<RenderDataDemo, {
17
+ type: 'data';
18
+ }>;
19
+ collectionsParentKey: string;
20
+ }): Extract<RenderDataDemo, {
21
+ type: 'data';
22
+ }>;
23
+ //# sourceMappingURL=rendering.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rendering.d.ts","sourceRoot":"","sources":["../src/rendering.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACrB,cAAc,EACd,wBAAwB,EACzB,MAAM,iBAAiB,CAAC;AAGzB,wBAAgB,gCAAgC,CAAC,EAC/C,QAAQ,EACR,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,qBAAqB,CAAC,eAAe,CAAC,CAAC,UAAU,CAAC,CAAC;IAC7D,SAAS,EAAE,qBAAqB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;CACzD,GAAG,wBAAwB,CAgC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,EAC7B,SAAS,EACT,IAAI,EACJ,oBAAoB,GACrB,EAAE;IACD,SAAS,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;IAClD,IAAI,EAAE,OAAO,CAAC,cAAc,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,oBAAoB,EAAE,MAAM,CAAC;CAC9B,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAkC5C"}
@@ -0,0 +1,75 @@
1
+ import { isEmpty, produce } from '@knapsack/utils';
2
+ import { convertSlotOptions } from './slot-layout-options-utils.js';
3
+ export function getContentStateFromAppClientData({ patterns, demosById, }) {
4
+ return {
5
+ patterns: Object.values(patterns).reduce((acc, pattern) => {
6
+ var _a, _b;
7
+ acc[pattern.id] = {
8
+ id: pattern.id,
9
+ templateDemos: ((_a = pattern.templates) === null || _a === void 0 ? void 0 : _a.flatMap((t) => {
10
+ return t.demoIds
11
+ .map((demoId) => {
12
+ const demo = demosById[demoId];
13
+ return {
14
+ ...demo,
15
+ templateId: t.id,
16
+ templateLanguageId: t.templateLanguageId,
17
+ };
18
+ })
19
+ .filter((d) => d.type === 'template');
20
+ })) || [],
21
+ templates: ((_b = pattern.templates) === null || _b === void 0 ? void 0 : _b.map(({ id, alias, path, templateLanguageId, spec }) => ({
22
+ id,
23
+ alias,
24
+ path,
25
+ templateLanguageId,
26
+ spec,
27
+ }))) || [],
28
+ };
29
+ return acc;
30
+ }, {}),
31
+ };
32
+ }
33
+ /**
34
+ * What we're going to here is look at all the slots data and grab
35
+ * the ACTUAL demo data we have locally here instead of just sending up the
36
+ * demoId - b/c that could be wrong on the server due to changes that were made
37
+ * in the UI to that demo that is in a slot for the demo we're currently rendering.
38
+ * A good example is if the Button was changed and we are now rendering a Card
39
+ * that uses the Button.
40
+ */
41
+ export function inlineDemoData({ demosById, demo, collectionsParentKey, }) {
42
+ if (Object.keys(demo.data.slots || {}).length === 0)
43
+ return demo;
44
+ return produce(demo, (draft) => {
45
+ Object.entries(draft.data.slots || {}).forEach(([slotName, slottedDatas]) => {
46
+ var _a;
47
+ var _b;
48
+ const slotOptions = (_a = draft.data.slotsOptions) === null || _a === void 0 ? void 0 : _a[slotName];
49
+ if (!isEmpty(slotOptions)) {
50
+ (_b = draft.data).slotsOptionsComputed || (_b.slotsOptionsComputed = {});
51
+ draft.data.slotsOptionsComputed[slotName] = convertSlotOptions({
52
+ slotOptions,
53
+ collectionsParentKey,
54
+ });
55
+ }
56
+ slottedDatas.forEach((slottedData) => {
57
+ if (slottedData.type !== 'template-demo')
58
+ return;
59
+ const slottedDemo = demosById[slottedData.demoId];
60
+ if (!slottedDemo) {
61
+ throw new Error(`slottedDemo, ${slottedData.demoId} not found in ${draft.id}`);
62
+ }
63
+ if (slottedDemo.type === 'data') {
64
+ // recursively grab the data of the sub-components of our sub-components
65
+ slottedData.demo = inlineDemoData({
66
+ demosById,
67
+ demo: slottedDemo,
68
+ collectionsParentKey,
69
+ });
70
+ }
71
+ });
72
+ });
73
+ });
74
+ }
75
+ //# sourceMappingURL=rendering.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rendering.js","sourceRoot":"","sources":["../src/rendering.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { SlotOptions, SlotOptionsComputed } from '@knapsack/types';
2
+ export declare function convertSlotOptions({ slotOptions: { cssClasses, wrappingElementName, ...slotOptions }, collectionsParentKey, }: {
3
+ slotOptions: SlotOptions;
4
+ collectionsParentKey: string;
5
+ }): SlotOptionsComputed;
6
+ //# sourceMappingURL=slot-layout-options-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slot-layout-options-utils.d.ts","sourceRoot":"","sources":["../src/slot-layout-options-utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,mBAAmB,EAEpB,MAAM,iBAAiB,CAAC;AAkBzB,wBAAgB,kBAAkB,CAAC,EACjC,WAAW,EAAE,EAAE,UAAe,EAAE,mBAA2B,EAAE,GAAG,WAAW,EAAE,EAC7E,oBAAoC,GACrC,EAAE;IACD,WAAW,EAAE,WAAW,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;CAC9B,GAAG,mBAAmB,CAqJtB"}
@@ -0,0 +1,156 @@
1
+ import { cssVarName, keys } from '@knapsack/utils';
2
+ import { themeDefinitionToAttributes } from './theming.js';
3
+ /**
4
+ * Helper function to convert a `TokenSrcValueInfo` to a string value.
5
+ */
6
+ const tokenSrcValueInfoToValue = (tokenSrcValueInfo) => {
7
+ return tokenSrcValueInfo.kind === 'static'
8
+ ? tokenSrcValueInfo.value
9
+ : `var(${cssVarName(tokenSrcValueInfo.referencedTokenId)})`;
10
+ };
11
+ export function convertSlotOptions({ slotOptions: { cssClasses = [], wrappingElementName = 'div', ...slotOptions }, collectionsParentKey = 'collections', }) {
12
+ return keys(slotOptions).reduce((acc, id) => {
13
+ switch (id) {
14
+ case 'gap': {
15
+ const tokenSrcValueInfo = slotOptions[id];
16
+ if (!tokenSrcValueInfo)
17
+ return acc;
18
+ acc.styles.display = 'flex';
19
+ acc.styles.gap = tokenSrcValueInfoToValue(tokenSrcValueInfo.value);
20
+ break;
21
+ }
22
+ case 'align': {
23
+ const option = slotOptions[id];
24
+ if (!option)
25
+ return acc;
26
+ acc.styles.display = 'flex';
27
+ switch (option.value) {
28
+ case 'top-left': {
29
+ acc.styles.alignItems = 'start';
30
+ acc.styles.justifyContent = 'start';
31
+ break;
32
+ }
33
+ case 'top-center': {
34
+ acc.styles.alignItems = 'start';
35
+ acc.styles.justifyContent = 'center';
36
+ break;
37
+ }
38
+ case 'top-right': {
39
+ acc.styles.alignItems = 'start';
40
+ acc.styles.justifyContent = 'end';
41
+ break;
42
+ }
43
+ case 'right': {
44
+ acc.styles.alignItems = 'center';
45
+ acc.styles.justifyContent = 'end';
46
+ break;
47
+ }
48
+ case 'bottom-right': {
49
+ acc.styles.alignItems = 'end';
50
+ acc.styles.justifyContent = 'end';
51
+ break;
52
+ }
53
+ case 'bottom-center': {
54
+ acc.styles.alignItems = 'end';
55
+ acc.styles.justifyContent = 'center';
56
+ break;
57
+ }
58
+ case 'bottom-left': {
59
+ acc.styles.alignItems = 'end';
60
+ acc.styles.justifyContent = 'start';
61
+ break;
62
+ }
63
+ case 'center': {
64
+ acc.styles.alignItems = 'center';
65
+ acc.styles.justifyContent = 'center';
66
+ break;
67
+ }
68
+ case 'left': {
69
+ acc.styles.alignItems = 'center';
70
+ acc.styles.justifyContent = 'start';
71
+ break;
72
+ }
73
+ default: {
74
+ const _exhaustiveCheck = option.value;
75
+ }
76
+ }
77
+ break;
78
+ }
79
+ case 'layout': {
80
+ const option = slotOptions[id];
81
+ if (!option)
82
+ return acc;
83
+ acc.styles.display = 'flex';
84
+ acc.styles.width = '100%';
85
+ switch (option.value) {
86
+ case 'horizontal': {
87
+ acc.styles.flexFlow = 'row';
88
+ break;
89
+ }
90
+ case 'vertical': {
91
+ acc.styles.flexFlow = 'column';
92
+ break;
93
+ }
94
+ case 'wrap': {
95
+ acc.styles.flexFlow = 'wrap';
96
+ break;
97
+ }
98
+ default: {
99
+ const _exhaustiveCheck = option.value;
100
+ }
101
+ }
102
+ break;
103
+ }
104
+ case 'paddingHorizontal': {
105
+ const tokenSrcValueInfo = slotOptions[id];
106
+ if (!tokenSrcValueInfo)
107
+ return acc;
108
+ const [paddingLeft, paddingRight] = tokenSrcValueInfo.value;
109
+ // Left
110
+ if (paddingLeft === null || paddingLeft === void 0 ? void 0 : paddingLeft.kind) {
111
+ acc.styles.paddingLeft = tokenSrcValueInfoToValue(paddingLeft);
112
+ }
113
+ // Right
114
+ if (paddingRight === null || paddingRight === void 0 ? void 0 : paddingRight.kind) {
115
+ acc.styles.paddingRight = tokenSrcValueInfoToValue(paddingRight);
116
+ }
117
+ break;
118
+ }
119
+ case 'paddingVertical': {
120
+ const tokenSrcValueInfo = slotOptions[id];
121
+ if (!tokenSrcValueInfo)
122
+ return acc;
123
+ const [paddingTop, paddingBottom] = tokenSrcValueInfo.value;
124
+ // Top
125
+ if (paddingTop === null || paddingTop === void 0 ? void 0 : paddingTop.kind) {
126
+ acc.styles.paddingTop = tokenSrcValueInfoToValue(paddingTop);
127
+ }
128
+ // Bottom
129
+ if (paddingBottom === null || paddingBottom === void 0 ? void 0 : paddingBottom.kind) {
130
+ acc.styles.paddingBottom = tokenSrcValueInfoToValue(paddingBottom);
131
+ }
132
+ break;
133
+ }
134
+ case 'theme': {
135
+ const themeDef = slotOptions[id];
136
+ if (!themeDef)
137
+ return acc;
138
+ acc.attributes = themeDefinitionToAttributes({
139
+ collectionsParentKey,
140
+ themeDefinition: themeDef,
141
+ });
142
+ break;
143
+ }
144
+ default: {
145
+ const _exhaustiveCheck = id;
146
+ }
147
+ }
148
+ return acc;
149
+ }, {
150
+ wrappingElementName,
151
+ cssClasses,
152
+ attributes: {},
153
+ styles: {},
154
+ });
155
+ }
156
+ //# sourceMappingURL=slot-layout-options-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slot-layout-options-utils.js","sourceRoot":"","sources":["../src/slot-layout-options-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { ThemeDefinition } from '@knapsack/types';
2
+ export declare const themeDefinitionToAttributes: ({ collectionsParentKey, themeDefinition, }: {
3
+ collectionsParentKey: string;
4
+ themeDefinition: ThemeDefinition;
5
+ }) => {
6
+ [k: string]: string;
7
+ };
8
+ //# sourceMappingURL=theming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theming.d.ts","sourceRoot":"","sources":["../src/theming.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,eAAO,MAAM,2BAA2B,+CAGrC;IACD,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,eAAe,CAAC;CAClC;;CAcA,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { kebabCase } from '@knapsack/utils';
2
+ export const themeDefinitionToAttributes = ({ collectionsParentKey, themeDefinition = {}, }) => {
3
+ // No collectionsParentKey means *they have not configured collections*
4
+ if (!collectionsParentKey)
5
+ return {};
6
+ return Object.fromEntries(Object.entries(themeDefinition)
7
+ .filter(([_, modeId]) => !!modeId)
8
+ .map(([collectionId, modeId]) => {
9
+ return [
10
+ kebabCase(`data-${collectionsParentKey}-${collectionId}`),
11
+ modeId,
12
+ ];
13
+ }));
14
+ };
15
+ //# sourceMappingURL=theming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theming.js","sourceRoot":"","sources":["../src/theming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,EAC1C,oBAAoB,EACpB,eAAe,GAAG,EAAE,GAIrB,EAAE,EAAE;IACH,uEAAuE;IACvE,IAAI,CAAC,oBAAoB;QAAE,OAAO,EAAE,CAAC;IAErC,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC;SAC5B,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;SACjC,GAAG,CAAC,CAAC,CAAC,YAAY,EAAE,MAAM,CAAC,EAAE,EAAE;QAC9B,OAAO;YACL,SAAS,CAAC,QAAQ,oBAAoB,IAAI,YAAY,EAAE,CAAC;YACzD,MAAM;SACP,CAAC;IACJ,CAAC,CAAC,CACL,CAAC;AACJ,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@knapsack/rendering-utils",
3
+ "description": "",
4
+ "version": "4.69.11--canary.4820.6c04f2a.0",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.js"
10
+ },
11
+ "./package": "./package.json",
12
+ "./package.json": "./package.json"
13
+ },
14
+ "sideEffects": false,
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "clean": "rm -rf ./dist",
18
+ "lint": "eslint ./"
19
+ },
20
+ "dependencies": {
21
+ "@knapsack/utils": "4.69.11--canary.4820.6c04f2a.0"
22
+ },
23
+ "devDependencies": {
24
+ "@knapsack/eslint-config-starter": "4.69.11--canary.4820.6c04f2a.0",
25
+ "@knapsack/prettier-config": "4.69.11--canary.4820.6c04f2a.0",
26
+ "@knapsack/types": "4.69.11--canary.4820.6c04f2a.0",
27
+ "@knapsack/typescript-config-starter": "4.69.11--canary.4820.6c04f2a.0",
28
+ "eslint": "^8.57.0",
29
+ "typescript": "^5.5.4"
30
+ },
31
+ "license": "GPL-2.0-or-later",
32
+ "publishConfig": {
33
+ "access": "public"
34
+ },
35
+ "repository": {
36
+ "url": "https://github.com/knapsack-labs/app-monorepo",
37
+ "directory": "libs/rendering-utils",
38
+ "type": "git"
39
+ },
40
+ "gitHead": "6c04f2a066b6dfde853781a65b2c6e43a3a29f2f"
41
+ }
package/readme.md ADDED
@@ -0,0 +1 @@
1
+
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './rendering.js';
2
+ export * from './slot-layout-options-utils.js';
3
+ export * from './theming.js';
@@ -0,0 +1,100 @@
1
+ import { isEmpty, produce } from '@knapsack/utils';
2
+ import type {
3
+ KsAppClientData,
4
+ KsAppClientDataNoMeta,
5
+ RenderDataDemo,
6
+ ContentStateForRendering,
7
+ } from '@knapsack/types';
8
+ import { convertSlotOptions } from './slot-layout-options-utils.js';
9
+
10
+ export function getContentStateFromAppClientData({
11
+ patterns,
12
+ demosById,
13
+ }: {
14
+ patterns: KsAppClientDataNoMeta['patternsState']['patterns'];
15
+ demosById: KsAppClientDataNoMeta['db']['demos']['byId'];
16
+ }): ContentStateForRendering {
17
+ return {
18
+ patterns: Object.values(patterns).reduce((acc, pattern) => {
19
+ acc[pattern.id] = {
20
+ id: pattern.id,
21
+ templateDemos:
22
+ pattern.templates?.flatMap((t) => {
23
+ return t.demoIds
24
+ .map((demoId) => {
25
+ const demo = demosById[demoId];
26
+ return {
27
+ ...demo,
28
+ templateId: t.id,
29
+ templateLanguageId: t.templateLanguageId,
30
+ };
31
+ })
32
+ .filter((d) => d.type === 'template');
33
+ }) || [],
34
+ templates:
35
+ pattern.templates?.map(
36
+ ({ id, alias, path, templateLanguageId, spec }) => ({
37
+ id,
38
+ alias,
39
+ path,
40
+ templateLanguageId,
41
+ spec,
42
+ }),
43
+ ) || [],
44
+ };
45
+ return acc;
46
+ }, {} as ContentStateForRendering['patterns']),
47
+ };
48
+ }
49
+
50
+ /**
51
+ * What we're going to here is look at all the slots data and grab
52
+ * the ACTUAL demo data we have locally here instead of just sending up the
53
+ * demoId - b/c that could be wrong on the server due to changes that were made
54
+ * in the UI to that demo that is in a slot for the demo we're currently rendering.
55
+ * A good example is if the Button was changed and we are now rendering a Card
56
+ * that uses the Button.
57
+ */
58
+ export function inlineDemoData({
59
+ demosById,
60
+ demo,
61
+ collectionsParentKey,
62
+ }: {
63
+ demosById: KsAppClientData['db']['demos']['byId'];
64
+ demo: Extract<RenderDataDemo, { type: 'data' }>;
65
+ collectionsParentKey: string;
66
+ }): Extract<RenderDataDemo, { type: 'data' }> {
67
+ if (Object.keys(demo.data.slots || {}).length === 0) return demo;
68
+ return produce(demo, (draft) => {
69
+ Object.entries(draft.data.slots || {}).forEach(
70
+ ([slotName, slottedDatas]) => {
71
+ const slotOptions = draft.data.slotsOptions?.[slotName];
72
+ if (!isEmpty(slotOptions)) {
73
+ draft.data.slotsOptionsComputed ||= {};
74
+ draft.data.slotsOptionsComputed[slotName] = convertSlotOptions({
75
+ slotOptions,
76
+ collectionsParentKey,
77
+ });
78
+ }
79
+ slottedDatas.forEach((slottedData) => {
80
+ if (slottedData.type !== 'template-demo') return;
81
+ const slottedDemo = demosById[slottedData.demoId];
82
+ if (!slottedDemo) {
83
+ throw new Error(
84
+ `slottedDemo, ${slottedData.demoId} not found in ${draft.id}`,
85
+ );
86
+ }
87
+
88
+ if (slottedDemo.type === 'data') {
89
+ // recursively grab the data of the sub-components of our sub-components
90
+ slottedData.demo = inlineDemoData({
91
+ demosById,
92
+ demo: slottedDemo,
93
+ collectionsParentKey,
94
+ });
95
+ }
96
+ });
97
+ },
98
+ );
99
+ });
100
+ }
@@ -0,0 +1,179 @@
1
+ import { cssVarName, keys } from '@knapsack/utils';
2
+ import type {
3
+ SlotOptions,
4
+ SlotOptionsComputed,
5
+ TokenSrcValueInfo,
6
+ } from '@knapsack/types';
7
+ import { themeDefinitionToAttributes } from './theming.js';
8
+
9
+ type TokensWithStringStaticVal = Extract<
10
+ TokenSrcValueInfo,
11
+ { kind: 'static'; value: string }
12
+ >;
13
+ /**
14
+ * Helper function to convert a `TokenSrcValueInfo` to a string value.
15
+ */
16
+ const tokenSrcValueInfoToValue = (
17
+ tokenSrcValueInfo: TokenSrcValueInfo<TokensWithStringStaticVal['type']>,
18
+ ): string => {
19
+ return tokenSrcValueInfo.kind === 'static'
20
+ ? tokenSrcValueInfo.value
21
+ : `var(${cssVarName(tokenSrcValueInfo.referencedTokenId)})`;
22
+ };
23
+
24
+ export function convertSlotOptions({
25
+ slotOptions: { cssClasses = [], wrappingElementName = 'div', ...slotOptions },
26
+ collectionsParentKey = 'collections',
27
+ }: {
28
+ slotOptions: SlotOptions;
29
+ collectionsParentKey: string;
30
+ }): SlotOptionsComputed {
31
+ return keys(slotOptions).reduce<SlotOptionsComputed>(
32
+ (acc, id) => {
33
+ switch (id) {
34
+ case 'gap': {
35
+ const tokenSrcValueInfo = slotOptions[id];
36
+ if (!tokenSrcValueInfo) return acc;
37
+ acc.styles.display = 'flex';
38
+ acc.styles.gap = tokenSrcValueInfoToValue(tokenSrcValueInfo.value);
39
+
40
+ break;
41
+ }
42
+ case 'align': {
43
+ const option = slotOptions[id];
44
+ if (!option) return acc;
45
+ acc.styles.display = 'flex';
46
+ switch (option.value) {
47
+ case 'top-left': {
48
+ acc.styles.alignItems = 'start';
49
+ acc.styles.justifyContent = 'start';
50
+ break;
51
+ }
52
+ case 'top-center': {
53
+ acc.styles.alignItems = 'start';
54
+ acc.styles.justifyContent = 'center';
55
+ break;
56
+ }
57
+ case 'top-right': {
58
+ acc.styles.alignItems = 'start';
59
+ acc.styles.justifyContent = 'end';
60
+ break;
61
+ }
62
+ case 'right': {
63
+ acc.styles.alignItems = 'center';
64
+ acc.styles.justifyContent = 'end';
65
+ break;
66
+ }
67
+ case 'bottom-right': {
68
+ acc.styles.alignItems = 'end';
69
+ acc.styles.justifyContent = 'end';
70
+ break;
71
+ }
72
+ case 'bottom-center': {
73
+ acc.styles.alignItems = 'end';
74
+ acc.styles.justifyContent = 'center';
75
+ break;
76
+ }
77
+ case 'bottom-left': {
78
+ acc.styles.alignItems = 'end';
79
+ acc.styles.justifyContent = 'start';
80
+ break;
81
+ }
82
+ case 'center': {
83
+ acc.styles.alignItems = 'center';
84
+ acc.styles.justifyContent = 'center';
85
+ break;
86
+ }
87
+ case 'left': {
88
+ acc.styles.alignItems = 'center';
89
+ acc.styles.justifyContent = 'start';
90
+ break;
91
+ }
92
+ default: {
93
+ const _exhaustiveCheck: never = option.value;
94
+ }
95
+ }
96
+
97
+ break;
98
+ }
99
+ case 'layout': {
100
+ const option = slotOptions[id];
101
+ if (!option) return acc;
102
+ acc.styles.display = 'flex';
103
+ acc.styles.width = '100%';
104
+ switch (option.value) {
105
+ case 'horizontal': {
106
+ acc.styles.flexFlow = 'row';
107
+ break;
108
+ }
109
+ case 'vertical': {
110
+ acc.styles.flexFlow = 'column';
111
+ break;
112
+ }
113
+ case 'wrap': {
114
+ acc.styles.flexFlow = 'wrap';
115
+ break;
116
+ }
117
+ default: {
118
+ const _exhaustiveCheck: never = option.value;
119
+ }
120
+ }
121
+ break;
122
+ }
123
+ case 'paddingHorizontal': {
124
+ const tokenSrcValueInfo = slotOptions[id];
125
+ if (!tokenSrcValueInfo) return acc;
126
+
127
+ const [paddingLeft, paddingRight] = tokenSrcValueInfo.value;
128
+
129
+ // Left
130
+ if (paddingLeft?.kind) {
131
+ acc.styles.paddingLeft = tokenSrcValueInfoToValue(paddingLeft);
132
+ }
133
+ // Right
134
+ if (paddingRight?.kind) {
135
+ acc.styles.paddingRight = tokenSrcValueInfoToValue(paddingRight);
136
+ }
137
+ break;
138
+ }
139
+ case 'paddingVertical': {
140
+ const tokenSrcValueInfo = slotOptions[id];
141
+ if (!tokenSrcValueInfo) return acc;
142
+
143
+ const [paddingTop, paddingBottom] = tokenSrcValueInfo.value;
144
+
145
+ // Top
146
+ if (paddingTop?.kind) {
147
+ acc.styles.paddingTop = tokenSrcValueInfoToValue(paddingTop);
148
+ }
149
+ // Bottom
150
+ if (paddingBottom?.kind) {
151
+ acc.styles.paddingBottom = tokenSrcValueInfoToValue(paddingBottom);
152
+ }
153
+ break;
154
+ }
155
+ case 'theme': {
156
+ const themeDef = slotOptions[id];
157
+ if (!themeDef) return acc;
158
+
159
+ acc.attributes = themeDefinitionToAttributes({
160
+ collectionsParentKey,
161
+ themeDefinition: themeDef,
162
+ });
163
+
164
+ break;
165
+ }
166
+ default: {
167
+ const _exhaustiveCheck: never = id;
168
+ }
169
+ }
170
+ return acc;
171
+ },
172
+ {
173
+ wrappingElementName,
174
+ cssClasses,
175
+ attributes: {},
176
+ styles: {},
177
+ } satisfies SlotOptionsComputed,
178
+ );
179
+ }
package/src/theming.ts ADDED
@@ -0,0 +1,24 @@
1
+ import { kebabCase } from '@knapsack/utils';
2
+ import type { ThemeDefinition } from '@knapsack/types';
3
+
4
+ export const themeDefinitionToAttributes = ({
5
+ collectionsParentKey,
6
+ themeDefinition = {},
7
+ }: {
8
+ collectionsParentKey: string;
9
+ themeDefinition: ThemeDefinition;
10
+ }) => {
11
+ // No collectionsParentKey means *they have not configured collections*
12
+ if (!collectionsParentKey) return {};
13
+
14
+ return Object.fromEntries(
15
+ Object.entries(themeDefinition)
16
+ .filter(([_, modeId]) => !!modeId)
17
+ .map(([collectionId, modeId]) => {
18
+ return [
19
+ kebabCase(`data-${collectionsParentKey}-${collectionId}`),
20
+ modeId,
21
+ ];
22
+ }),
23
+ );
24
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "@knapsack/typescript-config-starter/tsconfig.build.json",
3
+ "compilerOptions": {
4
+ "noImplicitAny": true,
5
+ "strict": true,
6
+ "outDir": "./dist"
7
+ },
8
+ "include": ["./src"]
9
+ }