-
Notifications
You must be signed in to change notification settings - Fork 281
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: Remove style-dictionary dependency from React Native package #5848
base: main
Are you sure you want to change the base?
Changes from all commits
dcf4aba
22f90fc
a8c46ae
0eae19c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
"@aws-amplify/ui-react-native": patch | ||
"@aws-amplify/ui": patch | ||
--- | ||
|
||
chore: Copy `style-dictionary` functions to ui package and export from there. Remove `style-dictionary` dependency from React Native package. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,8 +8,10 @@ const config: Config = { | |
'!<rootDir>/src/index.ts', | ||
// ignore internal `debugUtils` from coverage thresholds | ||
'!<rootDir>/**/debugUtils.ts', | ||
// ignore coverage for style-dictionary type declaration file | ||
'!<rootDir>/src/theme/types/style-dictionary.d.ts', | ||
// ignore coverage for copied style-dictionary functions | ||
'!<rootDir>/src/theme/createTheme/resolveObject.ts', | ||
'!<rootDir>/src/utils/references.ts', | ||
'!<rootDir>/src/utils/groupMessages.ts', | ||
Comment on lines
+12
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why would we ignore testing this code? By migrating it in to our code base we are now liable for it |
||
], | ||
coverageThreshold: { | ||
global: { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
// Internal Style Dictionary methods | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Copied from |
||
// copied from amzn/style-dictionary with the owner's permission | ||
import { | ||
cloneDeep, | ||
createReferenceRegex, | ||
getName, | ||
getPathFromName, | ||
GroupMessages, | ||
has, | ||
resolveReference, | ||
usesReference, | ||
} from '../../utils'; | ||
|
||
const PROPERTY_REFERENCE_WARNINGS = | ||
GroupMessages.GROUP.PropertyReferenceWarnings; | ||
|
||
let current_context = []; // To maintain the context to be able to test for circular definitions | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Singletons scare me, does this need to be one? Same comment for all module scoped data structures |
||
const defaults = { | ||
ignoreKeys: ['original'], | ||
ignorePaths: [], | ||
}; | ||
let updated_object, regex, options; | ||
|
||
export function resolveObject<T>(object: Record<string, any>): T { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only change to this file is adding the generic type |
||
options = Object.assign({}, defaults); | ||
|
||
updated_object = cloneDeep(object); // This object will be edited | ||
|
||
regex = createReferenceRegex(options); | ||
|
||
if (typeof object === 'object') { | ||
current_context = []; | ||
return traverseObj(updated_object) as T; | ||
} else { | ||
throw new Error('Please pass an object in'); | ||
} | ||
} | ||
|
||
function traverseObj<T>(obj): T { | ||
let key; | ||
|
||
for (key in obj) { | ||
if (!has(obj, key)) { | ||
continue; | ||
} | ||
|
||
// We want to check for ignoredKeys, this is to | ||
// skip over attributes that should not be | ||
// mutated, like a copy of the original property. | ||
if (options.ignoreKeys && options.ignoreKeys.indexOf(key) !== -1) { | ||
continue; | ||
} | ||
|
||
current_context.push(key); | ||
if (typeof obj[key] === 'object') { | ||
traverseObj(obj[key]); | ||
} else { | ||
if (typeof obj[key] === 'string' && obj[key].indexOf('{') > -1) { | ||
obj[key] = compile_value(obj[key], [getName(current_context)]); | ||
} | ||
} | ||
current_context.pop(); | ||
} | ||
|
||
return obj as T; | ||
} | ||
|
||
let foundCirc = {}; | ||
function compile_value(value, stack) { | ||
let to_ret = value, | ||
ref; | ||
|
||
// Replace the reference inline, but don't replace the whole string because | ||
// references can be part of the value such as "1px solid {color.border.light}" | ||
value.replace(regex, function (match, variable) { | ||
variable = variable.trim(); | ||
|
||
// Find what the value is referencing | ||
const pathName = getPathFromName(variable, options); | ||
const context = getName(current_context, options); | ||
const refHasValue = pathName[pathName.length - 1] === 'value'; | ||
|
||
if (refHasValue && options.ignorePaths.indexOf(variable) !== -1) { | ||
return value; | ||
} else if ( | ||
!refHasValue && | ||
options.ignorePaths.indexOf(`${variable}.value`) !== -1 | ||
) { | ||
return value; | ||
} | ||
|
||
stack.push(variable); | ||
|
||
ref = resolveReference(pathName, updated_object); | ||
|
||
// If the reference doesn't end in 'value' | ||
// and | ||
// the reference points to someplace that has a `value` attribute | ||
// we should take the '.value' of the reference | ||
// per the W3C draft spec where references do not have .value | ||
// https://design-tokens.github.io/community-group/format/#aliases-references | ||
if (!refHasValue && ref && has(ref, 'value')) { | ||
ref = ref.value; | ||
} | ||
|
||
if (typeof ref !== 'undefined') { | ||
if (typeof ref === 'string' || typeof ref === 'number') { | ||
to_ret = value.replace(match, ref); | ||
|
||
// Recursive, therefore we can compute multi-layer variables like a = b, b = c, eventually a = c | ||
if (usesReference(to_ret, regex)) { | ||
var reference = to_ret.slice(1, -1); | ||
|
||
// Compare to found circular references | ||
if (has(foundCirc, reference)) { | ||
// If the current reference is a member of a circular reference, do nothing | ||
} else if (stack.indexOf(reference) !== -1) { | ||
// If the current stack already contains the current reference, we found a new circular reference | ||
// chop down only the circular part, save it to our circular reference info, and spit out an error | ||
|
||
// Get the position of the existing reference in the stack | ||
var stackIndexReference = stack.indexOf(reference); | ||
|
||
// Get the portion of the stack that starts at the circular reference and brings you through until the end | ||
var circStack = stack.slice(stackIndexReference); | ||
|
||
// For all the references in this list, add them to the list of references that end up in a circular reference | ||
circStack.forEach(function (key) { | ||
foundCirc[key] = true; | ||
}); | ||
|
||
// Add our found circular reference to the end of the cycle | ||
circStack.push(reference); | ||
|
||
// Add circ reference info to our list of warning messages | ||
GroupMessages.add( | ||
PROPERTY_REFERENCE_WARNINGS, | ||
'Circular definition cycle: ' + circStack.join(', ') | ||
); | ||
} else { | ||
to_ret = compile_value(to_ret, stack); | ||
} | ||
} | ||
// if evaluated value is a number and equal to the reference, we want to keep the type | ||
if (typeof ref === 'number' && ref.toString() === to_ret) { | ||
to_ret = ref; | ||
} | ||
} else { | ||
// if evaluated value is not a string or number, we want to keep the type | ||
to_ret = ref; | ||
} | ||
} else { | ||
GroupMessages.add( | ||
PROPERTY_REFERENCE_WARNINGS, | ||
"Reference doesn't exist: " + | ||
context + | ||
' tries to reference ' + | ||
variable + | ||
', which is not defined' | ||
); | ||
to_ret = ref; | ||
} | ||
stack.pop(variable); | ||
|
||
return to_ret; | ||
}); | ||
|
||
return to_ret; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!<rootDir>/src/theme/types/style-dictionary.d.ts
does not exist anymore