@trackunit/react-components 3.8.1 → 3.8.2-alpha-775ca1816d6.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/index.cjs.js +321 -801
- package/index.esm.js +322 -800
- package/migrations/entry.js.map +1 -0
- package/migrations/utils/jsx-utils.js.map +1 -0
- package/migrations/v2-0-0/breadcrumb-remove-deprecated-props.js.map +1 -0
- package/migrations/v2-0-0/cardheader-onclickclose-to-actions.js.map +1 -0
- package/migrations/v2-0-0/iconbutton-add-required-name.js.map +1 -0
- package/migrations/v2-0-0/kpi-tooltiplabel-to-wrapper.js.map +1 -0
- package/migrations/v2-0-0/notice-tooltiplabel-to-wrapper.js.map +1 -0
- package/migrations/v2-0-0/pagination-add-required-titles.js.map +1 -0
- package/migrations/v2-0-0/tag-add-removetaglabel.js.map +1 -0
- package/migrations/v2-0-0/togglegroup-remove-item-style.js.map +1 -0
- package/migrations/v3-0-0/copyabletext-to-text-copybutton.js.map +1 -0
- package/migrations/v3-0-0/menulist-rename-to-menucontent.js.map +1 -0
- package/package.json +6 -6
- package/src/hooks/persistence/usePersistedState.d.ts +31 -44
- package/src/hooks/persistence/useSearchParamSync.d.ts +7 -26
- package/src/hooks/persistence/useUrlParamSync.d.ts +71 -0
- package/src/index.d.ts +0 -1
- package/src/hooks/persistence/useHashParamSync.d.ts +0 -55
- package/src/hooks/persistence/useMigrateLegacySearchParam.d.ts +0 -62
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../../../libs/react/components/migrations/entry.ts"],"names":[],"mappings":"","sourcesContent":["// Migration entry point for @nx/js:tsc build target.\n// Migrations are registered in ../migrations.json and resolved by NX at runtime.\nexport {};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsx-utils.js","sourceRoot":"","sources":["../../../../../../libs/react/components/migrations/utils/jsx-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { logger, type Tree, visitNotIgnoredFiles } from \"@nx/devkit\";\nimport * as ts from \"typescript\";\n\nconst TSX_EXTENSIONS = [\".tsx\", \".jsx\"] as const;\nconst TS_EXTENSIONS = [\".ts\", \".tsx\", \".jsx\"] as const;\n\nconst isTsxFile = (filePath: string): boolean => TSX_EXTENSIONS.some(ext => filePath.endsWith(ext));\nconst isTsFile = (filePath: string): boolean => TS_EXTENSIONS.some(ext => filePath.endsWith(ext));\n\nconst isUnderNodeModules = (filePath: string): boolean =>\n filePath.includes(\"/node_modules/\") || filePath.startsWith(\"node_modules/\");\n\nconst isUnderDist = (filePath: string): boolean =>\n filePath.includes(\"/dist/\") || filePath.startsWith(\"dist/\") || filePath.includes(\"/.nx/\");\n\n/**\n * Visits every `.tsx`/`.jsx` file under the workspace root and invokes the\n * callback with the file path and its current contents. Files that don't\n * include the marker substring are skipped, which makes large workspaces\n * cheap to scan.\n */\nexport const visitTsxFiles = (\n tree: Tree,\n marker: string,\n callback: (filePath: string, content: string) => string | null | undefined\n): number => {\n let touched = 0;\n visitNotIgnoredFiles(tree, \"/\", filePath => {\n if (!isTsxFile(filePath)) return;\n if (isUnderNodeModules(filePath) || isUnderDist(filePath)) return;\n const content = tree.read(filePath, \"utf-8\");\n if (content === null) return;\n if (!content.includes(marker)) return;\n const updated = callback(filePath, content);\n if (updated !== null && updated !== undefined && updated !== content) {\n tree.write(filePath, updated);\n touched += 1;\n }\n });\n return touched;\n};\n\n/**\n * Same as {@link visitTsxFiles} but also includes plain `.ts` files. Use this\n * when the codemod also rewrites non-JSX files such as helpers or hooks.\n */\nexport const visitTsFiles = (\n tree: Tree,\n marker: string,\n callback: (filePath: string, content: string) => string | null | undefined\n): number => {\n let touched = 0;\n visitNotIgnoredFiles(tree, \"/\", filePath => {\n if (!isTsFile(filePath)) return;\n if (isUnderNodeModules(filePath) || isUnderDist(filePath)) return;\n const content = tree.read(filePath, \"utf-8\");\n if (content === null) return;\n if (!content.includes(marker)) return;\n const updated = callback(filePath, content);\n if (updated !== null && updated !== undefined && updated !== content) {\n tree.write(filePath, updated);\n touched += 1;\n }\n });\n return touched;\n};\n\n/**\n * Mapping of imported component aliases to their original names for a given\n * package. For `import { IconButton as Btn } from \"@trackunit/react-components\"`\n * this returns `{ Btn: \"IconButton\" }`.\n *\n * Returns `null` when the file imports nothing from the package, which lets\n * callers short-circuit before parsing JSX.\n */\nexport const getImportedAliases = (sourceFile: ts.SourceFile, packageName: string): Record<string, string> | null => {\n const result: Record<string, string> = {};\n let found = false;\n\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) continue;\n const moduleSpecifier = stmt.moduleSpecifier;\n if (!ts.isStringLiteral(moduleSpecifier)) continue;\n if (moduleSpecifier.text !== packageName) continue;\n\n const namedBindings = stmt.importClause?.namedBindings;\n if (namedBindings === undefined || !ts.isNamedImports(namedBindings)) continue;\n\n for (const element of namedBindings.elements) {\n const localName = element.name.text;\n const importedName = element.propertyName?.text ?? localName;\n result[localName] = importedName;\n found = true;\n }\n }\n\n return found ? result : null;\n};\n\n/**\n * Returns the local alias used in this file for `originalName` when imported\n * from `packageName`, or `null` if the component is not imported.\n */\nexport const getLocalAliasFor = (\n sourceFile: ts.SourceFile,\n packageName: string,\n originalName: string\n): string | null => {\n const aliases = getImportedAliases(sourceFile, packageName);\n if (aliases === null) return null;\n for (const [local, original] of Object.entries(aliases)) {\n if (original === originalName) return local;\n }\n return null;\n};\n\nexport type JsxElementMatch = {\n /** The opening JSX element (the one carrying the attributes). */\n openingElement: ts.JsxOpeningElement | ts.JsxSelfClosingElement;\n /** The full element including children, or the self-closing element. */\n element: ts.JsxElement | ts.JsxSelfClosingElement;\n};\n\n/**\n * Finds every JSX element whose tag name resolves to one of `tagNames`\n * (typically the local aliases returned by {@link getImportedAliases}).\n *\n * The result intentionally includes both opening and full elements so callers\n * can manipulate attributes (via `openingElement`) or wrap/replace the whole\n * element (via `element`).\n */\nexport const findJsxElements = (\n sourceFile: ts.SourceFile,\n tagNames: ReadonlyArray<string>\n): ReadonlyArray<JsxElementMatch> => {\n const matches: Array<JsxElementMatch> = [];\n const tagSet = new Set(tagNames);\n\n const visit = (node: ts.Node): void => {\n if (ts.isJsxSelfClosingElement(node)) {\n if (ts.isIdentifier(node.tagName) && tagSet.has(node.tagName.text)) {\n matches.push({ openingElement: node, element: node });\n }\n } else if (ts.isJsxElement(node)) {\n const opening = node.openingElement;\n if (ts.isIdentifier(opening.tagName) && tagSet.has(opening.tagName.text)) {\n matches.push({ openingElement: opening, element: node });\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return matches;\n};\n\n/**\n * Looks up a named JSX attribute on the opening element. Returns `null` when\n * the attribute is missing or part of a spread attribute (which we cannot\n * statically inspect).\n */\nexport const findJsxAttribute = (\n openingElement: ts.JsxOpeningElement | ts.JsxSelfClosingElement,\n attributeName: string\n): ts.JsxAttribute | null => {\n for (const attr of openingElement.attributes.properties) {\n if (!ts.isJsxAttribute(attr)) continue;\n if (!ts.isIdentifier(attr.name)) continue;\n if (attr.name.text === attributeName) return attr;\n }\n return null;\n};\n\n/**\n * `true` when the element forwards a spread expression such as `{...rest}`,\n * which means we can't be sure which attributes are actually set.\n */\nexport const hasSpreadAttribute = (openingElement: ts.JsxOpeningElement | ts.JsxSelfClosingElement): boolean => {\n return openingElement.attributes.properties.some(prop => ts.isJsxSpreadAttribute(prop));\n};\n\n/**\n * Parses the file as TSX so JSX is recognised. We do not need a full program\n * here; tsquery's `ast` helper produces a script-kind source file which loses\n * JSX context, so we go through `createSourceFile` directly.\n */\nexport const parseTsx = (content: string, fileName = \"file.tsx\"): ts.SourceFile =>\n ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);\n\n/**\n * Helper for codemods to log a one-line summary at the end of a run. Migration\n * runners aggregate logs per migration, so this keeps output focused.\n */\nexport const logSummary = (migrationName: string, touched: number, manualReviewNeeded?: number): void => {\n if (touched === 0) {\n logger.info(` ${migrationName}: no files changed`);\n return;\n }\n const reviewSuffix =\n manualReviewNeeded !== undefined && manualReviewNeeded > 0\n ? ` (${manualReviewNeeded} location(s) need manual review)`\n : \"\";\n logger.info(` ${migrationName}: updated ${touched} file(s)${reviewSuffix}`);\n};\n\n/**\n * Inserts an attribute string immediately after the tag name (so the new\n * attribute appears first). Returns the resulting source content.\n *\n * The added attribute is rendered verbatim, so callers are responsible for\n * including the leading space (e.g. ` title=\"Close\"`).\n */\nexport const insertAttributeIntoOpeningTag = (\n content: string,\n openingElement: ts.JsxOpeningElement | ts.JsxSelfClosingElement,\n attributeText: string\n): string => {\n const tagName = openingElement.tagName;\n const insertPos = tagName.getEnd();\n return `${content.slice(0, insertPos)} ${attributeText}${content.slice(insertPos)}`;\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breadcrumb-remove-deprecated-props.js","sourceRoot":"","sources":["../../../../../../libs/react/components/migrations/v2-0-0/breadcrumb-remove-deprecated-props.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Tree, logger } from \"@nx/devkit\";\nimport {\n findJsxAttribute,\n findJsxElements,\n getImportedAliases,\n logSummary,\n parseTsx,\n visitTsxFiles,\n} from \"../utils/jsx-utils\";\n\nconst PACKAGE_NAME = \"@trackunit/react-components\";\nconst COMPONENT_NAMES = [\"Breadcrumb\", \"BreadcrumbContainer\", \"BreadcrumbForMediumScreen\"] as const;\nconst PROPS_TO_REMOVE = [\"backButtonTitle\", \"expandCollapsedItemsTitle\"] as const;\n\nconst stripDeprecatedProps = (filePath: string, content: string): string | null => {\n const sourceFile = parseTsx(content, filePath);\n\n const aliases = getImportedAliases(sourceFile, PACKAGE_NAME);\n if (aliases === null) return null;\n\n const localTagNames: Array<string> = [];\n for (const [local, original] of Object.entries(aliases)) {\n if (COMPONENT_NAMES.some(name => name === original)) {\n localTagNames.push(local);\n }\n }\n if (localTagNames.length === 0) return null;\n\n const matches = findJsxElements(sourceFile, localTagNames);\n if (matches.length === 0) return null;\n\n // Collect every (start, end) range we want to delete. We process them in\n // reverse so earlier offsets stay valid while we splice.\n const ranges: Array<{ start: number; end: number }> = [];\n for (const { openingElement } of matches) {\n for (const propName of PROPS_TO_REMOVE) {\n const attr = findJsxAttribute(openingElement, propName);\n if (attr === null) continue;\n\n // Drop trailing whitespace + the attribute itself so we don't leave a\n // dangling space inside the opening tag. e.g. `<X foo=\"a\" bar=\"b\" />`\n // becomes `<X foo=\"a\" />` and `<X bar=\"b\" />` becomes `<X />`.\n let start = attr.getFullStart();\n const end = attr.getEnd();\n // getFullStart includes leading whitespace which is what we want.\n // Guard against negative ranges if multiple props collapse later.\n if (start < 0) start = attr.getStart();\n ranges.push({ start, end });\n }\n }\n\n if (ranges.length === 0) return null;\n\n ranges.sort((a, b) => b.start - a.start);\n\n let updated = content;\n for (const { start, end } of ranges) {\n updated = updated.slice(0, start) + updated.slice(end);\n }\n\n return updated;\n};\n\n/**\n * Removes the no-longer-supported `backButtonTitle` and\n * `expandCollapsedItemsTitle` props from `<Breadcrumb>`,\n * `<BreadcrumbContainer>`, and `<BreadcrumbForMediumScreen>`. Their accessible\n * names are now sourced from the `react-components` library translations.\n */\nexport const breadcrumbRemoveDeprecatedProps = (tree: Tree): void => {\n const touched = visitTsxFiles(tree, \"Breadcrumb\", stripDeprecatedProps);\n logSummary(\"breadcrumb-remove-deprecated-props\", touched);\n logger.info(\n \" Ensure the host application registers the @trackunit/react-components library translations so the back/expand buttons render localized labels.\"\n );\n};\n\nexport default breadcrumbRemoveDeprecatedProps;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cardheader-onclickclose-to-actions.js","sourceRoot":"","sources":["../../../../../../libs/react/components/migrations/v2-0-0/cardheader-onclickclose-to-actions.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Tree } from \"@nx/devkit\";\nimport * as ts from \"typescript\";\nimport {\n findJsxAttribute,\n findJsxElements,\n getImportedAliases,\n logSummary,\n parseTsx,\n visitTsxFiles,\n} from \"../utils/jsx-utils\";\n\nconst PACKAGE_NAME = \"@trackunit/react-components\";\nconst COMPONENT_NAME = \"CardHeader\";\n\nconst CLOSE_BUTTON_NAMES = [\"IconButton\", \"Icon\"] as const;\n\nconst renderCloseButton = (handlerExpr: string, iconAlias: string, iconButtonAlias: string): string =>\n `<${iconButtonAlias} icon={<${iconAlias} name=\"XMark\" size=\"small\" />} onClick={${handlerExpr}} title=\"Close\" variant=\"ghost-neutral\" />`;\n\nconst ensureNamedImport = (content: string, packageName: string, namesToAdd: ReadonlyArray<string>): string => {\n const sourceFile = parseTsx(content, \"source.tsx\");\n const aliases = getImportedAliases(sourceFile, packageName) ?? {};\n\n const missing = namesToAdd.filter(name => !Object.values(aliases).includes(name));\n if (missing.length === 0) return content;\n\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) continue;\n const moduleSpecifier = stmt.moduleSpecifier;\n if (!ts.isStringLiteral(moduleSpecifier) || moduleSpecifier.text !== packageName) continue;\n\n const namedBindings = stmt.importClause?.namedBindings;\n if (namedBindings === undefined || !ts.isNamedImports(namedBindings)) continue;\n\n const elementsText = namedBindings.elements.map(el => el.getText()).join(\", \");\n const merged = [elementsText, ...missing].join(\", \");\n const before = content.slice(0, namedBindings.getStart());\n const after = content.slice(namedBindings.getEnd());\n return `${before}{ ${merged} }${after}`;\n }\n\n // No existing import from the package; add a fresh line near the top.\n const importLine = `import { ${missing.join(\", \")} } from \"${packageName}\";\\n`;\n return importLine + content;\n};\n\nconst transformCardHeaderUsage = (filePath: string, content: string): string | null => {\n const sourceFile = parseTsx(content, filePath);\n\n const aliases = getImportedAliases(sourceFile, PACKAGE_NAME);\n if (aliases === null) return null;\n\n const cardHeaderAlias = Object.entries(aliases).find(([, name]) => name === COMPONENT_NAME)?.[0];\n if (cardHeaderAlias === undefined) return null;\n\n const matches = findJsxElements(sourceFile, [cardHeaderAlias]);\n if (matches.length === 0) return null;\n\n type Edit = { start: number; end: number; replacement: string };\n const edits: Array<Edit> = [];\n\n for (const { openingElement } of matches) {\n const onClickCloseAttr = findJsxAttribute(openingElement, \"onClickClose\");\n if (onClickCloseAttr === null) continue;\n\n const initializer = onClickCloseAttr.initializer;\n if (initializer === undefined) continue;\n\n let handlerExpr: string;\n if (ts.isJsxExpression(initializer) && initializer.expression !== undefined) {\n handlerExpr = initializer.expression.getText();\n } else if (ts.isStringLiteral(initializer)) {\n handlerExpr = `\"${initializer.text}\"`;\n } else {\n continue;\n }\n\n const actionsAttr = findJsxAttribute(openingElement, \"actions\");\n if (actionsAttr !== null) {\n // Don't try to merge with an existing actions prop; flag and skip.\n continue;\n }\n\n const replacement = `actions={${renderCloseButton(handlerExpr, \"Icon\", \"IconButton\")}}`;\n edits.push({\n start: onClickCloseAttr.getStart(),\n end: onClickCloseAttr.getEnd(),\n replacement,\n });\n }\n\n if (edits.length === 0) return null;\n\n edits.sort((a, b) => b.start - a.start);\n\n let updated = content;\n for (const { start, end, replacement } of edits) {\n updated = updated.slice(0, start) + replacement + updated.slice(end);\n }\n\n updated = ensureNamedImport(updated, PACKAGE_NAME, [...CLOSE_BUTTON_NAMES]);\n\n return updated;\n};\n\n/**\n * Replaces the removed `onClickClose` prop on `<CardHeader>` with the\n * equivalent action rendered through the `actions` slot using `IconButton` +\n * the `XMark` icon.\n *\n * Cards that already declared `actions` are skipped to avoid clobbering\n * existing markup.\n */\nexport const cardHeaderOnClickCloseToActions = (tree: Tree): void => {\n const touched = visitTsxFiles(tree, \"CardHeader\", transformCardHeaderUsage);\n logSummary(\"cardheader-onclickclose-to-actions\", touched);\n};\n\nexport default cardHeaderOnClickCloseToActions;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iconbutton-add-required-name.js","sourceRoot":"","sources":["../../../../../../libs/react/components/migrations/v2-0-0/iconbutton-add-required-name.ts"],"names":[],"mappings":";;;AAAA,uCAA+C;AAC/C,kDAQ4B;AAE5B,MAAM,YAAY,GAAG,6BAA6B,CAAC;AACnD,MAAM,cAAc,GAAG,YAAY,CAAC;AAEpC,MAAM,iBAAiB,GAAG,0CAA0C,CAAC;AAErE,MAAM,wBAAwB,GAAG,CAAC,QAAgB,EAAE,OAAe,EAAiB,EAAE;IACpF,MAAM,UAAU,GAAG,IAAA,oBAAQ,EAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAE/C,MAAM,OAAO,GAAG,IAAA,8BAAkB,EAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAC7D,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAElC,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5F,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAE1C,MAAM,OAAO,GAAG,IAAA,2BAAe,EAAC,UAAU,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAC1D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAGtC,MAAM,KAAK,GAAgB,EAAE,CAAC;IAE9B,KAAK,MAAM,EAAE,cAAc,EAAE,IAAI,OAAO,EAAE,CAAC;QACzC,IAAI,IAAA,8BAAkB,EAAC,cAAc,CAAC;YAAE,SAAS;QAEjD,MAAM,QAAQ,GAAG,IAAA,4BAAgB,EAAC,cAAc,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;QACpE,MAAM,YAAY,GAAG,IAAA,4BAAgB,EAAC,cAAc,EAAE,WAAW,CAAC,KAAK,IAAI,CAAC;QAC5E,IAAI,QAAQ,IAAI,YAAY;YAAE,SAAS;QAEvC,KAAK,CAAC,IAAI,CAAC;YACT,MAAM,EAAE,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE;YACvC,IAAI,EAAE,WAAW,iBAAiB,GAAG;SACtC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAExE,IAAI,OAAO,GAAG,OAAO,CAAC;IACtB,KAAK,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,KAAK,EAAE,CAAC;QACrC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF;;;;;;;GAOG;AACI,MAAM,yBAAyB,GAAG,CAAC,IAAU,EAAQ,EAAE;IAC5D,MAAM,OAAO,GAAG,IAAA,yBAAa,EAAC,IAAI,EAAE,YAAY,EAAE,wBAAwB,CAAC,CAAC;IAC5E,IAAA,sBAAU,EAAC,8BAA8B,EAAE,OAAO,CAAC,CAAC;IACpD,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,eAAM,CAAC,IAAI,CACT,8BAA8B,iBAAiB,6EAA6E,CAC7H,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AARW,QAAA,yBAAyB,6BAQpC;AAEF,kBAAe,iCAAyB,CAAC","sourcesContent":["import { type Tree, logger } from \"@nx/devkit\";\nimport {\n findJsxAttribute,\n findJsxElements,\n getImportedAliases,\n hasSpreadAttribute,\n logSummary,\n parseTsx,\n visitTsxFiles,\n} from \"../utils/jsx-utils\";\n\nconst PACKAGE_NAME = \"@trackunit/react-components\";\nconst COMPONENT_NAME = \"IconButton\";\n\nconst PLACEHOLDER_TITLE = \"TODO Replace with localized button title\";\n\nconst transformIconButtonUsage = (filePath: string, content: string): string | null => {\n const sourceFile = parseTsx(content, filePath);\n\n const aliases = getImportedAliases(sourceFile, PACKAGE_NAME);\n if (aliases === null) return null;\n\n const localAlias = Object.entries(aliases).find(([, name]) => name === COMPONENT_NAME)?.[0];\n if (localAlias === undefined) return null;\n\n const matches = findJsxElements(sourceFile, [localAlias]);\n if (matches.length === 0) return null;\n\n type Edit = { offset: number; text: string };\n const edits: Array<Edit> = [];\n\n for (const { openingElement } of matches) {\n if (hasSpreadAttribute(openingElement)) continue;\n\n const hasTitle = findJsxAttribute(openingElement, \"title\") !== null;\n const hasAriaLabel = findJsxAttribute(openingElement, \"ariaLabel\") !== null;\n if (hasTitle || hasAriaLabel) continue;\n\n edits.push({\n offset: openingElement.tagName.getEnd(),\n text: ` title=\"${PLACEHOLDER_TITLE}\"`,\n });\n }\n\n if (edits.length === 0) return null;\n\n edits.sort((a, b) => (a.offset === b.offset ? 0 : b.offset - a.offset));\n\n let updated = content;\n for (const { offset, text } of edits) {\n updated = updated.slice(0, offset) + text + updated.slice(offset);\n }\n return updated;\n};\n\n/**\n * Adds a placeholder `title` to `<IconButton>` usages that don't already\n * provide either `title` or `ariaLabel`. The new accessible name requirement\n * means every icon button must carry one of these two props.\n *\n * Usages with a spread attribute (e.g. `<IconButton {...props} />`) are\n * skipped because we cannot tell whether `title`/`ariaLabel` is forwarded.\n */\nexport const iconButtonAddRequiredName = (tree: Tree): void => {\n const touched = visitTsxFiles(tree, \"IconButton\", transformIconButtonUsage);\n logSummary(\"iconbutton-add-required-name\", touched);\n if (touched > 0) {\n logger.info(\n ` Replace the placeholder \"${PLACEHOLDER_TITLE}\" titles with localized strings (or switch to ariaLabel where appropriate).`\n );\n }\n};\n\nexport default iconButtonAddRequiredName;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kpi-tooltiplabel-to-wrapper.js","sourceRoot":"","sources":["../../../../../../libs/react/components/migrations/v2-0-0/kpi-tooltiplabel-to-wrapper.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Tree } from \"@nx/devkit\";\nimport * as ts from \"typescript\";\nimport {\n findJsxAttribute,\n findJsxElements,\n getImportedAliases,\n logSummary,\n parseTsx,\n visitTsxFiles,\n} from \"../utils/jsx-utils\";\n\nconst PACKAGE_NAME = \"@trackunit/react-components\";\nconst COMPONENT_NAME = \"KPI\";\n\nconst ensureTooltipImport = (content: string): string => {\n const sourceFile = parseTsx(content, \"source.tsx\");\n const aliases = getImportedAliases(sourceFile, PACKAGE_NAME);\n if (aliases !== null && Object.values(aliases).includes(\"Tooltip\")) return content;\n\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) continue;\n const moduleSpecifier = stmt.moduleSpecifier;\n if (!ts.isStringLiteral(moduleSpecifier) || moduleSpecifier.text !== PACKAGE_NAME) continue;\n\n const namedBindings = stmt.importClause?.namedBindings;\n if (namedBindings === undefined || !ts.isNamedImports(namedBindings)) continue;\n\n const elementsText = namedBindings.elements.map(el => el.getText()).join(\", \");\n const merged = `${elementsText}, Tooltip`;\n const before = content.slice(0, namedBindings.getStart());\n const after = content.slice(namedBindings.getEnd());\n return `${before}{ ${merged} }${after}`;\n }\n\n return `import { Tooltip } from \"${PACKAGE_NAME}\";\\n${content}`;\n};\n\nconst renderTooltipExpression = (label: string): string => label;\n\nconst transformKpiUsage = (filePath: string, content: string): string | null => {\n const sourceFile = parseTsx(content, filePath);\n\n const aliases = getImportedAliases(sourceFile, PACKAGE_NAME);\n if (aliases === null) return null;\n\n const localAlias = Object.entries(aliases).find(([, name]) => name === COMPONENT_NAME)?.[0];\n if (localAlias === undefined) return null;\n\n const matches = findJsxElements(sourceFile, [localAlias]);\n if (matches.length === 0) return null;\n\n type Edit = {\n elementStart: number;\n elementEnd: number;\n attrStart: number;\n attrEnd: number;\n label: string;\n elementText: string;\n };\n const edits: Array<Edit> = [];\n\n for (const { openingElement, element } of matches) {\n const tooltipLabelAttr = findJsxAttribute(openingElement, \"tooltipLabel\");\n if (tooltipLabelAttr === null) continue;\n\n const initializer = tooltipLabelAttr.initializer;\n if (initializer === undefined) continue;\n\n let label: string;\n if (ts.isStringLiteral(initializer)) {\n label = `\"${initializer.text}\"`;\n } else if (ts.isJsxExpression(initializer) && initializer.expression !== undefined) {\n label = `{${initializer.expression.getText()}}`;\n } else {\n continue;\n }\n\n edits.push({\n elementStart: element.getStart(),\n elementEnd: element.getEnd(),\n attrStart: tooltipLabelAttr.getFullStart(),\n attrEnd: tooltipLabelAttr.getEnd(),\n label,\n elementText: content.slice(element.getStart(), element.getEnd()),\n });\n }\n\n if (edits.length === 0) return null;\n\n edits.sort((a, b) => b.elementStart - a.elementStart);\n\n let updated = content;\n for (const edit of edits) {\n // Remove the tooltipLabel attribute first (it's inside the element).\n const elementWithoutAttr =\n edit.elementText.slice(0, edit.attrStart - edit.elementStart) +\n edit.elementText.slice(edit.attrEnd - edit.elementStart);\n const wrapped = `<Tooltip label=${renderTooltipExpression(edit.label)} placement=\"bottom\">${elementWithoutAttr}</Tooltip>`;\n updated = updated.slice(0, edit.elementStart) + wrapped + updated.slice(edit.elementEnd);\n }\n\n updated = ensureTooltipImport(updated);\n\n return updated;\n};\n\n/**\n * Replaces the removed `tooltipLabel` prop on `<KPI>` with an explicit\n * `<Tooltip>` wrapper. The `KPICard` variant is intentionally not touched\n * because it still owns its own `tooltipLabel` prop.\n */\nexport const kpiTooltipLabelToWrapper = (tree: Tree): void => {\n const touched = visitTsxFiles(tree, \"tooltipLabel\", transformKpiUsage);\n logSummary(\"kpi-tooltiplabel-to-wrapper\", touched);\n};\n\nexport default kpiTooltipLabelToWrapper;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notice-tooltiplabel-to-wrapper.js","sourceRoot":"","sources":["../../../../../../libs/react/components/migrations/v2-0-0/notice-tooltiplabel-to-wrapper.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Tree } from \"@nx/devkit\";\nimport * as ts from \"typescript\";\nimport {\n findJsxAttribute,\n findJsxElements,\n getImportedAliases,\n logSummary,\n parseTsx,\n visitTsxFiles,\n} from \"../utils/jsx-utils\";\n\nconst PACKAGE_NAME = \"@trackunit/react-components\";\nconst COMPONENT_NAME = \"Notice\";\n\nconst ensureTooltipImport = (content: string): string => {\n const sourceFile = parseTsx(content, \"source.tsx\");\n const aliases = getImportedAliases(sourceFile, PACKAGE_NAME);\n if (aliases !== null && Object.values(aliases).includes(\"Tooltip\")) return content;\n\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) continue;\n const moduleSpecifier = stmt.moduleSpecifier;\n if (!ts.isStringLiteral(moduleSpecifier) || moduleSpecifier.text !== PACKAGE_NAME) continue;\n\n const namedBindings = stmt.importClause?.namedBindings;\n if (namedBindings === undefined || !ts.isNamedImports(namedBindings)) continue;\n\n const elementsText = namedBindings.elements.map(el => el.getText()).join(\", \");\n const merged = `${elementsText}, Tooltip`;\n const before = content.slice(0, namedBindings.getStart());\n const after = content.slice(namedBindings.getEnd());\n return `${before}{ ${merged} }${after}`;\n }\n\n return `import { Tooltip } from \"${PACKAGE_NAME}\";\\n${content}`;\n};\n\nconst transformNoticeUsage = (filePath: string, content: string): string | null => {\n const sourceFile = parseTsx(content, filePath);\n\n const aliases = getImportedAliases(sourceFile, PACKAGE_NAME);\n if (aliases === null) return null;\n\n const localAlias = Object.entries(aliases).find(([, name]) => name === COMPONENT_NAME)?.[0];\n if (localAlias === undefined) return null;\n\n const matches = findJsxElements(sourceFile, [localAlias]);\n if (matches.length === 0) return null;\n\n type Edit = {\n elementStart: number;\n elementEnd: number;\n elementText: string;\n label: string | null;\n attrEdits: Array<{ start: number; end: number }>;\n };\n const edits: Array<Edit> = [];\n\n for (const { openingElement, element } of matches) {\n const tooltipLabelAttr = findJsxAttribute(openingElement, \"tooltipLabel\");\n const withTooltipAttr = findJsxAttribute(openingElement, \"withTooltip\");\n if (tooltipLabelAttr === null && withTooltipAttr === null) continue;\n\n let label: string | null = null;\n if (tooltipLabelAttr !== null) {\n const initializer = tooltipLabelAttr.initializer;\n if (initializer !== undefined) {\n if (ts.isStringLiteral(initializer)) {\n label = `\"${initializer.text}\"`;\n } else if (ts.isJsxExpression(initializer) && initializer.expression !== undefined) {\n label = `{${initializer.expression.getText()}}`;\n }\n }\n }\n\n const attrEdits: Array<{ start: number; end: number }> = [];\n for (const attr of [tooltipLabelAttr, withTooltipAttr]) {\n if (attr === null) continue;\n attrEdits.push({ start: attr.getFullStart(), end: attr.getEnd() });\n }\n\n edits.push({\n elementStart: element.getStart(),\n elementEnd: element.getEnd(),\n elementText: content.slice(element.getStart(), element.getEnd()),\n label,\n attrEdits,\n });\n }\n\n if (edits.length === 0) return null;\n\n edits.sort((a, b) => b.elementStart - a.elementStart);\n\n let updated = content;\n let needsTooltipImport = false;\n\n for (const edit of edits) {\n // Remove the tooltipLabel/withTooltip attributes from the element first.\n let elementWithoutAttrs = edit.elementText;\n const sortedAttrEdits = [...edit.attrEdits].sort((a, b) => b.start - a.start);\n for (const { start, end } of sortedAttrEdits) {\n elementWithoutAttrs =\n elementWithoutAttrs.slice(0, start - edit.elementStart) + elementWithoutAttrs.slice(end - edit.elementStart);\n }\n\n if (edit.label !== null) {\n const wrapped = `<Tooltip label=${edit.label} placement=\"bottom\">${elementWithoutAttrs}</Tooltip>`;\n updated = updated.slice(0, edit.elementStart) + wrapped + updated.slice(edit.elementEnd);\n needsTooltipImport = true;\n } else {\n // No label to forward (e.g. only `withTooltip`); just strip the props.\n updated = updated.slice(0, edit.elementStart) + elementWithoutAttrs + updated.slice(edit.elementEnd);\n }\n }\n\n if (needsTooltipImport) {\n updated = ensureTooltipImport(updated);\n }\n\n return updated;\n};\n\n/**\n * Removes the deprecated `withTooltip`/`tooltipLabel` props from `<Notice>`\n * usages. When a label is present the element is wrapped in `<Tooltip>` to\n * preserve hover behaviour; when only `withTooltip` was set the props are\n * dropped because they had no remaining effect.\n */\nexport const noticeTooltipLabelToWrapper = (tree: Tree): void => {\n const touched = visitTsxFiles(tree, \"Notice\", transformNoticeUsage);\n logSummary(\"notice-tooltiplabel-to-wrapper\", touched);\n};\n\nexport default noticeTooltipLabelToWrapper;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination-add-required-titles.js","sourceRoot":"","sources":["../../../../../../libs/react/components/migrations/v2-0-0/pagination-add-required-titles.ts"],"names":[],"mappings":";;;AAAA,uCAA+C;AAC/C,kDAQ4B;AAE5B,MAAM,YAAY,GAAG,6BAA6B,CAAC;AACnD,MAAM,cAAc,GAAG,YAAY,CAAC;AAEpC,MAAM,YAAY,GAA2B;IAC3C,iBAAiB,EAAE,eAAe;IAClC,aAAa,EAAE,WAAW;CAC3B,CAAC;AAEF,MAAM,wBAAwB,GAAG,CAAC,QAAgB,EAAE,OAAe,EAAiB,EAAE;IACpF,MAAM,UAAU,GAAG,IAAA,oBAAQ,EAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAE/C,MAAM,OAAO,GAAG,IAAA,8BAAkB,EAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAC7D,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAElC,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5F,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAE1C,MAAM,OAAO,GAAG,IAAA,2BAAe,EAAC,UAAU,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAC1D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAGtC,MAAM,KAAK,GAAgB,EAAE,CAAC;IAE9B,KAAK,MAAM,EAAE,cAAc,EAAE,IAAI,OAAO,EAAE,CAAC;QACzC,IAAI,IAAA,8BAAkB,EAAC,cAAc,CAAC;YAAE,SAAS;QAEjD,KAAK,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YACnE,IAAI,IAAA,4BAAgB,EAAC,cAAc,EAAE,QAAQ,CAAC,KAAK,IAAI;gBAAE,SAAS;YAClE,KAAK,CAAC,IAAI,CAAC;gBACT,MAAM,EAAE,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE;gBACvC,IAAI,EAAE,IAAI,QAAQ,KAAK,WAAW,GAAG;aACtC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,yEAAyE;IACzE,kEAAkE;IAClE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAExE,IAAI,OAAO,GAAG,OAAO,CAAC;IACtB,KAAK,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,KAAK,EAAE,CAAC;QACrC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF;;;;;;;;GAQG;AACI,MAAM,2BAA2B,GAAG,CAAC,IAAU,EAAQ,EAAE;IAC9D,MAAM,OAAO,GAAG,IAAA,yBAAa,EAAC,IAAI,EAAE,YAAY,EAAE,wBAAwB,CAAC,CAAC;IAC5E,IAAA,sBAAU,EAAC,gCAAgC,EAAE,OAAO,CAAC,CAAC;IACtD,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,eAAM,CAAC,IAAI,CAAC,+FAA+F,CAAC,CAAC;IAC/G,CAAC;AACH,CAAC,CAAC;AANW,QAAA,2BAA2B,+BAMtC;AAEF,kBAAe,mCAA2B,CAAC","sourcesContent":["import { type Tree, logger } from \"@nx/devkit\";\nimport {\n findJsxAttribute,\n findJsxElements,\n getImportedAliases,\n hasSpreadAttribute,\n logSummary,\n parseTsx,\n visitTsxFiles,\n} from \"../utils/jsx-utils\";\n\nconst PACKAGE_NAME = \"@trackunit/react-components\";\nconst COMPONENT_NAME = \"Pagination\";\n\nconst PLACEHOLDERS: Record<string, string> = {\n previousPageTitle: \"Previous page\",\n nextPageTitle: \"Next page\",\n};\n\nconst transformPaginationUsage = (filePath: string, content: string): string | null => {\n const sourceFile = parseTsx(content, filePath);\n\n const aliases = getImportedAliases(sourceFile, PACKAGE_NAME);\n if (aliases === null) return null;\n\n const localAlias = Object.entries(aliases).find(([, name]) => name === COMPONENT_NAME)?.[0];\n if (localAlias === undefined) return null;\n\n const matches = findJsxElements(sourceFile, [localAlias]);\n if (matches.length === 0) return null;\n\n type Edit = { offset: number; text: string };\n const edits: Array<Edit> = [];\n\n for (const { openingElement } of matches) {\n if (hasSpreadAttribute(openingElement)) continue;\n\n for (const [propName, placeholder] of Object.entries(PLACEHOLDERS)) {\n if (findJsxAttribute(openingElement, propName) !== null) continue;\n edits.push({\n offset: openingElement.tagName.getEnd(),\n text: ` ${propName}=\"${placeholder}\"`,\n });\n }\n }\n\n if (edits.length === 0) return null;\n\n // Apply in reverse so earlier offsets stay valid; keep order at the same\n // offset so attributes appear in declaration order in the source.\n edits.sort((a, b) => (a.offset === b.offset ? 0 : b.offset - a.offset));\n\n let updated = content;\n for (const { offset, text } of edits) {\n updated = updated.slice(0, offset) + text + updated.slice(offset);\n }\n return updated;\n};\n\n/**\n * Adds the now-required `previousPageTitle` and `nextPageTitle` props to\n * `<Pagination>` usages that don't already provide them. The values default\n * to the English strings \"Previous page\"/\"Next page\"; consumers should\n * replace them with their own localized strings.\n *\n * Usages with a spread attribute (e.g. `<Pagination {...props} />`) are\n * skipped because we cannot tell whether the props are already provided.\n */\nexport const paginationAddRequiredTitles = (tree: Tree): void => {\n const touched = visitTsxFiles(tree, \"Pagination\", transformPaginationUsage);\n logSummary(\"pagination-add-required-titles\", touched);\n if (touched > 0) {\n logger.info(` Replace the placeholder \"Previous page\"/\"Next page\" strings with your own localized values.`);\n }\n};\n\nexport default paginationAddRequiredTitles;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tag-add-removetaglabel.js","sourceRoot":"","sources":["../../../../../../libs/react/components/migrations/v2-0-0/tag-add-removetaglabel.ts"],"names":[],"mappings":";;;AAAA,uCAA+C;AAC/C,kDAQ4B;AAE5B,MAAM,YAAY,GAAG,6BAA6B,CAAC;AACnD,MAAM,cAAc,GAAG,KAAK,CAAC;AAE7B,MAAM,4BAA4B,GAAG,YAAY,CAAC;AAElD,MAAM,iBAAiB,GAAG,CAAC,QAAgB,EAAE,OAAe,EAAiB,EAAE;IAC7E,MAAM,UAAU,GAAG,IAAA,oBAAQ,EAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAE/C,MAAM,OAAO,GAAG,IAAA,8BAAkB,EAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAC7D,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAElC,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5F,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAE1C,MAAM,OAAO,GAAG,IAAA,2BAAe,EAAC,UAAU,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAC1D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAGtC,MAAM,KAAK,GAAgB,EAAE,CAAC;IAE9B,KAAK,MAAM,EAAE,cAAc,EAAE,IAAI,OAAO,EAAE,CAAC;QACzC,IAAI,IAAA,8BAAkB,EAAC,cAAc,CAAC;YAAE,SAAS;QAEjD,0EAA0E;QAC1E,wBAAwB;QACxB,IAAI,IAAA,4BAAgB,EAAC,cAAc,EAAE,cAAc,CAAC,KAAK,IAAI;YAAE,SAAS;QACxE,IAAI,IAAA,4BAAgB,EAAC,cAAc,EAAE,gBAAgB,CAAC,KAAK,IAAI;YAAE,SAAS;QAE1E,KAAK,CAAC,IAAI,CAAC;YACT,MAAM,EAAE,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE;YACvC,IAAI,EAAE,oBAAoB,4BAA4B,GAAG;SAC1D,CAAC,CAAC;IACL,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAExE,IAAI,OAAO,GAAG,OAAO,CAAC;IACtB,KAAK,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,KAAK,EAAE,CAAC;QACrC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF;;;;;GAKG;AACI,MAAM,oBAAoB,GAAG,CAAC,IAAU,EAAQ,EAAE;IACvD,MAAM,OAAO,GAAG,IAAA,yBAAa,EAAC,IAAI,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;IAC9D,IAAA,sBAAU,EAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;IAC9C,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,eAAM,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAC;IAC9F,CAAC;AACH,CAAC,CAAC;AANW,QAAA,oBAAoB,wBAM/B;AAEF,kBAAe,4BAAoB,CAAC","sourcesContent":["import { type Tree, logger } from \"@nx/devkit\";\nimport {\n findJsxAttribute,\n findJsxElements,\n getImportedAliases,\n hasSpreadAttribute,\n logSummary,\n parseTsx,\n visitTsxFiles,\n} from \"../utils/jsx-utils\";\n\nconst PACKAGE_NAME = \"@trackunit/react-components\";\nconst COMPONENT_NAME = \"Tag\";\n\nconst REMOVE_TAG_LABEL_PLACEHOLDER = \"Remove tag\";\n\nconst transformTagUsage = (filePath: string, content: string): string | null => {\n const sourceFile = parseTsx(content, filePath);\n\n const aliases = getImportedAliases(sourceFile, PACKAGE_NAME);\n if (aliases === null) return null;\n\n const localAlias = Object.entries(aliases).find(([, name]) => name === COMPONENT_NAME)?.[0];\n if (localAlias === undefined) return null;\n\n const matches = findJsxElements(sourceFile, [localAlias]);\n if (matches.length === 0) return null;\n\n type Edit = { offset: number; text: string };\n const edits: Array<Edit> = [];\n\n for (const { openingElement } of matches) {\n if (hasSpreadAttribute(openingElement)) continue;\n\n // Only act when the tag is dismissible (has onClickClose) and missing the\n // newly required label.\n if (findJsxAttribute(openingElement, \"onClickClose\") === null) continue;\n if (findJsxAttribute(openingElement, \"removeTagLabel\") !== null) continue;\n\n edits.push({\n offset: openingElement.tagName.getEnd(),\n text: ` removeTagLabel=\"${REMOVE_TAG_LABEL_PLACEHOLDER}\"`,\n });\n }\n\n if (edits.length === 0) return null;\n\n edits.sort((a, b) => (a.offset === b.offset ? 0 : b.offset - a.offset));\n\n let updated = content;\n for (const { offset, text } of edits) {\n updated = updated.slice(0, offset) + text + updated.slice(offset);\n }\n return updated;\n};\n\n/**\n * Adds the now-required `removeTagLabel` prop to dismissible `<Tag>` usages\n * (those with `onClickClose`) when it is missing. Default value is the English\n * string \"Remove tag\"; consumers should replace it with their own localized\n * label.\n */\nexport const tagAddRemoveTagLabel = (tree: Tree): void => {\n const touched = visitTsxFiles(tree, \"Tag\", transformTagUsage);\n logSummary(\"tag-add-removetaglabel\", touched);\n if (touched > 0) {\n logger.info(` Replace the placeholder \"Remove tag\" string with your own localized value.`);\n }\n};\n\nexport default tagAddRemoveTagLabel;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"togglegroup-remove-item-style.js","sourceRoot":"","sources":["../../../../../../libs/react/components/migrations/v2-0-0/togglegroup-remove-item-style.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Tree, logger } from \"@nx/devkit\";\nimport * as ts from \"typescript\";\nimport {\n findJsxAttribute,\n findJsxElements,\n getImportedAliases,\n logSummary,\n parseTsx,\n visitTsxFiles,\n} from \"../utils/jsx-utils\";\n\nconst PACKAGE_NAME = \"@trackunit/react-components\";\nconst COMPONENT_NAME = \"ToggleGroup\";\n\ntype Removal = { start: number; end: number };\n\nconst collectStyleRemovalsFromArray = (arrayLiteral: ts.ArrayLiteralExpression): ReadonlyArray<Removal> => {\n const removals: Array<Removal> = [];\n for (const element of arrayLiteral.elements) {\n if (!ts.isObjectLiteralExpression(element)) continue;\n for (const prop of element.properties) {\n if (\n (ts.isPropertyAssignment(prop) || ts.isShorthandPropertyAssignment(prop)) &&\n ts.isIdentifier(prop.name) &&\n prop.name.text === \"style\"\n ) {\n removals.push({ start: prop.getFullStart(), end: prop.getEnd() });\n }\n }\n }\n return removals;\n};\n\nconst transformToggleGroupUsage = (\n filePath: string,\n content: string\n): { content: string | null; skippedNonInline: number } => {\n const sourceFile = parseTsx(content, filePath);\n\n const aliases = getImportedAliases(sourceFile, PACKAGE_NAME);\n if (aliases === null) return { content: null, skippedNonInline: 0 };\n\n const localAlias = Object.entries(aliases).find(([, name]) => name === COMPONENT_NAME)?.[0];\n if (localAlias === undefined) return { content: null, skippedNonInline: 0 };\n\n const matches = findJsxElements(sourceFile, [localAlias]);\n if (matches.length === 0) return { content: null, skippedNonInline: 0 };\n\n const removals: Array<Removal> = [];\n let skippedNonInline = 0;\n\n for (const { openingElement } of matches) {\n const listAttr = findJsxAttribute(openingElement, \"list\");\n if (listAttr === null) continue;\n\n const initializer = listAttr.initializer;\n if (initializer === undefined || !ts.isJsxExpression(initializer)) continue;\n const expr = initializer.expression;\n if (expr === undefined) continue;\n\n if (!ts.isArrayLiteralExpression(expr)) {\n // The list is referenced through a variable / function call; we can't\n // safely strip `style` without potentially editing unrelated objects.\n skippedNonInline += 1;\n continue;\n }\n\n removals.push(...collectStyleRemovalsFromArray(expr));\n }\n\n if (removals.length === 0) return { content: null, skippedNonInline };\n\n // Remove the property and its trailing comma if present so we don't leave\n // dangling `, ,` sequences.\n const sorted = [...removals].sort((a, b) => b.start - a.start);\n let updated = content;\n for (let { start, end } of sorted) {\n while (start > 0 && (updated[start - 1] === \" \" || updated[start - 1] === \"\\t\")) {\n start -= 1;\n }\n if (updated[end] === \",\") {\n end += 1;\n }\n updated = updated.slice(0, start) + updated.slice(end);\n }\n\n return { content: updated, skippedNonInline };\n};\n\n/**\n * Removes the `style` property from items in `<ToggleGroup list={[...]}>`\n * because `BasicToggleGroupListProps` no longer extends `Styleable`.\n *\n * Only inline array literals are processed; lists pulled in via a variable or\n * function call are left untouched and reported in the migration summary so\n * the developer can review them.\n */\nexport const toggleGroupRemoveItemStyle = (tree: Tree): void => {\n let touched = 0;\n let totalSkipped = 0;\n visitTsxFiles(tree, COMPONENT_NAME, (filePath, content) => {\n const { content: updated, skippedNonInline } = transformToggleGroupUsage(filePath, content);\n totalSkipped += skippedNonInline;\n if (updated !== null && updated !== content) {\n touched += 1;\n return updated;\n }\n return null;\n });\n logSummary(\"togglegroup-remove-item-style\", touched, totalSkipped);\n if (totalSkipped > 0) {\n logger.info(\n ` ${totalSkipped} ToggleGroup usage(s) referenced their list through a variable/function. Remove any 'style' properties from those item objects manually.`\n );\n }\n};\n\nexport default toggleGroupRemoveItemStyle;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copyabletext-to-text-copybutton.js","sourceRoot":"","sources":["../../../../../../libs/react/components/migrations/v3-0-0/copyabletext-to-text-copybutton.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Tree } from \"@nx/devkit\";\nimport * as ts from \"typescript\";\nimport {\n findJsxAttribute,\n findJsxElements,\n getImportedAliases,\n hasSpreadAttribute,\n logSummary,\n parseTsx,\n visitTsxFiles,\n} from \"../utils/jsx-utils\";\n\nconst PACKAGE_NAME = \"@trackunit/react-components\";\nconst COMPONENT_NAME = \"CopyableText\";\n\n/** Attribute initializer rendered back to source, e.g. `\"abc\"` or `{value}`. */\nconst attributeText = (attr: ts.JsxAttribute): string | null => {\n const initializer = attr.initializer;\n if (initializer === undefined) return null;\n return initializer.getText();\n};\n\n/**\n * The expression the copied text resolves to: `text=\"abc\"` yields `\"abc\"`,\n * `text={value}` yields `value`. Used both as the CopyButton value and as the\n * rendered children, so it must be a side-effect-free expression.\n */\nconst textExpression = (attr: ts.JsxAttribute): string | null => {\n const initializer = attr.initializer;\n if (initializer === undefined) return null;\n if (ts.isStringLiteral(initializer)) return initializer.getText();\n if (ts.isJsxExpression(initializer) && initializer.expression !== undefined) {\n return initializer.expression.getText();\n }\n return null;\n};\n\nconst renderReplacement = ({\n textExpr,\n size,\n copyLabelAttr,\n copiedLabelAttr,\n classNameLiteral,\n styleAttr,\n testIdAttr,\n textAlias,\n copyButtonAlias,\n}: {\n textExpr: string;\n size: \"sm\" | \"xs\";\n copyLabelAttr: string | null;\n copiedLabelAttr: string | null;\n classNameLiteral: string | null;\n styleAttr: string | null;\n testIdAttr: string | null;\n textAlias: string;\n copyButtonAlias: string;\n}): string => {\n const wrapperClasses = [\"flex\", \"min-w-0\", \"max-w-full\", \"items-center\", \"gap-0.5\", classNameLiteral]\n .filter(Boolean)\n .join(\" \");\n\n const wrapperAttrs = [\n `className=\"${wrapperClasses}\"`,\n styleAttr !== null ? `style=${styleAttr}` : null,\n testIdAttr !== null ? `data-testid=${testIdAttr}` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const textProps = [`className=\"min-w-0 truncate\"`, size === \"xs\" ? `size=\"small\"` : null, `type=\"span\"`]\n .filter(Boolean)\n .join(\" \");\n\n const buttonProps = [\n `className=\"shrink-0\"`,\n copiedLabelAttr !== null ? `copiedLabel=${copiedLabelAttr}` : null,\n copyLabelAttr !== null ? `copyLabel=${copyLabelAttr}` : null,\n size === \"xs\" ? `size=\"extraSmall\"` : null,\n `value={${textExpr}}`,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return `<span ${wrapperAttrs}><${textAlias} ${textProps}>{${textExpr}}</${textAlias}><${copyButtonAlias} ${buttonProps} /></span>`;\n};\n\n/** Removes `name` (possibly aliased) from the package's named import list. */\nconst removeNamedImport = (content: string, packageName: string, name: string): string => {\n const sourceFile = parseTsx(content, \"source.tsx\");\n\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) continue;\n const moduleSpecifier = stmt.moduleSpecifier;\n if (!ts.isStringLiteral(moduleSpecifier) || moduleSpecifier.text !== packageName) continue;\n\n const namedBindings = stmt.importClause?.namedBindings;\n if (namedBindings === undefined || !ts.isNamedImports(namedBindings)) continue;\n\n const remaining = namedBindings.elements.filter(el => (el.propertyName?.text ?? el.name.text) !== name);\n if (remaining.length === namedBindings.elements.length) continue;\n\n if (remaining.length === 0) {\n // The import only carried this component; drop the whole statement.\n const start = stmt.getFullStart();\n const end = stmt.getEnd();\n const trailing = content.slice(end).startsWith(\"\\n\") ? end + 1 : end;\n return `${content.slice(0, start)}${content.slice(trailing)}`;\n }\n\n const elementsText = remaining.map(el => el.getText()).join(\", \");\n return `${content.slice(0, namedBindings.getStart())}{ ${elementsText} }${content.slice(namedBindings.getEnd())}`;\n }\n\n return content;\n};\n\nconst ensureNamedImport = (content: string, packageName: string, namesToAdd: ReadonlyArray<string>): string => {\n const sourceFile = parseTsx(content, \"source.tsx\");\n const aliases = getImportedAliases(sourceFile, packageName) ?? {};\n\n const missing = namesToAdd.filter(name => !Object.values(aliases).includes(name));\n if (missing.length === 0) return content;\n\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) continue;\n const moduleSpecifier = stmt.moduleSpecifier;\n if (!ts.isStringLiteral(moduleSpecifier) || moduleSpecifier.text !== packageName) continue;\n\n const namedBindings = stmt.importClause?.namedBindings;\n if (namedBindings === undefined || !ts.isNamedImports(namedBindings)) continue;\n\n const elementsText = namedBindings.elements.map(el => el.getText()).join(\", \");\n const merged = [elementsText, ...missing].join(\", \");\n return `${content.slice(0, namedBindings.getStart())}{ ${merged} }${content.slice(namedBindings.getEnd())}`;\n }\n\n const importLine = `import { ${missing.join(\", \")} } from \"${packageName}\";\\n`;\n return `${importLine}${content}`;\n};\n\nlet manualReviewCount = 0;\n\nconst transformCopyableTextUsage = (filePath: string, content: string): string | null => {\n const sourceFile = parseTsx(content, filePath);\n\n const aliases = getImportedAliases(sourceFile, PACKAGE_NAME);\n if (aliases === null) return null;\n\n const copyableTextAlias = Object.entries(aliases).find(([, name]) => name === COMPONENT_NAME)?.[0];\n if (copyableTextAlias === undefined) return null;\n\n // A referenced CopyableTextProps type cannot be rewritten mechanically;\n // leave the whole file for a human so it isn't half-migrated.\n if (Object.values(aliases).includes(\"CopyableTextProps\")) {\n manualReviewCount += 1;\n return null;\n }\n\n const matches = findJsxElements(sourceFile, [copyableTextAlias]);\n if (matches.length === 0) return null;\n\n type Edit = { start: number; end: number; replacement: string };\n const edits: Array<Edit> = [];\n\n for (const { openingElement, element } of matches) {\n if (hasSpreadAttribute(openingElement) || findJsxAttribute(openingElement, \"ref\") !== null) {\n manualReviewCount += 1;\n continue;\n }\n\n const textAttr = findJsxAttribute(openingElement, \"text\");\n const textExpr = textAttr !== null ? textExpression(textAttr) : null;\n if (textExpr === null) {\n manualReviewCount += 1;\n continue;\n }\n\n const sizeAttr = findJsxAttribute(openingElement, \"size\");\n const sizeInitializer = sizeAttr?.initializer;\n const size = sizeInitializer !== undefined && sizeInitializer.getText().includes(\"xs\") ? \"xs\" : \"sm\";\n\n const classNameAttr = findJsxAttribute(openingElement, \"className\");\n let classNameLiteral: string | null = null;\n if (classNameAttr !== null) {\n const initializer = classNameAttr.initializer;\n if (initializer !== undefined && ts.isStringLiteral(initializer)) {\n classNameLiteral = initializer.text;\n } else {\n // Dynamic classNames can't be merged into the wrapper's string safely.\n manualReviewCount += 1;\n continue;\n }\n }\n\n const copyLabelAttr = findJsxAttribute(openingElement, \"copyLabel\");\n const copiedLabelAttr = findJsxAttribute(openingElement, \"copiedLabel\");\n const styleAttr = findJsxAttribute(openingElement, \"style\");\n const testIdAttr = findJsxAttribute(openingElement, \"data-testid\");\n\n const replacement = renderReplacement({\n textExpr,\n size,\n copyLabelAttr: copyLabelAttr !== null ? attributeText(copyLabelAttr) : null,\n copiedLabelAttr: copiedLabelAttr !== null ? attributeText(copiedLabelAttr) : null,\n classNameLiteral,\n styleAttr: styleAttr !== null ? attributeText(styleAttr) : null,\n testIdAttr: testIdAttr !== null ? attributeText(testIdAttr) : null,\n textAlias: \"Text\",\n copyButtonAlias: \"CopyButton\",\n });\n\n edits.push({ start: element.getStart(), end: element.getEnd(), replacement });\n }\n\n if (edits.length === 0) return null;\n\n edits.sort((a, b) => b.start - a.start);\n\n let updated = content;\n for (const { start, end, replacement } of edits) {\n updated = `${updated.slice(0, start)}${replacement}${updated.slice(end)}`;\n }\n\n // Only drop the import when every usage in the file was rewritten.\n const remaining = findJsxElements(parseTsx(updated, filePath), [copyableTextAlias]);\n if (remaining.length === 0) {\n updated = removeNamedImport(updated, PACKAGE_NAME, COMPONENT_NAME);\n } else {\n manualReviewCount += 1;\n }\n\n updated = ensureNamedImport(updated, PACKAGE_NAME, [\"Text\", \"CopyButton\"]);\n\n return updated;\n};\n\n/**\n * Rewrites `<CopyableText text={x} …/>` (removed in v3) into the plain\n * value/copy pair: a `Text` next to a `CopyButton` that copies the same\n * expression. `size=\"xs\"` maps to `Text size=\"small\"` + `CopyButton\n * size=\"extraSmall\"`; `copyLabel`/`copiedLabel` carry over (CopyButton also\n * ships localized defaults). Usages with spreads, refs, dynamic classNames,\n * or a referenced `CopyableTextProps` type are left for manual review.\n */\nexport const copyableTextToTextCopyButton = (tree: Tree): void => {\n manualReviewCount = 0;\n const touched = visitTsxFiles(tree, COMPONENT_NAME, transformCopyableTextUsage);\n logSummary(\"copyabletext-to-text-copybutton\", touched, manualReviewCount);\n};\n\nexport default copyableTextToTextCopyButton;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menulist-rename-to-menucontent.js","sourceRoot":"","sources":["../../../../../../libs/react/components/migrations/v3-0-0/menulist-rename-to-menucontent.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Tree } from \"@nx/devkit\";\nimport * as ts from \"typescript\";\nimport { getImportedAliases, logSummary, parseTsx, visitTsxFiles } from \"../utils/jsx-utils\";\n\nconst PACKAGE_NAME = \"@trackunit/react-components\";\n\nconst RENAMES: ReadonlyArray<{ readonly from: string; readonly to: string }> = [\n { from: \"MenuList\", to: \"MenuContent\" },\n { from: \"MenuListProps\", to: \"MenuContentProps\" },\n];\n\ntype Edit = { start: number; end: number; text: string };\n\n/**\n * Every `Identifier` node in the file matching `name`. Safe to use as a\n * blanket rename once we've confirmed (via `getImportedAliases`) that `name`\n * is genuinely imported from the target package with no local alias — in\n * that case the import specifier, JSX tag references, and type references\n * all share the same identifier text, so one pass covers every site.\n */\nconst collectIdentifierEdits = (sourceFile: ts.SourceFile, name: string, replacement: string): Array<Edit> => {\n const edits: Array<Edit> = [];\n const visit = (node: ts.Node): void => {\n if (ts.isIdentifier(node) && node.text === name) {\n edits.push({ start: node.getStart(sourceFile), end: node.getEnd(), text: replacement });\n }\n ts.forEachChild(node, visit);\n };\n visit(sourceFile);\n return edits;\n};\n\n/**\n * Locates the `propertyName` of an aliased named import specifier\n * (`{ MenuList as Foo }`) for `importedName`. Only that part needs\n * rewriting — the local binding `Foo` (and therefore every usage site in\n * the file) stays exactly as the author wrote it.\n */\nconst findAliasedImportSpecifierEdit = (\n sourceFile: ts.SourceFile,\n packageName: string,\n importedName: string,\n replacement: string\n): Edit | null => {\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) continue;\n const moduleSpecifier = stmt.moduleSpecifier;\n if (!ts.isStringLiteral(moduleSpecifier) || moduleSpecifier.text !== packageName) continue;\n\n const namedBindings = stmt.importClause?.namedBindings;\n if (namedBindings === undefined || !ts.isNamedImports(namedBindings)) continue;\n\n for (const element of namedBindings.elements) {\n if (element.propertyName === undefined) continue;\n if (element.propertyName.text !== importedName) continue;\n return {\n start: element.propertyName.getStart(sourceFile),\n end: element.propertyName.getEnd(),\n text: replacement,\n };\n }\n }\n return null;\n};\n\nconst transformMenuListUsage = (filePath: string, content: string): string | null => {\n const sourceFile = parseTsx(content, filePath);\n\n const aliases = getImportedAliases(sourceFile, PACKAGE_NAME);\n if (aliases === null) return null;\n\n const edits: Array<Edit> = [];\n\n for (const { from, to } of RENAMES) {\n const localAlias = Object.entries(aliases).find(([, original]) => original === from)?.[0];\n if (localAlias === undefined) continue;\n\n if (localAlias === from) {\n edits.push(...collectIdentifierEdits(sourceFile, from, to));\n } else {\n const edit = findAliasedImportSpecifierEdit(sourceFile, PACKAGE_NAME, from, to);\n if (edit !== null) edits.push(edit);\n }\n }\n\n if (edits.length === 0) return null;\n\n edits.sort((a, b) => b.start - a.start);\n\n let updated = content;\n for (const { start, end, text } of edits) {\n updated = updated.slice(0, start) + text + updated.slice(end);\n }\n return updated;\n};\n\n/**\n * Renames `MenuList`/`MenuListProps` to `MenuContent`/`MenuContentProps`\n * everywhere they're imported from `@trackunit/react-components` — the\n * import specifier, every JSX tag usage, and every type reference (e.g.\n * `Omit<MenuListProps, \"children\">`).\n *\n * Aliased imports (`{ MenuList as Foo }`) only need the imported name\n * rewritten; the local alias and its usage sites are left untouched.\n * Unrelated same-prefix exports like `cvaMenuList`/`cvaMenuListItem` are\n * never matched since identifier comparisons are exact, not substring.\n */\nexport const menuListRenameToMenuContent = (tree: Tree): void => {\n const touched = visitTsxFiles(tree, \"MenuList\", transformMenuListUsage);\n logSummary(\"menulist-rename-to-menucontent\", touched);\n};\n\nexport default menuListRenameToMenuContent;\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-components",
|
|
3
|
-
"version": "3.8.
|
|
3
|
+
"version": "3.8.2-alpha-775ca1816d6.0",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"migrations": "./migrations.json",
|
|
@@ -14,16 +14,16 @@
|
|
|
14
14
|
"@floating-ui/react": "^0.26.25",
|
|
15
15
|
"string-ts": "^2.0.0",
|
|
16
16
|
"tailwind-merge": "^2.0.0",
|
|
17
|
-
"@trackunit/ui-design-tokens": "1.18.
|
|
18
|
-
"@trackunit/css-class-variance-utilities": "2.3.
|
|
19
|
-
"@trackunit/shared-utils": "1.19.
|
|
20
|
-
"@trackunit/ui-icons": "1.17.
|
|
17
|
+
"@trackunit/ui-design-tokens": "1.18.5-alpha-775ca1816d6.0",
|
|
18
|
+
"@trackunit/css-class-variance-utilities": "2.3.5-alpha-775ca1816d6.0",
|
|
19
|
+
"@trackunit/shared-utils": "1.19.5-alpha-775ca1816d6.0",
|
|
20
|
+
"@trackunit/ui-icons": "1.17.5-alpha-775ca1816d6.0",
|
|
21
21
|
"es-toolkit": "^1.52.0",
|
|
22
22
|
"@tanstack/react-virtual": "^3.14.13",
|
|
23
23
|
"dequal": "^2.0.3",
|
|
24
24
|
"fflate": "^0.8.3",
|
|
25
25
|
"zod": "^3.25.76",
|
|
26
|
-
"@trackunit/i18n-library-translation": "2.8.
|
|
26
|
+
"@trackunit/i18n-library-translation": "2.8.5-alpha-775ca1816d6.0"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
29
|
"react": "^19.0.0",
|
|
@@ -1,24 +1,19 @@
|
|
|
1
|
+
import { type UrlParamLocation } from "./useUrlParamSync";
|
|
1
2
|
/**
|
|
2
3
|
* Selects which part of the URL backs the persisted state.
|
|
3
4
|
*
|
|
4
5
|
* - `"search"` (default): `?<key>=<encoded>`. Subject to the AWS WAF
|
|
5
|
-
* managed-rule cap (~5000 bytes) — large states
|
|
6
|
-
* truncated before they hit the browser bar.
|
|
6
|
+
* managed-rule cap (~5000 bytes) — large states are dropped from the URL.
|
|
7
7
|
* - `"hash"`: `#<key>=<encoded>`. Stays on the client, so the cap is
|
|
8
|
-
* driven only by browser URL limits.
|
|
9
|
-
* `usePersistedState` also performs a one-shot migration from any
|
|
10
|
-
* legacy `?<key>=...` value so previously shared links don't lose state.
|
|
8
|
+
* driven only by browser URL limits.
|
|
11
9
|
*/
|
|
12
|
-
export type UrlPersistenceLocation =
|
|
10
|
+
export type UrlPersistenceLocation = UrlParamLocation;
|
|
13
11
|
type UsePersistedStateOptions<TState> = {
|
|
14
12
|
readonly key: string;
|
|
15
13
|
readonly validate: (raw: unknown) => TState | undefined;
|
|
16
|
-
readonly serialize?: (state: TState) => string;
|
|
17
14
|
readonly toUrlValue?: (state: TState) => string | object | Array<object>;
|
|
18
15
|
readonly fromUrlValue?: (decoded: unknown) => unknown;
|
|
19
|
-
readonly enabled?: boolean;
|
|
20
16
|
readonly localStorageEnabled?: boolean;
|
|
21
|
-
readonly onExternalChange?: () => void;
|
|
22
17
|
readonly replace?: boolean;
|
|
23
18
|
readonly clientSideUserId?: string;
|
|
24
19
|
/**
|
|
@@ -30,8 +25,7 @@ type UsePersistedStateOptions<TState> = {
|
|
|
30
25
|
* (e.g. per-user layout details that shouldn't be shareable) so the
|
|
31
26
|
* omitted fields still survive reloads via localStorage.
|
|
32
27
|
*
|
|
33
|
-
* Default is `false
|
|
34
|
-
* fully replaces localStorage state on read.
|
|
28
|
+
* Default is `false`: URL state fully replaces localStorage state on read.
|
|
35
29
|
*/
|
|
36
30
|
readonly mergeWithStorageOnRead?: boolean;
|
|
37
31
|
/**
|
|
@@ -56,15 +50,16 @@ type UsePersistedStateOptions<TState> = {
|
|
|
56
50
|
};
|
|
57
51
|
type UsePersistedStateReturn<TState> = {
|
|
58
52
|
readonly initialState: TState | undefined;
|
|
53
|
+
/** Writes `state` to localStorage and the URL; each slot skips a value equal to its last write. */
|
|
59
54
|
readonly persistState: (state: TState) => void;
|
|
60
|
-
readonly clearState: () => void;
|
|
61
55
|
/**
|
|
62
|
-
* Writes
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* the caller can retry. A no-op success returns `true`.
|
|
56
|
+
* Writes `state` to localStorage only; `undefined` removes the entry.
|
|
57
|
+
* Use together with `persistToUrl` when the two writes should not share a
|
|
58
|
+
* schedule — e.g. storage immediately, URL debounced.
|
|
66
59
|
*/
|
|
67
|
-
readonly
|
|
60
|
+
readonly persistToStorage: (state: TState | undefined) => void;
|
|
61
|
+
/** Writes `state` to the URL only; `undefined` removes the entry. */
|
|
62
|
+
readonly persistToUrl: (state: TState | undefined) => void;
|
|
68
63
|
};
|
|
69
64
|
/**
|
|
70
65
|
* Generic persistence hook that loads state from a URL slot (search param
|
|
@@ -72,47 +67,39 @@ type UsePersistedStateReturn<TState> = {
|
|
|
72
67
|
* and writes changes to both.
|
|
73
68
|
*
|
|
74
69
|
* On mount the hook resolves the initial state as follows:
|
|
75
|
-
* - If the
|
|
76
|
-
* value, decode it and pass through `validate`.
|
|
77
|
-
* - In `urlLocation: "hash"` mode, if the canonical hash slot has no valid
|
|
78
|
-
* value but a **legacy** `?<key>=...` search param is present, decode and
|
|
79
|
-
* validate that as a one-shot fallback. The value is copied into the hash
|
|
80
|
-
* and the search param is stripped via a `replace` navigation.
|
|
81
|
-
* - A value that comes only from localStorage is not written to the URL.
|
|
82
|
-
* Copying it on load left a layout in history, bookmarks, and login
|
|
83
|
-
* redirects, which then replayed an older layout over the saved one
|
|
84
|
-
* (GLU-2396). The URL is written when the user changes the state.
|
|
70
|
+
* - If the URL slot holds a value, decode it and pass through `validate`.
|
|
85
71
|
* - If localStorage is enabled, read and validate its value.
|
|
86
72
|
* - When `mergeWithStorageOnRead` is `false` (default): URL state wins
|
|
87
73
|
* entirely when present, otherwise fall back to localStorage.
|
|
88
74
|
* - When `mergeWithStorageOnRead` is `true`: shallow-merge URL fields over
|
|
89
75
|
* localStorage so fields stripped by `toUrlValue` survive via storage.
|
|
90
76
|
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
77
|
+
* A value that comes only from localStorage is never written to the URL on
|
|
78
|
+
* load. Copying it left a layout in history, bookmarks, and login redirects,
|
|
79
|
+
* which then replayed an older layout over the saved one (GLU-2396). The URL
|
|
80
|
+
* is written when the consumer persists a change.
|
|
95
81
|
*
|
|
96
|
-
* `
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
82
|
+
* `persistState` writes to localStorage (`storageSerializer`) and to the URL
|
|
83
|
+
* (via `toUrlValue` + encoding).
|
|
84
|
+
* Each slot skips a value deep-equal to its last write. The URL side starts
|
|
85
|
+
* from the hydrated state, so echoing `initialState` writes no URL entry. The
|
|
86
|
+
* storage side starts from what localStorage held, so a consumer that persists
|
|
87
|
+
* `initialState` after opening a link saves that link's state for the account
|
|
88
|
+
* that opened it, and a reload of the account's own link writes nothing.
|
|
89
|
+
* `persistToStorage` and `persistToUrl` are the same two halves exposed
|
|
90
|
+
* separately for consumers that schedule them differently; passing `undefined`
|
|
91
|
+
* removes the entry rather than writing an empty value.
|
|
101
92
|
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
* user has reset. It is idempotent — clearing an absent entry is a no-op.
|
|
93
|
+
* The snapshot is re-read when the storage key or the storage/merge options
|
|
94
|
+
* change, in the same render, so a write in that commit already sees the
|
|
95
|
+
* state for the new key.
|
|
106
96
|
*
|
|
107
97
|
* @param options - Configuration for the persisted state.
|
|
108
98
|
* @param options.key - Unique identifier used for both the URL slot and the localStorage key.
|
|
109
99
|
* @param options.validate - Called with the decoded/parsed value; must return `TState` or `undefined`.
|
|
110
|
-
* @param options.serialize - Custom localStorage serialiser (default `storageSerializer.serialize`).
|
|
111
100
|
* @param options.toUrlValue - Transform applied before URL encoding (default: encode state as-is).
|
|
112
101
|
* @param options.fromUrlValue - Transform applied after URL decoding, before validation (default: identity).
|
|
113
|
-
* @param options.enabled - When `false` the URL is neither read nor written (default `true`).
|
|
114
102
|
* @param options.localStorageEnabled - When `false` localStorage is neither read nor written (default `true`).
|
|
115
|
-
* @param options.onExternalChange - Fired when the URL value changes externally (e.g. browser back).
|
|
116
103
|
* @param options.replace - Forwarded to the underlying URL sync hook.
|
|
117
104
|
* @param options.clientSideUserId - The user ID to use for the localStorage key.
|
|
118
105
|
* @param options.mergeWithStorageOnRead - Merge URL state on top of localStorage
|
|
@@ -122,5 +109,5 @@ type UsePersistedStateReturn<TState> = {
|
|
|
122
109
|
* @param options.stampUrlWithIdentity - Stamp URL writes with the current identity so the login
|
|
123
110
|
* redirect can drop entries left by another account on this browser. Default `false`.
|
|
124
111
|
*/
|
|
125
|
-
export declare const usePersistedState: <TState extends object>({ key, validate,
|
|
112
|
+
export declare const usePersistedState: <TState extends object>({ key, validate, toUrlValue, fromUrlValue, localStorageEnabled, replace, clientSideUserId, mergeWithStorageOnRead, urlLocation, stampUrlWithIdentity, }: UsePersistedStateOptions<TState>) => UsePersistedStateReturn<TState>;
|
|
126
113
|
export {};
|
|
@@ -1,30 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
* Sized to stay safely below the AWS WAF managed-rule default
|
|
6
|
-
* `SizeRestrictions_QUERYSTRING` cap of 5000 bytes for the entire url host + path + query + hash string
|
|
7
|
-
*/
|
|
8
|
-
export declare const MAX_URL_LENGTH = 5000;
|
|
9
|
-
type UseSearchParamSyncOptions = {
|
|
10
|
-
readonly key: string;
|
|
11
|
-
readonly enabled?: boolean;
|
|
12
|
-
readonly onExternalChange?: () => void;
|
|
13
|
-
readonly replace?: boolean;
|
|
14
|
-
};
|
|
15
|
-
type UseSearchParamSyncReturn = {
|
|
16
|
-
readonly searchValue: string | undefined;
|
|
17
|
-
readonly updateSearchParam: (encodedValue: string | undefined, options?: {
|
|
18
|
-
readonly replace?: boolean;
|
|
19
|
-
}) => void;
|
|
20
|
-
};
|
|
1
|
+
import { type UseUrlParamSyncOptions, type UseUrlParamSyncReturn } from "./useUrlParamSync";
|
|
2
|
+
export { MAX_URL_LENGTH } from "./useUrlParamSync";
|
|
3
|
+
type UseSearchParamSyncOptions = Omit<UseUrlParamSyncOptions, "location">;
|
|
21
4
|
/**
|
|
22
5
|
* Syncs an encoded string value with a URL search parameter via Tanstack Router.
|
|
23
6
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* back/forward, shared links) via an optional callback.
|
|
7
|
+
* Thin wrapper over {@link useUrlParamSync} with `location: "search"`; see it
|
|
8
|
+
* for the write queue, the size guard (`MAX_URL_LENGTH`), and external-change
|
|
9
|
+
* detection.
|
|
28
10
|
*
|
|
29
11
|
* @param options - Configuration for the search param sync.
|
|
30
12
|
* @param options.key - The URL search parameter name.
|
|
@@ -32,5 +14,4 @@ type UseSearchParamSyncReturn = {
|
|
|
32
14
|
* @param options.onExternalChange - Called when the param changes externally.
|
|
33
15
|
* @param options.replace - `true` to always use `replaceState`.
|
|
34
16
|
*/
|
|
35
|
-
export declare const useSearchParamSync: (
|
|
36
|
-
export {};
|
|
17
|
+
export declare const useSearchParamSync: (options: UseSearchParamSyncOptions) => UseUrlParamSyncReturn;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maximum full URL length after adding one persisted search param before the
|
|
3
|
+
* URL write is skipped (localStorage still persists the full state).
|
|
4
|
+
*
|
|
5
|
+
* Sized to stay safely below the AWS WAF managed-rule default
|
|
6
|
+
* `SizeRestrictions_QUERYSTRING` cap of 5000 bytes for the entire
|
|
7
|
+
* host + path + query + hash string.
|
|
8
|
+
*/
|
|
9
|
+
export declare const MAX_URL_LENGTH = 5000;
|
|
10
|
+
/**
|
|
11
|
+
* Maximum length of the URL fragment after adding one persisted entry.
|
|
12
|
+
* Oversized new entries are skipped; oversized replacements remove the stale
|
|
13
|
+
* entry so localStorage remains authoritative.
|
|
14
|
+
*
|
|
15
|
+
* The fragment is never sent to the server, so the WAF cap above does not
|
|
16
|
+
* apply. 64 KB stays well below typical browser URL limits (Chromium ≳ 100 KB,
|
|
17
|
+
* Firefox ≳ 64 KB on the address bar) while leaving generous headroom for any
|
|
18
|
+
* realistic table state.
|
|
19
|
+
*/
|
|
20
|
+
export declare const MAX_HASH_LENGTH: number;
|
|
21
|
+
/**
|
|
22
|
+
* Which part of the URL a persisted value lives in.
|
|
23
|
+
*
|
|
24
|
+
* - `"search"`: `?<key>=<encoded>`. Subject to the AWS WAF cap
|
|
25
|
+
* ({@link MAX_URL_LENGTH}); large states are dropped from the URL.
|
|
26
|
+
* - `"hash"`: `#<key>=<encoded>`. Client-only, capped by
|
|
27
|
+
* {@link MAX_HASH_LENGTH}.
|
|
28
|
+
*/
|
|
29
|
+
export type UrlParamLocation = "search" | "hash";
|
|
30
|
+
export type UseUrlParamSyncOptions = {
|
|
31
|
+
readonly key: string;
|
|
32
|
+
readonly location: UrlParamLocation;
|
|
33
|
+
readonly enabled?: boolean;
|
|
34
|
+
readonly onExternalChange?: () => void;
|
|
35
|
+
readonly replace?: boolean;
|
|
36
|
+
};
|
|
37
|
+
export type UseUrlParamSyncReturn = {
|
|
38
|
+
/** The raw encoded value currently in the URL slot, or `undefined` when absent or disabled. */
|
|
39
|
+
readonly searchValue: string | undefined;
|
|
40
|
+
/** Writes `encodedValue` into the URL slot; `undefined` removes the entry. */
|
|
41
|
+
readonly updateSearchParam: (encodedValue: string | undefined) => void;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Syncs an encoded string value with a single named entry in the URL — either
|
|
45
|
+
* a search param or an entry inside the hash fragment — via Tanstack Router.
|
|
46
|
+
*
|
|
47
|
+
* Writes go through the application router so other search params and
|
|
48
|
+
* foreign fragment content are preserved. Each slot has a size guard
|
|
49
|
+
* ({@link MAX_URL_LENGTH} for search, {@link MAX_HASH_LENGTH} for hash); an
|
|
50
|
+
* oversized value is dropped from the URL and localStorage stays
|
|
51
|
+
* authoritative. External changes to the entry (browser back/forward, a
|
|
52
|
+
* pasted link, a foreign router push) fire `onExternalChange`.
|
|
53
|
+
*
|
|
54
|
+
* Writes are dispatched via a pending-write queue rather than calling
|
|
55
|
+
* `navigate` directly. Tanstack Router's `router.state.status === "pending"`
|
|
56
|
+
* is common during the first paint of a route (loaders, suspense), and an
|
|
57
|
+
* implementation that simply returned in that case lost the write outright.
|
|
58
|
+
* `updateSearchParam` stores the latest attempted write and schedules an rAF
|
|
59
|
+
* flush; the flush only navigates when the router is idle, and an effect
|
|
60
|
+
* retries whenever the router settles. A queued write is dropped on unmount so
|
|
61
|
+
* it cannot drain onto the next route.
|
|
62
|
+
*
|
|
63
|
+
* @param options - Configuration for the URL entry sync.
|
|
64
|
+
* @param options.key - The search param name or fragment entry name.
|
|
65
|
+
* @param options.location - `"search"` or `"hash"`.
|
|
66
|
+
* @param options.enabled - Set to `false` to disable all URL interaction (default `true`).
|
|
67
|
+
* @param options.onExternalChange - Called when the entry changes externally.
|
|
68
|
+
* @param options.replace - `true` to always use `replaceState`; `false` to always push.
|
|
69
|
+
* Default: replace when the entry is being added, push when it already has a value.
|
|
70
|
+
*/
|
|
71
|
+
export declare const useUrlParamSync: ({ key, location: urlLocation, enabled, onExternalChange, replace: replaceOption, }: UseUrlParamSyncOptions) => UseUrlParamSyncReturn;
|
package/src/index.d.ts
CHANGED
|
@@ -126,7 +126,6 @@ export * from "./hooks/localStorage/useLocalStorageReducer";
|
|
|
126
126
|
export * from "./hooks/localStorage/useSessionStorage";
|
|
127
127
|
export * from "./hooks/localStorage/useSessionStorageReducer";
|
|
128
128
|
export * from "./hooks/noPagination";
|
|
129
|
-
export * from "./hooks/persistence/useHashParamSync";
|
|
130
129
|
export * from "./hooks/persistence/usePersistedState";
|
|
131
130
|
export * from "./hooks/persistence/useSearchParamSync";
|
|
132
131
|
export * from "./hooks/persistence/useStorageKey";
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Default maximum length of the resulting URL fragment after adding one
|
|
3
|
-
* persisted entry. Oversized new entries are skipped; oversized replacements
|
|
4
|
-
* remove the stale entry so localStorage remains authoritative.
|
|
5
|
-
*
|
|
6
|
-
* The fragment is never sent to the server, so it is not subject to the
|
|
7
|
-
* AWS WAF managed-rule `SizeRestrictions_QUERYSTRING` cap that applies to
|
|
8
|
-
* search params (5000 bytes). 64 KB stays well below typical browser URL
|
|
9
|
-
* limits (Chromium ≳ 100 KB, Firefox ≳ 64 KB on the address bar) while
|
|
10
|
-
* still leaving generous headroom for any realistic table state.
|
|
11
|
-
*/
|
|
12
|
-
export declare const MAX_HASH_LENGTH: number;
|
|
13
|
-
type UseHashParamSyncOptions = {
|
|
14
|
-
readonly key: string;
|
|
15
|
-
readonly enabled?: boolean;
|
|
16
|
-
readonly onExternalChange?: () => void;
|
|
17
|
-
readonly replace?: boolean;
|
|
18
|
-
};
|
|
19
|
-
type UseHashParamSyncReturn = {
|
|
20
|
-
/**
|
|
21
|
-
* Mirrors the field name on `useSearchParamSync` so this hook is a
|
|
22
|
-
* drop-in replacement when only the URL location changes (search ↔ hash).
|
|
23
|
-
* Despite the name, this value is read from `location.hash`.
|
|
24
|
-
*/
|
|
25
|
-
readonly searchValue: string | undefined;
|
|
26
|
-
/**
|
|
27
|
-
* Mirrors the function name on `useSearchParamSync`. Writes to
|
|
28
|
-
* `location.hash`, preserving any foreign fragment content untouched.
|
|
29
|
-
*/
|
|
30
|
-
readonly updateSearchParam: (encodedValue: string | undefined, options?: {
|
|
31
|
-
readonly replace?: boolean;
|
|
32
|
-
}) => void;
|
|
33
|
-
};
|
|
34
|
-
/**
|
|
35
|
-
* Syncs an encoded string value with a single named entry inside the URL
|
|
36
|
-
* fragment (`location.hash`) via Tanstack Router.
|
|
37
|
-
*
|
|
38
|
-
* Behaviour mirrors `useSearchParamSync`, with two differences:
|
|
39
|
-
* - Reads from and writes to `location.hash` instead of `location.search`.
|
|
40
|
-
* - Oversized replacements remove stale values using
|
|
41
|
-
* {@link MAX_HASH_LENGTH}, rather than the AWS-WAF-driven search-param cap.
|
|
42
|
-
*
|
|
43
|
-
* The fragment is treated as a sequence of `&`-separated tokens via the
|
|
44
|
-
* pure utilities in `./hashFragment`. Foreign tokens (bare anchors, other
|
|
45
|
-
* named entries) are preserved byte-for-byte on every write.
|
|
46
|
-
*
|
|
47
|
-
* @param options - Configuration for the hash entry sync.
|
|
48
|
-
* @param options.key - The named entry inside the fragment.
|
|
49
|
-
* @param options.enabled - Set to `false` to disable all URL interaction (default `true`).
|
|
50
|
-
* @param options.onExternalChange - Called when the entry changes externally
|
|
51
|
-
* (e.g. browser back/forward, pasted link, foreign router push).
|
|
52
|
-
* @param options.replace - `true` to always use `replaceState` instead of pushState.
|
|
53
|
-
*/
|
|
54
|
-
export declare const useHashParamSync: ({ key, enabled, onExternalChange, replace: replaceOption, }: UseHashParamSyncOptions) => UseHashParamSyncReturn;
|
|
55
|
-
export {};
|