@kalink-ui/seedly 0.1.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/package.json +78 -0
  2. package/src/components/.DS_Store +0 -0
  3. package/src/components/box/box.css.ts +47 -0
  4. package/src/components/box/box.stories.tsx +29 -0
  5. package/src/components/box/box.tsx +55 -0
  6. package/src/components/box/index.ts +2 -0
  7. package/src/components/button/button.css.ts +33 -0
  8. package/src/components/button/button.stories.tsx +31 -0
  9. package/src/components/button/button.tsx +33 -0
  10. package/src/components/button/index.ts +2 -0
  11. package/src/components/center/.DS_Store +0 -0
  12. package/src/components/center/center.css.ts +35 -0
  13. package/src/components/center/center.stories.tsx +31 -0
  14. package/src/components/center/center.tsx +46 -0
  15. package/src/components/center/index.ts +2 -0
  16. package/src/components/cluster/.DS_Store +0 -0
  17. package/src/components/cluster/cluster.css.ts +60 -0
  18. package/src/components/cluster/cluster.stories.tsx +37 -0
  19. package/src/components/cluster/cluster.tsx +46 -0
  20. package/src/components/cluster/index.ts +2 -0
  21. package/src/components/cover/.DS_Store +0 -0
  22. package/src/components/cover/cover.css.ts +60 -0
  23. package/src/components/cover/cover.stories.tsx +45 -0
  24. package/src/components/cover/cover.tsx +55 -0
  25. package/src/components/cover/index.ts +2 -0
  26. package/src/components/frame/.DS_Store +0 -0
  27. package/src/components/frame/frame.css.ts +61 -0
  28. package/src/components/frame/frame.stories.tsx +39 -0
  29. package/src/components/frame/frame.tsx +28 -0
  30. package/src/components/frame/index.ts +2 -0
  31. package/src/components/grid/.DS_Store +0 -0
  32. package/src/components/grid/grid.css.ts +26 -0
  33. package/src/components/grid/grid.stories.tsx +50 -0
  34. package/src/components/grid/grid.tsx +48 -0
  35. package/src/components/grid/index.ts +2 -0
  36. package/src/components/layout.mdx +206 -0
  37. package/src/components/sidebar/.DS_Store +0 -0
  38. package/src/components/sidebar/index.ts +2 -0
  39. package/src/components/sidebar/sidebar.css.ts +68 -0
  40. package/src/components/sidebar/sidebar.stories.tsx +60 -0
  41. package/src/components/sidebar/sidebar.tsx +77 -0
  42. package/src/components/stack/.DS_Store +0 -0
  43. package/src/components/stack/index.ts +2 -0
  44. package/src/components/stack/stack.css.ts +36 -0
  45. package/src/components/stack/stack.stories.tsx +72 -0
  46. package/src/components/stack/stack.tsx +44 -0
  47. package/src/components/switcher/.DS_Store +0 -0
  48. package/src/components/switcher/index.ts +2 -0
  49. package/src/components/switcher/switcher.css.ts +93 -0
  50. package/src/components/switcher/switcher.stories.tsx +66 -0
  51. package/src/components/switcher/switcher.tsx +53 -0
  52. package/src/styles/index.ts +2 -0
  53. package/src/styles/seed/.DS_Store +0 -0
  54. package/src/styles/seed/index.ts +1 -0
  55. package/src/styles/seed/seed.stories.tsx +52 -0
  56. package/src/styles/seed/seed.tsx +53 -0
  57. package/src/styles/styles.mdx +98 -0
  58. package/src/styles/system-contract.css.ts +144 -0
  59. package/src/types/index.ts +5 -0
  60. package/src/types/utils.types.ts +15 -0
  61. package/src/utils/__tests__/extract-sprinkles-props.test.ts +101 -0
  62. package/src/utils/__tests__/is-object.test.ts +24 -0
  63. package/src/utils/__tests__/map-contract-vars.test.ts +34 -0
  64. package/src/utils/arg-types/.DS_Store +0 -0
  65. package/src/utils/arg-types/arg-types-from-recipe.ts +37 -0
  66. package/src/utils/arg-types/arg-types-from-sprinkles.ts +43 -0
  67. package/src/utils/arg-types/common/composable.ts +13 -0
  68. package/src/utils/arg-types/common/index.ts +4 -0
  69. package/src/utils/arg-types/common/polymorphic.ts +14 -0
  70. package/src/utils/arg-types/common/referable.ts +10 -0
  71. package/src/utils/arg-types/common/stylable.ts +14 -0
  72. package/src/utils/arg-types/common-args.ts +26 -0
  73. package/src/utils/arg-types/index.ts +3 -0
  74. package/src/utils/extract-sprinkles-props.ts +46 -0
  75. package/src/utils/index.ts +3 -0
  76. package/src/utils/is-object.ts +3 -0
  77. package/src/utils/map-contract-vars.ts +10 -0
@@ -0,0 +1,98 @@
1
+ import { Meta } from '@storybook/addon-docs';
2
+
3
+ <Meta title="Styles/Styles Documentation" />
4
+
5
+ # Styles Documentation
6
+
7
+ This document provides an overview of two important files in our styling system: `contract.css.ts` and `seed.tsx`.
8
+
9
+ ## contract.css.ts
10
+
11
+ The `contract.css.ts` file defines the type contract for our design system's typography. It establishes a consistent structure for different text styles across various sizes.
12
+
13
+ ### Structure
14
+
15
+ The type contract is organized into the following categories:
16
+
17
+ - `display`
18
+ - `headline`
19
+ - `title`
20
+ - `label`
21
+ - `body`
22
+
23
+ Each category has three size variants:
24
+
25
+ - `large`
26
+ - `medium`
27
+ - `small`
28
+
29
+ ### Usage
30
+
31
+ This contract ensures that all typography in the application follows a consistent structure. It can be used to create theme variations and maintain a coherent typographic scale across the entire design system.
32
+
33
+ Example of the structure:
34
+
35
+ ```typescript
36
+ type: {
37
+ display: {
38
+ large: typeContract,
39
+ medium: typeContract,
40
+ small: typeContract,
41
+ },
42
+ // ... other categories
43
+ }
44
+ ```
45
+
46
+ ## seed.tsx
47
+
48
+ The `seed.tsx` file provides a foundation for creating flexible, polymorphic components with built-in support for design system styles.
49
+
50
+ ### Key Features
51
+
52
+ 1. **Polymorphic Components**: Allows components to change their root HTML element.
53
+ 2. **Sprinkles Integration**: Incorporates the Sprinkles CSS-in-JS solution for applying atomic styles.
54
+ 3. **Type Safety**: Ensures type safety for props and element types.
55
+
56
+ ### Main Functions
57
+
58
+ #### `plantSeed`
59
+
60
+ This function creates a base component (Seed) that can be used to build other components in the design system.
61
+
62
+ Parameters:
63
+
64
+ - `sprinkles`: A Sprinkles function for applying atomic styles.
65
+ - `defaultClassName`: An optional default class name for the component.
66
+
67
+ Usage:
68
+
69
+ ```jsx
70
+ import { plantSeed } from './seed';
71
+ import { sprinkles } from './your-sprinkles-file';
72
+
73
+ const Sprout = plantSeed({ sprinkles });
74
+
75
+ // Use Sprout as a base for other components
76
+ const Box = (props) => <Sprout {...props} />;
77
+ ```
78
+
79
+ ### Types
80
+
81
+ #### `SeedProps`
82
+
83
+ This type combines polymorphic component props with Sprinkles props:
84
+
85
+ ```typescript
86
+ type SeedProps<
87
+ TUse extends ElementType,
88
+ TSprinklesFn extends SprinklesFnBase,
89
+ > = PolymorphicComponentProps<TUse> & GetSprinkles<TSprinklesFn>;
90
+ ```
91
+
92
+ ### Benefits
93
+
94
+ - **Consistency**: Ensures all components built with `plantSeed` have consistent prop interfaces.
95
+ - **Flexibility**: Allows easy creation of new components with full access to design system styles.
96
+ - **Performance**: Leverages Sprinkles for efficient CSS generation and application.
97
+
98
+ By using `contract.css.ts` and `seed.tsx` together, you can create a robust, type-safe, and flexible foundation for your design system components.
@@ -0,0 +1,144 @@
1
+ import { createThemeContract } from '@vanilla-extract/css';
2
+
3
+ const typeContract = {
4
+ font: null,
5
+ weight: null,
6
+ lineHeight: null,
7
+ tracking: null,
8
+ size: null,
9
+ };
10
+
11
+ export const sys = createThemeContract({
12
+ layout: {
13
+ direction: null,
14
+ measure: null,
15
+ },
16
+
17
+ color: {
18
+ background: null,
19
+ foreground: null,
20
+ muted: null,
21
+ outline: null,
22
+ },
23
+
24
+ state: {
25
+ hovered: {
26
+ opacity: null,
27
+ },
28
+ focused: {
29
+ opacity: null,
30
+ },
31
+ pressed: {
32
+ opacity: null,
33
+ },
34
+ },
35
+
36
+ shape: {
37
+ corner: {
38
+ none: null,
39
+ sharp: null,
40
+ small: null,
41
+ medium: null,
42
+ rounded: null,
43
+ circle: null,
44
+ },
45
+ },
46
+
47
+ elevation: {
48
+ none: null,
49
+ minimal: null,
50
+ low: null,
51
+ moderate: null,
52
+ high: null,
53
+ peak: null,
54
+ },
55
+
56
+ motion: {
57
+ duration: {
58
+ short: {
59
+ 1: null,
60
+ 2: null,
61
+ 3: null,
62
+ 4: null,
63
+ },
64
+ medium: {
65
+ 1: null,
66
+ 2: null,
67
+ 3: null,
68
+ 4: null,
69
+ },
70
+ long: {
71
+ 1: null,
72
+ 2: null,
73
+ 3: null,
74
+ 4: null,
75
+ },
76
+ },
77
+
78
+ easing: {
79
+ standard: null,
80
+ decelerate: {
81
+ standard: null,
82
+ emphasized: null,
83
+ },
84
+ accelerate: {
85
+ standard: null,
86
+ emphasized: null,
87
+ },
88
+ },
89
+ },
90
+
91
+ typography: {
92
+ display: {
93
+ large: typeContract,
94
+ medium: typeContract,
95
+ small: typeContract,
96
+ },
97
+
98
+ headline: {
99
+ large: typeContract,
100
+ medium: typeContract,
101
+ small: typeContract,
102
+ },
103
+
104
+ title: {
105
+ large: typeContract,
106
+ medium: typeContract,
107
+ small: typeContract,
108
+ },
109
+
110
+ label: {
111
+ large: typeContract,
112
+ medium: typeContract,
113
+ small: typeContract,
114
+ },
115
+
116
+ body: {
117
+ large: typeContract,
118
+ medium: typeContract,
119
+ small: typeContract,
120
+ },
121
+ },
122
+
123
+ spacing: {
124
+ 0: null,
125
+ 1: null,
126
+ 2: null,
127
+ 3: null,
128
+ 4: null,
129
+ 5: null,
130
+ 6: null,
131
+ 7: null,
132
+ 8: null,
133
+ 9: null,
134
+ 10: null,
135
+ 11: null,
136
+ 12: null,
137
+ 13: null,
138
+ 14: null,
139
+ 15: null,
140
+ 16: null,
141
+ 17: null,
142
+ 18: null,
143
+ },
144
+ });
@@ -0,0 +1,5 @@
1
+ export {
2
+ type PolymorphicComponentProps,
3
+ type DistributiveOmit,
4
+ type UnwrapArray,
5
+ } from './utils.types';
@@ -0,0 +1,15 @@
1
+ import type { ComponentPropsWithRef, ElementType } from 'react';
2
+
3
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
4
+ export type DistributiveOmit<T, TOmitted extends PropertyKey> = T extends any
5
+ ? Omit<T, TOmitted>
6
+ : never;
7
+
8
+ export type UnwrapArray<R> = R extends unknown[] ? UnwrapArray<R[number]> : R;
9
+
10
+ export type PolymorphicComponentProps<TUse extends ElementType> = {
11
+ use?: TUse;
12
+ } & DistributiveOmit<
13
+ ComponentPropsWithRef<ElementType extends TUse ? 'div' : TUse>,
14
+ 'use'
15
+ >;
@@ -0,0 +1,101 @@
1
+ import { describe, test } from '@std/testing/bdd';
2
+ import { spy } from '@std/testing/mock';
3
+ import { expect } from '@std/expect';
4
+
5
+ import {
6
+ extractSprinklesProps,
7
+ type SprinklesFnBase,
8
+ } from '@/utils/extract-sprinkles-props';
9
+
10
+ describe('extractSprinklesProps', () => {
11
+ const mockSprinkles: SprinklesFnBase = {
12
+ properties: new Set(['color', 'fontSize', 'padding']),
13
+ } as SprinklesFnBase;
14
+
15
+ test('should correctly separate sprinkles props from component props', () => {
16
+ const props = {
17
+ color: 'red',
18
+ fontSize: '16px',
19
+ padding: '10px',
20
+ onClick: spy(),
21
+ className: 'custom-class',
22
+ };
23
+
24
+ const [sprinkleProps, componentProps] = extractSprinklesProps(
25
+ props,
26
+ mockSprinkles,
27
+ );
28
+
29
+ expect(sprinkleProps).toEqual({
30
+ color: 'red',
31
+ fontSize: '16px',
32
+ padding: '10px',
33
+ });
34
+
35
+ expect(componentProps).toEqual({
36
+ onClick: expect.any(Function),
37
+ className: 'custom-class',
38
+ });
39
+ });
40
+
41
+ test('should handle props with no sprinkles properties', () => {
42
+ const props = {
43
+ onClick: spy(),
44
+ className: 'custom-class',
45
+ };
46
+
47
+ const [sprinkleProps, componentProps] = extractSprinklesProps(
48
+ props,
49
+ mockSprinkles,
50
+ );
51
+
52
+ expect(sprinkleProps).toEqual({});
53
+ expect(componentProps).toEqual(props);
54
+ });
55
+
56
+ test('should handle props with only sprinkles properties', () => {
57
+ const props = {
58
+ color: 'blue',
59
+ fontSize: '14px',
60
+ };
61
+
62
+ const [sprinkleProps, componentProps] = extractSprinklesProps(
63
+ props,
64
+ mockSprinkles,
65
+ );
66
+
67
+ expect(sprinkleProps).toEqual(props);
68
+ expect(componentProps).toEqual({});
69
+ });
70
+
71
+ test('should handle empty props object', () => {
72
+ const props = {};
73
+
74
+ const [sprinkleProps, componentProps] = extractSprinklesProps(
75
+ props,
76
+ mockSprinkles,
77
+ );
78
+
79
+ expect(sprinkleProps).toEqual({});
80
+ expect(componentProps).toEqual({});
81
+ });
82
+
83
+ test('should handle sprinkles function with empty properties set', () => {
84
+ const emptySprinkles: SprinklesFnBase = {
85
+ properties: new Set(),
86
+ } as SprinklesFnBase;
87
+
88
+ const props = {
89
+ color: 'green',
90
+ onClick: spy(),
91
+ };
92
+
93
+ const [sprinkleProps, componentProps] = extractSprinklesProps(
94
+ props,
95
+ emptySprinkles,
96
+ );
97
+
98
+ expect(sprinkleProps).toEqual({});
99
+ expect(componentProps).toEqual(props);
100
+ });
101
+ });
@@ -0,0 +1,24 @@
1
+ import { isObject } from "@/utils/is-object.ts";
2
+ import { describe, it } from "@std/testing/bdd";
3
+ import { expect } from "@std/expect";
4
+
5
+ describe("isObject", () => {
6
+ it("should return true if value is an object", () => {
7
+ expect(isObject({})).toEqual(true);
8
+ });
9
+
10
+ it("should return false if value is an array", () => {
11
+ expect(isObject([])).toEqual(false);
12
+ });
13
+
14
+ it("should return false if value is null or undefined", () => {
15
+ expect(isObject(null)).toEqual(false);
16
+ expect(isObject(undefined)).toEqual(false);
17
+ });
18
+
19
+ it("should return false if value is any scalar", () => {
20
+ expect(isObject(1)).toEqual(false);
21
+ expect(isObject("foo")).toEqual(false);
22
+ expect(isObject(true)).toEqual(false);
23
+ });
24
+ });
@@ -0,0 +1,34 @@
1
+ import { mapContractVars } from "@/utils/map-contract-vars.ts";
2
+ import { describe, test } from "@std/testing/bdd";
3
+ import { expect } from "@std/expect";
4
+
5
+ describe("mapContractVars", () => {
6
+ test("should map contract vars", () => {
7
+ const contract = {
8
+ foo: "foo",
9
+ bar: "bar",
10
+ };
11
+
12
+ const result = mapContractVars(contract, (key) => ({
13
+ padding: `var(--${key})`,
14
+ vars: {
15
+ [`--${key}`]: contract[key],
16
+ },
17
+ }));
18
+
19
+ expect(result).toEqual({
20
+ foo: {
21
+ padding: "var(--foo)",
22
+ vars: {
23
+ "--foo": "foo",
24
+ },
25
+ },
26
+ bar: {
27
+ padding: "var(--bar)",
28
+ vars: {
29
+ "--bar": "bar",
30
+ },
31
+ },
32
+ });
33
+ });
34
+ });
Binary file
@@ -0,0 +1,37 @@
1
+ import { type ComplexStyleRule } from '@vanilla-extract/css';
2
+ import { type RuntimeFn } from '@vanilla-extract/recipes';
3
+
4
+ type RecipeStyleRule = ComplexStyleRule | string;
5
+ type VariantDefinitions = Record<string, RecipeStyleRule>;
6
+ type VariantGroups = Record<string, VariantDefinitions>;
7
+
8
+ export function argTypesFromRecipe(
9
+ recipe: RuntimeFn<VariantGroups>,
10
+ excludes: string[] = [],
11
+ ) {
12
+ return Object.entries(recipe.classNames.variants).reduce(
13
+ (acc, [name, variant]) => {
14
+ if (excludes.includes(name)) {
15
+ return acc;
16
+ }
17
+
18
+ const options = Object.keys(variant);
19
+ let control = options.length > 5 ? 'select' : 'radio';
20
+
21
+ if (options.length === 1 && options[0] === 'true') {
22
+ options.push('false');
23
+ control = 'boolean';
24
+ }
25
+
26
+ return {
27
+ ...acc,
28
+ [name]: {
29
+ control,
30
+ options,
31
+ table: { category: 'Styling props' },
32
+ },
33
+ };
34
+ },
35
+ {},
36
+ );
37
+ }
@@ -0,0 +1,43 @@
1
+ import { isObject } from '@kalink/ui/utils';
2
+
3
+ type ArgTypesFromSprinklesProps = {
4
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
5
+ props: Record<string, any>;
6
+ excludes?: string[];
7
+ category?: string;
8
+ } & {};
9
+
10
+ export function argTypesFromSprinkles({
11
+ props,
12
+ excludes = [],
13
+ category = 'Sprinkles props',
14
+ }: ArgTypesFromSprinklesProps) {
15
+ return Object.entries(props).reduce((acc, [name]) => {
16
+ if (Array.isArray(excludes) && excludes.includes(name)) {
17
+ return acc;
18
+ }
19
+
20
+ let options = props[name] || [];
21
+ let control = 'select';
22
+
23
+ if (options.length === 1 && options[0] === 'true') {
24
+ options.push('false');
25
+ control = 'boolean';
26
+ }
27
+
28
+ if (isObject(options)) {
29
+ options = Object.fromEntries(
30
+ Object.keys(options).map((key) => [key, key]),
31
+ );
32
+ }
33
+
34
+ return {
35
+ ...acc,
36
+ [name]: {
37
+ control,
38
+ options,
39
+ table: { category },
40
+ },
41
+ };
42
+ }, {});
43
+ }
@@ -0,0 +1,13 @@
1
+ export const composable = {
2
+ children: {
3
+ control: false,
4
+ description: 'Content of the component.',
5
+ defaultValue: '',
6
+ table: {
7
+ category: 'Intrinsic props',
8
+ type: {
9
+ summary: 'ReactNode',
10
+ },
11
+ },
12
+ },
13
+ };
@@ -0,0 +1,4 @@
1
+ export { composable } from './composable';
2
+ export { polymorphic } from './polymorphic';
3
+ export { referable } from './referable';
4
+ export { stylable } from './stylable';
@@ -0,0 +1,14 @@
1
+ export const polymorphic = {
2
+ use: {
3
+ control: false,
4
+ description:
5
+ 'The component used to render the root node of the component. Either a string to use an `JSX.IntrinsicElements` or a component reference to use a `React.ComponentType`',
6
+ defaultValue: '',
7
+ table: {
8
+ category: 'Intrinsic props',
9
+ type: {
10
+ summary: 'ElementType',
11
+ },
12
+ },
13
+ },
14
+ };
@@ -0,0 +1,10 @@
1
+ export const referable = {
2
+ ref: {
3
+ control: false,
4
+ description: 'Ref passed to the component root.',
5
+ defaultValue: '',
6
+ table: {
7
+ category: 'Intrinsic props',
8
+ },
9
+ },
10
+ };
@@ -0,0 +1,14 @@
1
+ export const stylable = {
2
+ className: {
3
+ control: false,
4
+ description:
5
+ 'A class name string passed to the component. Merged with the inner class names.',
6
+ defaultValue: '',
7
+ table: {
8
+ category: 'Intrinsic props',
9
+ type: {
10
+ summary: 'string',
11
+ },
12
+ },
13
+ },
14
+ };
@@ -0,0 +1,26 @@
1
+ /* eslint-disable import/namespace */
2
+ import * as CommonArgDefs from './common';
3
+
4
+ export enum CommonArgs {
5
+ COMPOSABLE = 'composable',
6
+ POLYMORPHIC = 'polymorphic',
7
+ STYLABLE = 'stylable',
8
+ REFERABLE = 'referable',
9
+ }
10
+
11
+ export function commonArgs(args: CommonArgs[]) {
12
+ const argTypes: Partial<Record<string, object>> = {};
13
+ const knownArgs = Object.values(CommonArgs);
14
+
15
+ for (const arg of args) {
16
+ if (!knownArgs.includes(arg)) {
17
+ continue;
18
+ }
19
+
20
+ for (const argDef in CommonArgDefs[arg]) {
21
+ argTypes[argDef] = (CommonArgDefs[arg] as Record<string, object>)[argDef];
22
+ }
23
+ }
24
+
25
+ return argTypes;
26
+ }
@@ -0,0 +1,3 @@
1
+ export { argTypesFromRecipe } from './arg-types-from-recipe';
2
+ export { argTypesFromSprinkles } from './arg-types-from-sprinkles';
3
+ export { commonArgs, CommonArgs } from './common-args';
@@ -0,0 +1,46 @@
1
+ import type { SprinklesProperties } from '@vanilla-extract/sprinkles';
2
+ import type { UnknownRecord } from 'type-fest';
3
+
4
+ export interface SprinklesFnBase {
5
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
6
+ (...args: any): string;
7
+ properties: Set<string>;
8
+ }
9
+
10
+ export type GetSprinkles<T extends SprinklesFnBase> = Parameters<T>[0];
11
+
12
+ export type SprinklesProps<TSprinklesFnBase extends SprinklesFnBase> =
13
+ TSprinklesFnBase['properties'] extends Set<infer T>
14
+ ? {
15
+ [KeyType in keyof T]: T[KeyType] extends SprinklesProperties
16
+ ? KeyType
17
+ : never;
18
+ }
19
+ : never;
20
+
21
+ /**
22
+ * Extracts the sprinkles properties from the given component props,
23
+ * returning an array containing the extracted sprinkle props and
24
+ * the remaining component props.
25
+ */
26
+ export const extractSprinklesProps = <
27
+ ComponentProps extends UnknownRecord,
28
+ SprinklesFn extends SprinklesFnBase,
29
+ >(
30
+ props: ComponentProps,
31
+ sprinkles: SprinklesFn,
32
+ ) => {
33
+ const sprinkleProps: Record<string, unknown> = {};
34
+ const componentProps: Record<string, unknown> = {};
35
+
36
+ for (const prop of Object.keys(props)) {
37
+ if (sprinkles.properties.has(prop)) {
38
+ sprinkleProps[prop] = props[prop];
39
+ continue;
40
+ }
41
+
42
+ componentProps[prop] = props[prop];
43
+ }
44
+
45
+ return [sprinkleProps, componentProps];
46
+ };
@@ -0,0 +1,3 @@
1
+ export { extractSprinklesProps } from './extract-sprinkles-props';
2
+ export { isObject } from './is-object';
3
+ export { mapContractVars } from './map-contract-vars';
@@ -0,0 +1,3 @@
1
+ export const isObject = <T extends object>(value: unknown): value is T => {
2
+ return !!value && typeof value === "object" && !Array.isArray(value);
3
+ };
@@ -0,0 +1,10 @@
1
+ type MappedVars = Record<string, unknown>;
2
+
3
+ export const mapContractVars = <TContract extends Record<string, unknown>>(
4
+ contractVars: TContract,
5
+ mapFn: (key: keyof TContract) => MappedVars,
6
+ ) => {
7
+ return Object.fromEntries(
8
+ Object.keys(contractVars).map((key) => [key, mapFn(key)]),
9
+ ) as Record<keyof TContract, MappedVars>;
10
+ };