@kanso-labs/react-native-kanso-ui 0.1.1 → 0.2.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/button/index.d.ts +24 -2
- package/dist/button/index.js.map +1 -1
- package/dist/button/pending.js +144 -0
- package/dist/button/pending.js.map +1 -0
- package/dist/components/button/index.d.ts +1 -1
- package/dist/components/button/index.js +154 -112
- package/dist/components/button/index.js.map +1 -1
- package/dist/components/icon-button/index.d.ts +1 -1
- package/dist/components/icon-button/index.js +160 -110
- package/dist/components/icon-button/index.js.map +1 -1
- package/dist/components/meter/index.d.ts +73 -0
- package/dist/components/meter/index.js +179 -0
- package/dist/components/meter/index.js.map +1 -0
- package/dist/components/number-field/index.js +1 -9
- package/dist/components/number-field/index.js.map +1 -1
- package/dist/components/progress-indicator/index.d.ts +113 -0
- package/dist/components/progress-indicator/index.js +1024 -0
- package/dist/components/progress-indicator/index.js.map +1 -0
- package/dist/components/snackbar/index.d.ts +120 -0
- package/dist/components/snackbar/index.js +540 -0
- package/dist/components/snackbar/index.js.map +1 -0
- package/dist/glyphs/hidden.js +13 -0
- package/dist/glyphs/hidden.js.map +1 -0
- package/dist/glyphs/index.js +2 -8
- package/dist/glyphs/index.js.map +1 -1
- package/dist/i18n/index.js +23 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/messages.js +41 -0
- package/dist/i18n/messages.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +6 -3
- package/dist/indicator/index.d.ts +15 -0
- package/dist/indicator/index.js +256 -0
- package/dist/indicator/index.js.map +1 -0
- package/dist/indicator/motion.js +86 -0
- package/dist/indicator/motion.js.map +1 -0
- package/dist/indicator/paths.js +72 -0
- package/dist/indicator/paths.js.map +1 -0
- package/dist/indicator/styles.js +62 -0
- package/dist/indicator/styles.js.map +1 -0
- package/dist/number/locale.js +14 -0
- package/dist/number/locale.js.map +1 -0
- package/dist/overlay/host.js +65 -2
- package/dist/overlay/host.js.map +1 -1
- package/dist/press/index.js +10 -9
- package/dist/press/index.js.map +1 -1
- package/dist/theme/resolve.js +1 -1
- package/dist/theme/resolve.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.js","names":["Attempt","Settled","reason","Easing","x1","y1","x2","y2","Group","ResolvedGroups","Groups","key","G","Kind","colors","Readonly","Record","motion","radii","shadows","sizing","spacing","stateLayerOpacity","typography","raw","value","Value","ThemeProblem","property","ThemeProperties","Partial","CATEGORIES","EASING_KEYWORDS","ease","linear","FONT_WEIGHT_KEYWORDS","bold","normal","UNSUPPORTED_FUNCTION","NUMBER","String","camelCase","kebab","replaceAll","_","letter","toUpperCase","classify","group","kind","startsWith","undefined","name","slice","length","match","find","category","rest","kindOf","closingParenthesis","from","depth","index","typographyKindOf","parseColor","drawable","test","parseDuration","exec","duration","Number","parseEasing","keyword","points","split","map","point","trim","every","RegExp","x","parseFontFamily","families","splitTopLevel","family","replace","includes","parseFontWeight","weight","parseLength","parseOpacity","opacity","Math","min","max","parseShadow","parts","quote","start","character","push","endsWith","measured","some","suffix","PARSERS","color","easing","fontFamily","fontWeight","shadow","declarations","properties","Map","Object","entries","filter","entry","resolveTheme","defaults","overrides","problems","theme","declared","replaced","settled","settling","cyclic","Set","substitute","indexOf","end","fallback","join","referenced","has","settle","replacement","evaluate","unsupported","read","parsed","attempt","result","known","get","classified","member","add","pop","set","assign"],"sources":["../../src/theme/resolve.ts"],"sourcesContent":["type Attempt = Settled | { readonly reason: string }\n\n/** A cubic Bézier curve's control points, as `cubic-bezier()` lists them. */\ntype Easing = readonly [x1: number, y1: number, x2: number, y2: number]\n\ntype Group = keyof ResolvedGroups\n\n// The resolved theme with its groups writable, for the resolver to fill in.\ntype Groups = {\n -readonly [G in Group]: { [key: string]: ResolvedGroups[G][string] }\n}\n\ntype Kind =\n | 'color'\n | 'duration'\n | 'easing'\n | 'fontFamily'\n | 'fontWeight'\n | 'length'\n | 'opacity'\n | 'shadow'\n\n/**\n * The tokens in the values React Native styles take, grouped and keyed as the\n * web library's StyleX tokens are: `--kui-color-primary` is `colors.primary`\n * and `--kui-typography-body-large-size` is `typography.bodyLargeSize`. Any\n * set of properties resolves to this shape; `ResolvedTheme` in ./scope.ts is\n * the same groups with the keys the library's own tokens give them.\n */\ntype ResolvedGroups = {\n readonly colors: Readonly<Record<string, string>>\n readonly motion: Readonly<Record<string, Easing | number>>\n readonly radii: Readonly<Record<string, number>>\n readonly shadows: Readonly<Record<string, string>>\n readonly sizing: Readonly<Record<string, number>>\n readonly spacing: Readonly<Record<string, number>>\n readonly stateLayerOpacity: Readonly<Record<string, number>>\n readonly typography: Readonly<Record<string, number | readonly string[]>>\n}\n\ntype Settled = { readonly raw: string; readonly value: Value }\n\n/** A property whose value could not be used, and why. */\ntype ThemeProblem = {\n readonly property: string\n readonly reason: string\n readonly value: string\n}\n\n/**\n * A set of `--kui-*` custom properties and their values, written in CSS syntax\n * exactly as kanso-ui's `tokens.css` declares them, so one theme serves both\n * libraries.\n */\ntype ThemeProperties = Readonly<Partial<Record<`--kui-${string}`, string>>>\n\ntype Value = Easing | number | readonly string[] | string\n\n// The segment each group takes in a property's name, as kanso-ui's\n// build-tokens.mjs writes it: singular where the group's own name is plural.\nconst CATEGORIES: readonly (readonly [string, Group])[] = [\n ['color', 'colors'],\n ['motion', 'motion'],\n ['radius', 'radii'],\n ['shadow', 'shadows'],\n ['sizing', 'sizing'],\n ['spacing', 'spacing'],\n ['state-layer-opacity', 'stateLayerOpacity'],\n ['typography', 'typography'],\n]\n\n// The CSS keywords a timing function may be written as, as the curves the\n// CSS Easing specification defines them to be.\nconst EASING_KEYWORDS: Readonly<Partial<Record<string, Easing>>> = {\n ease: [0.25, 0.1, 0.25, 1],\n 'ease-in': [0.42, 0, 1, 1],\n 'ease-in-out': [0.42, 0, 0.58, 1],\n 'ease-out': [0, 0, 0.58, 1],\n linear: [0, 0, 1, 1],\n}\n\nconst FONT_WEIGHT_KEYWORDS: Readonly<Partial<Record<string, number>>> = {\n bold: 700,\n normal: 400,\n}\n\n// Functions a browser evaluates and React Native does not. `var()` is the one\n// CSS function the resolver evaluates itself, so it is not among them.\nconst UNSUPPORTED_FUNCTION =\n /\\b(attr|calc|clamp|color-mix|env|light-dark|max|min)\\(/u\n\nconst NUMBER = String.raw`-?(?:\\d+\\.?\\d*|\\.\\d+)`\n\nfunction camelCase(kebab: string): string {\n return kebab.replaceAll(/-([a-z0-9])/gu, (_, letter: string) =>\n letter.toUpperCase(),\n )\n}\n\n/** The group a property belongs to, the key it takes there, and its kind. */\nfunction classify(\n property: string,\n): undefined | { group: Group; key: string; kind: Kind } {\n if (!property.startsWith('--kui-')) {\n return undefined\n }\n\n const name = property.slice('--kui-'.length)\n const match = CATEGORIES.find(([category]) => name.startsWith(`${category}-`))\n\n if (match === undefined) {\n return undefined\n }\n\n const [category, group] = match\n const rest = name.slice(category.length + 1)\n const kind = kindOf(category, rest)\n\n return kind === undefined ? undefined : { group, key: camelCase(rest), kind }\n}\n\n/** The index of the parenthesis closing the one just before `from`. */\nfunction closingParenthesis(value: string, from: number): number {\n let depth = 1\n\n for (let index = from; index < value.length; index++) {\n if (value[index] === '(') {\n depth++\n } else if (value[index] === ')') {\n depth--\n\n if (depth === 0) {\n return index\n }\n }\n }\n\n return -1\n}\n\nfunction kindOf(category: string, rest: string): Kind | undefined {\n switch (category) {\n case 'color': {\n return 'color'\n }\n case 'motion': {\n if (rest.startsWith('duration-')) {\n return 'duration'\n }\n\n return rest.startsWith('easing-') ? 'easing' : undefined\n }\n case 'radius':\n case 'sizing':\n case 'spacing': {\n return 'length'\n }\n case 'shadow': {\n return 'shadow'\n }\n case 'state-layer-opacity': {\n return 'opacity'\n }\n default: {\n return typographyKindOf(rest)\n }\n }\n}\n\nfunction parseColor(value: string): string | undefined {\n const drawable =\n /^#([\\da-f]{3,4}|[\\da-f]{6}|[\\da-f]{8})$/iu.test(value) ||\n /^(rgba?|hsla?|hwb)\\([^()]*\\)$/iu.test(value) ||\n /^[a-z]+$/iu.test(value)\n\n return drawable ? value : undefined\n}\n\nfunction parseDuration(value: string): number | undefined {\n const match = /^(\\d+\\.?\\d*|\\.\\d+)(ms|s)$/u.exec(value)\n\n if (match === null) {\n return undefined\n }\n\n const duration = Number(match[1])\n\n return match[2] === 's' ? duration * 1000 : duration\n}\n\nfunction parseEasing(value: string): Easing | undefined {\n const keyword = EASING_KEYWORDS[value]\n\n if (keyword !== undefined) {\n return keyword\n }\n\n const match = /^cubic-bezier\\(([^()]*)\\)$/u.exec(value)\n\n if (match === null) {\n return undefined\n }\n\n const points = match[1].split(',').map((point) => point.trim())\n\n if (\n points.length !== 4 ||\n !points.every((point) => new RegExp(`^${NUMBER}$`, 'u').test(point))\n ) {\n return undefined\n }\n\n const [x1, y1, x2, y2] = points.map(Number)\n\n // The curve has to stay a function of time, which is what holds both x\n // coordinates inside the unit interval.\n return [x1, x2].every((x) => x >= 0 && x <= 1) ? [x1, y1, x2, y2] : undefined\n}\n\nfunction parseFontFamily(value: string): readonly string[] | undefined {\n const families = splitTopLevel(value).map((family) =>\n family.trim().replace(/^([\"'])(.*)\\1$/u, '$2'),\n )\n\n return families.every((family) => family !== '' && !family.includes('('))\n ? families\n : undefined\n}\n\nfunction parseFontWeight(value: string): number | undefined {\n const keyword = FONT_WEIGHT_KEYWORDS[value]\n\n if (keyword !== undefined) {\n return keyword\n }\n\n if (!/^\\d+(\\.\\d+)?$/u.test(value)) {\n return undefined\n }\n\n const weight = Number(value)\n\n return weight >= 1 && weight <= 1000 ? weight : undefined\n}\n\nfunction parseLength(value: string): number | undefined {\n const match = new RegExp(`^(${NUMBER})(px)?$`, 'u').exec(value)\n\n if (match === null) {\n return undefined\n }\n\n const length = Number(match[1])\n\n // CSS takes a bare number as a length only when it is zero.\n return match[2] !== 'px' && length !== 0 ? undefined : length\n}\n\nfunction parseOpacity(value: string): number | undefined {\n const match = new RegExp(`^(${NUMBER})(%)?$`, 'u').exec(value)\n\n if (match === null) {\n return undefined\n }\n\n const opacity = Number(match[1]) / (match[2] === '%' ? 100 : 1)\n\n // CSS clamps an opacity to the unit interval rather than rejecting it.\n return Math.min(Math.max(opacity, 0), 1)\n}\n\nfunction parseShadow(value: string): string | undefined {\n return value === '' ? undefined : value\n}\n\n/** Splits a value at its top-level commas, leaving any inside parentheses. */\nfunction splitTopLevel(value: string): string[] {\n const parts: string[] = []\n let depth = 0\n let quote: string | undefined\n let start = 0\n\n for (let index = 0; index < value.length; index++) {\n const character = value[index]\n\n if (quote !== undefined) {\n quote = character === quote ? undefined : quote\n } else if (character === '\"' || character === \"'\") {\n quote = character\n } else if (character === '(') {\n depth++\n } else if (character === ')') {\n depth--\n } else if (character === ',' && depth === 0) {\n parts.push(value.slice(start, index))\n start = index + 1\n }\n }\n\n parts.push(value.slice(start))\n\n return parts\n}\n\nfunction typographyKindOf(rest: string): Kind | undefined {\n if (rest.startsWith('font-family-') || rest.endsWith('-font')) {\n return 'fontFamily'\n }\n\n if (rest.startsWith('weight-') || rest.endsWith('-weight')) {\n return 'fontWeight'\n }\n\n const measured = ['-line-height', '-size', '-tracking'].some((suffix) =>\n rest.endsWith(suffix),\n )\n\n return measured ? 'length' : undefined\n}\n\n// How each kind of value is read, and what a value that cannot be read is\n// reported as.\nconst PARSERS: Readonly<\n Record<Kind, readonly [(value: string) => undefined | Value, string]>\n> = {\n color: [parseColor, 'is not a colour React Native can draw'],\n duration: [parseDuration, 'is not a duration in ms or s'],\n easing: [parseEasing, 'is not a cubic-bezier() curve or an easing keyword'],\n fontFamily: [parseFontFamily, 'is not a font family list'],\n fontWeight: [parseFontWeight, 'is not a font weight from 1 to 1000'],\n length: [parseLength, 'is not a length in px'],\n opacity: [parseOpacity, 'is not a number or a percentage'],\n shadow: [parseShadow, 'is empty'],\n}\n\n/** The properties a theme declares, leaving out any it lists as undefined. */\nfunction declarations(properties: ThemeProperties): Map<string, string> {\n return new Map(\n Object.entries(properties).filter(\n (entry): entry is [string, string] => entry[1] !== undefined,\n ),\n )\n}\n\n/**\n * Turns a theme in CSS syntax into the values React Native styles take.\n *\n * `defaults` is the whole contract, and `overrides` replace any of it, as a\n * consumer's declarations replace the library's on web. A `var()` reference\n * resolves against both, with its fallback where the property it names has no\n * usable value, so a role pointing at a family or a weight follows an override\n * of that family or weight as it does in a browser.\n *\n * A value native cannot use, such as a `calc()` or a `color-mix()`, leaves its\n * property at the default instead of dropping it, and a property the defaults\n * do not declare is ignored. Each is listed in `problems` by name, for the\n * caller to report.\n */\nfunction resolveTheme(\n defaults: ThemeProperties,\n overrides: ThemeProperties = {},\n): { problems: readonly ThemeProblem[]; theme: ResolvedGroups } {\n const declared = declarations(defaults)\n const replaced = declarations(overrides)\n const problems: ThemeProblem[] = []\n const settled = new Map<string, null | Settled>()\n const settling: string[] = []\n const cyclic = new Set<string>()\n\n function substitute(value: string): string | { reason: string } {\n const start = value.indexOf('var(')\n\n if (start === -1) {\n return value\n }\n\n const end = closingParenthesis(value, start + 'var('.length)\n\n if (end === -1) {\n return { reason: 'has a var() that is never closed' }\n }\n\n const [name, ...rest] = splitTopLevel(\n value.slice(start + 'var('.length, end),\n )\n const property = name.trim()\n const fallback = rest.length === 0 ? undefined : rest.join(',').trim()\n const referenced = declared.has(property) ? settle(property) : null\n\n let replacement: string | { reason: string }\n\n if (referenced !== null) {\n replacement = referenced.raw\n } else if (fallback === undefined) {\n replacement = {\n reason: `refers to ${property}, which has no usable value`,\n }\n } else {\n replacement = substitute(fallback)\n }\n\n if (typeof replacement !== 'string') {\n return replacement\n }\n\n return substitute(\n `${value.slice(0, start)}${replacement}${value.slice(end + 1)}`,\n )\n }\n\n function evaluate(kind: Kind, value: string): Attempt {\n const raw = substitute(value.trim())\n\n if (typeof raw !== 'string') {\n return raw\n }\n\n const unsupported = UNSUPPORTED_FUNCTION.exec(raw)\n\n if (unsupported !== null) {\n return {\n reason: `uses ${unsupported[1]}(), which native cannot evaluate`,\n }\n }\n\n const [read, reason] = PARSERS[kind]\n const parsed = read(raw)\n\n return parsed === undefined ? { reason } : { raw, value: parsed }\n }\n\n /** Evaluates one declaration, listing it as a problem if it fails. */\n function attempt(\n property: string,\n kind: Kind,\n value: string | undefined,\n ): null | Settled {\n if (value === undefined) {\n return null\n }\n\n const result = evaluate(kind, value)\n\n if ('reason' in result) {\n problems.push({ property, reason: result.reason, value })\n\n return null\n }\n\n return result\n }\n\n function settle(property: string): null | Settled {\n const known = settled.get(property)\n\n if (known !== undefined) {\n return known\n }\n\n const classified = classify(property)\n\n if (classified === undefined) {\n return null\n }\n\n // A reference leading back to a property still being settled closes a\n // cycle, and every property on it is invalid, as in CSS. The defaults\n // hold no cycle, so the members fall back to theirs.\n const index = settling.indexOf(property)\n\n if (index !== -1) {\n for (const member of settling.slice(index)) {\n cyclic.add(member)\n }\n\n return null\n }\n\n settling.push(property)\n\n const value = replaced.get(property)\n let result = attempt(property, classified.kind, value)\n\n if (result !== null && value !== undefined && cyclic.has(property)) {\n problems.push({\n property,\n reason: 'refers back to itself through var()',\n value,\n })\n result = null\n }\n\n result ??= attempt(property, classified.kind, declared.get(property))\n\n settling.pop()\n settled.set(property, result)\n\n return result\n }\n\n const theme: Groups = {\n colors: {},\n motion: {},\n radii: {},\n shadows: {},\n sizing: {},\n spacing: {},\n stateLayerOpacity: {},\n typography: {},\n }\n\n for (const [property, value] of declared) {\n const classified = classify(property)\n\n if (classified === undefined) {\n problems.push({ property, reason: 'is not a Kanso UI token', value })\n\n continue\n }\n\n const result = settle(property)\n\n // classify() pairs every group with the kinds whose values it holds, which\n // is the one thing the type of a group's record cannot see.\n if (result !== null) {\n Object.assign(theme[classified.group], { [classified.key]: result.value })\n }\n }\n\n for (const [property, value] of replaced) {\n if (!declared.has(property)) {\n problems.push({ property, reason: 'is not a Kanso UI token', value })\n }\n }\n\n return { problems, theme }\n}\n\nexport type { Easing, ResolvedGroups, ThemeProblem, ThemeProperties }\nexport { resolveTheme }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"resolve.js","names":["Attempt","Settled","reason","Easing","x1","y1","x2","y2","Group","ResolvedGroups","Groups","key","G","Kind","colors","Readonly","Record","motion","radii","shadows","sizing","spacing","stateLayerOpacity","typography","raw","value","Value","ThemeProblem","property","ThemeProperties","Partial","CATEGORIES","EASING_KEYWORDS","ease","linear","FONT_WEIGHT_KEYWORDS","bold","normal","UNSUPPORTED_FUNCTION","NUMBER","String","camelCase","kebab","replaceAll","_","letter","toUpperCase","classify","group","kind","startsWith","undefined","name","slice","length","match","find","category","rest","kindOf","closingParenthesis","from","depth","index","typographyKindOf","parseColor","drawable","test","parseDuration","exec","duration","Number","parseEasing","keyword","points","split","map","point","trim","every","RegExp","x","parseFontFamily","families","splitTopLevel","family","replace","includes","parseFontWeight","weight","parseLength","parseOpacity","opacity","Math","min","max","parseShadow","parts","quote","start","character","push","endsWith","measured","some","suffix","PARSERS","color","easing","fontFamily","fontWeight","shadow","declarations","properties","Map","Object","entries","filter","entry","resolveTheme","defaults","overrides","problems","theme","declared","replaced","settled","settling","cyclic","Set","substitute","indexOf","end","fallback","join","referenced","has","settle","replacement","evaluate","unsupported","read","parsed","attempt","result","known","get","classified","member","add","pop","set","assign"],"sources":["../../src/theme/resolve.ts"],"sourcesContent":["type Attempt = Settled | { readonly reason: string }\n\n/** A cubic Bézier curve's control points, as `cubic-bezier()` lists them. */\ntype Easing = readonly [x1: number, y1: number, x2: number, y2: number]\n\ntype Group = keyof ResolvedGroups\n\n// The resolved theme with its groups writable, for the resolver to fill in.\ntype Groups = {\n -readonly [G in Group]: { [key: string]: ResolvedGroups[G][string] }\n}\n\ntype Kind =\n | 'color'\n | 'duration'\n | 'easing'\n | 'fontFamily'\n | 'fontWeight'\n | 'length'\n | 'opacity'\n | 'shadow'\n\n/**\n * The tokens in the values React Native styles take, grouped and keyed as the\n * web library's StyleX tokens are: `--kui-color-primary` is `colors.primary`\n * and `--kui-typography-body-large-size` is `typography.bodyLargeSize`. Any\n * set of properties resolves to this shape; `ResolvedTheme` in ./scope.ts is\n * the same groups with the keys the library's own tokens give them.\n */\ntype ResolvedGroups = {\n readonly colors: Readonly<Record<string, string>>\n readonly motion: Readonly<Record<string, Easing | number>>\n readonly radii: Readonly<Record<string, number>>\n readonly shadows: Readonly<Record<string, string>>\n readonly sizing: Readonly<Record<string, number>>\n readonly spacing: Readonly<Record<string, number>>\n readonly stateLayerOpacity: Readonly<Record<string, number>>\n readonly typography: Readonly<Record<string, number | readonly string[]>>\n}\n\ntype Settled = { readonly raw: string; readonly value: Value }\n\n/** A property whose value could not be used, and why. */\ntype ThemeProblem = {\n readonly property: string\n readonly reason: string\n readonly value: string\n}\n\n/**\n * A set of `--kui-*` custom properties and their values, written in CSS syntax\n * exactly as kanso-ui's `tokens.css` declares them, so one theme serves both\n * libraries.\n */\ntype ThemeProperties = Readonly<Partial<Record<`--kui-${string}`, string>>>\n\ntype Value = Easing | number | readonly string[] | string\n\n// The segment each group takes in a property's name, as kanso-ui's\n// build-tokens.mjs writes it: singular where the group's own name is plural.\nconst CATEGORIES: readonly (readonly [string, Group])[] = [\n ['color', 'colors'],\n ['motion', 'motion'],\n ['radius', 'radii'],\n ['shadow', 'shadows'],\n ['sizing', 'sizing'],\n ['spacing', 'spacing'],\n ['state-layer-opacity', 'stateLayerOpacity'],\n ['typography', 'typography'],\n]\n\n// The CSS keywords a timing function may be written as, as the curves the\n// CSS Easing specification defines them to be.\nconst EASING_KEYWORDS: Readonly<Partial<Record<string, Easing>>> = {\n ease: [0.25, 0.1, 0.25, 1],\n 'ease-in': [0.42, 0, 1, 1],\n 'ease-in-out': [0.42, 0, 0.58, 1],\n 'ease-out': [0, 0, 0.58, 1],\n linear: [0, 0, 1, 1],\n}\n\nconst FONT_WEIGHT_KEYWORDS: Readonly<Partial<Record<string, number>>> = {\n bold: 700,\n normal: 400,\n}\n\n// Functions a browser evaluates and React Native does not. `var()` is the one\n// CSS function the resolver evaluates itself, so it is not among them.\nconst UNSUPPORTED_FUNCTION =\n /\\b(attr|calc|clamp|color-mix|env|light-dark|max|min)\\(/u\n\nconst NUMBER = String.raw`-?(?:\\d+\\.?\\d*|\\.\\d+)`\n\nfunction camelCase(kebab: string): string {\n return kebab.replaceAll(/-([a-z0-9])/gu, (_, letter: string) =>\n letter.toUpperCase(),\n )\n}\n\n/** The group a property belongs to, the key it takes there, and its kind. */\nfunction classify(\n property: string,\n): undefined | { group: Group; key: string; kind: Kind } {\n if (!property.startsWith('--kui-')) {\n return undefined\n }\n\n const name = property.slice('--kui-'.length)\n const match = CATEGORIES.find(([category]) => name.startsWith(`${category}-`))\n\n if (match === undefined) {\n return undefined\n }\n\n const [category, group] = match\n const rest = name.slice(category.length + 1)\n const kind = kindOf(category, rest)\n\n return kind === undefined ? undefined : { group, key: camelCase(rest), kind }\n}\n\n/** The index of the parenthesis closing the one just before `from`. */\nfunction closingParenthesis(value: string, from: number): number {\n let depth = 1\n\n for (let index = from; index < value.length; index++) {\n if (value[index] === '(') {\n depth++\n } else if (value[index] === ')') {\n depth--\n\n if (depth === 0) {\n return index\n }\n }\n }\n\n return -1\n}\n\nfunction kindOf(category: string, rest: string): Kind | undefined {\n switch (category) {\n case 'color': {\n return 'color'\n }\n case 'motion': {\n if (rest.startsWith('duration-')) {\n return 'duration'\n }\n\n return rest.startsWith('easing-') ? 'easing' : undefined\n }\n case 'radius':\n case 'sizing':\n case 'spacing': {\n return 'length'\n }\n case 'shadow': {\n return 'shadow'\n }\n case 'state-layer-opacity': {\n return 'opacity'\n }\n default: {\n return typographyKindOf(rest)\n }\n }\n}\n\nfunction parseColor(value: string): string | undefined {\n const drawable =\n /^#([\\da-f]{3,4}|[\\da-f]{6}|[\\da-f]{8})$/iu.test(value) ||\n /^(rgba?|hsla?|hwb)\\([^()]*\\)$/iu.test(value) ||\n /^[a-z]+$/iu.test(value)\n\n return drawable ? value : undefined\n}\n\nfunction parseDuration(value: string): number | undefined {\n const match = /^(\\d+\\.?\\d*|\\.\\d+)(ms|s)$/u.exec(value)\n\n if (match === null) {\n return undefined\n }\n\n const duration = Number(match[1])\n\n return match[2] === 's' ? duration * 1000 : duration\n}\n\nfunction parseEasing(value: string): Easing | undefined {\n const keyword = EASING_KEYWORDS[value]\n\n if (keyword !== undefined) {\n return keyword\n }\n\n const match = /^cubic-bezier\\(([^()]*)\\)$/u.exec(value)\n\n if (match === null) {\n return undefined\n }\n\n const points = match[1].split(',').map((point) => point.trim())\n\n if (\n points.length !== 4 ||\n !points.every((point) => new RegExp(`^${NUMBER}$`, 'u').test(point))\n ) {\n return undefined\n }\n\n const [x1, y1, x2, y2] = points.map(Number)\n\n // The curve has to stay a function of time, which is what holds both x\n // coordinates inside the unit interval.\n return [x1, x2].every((x) => x >= 0 && x <= 1) ? [x1, y1, x2, y2] : undefined\n}\n\nfunction parseFontFamily(value: string): readonly string[] | undefined {\n const families = splitTopLevel(value).map((family) =>\n family.trim().replace(/^([\"'])(.*)\\1$/u, '$2'),\n )\n\n return families.every((family) => family !== '' && !family.includes('('))\n ? families\n : undefined\n}\n\nfunction parseFontWeight(value: string): number | undefined {\n const keyword = FONT_WEIGHT_KEYWORDS[value]\n\n if (keyword !== undefined) {\n return keyword\n }\n\n if (!/^\\d+(\\.\\d+)?$/u.test(value)) {\n return undefined\n }\n\n const weight = Number(value)\n\n return weight >= 1 && weight <= 1000 ? weight : undefined\n}\n\nfunction parseLength(value: string): number | undefined {\n const match = new RegExp(`^(${NUMBER})(px)?$`, 'u').exec(value)\n\n if (match === null) {\n return undefined\n }\n\n const length = Number(match[1])\n\n // CSS takes a bare number as a length only when it is zero.\n return match[2] !== 'px' && length !== 0 ? undefined : length\n}\n\nfunction parseOpacity(value: string): number | undefined {\n const match = new RegExp(`^(${NUMBER})(%)?$`, 'u').exec(value)\n\n if (match === null) {\n return undefined\n }\n\n const opacity = Number(match[1]) / (match[2] === '%' ? 100 : 1)\n\n // CSS clamps an opacity to the unit interval rather than rejecting it.\n return Math.min(Math.max(opacity, 0), 1)\n}\n\nfunction parseShadow(value: string): string | undefined {\n return value === '' ? undefined : value\n}\n\n/** Splits a value at its top-level commas, leaving any inside parentheses. */\nfunction splitTopLevel(value: string): string[] {\n const parts: string[] = []\n let depth = 0\n let quote: string | undefined\n let start = 0\n\n for (let index = 0; index < value.length; index++) {\n const character = value[index]\n\n if (quote !== undefined) {\n quote = character === quote ? undefined : quote\n } else if (character === '\"' || character === \"'\") {\n quote = character\n } else if (character === '(') {\n depth++\n } else if (character === ')') {\n depth--\n } else if (character === ',' && depth === 0) {\n parts.push(value.slice(start, index))\n start = index + 1\n }\n }\n\n parts.push(value.slice(start))\n\n return parts\n}\n\nfunction typographyKindOf(rest: string): Kind | undefined {\n if (rest.startsWith('font-family-') || rest.endsWith('-font')) {\n return 'fontFamily'\n }\n\n if (rest.startsWith('weight-') || rest.endsWith('-weight')) {\n return 'fontWeight'\n }\n\n const measured = ['-line-height', '-size', '-tracking'].some((suffix) =>\n rest.endsWith(suffix),\n )\n\n return measured ? 'length' : undefined\n}\n\n// How each kind of value is read, and what a value that cannot be read is\n// reported as.\nconst PARSERS: Readonly<\n Record<Kind, readonly [(value: string) => undefined | Value, string]>\n> = {\n color: [parseColor, 'is not a colour React Native can draw'],\n duration: [parseDuration, 'is not a duration in ms or s'],\n easing: [parseEasing, 'is not a cubic-bezier() curve or an easing keyword'],\n fontFamily: [parseFontFamily, 'is not a font family list'],\n fontWeight: [parseFontWeight, 'is not a font weight from 1 to 1000'],\n length: [parseLength, 'is not a length in px'],\n opacity: [parseOpacity, 'is not a number or a percentage'],\n shadow: [parseShadow, 'is empty'],\n}\n\n/** The properties a theme declares, leaving out any it lists as undefined. */\nfunction declarations(properties: ThemeProperties): Map<string, string> {\n return new Map(\n Object.entries(properties).filter(\n (entry): entry is [string, string] => entry[1] !== undefined,\n ),\n )\n}\n\n/**\n * Turns a theme in CSS syntax into the values React Native styles take.\n *\n * `defaults` is the whole contract, and `overrides` replace any of it, as a\n * consumer's declarations replace the library's on web. A `var()` reference\n * resolves against both, with its fallback where the property it names has no\n * usable value, so a role pointing at a family or a weight follows an override\n * of that family or weight as it does in a browser.\n *\n * A value native cannot use, such as a `calc()` or a `color-mix()`, leaves its\n * property at the default instead of dropping it, and a property the defaults\n * do not declare is ignored. Each is listed in `problems` by name, for the\n * caller to report.\n */\nfunction resolveTheme(\n defaults: ThemeProperties,\n overrides: ThemeProperties = {},\n): { problems: readonly ThemeProblem[]; theme: ResolvedGroups } {\n const declared = declarations(defaults)\n const replaced = declarations(overrides)\n const problems: ThemeProblem[] = []\n const settled = new Map<string, null | Settled>()\n const settling: string[] = []\n const cyclic = new Set<string>()\n\n function substitute(value: string): string | { reason: string } {\n const start = value.indexOf('var(')\n\n if (start === -1) {\n return value\n }\n\n const end = closingParenthesis(value, start + 'var('.length)\n\n if (end === -1) {\n return { reason: 'has a var() that is never closed' }\n }\n\n const [name, ...rest] = splitTopLevel(\n value.slice(start + 'var('.length, end),\n )\n const property = name.trim()\n const fallback = rest.length === 0 ? undefined : rest.join(',').trim()\n const referenced = declared.has(property) ? settle(property) : null\n\n let replacement: string | { reason: string }\n\n if (referenced !== null) {\n replacement = referenced.raw\n } else if (fallback === undefined) {\n replacement = {\n reason: `refers to ${property}, which has no usable value`,\n }\n } else {\n replacement = substitute(fallback)\n }\n\n if (typeof replacement !== 'string') {\n return replacement\n }\n\n return substitute(\n `${value.slice(0, start)}${replacement}${value.slice(end + 1)}`,\n )\n }\n\n function evaluate(kind: Kind, value: string): Attempt {\n const raw = substitute(value.trim())\n\n if (typeof raw !== 'string') {\n return raw\n }\n\n const unsupported = UNSUPPORTED_FUNCTION.exec(raw)\n\n if (unsupported !== null) {\n return {\n reason: `uses ${unsupported[1]}(), which native cannot evaluate`,\n }\n }\n\n const [read, reason] = PARSERS[kind]\n const parsed = read(raw)\n\n return parsed === undefined ? { reason } : { raw, value: parsed }\n }\n\n /** Evaluates one declaration, listing it as a problem if it fails. */\n function attempt(\n property: string,\n kind: Kind,\n value: string | undefined,\n ): null | Settled {\n if (value === undefined) {\n return null\n }\n\n const result = evaluate(kind, value)\n\n if ('reason' in result) {\n problems.push({ property, reason: result.reason, value })\n\n return null\n }\n\n return result\n }\n\n function settle(property: string): null | Settled {\n const known = settled.get(property)\n\n if (known !== undefined) {\n return known\n }\n\n const classified = classify(property)\n\n if (classified === undefined) {\n return null\n }\n\n // A reference leading back to a property still being settled closes a\n // cycle, and every property on it is invalid, as in CSS. The defaults\n // hold no cycle, so the members fall back to theirs.\n const index = settling.indexOf(property)\n\n if (index !== -1) {\n for (const member of settling.slice(index)) {\n cyclic.add(member)\n }\n\n return null\n }\n\n settling.push(property)\n\n const value = replaced.get(property)\n let result = attempt(property, classified.kind, value)\n\n if (result !== null && value !== undefined && cyclic.has(property)) {\n problems.push({\n property,\n reason: 'refers back to itself through var()',\n value,\n })\n result = null\n }\n\n result ??= attempt(property, classified.kind, declared.get(property))\n\n settling.pop()\n settled.set(property, result)\n\n return result\n }\n\n const theme: Groups = {\n colors: {},\n motion: {},\n radii: {},\n shadows: {},\n sizing: {},\n spacing: {},\n stateLayerOpacity: {},\n typography: {},\n }\n\n for (const [property, value] of declared) {\n const classified = classify(property)\n\n if (classified === undefined) {\n problems.push({ property, reason: 'is not a Kanso UI token', value })\n\n continue\n }\n\n const result = settle(property)\n\n // classify() pairs every group with the kinds whose values it holds, which\n // is the one thing the type of a group's record cannot see.\n if (result !== null) {\n Object.assign(theme[classified.group], { [classified.key]: result.value })\n }\n }\n\n for (const [property, value] of replaced) {\n if (!declared.has(property)) {\n problems.push({ property, reason: 'is not a Kanso UI token', value })\n }\n }\n\n return { problems, theme }\n}\n\nexport type { Easing, ResolvedGroups, ThemeProblem, ThemeProperties }\nexport { parseLength, resolveTheme }\n"],"mappings":"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"}
|
package/package.json
CHANGED