@usefillo/core 0.24.1 → 0.25.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/dist/index.d.ts +45 -4
- package/dist/index.js +80 -6
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -401,16 +401,31 @@ interface FormSchema {
|
|
|
401
401
|
pages: FormPage[];
|
|
402
402
|
settings: FormSettings;
|
|
403
403
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
colorScheme?: "light" | "dark" | "auto";
|
|
404
|
+
/** The colors (and logo) of one appearance. */
|
|
405
|
+
interface FormThemePalette {
|
|
407
406
|
/** Accent for buttons, focus rings, selection. */
|
|
408
407
|
primary?: string;
|
|
409
408
|
background?: string;
|
|
410
409
|
text?: string;
|
|
410
|
+
/**
|
|
411
|
+
* Logo shown above the form on Fillo-hosted pages: the id of an image
|
|
412
|
+
* uploaded to the workspace. Embedded forms leave branding to the host app.
|
|
413
|
+
*/
|
|
414
|
+
logo?: string;
|
|
415
|
+
}
|
|
416
|
+
interface FormTheme extends FormThemePalette {
|
|
417
|
+
/** Omit to inherit the host page. Use "auto" to follow the visitor's system directly. */
|
|
418
|
+
colorScheme?: "light" | "dark" | "auto";
|
|
411
419
|
/** Border radius scale, e.g. "8px". */
|
|
412
420
|
radius?: string;
|
|
413
421
|
fontFamily?: string;
|
|
422
|
+
/**
|
|
423
|
+
* Dark-mode colors, for a form that follows a light/dark setting
|
|
424
|
+
* (`colorScheme` omitted or "auto"). The top-level colors are then the
|
|
425
|
+
* light palette. An unset dark color uses the default dark token; an unset
|
|
426
|
+
* dark logo reuses the top-level logo. Ignored when `colorScheme` is fixed.
|
|
427
|
+
*/
|
|
428
|
+
dark?: FormThemePalette;
|
|
414
429
|
}
|
|
415
430
|
/** Branding the server tells the SDK to render. Server-owned so the wording /
|
|
416
431
|
* link can change centrally without a new SDK release. */
|
|
@@ -1980,6 +1995,8 @@ declare const FILLO_THEME_VARS: readonly [{
|
|
|
1980
1995
|
readonly var: "--fillo-muted";
|
|
1981
1996
|
}, {
|
|
1982
1997
|
readonly var: "--fillo-border";
|
|
1998
|
+
}, {
|
|
1999
|
+
readonly var: "--fillo-control-border";
|
|
1983
2000
|
}, {
|
|
1984
2001
|
readonly var: "--fillo-control-bg";
|
|
1985
2002
|
}, {
|
|
@@ -2006,6 +2023,30 @@ declare const FILLO_THEME_VARS: readonly [{
|
|
|
2006
2023
|
* `[data-fillo-color-scheme="dark"]` CSS, so no new CSS is needed.
|
|
2007
2024
|
*/
|
|
2008
2025
|
declare function resolveThemeAppearance(theme: FormTheme | null): FormTheme | null;
|
|
2026
|
+
/**
|
|
2027
|
+
* True when the theme switches palettes with the light/dark setting: it has
|
|
2028
|
+
* dark colors and its scheme is not fixed (omitted or "auto"). A dark logo
|
|
2029
|
+
* alone switches nothing.
|
|
2030
|
+
*/
|
|
2031
|
+
declare function themeHasDarkPalette(theme: FormTheme | null | undefined): boolean;
|
|
2032
|
+
interface ThemeDomAttributes {
|
|
2033
|
+
/** Inline custom properties for the form root (`--fillo-primary`, …). */
|
|
2034
|
+
vars: Record<string, string>;
|
|
2035
|
+
/** `data-fillo-*` attributes for the form root. */
|
|
2036
|
+
attrs: Record<string, string>;
|
|
2037
|
+
}
|
|
2038
|
+
/**
|
|
2039
|
+
* Turn an untrusted theme into the form root's inline custom properties and
|
|
2040
|
+
* data attributes — one implementation for every renderer.
|
|
2041
|
+
*
|
|
2042
|
+
* A theme with a dark palette (see themeHasDarkPalette) emits each color as
|
|
2043
|
+
* `light-dark(light, dark)`, so it follows the form's own color-scheme: the
|
|
2044
|
+
* host page's when `colorScheme` is omitted, the visitor's device on "auto".
|
|
2045
|
+
* `data-fillo-on-primary` (and `-dark`) name the text tone that reads on a
|
|
2046
|
+
* custom accent; the stylesheet maps them to `--fillo-primary-contrast`, which
|
|
2047
|
+
* stays overridable from consumer CSS.
|
|
2048
|
+
*/
|
|
2049
|
+
declare function resolveThemeDom(theme: FormTheme | null | undefined): ThemeDomAttributes | null;
|
|
2009
2050
|
|
|
2010
2051
|
/** Result of syncing a code-defined form: its canonical id, slug, and branding. */
|
|
2011
2052
|
interface SyncedForm {
|
|
@@ -2252,4 +2293,4 @@ declare class Sha1 {
|
|
|
2252
2293
|
}
|
|
2253
2294
|
declare const sha1Base64: (bytes: Uint8Array) => string;
|
|
2254
2295
|
|
|
2255
|
-
export { type AutoSubmitContext, BLOCK_KIND_META, type BaseField, type Block, type BlockKind, CONTENT_KINDS, type CalcExpr, type CalculatedField, type ChallengeConfig, type ChallengeTheme, type CheckboxField, type ChoiceField, type CodeForm, type Condition, type ConditionOp, type ContentBlock, type ContentKind, type CreatedDraft, type CustomField, DEFAULT_FIELD_STRINGS, DEFAULT_RESPONDENT_ERROR_STRINGS, DEFAULT_STRINGS, DRAFT_KINDS, type DateField, type DividerBlock, FILLO_CALC_MIN_SDK_VERSION, FILLO_CHALLENGE_MIN_SDK_VERSION, FILLO_DATA_ATTRS, FILLO_GROUP_MIN_SDK_VERSION, FILLO_MIN_SDK_VERSION, FILLO_SCHEMA_VERSION, FILLO_SDK_VERSION, FILLO_SLOTS, FILLO_THEME_VARS, type Field, type FieldKind, type FieldSpec, type FieldValue, type FileUploadField, type FileValue, type FilloAppearance, FilloClient, type FilloClientOptions, FilloError, type FilloFieldStrings, FilloJsxError, type FilloRendererStrings, type FilloRespondent, type FilloSlot, type FilloStrings, type FormBranding, type FormController, type FormControllerOptions, type FormControllerState, type FormDraftSpec, type FormPage, type FormSchema, type FormSettings, type FormStatus, type FormTheme, type GroupInstanceValue, type HeadingBlock, type HiddenField, JSX_BLOCK_COMPONENTS, JSX_BLOCK_SPECS, type JsonValue, type JsxFormMeta, type JumpRule, type LinearScaleField, MAX_FILES_PER_FIELD, type MatrixField, type NextPage, type NumberField, PHONE_COUNTRIES, PHONE_PICKER_COUNTRIES, PHONE_POPOVER_VIEWPORT_GAP, type ParagraphBlock, type ParsePhoneOptions, type ParsedPhone, type PhoneCountry, type PhoneField, type PhonePopoverPlacement, type ProvisionWorkspaceResult, type PublishedForm, REQUIRED_FIELD_MESSAGE, type RankingField, type RatingField, type RepeatingGroupField, type RespondentErrorOverrides, type RespondentErrorStrings, type ResponseData, type ResponseDraft, type ResponseLimit, type SchemaValidationResult, type SelectOption, Sha1, type SignatureField, type SlotClass, type SlotState, type SubmitMeta, type SubmitResult, type SyncFormResult, type SyncedForm, type TextField, type TrustPolicy, type UploadFileOptions, type UploadProgress, type UploadSession, type UploadStatus, type UploadTransport, type ValidationResult, type WhenBuilder, allFields, assembleForm, codeFormFromJsx, computeCalculated, conditionsMet, contentHash, countryByDialCode, countryByIso, countryByTimeZone, createBlock, createClient, createEmptyForm, createFormController, createId, defineForm, digitsOnly, evaluateCalc, flagEmoji, formSchemasEqual, formatAnswer, formatGroupedNumber, formatNational, isAutoSubmitBlock, isBlockVisible, isBuildTimeDevEnv, isCodeForm, isField, isFilloError, isLikelyDevEnv, isPossiblePhone, isTerminalPage, isValidPartialNumberText, localeForNotation, needsExplicitSubmit, normalizeFormSchema, normalizeFormTheme, normalizeSettings, parseGroupedNumber, parsePhone, pipeBlock, positionPhonePopover, prefillFromParams, provisionWorkspace, radioGroupStep, reachableFieldIds, reachableFields, reachablePageIds, reachablePageSequence, requiredFieldMessage, resolveNextPage, resolveSlotClass, resolveStrings, resolveText, resolveThemeAppearance, respondentErrorStringsFor, responseScopeValue, schemaFromJsx, sha1Base64, shouldAutoSubmit, slotClass, syncCodeForm, toE164, validateField, validateFormSchema, validateResponse, visibleBlocks, visibleFields, visibleGroupChildren, visiblePageBlocks, when };
|
|
2296
|
+
export { type AutoSubmitContext, BLOCK_KIND_META, type BaseField, type Block, type BlockKind, CONTENT_KINDS, type CalcExpr, type CalculatedField, type ChallengeConfig, type ChallengeTheme, type CheckboxField, type ChoiceField, type CodeForm, type Condition, type ConditionOp, type ContentBlock, type ContentKind, type CreatedDraft, type CustomField, DEFAULT_FIELD_STRINGS, DEFAULT_RESPONDENT_ERROR_STRINGS, DEFAULT_STRINGS, DRAFT_KINDS, type DateField, type DividerBlock, FILLO_CALC_MIN_SDK_VERSION, FILLO_CHALLENGE_MIN_SDK_VERSION, FILLO_DATA_ATTRS, FILLO_GROUP_MIN_SDK_VERSION, FILLO_MIN_SDK_VERSION, FILLO_SCHEMA_VERSION, FILLO_SDK_VERSION, FILLO_SLOTS, FILLO_THEME_VARS, type Field, type FieldKind, type FieldSpec, type FieldValue, type FileUploadField, type FileValue, type FilloAppearance, FilloClient, type FilloClientOptions, FilloError, type FilloFieldStrings, FilloJsxError, type FilloRendererStrings, type FilloRespondent, type FilloSlot, type FilloStrings, type FormBranding, type FormController, type FormControllerOptions, type FormControllerState, type FormDraftSpec, type FormPage, type FormSchema, type FormSettings, type FormStatus, type FormTheme, type FormThemePalette, type GroupInstanceValue, type HeadingBlock, type HiddenField, JSX_BLOCK_COMPONENTS, JSX_BLOCK_SPECS, type JsonValue, type JsxFormMeta, type JumpRule, type LinearScaleField, MAX_FILES_PER_FIELD, type MatrixField, type NextPage, type NumberField, PHONE_COUNTRIES, PHONE_PICKER_COUNTRIES, PHONE_POPOVER_VIEWPORT_GAP, type ParagraphBlock, type ParsePhoneOptions, type ParsedPhone, type PhoneCountry, type PhoneField, type PhonePopoverPlacement, type ProvisionWorkspaceResult, type PublishedForm, REQUIRED_FIELD_MESSAGE, type RankingField, type RatingField, type RepeatingGroupField, type RespondentErrorOverrides, type RespondentErrorStrings, type ResponseData, type ResponseDraft, type ResponseLimit, type SchemaValidationResult, type SelectOption, Sha1, type SignatureField, type SlotClass, type SlotState, type SubmitMeta, type SubmitResult, type SyncFormResult, type SyncedForm, type TextField, type ThemeDomAttributes, type TrustPolicy, type UploadFileOptions, type UploadProgress, type UploadSession, type UploadStatus, type UploadTransport, type ValidationResult, type WhenBuilder, allFields, assembleForm, codeFormFromJsx, computeCalculated, conditionsMet, contentHash, countryByDialCode, countryByIso, countryByTimeZone, createBlock, createClient, createEmptyForm, createFormController, createId, defineForm, digitsOnly, evaluateCalc, flagEmoji, formSchemasEqual, formatAnswer, formatGroupedNumber, formatNational, isAutoSubmitBlock, isBlockVisible, isBuildTimeDevEnv, isCodeForm, isField, isFilloError, isLikelyDevEnv, isPossiblePhone, isTerminalPage, isValidPartialNumberText, localeForNotation, needsExplicitSubmit, normalizeFormSchema, normalizeFormTheme, normalizeSettings, parseGroupedNumber, parsePhone, pipeBlock, positionPhonePopover, prefillFromParams, provisionWorkspace, radioGroupStep, reachableFieldIds, reachableFields, reachablePageIds, reachablePageSequence, requiredFieldMessage, resolveNextPage, resolveSlotClass, resolveStrings, resolveText, resolveThemeAppearance, resolveThemeDom, respondentErrorStringsFor, responseScopeValue, schemaFromJsx, sha1Base64, shouldAutoSubmit, slotClass, syncCodeForm, themeHasDarkPalette, toE164, validateField, validateFormSchema, validateResponse, visibleBlocks, visibleFields, visibleGroupChildren, visiblePageBlocks, when };
|
package/dist/index.js
CHANGED
|
@@ -1114,7 +1114,7 @@ var schemaShape = z2.object({
|
|
|
1114
1114
|
});
|
|
1115
1115
|
var MAX_SCHEMA_VERSION = 1;
|
|
1116
1116
|
var FILLO_SCHEMA_VERSION = 1;
|
|
1117
|
-
var FILLO_SDK_VERSION = true ? "0.
|
|
1117
|
+
var FILLO_SDK_VERSION = true ? "0.25.0" : "0.0.0-dev";
|
|
1118
1118
|
var FILLO_MIN_SDK_VERSION = "0.4.0";
|
|
1119
1119
|
var FILLO_CHALLENGE_MIN_SDK_VERSION = "0.9.0";
|
|
1120
1120
|
var FILLO_CALC_MIN_SDK_VERSION = "0.11.0";
|
|
@@ -1893,17 +1893,30 @@ function safeCssToken(value, max) {
|
|
|
1893
1893
|
if (/[;{}<>]/.test(token) || /url\s*\(/i.test(token)) return void 0;
|
|
1894
1894
|
return token;
|
|
1895
1895
|
}
|
|
1896
|
+
function themeAssetId(value) {
|
|
1897
|
+
return typeof value === "string" && /^[A-Za-z0-9_-]{8,64}$/.test(value) ? value : void 0;
|
|
1898
|
+
}
|
|
1899
|
+
function normalizeThemePalette(input) {
|
|
1900
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) return void 0;
|
|
1901
|
+
const rec = input;
|
|
1902
|
+
const palette = cleanObject({
|
|
1903
|
+
primary: safeCssToken(rec.primary, 200),
|
|
1904
|
+
background: safeCssToken(rec.background, 200),
|
|
1905
|
+
text: safeCssToken(rec.text, 200),
|
|
1906
|
+
logo: themeAssetId(rec.logo)
|
|
1907
|
+
});
|
|
1908
|
+
return Object.keys(palette).length > 0 ? palette : void 0;
|
|
1909
|
+
}
|
|
1896
1910
|
function normalizeFormTheme(input) {
|
|
1897
1911
|
if (!input || typeof input !== "object" || Array.isArray(input)) return null;
|
|
1898
1912
|
const rec = input;
|
|
1899
1913
|
const colorScheme = rec.colorScheme === "light" || rec.colorScheme === "dark" || rec.colorScheme === "auto" ? rec.colorScheme : void 0;
|
|
1900
1914
|
const theme = cleanObject({
|
|
1901
1915
|
colorScheme,
|
|
1902
|
-
|
|
1903
|
-
background: safeCssToken(rec.background, 200),
|
|
1904
|
-
text: safeCssToken(rec.text, 200),
|
|
1916
|
+
...normalizeThemePalette(rec),
|
|
1905
1917
|
radius: safeCssToken(rec.radius, 64),
|
|
1906
|
-
fontFamily: safeCssToken(rec.fontFamily, 200)
|
|
1918
|
+
fontFamily: safeCssToken(rec.fontFamily, 200),
|
|
1919
|
+
dark: normalizeThemePalette(rec.dark)
|
|
1907
1920
|
});
|
|
1908
1921
|
return Object.keys(theme).length > 0 ? theme : null;
|
|
1909
1922
|
}
|
|
@@ -4194,6 +4207,7 @@ var FILLO_THEME_VARS = [
|
|
|
4194
4207
|
{ var: "--fillo-font", themeProp: "fontFamily" },
|
|
4195
4208
|
{ var: "--fillo-muted" },
|
|
4196
4209
|
{ var: "--fillo-border" },
|
|
4210
|
+
{ var: "--fillo-control-border" },
|
|
4197
4211
|
{ var: "--fillo-control-bg" },
|
|
4198
4212
|
{ var: "--fillo-error" },
|
|
4199
4213
|
{ var: "--fillo-primary-contrast" }
|
|
@@ -4222,13 +4236,71 @@ function relativeLuminance(token) {
|
|
|
4222
4236
|
return 0.2126 * srgbToLinear(r) + 0.7152 * srgbToLinear(g) + 0.0722 * srgbToLinear(b);
|
|
4223
4237
|
}
|
|
4224
4238
|
function resolveThemeAppearance(theme) {
|
|
4225
|
-
if (!theme || theme.colorScheme === "light" || theme.colorScheme === "dark" || !theme.background
|
|
4239
|
+
if (!theme || theme.colorScheme === "light" || theme.colorScheme === "dark" || !theme.background || // A form with dark colors of its own follows the light/dark setting.
|
|
4240
|
+
themeHasDarkPalette(theme)) {
|
|
4226
4241
|
return theme;
|
|
4227
4242
|
}
|
|
4228
4243
|
const luminance = relativeLuminance(theme.background);
|
|
4229
4244
|
if (luminance == null) return theme;
|
|
4230
4245
|
return { ...theme, colorScheme: luminance > DARK_LUMINANCE_THRESHOLD ? "light" : "dark" };
|
|
4231
4246
|
}
|
|
4247
|
+
function themeHasDarkPalette(theme) {
|
|
4248
|
+
if (!theme || theme.colorScheme === "light" || theme.colorScheme === "dark") return false;
|
|
4249
|
+
const dark = theme.dark;
|
|
4250
|
+
return Boolean(dark && (dark.primary || dark.background || dark.text));
|
|
4251
|
+
}
|
|
4252
|
+
var ON_LIGHT_TEXT = "#18181b";
|
|
4253
|
+
function onColorTone(color) {
|
|
4254
|
+
const luminance = relativeLuminance(color);
|
|
4255
|
+
if (luminance == null) return null;
|
|
4256
|
+
const withWhite = 1.05 / (luminance + 0.05);
|
|
4257
|
+
const withDark = (luminance + 0.05) / ((relativeLuminance(ON_LIGHT_TEXT) ?? 0) + 0.05);
|
|
4258
|
+
return withWhite >= withDark ? "light" : "dark";
|
|
4259
|
+
}
|
|
4260
|
+
var PALETTE_VARS = [
|
|
4261
|
+
["primary", "--fillo-primary"],
|
|
4262
|
+
["background", "--fillo-bg"],
|
|
4263
|
+
["text", "--fillo-text"]
|
|
4264
|
+
];
|
|
4265
|
+
var DEFAULT_PALETTE = {
|
|
4266
|
+
light: { primary: "#18181b", background: "transparent", text: "#18181b" },
|
|
4267
|
+
dark: { primary: "#fafafa", background: "transparent", text: "#f4f4f5" }
|
|
4268
|
+
};
|
|
4269
|
+
function resolveThemeDom(theme) {
|
|
4270
|
+
const safe = resolveThemeAppearance(normalizeFormTheme(theme));
|
|
4271
|
+
if (!safe) return null;
|
|
4272
|
+
const vars = {};
|
|
4273
|
+
const attrs = {};
|
|
4274
|
+
if (safe.colorScheme) attrs["data-fillo-color-scheme"] = safe.colorScheme;
|
|
4275
|
+
const dark = themeHasDarkPalette(safe) ? safe.dark : void 0;
|
|
4276
|
+
for (const [key, name] of PALETTE_VARS) {
|
|
4277
|
+
const light = safe[key];
|
|
4278
|
+
if (!dark) {
|
|
4279
|
+
if (light) vars[name] = light;
|
|
4280
|
+
continue;
|
|
4281
|
+
}
|
|
4282
|
+
const darkValue = dark[key];
|
|
4283
|
+
if (!light && !darkValue) continue;
|
|
4284
|
+
vars[name] = `light-dark(${light ?? DEFAULT_PALETTE.light[key]}, ${darkValue ?? DEFAULT_PALETTE.dark[key]})`;
|
|
4285
|
+
}
|
|
4286
|
+
if (safe.radius) vars["--fillo-radius"] = safe.radius;
|
|
4287
|
+
if (safe.fontFamily) vars["--fillo-font"] = safe.fontFamily;
|
|
4288
|
+
if (dark) {
|
|
4289
|
+
const lightTone = onColorTone(safe.primary ?? DEFAULT_PALETTE.light.primary);
|
|
4290
|
+
const darkTone = onColorTone(dark.primary ?? DEFAULT_PALETTE.dark.primary);
|
|
4291
|
+
if (lightTone && darkTone) {
|
|
4292
|
+
attrs["data-fillo-on-primary"] = lightTone;
|
|
4293
|
+
attrs["data-fillo-on-primary-dark"] = darkTone;
|
|
4294
|
+
}
|
|
4295
|
+
} else if (safe.primary) {
|
|
4296
|
+
const tone = onColorTone(safe.primary);
|
|
4297
|
+
if (tone) attrs["data-fillo-on-primary"] = tone;
|
|
4298
|
+
}
|
|
4299
|
+
if (safe.primary || safe.background || safe.text || dark) {
|
|
4300
|
+
attrs["data-fillo-has-color-theme"] = "";
|
|
4301
|
+
}
|
|
4302
|
+
return { vars, attrs };
|
|
4303
|
+
}
|
|
4232
4304
|
|
|
4233
4305
|
// src/define.ts
|
|
4234
4306
|
function defineForm(def) {
|
|
@@ -4864,6 +4936,7 @@ export {
|
|
|
4864
4936
|
resolveStrings,
|
|
4865
4937
|
resolveText,
|
|
4866
4938
|
resolveThemeAppearance,
|
|
4939
|
+
resolveThemeDom,
|
|
4867
4940
|
respondentErrorStringsFor,
|
|
4868
4941
|
responseScopeValue,
|
|
4869
4942
|
schemaFromJsx,
|
|
@@ -4871,6 +4944,7 @@ export {
|
|
|
4871
4944
|
shouldAutoSubmit,
|
|
4872
4945
|
slotClass,
|
|
4873
4946
|
syncCodeForm,
|
|
4947
|
+
themeHasDarkPalette,
|
|
4874
4948
|
toE164,
|
|
4875
4949
|
validateField,
|
|
4876
4950
|
validateFormSchema,
|