@geniee-inc/sfa-kit 1.6.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 (66) hide show
  1. package/GUIDE.md +585 -0
  2. package/LICENSE.md +21 -0
  3. package/README.md +31 -0
  4. package/package.json +36 -0
  5. package/src/index.d.ts +29 -0
  6. package/src/index.js +21 -0
  7. package/src/lib/auth/DevToolbar.d.ts +38 -0
  8. package/src/lib/auth/DevToolbar.js +271 -0
  9. package/src/lib/auth/SfaLoginGate.d.ts +53 -0
  10. package/src/lib/auth/SfaLoginGate.js +462 -0
  11. package/src/lib/auth/StandalonePreviewContext.d.ts +27 -0
  12. package/src/lib/auth/StandalonePreviewContext.js +14 -0
  13. package/src/lib/auth/embed-protocol.d.ts +40 -0
  14. package/src/lib/auth/embed-protocol.js +56 -0
  15. package/src/lib/auth/exchange-code.d.ts +14 -0
  16. package/src/lib/auth/exchange-code.js +45 -0
  17. package/src/lib/auth/keystone-auth.d.ts +16 -0
  18. package/src/lib/auth/keystone-auth.js +84 -0
  19. package/src/lib/auth/session-store.d.ts +19 -0
  20. package/src/lib/auth/session-store.js +73 -0
  21. package/src/lib/auth/types.d.ts +33 -0
  22. package/src/lib/auth/types.js +1 -0
  23. package/src/lib/auth/useEmbedContext.d.ts +22 -0
  24. package/src/lib/auth/useEmbedContext.js +31 -0
  25. package/src/lib/components/EmptyState.d.ts +18 -0
  26. package/src/lib/components/EmptyState.js +36 -0
  27. package/src/lib/components/ErrorBoundary.d.ts +31 -0
  28. package/src/lib/components/ErrorBoundary.js +100 -0
  29. package/src/lib/components/FieldRenderer.d.ts +11 -0
  30. package/src/lib/components/FieldRenderer.js +57 -0
  31. package/src/lib/components/RecordList.d.ts +20 -0
  32. package/src/lib/components/RecordList.js +139 -0
  33. package/src/lib/components/RecordView.d.ts +14 -0
  34. package/src/lib/components/RecordView.js +153 -0
  35. package/src/lib/errors.d.ts +15 -0
  36. package/src/lib/errors.js +15 -0
  37. package/src/lib/hooks/useCreateRecord.d.ts +17 -0
  38. package/src/lib/hooks/useCreateRecord.js +48 -0
  39. package/src/lib/hooks/useDeleteRecord.d.ts +16 -0
  40. package/src/lib/hooks/useDeleteRecord.js +48 -0
  41. package/src/lib/hooks/useDescribe.d.ts +16 -0
  42. package/src/lib/hooks/useDescribe.js +40 -0
  43. package/src/lib/hooks/useFieldTypes.d.ts +15 -0
  44. package/src/lib/hooks/useFieldTypes.js +39 -0
  45. package/src/lib/hooks/useObjectCatalog.d.ts +15 -0
  46. package/src/lib/hooks/useObjectCatalog.js +39 -0
  47. package/src/lib/hooks/useRecord.d.ts +15 -0
  48. package/src/lib/hooks/useRecord.js +49 -0
  49. package/src/lib/hooks/useRecordList.d.ts +19 -0
  50. package/src/lib/hooks/useRecordList.js +82 -0
  51. package/src/lib/hooks/useRelatedRecords.d.ts +65 -0
  52. package/src/lib/hooks/useRelatedRecords.js +227 -0
  53. package/src/lib/hooks/useUpdateRecord.d.ts +23 -0
  54. package/src/lib/hooks/useUpdateRecord.js +55 -0
  55. package/src/lib/provider/SfaClient.d.ts +98 -0
  56. package/src/lib/provider/SfaClient.js +688 -0
  57. package/src/lib/provider/SfaProvider.d.ts +38 -0
  58. package/src/lib/provider/SfaProvider.js +44 -0
  59. package/src/lib/provider/types.d.ts +184 -0
  60. package/src/lib/provider/types.js +1 -0
  61. package/src/lib/provider/useSfaClient.d.ts +11 -0
  62. package/src/lib/provider/useSfaClient.js +24 -0
  63. package/src/lib/theme.d.ts +55 -0
  64. package/src/lib/theme.js +68 -0
  65. package/src/lib/version.d.ts +1 -0
  66. package/src/lib/version.js +1 -0
@@ -0,0 +1,38 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { SfaApiMode, SfaAuth, SfaClientInterface } from './types';
3
+ export interface SfaContextValue {
4
+ readonly client: SfaClientInterface;
5
+ readonly auth: SfaAuth | undefined;
6
+ readonly mode: SfaApiMode;
7
+ readonly organizationId: string | undefined;
8
+ /** When true, mutation hooks (create/update/delete) throw instead of executing. */
9
+ readonly readOnly: boolean;
10
+ }
11
+ export declare const SfaContext: import("react").Context<SfaContextValue | null>;
12
+ interface SfaProviderProps {
13
+ readonly apiBase: string;
14
+ readonly auth?: SfaAuth;
15
+ readonly mode?: SfaApiMode;
16
+ readonly organizationId?: string;
17
+ readonly onAuthError?: () => void;
18
+ /**
19
+ * Disable mutation hooks (create/update/delete). Defaults to false.
20
+ *
21
+ * Set to true in JAI Studio standalone preview mode. In preview, the
22
+ * DevToolbar shows "Preview Mode" and the user authenticates with real
23
+ * credentials, but the session is for testing page layout, not for
24
+ * modifying production data. Without this guard, a generated page with
25
+ * write hooks would silently create/update/delete real records during
26
+ * preview, which users would not expect.
27
+ *
28
+ * When the same page is embedded in SFA/CRM (production), readOnly
29
+ * stays false and writes work normally.
30
+ */
31
+ readonly readOnly?: boolean;
32
+ readonly children: ReactNode;
33
+ }
34
+ /**
35
+ * @description Wraps the page and provides an SfaClient to all child components via context.
36
+ */
37
+ export declare function SfaProvider({ apiBase, auth, mode, organizationId, onAuthError, readOnly, children, }: SfaProviderProps): JSX.Element;
38
+ export {};
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useMemo, useRef } from 'react';
3
+ import { SfaClient } from './SfaClient';
4
+ function detectMode(apiBase) {
5
+ // An absolute HTTP(S) URL points at an API endpoint (including a local
6
+ // keystone at localhost/127.0.0.1) -> direct. A relative path relays
7
+ // through the hosting app -> proxy.
8
+ if (/^https?:\/\//i.test(apiBase))
9
+ return 'direct';
10
+ return 'proxy';
11
+ }
12
+ export const SfaContext = createContext(null);
13
+ /**
14
+ * @description Wraps the page and provides an SfaClient to all child components via context.
15
+ */
16
+ export function SfaProvider({ apiBase, auth, mode, organizationId, onAuthError, readOnly = false, children, }) {
17
+ const resolvedMode = mode !== null && mode !== void 0 ? mode : detectMode(apiBase);
18
+ const resolvedOrgId = organizationId;
19
+ // Depend on the token string (primitive, compared by value) instead of the
20
+ // auth object reference, so inline `auth={{ accessToken }}` doesn't cause
21
+ // SfaClient re-creation on every parent render.
22
+ const accessToken = auth === null || auth === void 0 ? void 0 : auth.accessToken;
23
+ // Use a ref for onAuthError so updates don't trigger client re-creation.
24
+ const onAuthErrorRef = useRef(onAuthError);
25
+ onAuthErrorRef.current = onAuthError;
26
+ const value = useMemo(() => {
27
+ const stableAuth = accessToken ? { accessToken } : undefined;
28
+ const client = new SfaClient({
29
+ apiBase,
30
+ auth: stableAuth,
31
+ mode: resolvedMode,
32
+ organizationId: resolvedOrgId,
33
+ onAuthError: () => { var _a; return (_a = onAuthErrorRef.current) === null || _a === void 0 ? void 0 : _a.call(onAuthErrorRef); },
34
+ });
35
+ return {
36
+ client,
37
+ auth: stableAuth,
38
+ mode: resolvedMode,
39
+ organizationId: resolvedOrgId,
40
+ readOnly,
41
+ };
42
+ }, [apiBase, accessToken, resolvedMode, resolvedOrgId, readOnly]);
43
+ return _jsx(SfaContext.Provider, { value: value, children: children });
44
+ }
@@ -0,0 +1,184 @@
1
+ export interface SfaAuth {
2
+ readonly accessToken: string;
3
+ }
4
+ export type SfaApiMode = 'direct' | 'proxy';
5
+ export interface SfaClientConfig {
6
+ readonly apiBase: string;
7
+ readonly auth?: SfaAuth;
8
+ readonly mode: SfaApiMode;
9
+ readonly organizationId?: string;
10
+ readonly onAuthError?: () => void;
11
+ }
12
+ /**
13
+ * @description Normalized field kinds aligned with keystone's 10-type model.
14
+ * Components render based on these kinds, not the raw Chikyu type strings.
15
+ */
16
+ export type SfaFieldKind = 'text' | 'number' | 'date' | 'datetime' | 'single_choice' | 'multi_choice' | 'reference' | 'user_reference' | 'computed' | 'record_type';
17
+ /**
18
+ * @description A normalized field value. Components use `kind` to decide
19
+ * rendering and `label` for display. The `value` is the raw stored value.
20
+ * This shape works for both Chikyu (caption -> label) and keystone
21
+ * (coded.label -> label, scalar has label=null).
22
+ */
23
+ export interface SfaFieldValue {
24
+ readonly kind: SfaFieldKind;
25
+ readonly value: unknown;
26
+ readonly label: string | null;
27
+ }
28
+ export type SfaFieldValueMapping = Readonly<Record<string, SfaFieldValue>>;
29
+ export interface SfaRecord {
30
+ readonly record_id: string;
31
+ readonly collection_name: string;
32
+ readonly fields: SfaFieldValueMapping;
33
+ readonly titleFields: readonly string[];
34
+ /** Pre-built display title from keystone. Preferred over titleFields when present. */
35
+ readonly title?: string | null;
36
+ /** Opaque version token for optimistic locking (keystone ETag value). */
37
+ readonly version?: string | null;
38
+ readonly permissions: {
39
+ readonly canEdit: boolean;
40
+ readonly canDelete: boolean;
41
+ };
42
+ }
43
+ export interface SfaListResponse {
44
+ readonly items: readonly SfaRecord[];
45
+ readonly totalCount: number;
46
+ readonly hasMore: boolean;
47
+ readonly pageIndex: number;
48
+ /** Cursor for fetching the next page (keystone cursor-based pagination). */
49
+ readonly nextCursor?: string | null;
50
+ /** Cursor for fetching the previous page (keystone cursor-based pagination). */
51
+ readonly prevCursor?: string | null;
52
+ }
53
+ export interface SfaClientInterface {
54
+ get(collection: string, recordId: string): Promise<SfaRecord>;
55
+ list(collection: string, params?: SfaListParams): Promise<SfaListResponse>;
56
+ describe(objectKey: string): Promise<SfaDescribeResult>;
57
+ listObjects(): Promise<SfaObjectCatalog>;
58
+ listFieldTypes(): Promise<SfaFieldTypeCatalog>;
59
+ create(collection: string, fields: Record<string, unknown>, options?: SfaCreateOptions): Promise<SfaRecord>;
60
+ update(collection: string, recordId: string, fields: Record<string, unknown>, version: string): Promise<SfaRecord>;
61
+ delete(collection: string, recordId: string, version: string): Promise<void>;
62
+ }
63
+ /**
64
+ * @description Options for creating a record. The idempotency key prevents
65
+ * duplicate creates if the same request is retried.
66
+ */
67
+ export interface SfaCreateOptions {
68
+ readonly idempotencyKey?: string;
69
+ }
70
+ /**
71
+ * @description A single per-field validation error from a 422 response.
72
+ */
73
+ export interface SfaFieldError {
74
+ readonly field: string;
75
+ readonly code: string;
76
+ readonly message: string;
77
+ }
78
+ export interface SfaListParams {
79
+ readonly limit?: number;
80
+ readonly offset?: number;
81
+ readonly sortBy?: string;
82
+ readonly sortOrder?: 'asc' | 'desc';
83
+ readonly filter?: Record<string, unknown>;
84
+ /** Opaque cursor for keystone cursor-based pagination. Takes precedence over offset. */
85
+ readonly cursor?: string;
86
+ }
87
+ export type SfaObjectOrigin = 'standard' | 'custom';
88
+ export type SfaRelationshipKind = 'association' | 'master_detail';
89
+ export type SfaCardinality = 'one' | 'many';
90
+ export interface SfaFieldOption {
91
+ readonly value: string;
92
+ readonly label: string;
93
+ readonly order?: number;
94
+ readonly hidden?: boolean;
95
+ }
96
+ /**
97
+ * @description One field in an object's schema. Provides everything needed
98
+ * to render, validate, and filter by this field.
99
+ */
100
+ export interface SfaFieldDescriptor {
101
+ readonly key: string;
102
+ readonly label: string;
103
+ readonly kind: SfaFieldKind;
104
+ readonly description: string | null;
105
+ readonly required: boolean;
106
+ readonly readOnly: boolean;
107
+ readonly order: number;
108
+ readonly section: string | null;
109
+ readonly filterable: boolean;
110
+ readonly sortable: boolean;
111
+ readonly options?: readonly SfaFieldOption[];
112
+ readonly targetObject?: string;
113
+ readonly cardinality?: SfaCardinality;
114
+ readonly displayField?: string;
115
+ }
116
+ /**
117
+ * @description A directed relationship from one object to another.
118
+ */
119
+ export interface SfaRelationDescriptor {
120
+ readonly name: string;
121
+ readonly target: string;
122
+ readonly cardinality: SfaCardinality;
123
+ readonly kind: SfaRelationshipKind;
124
+ readonly viaField: string;
125
+ }
126
+ export interface SfaObjectPermissions {
127
+ readonly readable: boolean;
128
+ readonly creatable: boolean;
129
+ readonly updatable: boolean;
130
+ readonly deletable: boolean;
131
+ }
132
+ /**
133
+ * @description Lightweight object summary from the catalog (GET /v1/objects).
134
+ */
135
+ export interface SfaObjectSummary {
136
+ readonly key: string;
137
+ readonly label: string;
138
+ readonly origin: SfaObjectOrigin;
139
+ readonly primaryDisplayField: string | null;
140
+ readonly relationships: readonly SfaRelationDescriptor[];
141
+ }
142
+ /**
143
+ * @description Full object description from describe (GET /v1/objects/{key}).
144
+ */
145
+ export interface SfaObjectDetail {
146
+ readonly key: string;
147
+ readonly label: string;
148
+ readonly origin: SfaObjectOrigin;
149
+ readonly primaryDisplayField: string | null;
150
+ readonly fields: readonly SfaFieldDescriptor[];
151
+ readonly relationships: readonly SfaRelationDescriptor[];
152
+ readonly permissions: SfaObjectPermissions;
153
+ }
154
+ export interface SfaDescribeResult {
155
+ readonly object: SfaObjectDetail;
156
+ }
157
+ export interface SfaObjectCatalog {
158
+ readonly objects: readonly SfaObjectSummary[];
159
+ }
160
+ export type SfaFilterOperator = 'eq' | 'ne' | 'lt' | 'lte' | 'gt' | 'gte' | 'between' | 'within_relative' | 'contains' | 'starts_with' | 'ends_with' | 'in' | 'not_in' | 'is_null' | 'is_not_null';
161
+ /**
162
+ * @description Self-describing definition of one field kind from the
163
+ * static catalog (GET /v1/field-types). Tells the consumer what a kind
164
+ * means, how its value reads, and what filter operators it supports.
165
+ */
166
+ export interface SfaFieldTypeDescriptor {
167
+ readonly kind: SfaFieldKind;
168
+ readonly summary: string;
169
+ readonly valueShape: string;
170
+ readonly multiValued: boolean;
171
+ readonly editableByDefault: boolean;
172
+ readonly hasOptions: boolean;
173
+ readonly referencesObject: boolean;
174
+ readonly operators: readonly SfaFilterOperator[];
175
+ }
176
+ export interface SfaFieldTypeCatalog {
177
+ readonly fieldTypes: readonly SfaFieldTypeDescriptor[];
178
+ }
179
+ export type FieldGroupLayout = '1-col' | '2-col' | '3-col';
180
+ export interface FieldGroupSpec {
181
+ readonly title?: string;
182
+ readonly layout?: FieldGroupLayout;
183
+ readonly fields: readonly string[];
184
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ import type { SfaContextValue } from './SfaProvider';
2
+ import type { SfaClientInterface } from './types';
3
+ /**
4
+ * @description Returns the SfaClient instance from the nearest SfaProvider.
5
+ */
6
+ export declare function useSfaClient(): SfaClientInterface;
7
+ /**
8
+ * @description Returns the full SfaProvider context including the readOnly flag.
9
+ * Used by mutation hooks to guard against writes in preview mode.
10
+ */
11
+ export declare function useSfaContext(): SfaContextValue;
@@ -0,0 +1,24 @@
1
+ import { useContext } from 'react';
2
+ import { ERR_NO_PROVIDER } from '../errors';
3
+ import { SfaContext } from './SfaProvider';
4
+ /**
5
+ * @description Returns the SfaClient instance from the nearest SfaProvider.
6
+ */
7
+ export function useSfaClient() {
8
+ const context = useContext(SfaContext);
9
+ if (context == null) {
10
+ throw new Error(ERR_NO_PROVIDER);
11
+ }
12
+ return context.client;
13
+ }
14
+ /**
15
+ * @description Returns the full SfaProvider context including the readOnly flag.
16
+ * Used by mutation hooks to guard against writes in preview mode.
17
+ */
18
+ export function useSfaContext() {
19
+ const context = useContext(SfaContext);
20
+ if (context == null) {
21
+ throw new Error(ERR_NO_PROVIDER);
22
+ }
23
+ return context;
24
+ }
@@ -0,0 +1,55 @@
1
+ import type { CSSProperties } from 'react';
2
+ /**
3
+ * @description All colors use CSS custom properties with GENIEE SFA defaults as fallbacks.
4
+ * Override any color by setting the CSS variable on a parent element:
5
+ * :root { --sfa-primary: #FF0000; }
6
+ * <div style={{ '--sfa-primary': '#FF0000' }}>...</div>
7
+ */
8
+ export declare const color: {
9
+ readonly primary: "var(--sfa-primary, #3867D1)";
10
+ readonly primaryHover: "var(--sfa-primary-hover, #4E7EF5)";
11
+ readonly primaryLight: "var(--sfa-primary-light, #F0F5FF)";
12
+ readonly primaryDark: "var(--sfa-primary-dark, #203EAB)";
13
+ readonly error: "var(--sfa-error, #ED5C5C)";
14
+ readonly errorHover: "var(--sfa-error-hover, #FF8282)";
15
+ readonly errorLight: "var(--sfa-error-light, #FEF0F0)";
16
+ readonly success: "var(--sfa-success, #A3C848)";
17
+ readonly warning: "var(--sfa-warning, #F2B45E)";
18
+ readonly white: "#FFFFFF";
19
+ readonly black: "#000000";
20
+ readonly textPrimary: "var(--sfa-text-primary, #313542)";
21
+ readonly textSecondary: "var(--sfa-text-secondary, #838A98)";
22
+ readonly textMuted: "var(--sfa-text-muted, #ACB0BA)";
23
+ readonly textPlaceholder: "var(--sfa-text-placeholder, #C1C1C1)";
24
+ readonly border: "var(--sfa-border, #D6D9DD)";
25
+ readonly borderLight: "var(--sfa-border-light, #F2F2F2)";
26
+ readonly divider: "var(--sfa-divider, #F2F2F2)";
27
+ readonly bgDefault: "var(--sfa-bg-default, #F7F8FA)";
28
+ readonly bgSurface: "var(--sfa-bg-surface, #FFFFFF)";
29
+ readonly bgHover: "var(--sfa-bg-hover, rgba(0, 0, 0, 0.03))";
30
+ readonly bgDisabled: "var(--sfa-bg-disabled, rgba(0, 0, 0, 0.1))";
31
+ };
32
+ export declare const font: {
33
+ readonly family: "var(--sfa-font-family, 'Noto Sans JP', 'Roboto', 'Helvetica', 'Arial', sans-serif)";
34
+ readonly sizeXs: 11;
35
+ readonly sizeSm: 12;
36
+ readonly sizeMd: 13;
37
+ readonly sizeLg: 14;
38
+ readonly sizeXl: 16;
39
+ readonly sizeTitle: 18;
40
+ readonly weightRegular: 400;
41
+ readonly weightMedium: 700;
42
+ };
43
+ export declare const space: {
44
+ readonly xs: 4;
45
+ readonly sm: 8;
46
+ readonly md: 16;
47
+ readonly lg: 24;
48
+ readonly xl: 32;
49
+ };
50
+ export declare const radius: {
51
+ readonly sm: 4;
52
+ readonly md: 4;
53
+ };
54
+ export declare const baseContainerStyle: CSSProperties;
55
+ export declare const baseButtonStyle: CSSProperties;
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @description All colors use CSS custom properties with GENIEE SFA defaults as fallbacks.
3
+ * Override any color by setting the CSS variable on a parent element:
4
+ * :root { --sfa-primary: #FF0000; }
5
+ * <div style={{ '--sfa-primary': '#FF0000' }}>...</div>
6
+ */
7
+ export const color = {
8
+ primary: 'var(--sfa-primary, #3867D1)',
9
+ primaryHover: 'var(--sfa-primary-hover, #4E7EF5)',
10
+ primaryLight: 'var(--sfa-primary-light, #F0F5FF)',
11
+ primaryDark: 'var(--sfa-primary-dark, #203EAB)',
12
+ error: 'var(--sfa-error, #ED5C5C)',
13
+ errorHover: 'var(--sfa-error-hover, #FF8282)',
14
+ errorLight: 'var(--sfa-error-light, #FEF0F0)',
15
+ success: 'var(--sfa-success, #A3C848)',
16
+ warning: 'var(--sfa-warning, #F2B45E)',
17
+ white: '#FFFFFF',
18
+ black: '#000000',
19
+ textPrimary: 'var(--sfa-text-primary, #313542)',
20
+ textSecondary: 'var(--sfa-text-secondary, #838A98)',
21
+ textMuted: 'var(--sfa-text-muted, #ACB0BA)',
22
+ textPlaceholder: 'var(--sfa-text-placeholder, #C1C1C1)',
23
+ border: 'var(--sfa-border, #D6D9DD)',
24
+ borderLight: 'var(--sfa-border-light, #F2F2F2)',
25
+ divider: 'var(--sfa-divider, #F2F2F2)',
26
+ bgDefault: 'var(--sfa-bg-default, #F7F8FA)',
27
+ bgSurface: 'var(--sfa-bg-surface, #FFFFFF)',
28
+ bgHover: 'var(--sfa-bg-hover, rgba(0, 0, 0, 0.03))',
29
+ bgDisabled: 'var(--sfa-bg-disabled, rgba(0, 0, 0, 0.1))',
30
+ };
31
+ export const font = {
32
+ family: "var(--sfa-font-family, 'Noto Sans JP', 'Roboto', 'Helvetica', 'Arial', sans-serif)",
33
+ sizeXs: 11,
34
+ sizeSm: 12,
35
+ sizeMd: 13,
36
+ sizeLg: 14,
37
+ sizeXl: 16,
38
+ sizeTitle: 18,
39
+ weightRegular: 400,
40
+ weightMedium: 700,
41
+ };
42
+ export const space = {
43
+ xs: 4,
44
+ sm: 8,
45
+ md: 16,
46
+ lg: 24,
47
+ xl: 32,
48
+ };
49
+ export const radius = {
50
+ sm: 4,
51
+ md: 4,
52
+ };
53
+ export const baseContainerStyle = {
54
+ fontFamily: font.family,
55
+ color: color.textPrimary,
56
+ fontSize: font.sizeLg,
57
+ };
58
+ export const baseButtonStyle = {
59
+ fontFamily: font.family,
60
+ fontSize: font.sizeMd,
61
+ fontWeight: font.weightRegular,
62
+ borderRadius: radius.sm,
63
+ cursor: 'pointer',
64
+ textTransform: 'none',
65
+ boxShadow: 'none',
66
+ lineHeight: '20px',
67
+ transition: '0.2s',
68
+ };
@@ -0,0 +1 @@
1
+ export declare const SFA_KIT_VERSION = "1.6.0";
@@ -0,0 +1 @@
1
+ export const SFA_KIT_VERSION = "1.6.0";